]> git.mxchange.org Git - friendica.git/commitdiff
Revert "Move Objects to Model"
authorMichael Vogel <icarus@dabo.de>
Fri, 8 Dec 2017 04:21:51 +0000 (05:21 +0100)
committerGitHub <noreply@github.com>
Fri, 8 Dec 2017 04:21:51 +0000 (05:21 +0100)
83 files changed:
boot.php
include/acl_selectors.php
include/api.php
include/bb2diaspora.php
include/bbcode.php
include/contact_widgets.php
include/conversation.php
include/follow.php
include/identity.php
include/items.php
include/like.php
include/network.php
include/plaintext.php
include/post_update.php
include/tags.php
include/threads.php
include/uimport.php
mod/admin.php
mod/allfriends.php
mod/cal.php
mod/common.php
mod/contacts.php
mod/crepair.php
mod/dfrn_confirm.php
mod/dfrn_notify.php
mod/dfrn_request.php
mod/directory.php
mod/dirfind.php
mod/display.php
mod/fbrowser.php
mod/follow.php
mod/hovercard.php
mod/install.php
mod/item.php
mod/match.php
mod/message.php
mod/network.php
mod/nogroup.php
mod/photo.php
mod/photos.php
mod/ping.php
mod/profile_photo.php
mod/profiles.php
mod/proxy.php
mod/randprof.php
mod/settings.php
mod/suggest.php
mod/unfollow.php
mod/videos.php
mod/viewcontacts.php
mod/wall_upload.php
src/Core/NotificationsManager.php
src/Model/Contact.php [deleted file]
src/Model/GContact.php [deleted file]
src/Model/GlobalContact.php [new file with mode: 0644]
src/Model/Photo.php [deleted file]
src/Model/Profile.php [deleted file]
src/Model/User.php
src/Network/Probe.php
src/Object/Contact.php [new file with mode: 0644]
src/Object/Conversation.php [new file with mode: 0644]
src/Object/Image.php [deleted file]
src/Object/Item.php [new file with mode: 0644]
src/Object/Photo.php [new file with mode: 0644]
src/Object/Post.php [deleted file]
src/Object/Profile.php [new file with mode: 0644]
src/Object/Thread.php [deleted file]
src/ParseUrl.php
src/Protocol/DFRN.php
src/Protocol/Diaspora.php
src/Protocol/OStatus.php
src/Protocol/PortableContact.php
src/Worker/CronJobs.php
src/Worker/Delivery.php
src/Worker/DiscoverPoCo.php
src/Worker/GProbe.php
src/Worker/Notifier.php
src/Worker/OnePoll.php
update.php
util/global_community_block.php
view/theme/frio/theme.php
view/theme/frost/theme.php
view/theme/vier/theme.php

index fa26028113251db526161ea8380a07f4b92b1d48..148ca5e6e2f2bc2175b54a7c7d19465be3f829c3 100644 (file)
--- a/boot.php
+++ b/boot.php
@@ -27,7 +27,8 @@ use Friendica\Core\Config;
 use Friendica\Core\PConfig;
 use Friendica\Core\Worker;
 use Friendica\Database\DBM;
-use Friendica\Model\Contact;
+use Friendica\Object\Contact;
+use Friendica\Util\Lock;
 
 require_once 'include/network.php';
 require_once 'include/plugin.php';
index d1b791136f6aec05c84d7d0d3a51b6be7e4cb209..f971d462b2109f9f9877adab0fe84e5e6b3e6d09 100644 (file)
@@ -6,8 +6,8 @@ use Friendica\App;
 use Friendica\Content\Feature;
 use Friendica\Core\Config;
 use Friendica\Database\DBM;
-use Friendica\Model\Contact;
-use Friendica\Model\GContact;
+use Friendica\Model\GlobalContact;
+use Friendica\Object\Contact;
 
 require_once "include/contact_selectors.php";
 require_once "include/contact_widgets.php";
@@ -774,7 +774,7 @@ function navbar_complete(App $a) {
        }
 
        if ($localsearch) {
-               $x = GContact::searchByName($search, $mode);
+               $x = GlobalContact::searchByName($search, $mode);
                return $x;
        }
 
index e5963fb8fac871ec9f69d45c37784eb60cf29760..b5799d4786cac0e5bdb97017337e33aa120c9d51 100644 (file)
@@ -12,8 +12,6 @@ use Friendica\Core\Config;
 use Friendica\Core\NotificationsManager;
 use Friendica\Core\Worker;
 use Friendica\Database\DBM;
-use Friendica\Model\Contact;
-use Friendica\Model\Photo;
 use Friendica\Model\User;
 use Friendica\Network\FKOAuth1;
 use Friendica\Network\HTTPException;
@@ -25,7 +23,8 @@ use Friendica\Network\HTTPException\NotFoundException;
 use Friendica\Network\HTTPException\NotImplementedException;
 use Friendica\Network\HTTPException\UnauthorizedException;
 use Friendica\Network\HTTPException\TooManyRequestsException;
-use Friendica\Object\Image;
+use Friendica\Object\Contact;
+use Friendica\Object\Photo;
 use Friendica\Protocol\Diaspora;
 use Friendica\Util\XML;
 
@@ -1193,7 +1192,7 @@ function api_statuses_update($type)
                        api_user()
                );
                if (DBM::is_result($r)) {
-                       $phototypes = Image::supportedTypes();
+                       $phototypes = Photo::supportedTypes();
                        $ext = $phototypes[$r[0]['type']];
                        $_REQUEST['body'] .= "\n\n" . '[url=' . System::baseUrl() . '/photos/' . $r[0]['nickname'] . '/image/' . $r[0]['resource-id'] . ']';
                        $_REQUEST['body'] .= '[img]' . System::baseUrl() . '/photo/' . $r[0]['resource-id'] . '-' . $r[0]['scale'] . '.' . $ext . '[/img][/url]';
@@ -2378,7 +2377,7 @@ function api_get_attachments(&$body)
        $attachments = array();
 
        foreach ($images[1] as $image) {
-               $imagedata = Image::getInfoFromURL($image);
+               $imagedata = Photo::getInfoFromURL($image);
 
                if ($imagedata) {
                        $attachments[] = array("url" => $image, "mimetype" => $imagedata["mime"], "size" => $imagedata["size"]);
@@ -2510,7 +2509,7 @@ function api_get_entitities(&$text, $bbcode)
 
                $start = iconv_strpos($text, $url, $offset, "UTF-8");
                if (!($start === false)) {
-                       $image = Image::getInfoFromURL($url);
+                       $image = Photo::getInfoFromURL($url);
                        if ($image) {
                                // If image cache is activated, then use the following sizes:
                                // thumb  (150), small (340), medium (600) and large (1024)
@@ -2518,19 +2517,19 @@ function api_get_entitities(&$text, $bbcode)
                                        $media_url = proxy_url($url);
 
                                        $sizes = array();
-                                       $scale = Image::getScalingDimensions($image[0], $image[1], 150);
+                                       $scale = Photo::scaleImageTo($image[0], $image[1], 150);
                                        $sizes["thumb"] = array("w" => $scale["width"], "h" => $scale["height"], "resize" => "fit");
 
                                        if (($image[0] > 150) || ($image[1] > 150)) {
-                                               $scale = Image::getScalingDimensions($image[0], $image[1], 340);
+                                               $scale = Photo::scaleImageTo($image[0], $image[1], 340);
                                                $sizes["small"] = array("w" => $scale["width"], "h" => $scale["height"], "resize" => "fit");
                                        }
 
-                                       $scale = Image::getScalingDimensions($image[0], $image[1], 600);
+                                       $scale = Photo::scaleImageTo($image[0], $image[1], 600);
                                        $sizes["medium"] = array("w" => $scale["width"], "h" => $scale["height"], "resize" => "fit");
 
                                        if (($image[0] > 600) || ($image[1] > 600)) {
-                                               $scale = Image::getScalingDimensions($image[0], $image[1], 1024);
+                                               $scale = Photo::scaleImageTo($image[0], $image[1], 1024);
                                                $sizes["large"] = array("w" => $scale["width"], "h" => $scale["height"], "resize" => "fit");
                                        }
                                } else {
@@ -3947,7 +3946,7 @@ function save_media_to_database($mediatype, $media, $type, $album, $allow_cid, $
        }
 
        if ($filetype == "") {
-               $filetype=Image::guessType($filename);
+               $filetype=Photo::guessImageType($filename);
        }
        $imagedata = getimagesize($src);
        if ($imagedata) {
@@ -3971,13 +3970,13 @@ function save_media_to_database($mediatype, $media, $type, $album, $allow_cid, $
 
        // create Photo instance with the data of the image
        $imagedata = @file_get_contents($src);
-       $Image = new Image($imagedata, $filetype);
-       if (! $Image->isValid()) {
+       $ph = new Photo($imagedata, $filetype);
+       if (! $ph->isValid()) {
                throw new InternalServerErrorException("unable to process image data");
        }
 
        // check orientation of image
-       $Image->orient($src);
+       $ph->orient($src);
        @unlink($src);
 
        // check max length of images on server
@@ -3986,11 +3985,11 @@ function save_media_to_database($mediatype, $media, $type, $album, $allow_cid, $
                $max_length = MAX_IMAGE_LENGTH;
        }
        if ($max_length > 0) {
-               $Image->scaleDown($max_length);
+               $ph->scaleImage($max_length);
                logger("File upload: Scaling picture to new size " . $max_length, LOGGER_DEBUG);
        }
-       $width = $Image->getWidth();
-       $height = $Image->getHeight();
+       $width = $ph->getWidth();
+       $height = $ph->getHeight();
 
        // create a new resource-id if not already provided
        $hash = ($photo_id == null) ? photo_new_resource() : $photo_id;
@@ -3999,21 +3998,21 @@ function save_media_to_database($mediatype, $media, $type, $album, $allow_cid, $
                // upload normal image (scales 0, 1, 2)
                logger("photo upload: starting new photo upload", LOGGER_DEBUG);
 
-               $r = Photo::store($Image, local_user(), $visitor, $hash, $filename, $album, 0, 0, $allow_cid, $allow_gid, $deny_cid, $deny_gid, $desc);
+               $r =$ph->store(local_user(), $visitor, $hash, $filename, $album, 0, 0, $allow_cid, $allow_gid, $deny_cid, $deny_gid, $desc);
                if (! $r) {
                        logger("photo upload: image upload with scale 0 (original size) failed");
                }
                if ($width > 640 || $height > 640) {
-                       $Image->scaleDown(640);
-                       $r = Photo::store($Image, local_user(), $visitor, $hash, $filename, $album, 1, 0, $allow_cid, $allow_gid, $deny_cid, $deny_gid, $desc);
+                       $ph->scaleImage(640);
+                       $r = $ph->store(local_user(), $visitor, $hash, $filename, $album, 1, 0, $allow_cid, $allow_gid, $deny_cid, $deny_gid, $desc);
                        if (! $r) {
                                logger("photo upload: image upload with scale 1 (640x640) failed");
                        }
                }
 
                if ($width > 320 || $height > 320) {
-                       $Image->scaleDown(320);
-                       $r = Photo::store($Image, local_user(), $visitor, $hash, $filename, $album, 2, 0, $allow_cid, $allow_gid, $deny_cid, $deny_gid, $desc);
+                       $ph->scaleImage(320);
+                       $r = $ph->store(local_user(), $visitor, $hash, $filename, $album, 2, 0, $allow_cid, $allow_gid, $deny_cid, $deny_gid, $desc);
                        if (! $r) {
                                logger("photo upload: image upload with scale 2 (320x320) failed");
                        }
@@ -4024,29 +4023,29 @@ function save_media_to_database($mediatype, $media, $type, $album, $allow_cid, $
                logger("photo upload: starting new profile image upload", LOGGER_DEBUG);
 
                if ($width > 175 || $height > 175) {
-                       $Image->scaleDown(175);
-                       $r = Photo::store($Image, local_user(), $visitor, $hash, $filename, $album, 4, $profile, $allow_cid, $allow_gid, $deny_cid, $deny_gid, $desc);
+                       $ph->scaleImage(175);
+                       $r = $ph->store(local_user(), $visitor, $hash, $filename, $album, 4, $profile, $allow_cid, $allow_gid, $deny_cid, $deny_gid, $desc);
                        if (! $r) {
                                logger("photo upload: profile image upload with scale 4 (175x175) failed");
                        }
                }
 
                if ($width > 80 || $height > 80) {
-                       $Image->scaleDown(80);
-                       $r = Photo::store($Image, local_user(), $visitor, $hash, $filename, $album, 5, $profile, $allow_cid, $allow_gid, $deny_cid, $deny_gid, $desc);
+                       $ph->scaleImage(80);
+                       $r = $ph->store(local_user(), $visitor, $hash, $filename, $album, 5, $profile, $allow_cid, $allow_gid, $deny_cid, $deny_gid, $desc);
                        if (! $r) {
                                logger("photo upload: profile image upload with scale 5 (80x80) failed");
                        }
                }
 
                if ($width > 48 || $height > 48) {
-                       $Image->scaleDown(48);
-                       $r = Photo::store($Image, local_user(), $visitor, $hash, $filename, $album, 6, $profile, $allow_cid, $allow_gid, $deny_cid, $deny_gid, $desc);
+                       $ph->scaleImage(48);
+                       $r = $ph->store(local_user(), $visitor, $hash, $filename, $album, 6, $profile, $allow_cid, $allow_gid, $deny_cid, $deny_gid, $desc);
                        if (! $r) {
                                logger("photo upload: profile image upload with scale 6 (48x48) failed");
                        }
                }
-               $Image->__destruct();
+               $ph->__destruct();
                logger("photo upload: new profile image upload ended", LOGGER_DEBUG);
        }
 
index e1a67d432d261600cae885ed2185b422275288cd..3b1540473a31d2172218056afe68eafff56accd5 100644 (file)
@@ -2,8 +2,8 @@
 
 use Friendica\App;
 use Friendica\Core\System;
-use Friendica\Model\Contact;
 use Friendica\Network\Probe;
+use Friendica\Object\Contact;
 
 use League\HTMLToMarkdown\HtmlConverter;
 
index b445fd01b047b3370284b8e35bd53dded972c718..196c3ca3c1578e76bf3954ecf542aa53b6ec24b5 100644 (file)
@@ -5,7 +5,7 @@ use Friendica\Content\Smilies;
 use Friendica\Core\Cache;
 use Friendica\Core\System;
 use Friendica\Core\Config;
-use Friendica\Model\Contact;
+use Friendica\Object\Contact;
 
 require_once 'include/oembed.php';
 require_once 'include/event.php';
index 9c44f4d15695027027a5f756f8cfb93a1f62d92f..31e57ea839e56f9b95bbbfd868a33089eb3a99ef 100644 (file)
@@ -7,7 +7,7 @@ use Friendica\Core\System;
 use Friendica\Core\Config;
 use Friendica\Core\PConfig;
 use Friendica\Database\DBM;
-use Friendica\Model\GContact;
+use Friendica\Model\GlobalContact;
 
 require_once 'include/contact_selectors.php';
 
@@ -250,18 +250,18 @@ function common_friends_visitor_widget($profile_uid) {
        }
 
        if ($cid) {
-               $t = GContact::countCommonFriends($profile_uid, $cid);
+               $t = GlobalContact::countCommonFriends($profile_uid, $cid);
        } else {
-               $t = GContact::countCommonFriendsZcid($profile_uid, $zcid);
+               $t = GlobalContact::countCommonFriendsZcid($profile_uid, $zcid);
        }
        if (! $t) {
                return;
        }
 
        if ($cid) {
-               $r = GContact::commonFriends($profile_uid, $cid, 0, 5, true);
+               $r = GlobalContact::commonFriends($profile_uid, $cid, 0, 5, true);
        } else {
-               $r = GContact::commonFriendsZcid($profile_uid, $zcid, 0, 5, true);
+               $r = GlobalContact::commonFriendsZcid($profile_uid, $zcid, 0, 5, true);
        }
 
        return replace_macros(get_markup_template('remote_friends_common.tpl'), array(
index ce937a7a71d05e612a4b0f4f96ff6375f4e39a57..2543a5170e80ac6d1b198a2f0f31333396d0b7d2 100644 (file)
@@ -8,8 +8,8 @@ use Friendica\Core\Config;
 use Friendica\Core\PConfig;
 use Friendica\Core\System;
 use Friendica\Database\DBM;
-use Friendica\Model\Contact;
-use Friendica\Object\Thread;
+use Friendica\Object\Contact;
+use Friendica\Object\Conversation;
 use Friendica\Object\Item;
 
 require_once "include/bbcode.php";
@@ -840,7 +840,7 @@ function conversation(App $a, $items, $mode, $update, $preview = false) {
                        // Normal View
                        $page_template = get_markup_template("threaded_conversation.tpl");
 
-                       $conv = new Thread($mode, $preview);
+                       $conv = new Conversation($mode, $preview);
 
                        /*
                         * get all the topmost parents
@@ -881,7 +881,7 @@ function conversation(App $a, $items, $mode, $update, $preview = false) {
 
                                if ($item['id'] == $item['parent']) {
                                        $item_object = new Item($item);
-                                       $conv->addParent($item_object);
+                                       $conv->addThread($item_object);
                                }
                        }
 
index e08136cab1e925bf48d93a55cefb0945372c7663..14b9c68ed59fd3476154a2ec367ab84d63adde71 100644 (file)
@@ -7,8 +7,8 @@ use Friendica\Core\Config;
 use Friendica\Core\System;
 use Friendica\Core\Worker;
 use Friendica\Database\DBM;
-use Friendica\Model\Contact;
 use Friendica\Network\Probe;
+use Friendica\Object\Contact;
 use Friendica\Protocol\Diaspora;
 use Friendica\Protocol\OStatus;
 use Friendica\Protocol\PortableContact;
index 9a0900dc1f14db2fe74bf50d02228985a84c2291..a3a007cc18a12c0edf97239ce9f5ffc77898fac1 100644 (file)
@@ -12,7 +12,7 @@ use Friendica\Core\PConfig;
 use Friendica\Core\System;
 use Friendica\Core\Worker;
 use Friendica\Database\DBM;
-use Friendica\Model\Contact;
+use Friendica\Object\Contact;
 
 require_once 'include/bbcode.php';
 require_once 'mod/proxy.php';
index 0779ed91e19da00bf3f4eec2ac984f57cf37a3db..61a9c7a1fab5fab034050cd703a73f50df9b2e52 100644 (file)
@@ -10,11 +10,11 @@ use Friendica\Core\PConfig;
 use Friendica\Core\Worker;
 use Friendica\Core\System;
 use Friendica\Database\DBM;
-use Friendica\Model\Contact;
-use Friendica\Model\GContact;
-use Friendica\Object\Image;
+use Friendica\Model\GlobalContact;
+use Friendica\Object\Contact;
 use Friendica\Protocol\DFRN;
 use Friendica\Protocol\OStatus;
+use Friendica\Util\Lock;
 
 require_once 'include/bbcode.php';
 require_once 'include/oembed.php';
@@ -742,10 +742,10 @@ function item_store($arr, $force_parent = false, $notify = false, $dontcache = f
                 * On comments the author is the better choice.
                 */
                if ($arr['parent-uri'] === $arr['uri']) {
-                       $arr["gcontact-id"] = GContact::getId(array("url" => $arr['owner-link'], "network" => $arr['network'],
+                       $arr["gcontact-id"] = GlobalContact::getId(array("url" => $arr['owner-link'], "network" => $arr['network'],
                                                                 "photo" => $arr['owner-avatar'], "name" => $arr['owner-name']));
                } else {
-                       $arr["gcontact-id"] = GContact::getId(array("url" => $arr['author-link'], "network" => $arr['network'],
+                       $arr["gcontact-id"] = GlobalContact::getId(array("url" => $arr['author-link'], "network" => $arr['network'],
                                                                 "photo" => $arr['author-avatar'], "name" => $arr['author-name']));
                }
        }
@@ -1887,11 +1887,11 @@ function fix_private_photos($s, $uid, $item = null, $cid = 0) {
                                                        $width = intval($match[1]);
                                                        $height = intval($match[2]);
 
-                                                       $Image = new Image($data, $type);
-                                                       if ($Image->isValid()) {
-                                                               $Image->scaleDown(max($width, $height));
-                                                               $data = $Image->asString();
-                                                               $type = $Image->getType();
+                                                       $ph = new Photo($data, $type);
+                                                       if ($ph->isValid()) {
+                                                               $ph->scaleImage(max($width, $height));
+                                                               $data = $ph->imageString();
+                                                               $type = $ph->getType();
                                                        }
                                                }
 
index 9a8b9b957b0db24fd2d7f459eb5c24be1132ca4f..1dcadde705ef93e9885edf07a07af5509e75fa21 100644 (file)
@@ -4,7 +4,7 @@ use Friendica\App;
 use Friendica\Core\System;
 use Friendica\Core\Worker;
 use Friendica\Database\DBM;
-use Friendica\Model\Contact;
+use Friendica\Object\Contact;
 use Friendica\Protocol\Diaspora;
 
 /**
index 16c8185e1abb48b0fec1ada966fe06a0e9ffce35..45f5d4e79a9c4572e63d35bc88c92879a44f7661 100644 (file)
@@ -6,7 +6,7 @@ use Friendica\App;
 use Friendica\Core\System;
 use Friendica\Core\Config;
 use Friendica\Network\Probe;
-use Friendica\Object\Image;
+use Friendica\Object\Photo;
 use Friendica\Util\XML;
 
 /**
@@ -710,18 +710,18 @@ function scale_external_images($srctext, $include_link = true, $scale_replace =
                        }
 
                        // guess mimetype from headers or filename
-                       $type = Image::guessType($mtch[1], true);
+                       $type = Photo::guessImageType($mtch[1], true);
 
                        if ($i) {
-                               $Image = new Image($i, $type);
-                               if ($Image->isValid()) {
-                                       $orig_width = $Image->getWidth();
-                                       $orig_height = $Image->getHeight();
+                               $ph = new Photo($i, $type);
+                               if ($ph->isValid()) {
+                                       $orig_width = $ph->getWidth();
+                                       $orig_height = $ph->getHeight();
 
                                        if ($orig_width > 640 || $orig_height > 640) {
-                                               $Image->scaleDown(640);
-                                               $new_width = $Image->getWidth();
-                                               $new_height = $Image->getHeight();
+                                               $ph->scaleImage(640);
+                                               $new_width = $ph->getWidth();
+                                               $new_height = $ph->getHeight();
                                                logger('scale_external_images: ' . $orig_width . '->' . $new_width . 'w ' . $orig_height . '->' . $new_height . 'h' . ' match: ' . $mtch[0], LOGGER_DEBUG);
                                                $s = str_replace(
                                                        $mtch[0],
index 39dcc9ecdbd7d888cdc6c601bde0acc3570a4dd9..221d1471b1a7576fd8199e42108027037abf43d1 100644 (file)
@@ -5,7 +5,7 @@
 use Friendica\App;
 use Friendica\ParseUrl;
 use Friendica\Core\PConfig;
-use Friendica\Object\Image;
+use Friendica\Object\Photo;
 
 require_once "include/bbcode.php";
 require_once "include/html2plain.php";
@@ -51,7 +51,7 @@ function get_old_attachment_data($body) {
 
                        if (preg_match("/\[img\]([$URLSearchString]*)\[\/img\]/ism", $attacheddata, $matches)) {
 
-                               $picturedata = Image::getInfoFromURL($matches[1]);
+                               $picturedata = Photo::getInfoFromURL($matches[1]);
 
                                if (($picturedata[0] >= 500) && ($picturedata[0] >= $picturedata[1]))
                                        $post["image"] = $matches[1];
@@ -221,7 +221,7 @@ function get_attached_data($body, $item = array()) {
                                        $post["preview"] = $pictures[0][2];
                                        $post["text"] = str_replace($pictures[0][0], "", $body);
                                } else {
-                                       $imgdata = Image::getInfoFromURL($pictures[0][1]);
+                                       $imgdata = Photo::getInfoFromURL($pictures[0][1]);
                                        if (substr($imgdata["mime"], 0, 6) == "image/") {
                                                $post["type"] = "photo";
                                                $post["image"] = $pictures[0][1];
index 0d223709e2d506acdc743752d727510837cdd622..f67c064daf2f527f21bd9b5aed2e2523b80a9b83 100644 (file)
@@ -5,8 +5,8 @@
 
 use Friendica\Core\Config;
 use Friendica\Database\DBM;
-use Friendica\Model\Contact;
-use Friendica\Model\GContact;
+use Friendica\Model\GlobalContact;
+use Friendica\Object\Contact;
 
 /**
  * @brief Calls the post update functions
@@ -74,7 +74,7 @@ function post_update_1192() {
 
        // Set the "gcontact-id" in the item table and add a new gcontact entry if needed
        foreach ($item_arr AS $item) {
-               $gcontact_id = GContact::getId(array("url" => $item['author-link'], "network" => $item['network'],
+               $gcontact_id = GlobalContact::getId(array("url" => $item['author-link'], "network" => $item['network'],
                                                "photo" => $item['author-avatar'], "name" => $item['author-name']));
                q("UPDATE `item` SET `gcontact-id` = %d WHERE `uid` = %d AND `author-link` = '%s' AND `gcontact-id` = 0",
                        intval($gcontact_id), intval($item["uid"]), dbesc($item["author-link"]));
index 8d8fb765595ddd9f90f84325c94500db2abd0bc2..45a17f9c96791987d32465b44c557c105cba3572 100644 (file)
@@ -6,7 +6,7 @@ use Friendica\App;
 use Friendica\Content\Feature;
 use Friendica\Core\System;
 use Friendica\Database\DBM;
-use Friendica\Model\Contact;
+use Friendica\Object\Contact;
 
 function create_tags_from_item($itemid) {
        $profile_base = System::baseUrl();
@@ -157,13 +157,13 @@ function update_items() {
 /**
  * @brief Get alphabetical sorted array of used tags/terms of an user including
  * a weighting by frequency of use.
- *
+ * 
  * @param int $uid      The user ID.
  * @param int $count    Max number of displayed tags/terms.
  * @param int $owner_id The contact id of the owner of the tagged items.
  * @param string $flags Special item flags.
  * @param int $type     The tag/term type.
- *
+ * 
  * @return arr          Alphabetical sorted array of used tags of an user.
  */
 function tagadelic($uid, $count = 0, $owner_id = 0, $flags = '', $type = TERM_HASHTAG) {
@@ -197,19 +197,19 @@ function tagadelic($uid, $count = 0, $owner_id = 0, $flags = '', $type = TERM_HA
        if(!DBM::is_result($r)) {
                return array();
        }
-
+               
        return tag_calc($r);
 }
 
 /**
  * @brief Construct a tag/term cloud block for an user.
- *
+ * 
  * @param int $uid      The user ID.
  * @param int $count    Max number of displayed tags/terms.
  * @param int $owner_id The contact ID of the owner of the tagged items.
  * @param string $flags Special item flags.
  * @param int $type     The tag/term type.
- *
+ * 
  * @return string       HTML formatted output.
  */
 function wtagblock($uid, $count = 0,$owner_id = 0, $flags = '', $type = TERM_HASHTAG) {
@@ -244,7 +244,7 @@ function wtagblock($uid, $count = 0,$owner_id = 0, $flags = '', $type = TERM_HAS
 
 /**
  * @brief Calculate weighting of tags according to the frequency of use.
- *
+ * 
  * @param array $arr Array of tags/terms with tag/term name and total count of use.
  * @return array     Alphabetical sorted array of used tags/terms of an user.
  */
@@ -279,10 +279,10 @@ function tag_calc($arr) {
 
 /**
  * @brief Compare function to sort tags/terms alphabetically.
- *
+ * 
  * @param type $a
  * @param type $b
- *
+ * 
  * @return int
  */
 function tags_sort($a, $b) {
@@ -294,7 +294,7 @@ function tags_sort($a, $b) {
 
 /**
  * @brief Insert a tag cloud widget for the present profile.
- *
+ * 
  * @param int     $limit Max number of displayed tags.
  * @return string HTML formattat output.
  */
index 494fbe1ce33a0ccdecd127e13d52a0efa50c4e0b..00848ccc6e328e55a6c28c82719f9f8e56688f35 100644 (file)
@@ -3,7 +3,7 @@
 use Friendica\App;
 use Friendica\Core\System;
 use Friendica\Database\DBM;
-use Friendica\Model\Contact;
+use Friendica\Object\Contact;
 
 function add_thread($itemid, $onlyshadow = false) {
        $items = q("SELECT `uid`, `created`, `edited`, `commented`, `received`, `changed`, `wall`, `private`, `pubmail`,
index e3c2f4e6c1f69c0b67953cf895ffd55e30b0d558..7effcd62ddd9da5f05f74b81cf95f681e8945a5b 100644 (file)
@@ -7,8 +7,7 @@ use Friendica\Core\System;
 use Friendica\Core\PConfig;
 use Friendica\Core\Worker;
 use Friendica\Database\DBM;
-use Friendica\Model\Photo;
-use Friendica\Object\Image;
+use Friendica\Object\Photo;
 
 define("IMPORT_DEBUG", False);
 
@@ -261,9 +260,8 @@ function import_account(App $a, $file) {
                $photo['uid'] = $newuid;
                $photo['data'] = hex2bin($photo['data']);
 
-               $Image = new Image($photo['data'], $photo['type']);
-               $r = Photo::store(
-                               $Image,
+               $p = new Photo($photo['data'], $photo['type']);
+               $r = $p->store(
                                $photo['uid'], $photo['contact-id'], //0
                                $photo['resource-id'], $photo['filename'], $photo['album'], $photo['scale'], $photo['profile'], //1
                                $photo['allow_cid'], $photo['allow_gid'], $photo['deny_cid'], $photo['deny_gid']
index 321e7b617204576a1286afa891bbbda0e9b17d01..29e10bda8301088be9b97f74c196008b69d3b69a 100644 (file)
@@ -10,8 +10,8 @@ use Friendica\Core\System;
 use Friendica\Core\Config;
 use Friendica\Core\Worker;
 use Friendica\Database\DBM;
-use Friendica\Model\Contact;
 use Friendica\Model\User;
+use Friendica\Object\Contact;
 
 require_once 'include/enotify.php';
 require_once 'include/text.php';
index 1456661253ff25bfb44f2e94e45fb2f0474a618a..3cfe6c0f9efaa164cea1710ad55d02f438bade50 100644 (file)
@@ -5,8 +5,8 @@
 use Friendica\App;
 use Friendica\Core\System;
 use Friendica\Database\DBM;
-use Friendica\Model\Contact;
-use Friendica\Model\GContact;
+use Friendica\Model\GlobalContact;
+use Friendica\Object\Contact;
 
 require_once 'include/contact_selectors.php';
 require_once 'mod/contacts.php';
@@ -41,12 +41,12 @@ function allfriends_content(App $a) {
        $a->page['aside'] = "";
        profile_load($a, "", 0, Contact::getDetailsByURL($c[0]["url"]));
 
-       $total = GContact::countAllFriends(local_user(), $cid);
+       $total = GlobalContact::countAllFriends(local_user(), $cid);
 
        if(count($total))
                $a->set_pager_total($total);
 
-       $r = GContact::allFriends(local_user(), $cid, $a->pager['start'], $a->pager['itemspage']);
+       $r = GlobalContact::allFriends(local_user(), $cid, $a->pager['start'], $a->pager['itemspage']);
 
        if (! DBM::is_result($r)) {
                $o .= t('No friends to display.');
index cef9857ea934d84bf794682d2c4744453b6784c4..7eb31905b8ee80fb773dd26c6540bf8b971c03b3 100644 (file)
@@ -11,7 +11,7 @@ use Friendica\Core\Config;
 use Friendica\Core\PConfig;
 use Friendica\Core\System;
 use Friendica\Database\DBM;
-use Friendica\Model\Contact;
+use Friendica\Object\Contact;
 
 require_once 'include/event.php';
 require_once 'include/redir.php';
index 74b4dec7c6e8253bd11e2dbae7cb6e1a3c9f780a..9933c3f51fc2178a76a47bb9ef52f91d90852307 100644 (file)
@@ -4,8 +4,8 @@
  */
 use Friendica\App;
 use Friendica\Database\DBM;
-use Friendica\Model\Contact;
-use Friendica\Model\GContact;
+use Friendica\Model\GlobalContact;
+use Friendica\Object\Contact;
 
 require_once 'include/contact_selectors.php';
 require_once 'mod/contacts.php';
@@ -85,9 +85,9 @@ function common_content(App $a) {
        }
 
        if ($cid) {
-               $t = GContact::countCommonFriends($uid, $cid);
+               $t = GlobalContact::countCommonFriends($uid, $cid);
        } else {
-               $t = GContact::countCommonFriendsZcid($uid, $zcid);
+               $t = GlobalContact::countCommonFriendsZcid($uid, $zcid);
        }
 
        if (count($t)) {
@@ -99,9 +99,9 @@ function common_content(App $a) {
 
 
        if ($cid) {
-               $r = GContact::commonFriends($uid, $cid, $a->pager['start'], $a->pager['itemspage']);
+               $r = GlobalContact::commonFriends($uid, $cid, $a->pager['start'], $a->pager['itemspage']);
        } else {
-               $r = GContact::commonFriendsZcid($uid, $zcid, $a->pager['start'], $a->pager['itemspage']);
+               $r = GlobalContact::commonFriendsZcid($uid, $zcid, $a->pager['start'], $a->pager['itemspage']);
        }
 
 
index 71ffcc2d664745b36fd1e128a5c16fd514e88b0e..9feacaf5e38f2e2044f0fdd3aa06f4ed24f8b510 100644 (file)
@@ -6,9 +6,9 @@ use Friendica\App;
 use Friendica\Core\System;
 use Friendica\Core\Worker;
 use Friendica\Database\DBM;
-use Friendica\Model\Contact;
-use Friendica\Model\GContact;
+use Friendica\Model\GlobalContact;
 use Friendica\Network\Probe;
+use Friendica\Object\Contact;
 
 require_once 'include/contact_selectors.php';
 require_once 'mod/proxy.php';
@@ -313,7 +313,7 @@ function _contact_update_profile($contact_id) {
        Contact::updateAvatar($data['photo'], local_user(), $contact_id, true);
 
        // Update the entry in the gcontact table
-       GContact::updateFromProbe($data["url"]);
+       GlobalContact::updateFromProbe($data["url"]);
 }
 
 function _contact_block($contact_id, $orig_record) {
@@ -887,7 +887,7 @@ function contacts_tab($a, $contact_id, $active_tab) {
        );
 
        // Show this tab only if there is visible friend list
-       $x = GContact::countAllFriends(local_user(), $contact_id);
+       $x = GlobalContact::countAllFriends(local_user(), $contact_id);
        if ($x)
                $tabs[] = array('label'=>t('Contacts'),
                                'url' => "allfriends/".$contact_id,
@@ -897,7 +897,7 @@ function contacts_tab($a, $contact_id, $active_tab) {
                                'accesskey' => 't');
 
        // Show this tab only if there is visible common friend list
-       $common = GContact::countCommonFriends(local_user(), $contact_id);
+       $common = GlobalContact::countCommonFriends(local_user(), $contact_id);
        if ($common)
                $tabs[] = array('label'=>t('Common Friends'),
                                'url' => "common/loc/".local_user()."/".$contact_id,
index 32db9be92ca6b526735d31afccb1cd2e369427c3..7e1921f304124539d84a3114e5c6cbfd27c6b90b 100644 (file)
@@ -5,7 +5,7 @@
 use Friendica\App;
 use Friendica\Core\Config;
 use Friendica\Database\DBM;
-use Friendica\Model\Contact;
+use Friendica\Object\Contact;
 
 require_once 'include/contact_selectors.php';
 require_once 'mod/contacts.php';
index c999013eff121007f427610591ea21b1b56f40d0..18d9f25bf598c2a40b2fc938e46de4b4434808d0 100644 (file)
@@ -24,8 +24,8 @@ use Friendica\Core\PConfig;
 use Friendica\Core\System;
 use Friendica\Core\Worker;
 use Friendica\Database\DBM;
-use Friendica\Model\Contact;
 use Friendica\Network\Probe;
+use Friendica\Object\Contact;
 use Friendica\Protocol\Diaspora;
 
 require_once 'include/enotify.php';
index b81f26db9df41219ffd28f1271756c150c40e81c..61be7966e06b95a036a59bab13d318a08edbb1b1 100644 (file)
@@ -9,7 +9,7 @@
 use Friendica\App;
 use Friendica\Core\Config;
 use Friendica\Database\DBM;
-use Friendica\Model\Contact;
+use Friendica\Object\Contact;
 use Friendica\Protocol\DFRN;
 
 require_once 'include/items.php';
index bff1464ae47a1cb41db4e0750c9d3dca01ebbf17..67395a9fcc714abb740ab9eecf15e1ac5177d278 100644 (file)
@@ -15,8 +15,8 @@ use Friendica\Core\Config;
 use Friendica\Core\PConfig;
 use Friendica\Core\System;
 use Friendica\Database\DBM;
-use Friendica\Model\Contact;
 use Friendica\Network\Probe;
+use Friendica\Object\Contact;
 
 require_once 'include/enotify.php';
 require_once 'include/group.php';
index f29e3eb69ba8e057fa375a71d25a3e42de83276d..d8ad6aeaba9c64c3039c54c2e61033ad8aed4188 100644 (file)
@@ -3,7 +3,7 @@
 use Friendica\App;
 use Friendica\Core\Config;
 use Friendica\Database\DBM;
-use Friendica\Model\Contact;
+use Friendica\Object\Contact;
 
 function directory_init(App $a) {
        $a->set_pager_itemspage(60);
index bef89a4794ce1f74b0bf7da01cdd3b74244a9792..4ba122b566e278f3ac7f72941b2e0f97a09184ca 100644 (file)
@@ -6,9 +6,9 @@ use Friendica\App;
 use Friendica\Core\Config;
 use Friendica\Core\System;
 use Friendica\Core\Worker;
-use Friendica\Model\Contact;
-use Friendica\Model\GContact;
+use Friendica\Model\GlobalContact;
 use Friendica\Network\Probe;
+use Friendica\Object\Contact;
 use Friendica\Protocol\PortableContact;
 
 require_once 'include/contact_widgets.php';
@@ -82,7 +82,7 @@ function dirfind_content(App $a, $prefix = "") {
 
                        // Add the contact to the global contacts if it isn't already in our system
                        if (($contact["cid"] == 0) && ($contact["zid"] == 0) && ($contact["gid"] == 0)) {
-                               GContact::update($user_data);
+                               GlobalContact::update($user_data);
                        }
                } elseif ($local) {
 
index 2d22637ece0278e882c741efad75a09ae27a9d24..e81e654acb5528e2327d9c94a2d5d10c317d01be 100644 (file)
@@ -4,7 +4,7 @@ use Friendica\App;
 use Friendica\Core\Config;
 use Friendica\Core\System;
 use Friendica\Database\DBM;
-use Friendica\Model\Contact;
+use Friendica\Object\Contact;
 use Friendica\Protocol\DFRN;
 
 function display_init(App $a) {
index 3297dd918b0a74567362670cd1afcdda2d02a93a..516be5298725298455981c53d80d4ea2ab93c80a 100644 (file)
@@ -7,7 +7,7 @@
 
 use Friendica\App;
 use Friendica\Core\System;
-use Friendica\Object\Image;
+use Friendica\Object\Photo;
 
 /**
  * @param App $a
@@ -66,7 +66,7 @@ function fbrowser_content(App $a) {
 
                        function _map_files1($rr){
                                $a = get_app();
-                               $types = Image::supportedTypes();
+                               $types = Photo::supportedTypes();
                                $ext = $types[$rr['type']];
                                $filename_e = $rr['filename'];
 
index f0cffff4a1afb860e8dc0b8e05d52b7fcbc98ba8..b5e73ca9a44676be10b9f46d4c820ca4a14891ea 100644 (file)
@@ -3,8 +3,8 @@
 use Friendica\App;
 use Friendica\Core\Config;
 use Friendica\Core\System;
-use Friendica\Model\Contact;
 use Friendica\Network\Probe;
+use Friendica\Object\Contact;
 
 require_once 'include/follow.php';
 require_once 'include/contact_selectors.php';
index 8ad5cd0ebe14b404cede665a96b96db0c059f246..5542fe5b9837738da8f93fec7b6d525b5c4ae746 100644 (file)
@@ -10,8 +10,8 @@
 
 use Friendica\App;
 use Friendica\Core\Config;
-use Friendica\Model\Contact;
-use Friendica\Model\GContact;
+use Friendica\Model\GlobalContact;
+use Friendica\Object\Contact;
 
 function hovercard_init(App $a) {
        // Just for testing purposes
@@ -47,7 +47,7 @@ function hovercard_content() {
        }
 
        // if it's the url containing https it should be converted to http
-       $nurl = normalise_link(GContact::cleanContactUrl($profileurl));
+       $nurl = normalise_link(GlobalContact::cleanContactUrl($profileurl));
        if($nurl) {
                // Search for contact data
                $contact = Contact::getDetailsByURL($nurl);
index 8df5d09352c8f84404038f783b2f4499bd7c3bea..0da8ec040f2a11d59bd587a033cc51b87cc2fe2f 100644 (file)
@@ -5,7 +5,7 @@
 use Friendica\App;
 use Friendica\Core\System;
 use Friendica\Database\DBM;
-use Friendica\Object\Image;
+use Friendica\Object\Photo;
 
 $install_wizard_pass = 1;
 
@@ -503,7 +503,7 @@ function check_imagik(&$checks) {
 
        if (class_exists('Imagick')) {
                $imagick = true;
-               $supported = Image::supportedTypes();
+               $supported = Photo::supportedTypes();
                if (array_key_exists('image/gif', $supported)) {
                        $gif = true;
                }
index c35a48b7e71173ddb6ab56b0df04974294052955..ffac1c8e445deb4dddb6c824212d77d83b7bb3fe 100644 (file)
@@ -22,9 +22,9 @@ use Friendica\Core\Config;
 use Friendica\Core\System;
 use Friendica\Core\Worker;
 use Friendica\Database\DBM;
-use Friendica\Model\Contact;
-use Friendica\Model\GContact;
+use Friendica\Model\GlobalContact;
 use Friendica\Network\Probe;
+use Friendica\Object\Contact;
 use Friendica\Protocol\Diaspora;
 use Friendica\Protocol\Email;
 use Friendica\Util\Emailer;
@@ -743,7 +743,7 @@ function item_post(App $a) {
        $datarray['postopts']      = $postopts;
        $datarray['origin']        = $origin;
        $datarray['moderated']     = $allow_moderated;
-       $datarray['gcontact-id']   = GContact::getId(array("url" => $datarray['author-link'], "network" => $datarray['network'],
+       $datarray['gcontact-id']   = GlobalContact::getId(array("url" => $datarray['author-link'], "network" => $datarray['network'],
                                                        "photo" => $datarray['author-avatar'], "name" => $datarray['author-name']));
        $datarray['object']        = $object;
 
@@ -1244,7 +1244,7 @@ function handle_tag(App $a, &$body, &$inform, &$str_tags, $profile_uid, $tag, $n
                        if (!DBM::is_result($r)) {
                                $probed = Probe::uri($name);
                                if ($result['network'] != NETWORK_PHANTOM) {
-                                       GContact::update($probed);
+                                       GlobalContact::update($probed);
                                        $r = q("SELECT `url`, `name`, `nick`, `network`, `alias`, `notify` FROM `gcontact` WHERE `nurl` = '%s' LIMIT 1",
                                                dbesc(normalise_link($probed["url"])));
                                }
index 563ce5bedcbcb3aaac8190b6edf553cf7f5bd8ee..3a0d10c3191873f05590bdbdf6aece32209bf629 100644 (file)
@@ -6,7 +6,7 @@ use Friendica\App;
 use Friendica\Core\Config;
 use Friendica\Core\System;
 use Friendica\Database\DBM;
-use Friendica\Model\Contact;
+use Friendica\Object\Contact;
 
 require_once 'include/text.php';
 require_once 'include/contact_widgets.php';
index 7bb17f39068011e63d7241caf6a9c6cd546cf917..cefc44356f34a01101f1942ffa35c3e6444cd77c 100644 (file)
@@ -4,7 +4,7 @@ use Friendica\App;
 use Friendica\Content\Smilies;
 use Friendica\Core\System;
 use Friendica\Database\DBM;
-use Friendica\Model\Contact;
+use Friendica\Object\Contact;
 
 require_once 'include/acl_selectors.php';
 require_once 'include/message.php';
index 3ac13b24e01c76a359d5a0e4e5e8ec39d878ffbe..7e61d083f68d8e87f338ce7ac323dc8b2bca19d8 100644 (file)
@@ -9,7 +9,7 @@ use Friendica\Core\System;
 use Friendica\Core\Config;
 use Friendica\Core\PConfig;
 use Friendica\Database\DBM;
-use Friendica\Model\Contact;
+use Friendica\Object\Contact;
 
 require_once 'include/conversation.php';
 require_once 'include/group.php';
index d7df8cb187d75c5b4af48fb018e5d573baa4d0c4..5fb9afc2ac48c77e1a2d5135994e597ddc326cc9 100644 (file)
@@ -4,7 +4,7 @@
  */
 use Friendica\App;
 use Friendica\Database\DBM;
-use Friendica\Model\Contact;
+use Friendica\Object\Contact;
 
 require_once 'include/contact_selectors.php';
 
index 243dfda029b03b47ff350fece6cf0091e70096e0..8368b99a6b99f4ff13f66e5817b8fd3f1bddba81 100644 (file)
@@ -4,7 +4,7 @@
  */
 use Friendica\App;
 use Friendica\Database\DBM;
-use Friendica\Object\Image;
+use Friendica\Object\Photo;
 
 require_once 'include/security.php';
 
@@ -75,7 +75,7 @@ function photo_init(App $a) {
 
                $uid = str_replace(array('.jpg', '.png', '.gif'), array('', '', ''), $person);
 
-               foreach (Image::supportedTypes() AS $m => $e) {
+               foreach (Photo::supportedTypes() AS $m => $e) {
                        $uid = str_replace('.'.$e, '', $uid);
                }
 
@@ -100,7 +100,7 @@ function photo_init(App $a) {
                $resolution = 0;
                $photo = str_replace(array('.jpg', '.png', '.gif'), array('', '', ''), $photo);
 
-               foreach (Image::supportedTypes() AS $m => $e) {
+               foreach (Photo::supportedTypes() AS $m => $e) {
                        $photo = str_replace('.'.$e, '', $photo);
                }
 
@@ -167,14 +167,14 @@ function photo_init(App $a) {
        }
 
        // Resize only if its not a GIF and it is supported by the library
-       if (($mimetype != "image/gif") && in_array($mimetype, Image::supportedTypes())) {
-               $Image = new Image($data, $mimetype);
-               if ($Image->isValid()) {
+       if (($mimetype != "image/gif") && in_array($mimetype, Photo::supportedTypes())) {
+               $ph = new Photo($data, $mimetype);
+               if ($ph->isValid()) {
                        if (isset($customres) && $customres > 0 && $customres < 500) {
-                               $Image->scaleToSquare($customres);
+                               $ph->scaleImageSquare($customres);
                        }
-                       $data = $Image->asString();
-                       $mimetype = $Image->getType();
+                       $data = $ph->imageString();
+                       $mimetype = $ph->getType();
                }
        }
 
index cc3ec71a658a940127b31b8264bc105b4dce43d6..3e2c44e3cd9a70292d6babccd36a26a23b8004d0 100644 (file)
@@ -8,10 +8,9 @@ use Friendica\Core\System;
 use Friendica\Core\Config;
 use Friendica\Core\Worker;
 use Friendica\Database\DBM;
-use Friendica\Model\Contact;
-use Friendica\Model\Photo;
 use Friendica\Network\Probe;
-use Friendica\Object\Image;
+use Friendica\Object\Contact;
+use Friendica\Object\Photo;
 
 require_once 'include/photos.php';
 require_once 'include/items.php';
@@ -137,7 +136,7 @@ function photos_post(App $a) {
        logger('mod_photos: REQUEST ' . print_r($_REQUEST,true), LOGGER_DATA);
        logger('mod_photos: FILES '   . print_r($_FILES,true), LOGGER_DATA);
 
-       $phototypes = Image::supportedTypes();
+       $phototypes = Photo::supportedTypes();
 
        $can_post  = false;
        $visitor   = 0;
@@ -425,16 +424,16 @@ function photos_post(App $a) {
                                intval($page_owner_uid)
                        );
                        if (DBM::is_result($r)) {
-                               $Image = new Image($r[0]['data'], $r[0]['type']);
-                               if ($Image->isValid()) {
+                               $ph = new Photo($r[0]['data'], $r[0]['type']);
+                               if ($ph->isValid()) {
                                        $rotate_deg = ( (intval($_POST['rotate']) == 1) ? 270 : 90 );
-                                       $Image->rotate($rotate_deg);
+                                       $ph->rotate($rotate_deg);
 
-                                       $width  = $Image->getWidth();
-                                       $height = $Image->getHeight();
+                                       $width  = $ph->getWidth();
+                                       $height = $ph->getHeight();
 
                                        $x = q("UPDATE `photo` SET `data` = '%s', `height` = %d, `width` = %d WHERE `resource-id` = '%s' AND `uid` = %d AND `scale` = 0",
-                                               dbesc($Image->asString()),
+                                               dbesc($ph->imageString()),
                                                intval($height),
                                                intval($width),
                                                dbesc($resource_id),
@@ -442,12 +441,12 @@ function photos_post(App $a) {
                                        );
 
                                        if ($width > 640 || $height > 640) {
-                                               $Image->scaleDown(640);
-                                               $width  = $Image->getWidth();
-                                               $height = $Image->getHeight();
+                                               $ph->scaleImage(640);
+                                               $width  = $ph->getWidth();
+                                               $height = $ph->getHeight();
 
                                                $x = q("UPDATE `photo` SET `data` = '%s', `height` = %d, `width` = %d WHERE `resource-id` = '%s' AND `uid` = %d AND `scale` = 1",
-                                                       dbesc($Image->asString()),
+                                                       dbesc($ph->imageString()),
                                                        intval($height),
                                                        intval($width),
                                                        dbesc($resource_id),
@@ -456,12 +455,12 @@ function photos_post(App $a) {
                                        }
 
                                        if ($width > 320 || $height > 320) {
-                                               $Image->scaleDown(320);
-                                               $width  = $Image->getWidth();
-                                               $height = $Image->getHeight();
+                                               $ph->scaleImage(320);
+                                               $width  = $ph->getWidth();
+                                               $height = $ph->getHeight();
 
                                                $x = q("UPDATE `photo` SET `data` = '%s', `height` = %d, `width` = %d WHERE `resource-id` = '%s' AND `uid` = %d AND `scale` = 2",
-                                                       dbesc($Image->asString()),
+                                                       dbesc($ph->imageString()),
                                                        intval($height),
                                                        intval($width),
                                                        dbesc($resource_id),
@@ -812,7 +811,7 @@ function photos_post(App $a) {
                $type       = $_FILES['userfile']['type'];
        }
        if ($type == "") {
-               $type = Image::guessType($filename);
+               $type = Photo::guessImageType($filename);
        }
 
        logger('photos: upload: received file: ' . $filename . ' as ' . $src . ' ('. $type . ') ' . $filesize . ' bytes', LOGGER_DEBUG);
@@ -839,9 +838,9 @@ function photos_post(App $a) {
 
        $imagedata = @file_get_contents($src);
 
-       $Image = new Image($imagedata, $type);
+       $ph = new Photo($imagedata, $type);
 
-       if (! $Image->isValid()) {
+       if (! $ph->isValid()) {
                logger('mod/photos.php: photos_post(): unable to process image' , LOGGER_DEBUG);
                notice( t('Unable to process image.') . EOL );
                @unlink($src);
@@ -850,7 +849,7 @@ function photos_post(App $a) {
                killme();
        }
 
-       $exif = $Image->orient($src);
+       $exif = $ph->orient($src);
        @unlink($src);
 
        $max_length = Config::get('system', 'max_image_length');
@@ -858,17 +857,17 @@ function photos_post(App $a) {
                $max_length = MAX_IMAGE_LENGTH;
        }
        if ($max_length > 0) {
-               $Image->scaleDown($max_length);
+               $ph->scaleImage($max_length);
        }
 
-       $width  = $Image->getWidth();
-       $height = $Image->getHeight();
+       $width  = $ph->getWidth();
+       $height = $ph->getHeight();
 
        $smallest = 0;
 
        $photo_hash = photo_new_resource();
 
-       $r = Photo::store($Image, $page_owner_uid, $visitor, $photo_hash, $filename, $album, 0 , 0, $str_contact_allow, $str_group_allow, $str_contact_deny, $str_group_deny);
+       $r = $ph->store($page_owner_uid, $visitor, $photo_hash, $filename, $album, 0 , 0, $str_contact_allow, $str_group_allow, $str_contact_deny, $str_group_deny);
 
        if (! $r) {
                logger('mod/photos.php: photos_post(): image store failed' , LOGGER_DEBUG);
@@ -877,14 +876,14 @@ function photos_post(App $a) {
        }
 
        if ($width > 640 || $height > 640) {
-               $Image->scaleDown(640);
-               Photo::store($Image, $page_owner_uid, $visitor, $photo_hash, $filename, $album, 1, 0, $str_contact_allow, $str_group_allow, $str_contact_deny, $str_group_deny);
+               $ph->scaleImage(640);
+               $ph->store($page_owner_uid, $visitor, $photo_hash, $filename, $album, 1, 0, $str_contact_allow, $str_group_allow, $str_contact_deny, $str_group_deny);
                $smallest = 1;
        }
 
        if ($width > 320 || $height > 320) {
-               $Image->scaleDown(320);
-               Photo::store($Image, $page_owner_uid, $visitor, $photo_hash, $filename, $album, 2, 0, $str_contact_allow, $str_group_allow, $str_contact_deny, $str_group_deny);
+               $ph->scaleImage(320);
+               $ph->store($page_owner_uid, $visitor, $photo_hash, $filename, $album, 2, 0, $str_contact_allow, $str_group_allow, $str_contact_deny, $str_group_deny);
                $smallest = 2;
        }
 
@@ -933,7 +932,7 @@ function photos_post(App $a) {
        $arr['origin']        = 1;
 
        $arr['body']          = '[url=' . System::baseUrl() . '/photos/' . $owner_record['nickname'] . '/image/' . $photo_hash . ']'
-                               . '[img]' . System::baseUrl() . "/photo/{$photo_hash}-{$smallest}.".$Image->getExt() . '[/img]'
+                               . '[img]' . System::baseUrl() . "/photo/{$photo_hash}-{$smallest}.".$ph->getExt() . '[/img]'
                                . '[/url]';
 
        $item_id = item_store($arr);
@@ -981,7 +980,7 @@ function photos_content(App $a) {
                return;
        }
 
-       $phototypes = Image::supportedTypes();
+       $phototypes = Photo::supportedTypes();
 
        $_SESSION['photo_return'] = $a->cmd;
 
index 883129d14f1c22f2215e0de4e22ccba07dd60d8d..0f2a9584b863daf54454370990e53b29fb007f62 100644 (file)
@@ -9,7 +9,7 @@ use Friendica\Core\Cache;
 use Friendica\Core\System;
 use Friendica\Core\PConfig;
 use Friendica\Database\DBM;
-use Friendica\Model\Contact;
+use Friendica\Object\Contact;
 use Friendica\Util\XML;
 
 require_once 'include/datetime.php';
index e12c6e5c646b6a56111d3b289a42414363a3d41d..f667359b5184a18ba515167b418628a9b21e81ec 100644 (file)
@@ -7,8 +7,7 @@ use Friendica\Core\Config;
 use Friendica\Core\System;
 use Friendica\Core\Worker;
 use Friendica\Database\DBM;
-use Friendica\Model\Photo;
-use Friendica\Object\Image;
+use Friendica\Object\Photo;
 
 function profile_photo_init(App $a) {
 
@@ -73,27 +72,27 @@ function profile_photo_post(App $a) {
 
                        $base_image = $r[0];
 
-                       $Image = new Image($base_image['data'], $base_image['type']);
-                       if ($Image->isValid()) {
-                               $Image->crop(175,$srcX,$srcY,$srcW,$srcH);
+                       $im = new Photo($base_image['data'], $base_image['type']);
+                       if ($im->isValid()) {
+                               $im->cropImage(175,$srcX,$srcY,$srcW,$srcH);
 
-                               $r = Photo::store($Image, local_user(), 0, $base_image['resource-id'],$base_image['filename'], t('Profile Photos'), 4, $is_default_profile);
+                               $r = $im->store(local_user(), 0, $base_image['resource-id'],$base_image['filename'], t('Profile Photos'), 4, $is_default_profile);
 
                                if ($r === false) {
                                        notice ( sprintf(t('Image size reduction [%s] failed.'),"175") . EOL );
                                }
 
-                               $Image->scaleDown(80);
+                               $im->scaleImage(80);
 
-                               $r = Photo::store($Image, local_user(), 0, $base_image['resource-id'],$base_image['filename'], t('Profile Photos'), 5, $is_default_profile);
+                               $r = $im->store(local_user(), 0, $base_image['resource-id'],$base_image['filename'], t('Profile Photos'), 5, $is_default_profile);
 
                                if ($r === false) {
                                        notice( sprintf(t('Image size reduction [%s] failed.'),"80") . EOL );
                                }
 
-                               $Image->scaleDown(48);
+                               $im->scaleImage(48);
 
-                               $r = Photo::store($Image, local_user(), 0, $base_image['resource-id'],$base_image['filename'], t('Profile Photos'), 6, $is_default_profile);
+                               $r = $im->store(local_user(), 0, $base_image['resource-id'],$base_image['filename'], t('Profile Photos'), 6, $is_default_profile);
 
                                if ($r === false) {
                                        notice( sprintf(t('Image size reduction [%s] failed.'),"48") . EOL );
@@ -108,15 +107,15 @@ function profile_photo_post(App $a) {
                                        );
 
                                        $r = q("UPDATE `contact` SET `photo` = '%s', `thumb` = '%s', `micro` = '%s'  WHERE `self` AND `uid` = %d",
-                                               dbesc(System::baseUrl() . '/photo/' . $base_image['resource-id'] . '-4.' . $Image->getExt()),
-                                               dbesc(System::baseUrl() . '/photo/' . $base_image['resource-id'] . '-5.' . $Image->getExt()),
-                                               dbesc(System::baseUrl() . '/photo/' . $base_image['resource-id'] . '-6.' . $Image->getExt()),
+                                               dbesc(System::baseUrl() . '/photo/' . $base_image['resource-id'] . '-4.' . $im->getExt()),
+                                               dbesc(System::baseUrl() . '/photo/' . $base_image['resource-id'] . '-5.' . $im->getExt()),
+                                               dbesc(System::baseUrl() . '/photo/' . $base_image['resource-id'] . '-6.' . $im->getExt()),
                                                intval(local_user())
                                        );
                                } else {
                                        $r = q("update profile set photo = '%s', thumb = '%s' where id = %d and uid = %d",
-                                               dbesc(System::baseUrl() . '/photo/' . $base_image['resource-id'] . '-4.' . $Image->getExt()),
-                                               dbesc(System::baseUrl() . '/photo/' . $base_image['resource-id'] . '-5.' . $Image->getExt()),
+                                               dbesc(System::baseUrl() . '/photo/' . $base_image['resource-id'] . '-4.' . $im->getExt()),
+                                               dbesc(System::baseUrl() . '/photo/' . $base_image['resource-id'] . '-5.' . $im->getExt()),
                                                intval($_REQUEST['profile']),
                                                intval(local_user())
                                        );
@@ -152,7 +151,7 @@ function profile_photo_post(App $a) {
        $filesize = intval($_FILES['userfile']['size']);
        $filetype = $_FILES['userfile']['type'];
        if ($filetype == "") {
-               $filetype = Image::guessType($filename);
+               $filetype = Photo::guessImageType($filename);
        }
 
        $maximagesize = Config::get('system', 'maximagesize');
@@ -164,7 +163,7 @@ function profile_photo_post(App $a) {
        }
 
        $imagedata = @file_get_contents($src);
-       $ph = new Image($imagedata, $filetype);
+       $ph = new Photo($imagedata, $filetype);
 
        if (! $ph->isValid()) {
                notice(t('Unable to process image.') . EOL);
@@ -240,7 +239,7 @@ function profile_photo_content(App $a) {
                        goaway(System::baseUrl() . '/profiles');
                        return; // NOTREACHED
                }
-               $ph = new Image($r[0]['data'], $r[0]['type']);
+               $ph = new Photo($r[0]['data'], $r[0]['type']);
                profile_photo_crop_ui_head($a, $ph);
                // go ahead as we have jus uploaded a new photo to crop
        }
@@ -289,22 +288,22 @@ function profile_photo_content(App $a) {
 
 
 if(! function_exists('profile_photo_crop_ui_head')) {
-function profile_photo_crop_ui_head(App $a, Image $Image) {
+function profile_photo_crop_ui_head(App $a, $ph) {
        $max_length = Config::get('system','max_image_length');
        if (! $max_length) {
                $max_length = MAX_IMAGE_LENGTH;
        }
        if ($max_length > 0) {
-               $Image->scaleDown($max_length);
+               $ph->scaleImage($max_length);
        }
 
-       $width = $Image->getWidth();
-       $height = $Image->getHeight();
+       $width = $ph->getWidth();
+       $height = $ph->getHeight();
 
        if ($width < 175 || $height < 175) {
-               $Image->scaleUp(200);
-               $width = $Image->getWidth();
-               $height = $Image->getHeight();
+               $ph->scaleImageUp(200);
+               $width = $ph->getWidth();
+               $height = $ph->getHeight();
        }
 
        $hash = photo_new_resource();
@@ -312,7 +311,7 @@ function profile_photo_crop_ui_head(App $a, Image $Image) {
 
        $smallest = 0;
 
-       $r = Photo::store($Image, local_user(), 0 , $hash, $filename, t('Profile Photos'), 0 );
+       $r = $ph->store(local_user(), 0 , $hash, $filename, t('Profile Photos'), 0 );
 
        if ($r) {
                info( t('Image uploaded successfully.') . EOL );
@@ -321,8 +320,8 @@ function profile_photo_crop_ui_head(App $a, Image $Image) {
        }
 
        if ($width > 640 || $height > 640) {
-               $Image->scaleDown(640);
-               $r = Photo::store($Image, local_user(), 0 , $hash, $filename, t('Profile Photos'), 1 );
+               $ph->scaleImage(640);
+               $r = $ph->store(local_user(), 0 , $hash, $filename, t('Profile Photos'), 1 );
 
                if ($r === false) {
                        notice( sprintf(t('Image size reduction [%s] failed.'),"640") . EOL );
@@ -333,7 +332,7 @@ function profile_photo_crop_ui_head(App $a, Image $Image) {
 
        $a->config['imagecrop'] = $hash;
        $a->config['imagecrop_resolution'] = $smallest;
-       $a->config['imagecrop_ext'] = $Image->getExt();
+       $a->config['imagecrop_ext'] = $ph->getExt();
        $a->page['htmlhead'] .= replace_macros(get_markup_template("crophead.tpl"), array());
        $a->page['end'] .= replace_macros(get_markup_template("cropend.tpl"), array());
        return;
index 893f0d51e34ba35cdd2e2271a93df29fffb383fc..eca13bf10c087ce80028f0aa1b4b2eaef0db9240 100644 (file)
@@ -9,9 +9,9 @@ use Friendica\Core\PConfig;
 use Friendica\Core\System;
 use Friendica\Core\Worker;
 use Friendica\Database\DBM;
-use Friendica\Model\GContact;
-use Friendica\Model\Profile;
+use Friendica\Model\GlobalContact;
 use Friendica\Network\Probe;
+use Friendica\Object\Profile;
 
 function profiles_init(App $a) {
 
@@ -509,7 +509,7 @@ function profiles_post(App $a) {
                        Worker::add(PRIORITY_LOW, 'ProfileUpdate', local_user());
 
                        // Update the global contact for the user
-                       GContact::updateForUser(local_user());
+                       GlobalContact::updateForUser(local_user());
                }
        }
 }
index e134565ce023e7c17e3a40a406aa067899f02b0c..790309c62769d4cea2ff235a02299cc544d074c2 100644 (file)
@@ -8,8 +8,7 @@ use Friendica\App;
 use Friendica\Core\Config;
 use Friendica\Core\System;
 use Friendica\Database\DBM;
-use Friendica\Model\Photo;
-use Friendica\Object\Image;
+use Friendica\Object\Photo;
 
 define('PROXY_DEFAULT_TIME', 86400); // 1 Day
 
@@ -131,9 +130,9 @@ function proxy_init(App $a) {
 
                        // reduce quality - if it isn't a GIF
                        if ($mime != 'image/gif') {
-                               $Image = new Image($img_str, $mime);
-                               if ($Image->isValid()) {
-                                       $img_str = $Image->asString();
+                               $img = new Photo($img_str, $mime);
+                               if ($img->isValid()) {
+                                       $img_str = $img->imageString();
                                }
                        }
 
@@ -175,10 +174,10 @@ function proxy_init(App $a) {
                        $mime = 'image/png';
                        $cachefile = ''; // Clear the cachefile so that the dummy isn't stored
                        $valid = false;
-                       $Image = new Image($img_str, 'image/png');
-                       if ($Image->isValid()) {
-                               $Image->scaleDown(10);
-                               $img_str = $Image->asString();
+                       $img = new Photo($img_str, 'image/png');
+                       if ($img->isValid()) {
+                               $img->scaleImage(10);
+                               $img_str = $img->imageString();
                        }
                } elseif ($mime != 'image/jpeg' && !$direct_cache && $cachefile == '') {
                        $image = @imagecreatefromstring($img_str);
@@ -193,9 +192,9 @@ function proxy_init(App $a) {
                                'allow_cid' => '', 'allow_gid' => '', 'deny_cid' => '', 'deny_gid' => '', 'desc' => $mime);
                        dba::insert('photo', $fields);
                } else {
-                       $Image = new Image($img_str, $mime);
-                       if ($Image->isValid() && !$direct_cache && ($cachefile == '')) {
-                               Photo::store($Image, 0, 0, $urlhash, $_REQUEST['url'], '', 100);
+                       $img = new Photo($img_str, $mime);
+                       if ($img->isValid() && !$direct_cache && ($cachefile == '')) {
+                               $img->store(0, 0, $urlhash, $_REQUEST['url'], '', 100);
                        }
                }
        }
@@ -204,10 +203,10 @@ function proxy_init(App $a) {
 
        // reduce quality - if it isn't a GIF
        if ($mime != 'image/gif') {
-               $Image = new Image($img_str, $mime);
-               if ($Image->isValid()) {
-                       $Image->scaleDown($size);
-                       $img_str = $Image->asString();
+               $img = new Photo($img_str, $mime);
+               if ($img->isValid()) {
+                       $img->scaleImage($size);
+                       $img_str = $img->imageString();
                }
        }
 
index 40ad09271d67b25811c3c1ffff10ba250b83ca38..38d05c53e4308814b1a85ea28f468afe4dd93646 100644 (file)
@@ -2,10 +2,10 @@
 
 use Friendica\App;
 use Friendica\Core\System;
-use Friendica\Model\GContact;
+use Friendica\Model\GlobalContact;
 
 function randprof_init(App $a) {
-       $x = GContact::getRandomUrl();
+       $x = GlobalContact::getRandomUrl();
 
        if ($x) {
                goaway(zrl($x));
index 5f14c82835889a7a56a2819cb6923ea5b65be3cf..778a1d8a772dcc01900b9bcae7762f64a31077b1 100644 (file)
@@ -9,7 +9,7 @@ use Friendica\Core\Worker;
 use Friendica\Core\Config;
 use Friendica\Core\PConfig;
 use Friendica\Database\DBM;
-use Friendica\Model\GContact;
+use Friendica\Model\GlobalContact;
 use Friendica\Model\User;
 use Friendica\Protocol\Email;
 
@@ -650,7 +650,7 @@ function settings_post(App $a) {
        Worker::add(PRIORITY_LOW, 'ProfileUpdate', local_user());
 
        // Update the global contact for the user
-       GContact::updateForUser(local_user());
+       GlobalContact::updateForUser(local_user());
 
        //$_SESSION['theme'] = $theme;
        if ($email_changed && $a->config['register_policy'] == REGISTER_VERIFY) {
index deda2b2c6c93bbfdb5738c6807ac2d5b4ddad0a3..f05c76cedae20573a43994f4836dc61b68713fc1 100644 (file)
@@ -5,8 +5,8 @@
 use Friendica\App;
 use Friendica\Core\System;
 use Friendica\Database\DBM;
-use Friendica\Model\Contact;
-use Friendica\Model\GContact;
+use Friendica\Model\GlobalContact;
+use Friendica\Object\Contact;
 
 require_once 'include/contact_widgets.php';
 
@@ -69,7 +69,7 @@ function suggest_content(App $a) {
        $a->page['aside'] .= follow_widget();
 
 
-       $r = GContact::suggestionQuery(local_user());
+       $r = GlobalContact::suggestionQuery(local_user());
 
        if (! DBM::is_result($r)) {
                $o .= t('No suggestions available. If this is a new site, please try again in 24 hours.');
index 907982cd8a023eccbe842c2114d44150c5dd0237..3f94fb5760eb48ad69986fab4cf162d10019ac21 100644 (file)
@@ -3,7 +3,7 @@
 use Friendica\App;
 use Friendica\Core\System;
 use Friendica\Database\DBM;
-use Friendica\Model\Contact;
+use Friendica\Object\Contact;
 
 require_once 'include/follow.php';
 require_once 'include/contact_selectors.php';
index bb0e0c237fd432aff144e5cd804dcdf853432ab5..412966f862b7e3138085f9d92679377010054b2d 100644 (file)
@@ -5,7 +5,7 @@ use Friendica\Core\Config;
 use Friendica\Core\System;
 use Friendica\Core\Worker;
 use Friendica\Database\DBM;
-use Friendica\Model\Contact;
+use Friendica\Object\Contact;
 
 require_once('include/items.php');
 require_once('include/acl_selectors.php');
index 1b4ff69c00285ad4b61f6536b0f4db084d479774..30ae92f8e32e7d2a6a5c530bc380b2109cc56a1b 100644 (file)
@@ -3,7 +3,7 @@
 use Friendica\App;
 use Friendica\Core\Config;
 use Friendica\Database\DBM;
-use Friendica\Model\Contact;
+use Friendica\Object\Contact;
 
 require_once('include/contact_selectors.php');
 
index a608743d07ff6292799f3c50fe8484b27591093d..ce73f85151dde9277796c619baaef129110a299d 100644 (file)
@@ -13,8 +13,7 @@ use Friendica\App;
 use Friendica\Core\System;
 use Friendica\Core\Config;
 use Friendica\Database\DBM;
-use Friendica\Model\Photo;
-use Friendica\Object\Image;
+use Friendica\Object\Photo;
 
 function wall_upload_post(App $a, $desktopmode = true) {
 
@@ -162,8 +161,8 @@ function wall_upload_post(App $a, $desktopmode = true) {
                $filetype = "";
        }
 
-       if ($filetype == "") {
-               $filetype = Image::guessType($filename);
+       if ($filetype=="") {
+               $filetype=Photo::guessImageType($filename);
        }
 
        // If there is a temp name, then do a manual check
@@ -191,9 +190,9 @@ function wall_upload_post(App $a, $desktopmode = true) {
        }
 
        $imagedata = @file_get_contents($src);
-       $Image = new Image($imagedata, $filetype);
+       $ph = new Photo($imagedata, $filetype);
 
-       if (! $Image->isValid()) {
+       if (! $ph->isValid()) {
                $msg = t('Unable to process image.');
                if ($r_json) {
                        echo json_encode(array('error'=>$msg));
@@ -204,7 +203,7 @@ function wall_upload_post(App $a, $desktopmode = true) {
                killme();
        }
 
-       $Image->orient($src);
+       $ph->orient($src);
        @unlink($src);
 
        $max_length = Config::get('system', 'max_image_length');
@@ -212,12 +211,12 @@ function wall_upload_post(App $a, $desktopmode = true) {
                $max_length = MAX_IMAGE_LENGTH;
        }
        if ($max_length > 0) {
-               $Image->scaleDown($max_length);
+               $ph->scaleImage($max_length);
                logger("File upload: Scaling picture to new size " . $max_length, LOGGER_DEBUG);
        }
 
-       $width = $Image->getWidth();
-       $height = $Image->getHeight();
+       $width = $ph->getWidth();
+       $height = $ph->getHeight();
 
        $hash = photo_new_resource();
 
@@ -230,7 +229,7 @@ function wall_upload_post(App $a, $desktopmode = true) {
 
        $defperm = '<' . $default_cid . '>';
 
-       $r = Photo::store($Image, $page_owner_uid, $visitor, $hash, $filename, $album, 0, 0, $defperm);
+       $r = $ph->store($page_owner_uid, $visitor, $hash, $filename, $album, 0, 0, $defperm);
 
        if (! $r) {
                $msg = t('Image upload failed.');
@@ -243,16 +242,16 @@ function wall_upload_post(App $a, $desktopmode = true) {
        }
 
        if ($width > 640 || $height > 640) {
-               $Image->scaleDown(640);
-               $r = Photo::store($Image, $page_owner_uid, $visitor, $hash, $filename, $album, 1, 0, $defperm);
+               $ph->scaleImage(640);
+               $r = $ph->store($page_owner_uid, $visitor, $hash, $filename, $album, 1, 0, $defperm);
                if ($r) {
                        $smallest = 1;
                }
        }
 
        if ($width > 320 || $height > 320) {
-               $Image->scaleDown(320);
-               $r = Photo::store($Image, $page_owner_uid, $visitor, $hash, $filename, $album, 2, 0, $defperm);
+               $ph->scaleImage(320);
+               $r = $ph->store($page_owner_uid, $visitor, $hash, $filename, $album, 2, 0, $defperm);
                if ($r && ($smallest == 0)) {
                        $smallest = 2;
                }
@@ -281,8 +280,8 @@ function wall_upload_post(App $a, $desktopmode = true) {
                $picture["height"]    = $r[0]["height"];
                $picture["type"]      = $r[0]["type"];
                $picture["albumpage"] = System::baseUrl() . '/photos/' . $page_owner_nick . '/image/' . $hash;
-               $picture["picture"]   = System::baseUrl() . "/photo/{$hash}-0." . $Image->getExt();
-               $picture["preview"]   = System::baseUrl() . "/photo/{$hash}-{$smallest}." . $Image->getExt();
+               $picture["picture"]   = System::baseUrl() . "/photo/{$hash}-0." . $ph->getExt();
+               $picture["preview"]   = System::baseUrl() . "/photo/{$hash}-{$smallest}." . $ph->getExt();
 
                if ($r_json) {
                        echo json_encode(array('picture'=>$picture));
@@ -300,9 +299,9 @@ function wall_upload_post(App $a, $desktopmode = true) {
 /* mod Waitman Gobble NO WARRANTY */
        // if we get the signal then return the image url info in BBCODE
        if ($_REQUEST['hush']!='yeah') {
-               echo  "\n\n" . '[url=' . System::baseUrl() . '/photos/' . $page_owner_nick . '/image/' . $hash . '][img]' . System::baseUrl() . "/photo/{$hash}-{$smallest}.".$Image->getExt()."[/img][/url]\n\n";
+               echo  "\n\n" . '[url=' . System::baseUrl() . '/photos/' . $page_owner_nick . '/image/' . $hash . '][img]' . System::baseUrl() . "/photo/{$hash}-{$smallest}.".$ph->getExt()."[/img][/url]\n\n";
        } else {
-               $m = '[url='.System::baseUrl().'/photos/'.$page_owner_nick.'/image/'.$hash.'][img]'.System::baseUrl()."/photo/{$hash}-{$smallest}.".$Image->getExt()."[/img][/url]";
+               $m = '[url='.System::baseUrl().'/photos/'.$page_owner_nick.'/image/'.$hash.'][img]'.System::baseUrl()."/photo/{$hash}-{$smallest}.".$ph->getExt()."[/img][/url]";
                return($m);
        }
 /* mod Waitman Gobble NO WARRANTY */
index 9adac10c921b6b98af1c0b7922ba318c2a44609e..42d514e618eb227aa0dadd59c10f3de1e9bd600a 100644 (file)
@@ -9,7 +9,7 @@ namespace Friendica\Core;
 use Friendica\Core\Pconfig;
 use Friendica\Core\System;
 use Friendica\Database\DBM;
-use Friendica\Model\Contact;
+use Friendica\Object\Contact;
 
 require_once 'include/html2plain.php';
 require_once 'include/datetime.php';
diff --git a/src/Model/Contact.php b/src/Model/Contact.php
deleted file mode 100644 (file)
index 3708603..0000000
+++ /dev/null
@@ -1,947 +0,0 @@
-<?php
-
-/**
- * @file src/Model/Contact.php
- */
-
-namespace Friendica\Model;
-
-use Friendica\BaseObject;
-use Friendica\Core\PConfig;
-use Friendica\Core\System;
-use Friendica\Core\Worker;
-use Friendica\Database\DBM;
-use Friendica\Network\Probe;
-use Friendica\Object\Image;
-use Friendica\Protocol\Diaspora;
-use Friendica\Protocol\DFRN;
-use Friendica\Protocol\OStatus;
-use Friendica\Protocol\Salmon;
-use dba;
-
-require_once 'boot.php';
-require_once 'include/text.php';
-
-/**
- * @brief functions for interacting with a contact
- */
-class Contact extends BaseObject
-{
-       /**
-        * Creates the self-contact for the provided user id
-        *
-        * @param int $uid
-        * @return bool Operation success
-        */
-       public static function createSelfFromUserId($uid)
-       {
-               // Only create the entry if it doesn't exist yet
-               if (dba::exists('contact', ['uid' => intval($uid), 'self'])) {
-                       return true;
-               }
-
-               $user = dba::select('user', ['uid', 'username', 'nickname'], ['uid' => intval($uid)], ['limit' => 1]);
-               if (!DBM::is_result($user)) {
-                       return false;
-               }
-
-               $return = dba::insert('contact', [
-                       'uid'         => $user['uid'],
-                       'created'     => datetime_convert(),
-                       'self'        => 1,
-                       'name'        => $user['username'],
-                       'nick'        => $user['nickname'],
-                       'photo'       => System::baseUrl() . '/photo/profile/' . $user['uid'] . '.jpg',
-                       'thumb'       => System::baseUrl() . '/photo/avatar/'  . $user['uid'] . '.jpg',
-                       'micro'       => System::baseUrl() . '/photo/micro/'   . $user['uid'] . '.jpg',
-                       'blocked'     => 0,
-                       'pending'     => 0,
-                       'url'         => System::baseUrl() . '/profile/' . $user['nickname'],
-                       'nurl'        => normalise_link(System::baseUrl() . '/profile/' . $user['nickname']),
-                       'addr'        => $user['nickname'] . '@' . substr(System::baseUrl(), strpos(System::baseUrl(), '://') + 3),
-                       'request'     => System::baseUrl() . '/dfrn_request/' . $user['nickname'],
-                       'notify'      => System::baseUrl() . '/dfrn_notify/'  . $user['nickname'],
-                       'poll'        => System::baseUrl() . '/dfrn_poll/'    . $user['nickname'],
-                       'confirm'     => System::baseUrl() . '/dfrn_confirm/' . $user['nickname'],
-                       'poco'        => System::baseUrl() . '/poco/'         . $user['nickname'],
-                       'name-date'   => datetime_convert(),
-                       'uri-date'    => datetime_convert(),
-                       'avatar-date' => datetime_convert(),
-                       'closeness'   => 0
-               ]);
-
-               return $return;
-       }
-
-       /**
-        * @brief Marks a contact for removal
-        *
-        * @param int $id contact id
-        * @return null
-        */
-       public static function remove($id)
-       {
-               // We want just to make sure that we don't delete our "self" contact
-               $r = dba::select('contact', array('uid'), array('id' => $id, 'self' => false), array('limit' => 1));
-
-               if (!DBM::is_result($r) || !intval($r['uid'])) {
-                       return;
-               }
-
-               $archive = PConfig::get($r['uid'], 'system', 'archive_removed_contacts');
-               if ($archive) {
-                       dba::update('contact', array('archive' => true, 'network' => 'none', 'writable' => false), array('id' => $id));
-                       return;
-               }
-
-               dba::delete('contact', array('id' => $id));
-
-               // Delete the rest in the background
-               Worker::add(PRIORITY_LOW, 'RemoveContact', $id);
-       }
-
-       /**
-        * @brief Sends an unfriend message. Does not remove the contact
-        *
-        * @param array $user    User unfriending
-        * @param array $contact Contact unfriended
-        * @return void
-        */
-       public static function terminateFriendship(array $user, array $contact)
-       {
-               if ($contact['network'] === NETWORK_OSTATUS) {
-                       // create an unfollow slap
-                       $item = array();
-                       $item['verb'] = NAMESPACE_OSTATUS . "/unfollow";
-                       $item['follow'] = $contact["url"];
-                       $slap = OStatus::salmon($item, $user);
-
-                       if ((x($contact, 'notify')) && (strlen($contact['notify']))) {
-                               Salmon::slapper($user, $contact['notify'], $slap);
-                       }
-               } elseif ($contact['network'] === NETWORK_DIASPORA) {
-                       Diaspora::sendUnshare($user, $contact);
-               } elseif ($contact['network'] === NETWORK_DFRN) {
-                       DFRN::deliver($user, $contact, 'placeholder', 1);
-               }
-       }
-
-       /**
-        * @brief Marks a contact for archival after a communication issue delay
-        *
-        * Contact has refused to recognise us as a friend. We will start a countdown.
-        * If they still don't recognise us in 32 days, the relationship is over,
-        * and we won't waste any more time trying to communicate with them.
-        * This provides for the possibility that their database is temporarily messed
-        * up or some other transient event and that there's a possibility we could recover from it.
-        *
-        * @param array $contact contact to mark for archival
-        * @return type
-        */
-       public static function markForArchival(array $contact)
-       {
-               // Contact already archived or "self" contact? => nothing to do
-               if ($contact['archive'] || $contact['self']) {
-                       return;
-               }
-
-               if ($contact['term-date'] <= NULL_DATE) {
-                       dba::update('contact', array('term-date' => datetime_convert()), array('id' => $contact['id']));
-
-                       if ($contact['url'] != '') {
-                               dba::update('contact', array('term-date' => datetime_convert()), array('`nurl` = ? AND `term-date` <= ? AND NOT `self`', normalise_link($contact['url']), NULL_DATE));
-                       }
-               } else {
-                       /* @todo
-                        * We really should send a notification to the owner after 2-3 weeks
-                        * so they won't be surprised when the contact vanishes and can take
-                        * remedial action if this was a serious mistake or glitch
-                        */
-
-                       /// @todo Check for contact vitality via probing
-                       $expiry = $contact['term-date'] . ' + 32 days ';
-                       if (datetime_convert() > datetime_convert('UTC', 'UTC', $expiry)) {
-                               /* Relationship is really truly dead. archive them rather than
-                                * delete, though if the owner tries to unarchive them we'll start
-                                * the whole process over again.
-                                */
-                               dba::update('contact', array('archive' => 1), array('id' => $contact['id']));
-
-                               if ($contact['url'] != '') {
-                                       dba::update('contact', array('archive' => 1), array('nurl' => normalise_link($contact['url']), 'self' => false));
-                               }
-                       }
-               }
-       }
-
-       /**
-        * @brief Cancels the archival countdown
-        *
-        * @see Contact::markForArchival()
-        *
-        * @param array $contact contact to be unmarked for archival
-        * @return null
-        */
-       public static function unmarkForArchival(array $contact)
-       {
-               $condition = array('`id` = ? AND (`term-date` > ? OR `archive`)', $contact['id'], NULL_DATE);
-               $exists = dba::exists('contact', $condition);
-
-               // We don't need to update, we never marked this contact for archival
-               if (!$exists) {
-                       return;
-               }
-
-               // It's a miracle. Our dead contact has inexplicably come back to life.
-               $fields = array('term-date' => NULL_DATE, 'archive' => false);
-               dba::update('contact', $fields, array('id' => $contact['id']));
-
-               if ($contact['url'] != '') {
-                       dba::update('contact', $fields, array('nurl' => normalise_link($contact['url'])));
-               }
-       }
-
-       /**
-        * @brief Get contact data for a given profile link
-        *
-        * The function looks at several places (contact table and gcontact table) for the contact
-        * It caches its result for the same script execution to prevent duplicate calls
-        *
-        * @param string $url     The profile link
-        * @param int    $uid     User id
-        * @param array  $default If not data was found take this data as default value
-        *
-        * @return array Contact data
-        */
-       public static function getDetailsByURL($url, $uid = -1, array $default = [])
-       {
-               static $cache = array();
-
-               if ($url == '') {
-                       return $default;
-               }
-
-               if ($uid == -1) {
-                       $uid = local_user();
-               }
-
-               if (isset($cache[$url][$uid])) {
-                       return $cache[$url][$uid];
-               }
-
-               $ssl_url = str_replace('http://', 'https://', $url);
-
-               // Fetch contact data from the contact table for the given user
-               $s = dba::p("SELECT `id`, `id` AS `cid`, 0 AS `gid`, 0 AS `zid`, `uid`, `url`, `nurl`, `alias`, `network`, `name`, `nick`, `addr`, `location`, `about`, `xmpp`,
-                       `keywords`, `gender`, `photo`, `thumb`, `micro`, `forum`, `prv`, (`forum` | `prv`) AS `community`, `contact-type`, `bd` AS `birthday`, `self`
-               FROM `contact` WHERE `nurl` = ? AND `uid` = ?", normalise_link($url), $uid);
-               $r = dba::inArray($s);
-
-               // Fetch contact data from the contact table for the given user, checking with the alias
-               if (!DBM::is_result($r)) {
-                       $s = dba::p("SELECT `id`, `id` AS `cid`, 0 AS `gid`, 0 AS `zid`, `uid`, `url`, `nurl`, `alias`, `network`, `name`, `nick`, `addr`, `location`, `about`, `xmpp`,
-                               `keywords`, `gender`, `photo`, `thumb`, `micro`, `forum`, `prv`, (`forum` | `prv`) AS `community`, `contact-type`, `bd` AS `birthday`, `self`
-                       FROM `contact` WHERE `alias` IN (?, ?, ?) AND `uid` = ?", normalise_link($url), $url, $ssl_url, $uid);
-                       $r = dba::inArray($s);
-               }
-
-               // Fetch the data from the contact table with "uid=0" (which is filled automatically)
-               if (!DBM::is_result($r)) {
-                       $s = dba::p("SELECT `id`, 0 AS `cid`, `id` AS `zid`, 0 AS `gid`, `uid`, `url`, `nurl`, `alias`, `network`, `name`, `nick`, `addr`, `location`, `about`, `xmpp`,
-                       `keywords`, `gender`, `photo`, `thumb`, `micro`, `forum`, `prv`, (`forum` | `prv`) AS `community`, `contact-type`, `bd` AS `birthday`, 0 AS `self`
-                       FROM `contact` WHERE `nurl` = ? AND `uid` = 0", normalise_link($url));
-                       $r = dba::inArray($s);
-               }
-
-               // Fetch the data from the contact table with "uid=0" (which is filled automatically) - checked with the alias
-               if (!DBM::is_result($r)) {
-                       $s = dba::p("SELECT `id`, 0 AS `cid`, `id` AS `zid`, 0 AS `gid`, `uid`, `url`, `nurl`, `alias`, `network`, `name`, `nick`, `addr`, `location`, `about`, `xmpp`,
-                       `keywords`, `gender`, `photo`, `thumb`, `micro`, `forum`, `prv`, (`forum` | `prv`) AS `community`, `contact-type`, `bd` AS `birthday`, 0 AS `self`
-                       FROM `contact` WHERE `alias` IN (?, ?, ?) AND `uid` = 0", normalise_link($url), $url, $ssl_url);
-                       $r = dba::inArray($s);
-               }
-
-               // Fetch the data from the gcontact table
-               if (!DBM::is_result($r)) {
-                       $s = dba::p("SELECT 0 AS `id`, 0 AS `cid`, `id` AS `gid`, 0 AS `zid`, 0 AS `uid`, `url`, `nurl`, `alias`, `network`, `name`, `nick`, `addr`, `location`, `about`, '' AS `xmpp`,
-                       `keywords`, `gender`, `photo`, `photo` AS `thumb`, `photo` AS `micro`, `community` AS `forum`, 0 AS `prv`, `community`, `contact-type`, `birthday`, 0 AS `self`
-                       FROM `gcontact` WHERE `nurl` = ?", normalise_link($url));
-                       $r = dba::inArray($s);
-               }
-
-               if (DBM::is_result($r)) {
-                       // If there is more than one entry we filter out the connector networks
-                       if (count($r) > 1) {
-                               foreach ($r as $id => $result) {
-                                       if ($result["network"] == NETWORK_STATUSNET) {
-                                               unset($r[$id]);
-                                       }
-                               }
-                       }
-
-                       $profile = array_shift($r);
-
-                       // "bd" always contains the upcoming birthday of a contact.
-                       // "birthday" might contain the birthday including the year of birth.
-                       if ($profile["birthday"] > '0001-01-01') {
-                               $bd_timestamp = strtotime($profile["birthday"]);
-                               $month = date("m", $bd_timestamp);
-                               $day = date("d", $bd_timestamp);
-
-                               $current_timestamp = time();
-                               $current_year = date("Y", $current_timestamp);
-                               $current_month = date("m", $current_timestamp);
-                               $current_day = date("d", $current_timestamp);
-
-                               $profile["bd"] = $current_year . "-" . $month . "-" . $day;
-                               $current = $current_year . "-" . $current_month . "-" . $current_day;
-
-                               if ($profile["bd"] < $current) {
-                                       $profile["bd"] = ( ++$current_year) . "-" . $month . "-" . $day;
-                               }
-                       } else {
-                               $profile["bd"] = '0001-01-01';
-                       }
-               } else {
-                       $profile = $default;
-               }
-
-               if (($profile["photo"] == "") && isset($default["photo"])) {
-                       $profile["photo"] = $default["photo"];
-               }
-
-               if (($profile["name"] == "") && isset($default["name"])) {
-                       $profile["name"] = $default["name"];
-               }
-
-               if (($profile["network"] == "") && isset($default["network"])) {
-                       $profile["network"] = $default["network"];
-               }
-
-               if (($profile["thumb"] == "") && isset($profile["photo"])) {
-                       $profile["thumb"] = $profile["photo"];
-               }
-
-               if (($profile["micro"] == "") && isset($profile["thumb"])) {
-                       $profile["micro"] = $profile["thumb"];
-               }
-
-               if ((($profile["addr"] == "") || ($profile["name"] == "")) && ($profile["gid"] != 0)
-                       && in_array($profile["network"], array(NETWORK_DFRN, NETWORK_DIASPORA, NETWORK_OSTATUS))
-               ) {
-                       Worker::add(PRIORITY_LOW, "UpdateGContact", $profile["gid"]);
-               }
-
-               // Show contact details of Diaspora contacts only if connected
-               if (($profile["cid"] == 0) && ($profile["network"] == NETWORK_DIASPORA)) {
-                       $profile["location"] = "";
-                       $profile["about"] = "";
-                       $profile["gender"] = "";
-                       $profile["birthday"] = '0001-01-01';
-               }
-
-               $cache[$url][$uid] = $profile;
-
-               return $profile;
-       }
-
-       /**
-        * @brief Get contact data for a given address
-        *
-        * The function looks at several places (contact table and gcontact table) for the contact
-        *
-        * @param string $addr The profile link
-        * @param int    $uid  User id
-        *
-        * @return array Contact data
-        */
-       public static function getDetailsByAddr($addr, $uid = -1)
-       {
-               static $cache = array();
-
-               if ($addr == '') {
-                       return array();
-               }
-
-               if ($uid == -1) {
-                       $uid = local_user();
-               }
-
-               // Fetch contact data from the contact table for the given user
-               $r = q("SELECT `id`, `id` AS `cid`, 0 AS `gid`, 0 AS `zid`, `uid`, `url`, `nurl`, `alias`, `network`, `name`, `nick`, `addr`, `location`, `about`, `xmpp`,
-                       `keywords`, `gender`, `photo`, `thumb`, `micro`, `forum`, `prv`, (`forum` | `prv`) AS `community`, `contact-type`, `bd` AS `birthday`, `self`
-               FROM `contact` WHERE `addr` = '%s' AND `uid` = %d", dbesc($addr), intval($uid));
-
-               // Fetch the data from the contact table with "uid=0" (which is filled automatically)
-               if (!DBM::is_result($r))
-                       $r = q("SELECT `id`, 0 AS `cid`, `id` AS `zid`, 0 AS `gid`, `uid`, `url`, `nurl`, `alias`, `network`, `name`, `nick`, `addr`, `location`, `about`, `xmpp`,
-                       `keywords`, `gender`, `photo`, `thumb`, `micro`, `forum`, `prv`, (`forum` | `prv`) AS `community`, `contact-type`, `bd` AS `birthday`, 0 AS `self`
-                       FROM `contact` WHERE `addr` = '%s' AND `uid` = 0", dbesc($addr));
-
-               // Fetch the data from the gcontact table
-               if (!DBM::is_result($r))
-                       $r = q("SELECT 0 AS `id`, 0 AS `cid`, `id` AS `gid`, 0 AS `zid`, 0 AS `uid`, `url`, `nurl`, `alias`, `network`, `name`, `nick`, `addr`, `location`, `about`, '' AS `xmpp`,
-                       `keywords`, `gender`, `photo`, `photo` AS `thumb`, `photo` AS `micro`, `community` AS `forum`, 0 AS `prv`, `community`, `contact-type`, `birthday`, 0 AS `self`
-                       FROM `gcontact` WHERE `addr` = '%s'", dbesc($addr));
-
-               if (!DBM::is_result($r)) {
-                       $data = Probe::uri($addr);
-
-                       $profile = self::getDetailsByURL($data['url'], $uid);
-               } else {
-                       $profile = $r[0];
-               }
-
-               return $profile;
-       }
-
-       /**
-        * @brief Returns the data array for the photo menu of a given contact
-        *
-        * @param array $contact contact
-        * @param int   $uid     optional, default 0
-        * @return array
-        */
-       public static function photoMenu(array $contact, $uid = 0)
-       {
-               // @todo Unused, to be removed
-               $a = get_app();
-
-               $contact_url = '';
-               $pm_url = '';
-               $status_link = '';
-               $photos_link = '';
-               $posts_link = '';
-               $contact_drop_link = '';
-               $poke_link = '';
-
-               if ($uid == 0) {
-                       $uid = local_user();
-               }
-
-               if ($contact['uid'] != $uid) {
-                       if ($uid == 0) {
-                               $profile_link = zrl($contact['url']);
-                               $menu = array('profile' => array(t('View Profile'), $profile_link, true));
-
-                               return $menu;
-                       }
-
-                       $r = dba::select('contact', array(), array('nurl' => $contact['nurl'], 'network' => $contact['network'], 'uid' => $uid), array('limit' => 1));
-                       if ($r) {
-                               return self::photoMenu($r, $uid);
-                       } else {
-                               $profile_link = zrl($contact['url']);
-                               $connlnk = 'follow/?url=' . $contact['url'];
-                               $menu = array(
-                                       'profile' => array(t('View Profile'), $profile_link, true),
-                                       'follow' => array(t('Connect/Follow'), $connlnk, true)
-                               );
-
-                               return $menu;
-                       }
-               }
-
-               $sparkle = false;
-               if ($contact['network'] === NETWORK_DFRN) {
-                       $sparkle = true;
-                       $profile_link = System::baseUrl() . '/redir/' . $contact['id'];
-               } else {
-                       $profile_link = $contact['url'];
-               }
-
-               if ($profile_link === 'mailbox') {
-                       $profile_link = '';
-               }
-
-               if ($sparkle) {
-                       $status_link = $profile_link . '?url=status';
-                       $photos_link = $profile_link . '?url=photos';
-                       $profile_link = $profile_link . '?url=profile';
-               }
-
-               if (in_array($contact['network'], array(NETWORK_DFRN, NETWORK_DIASPORA))) {
-                       $pm_url = System::baseUrl() . '/message/new/' . $contact['id'];
-               }
-
-               if ($contact['network'] == NETWORK_DFRN) {
-                       $poke_link = System::baseUrl() . '/poke/?f=&c=' . $contact['id'];
-               }
-
-               $contact_url = System::baseUrl() . '/contacts/' . $contact['id'];
-
-               $posts_link = System::baseUrl() . '/contacts/' . $contact['id'] . '/posts';
-               $contact_drop_link = System::baseUrl() . '/contacts/' . $contact['id'] . '/drop?confirm=1';
-
-               /**
-                * Menu array:
-                * "name" => [ "Label", "link", (bool)Should the link opened in a new tab? ]
-                */
-               $menu = array(
-                       'status' => array(t("View Status"), $status_link, true),
-                       'profile' => array(t("View Profile"), $profile_link, true),
-                       'photos' => array(t("View Photos"), $photos_link, true),
-                       'network' => array(t("Network Posts"), $posts_link, false),
-                       'edit' => array(t("View Contact"), $contact_url, false),
-                       'drop' => array(t("Drop Contact"), $contact_drop_link, false),
-                       'pm' => array(t("Send PM"), $pm_url, false),
-                       'poke' => array(t("Poke"), $poke_link, false),
-               );
-
-
-               $args = array('contact' => $contact, 'menu' => &$menu);
-
-               call_hooks('contact_photo_menu', $args);
-
-               $menucondensed = array();
-
-               foreach ($menu as $menuname => $menuitem) {
-                       if ($menuitem[1] != '') {
-                               $menucondensed[$menuname] = $menuitem;
-                       }
-               }
-
-               return $menucondensed;
-       }
-
-       /**
-        * @brief Returns ungrouped contact count or list for user
-        *
-        * Returns either the total number of ungrouped contacts for the given user
-        * id or a paginated list of ungrouped contacts.
-        *
-        * @param int $uid   uid
-        * @param int $start optional, default 0
-        * @param int $count optional, default 0
-        *
-        * @return array
-        */
-       public static function getUngroupedList($uid, $start = 0, $count = 0)
-       {
-               if (!$count) {
-                       $r = q(
-                               "SELECT COUNT(*) AS `total`
-                                FROM `contact`
-                                WHERE `uid` = %d
-                                AND NOT `self`
-                                AND NOT `blocked`
-                                AND NOT `pending`
-                                AND `id` NOT IN (
-                                       SELECT DISTINCT(`contact-id`)
-                                       FROM `group_member`
-                                       WHERE `uid` = %d
-                               )", intval($uid), intval($uid)
-                       );
-
-                       return $r;
-               }
-
-               $r = q(
-                       "SELECT *
-                       FROM `contact`
-                       WHERE `uid` = %d
-                       AND NOT `self`
-                       AND NOT `blocked`
-                       AND NOT `pending`
-                       AND `id` NOT IN (
-                               SELECT DISTINCT(`contact-id`)
-                               FROM `group_member` WHERE `uid` = %d
-                       )
-                       LIMIT %d, %d", intval($uid), intval($uid), intval($start), intval($count)
-               );
-               return $r;
-       }
-
-       /**
-        * @brief Fetch the contact id for a given url and user
-        *
-        * First lookup in the contact table to find a record matching either `url`, `nurl`,
-        * `addr` or `alias`.
-        *
-        * If there's no record and we aren't looking for a public contact, we quit.
-        * If there's one, we check that it isn't time to update the picture else we
-        * directly return the found contact id.
-        *
-        * Second, we probe the provided $url wether it's http://server.tld/profile or
-        * nick@server.tld. We quit if we can't get any info back.
-        *
-        * Third, we create the contact record if it doesn't exist
-        *
-        * Fourth, we update the existing record with the new data (avatar, alias, nick)
-        * if there's any updates
-        *
-        * @param string  $url       Contact URL
-        * @param integer $uid       The user id for the contact (0 = public contact)
-        * @param boolean $no_update Don't update the contact
-        *
-        * @return integer Contact ID
-        */
-       public static function getIdForURL($url, $uid = 0, $no_update = false)
-       {
-               logger("Get contact data for url " . $url . " and user " . $uid . " - " . System::callstack(), LOGGER_DEBUG);
-
-               $contact_id = 0;
-
-               if ($url == '') {
-                       return 0;
-               }
-
-               /// @todo Verify if we can't use Contact::getDetailsByUrl instead of the following
-               // We first try the nurl (http://server.tld/nick), most common case
-               $contact = dba::select('contact', array('id', 'avatar-date'), array('nurl' => normalise_link($url), 'uid' => $uid), array('limit' => 1));
-
-               // Then the addr (nick@server.tld)
-               if (!DBM::is_result($contact)) {
-                       $contact = dba::select('contact', array('id', 'avatar-date'), array('addr' => $url, 'uid' => $uid), array('limit' => 1));
-               }
-
-               // Then the alias (which could be anything)
-               if (!DBM::is_result($contact)) {
-                       // The link could be provided as http although we stored it as https
-                       $ssl_url = str_replace('http://', 'https://', $url);
-                       $r = dba::select('contact', array('id', 'avatar-date'), array('`alias` IN (?, ?, ?) AND `uid` = ?', $url, normalise_link($url), $ssl_url, $uid), array('limit' => 1));
-                       $contact = dba::fetch($r);
-                       dba::close($r);
-               }
-
-               if (DBM::is_result($contact)) {
-                       $contact_id = $contact["id"];
-
-                       // Update the contact every 7 days
-                       $update_contact = ($contact['avatar-date'] < datetime_convert('', '', 'now -7 days'));
-
-                       // We force the update if the avatar is empty
-                       if ($contact['avatar'] == '') {
-                               $update_contact = true;
-                       }
-
-                       if (!$update_contact || $no_update) {
-                               return $contact_id;
-                       }
-               } elseif ($uid != 0) {
-                       // Non-existing user-specific contact, exiting
-                       return 0;
-               }
-
-               $data = Probe::uri($url, "", $uid);
-
-               // Last try in gcontact for unsupported networks
-               if (!in_array($data["network"], array(NETWORK_DFRN, NETWORK_OSTATUS, NETWORK_DIASPORA, NETWORK_PUMPIO, NETWORK_MAIL))) {
-                       if ($uid != 0) {
-                               return 0;
-                       }
-
-                       // Get data from the gcontact table
-                       $gcontacts = dba::select('gcontact', array('name', 'nick', 'url', 'photo', 'addr', 'alias', 'network'), array('nurl' => normalise_link($url)), array('limit' => 1));
-                       if (!DBM::is_result($gcontacts)) {
-                               return 0;
-                       }
-
-                       $data = array_merge($data, $gcontacts);
-               }
-
-               if (!$contact_id && ($data["alias"] != '') && ($data["alias"] != $url)) {
-                       $contact_id = self::getIdForURL($data["alias"], $uid, true);
-               }
-
-               $url = $data["url"];
-               if (!$contact_id) {
-                       dba::insert(
-                               'contact', array('uid' => $uid, 'created' => datetime_convert(), 'url' => $data["url"],
-                               'nurl' => normalise_link($data["url"]), 'addr' => $data["addr"],
-                               'alias' => $data["alias"], 'notify' => $data["notify"], 'poll' => $data["poll"],
-                               'name' => $data["name"], 'nick' => $data["nick"], 'photo' => $data["photo"],
-                               'keywords' => $data["keywords"], 'location' => $data["location"], 'about' => $data["about"],
-                               'network' => $data["network"], 'pubkey' => $data["pubkey"],
-                               'rel' => CONTACT_IS_SHARING, 'priority' => $data["priority"],
-                               'batch' => $data["batch"], 'request' => $data["request"],
-                               'confirm' => $data["confirm"], 'poco' => $data["poco"],
-                               'name-date' => datetime_convert(), 'uri-date' => datetime_convert(),
-                               'avatar-date' => datetime_convert(), 'writable' => 1, 'blocked' => 0,
-                               'readonly' => 0, 'pending' => 0)
-                       );
-
-                       $s = dba::select('contact', array('id'), array('nurl' => normalise_link($data["url"]), 'uid' => $uid), array('order' => array('id'), 'limit' => 2));
-                       $contacts = dba::inArray($s);
-                       if (!DBM::is_result($contacts)) {
-                               return 0;
-                       }
-
-                       $contact_id = $contacts[0]["id"];
-
-                       // Update the newly created contact from data in the gcontact table
-                       $gcontact = dba::select('gcontact', array('location', 'about', 'keywords', 'gender'), array('nurl' => normalise_link($data["url"])), array('limit' => 1));
-                       if (DBM::is_result($gcontact)) {
-                               // Only use the information when the probing hadn't fetched these values
-                               if ($data['keywords'] != '') {
-                                       unset($gcontact['keywords']);
-                               }
-                               if ($data['location'] != '') {
-                                       unset($gcontact['location']);
-                               }
-                               if ($data['about'] != '') {
-                                       unset($gcontact['about']);
-                               }
-                               dba::update('contact', $gcontact, array('id' => $contact_id));
-                       }
-
-                       if (count($contacts) > 1 && $uid == 0 && $contact_id != 0 && $data["url"] != "") {
-                               dba::delete('contact', array("`nurl` = ? AND `uid` = 0 AND `id` != ? AND NOT `self`",
-                                       normalise_link($data["url"]), $contact_id));
-                       }
-               }
-
-               self::updateAvatar($data["photo"], $uid, $contact_id);
-
-               $fields = array('url', 'nurl', 'addr', 'alias', 'name', 'nick', 'keywords', 'location', 'about', 'avatar-date', 'pubkey');
-               $contact = dba::select('contact', $fields, array('id' => $contact_id), array('limit' => 1));
-
-               // This condition should always be true
-               if (!DBM::is_result($contact)) {
-                       return $contact_id;
-               }
-
-               $updated = array('addr' => $data['addr'],
-                       'alias' => $data['alias'],
-                       'url' => $data['url'],
-                       'nurl' => normalise_link($data['url']),
-                       'name' => $data['name'],
-                       'nick' => $data['nick']);
-
-               // Only fill the pubkey if it was empty before. We have to prevent identity theft.
-               if (!empty($contact['pubkey'])) {
-                       unset($contact['pubkey']);
-               } else {
-                       $updated['pubkey'] = $data['pubkey'];
-               }
-
-               if ($data['keywords'] != '') {
-                       $updated['keywords'] = $data['keywords'];
-               }
-               if ($data['location'] != '') {
-                       $updated['location'] = $data['location'];
-               }
-               if ($data['about'] != '') {
-                       $updated['about'] = $data['about'];
-               }
-
-               if (($data["addr"] != $contact["addr"]) || ($data["alias"] != $contact["alias"])) {
-                       $updated['uri-date'] = datetime_convert();
-               }
-               if (($data["name"] != $contact["name"]) || ($data["nick"] != $contact["nick"])) {
-                       $updated['name-date'] = datetime_convert();
-               }
-
-               $updated['avatar-date'] = datetime_convert();
-
-               dba::update('contact', $updated, array('id' => $contact_id), $contact);
-
-               return $contact_id;
-       }
-
-       /**
-        * @brief Checks if the contact is blocked
-        *
-        * @param int $cid contact id
-        *
-        * @return boolean Is the contact blocked?
-        */
-       public static function isBlocked($cid)
-       {
-               if ($cid == 0) {
-                       return false;
-               }
-
-               $blocked = dba::select('contact', array('blocked'), array('id' => $cid), array('limit' => 1));
-               if (!DBM::is_result($blocked)) {
-                       return false;
-               }
-               return (bool) $blocked['blocked'];
-       }
-
-       /**
-        * @brief Checks if the contact is hidden
-        *
-        * @param int $cid contact id
-        *
-        * @return boolean Is the contact hidden?
-        */
-       public static function isHidden($cid)
-       {
-               if ($cid == 0) {
-                       return false;
-               }
-
-               $hidden = dba::select('contact', array('hidden'), array('id' => $cid), array('limit' => 1));
-               if (!DBM::is_result($hidden)) {
-                       return false;
-               }
-               return (bool) $hidden['hidden'];
-       }
-
-       /**
-        * @brief Returns posts from a given contact url
-        *
-        * @param string $contact_url Contact URL
-        *
-        * @return string posts in HTML
-        */
-       public static function getPostsFromUrl($contact_url)
-       {
-               $a = self::getApp();
-
-               require_once 'include/conversation.php';
-
-               // There are no posts with "uid = 0" with connector networks
-               // This speeds up the query a lot
-               $r = q("SELECT `network`, `id` AS `author-id`, `contact-type` FROM `contact`
-                       WHERE `contact`.`nurl` = '%s' AND `contact`.`uid` = 0", dbesc(normalise_link($contact_url)));
-
-               if (!DBM::is_result($r)) {
-                       return '';
-               }
-
-               if (in_array($r[0]["network"], array(NETWORK_DFRN, NETWORK_DIASPORA, NETWORK_OSTATUS, ""))) {
-                       $sql = "(`item`.`uid` = 0 OR (`item`.`uid` = %d AND NOT `item`.`global`))";
-               } else {
-                       $sql = "`item`.`uid` = %d";
-               }
-
-               $author_id = intval($r[0]["author-id"]);
-
-               $contact = ($r[0]["contact-type"] == ACCOUNT_TYPE_COMMUNITY ? 'owner-id' : 'author-id');
-
-               $r = q(item_query() . " AND `item`.`" . $contact . "` = %d AND " . $sql .
-                       " ORDER BY `item`.`created` DESC LIMIT %d, %d", intval($author_id), intval(local_user()), intval($a->pager['start']), intval($a->pager['itemspage'])
-               );
-
-
-               $o = conversation($a, $r, 'community', false);
-
-               $o .= alt_pager($a, count($r));
-
-               return $o;
-       }
-
-       /**
-        * @brief Returns the account type name
-        *
-        * The function can be called with either the user or the contact array
-        *
-        * @param array $contact contact or user array
-        * @return string
-        */
-       public static function getAccountType(array $contact)
-       {
-               // There are several fields that indicate that the contact or user is a forum
-               // "page-flags" is a field in the user table,
-               // "forum" and "prv" are used in the contact table. They stand for PAGE_COMMUNITY and PAGE_PRVGROUP.
-               // "community" is used in the gcontact table and is true if the contact is PAGE_COMMUNITY or PAGE_PRVGROUP.
-               if ((isset($contact['page-flags']) && (intval($contact['page-flags']) == PAGE_COMMUNITY))
-                       || (isset($contact['page-flags']) && (intval($contact['page-flags']) == PAGE_PRVGROUP))
-                       || (isset($contact['forum']) && intval($contact['forum']))
-                       || (isset($contact['prv']) && intval($contact['prv']))
-                       || (isset($contact['community']) && intval($contact['community']))
-               ) {
-                       $type = ACCOUNT_TYPE_COMMUNITY;
-               } else {
-                       $type = ACCOUNT_TYPE_PERSON;
-               }
-
-               // The "contact-type" (contact table) and "account-type" (user table) are more general then the chaos from above.
-               if (isset($contact["contact-type"])) {
-                       $type = $contact["contact-type"];
-               }
-               if (isset($contact["account-type"])) {
-                       $type = $contact["account-type"];
-               }
-
-               switch ($type) {
-                       case ACCOUNT_TYPE_ORGANISATION:
-                               $account_type = t("Organisation");
-                               break;
-                       case ACCOUNT_TYPE_NEWS:
-                               $account_type = t('News');
-                               break;
-                       case ACCOUNT_TYPE_COMMUNITY:
-                               $account_type = t("Forum");
-                               break;
-                       default:
-                               $account_type = "";
-                               break;
-               }
-
-               return $account_type;
-       }
-
-       /**
-        * @brief Blocks a contact
-        *
-        * @param int $uid
-        * @return bool
-        */
-       public static function block($uid)
-       {
-               $return = dba::update('contact', ['blocked' => true], ['id' => $uid]);
-
-               return $return;
-       }
-
-       /**
-        * @brief Unblocks a contact
-        *
-        * @param int $uid
-        * @return bool
-        */
-       public static function unblock($uid)
-       {
-               $return = dba::update('contact', ['blocked' => false], ['id' => $uid]);
-
-               return $return;
-  }
-
-  /**
-   * @brief Updates the avatar links in a contact only if needed
-        *
-        * @param string $avatar Link to avatar picture
-        * @param int    $uid    User id of contact owner
-        * @param int    $cid    Contact id
-        * @param bool   $force  force picture update
-        *
-        * @return array Returns array of the different avatar sizes
-        */
-       public static function updateAvatar($avatar, $uid, $cid, $force = false)
-       {
-               // Limit = 1 returns the row so no need for dba:inArray()
-               $r = dba::select('contact', array('avatar', 'photo', 'thumb', 'micro', 'nurl'), array('id' => $cid), array('limit' => 1));
-               if (!DBM::is_result($r)) {
-                       return false;
-               } else {
-                       $data = array($r["photo"], $r["thumb"], $r["micro"]);
-               }
-
-               if (($r["avatar"] != $avatar) || $force) {
-                       $photos = Image::importProfilePhoto($avatar, $uid, $cid, true);
-
-                       if ($photos) {
-                               dba::update(
-                                       'contact',
-                                       array('avatar' => $avatar, 'photo' => $photos[0], 'thumb' => $photos[1], 'micro' => $photos[2], 'avatar-date' => datetime_convert()),
-                                       array('id' => $cid)
-                               );
-
-                               // Update the public contact (contact id = 0)
-                               if ($uid != 0) {
-                                       $pcontact = dba::select('contact', array('id'), array('nurl' => $r[0]['nurl']), array('limit' => 1));
-                                       if (DBM::is_result($pcontact)) {
-                                               self::updateAvatar($avatar, 0, $pcontact['id'], $force);
-                                       }
-                               }
-
-                               return $photos;
-                       }
-               }
-
-               return $data;
-       }
-}
diff --git a/src/Model/GContact.php b/src/Model/GContact.php
deleted file mode 100644 (file)
index 1b846b3..0000000
+++ /dev/null
@@ -1,1076 +0,0 @@
-<?php
-/**
- * @file src/Model/GlobalContact.php
- * @brief This file includes the GlobalContact class with directory related functions
- */
-namespace Friendica\Model;
-
-use Friendica\Core\Config;
-use Friendica\Core\System;
-use Friendica\Core\Worker;
-use Friendica\Database\DBM;
-use Friendica\Model\Contact;
-use Friendica\Model\Profile;
-use Friendica\Network\Probe;
-use Friendica\Protocol\PortableContact;
-use dba;
-use Exception;
-
-require_once 'include/datetime.php';
-require_once 'include/network.php';
-require_once 'include/html2bbcode.php';
-
-/**
- * @brief This class handles GlobalContact related functions
- */
-class GContact
-{
-       /**
-        * @brief Search global contact table by nick or name
-        *
-        * @param string $search Name or nick
-        * @param string $mode   Search mode (e.g. "community")
-        *
-        * @return array with search results
-        */
-       public static function searchByName($search, $mode = '')
-       {
-               if ($search) {
-                       // check supported networks
-                       if (Config::get('system', 'diaspora_enabled')) {
-                               $diaspora = NETWORK_DIASPORA;
-                       } else {
-                               $diaspora = NETWORK_DFRN;
-                       }
-
-                       if (!Config::get('system', 'ostatus_disabled')) {
-                               $ostatus = NETWORK_OSTATUS;
-                       } else {
-                               $ostatus = NETWORK_DFRN;
-                       }
-
-                       // check if we search only communities or every contact
-                       if ($mode === "community") {
-                               $extra_sql = " AND `community`";
-                       } else {
-                               $extra_sql = "";
-                       }
-
-                       $search .= "%";
-
-                       $results = q(
-                               "SELECT `contact`.`id` AS `cid`, `gcontact`.`url`, `gcontact`.`name`, `gcontact`.`nick`, `gcontact`.`photo`,
-                                               `gcontact`.`network`, `gcontact`.`keywords`, `gcontact`.`addr`, `gcontact`.`community`
-                               FROM `gcontact`
-                               LEFT JOIN `contact` ON `contact`.`nurl` = `gcontact`.`nurl`
-                                       AND `contact`.`uid` = %d AND NOT `contact`.`blocked`
-                                       AND NOT `contact`.`pending` AND `contact`.`rel` IN ('%s', '%s')
-                               WHERE (`contact`.`id` > 0 OR (NOT `gcontact`.`hide` AND `gcontact`.`network` IN ('%s', '%s', '%s') AND
-                               ((`gcontact`.`last_contact` >= `gcontact`.`last_failure`) OR
-                               (`gcontact`.`updated` >= `gcontact`.`last_failure`)))) AND
-                               (`gcontact`.`addr` LIKE '%s' OR `gcontact`.`name` LIKE '%s' OR `gcontact`.`nick` LIKE '%s') $extra_sql
-                                       GROUP BY `gcontact`.`nurl`
-                                       ORDER BY `gcontact`.`nurl` DESC
-                                       LIMIT 1000",
-                               intval(local_user()),
-                               dbesc(CONTACT_IS_SHARING),
-                               dbesc(CONTACT_IS_FRIEND),
-                               dbesc(NETWORK_DFRN),
-                               dbesc($ostatus),
-                               dbesc($diaspora),
-                               dbesc(escape_tags($search)),
-                               dbesc(escape_tags($search)),
-                               dbesc(escape_tags($search))
-                       );
-
-                       return $results;
-               }
-       }
-
-       /**
-        * @brief Link the gcontact entry with user, contact and global contact
-        *
-        * @param integer $gcid Global contact ID
-        * @param integer $uid  User ID
-        * @param integer $cid  Contact ID
-        * @param integer $zcid Global Contact ID
-        * @return void
-        */
-       public static function link($gcid, $uid = 0, $cid = 0, $zcid = 0)
-       {
-               if ($gcid <= 0) {
-                       return;
-               }
-
-               $r = q(
-                       "SELECT * FROM `glink` WHERE `cid` = %d AND `uid` = %d AND `gcid` = %d AND `zcid` = %d LIMIT 1",
-                       intval($cid),
-                       intval($uid),
-                       intval($gcid),
-                       intval($zcid)
-               );
-
-               if (!DBM::is_result($r)) {
-                       q(
-                               "INSERT INTO `glink` (`cid`, `uid`, `gcid`, `zcid`, `updated`) VALUES (%d, %d, %d, %d, '%s') ",
-                               intval($cid),
-                               intval($uid),
-                               intval($gcid),
-                               intval($zcid),
-                               dbesc(datetime_convert())
-                       );
-               } else {
-                       q(
-                               "UPDATE `glink` SET `updated` = '%s' WHERE `cid` = %d AND `uid` = %d AND `gcid` = %d AND `zcid` = %d",
-                               dbesc(datetime_convert()),
-                               intval($cid),
-                               intval($uid),
-                               intval($gcid),
-                               intval($zcid)
-                       );
-               }
-       }
-
-       /**
-        * @brief Sanitize the given gcontact data
-        *
-        * @param array $gcontact array with gcontact data
-        * @throw Exception
-        *
-        * Generation:
-        *  0: No definition
-        *  1: Profiles on this server
-        *  2: Contacts of profiles on this server
-        *  3: Contacts of contacts of profiles on this server
-        *  4: ...
-        * @return array $gcontact
-        */
-       public static function sanitize($gcontact)
-       {
-               if ($gcontact['url'] == "") {
-                       throw new Exception('URL is empty');
-               }
-
-               $urlparts = parse_url($gcontact['url']);
-               if (!isset($urlparts["scheme"])) {
-                       throw new Exception("This (".$gcontact['url'].") doesn't seem to be an url.");
-               }
-
-               if (in_array($urlparts["host"], array("www.facebook.com", "facebook.com", "twitter.com", "identi.ca", "alpha.app.net"))) {
-                       throw new Exception('Contact from a non federated network ignored. ('.$gcontact['url'].')');
-               }
-
-               // Don't store the statusnet connector as network
-               // We can't simply set this to NETWORK_OSTATUS since the connector could have fetched posts from friendica as well
-               if ($gcontact['network'] == NETWORK_STATUSNET) {
-                       $gcontact['network'] = "";
-               }
-
-               // Assure that there are no parameter fragments in the profile url
-               if (in_array($gcontact['network'], array(NETWORK_DFRN, NETWORK_DIASPORA, NETWORK_OSTATUS, ""))) {
-                       $gcontact['url'] = self::cleanContactUrl($gcontact['url']);
-               }
-
-               $alternate = PortableContact::alternateOStatusUrl($gcontact['url']);
-
-               // The global contacts should contain the original picture, not the cached one
-               if (($gcontact['generation'] != 1) && stristr(normalise_link($gcontact['photo']), normalise_link(System::baseUrl()."/photo/"))) {
-                       $gcontact['photo'] = "";
-               }
-
-               if (!isset($gcontact['network'])) {
-                       $r = q(
-                               "SELECT `network` FROM `contact` WHERE `uid` = 0 AND `nurl` = '%s' AND `network` != '' AND `network` != '%s' LIMIT 1",
-                               dbesc(normalise_link($gcontact['url'])),
-                               dbesc(NETWORK_STATUSNET)
-                       );
-                       if (DBM::is_result($r)) {
-                               $gcontact['network'] = $r[0]["network"];
-                       }
-
-                       if (($gcontact['network'] == "") || ($gcontact['network'] == NETWORK_OSTATUS)) {
-                               $r = q(
-                                       "SELECT `network`, `url` FROM `contact` WHERE `uid` = 0 AND `alias` IN ('%s', '%s') AND `network` != '' AND `network` != '%s' LIMIT 1",
-                                       dbesc($gcontact['url']),
-                                       dbesc(normalise_link($gcontact['url'])),
-                                       dbesc(NETWORK_STATUSNET)
-                               );
-                               if (DBM::is_result($r)) {
-                                       $gcontact['network'] = $r[0]["network"];
-                               }
-                       }
-               }
-
-               $gcontact['server_url'] = '';
-               $gcontact['network'] = '';
-
-               $x = q(
-                       "SELECT * FROM `gcontact` WHERE `nurl` = '%s' LIMIT 1",
-                       dbesc(normalise_link($gcontact['url']))
-               );
-
-               if (DBM::is_result($x)) {
-                       if (!isset($gcontact['network']) && ($x[0]["network"] != NETWORK_STATUSNET)) {
-                               $gcontact['network'] = $x[0]["network"];
-                       }
-                       if ($gcontact['updated'] <= NULL_DATE) {
-                               $gcontact['updated'] = $x[0]["updated"];
-                       }
-                       if (!isset($gcontact['server_url']) && (normalise_link($x[0]["server_url"]) != normalise_link($x[0]["url"]))) {
-                               $gcontact['server_url'] = $x[0]["server_url"];
-                       }
-                       if (!isset($gcontact['addr'])) {
-                               $gcontact['addr'] = $x[0]["addr"];
-                       }
-               }
-
-               if ((!isset($gcontact['network']) || !isset($gcontact['name']) || !isset($gcontact['addr']) || !isset($gcontact['photo']) || !isset($gcontact['server_url']) || $alternate)
-                       && PortableContact::reachable($gcontact['url'], $gcontact['server_url'], $gcontact['network'], false)
-               ) {
-                       $data = Probe::uri($gcontact['url']);
-
-                       if ($data["network"] == NETWORK_PHANTOM) {
-                               throw new Exception('Probing for URL '.$gcontact['url'].' failed');
-                       }
-
-                       $orig_profile = $gcontact['url'];
-
-                       $gcontact["server_url"] = $data["baseurl"];
-
-                       $gcontact = array_merge($gcontact, $data);
-
-                       if ($alternate && ($gcontact['network'] == NETWORK_OSTATUS)) {
-                               // Delete the old entry - if it exists
-                               $r = q("SELECT `id` FROM `gcontact` WHERE `nurl` = '%s'", dbesc(normalise_link($orig_profile)));
-                               if (DBM::is_result($r)) {
-                                       q("DELETE FROM `gcontact` WHERE `nurl` = '%s'", dbesc(normalise_link($orig_profile)));
-                                       q("DELETE FROM `glink` WHERE `gcid` = %d", intval($r[0]["id"]));
-                               }
-                       }
-               }
-
-               if (!isset($gcontact['name']) || !isset($gcontact['photo'])) {
-                       throw new Exception('No name and photo for URL '.$gcontact['url']);
-               }
-
-               if (!in_array($gcontact['network'], array(NETWORK_DFRN, NETWORK_OSTATUS, NETWORK_DIASPORA))) {
-                       throw new Exception('No federated network ('.$gcontact['network'].') detected for URL '.$gcontact['url']);
-               }
-
-               if (!isset($gcontact['server_url'])) {
-                       // We check the server url to be sure that it is a real one
-                       $server_url = PortableContact::detectServer($gcontact['url']);
-
-                       // We are now sure that it is a correct URL. So we use it in the future
-                       if ($server_url != "") {
-                               $gcontact['server_url'] = $server_url;
-                       }
-               }
-
-               // The server URL doesn't seem to be valid, so we don't store it.
-               if (!PortableContact::checkServer($gcontact['server_url'], $gcontact['network'])) {
-                       $gcontact['server_url'] = "";
-               }
-
-               return $gcontact;
-       }
-
-       /**
-        * @param integer $uid id
-        * @param integer $cid id
-        * @return integer
-        */
-       public static function countCommonFriends($uid, $cid)
-       {
-               $r = q(
-                       "SELECT count(*) as `total`
-                       FROM `glink` INNER JOIN `gcontact` on `glink`.`gcid` = `gcontact`.`id`
-                       WHERE `glink`.`cid` = %d AND `glink`.`uid` = %d AND
-                       ((`gcontact`.`last_contact` >= `gcontact`.`last_failure`) OR
-                       (`gcontact`.`updated` >= `gcontact`.`last_failure`))
-                       AND `gcontact`.`nurl` IN (select nurl from contact where uid = %d and self = 0 and blocked = 0 and hidden = 0 and id != %d ) ",
-                       intval($cid),
-                       intval($uid),
-                       intval($uid),
-                       intval($cid)
-               );
-
-               // logger("countCommonFriends: $uid $cid {$r[0]['total']}");
-               if (DBM::is_result($r)) {
-                       return $r[0]['total'];
-               }
-               return 0;
-       }
-
-       /**
-        * @param integer $uid  id
-        * @param integer $zcid zcid
-        * @return integer
-        */
-       public static function countCommonFriendsZcid($uid, $zcid)
-       {
-               $r = q(
-                       "SELECT count(*) as `total`
-                       FROM `glink` INNER JOIN `gcontact` on `glink`.`gcid` = `gcontact`.`id`
-                       where `glink`.`zcid` = %d
-                       and `gcontact`.`nurl` in (select nurl from contact where uid = %d and self = 0 and blocked = 0 and hidden = 0 ) ",
-                       intval($zcid),
-                       intval($uid)
-               );
-
-               if (DBM::is_result($r)) {
-                       return $r[0]['total'];
-               }
-
-               return 0;
-       }
-
-       /**
-        * @param object  $uid     user
-        * @param object  $cid     cid
-        * @param integer $start   optional, default 0
-        * @param integer $limit   optional, default 9999
-        * @param boolean $shuffle optional, default false
-        * @return object
-        */
-       public static function commonFriends($uid, $cid, $start = 0, $limit = 9999, $shuffle = false)
-       {
-               if ($shuffle) {
-                       $sql_extra = " order by rand() ";
-               } else {
-                       $sql_extra = " order by `gcontact`.`name` asc ";
-               }
-
-               $r = q(
-                       "SELECT `gcontact`.*, `contact`.`id` AS `cid`
-                       FROM `glink`
-                       INNER JOIN `gcontact` ON `glink`.`gcid` = `gcontact`.`id`
-                       INNER JOIN `contact` ON `gcontact`.`nurl` = `contact`.`nurl`
-                       WHERE `glink`.`cid` = %d and `glink`.`uid` = %d
-                               AND `contact`.`uid` = %d AND `contact`.`self` = 0 AND `contact`.`blocked` = 0
-                               AND `contact`.`hidden` = 0 AND `contact`.`id` != %d
-                               AND ((`gcontact`.`last_contact` >= `gcontact`.`last_failure`) OR (`gcontact`.`updated` >= `gcontact`.`last_failure`))
-                               $sql_extra LIMIT %d, %d",
-                       intval($cid),
-                       intval($uid),
-                       intval($uid),
-                       intval($cid),
-                       intval($start),
-                       intval($limit)
-               );
-
-               /// @TODO Check all calling-findings of this function if they properly use DBM::is_result()
-               return $r;
-       }
-
-       /**
-        * @param object  $uid     user
-        * @param object  $zcid    zcid
-        * @param integer $start   optional, default 0
-        * @param integer $limit   optional, default 9999
-        * @param boolean $shuffle optional, default false
-        * @return object
-        */
-       public static function commonFriendsZcid($uid, $zcid, $start = 0, $limit = 9999, $shuffle = false)
-       {
-               if ($shuffle) {
-                       $sql_extra = " order by rand() ";
-               } else {
-                       $sql_extra = " order by `gcontact`.`name` asc ";
-               }
-
-               $r = q(
-                       "SELECT `gcontact`.*
-                       FROM `glink` INNER JOIN `gcontact` on `glink`.`gcid` = `gcontact`.`id`
-                       where `glink`.`zcid` = %d
-                       and `gcontact`.`nurl` in (select nurl from contact where uid = %d and self = 0 and blocked = 0 and hidden = 0 )
-                       $sql_extra limit %d, %d",
-                       intval($zcid),
-                       intval($uid),
-                       intval($start),
-                       intval($limit)
-               );
-
-               /// @TODO Check all calling-findings of this function if they properly use DBM::is_result()
-               return $r;
-       }
-
-       /**
-        * @param object $uid user
-        * @param object $cid cid
-        * @return integer
-        */
-       public static function countAllFriends($uid, $cid)
-       {
-               $r = q(
-                       "SELECT count(*) as `total`
-                       FROM `glink` INNER JOIN `gcontact` on `glink`.`gcid` = `gcontact`.`id`
-                       where `glink`.`cid` = %d and `glink`.`uid` = %d AND
-                       ((`gcontact`.`last_contact` >= `gcontact`.`last_failure`) OR (`gcontact`.`updated` >= `gcontact`.`last_failure`))",
-                       intval($cid),
-                       intval($uid)
-               );
-
-               if (DBM::is_result($r)) {
-                       return $r[0]['total'];
-               }
-
-               return 0;
-       }
-
-       /**
-        * @param object  $uid   user
-        * @param object  $cid   cid
-        * @param integer $start optional, default 0
-        * @param integer $limit optional, default 80
-        * @return object
-        */
-       public static function allFriends($uid, $cid, $start = 0, $limit = 80)
-       {
-               $r = q(
-                       "SELECT `gcontact`.*, `contact`.`id` AS `cid`
-                       FROM `glink`
-                       INNER JOIN `gcontact` on `glink`.`gcid` = `gcontact`.`id`
-                       LEFT JOIN `contact` ON `contact`.`nurl` = `gcontact`.`nurl` AND `contact`.`uid` = %d
-                       WHERE `glink`.`cid` = %d AND `glink`.`uid` = %d AND
-                       ((`gcontact`.`last_contact` >= `gcontact`.`last_failure`) OR (`gcontact`.`updated` >= `gcontact`.`last_failure`))
-                       ORDER BY `gcontact`.`name` ASC LIMIT %d, %d ",
-                       intval($uid),
-                       intval($cid),
-                       intval($uid),
-                       intval($start),
-                       intval($limit)
-               );
-
-               /// @TODO Check all calling-findings of this function if they properly use DBM::is_result()
-               return $r;
-       }
-
-       /**
-        * @param object  $uid   user
-        * @param integer $start optional, default 0
-        * @param integer $limit optional, default 80
-        * @return array
-        */
-       public static function suggestionQuery($uid, $start = 0, $limit = 80)
-       {
-               if (!$uid) {
-                       return array();
-               }
-
-               /*
-               * Uncommented because the result of the queries are to big to store it in the cache.
-               * We need to decide if we want to change the db column type or if we want to delete it.
-               */
-               //$list = Cache::get("suggestion_query:".$uid.":".$start.":".$limit);
-               //if (!is_null($list)) {
-               //      return $list;
-               //}
-
-               $network = array(NETWORK_DFRN);
-
-               if (Config::get('system', 'diaspora_enabled')) {
-                       $network[] = NETWORK_DIASPORA;
-               }
-
-               if (!Config::get('system', 'ostatus_disabled')) {
-                       $network[] = NETWORK_OSTATUS;
-               }
-
-               $sql_network = implode("', '", $network);
-               $sql_network = "'".$sql_network."'";
-
-               /// @todo This query is really slow
-               // By now we cache the data for five minutes
-               $r = q(
-                       "SELECT count(glink.gcid) as `total`, gcontact.* from gcontact
-                       INNER JOIN `glink` ON `glink`.`gcid` = `gcontact`.`id`
-                       where uid = %d and not gcontact.nurl in ( select nurl from contact where uid = %d )
-                       AND NOT `gcontact`.`name` IN (SELECT `name` FROM `contact` WHERE `uid` = %d)
-                       AND NOT `gcontact`.`id` IN (SELECT `gcid` FROM `gcign` WHERE `uid` = %d)
-                       AND `gcontact`.`updated` >= '%s'
-                       AND `gcontact`.`last_contact` >= `gcontact`.`last_failure`
-                       AND `gcontact`.`network` IN (%s)
-                       GROUP BY `glink`.`gcid` ORDER BY `gcontact`.`updated` DESC,`total` DESC LIMIT %d, %d",
-                       intval($uid),
-                       intval($uid),
-                       intval($uid),
-                       intval($uid),
-                       dbesc(NULL_DATE),
-                       $sql_network,
-                       intval($start),
-                       intval($limit)
-               );
-
-               if (DBM::is_result($r) && count($r) >= ($limit -1)) {
-                       /*
-                       * Uncommented because the result of the queries are to big to store it in the cache.
-                       * We need to decide if we want to change the db column type or if we want to delete it.
-                       */
-                       //Cache::set("suggestion_query:".$uid.":".$start.":".$limit, $r, CACHE_FIVE_MINUTES);
-
-                       return $r;
-               }
-
-               $r2 = q(
-                       "SELECT gcontact.* FROM gcontact
-                       INNER JOIN `glink` ON `glink`.`gcid` = `gcontact`.`id`
-                       WHERE `glink`.`uid` = 0 AND `glink`.`cid` = 0 AND `glink`.`zcid` = 0 AND NOT `gcontact`.`nurl` IN (SELECT `nurl` FROM `contact` WHERE `uid` = %d)
-                       AND NOT `gcontact`.`name` IN (SELECT `name` FROM `contact` WHERE `uid` = %d)
-                       AND NOT `gcontact`.`id` IN (SELECT `gcid` FROM `gcign` WHERE `uid` = %d)
-                       AND `gcontact`.`updated` >= '%s'
-                       AND `gcontact`.`last_contact` >= `gcontact`.`last_failure`
-                       AND `gcontact`.`network` IN (%s)
-                       ORDER BY rand() LIMIT %d, %d",
-                       intval($uid),
-                       intval($uid),
-                       intval($uid),
-                       dbesc(NULL_DATE),
-                       $sql_network,
-                       intval($start),
-                       intval($limit)
-               );
-
-               $list = array();
-               foreach ($r2 as $suggestion) {
-                       $list[$suggestion["nurl"]] = $suggestion;
-               }
-
-               foreach ($r as $suggestion) {
-                       $list[$suggestion["nurl"]] = $suggestion;
-               }
-
-               while (sizeof($list) > ($limit)) {
-                       array_pop($list);
-               }
-
-               /*
-               * Uncommented because the result of the queries are to big to store it in the cache.
-               * We need to decide if we want to change the db column type or if we want to delete it.
-               */
-               //Cache::set("suggestion_query:".$uid.":".$start.":".$limit, $list, CACHE_FIVE_MINUTES);
-               return $list;
-       }
-
-       /**
-        * @return void
-        */
-       public static function updateSuggestions()
-       {
-               $a = get_app();
-
-               $done = array();
-
-               /// @TODO Check if it is really neccessary to poll the own server
-               PortableContact::loadWorker(0, 0, 0, System::baseUrl() . '/poco');
-
-               $done[] = System::baseUrl() . '/poco';
-
-               if (strlen(Config::get('system', 'directory'))) {
-                       $x = fetch_url(get_server()."/pubsites");
-                       if ($x) {
-                               $j = json_decode($x);
-                               if ($j->entries) {
-                                       foreach ($j->entries as $entry) {
-                                               PortableContact::checkServer($entry->url);
-
-                                               $url = $entry->url . '/poco';
-                                               if (! in_array($url, $done)) {
-                                                       PortableContact::loadWorker(0, 0, 0, $entry->url . '/poco');
-                                               }
-                                       }
-                               }
-                       }
-               }
-
-               // Query your contacts from Friendica and Redmatrix/Hubzilla for their contacts
-               $r = q(
-                       "SELECT DISTINCT(`poco`) AS `poco` FROM `contact` WHERE `network` IN ('%s', '%s')",
-                       dbesc(NETWORK_DFRN),
-                       dbesc(NETWORK_DIASPORA)
-               );
-
-               if (DBM::is_result($r)) {
-                       foreach ($r as $rr) {
-                               $base = substr($rr['poco'], 0, strrpos($rr['poco'], '/'));
-                               if (! in_array($base, $done)) {
-                                       PortableContact::loadWorker(0, 0, 0, $base);
-                               }
-                       }
-               }
-       }
-
-       /**
-        * @brief Removes unwanted parts from a contact url
-        *
-        * @param string $url Contact url
-        *
-        * @return string Contact url with the wanted parts
-        */
-       public static function cleanContactUrl($url)
-       {
-               $parts = parse_url($url);
-
-               if (!isset($parts["scheme"]) || !isset($parts["host"])) {
-                       return $url;
-               }
-
-               $new_url = $parts["scheme"]."://".$parts["host"];
-
-               if (isset($parts["port"])) {
-                       $new_url .= ":".$parts["port"];
-               }
-
-               if (isset($parts["path"])) {
-                       $new_url .= $parts["path"];
-               }
-
-               if ($new_url != $url) {
-                       logger("Cleaned contact url ".$url." to ".$new_url." - Called by: ".System::callstack(), LOGGER_DEBUG);
-               }
-
-               return $new_url;
-       }
-
-       /**
-        * @brief Replace alternate OStatus user format with the primary one
-        *
-        * @param arr $contact contact array (called by reference)
-        * @return void
-        */
-       public static function fixAlternateContactAddress(&$contact)
-       {
-               if (($contact["network"] == NETWORK_OSTATUS) && PortableContact::alternateOStatusUrl($contact["url"])) {
-                       $data = Probe::uri($contact["url"]);
-                       if ($contact["network"] == NETWORK_OSTATUS) {
-                               logger("Fix primary url from ".$contact["url"]." to ".$data["url"]." - Called by: ".System::callstack(), LOGGER_DEBUG);
-                               $contact["url"] = $data["url"];
-                               $contact["addr"] = $data["addr"];
-                               $contact["alias"] = $data["alias"];
-                               $contact["server_url"] = $data["baseurl"];
-                       }
-               }
-       }
-
-       /**
-        * @brief Fetch the gcontact id, add an entry if not existed
-        *
-        * @param arr $contact contact array
-        *
-        * @return bool|int Returns false if not found, integer if contact was found
-        */
-       public static function getId($contact)
-       {
-               $gcontact_id = 0;
-               $doprobing = false;
-
-               if (in_array($contact["network"], array(NETWORK_PHANTOM))) {
-                       logger("Invalid network for contact url ".$contact["url"]." - Called by: ".System::callstack(), LOGGER_DEBUG);
-                       return false;
-               }
-
-               if ($contact["network"] == NETWORK_STATUSNET) {
-                       $contact["network"] = NETWORK_OSTATUS;
-               }
-
-               // All new contacts are hidden by default
-               if (!isset($contact["hide"])) {
-                       $contact["hide"] = true;
-               }
-
-               // Replace alternate OStatus user format with the primary one
-               self::fixAlternateContactAddress($contact);
-
-               // Remove unwanted parts from the contact url (e.g. "?zrl=...")
-               if (in_array($contact["network"], array(NETWORK_DFRN, NETWORK_DIASPORA, NETWORK_OSTATUS))) {
-                       $contact["url"] = self::cleanContactUrl($contact["url"]);
-               }
-
-               dba::lock('gcontact');
-               $r = q(
-                       "SELECT `id`, `last_contact`, `last_failure`, `network` FROM `gcontact` WHERE `nurl` = '%s' LIMIT 1",
-                       dbesc(normalise_link($contact["url"]))
-               );
-
-               if (DBM::is_result($r)) {
-                       $gcontact_id = $r[0]["id"];
-
-                       // Update every 90 days
-                       if (in_array($r[0]["network"], array(NETWORK_DFRN, NETWORK_DIASPORA, NETWORK_OSTATUS, ""))) {
-                               $last_failure_str = $r[0]["last_failure"];
-                               $last_failure = strtotime($r[0]["last_failure"]);
-                               $last_contact_str = $r[0]["last_contact"];
-                               $last_contact = strtotime($r[0]["last_contact"]);
-                               $doprobing = (((time() - $last_contact) > (90 * 86400)) && ((time() - $last_failure) > (90 * 86400)));
-                       }
-               } else {
-                       q(
-                               "INSERT INTO `gcontact` (`name`, `nick`, `addr` , `network`, `url`, `nurl`, `photo`, `created`, `updated`, `location`, `about`, `hide`, `generation`)
-                               VALUES ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d)",
-                               dbesc($contact["name"]),
-                               dbesc($contact["nick"]),
-                               dbesc($contact["addr"]),
-                               dbesc($contact["network"]),
-                               dbesc($contact["url"]),
-                               dbesc(normalise_link($contact["url"])),
-                               dbesc($contact["photo"]),
-                               dbesc(datetime_convert()),
-                               dbesc(datetime_convert()),
-                               dbesc($contact["location"]),
-                               dbesc($contact["about"]),
-                               intval($contact["hide"]),
-                               intval($contact["generation"])
-                       );
-
-                       $r = q(
-                               "SELECT `id`, `network` FROM `gcontact` WHERE `nurl` = '%s' ORDER BY `id` LIMIT 2",
-                               dbesc(normalise_link($contact["url"]))
-                       );
-
-                       if (DBM::is_result($r)) {
-                               $gcontact_id = $r[0]["id"];
-
-                               $doprobing = in_array($r[0]["network"], array(NETWORK_DFRN, NETWORK_DIASPORA, NETWORK_OSTATUS, ""));
-                       }
-               }
-               dba::unlock();
-
-               if ($doprobing) {
-                       logger("Last Contact: ". $last_contact_str." - Last Failure: ".$last_failure_str." - Checking: ".$contact["url"], LOGGER_DEBUG);
-                       Worker::add(PRIORITY_LOW, 'GProbe', $contact["url"]);
-               }
-
-               return $gcontact_id;
-       }
-
-       /**
-        * @brief Updates the gcontact table from a given array
-        *
-        * @param arr $contact contact array
-        *
-        * @return bool|int Returns false if not found, integer if contact was found
-        */
-       public static function update($contact)
-       {
-               // Check for invalid "contact-type" value
-               if (isset($contact['contact-type']) && (intval($contact['contact-type']) < 0)) {
-                       $contact['contact-type'] = 0;
-               }
-
-               /// @todo update contact table as well
-
-               $gcontact_id = self::getId($contact);
-
-               if (!$gcontact_id) {
-                       return false;
-               }
-
-               $r = q(
-                       "SELECT `name`, `nick`, `photo`, `location`, `about`, `addr`, `generation`, `birthday`, `gender`, `keywords`,
-                               `contact-type`, `hide`, `nsfw`, `network`, `alias`, `notify`, `server_url`, `connect`, `updated`, `url`
-                       FROM `gcontact` WHERE `id` = %d LIMIT 1",
-                       intval($gcontact_id)
-               );
-
-               // Get all field names
-               $fields = array();
-               foreach ($r[0] as $field => $data) {
-                       $fields[$field] = $data;
-               }
-
-               unset($fields["url"]);
-               unset($fields["updated"]);
-               unset($fields["hide"]);
-
-               // Bugfix: We had an error in the storing of keywords which lead to the "0"
-               // This value is still transmitted via poco.
-               if ($contact["keywords"] == "0") {
-                       unset($contact["keywords"]);
-               }
-
-               if ($r[0]["keywords"] == "0") {
-                       $r[0]["keywords"] = "";
-               }
-
-               // assign all unassigned fields from the database entry
-               foreach ($fields as $field => $data) {
-                       if (!isset($contact[$field]) || ($contact[$field] == "")) {
-                               $contact[$field] = $r[0][$field];
-                       }
-               }
-
-               if (!isset($contact["hide"])) {
-                       $contact["hide"] = $r[0]["hide"];
-               }
-
-               $fields["hide"] = $r[0]["hide"];
-
-               if ($contact["network"] == NETWORK_STATUSNET) {
-                       $contact["network"] = NETWORK_OSTATUS;
-               }
-
-               // Replace alternate OStatus user format with the primary one
-               self::fixAlternateContactAddress($contact);
-
-               if (!isset($contact["updated"])) {
-                       $contact["updated"] = DBM::date();
-               }
-
-               if ($contact["network"] == NETWORK_TWITTER) {
-                       $contact["server_url"] = 'http://twitter.com';
-               }
-
-               if ($contact["server_url"] == "") {
-                       $data = Probe::uri($contact["url"]);
-                       if ($data["network"] != NETWORK_PHANTOM) {
-                               $contact["server_url"] = $data['baseurl'];
-                       }
-               } else {
-                       $contact["server_url"] = normalise_link($contact["server_url"]);
-               }
-
-               if (($contact["addr"] == "") && ($contact["server_url"] != "") && ($contact["nick"] != "")) {
-                       $hostname = str_replace("http://", "", $contact["server_url"]);
-                       $contact["addr"] = $contact["nick"]."@".$hostname;
-               }
-
-               // Check if any field changed
-               $update = false;
-               unset($fields["generation"]);
-
-               if ((($contact["generation"] > 0) && ($contact["generation"] <= $r[0]["generation"])) || ($r[0]["generation"] == 0)) {
-                       foreach ($fields as $field => $data) {
-                               if ($contact[$field] != $r[0][$field]) {
-                                       logger("Difference for contact ".$contact["url"]." in field '".$field."'. New value: '".$contact[$field]."', old value '".$r[0][$field]."'", LOGGER_DEBUG);
-                                       $update = true;
-                               }
-                       }
-
-                       if ($contact["generation"] < $r[0]["generation"]) {
-                               logger("Difference for contact ".$contact["url"]." in field 'generation'. new value: '".$contact["generation"]."', old value '".$r[0]["generation"]."'", LOGGER_DEBUG);
-                               $update = true;
-                       }
-               }
-
-               if ($update) {
-                       logger("Update gcontact for ".$contact["url"], LOGGER_DEBUG);
-                       $condition = array('`nurl` = ? AND (`generation` = 0 OR `generation` >= ?)',
-                                       normalise_link($contact["url"]), $contact["generation"]);
-                       $contact["updated"] = DBM::date($contact["updated"]);
-
-                       $updated = array('photo' => $contact['photo'], 'name' => $contact['name'],
-                                       'nick' => $contact['nick'], 'addr' => $contact['addr'],
-                                       'network' => $contact['network'], 'birthday' => $contact['birthday'],
-                                       'gender' => $contact['gender'], 'keywords' => $contact['keywords'],
-                                       'hide' => $contact['hide'], 'nsfw' => $contact['nsfw'],
-                                       'contact-type' => $contact['contact-type'], 'alias' => $contact['alias'],
-                                       'notify' => $contact['notify'], 'url' => $contact['url'],
-                                       'location' => $contact['location'], 'about' => $contact['about'],
-                                       'generation' => $contact['generation'], 'updated' => $contact['updated'],
-                                       'server_url' => $contact['server_url'], 'connect' => $contact['connect']);
-
-                       dba::update('gcontact', $updated, $condition, $fields);
-
-                       // Now update the contact entry with the user id "0" as well.
-                       // This is used for the shadow copies of public items.
-                       $r = q(
-                               "SELECT `id` FROM `contact` WHERE `nurl` = '%s' AND `uid` = 0 ORDER BY `id` LIMIT 1",
-                               dbesc(normalise_link($contact["url"]))
-                       );
-
-                       if (DBM::is_result($r)) {
-                               logger("Update public contact ".$r[0]["id"], LOGGER_DEBUG);
-
-                               Contact::updateAvatar($contact["photo"], 0, $r[0]["id"]);
-
-                               $fields = array('name', 'nick', 'addr',
-                                               'network', 'bd', 'gender',
-                                               'keywords', 'alias', 'contact-type',
-                                               'url', 'location', 'about');
-                               $old_contact = dba::select('contact', $fields, array('id' => $r[0]["id"]), array('limit' => 1));
-
-                               // Update it with the current values
-                               $fields = array('name' => $contact['name'], 'nick' => $contact['nick'],
-                                               'addr' => $contact['addr'], 'network' => $contact['network'],
-                                               'bd' => $contact['birthday'], 'gender' => $contact['gender'],
-                                               'keywords' => $contact['keywords'], 'alias' => $contact['alias'],
-                                               'contact-type' => $contact['contact-type'], 'url' => $contact['url'],
-                                               'location' => $contact['location'], 'about' => $contact['about']);
-
-                               dba::update('contact', $fields, array('id' => $r[0]["id"]), $old_contact);
-                       }
-               }
-
-               return $gcontact_id;
-       }
-
-       /**
-        * @brief Updates the gcontact entry from probe
-        *
-        * @param str $url profile link
-        * @return void
-        */
-       public static function updateFromProbe($url)
-       {
-               $data = Probe::uri($url);
-
-               if (in_array($data["network"], array(NETWORK_PHANTOM))) {
-                       logger("Invalid network for contact url ".$data["url"]." - Called by: ".System::callstack(), LOGGER_DEBUG);
-                       return;
-               }
-
-               $data["server_url"] = $data["baseurl"];
-
-               self::update($data);
-       }
-
-       /**
-        * @brief Update the gcontact entry for a given user id
-        *
-        * @param int $uid User ID
-        * @return void
-        */
-       public static function updateForUser($uid)
-       {
-               $r = q(
-                       "SELECT `profile`.`locality`, `profile`.`region`, `profile`.`country-name`,
-                               `profile`.`name`, `profile`.`about`, `profile`.`gender`,
-                               `profile`.`pub_keywords`, `profile`.`dob`, `profile`.`photo`,
-                               `profile`.`net-publish`, `user`.`nickname`, `user`.`hidewall`,
-                               `contact`.`notify`, `contact`.`url`, `contact`.`addr`
-                       FROM `profile`
-                               INNER JOIN `user` ON `user`.`uid` = `profile`.`uid`
-                               INNER JOIN `contact` ON `contact`.`uid` = `profile`.`uid`
-                       WHERE `profile`.`uid` = %d AND `profile`.`is-default` AND `contact`.`self`",
-                       intval($uid)
-               );
-
-               $location = Profile::formatLocation(
-                       array("locality" => $r[0]["locality"], "region" => $r[0]["region"], "country-name" => $r[0]["country-name"])
-               );
-
-               // The "addr" field was added in 3.4.3 so it can be empty for older users
-               if ($r[0]["addr"] != "") {
-                       $addr = $r[0]["nickname"].'@'.str_replace(array("http://", "https://"), "", System::baseUrl());
-               } else {
-                       $addr = $r[0]["addr"];
-               }
-
-               $gcontact = array("name" => $r[0]["name"], "location" => $location, "about" => $r[0]["about"],
-                               "gender" => $r[0]["gender"], "keywords" => $r[0]["pub_keywords"],
-                               "birthday" => $r[0]["dob"], "photo" => $r[0]["photo"],
-                               "notify" => $r[0]["notify"], "url" => $r[0]["url"],
-                               "hide" => ($r[0]["hidewall"] || !$r[0]["net-publish"]),
-                               "nick" => $r[0]["nickname"], "addr" => $addr,
-                               "connect" => $addr, "server_url" => System::baseUrl(),
-                               "generation" => 1, "network" => NETWORK_DFRN);
-
-               self::update($gcontact);
-       }
-
-       /**
-        * @brief Fetches users of given GNU Social server
-        *
-        * If the "Statistics" plugin is enabled (See http://gstools.org/ for details) we query user data with this.
-        *
-        * @param str $server Server address
-        * @return void
-        */
-       public static function fetchGsUsers($server)
-       {
-               logger("Fetching users from GNU Social server ".$server, LOGGER_DEBUG);
-
-               $url = $server."/main/statistics";
-
-               $result = z_fetch_url($url);
-               if (!$result["success"]) {
-                       return false;
-               }
-
-               $statistics = json_decode($result["body"]);
-
-               if (is_object($statistics->config)) {
-                       if ($statistics->config->instance_with_ssl) {
-                               $server = "https://";
-                       } else {
-                               $server = "http://";
-                       }
-
-                       $server .= $statistics->config->instance_address;
-
-                       $hostname = $statistics->config->instance_address;
-               } else {
-                       /// @TODO is_object() above means here no object, still $statistics is being used as object
-                       if ($statistics->instance_with_ssl) {
-                               $server = "https://";
-                       } else {
-                               $server = "http://";
-                       }
-
-                       $server .= $statistics->instance_address;
-
-                       $hostname = $statistics->instance_address;
-               }
-
-               if (is_object($statistics->users)) {
-                       foreach ($statistics->users as $nick => $user) {
-                               $profile_url = $server."/".$user->nickname;
-
-                               $contact = array("url" => $profile_url,
-                                               "name" => $user->fullname,
-                                               "addr" => $user->nickname."@".$hostname,
-                                               "nick" => $user->nickname,
-                                               "about" => $user->bio,
-                                               "network" => NETWORK_OSTATUS,
-                                               "photo" => System::baseUrl()."/images/person-175.jpg");
-                               self::getId($contact);
-                       }
-               }
-       }
-
-       /**
-        * @brief Asking GNU Social server on a regular base for their user data
-        * @return void
-        */
-       public static function discoverGsUsers()
-       {
-               $requery_days = intval(Config::get("system", "poco_requery_days"));
-
-               $last_update = date("c", time() - (60 * 60 * 24 * $requery_days));
-
-               $r = q(
-                       "SELECT `nurl`, `url` FROM `gserver` WHERE `last_contact` >= `last_failure` AND `network` = '%s' AND `last_poco_query` < '%s' ORDER BY RAND() LIMIT 5",
-                       dbesc(NETWORK_OSTATUS),
-                       dbesc($last_update)
-               );
-
-               if (!DBM::is_result($r)) {
-                       return;
-               }
-
-               foreach ($r as $server) {
-                       self::fetchGsUsers($server["url"]);
-                       q("UPDATE `gserver` SET `last_poco_query` = '%s' WHERE `nurl` = '%s'", dbesc(datetime_convert()), dbesc($server["nurl"]));
-               }
-       }
-
-       /**
-        * @return string
-        */
-       public static function getRandomUrl()
-       {
-               $r = q(
-                       "SELECT `url` FROM `gcontact` WHERE `network` = '%s'
-                                       AND `last_contact` >= `last_failure`
-                                       AND `updated` > UTC_TIMESTAMP - INTERVAL 1 MONTH
-                               ORDER BY rand() LIMIT 1",
-                       dbesc(NETWORK_DFRN)
-               );
-
-               if (DBM::is_result($r)) {
-                       return dirname($r[0]['url']);
-               }
-
-               return '';
-       }
-}
diff --git a/src/Model/GlobalContact.php b/src/Model/GlobalContact.php
new file mode 100644 (file)
index 0000000..6ec1101
--- /dev/null
@@ -0,0 +1,1076 @@
+<?php
+/**
+ * @file src/Model/GlobalContact.php
+ * @brief This file includes the GlobalContact class with directory related functions
+ */
+namespace Friendica\Model;
+
+use Friendica\Core\Config;
+use Friendica\Core\System;
+use Friendica\Core\Worker;
+use Friendica\Database\DBM;
+use Friendica\Network\Probe;
+use Friendica\Object\Contact;
+use Friendica\Object\Profile;
+use Friendica\Protocol\PortableContact;
+use dba;
+use Exception;
+
+require_once 'include/datetime.php';
+require_once 'include/network.php';
+require_once 'include/html2bbcode.php';
+
+/**
+ * @brief This class handles GlobalContact related functions
+ */
+class GlobalContact
+{
+       /**
+        * @brief Search global contact table by nick or name
+        *
+        * @param string $search Name or nick
+        * @param string $mode   Search mode (e.g. "community")
+        *
+        * @return array with search results
+        */
+       public static function searchByName($search, $mode = '')
+       {
+               if ($search) {
+                       // check supported networks
+                       if (Config::get('system', 'diaspora_enabled')) {
+                               $diaspora = NETWORK_DIASPORA;
+                       } else {
+                               $diaspora = NETWORK_DFRN;
+                       }
+
+                       if (!Config::get('system', 'ostatus_disabled')) {
+                               $ostatus = NETWORK_OSTATUS;
+                       } else {
+                               $ostatus = NETWORK_DFRN;
+                       }
+
+                       // check if we search only communities or every contact
+                       if ($mode === "community") {
+                               $extra_sql = " AND `community`";
+                       } else {
+                               $extra_sql = "";
+                       }
+
+                       $search .= "%";
+
+                       $results = q(
+                               "SELECT `contact`.`id` AS `cid`, `gcontact`.`url`, `gcontact`.`name`, `gcontact`.`nick`, `gcontact`.`photo`,
+                                               `gcontact`.`network`, `gcontact`.`keywords`, `gcontact`.`addr`, `gcontact`.`community`
+                               FROM `gcontact`
+                               LEFT JOIN `contact` ON `contact`.`nurl` = `gcontact`.`nurl`
+                                       AND `contact`.`uid` = %d AND NOT `contact`.`blocked`
+                                       AND NOT `contact`.`pending` AND `contact`.`rel` IN ('%s', '%s')
+                               WHERE (`contact`.`id` > 0 OR (NOT `gcontact`.`hide` AND `gcontact`.`network` IN ('%s', '%s', '%s') AND
+                               ((`gcontact`.`last_contact` >= `gcontact`.`last_failure`) OR
+                               (`gcontact`.`updated` >= `gcontact`.`last_failure`)))) AND
+                               (`gcontact`.`addr` LIKE '%s' OR `gcontact`.`name` LIKE '%s' OR `gcontact`.`nick` LIKE '%s') $extra_sql
+                                       GROUP BY `gcontact`.`nurl`
+                                       ORDER BY `gcontact`.`nurl` DESC
+                                       LIMIT 1000",
+                               intval(local_user()),
+                               dbesc(CONTACT_IS_SHARING),
+                               dbesc(CONTACT_IS_FRIEND),
+                               dbesc(NETWORK_DFRN),
+                               dbesc($ostatus),
+                               dbesc($diaspora),
+                               dbesc(escape_tags($search)),
+                               dbesc(escape_tags($search)),
+                               dbesc(escape_tags($search))
+                       );
+
+                       return $results;
+               }
+       }
+
+       /**
+        * @brief Link the gcontact entry with user, contact and global contact
+        *
+        * @param integer $gcid Global contact ID
+        * @param integer $uid  User ID
+        * @param integer $cid  Contact ID
+        * @param integer $zcid Global Contact ID
+        * @return void
+        */
+       public static function link($gcid, $uid = 0, $cid = 0, $zcid = 0)
+       {
+               if ($gcid <= 0) {
+                       return;
+               }
+
+               $r = q(
+                       "SELECT * FROM `glink` WHERE `cid` = %d AND `uid` = %d AND `gcid` = %d AND `zcid` = %d LIMIT 1",
+                       intval($cid),
+                       intval($uid),
+                       intval($gcid),
+                       intval($zcid)
+               );
+
+               if (!DBM::is_result($r)) {
+                       q(
+                               "INSERT INTO `glink` (`cid`, `uid`, `gcid`, `zcid`, `updated`) VALUES (%d, %d, %d, %d, '%s') ",
+                               intval($cid),
+                               intval($uid),
+                               intval($gcid),
+                               intval($zcid),
+                               dbesc(datetime_convert())
+                       );
+               } else {
+                       q(
+                               "UPDATE `glink` SET `updated` = '%s' WHERE `cid` = %d AND `uid` = %d AND `gcid` = %d AND `zcid` = %d",
+                               dbesc(datetime_convert()),
+                               intval($cid),
+                               intval($uid),
+                               intval($gcid),
+                               intval($zcid)
+                       );
+               }
+       }
+
+       /**
+        * @brief Sanitize the given gcontact data
+        *
+        * @param array $gcontact array with gcontact data
+        * @throw Exception
+        *
+        * Generation:
+        *  0: No definition
+        *  1: Profiles on this server
+        *  2: Contacts of profiles on this server
+        *  3: Contacts of contacts of profiles on this server
+        *  4: ...
+        * @return array $gcontact
+        */
+       public static function sanitize($gcontact)
+       {
+               if ($gcontact['url'] == "") {
+                       throw new Exception('URL is empty');
+               }
+
+               $urlparts = parse_url($gcontact['url']);
+               if (!isset($urlparts["scheme"])) {
+                       throw new Exception("This (".$gcontact['url'].") doesn't seem to be an url.");
+               }
+
+               if (in_array($urlparts["host"], array("www.facebook.com", "facebook.com", "twitter.com", "identi.ca", "alpha.app.net"))) {
+                       throw new Exception('Contact from a non federated network ignored. ('.$gcontact['url'].')');
+               }
+
+               // Don't store the statusnet connector as network
+               // We can't simply set this to NETWORK_OSTATUS since the connector could have fetched posts from friendica as well
+               if ($gcontact['network'] == NETWORK_STATUSNET) {
+                       $gcontact['network'] = "";
+               }
+
+               // Assure that there are no parameter fragments in the profile url
+               if (in_array($gcontact['network'], array(NETWORK_DFRN, NETWORK_DIASPORA, NETWORK_OSTATUS, ""))) {
+                       $gcontact['url'] = self::cleanContactUrl($gcontact['url']);
+               }
+
+               $alternate = PortableContact::alternateOStatusUrl($gcontact['url']);
+
+               // The global contacts should contain the original picture, not the cached one
+               if (($gcontact['generation'] != 1) && stristr(normalise_link($gcontact['photo']), normalise_link(System::baseUrl()."/photo/"))) {
+                       $gcontact['photo'] = "";
+               }
+
+               if (!isset($gcontact['network'])) {
+                       $r = q(
+                               "SELECT `network` FROM `contact` WHERE `uid` = 0 AND `nurl` = '%s' AND `network` != '' AND `network` != '%s' LIMIT 1",
+                               dbesc(normalise_link($gcontact['url'])),
+                               dbesc(NETWORK_STATUSNET)
+                       );
+                       if (DBM::is_result($r)) {
+                               $gcontact['network'] = $r[0]["network"];
+                       }
+
+                       if (($gcontact['network'] == "") || ($gcontact['network'] == NETWORK_OSTATUS)) {
+                               $r = q(
+                                       "SELECT `network`, `url` FROM `contact` WHERE `uid` = 0 AND `alias` IN ('%s', '%s') AND `network` != '' AND `network` != '%s' LIMIT 1",
+                                       dbesc($gcontact['url']),
+                                       dbesc(normalise_link($gcontact['url'])),
+                                       dbesc(NETWORK_STATUSNET)
+                               );
+                               if (DBM::is_result($r)) {
+                                       $gcontact['network'] = $r[0]["network"];
+                               }
+                       }
+               }
+
+               $gcontact['server_url'] = '';
+               $gcontact['network'] = '';
+
+               $x = q(
+                       "SELECT * FROM `gcontact` WHERE `nurl` = '%s' LIMIT 1",
+                       dbesc(normalise_link($gcontact['url']))
+               );
+
+               if (DBM::is_result($x)) {
+                       if (!isset($gcontact['network']) && ($x[0]["network"] != NETWORK_STATUSNET)) {
+                               $gcontact['network'] = $x[0]["network"];
+                       }
+                       if ($gcontact['updated'] <= NULL_DATE) {
+                               $gcontact['updated'] = $x[0]["updated"];
+                       }
+                       if (!isset($gcontact['server_url']) && (normalise_link($x[0]["server_url"]) != normalise_link($x[0]["url"]))) {
+                               $gcontact['server_url'] = $x[0]["server_url"];
+                       }
+                       if (!isset($gcontact['addr'])) {
+                               $gcontact['addr'] = $x[0]["addr"];
+                       }
+               }
+
+               if ((!isset($gcontact['network']) || !isset($gcontact['name']) || !isset($gcontact['addr']) || !isset($gcontact['photo']) || !isset($gcontact['server_url']) || $alternate)
+                       && PortableContact::reachable($gcontact['url'], $gcontact['server_url'], $gcontact['network'], false)
+               ) {
+                       $data = Probe::uri($gcontact['url']);
+
+                       if ($data["network"] == NETWORK_PHANTOM) {
+                               throw new Exception('Probing for URL '.$gcontact['url'].' failed');
+                       }
+
+                       $orig_profile = $gcontact['url'];
+
+                       $gcontact["server_url"] = $data["baseurl"];
+
+                       $gcontact = array_merge($gcontact, $data);
+
+                       if ($alternate && ($gcontact['network'] == NETWORK_OSTATUS)) {
+                               // Delete the old entry - if it exists
+                               $r = q("SELECT `id` FROM `gcontact` WHERE `nurl` = '%s'", dbesc(normalise_link($orig_profile)));
+                               if (DBM::is_result($r)) {
+                                       q("DELETE FROM `gcontact` WHERE `nurl` = '%s'", dbesc(normalise_link($orig_profile)));
+                                       q("DELETE FROM `glink` WHERE `gcid` = %d", intval($r[0]["id"]));
+                               }
+                       }
+               }
+
+               if (!isset($gcontact['name']) || !isset($gcontact['photo'])) {
+                       throw new Exception('No name and photo for URL '.$gcontact['url']);
+               }
+
+               if (!in_array($gcontact['network'], array(NETWORK_DFRN, NETWORK_OSTATUS, NETWORK_DIASPORA))) {
+                       throw new Exception('No federated network ('.$gcontact['network'].') detected for URL '.$gcontact['url']);
+               }
+
+               if (!isset($gcontact['server_url'])) {
+                       // We check the server url to be sure that it is a real one
+                       $server_url = PortableContact::detectServer($gcontact['url']);
+
+                       // We are now sure that it is a correct URL. So we use it in the future
+                       if ($server_url != "") {
+                               $gcontact['server_url'] = $server_url;
+                       }
+               }
+
+               // The server URL doesn't seem to be valid, so we don't store it.
+               if (!PortableContact::checkServer($gcontact['server_url'], $gcontact['network'])) {
+                       $gcontact['server_url'] = "";
+               }
+
+               return $gcontact;
+       }
+
+       /**
+        * @param integer $uid id
+        * @param integer $cid id
+        * @return integer
+        */
+       public static function countCommonFriends($uid, $cid)
+       {
+               $r = q(
+                       "SELECT count(*) as `total`
+                       FROM `glink` INNER JOIN `gcontact` on `glink`.`gcid` = `gcontact`.`id`
+                       WHERE `glink`.`cid` = %d AND `glink`.`uid` = %d AND
+                       ((`gcontact`.`last_contact` >= `gcontact`.`last_failure`) OR
+                       (`gcontact`.`updated` >= `gcontact`.`last_failure`))
+                       AND `gcontact`.`nurl` IN (select nurl from contact where uid = %d and self = 0 and blocked = 0 and hidden = 0 and id != %d ) ",
+                       intval($cid),
+                       intval($uid),
+                       intval($uid),
+                       intval($cid)
+               );
+
+               // logger("countCommonFriends: $uid $cid {$r[0]['total']}");
+               if (DBM::is_result($r)) {
+                       return $r[0]['total'];
+               }
+               return 0;
+       }
+
+       /**
+        * @param integer $uid  id
+        * @param integer $zcid zcid
+        * @return integer
+        */
+       public static function countCommonFriendsZcid($uid, $zcid)
+       {
+               $r = q(
+                       "SELECT count(*) as `total`
+                       FROM `glink` INNER JOIN `gcontact` on `glink`.`gcid` = `gcontact`.`id`
+                       where `glink`.`zcid` = %d
+                       and `gcontact`.`nurl` in (select nurl from contact where uid = %d and self = 0 and blocked = 0 and hidden = 0 ) ",
+                       intval($zcid),
+                       intval($uid)
+               );
+
+               if (DBM::is_result($r)) {
+                       return $r[0]['total'];
+               }
+
+               return 0;
+       }
+
+       /**
+        * @param object  $uid     user
+        * @param object  $cid     cid
+        * @param integer $start   optional, default 0
+        * @param integer $limit   optional, default 9999
+        * @param boolean $shuffle optional, default false
+        * @return object
+        */
+       public static function commonFriends($uid, $cid, $start = 0, $limit = 9999, $shuffle = false)
+       {
+               if ($shuffle) {
+                       $sql_extra = " order by rand() ";
+               } else {
+                       $sql_extra = " order by `gcontact`.`name` asc ";
+               }
+
+               $r = q(
+                       "SELECT `gcontact`.*, `contact`.`id` AS `cid`
+                       FROM `glink`
+                       INNER JOIN `gcontact` ON `glink`.`gcid` = `gcontact`.`id`
+                       INNER JOIN `contact` ON `gcontact`.`nurl` = `contact`.`nurl`
+                       WHERE `glink`.`cid` = %d and `glink`.`uid` = %d
+                               AND `contact`.`uid` = %d AND `contact`.`self` = 0 AND `contact`.`blocked` = 0
+                               AND `contact`.`hidden` = 0 AND `contact`.`id` != %d
+                               AND ((`gcontact`.`last_contact` >= `gcontact`.`last_failure`) OR (`gcontact`.`updated` >= `gcontact`.`last_failure`))
+                               $sql_extra LIMIT %d, %d",
+                       intval($cid),
+                       intval($uid),
+                       intval($uid),
+                       intval($cid),
+                       intval($start),
+                       intval($limit)
+               );
+
+               /// @TODO Check all calling-findings of this function if they properly use DBM::is_result()
+               return $r;
+       }
+
+       /**
+        * @param object  $uid     user
+        * @param object  $zcid    zcid
+        * @param integer $start   optional, default 0
+        * @param integer $limit   optional, default 9999
+        * @param boolean $shuffle optional, default false
+        * @return object
+        */
+       public static function commonFriendsZcid($uid, $zcid, $start = 0, $limit = 9999, $shuffle = false)
+       {
+               if ($shuffle) {
+                       $sql_extra = " order by rand() ";
+               } else {
+                       $sql_extra = " order by `gcontact`.`name` asc ";
+               }
+
+               $r = q(
+                       "SELECT `gcontact`.*
+                       FROM `glink` INNER JOIN `gcontact` on `glink`.`gcid` = `gcontact`.`id`
+                       where `glink`.`zcid` = %d
+                       and `gcontact`.`nurl` in (select nurl from contact where uid = %d and self = 0 and blocked = 0 and hidden = 0 )
+                       $sql_extra limit %d, %d",
+                       intval($zcid),
+                       intval($uid),
+                       intval($start),
+                       intval($limit)
+               );
+
+               /// @TODO Check all calling-findings of this function if they properly use DBM::is_result()
+               return $r;
+       }
+
+       /**
+        * @param object $uid user
+        * @param object $cid cid
+        * @return integer
+        */
+       public static function countAllFriends($uid, $cid)
+       {
+               $r = q(
+                       "SELECT count(*) as `total`
+                       FROM `glink` INNER JOIN `gcontact` on `glink`.`gcid` = `gcontact`.`id`
+                       where `glink`.`cid` = %d and `glink`.`uid` = %d AND
+                       ((`gcontact`.`last_contact` >= `gcontact`.`last_failure`) OR (`gcontact`.`updated` >= `gcontact`.`last_failure`))",
+                       intval($cid),
+                       intval($uid)
+               );
+
+               if (DBM::is_result($r)) {
+                       return $r[0]['total'];
+               }
+
+               return 0;
+       }
+
+       /**
+        * @param object  $uid   user
+        * @param object  $cid   cid
+        * @param integer $start optional, default 0
+        * @param integer $limit optional, default 80
+        * @return object
+        */
+       public static function allFriends($uid, $cid, $start = 0, $limit = 80)
+       {
+               $r = q(
+                       "SELECT `gcontact`.*, `contact`.`id` AS `cid`
+                       FROM `glink`
+                       INNER JOIN `gcontact` on `glink`.`gcid` = `gcontact`.`id`
+                       LEFT JOIN `contact` ON `contact`.`nurl` = `gcontact`.`nurl` AND `contact`.`uid` = %d
+                       WHERE `glink`.`cid` = %d AND `glink`.`uid` = %d AND
+                       ((`gcontact`.`last_contact` >= `gcontact`.`last_failure`) OR (`gcontact`.`updated` >= `gcontact`.`last_failure`))
+                       ORDER BY `gcontact`.`name` ASC LIMIT %d, %d ",
+                       intval($uid),
+                       intval($cid),
+                       intval($uid),
+                       intval($start),
+                       intval($limit)
+               );
+
+               /// @TODO Check all calling-findings of this function if they properly use DBM::is_result()
+               return $r;
+       }
+
+       /**
+        * @param object  $uid   user
+        * @param integer $start optional, default 0
+        * @param integer $limit optional, default 80
+        * @return array
+        */
+       public static function suggestionQuery($uid, $start = 0, $limit = 80)
+       {
+               if (!$uid) {
+                       return array();
+               }
+
+               /*
+               * Uncommented because the result of the queries are to big to store it in the cache.
+               * We need to decide if we want to change the db column type or if we want to delete it.
+               */
+               //$list = Cache::get("suggestion_query:".$uid.":".$start.":".$limit);
+               //if (!is_null($list)) {
+               //      return $list;
+               //}
+
+               $network = array(NETWORK_DFRN);
+
+               if (Config::get('system', 'diaspora_enabled')) {
+                       $network[] = NETWORK_DIASPORA;
+               }
+
+               if (!Config::get('system', 'ostatus_disabled')) {
+                       $network[] = NETWORK_OSTATUS;
+               }
+
+               $sql_network = implode("', '", $network);
+               $sql_network = "'".$sql_network."'";
+
+               /// @todo This query is really slow
+               // By now we cache the data for five minutes
+               $r = q(
+                       "SELECT count(glink.gcid) as `total`, gcontact.* from gcontact
+                       INNER JOIN `glink` ON `glink`.`gcid` = `gcontact`.`id`
+                       where uid = %d and not gcontact.nurl in ( select nurl from contact where uid = %d )
+                       AND NOT `gcontact`.`name` IN (SELECT `name` FROM `contact` WHERE `uid` = %d)
+                       AND NOT `gcontact`.`id` IN (SELECT `gcid` FROM `gcign` WHERE `uid` = %d)
+                       AND `gcontact`.`updated` >= '%s'
+                       AND `gcontact`.`last_contact` >= `gcontact`.`last_failure`
+                       AND `gcontact`.`network` IN (%s)
+                       GROUP BY `glink`.`gcid` ORDER BY `gcontact`.`updated` DESC,`total` DESC LIMIT %d, %d",
+                       intval($uid),
+                       intval($uid),
+                       intval($uid),
+                       intval($uid),
+                       dbesc(NULL_DATE),
+                       $sql_network,
+                       intval($start),
+                       intval($limit)
+               );
+
+               if (DBM::is_result($r) && count($r) >= ($limit -1)) {
+                       /*
+                       * Uncommented because the result of the queries are to big to store it in the cache.
+                       * We need to decide if we want to change the db column type or if we want to delete it.
+                       */
+                       //Cache::set("suggestion_query:".$uid.":".$start.":".$limit, $r, CACHE_FIVE_MINUTES);
+
+                       return $r;
+               }
+
+               $r2 = q(
+                       "SELECT gcontact.* FROM gcontact
+                       INNER JOIN `glink` ON `glink`.`gcid` = `gcontact`.`id`
+                       WHERE `glink`.`uid` = 0 AND `glink`.`cid` = 0 AND `glink`.`zcid` = 0 AND NOT `gcontact`.`nurl` IN (SELECT `nurl` FROM `contact` WHERE `uid` = %d)
+                       AND NOT `gcontact`.`name` IN (SELECT `name` FROM `contact` WHERE `uid` = %d)
+                       AND NOT `gcontact`.`id` IN (SELECT `gcid` FROM `gcign` WHERE `uid` = %d)
+                       AND `gcontact`.`updated` >= '%s'
+                       AND `gcontact`.`last_contact` >= `gcontact`.`last_failure`
+                       AND `gcontact`.`network` IN (%s)
+                       ORDER BY rand() LIMIT %d, %d",
+                       intval($uid),
+                       intval($uid),
+                       intval($uid),
+                       dbesc(NULL_DATE),
+                       $sql_network,
+                       intval($start),
+                       intval($limit)
+               );
+
+               $list = array();
+               foreach ($r2 as $suggestion) {
+                       $list[$suggestion["nurl"]] = $suggestion;
+               }
+
+               foreach ($r as $suggestion) {
+                       $list[$suggestion["nurl"]] = $suggestion;
+               }
+
+               while (sizeof($list) > ($limit)) {
+                       array_pop($list);
+               }
+
+               /*
+               * Uncommented because the result of the queries are to big to store it in the cache.
+               * We need to decide if we want to change the db column type or if we want to delete it.
+               */
+               //Cache::set("suggestion_query:".$uid.":".$start.":".$limit, $list, CACHE_FIVE_MINUTES);
+               return $list;
+       }
+
+       /**
+        * @return void
+        */
+       public static function updateSuggestions()
+       {
+               $a = get_app();
+
+               $done = array();
+
+               /// @TODO Check if it is really neccessary to poll the own server
+               PortableContact::loadWorker(0, 0, 0, System::baseUrl() . '/poco');
+
+               $done[] = System::baseUrl() . '/poco';
+
+               if (strlen(Config::get('system', 'directory'))) {
+                       $x = fetch_url(get_server()."/pubsites");
+                       if ($x) {
+                               $j = json_decode($x);
+                               if ($j->entries) {
+                                       foreach ($j->entries as $entry) {
+                                               PortableContact::checkServer($entry->url);
+
+                                               $url = $entry->url . '/poco';
+                                               if (! in_array($url, $done)) {
+                                                       PortableContact::loadWorker(0, 0, 0, $entry->url . '/poco');
+                                               }
+                                       }
+                               }
+                       }
+               }
+
+               // Query your contacts from Friendica and Redmatrix/Hubzilla for their contacts
+               $r = q(
+                       "SELECT DISTINCT(`poco`) AS `poco` FROM `contact` WHERE `network` IN ('%s', '%s')",
+                       dbesc(NETWORK_DFRN),
+                       dbesc(NETWORK_DIASPORA)
+               );
+
+               if (DBM::is_result($r)) {
+                       foreach ($r as $rr) {
+                               $base = substr($rr['poco'], 0, strrpos($rr['poco'], '/'));
+                               if (! in_array($base, $done)) {
+                                       PortableContact::loadWorker(0, 0, 0, $base);
+                               }
+                       }
+               }
+       }
+
+       /**
+        * @brief Removes unwanted parts from a contact url
+        *
+        * @param string $url Contact url
+        *
+        * @return string Contact url with the wanted parts
+        */
+       public static function cleanContactUrl($url)
+       {
+               $parts = parse_url($url);
+
+               if (!isset($parts["scheme"]) || !isset($parts["host"])) {
+                       return $url;
+               }
+
+               $new_url = $parts["scheme"]."://".$parts["host"];
+
+               if (isset($parts["port"])) {
+                       $new_url .= ":".$parts["port"];
+               }
+
+               if (isset($parts["path"])) {
+                       $new_url .= $parts["path"];
+               }
+
+               if ($new_url != $url) {
+                       logger("Cleaned contact url ".$url." to ".$new_url." - Called by: ".System::callstack(), LOGGER_DEBUG);
+               }
+
+               return $new_url;
+       }
+
+       /**
+        * @brief Replace alternate OStatus user format with the primary one
+        *
+        * @param arr $contact contact array (called by reference)
+        * @return void
+        */
+       public static function fixAlternateContactAddress(&$contact)
+       {
+               if (($contact["network"] == NETWORK_OSTATUS) && PortableContact::alternateOStatusUrl($contact["url"])) {
+                       $data = Probe::uri($contact["url"]);
+                       if ($contact["network"] == NETWORK_OSTATUS) {
+                               logger("Fix primary url from ".$contact["url"]." to ".$data["url"]." - Called by: ".System::callstack(), LOGGER_DEBUG);
+                               $contact["url"] = $data["url"];
+                               $contact["addr"] = $data["addr"];
+                               $contact["alias"] = $data["alias"];
+                               $contact["server_url"] = $data["baseurl"];
+                       }
+               }
+       }
+
+       /**
+        * @brief Fetch the gcontact id, add an entry if not existed
+        *
+        * @param arr $contact contact array
+        *
+        * @return bool|int Returns false if not found, integer if contact was found
+        */
+       public static function getId($contact)
+       {
+               $gcontact_id = 0;
+               $doprobing = false;
+
+               if (in_array($contact["network"], array(NETWORK_PHANTOM))) {
+                       logger("Invalid network for contact url ".$contact["url"]." - Called by: ".System::callstack(), LOGGER_DEBUG);
+                       return false;
+               }
+
+               if ($contact["network"] == NETWORK_STATUSNET) {
+                       $contact["network"] = NETWORK_OSTATUS;
+               }
+
+               // All new contacts are hidden by default
+               if (!isset($contact["hide"])) {
+                       $contact["hide"] = true;
+               }
+
+               // Replace alternate OStatus user format with the primary one
+               self::fixAlternateContactAddress($contact);
+
+               // Remove unwanted parts from the contact url (e.g. "?zrl=...")
+               if (in_array($contact["network"], array(NETWORK_DFRN, NETWORK_DIASPORA, NETWORK_OSTATUS))) {
+                       $contact["url"] = self::cleanContactUrl($contact["url"]);
+               }
+
+               dba::lock('gcontact');
+               $r = q(
+                       "SELECT `id`, `last_contact`, `last_failure`, `network` FROM `gcontact` WHERE `nurl` = '%s' LIMIT 1",
+                       dbesc(normalise_link($contact["url"]))
+               );
+
+               if (DBM::is_result($r)) {
+                       $gcontact_id = $r[0]["id"];
+
+                       // Update every 90 days
+                       if (in_array($r[0]["network"], array(NETWORK_DFRN, NETWORK_DIASPORA, NETWORK_OSTATUS, ""))) {
+                               $last_failure_str = $r[0]["last_failure"];
+                               $last_failure = strtotime($r[0]["last_failure"]);
+                               $last_contact_str = $r[0]["last_contact"];
+                               $last_contact = strtotime($r[0]["last_contact"]);
+                               $doprobing = (((time() - $last_contact) > (90 * 86400)) && ((time() - $last_failure) > (90 * 86400)));
+                       }
+               } else {
+                       q(
+                               "INSERT INTO `gcontact` (`name`, `nick`, `addr` , `network`, `url`, `nurl`, `photo`, `created`, `updated`, `location`, `about`, `hide`, `generation`)
+                               VALUES ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d)",
+                               dbesc($contact["name"]),
+                               dbesc($contact["nick"]),
+                               dbesc($contact["addr"]),
+                               dbesc($contact["network"]),
+                               dbesc($contact["url"]),
+                               dbesc(normalise_link($contact["url"])),
+                               dbesc($contact["photo"]),
+                               dbesc(datetime_convert()),
+                               dbesc(datetime_convert()),
+                               dbesc($contact["location"]),
+                               dbesc($contact["about"]),
+                               intval($contact["hide"]),
+                               intval($contact["generation"])
+                       );
+
+                       $r = q(
+                               "SELECT `id`, `network` FROM `gcontact` WHERE `nurl` = '%s' ORDER BY `id` LIMIT 2",
+                               dbesc(normalise_link($contact["url"]))
+                       );
+
+                       if (DBM::is_result($r)) {
+                               $gcontact_id = $r[0]["id"];
+
+                               $doprobing = in_array($r[0]["network"], array(NETWORK_DFRN, NETWORK_DIASPORA, NETWORK_OSTATUS, ""));
+                       }
+               }
+               dba::unlock();
+
+               if ($doprobing) {
+                       logger("Last Contact: ". $last_contact_str." - Last Failure: ".$last_failure_str." - Checking: ".$contact["url"], LOGGER_DEBUG);
+                       Worker::add(PRIORITY_LOW, 'GProbe', $contact["url"]);
+               }
+
+               return $gcontact_id;
+       }
+
+       /**
+        * @brief Updates the gcontact table from a given array
+        *
+        * @param arr $contact contact array
+        *
+        * @return bool|int Returns false if not found, integer if contact was found
+        */
+       public static function update($contact)
+       {
+               // Check for invalid "contact-type" value
+               if (isset($contact['contact-type']) && (intval($contact['contact-type']) < 0)) {
+                       $contact['contact-type'] = 0;
+               }
+
+               /// @todo update contact table as well
+
+               $gcontact_id = self::getId($contact);
+
+               if (!$gcontact_id) {
+                       return false;
+               }
+
+               $r = q(
+                       "SELECT `name`, `nick`, `photo`, `location`, `about`, `addr`, `generation`, `birthday`, `gender`, `keywords`,
+                               `contact-type`, `hide`, `nsfw`, `network`, `alias`, `notify`, `server_url`, `connect`, `updated`, `url`
+                       FROM `gcontact` WHERE `id` = %d LIMIT 1",
+                       intval($gcontact_id)
+               );
+
+               // Get all field names
+               $fields = array();
+               foreach ($r[0] as $field => $data) {
+                       $fields[$field] = $data;
+               }
+
+               unset($fields["url"]);
+               unset($fields["updated"]);
+               unset($fields["hide"]);
+
+               // Bugfix: We had an error in the storing of keywords which lead to the "0"
+               // This value is still transmitted via poco.
+               if ($contact["keywords"] == "0") {
+                       unset($contact["keywords"]);
+               }
+
+               if ($r[0]["keywords"] == "0") {
+                       $r[0]["keywords"] = "";
+               }
+
+               // assign all unassigned fields from the database entry
+               foreach ($fields as $field => $data) {
+                       if (!isset($contact[$field]) || ($contact[$field] == "")) {
+                               $contact[$field] = $r[0][$field];
+                       }
+               }
+
+               if (!isset($contact["hide"])) {
+                       $contact["hide"] = $r[0]["hide"];
+               }
+
+               $fields["hide"] = $r[0]["hide"];
+
+               if ($contact["network"] == NETWORK_STATUSNET) {
+                       $contact["network"] = NETWORK_OSTATUS;
+               }
+
+               // Replace alternate OStatus user format with the primary one
+               self::fixAlternateContactAddress($contact);
+
+               if (!isset($contact["updated"])) {
+                       $contact["updated"] = DBM::date();
+               }
+
+               if ($contact["network"] == NETWORK_TWITTER) {
+                       $contact["server_url"] = 'http://twitter.com';
+               }
+
+               if ($contact["server_url"] == "") {
+                       $data = Probe::uri($contact["url"]);
+                       if ($data["network"] != NETWORK_PHANTOM) {
+                               $contact["server_url"] = $data['baseurl'];
+                       }
+               } else {
+                       $contact["server_url"] = normalise_link($contact["server_url"]);
+               }
+
+               if (($contact["addr"] == "") && ($contact["server_url"] != "") && ($contact["nick"] != "")) {
+                       $hostname = str_replace("http://", "", $contact["server_url"]);
+                       $contact["addr"] = $contact["nick"]."@".$hostname;
+               }
+
+               // Check if any field changed
+               $update = false;
+               unset($fields["generation"]);
+
+               if ((($contact["generation"] > 0) && ($contact["generation"] <= $r[0]["generation"])) || ($r[0]["generation"] == 0)) {
+                       foreach ($fields as $field => $data) {
+                               if ($contact[$field] != $r[0][$field]) {
+                                       logger("Difference for contact ".$contact["url"]." in field '".$field."'. New value: '".$contact[$field]."', old value '".$r[0][$field]."'", LOGGER_DEBUG);
+                                       $update = true;
+                               }
+                       }
+
+                       if ($contact["generation"] < $r[0]["generation"]) {
+                               logger("Difference for contact ".$contact["url"]." in field 'generation'. new value: '".$contact["generation"]."', old value '".$r[0]["generation"]."'", LOGGER_DEBUG);
+                               $update = true;
+                       }
+               }
+
+               if ($update) {
+                       logger("Update gcontact for ".$contact["url"], LOGGER_DEBUG);
+                       $condition = array('`nurl` = ? AND (`generation` = 0 OR `generation` >= ?)',
+                                       normalise_link($contact["url"]), $contact["generation"]);
+                       $contact["updated"] = DBM::date($contact["updated"]);
+
+                       $updated = array('photo' => $contact['photo'], 'name' => $contact['name'],
+                                       'nick' => $contact['nick'], 'addr' => $contact['addr'],
+                                       'network' => $contact['network'], 'birthday' => $contact['birthday'],
+                                       'gender' => $contact['gender'], 'keywords' => $contact['keywords'],
+                                       'hide' => $contact['hide'], 'nsfw' => $contact['nsfw'],
+                                       'contact-type' => $contact['contact-type'], 'alias' => $contact['alias'],
+                                       'notify' => $contact['notify'], 'url' => $contact['url'],
+                                       'location' => $contact['location'], 'about' => $contact['about'],
+                                       'generation' => $contact['generation'], 'updated' => $contact['updated'],
+                                       'server_url' => $contact['server_url'], 'connect' => $contact['connect']);
+
+                       dba::update('gcontact', $updated, $condition, $fields);
+
+                       // Now update the contact entry with the user id "0" as well.
+                       // This is used for the shadow copies of public items.
+                       $r = q(
+                               "SELECT `id` FROM `contact` WHERE `nurl` = '%s' AND `uid` = 0 ORDER BY `id` LIMIT 1",
+                               dbesc(normalise_link($contact["url"]))
+                       );
+
+                       if (DBM::is_result($r)) {
+                               logger("Update public contact ".$r[0]["id"], LOGGER_DEBUG);
+
+                               Contact::updateAvatar($contact["photo"], 0, $r[0]["id"]);
+
+                               $fields = array('name', 'nick', 'addr',
+                                               'network', 'bd', 'gender',
+                                               'keywords', 'alias', 'contact-type',
+                                               'url', 'location', 'about');
+                               $old_contact = dba::select('contact', $fields, array('id' => $r[0]["id"]), array('limit' => 1));
+
+                               // Update it with the current values
+                               $fields = array('name' => $contact['name'], 'nick' => $contact['nick'],
+                                               'addr' => $contact['addr'], 'network' => $contact['network'],
+                                               'bd' => $contact['birthday'], 'gender' => $contact['gender'],
+                                               'keywords' => $contact['keywords'], 'alias' => $contact['alias'],
+                                               'contact-type' => $contact['contact-type'], 'url' => $contact['url'],
+                                               'location' => $contact['location'], 'about' => $contact['about']);
+
+                               dba::update('contact', $fields, array('id' => $r[0]["id"]), $old_contact);
+                       }
+               }
+
+               return $gcontact_id;
+       }
+
+       /**
+        * @brief Updates the gcontact entry from probe
+        *
+        * @param str $url profile link
+        * @return void
+        */
+       public static function updateFromProbe($url)
+       {
+               $data = Probe::uri($url);
+
+               if (in_array($data["network"], array(NETWORK_PHANTOM))) {
+                       logger("Invalid network for contact url ".$data["url"]." - Called by: ".System::callstack(), LOGGER_DEBUG);
+                       return;
+               }
+
+               $data["server_url"] = $data["baseurl"];
+
+               self::update($data);
+       }
+
+       /**
+        * @brief Update the gcontact entry for a given user id
+        *
+        * @param int $uid User ID
+        * @return void
+        */
+       public static function updateForUser($uid)
+       {
+               $r = q(
+                       "SELECT `profile`.`locality`, `profile`.`region`, `profile`.`country-name`,
+                               `profile`.`name`, `profile`.`about`, `profile`.`gender`,
+                               `profile`.`pub_keywords`, `profile`.`dob`, `profile`.`photo`,
+                               `profile`.`net-publish`, `user`.`nickname`, `user`.`hidewall`,
+                               `contact`.`notify`, `contact`.`url`, `contact`.`addr`
+                       FROM `profile`
+                               INNER JOIN `user` ON `user`.`uid` = `profile`.`uid`
+                               INNER JOIN `contact` ON `contact`.`uid` = `profile`.`uid`
+                       WHERE `profile`.`uid` = %d AND `profile`.`is-default` AND `contact`.`self`",
+                       intval($uid)
+               );
+
+               $location = Profile::formatLocation(
+                       array("locality" => $r[0]["locality"], "region" => $r[0]["region"], "country-name" => $r[0]["country-name"])
+               );
+
+               // The "addr" field was added in 3.4.3 so it can be empty for older users
+               if ($r[0]["addr"] != "") {
+                       $addr = $r[0]["nickname"].'@'.str_replace(array("http://", "https://"), "", System::baseUrl());
+               } else {
+                       $addr = $r[0]["addr"];
+               }
+
+               $gcontact = array("name" => $r[0]["name"], "location" => $location, "about" => $r[0]["about"],
+                               "gender" => $r[0]["gender"], "keywords" => $r[0]["pub_keywords"],
+                               "birthday" => $r[0]["dob"], "photo" => $r[0]["photo"],
+                               "notify" => $r[0]["notify"], "url" => $r[0]["url"],
+                               "hide" => ($r[0]["hidewall"] || !$r[0]["net-publish"]),
+                               "nick" => $r[0]["nickname"], "addr" => $addr,
+                               "connect" => $addr, "server_url" => System::baseUrl(),
+                               "generation" => 1, "network" => NETWORK_DFRN);
+
+               self::update($gcontact);
+       }
+
+       /**
+        * @brief Fetches users of given GNU Social server
+        *
+        * If the "Statistics" plugin is enabled (See http://gstools.org/ for details) we query user data with this.
+        *
+        * @param str $server Server address
+        * @return void
+        */
+       public static function fetchGsUsers($server)
+       {
+               logger("Fetching users from GNU Social server ".$server, LOGGER_DEBUG);
+
+               $url = $server."/main/statistics";
+
+               $result = z_fetch_url($url);
+               if (!$result["success"]) {
+                       return false;
+               }
+
+               $statistics = json_decode($result["body"]);
+
+               if (is_object($statistics->config)) {
+                       if ($statistics->config->instance_with_ssl) {
+                               $server = "https://";
+                       } else {
+                               $server = "http://";
+                       }
+
+                       $server .= $statistics->config->instance_address;
+
+                       $hostname = $statistics->config->instance_address;
+               } else {
+                       /// @TODO is_object() above means here no object, still $statistics is being used as object
+                       if ($statistics->instance_with_ssl) {
+                               $server = "https://";
+                       } else {
+                               $server = "http://";
+                       }
+
+                       $server .= $statistics->instance_address;
+
+                       $hostname = $statistics->instance_address;
+               }
+
+               if (is_object($statistics->users)) {
+                       foreach ($statistics->users as $nick => $user) {
+                               $profile_url = $server."/".$user->nickname;
+
+                               $contact = array("url" => $profile_url,
+                                               "name" => $user->fullname,
+                                               "addr" => $user->nickname."@".$hostname,
+                                               "nick" => $user->nickname,
+                                               "about" => $user->bio,
+                                               "network" => NETWORK_OSTATUS,
+                                               "photo" => System::baseUrl()."/images/person-175.jpg");
+                               self::getId($contact);
+                       }
+               }
+       }
+
+       /**
+        * @brief Asking GNU Social server on a regular base for their user data
+        * @return void
+        */
+       public static function discoverGsUsers()
+       {
+               $requery_days = intval(Config::get("system", "poco_requery_days"));
+
+               $last_update = date("c", time() - (60 * 60 * 24 * $requery_days));
+
+               $r = q(
+                       "SELECT `nurl`, `url` FROM `gserver` WHERE `last_contact` >= `last_failure` AND `network` = '%s' AND `last_poco_query` < '%s' ORDER BY RAND() LIMIT 5",
+                       dbesc(NETWORK_OSTATUS),
+                       dbesc($last_update)
+               );
+
+               if (!DBM::is_result($r)) {
+                       return;
+               }
+
+               foreach ($r as $server) {
+                       self::fetchGsUsers($server["url"]);
+                       q("UPDATE `gserver` SET `last_poco_query` = '%s' WHERE `nurl` = '%s'", dbesc(datetime_convert()), dbesc($server["nurl"]));
+               }
+       }
+
+       /**
+        * @return string
+        */
+       public static function getRandomUrl()
+       {
+               $r = q(
+                       "SELECT `url` FROM `gcontact` WHERE `network` = '%s'
+                                       AND `last_contact` >= `last_failure`
+                                       AND `updated` > UTC_TIMESTAMP - INTERVAL 1 MONTH
+                               ORDER BY rand() LIMIT 1",
+                       dbesc(NETWORK_DFRN)
+               );
+
+               if (DBM::is_result($r)) {
+                       return dirname($r[0]['url']);
+               }
+
+               return '';
+       }
+}
diff --git a/src/Model/Photo.php b/src/Model/Photo.php
deleted file mode 100644 (file)
index 229f221..0000000
+++ /dev/null
@@ -1,174 +0,0 @@
-<?php
-
-/**
- * @file src/Model/Photo.php
- * @brief This file contains the Photo class for database interface
- */
-
-namespace Friendica\Model;
-
-use Friendica\Core\System;
-use Friendica\Database\DBM;
-use Friendica\Object\Image;
-use dba;
-
-require_once "include/photos.php";
-/**
- * Class to handle photo dabatase table
- */
-class Photo
-{
-       /**
-        * @param integer $uid       uid
-        * @param integer $cid       cid
-        * @param integer $rid       rid
-        * @param string  $filename  filename
-        * @param string  $album     album name
-        * @param integer $scale     scale
-        * @param integer $profile   optional, default = 0
-        * @param string  $allow_cid optional, default = ''
-        * @param string  $allow_gid optional, default = ''
-        * @param string  $deny_cid  optional, default = ''
-        * @param string  $deny_gid  optional, default = ''
-        * @param string  $desc      optional, default = ''
-        * @return object
-        */
-       public static function store(Image $Image, $uid, $cid, $rid, $filename, $album, $scale, $profile = 0, $allow_cid = '', $allow_gid = '', $deny_cid = '', $deny_gid = '', $desc = '')
-       {
-               $r = dba::select('photo', array('guid'), array("`resource-id` = ? AND `guid` != ?", $rid, ''), array('limit' => 1));
-               if (DBM::is_result($r)) {
-                       $guid = $r['guid'];
-               } else {
-                       $guid = get_guid();
-               }
-
-               $x = dba::select('photo', array('id'), array('resource-id' => $rid, 'uid' => $uid, 'contact-id' => $cid, 'scale' => $scale), array('limit' => 1));
-
-               $fields = array(
-                       'uid' => $uid,
-                       'contact-id' => $cid,
-                       'guid' => $guid,
-                       'resource-id' => $rid,
-                       'created' => datetime_convert(),
-                       'edited' => datetime_convert(),
-                       'filename' => basename($filename),
-                       'type' => $Image->getType(),
-                       'album' => $album,
-                       'height' => $Image->getHeight(),
-                       'width' => $Image->getWidth(),
-                       'datasize' => strlen($Image->asString()),
-                       'data' => $Image->asString(),
-                       'scale' => $scale,
-                       'profile' => $profile,
-                       'allow_cid' => $allow_cid,
-                       'allow_gid' => $allow_gid,
-                       'deny_cid' => $deny_cid,
-                       'deny_gid' => $deny_gid,
-                       'desc' => $desc
-               );
-
-               if (DBM::is_result($x)) {
-                       $r = dba::update('photo', $fields, array('id' => $x['id']));
-               } else {
-                       $r = dba::insert('photo', $fields);
-               }
-
-               return $r;
-       }
-
-       /**
-        * @param string  $photo         photo
-        * @param integer $uid           user id
-        * @param integer $cid           contact id
-        * @param boolean $quit_on_error optional, default false
-        * @return array
-        */
-       public static function importProfilePhoto($photo, $uid, $cid, $quit_on_error = false)
-       {
-               $r = dba::select(
-                       'photo', array('resource-id'), array('uid' => $uid, 'contact-id' => $cid, 'scale' => 4, 'album' => 'Contact Photos'), array('limit' => 1)
-               );
-
-               if (DBM::is_result($r) && strlen($r['resource-id'])) {
-                       $hash = $r['resource-id'];
-               } else {
-                       $hash = photo_new_resource();
-               }
-
-               $photo_failure = false;
-
-               $filename = basename($photo);
-               $img_str = fetch_url($photo, true);
-
-               if ($quit_on_error && ($img_str == "")) {
-                       return false;
-               }
-
-               $type = Image::guessType($photo, true);
-               $Image = new Image($img_str, $type);
-               if ($Image->isValid()) {
-                       $Image->scaleToSquare(175);
-
-                       $r = self::store($Image, $uid, $cid, $hash, $filename, 'Contact Photos', 4);
-
-                       if ($r === false) {
-                               $photo_failure = true;
-                       }
-
-                       $Image->scaleDown(80);
-
-                       $r = self::store($Image, $uid, $cid, $hash, $filename, 'Contact Photos', 5);
-
-                       if ($r === false) {
-                               $photo_failure = true;
-                       }
-
-                       $Image->scaleDown(48);
-
-                       $r = self::store($Image, $uid, $cid, $hash, $filename, 'Contact Photos', 6);
-
-                       if ($r === false) {
-                               $photo_failure = true;
-                       }
-
-                       $suffix = '?ts=' . time();
-
-                       $photo = System::baseUrl() . '/photo/' . $hash . '-4.' . $Image->getExt() . $suffix;
-                       $thumb = System::baseUrl() . '/photo/' . $hash . '-5.' . $Image->getExt() . $suffix;
-                       $micro = System::baseUrl() . '/photo/' . $hash . '-6.' . $Image->getExt() . $suffix;
-
-                       // Remove the cached photo
-                       $a = get_app();
-                       $basepath = $a->get_basepath();
-
-                       if (is_dir($basepath . "/photo")) {
-                               $filename = $basepath . '/photo/' . $hash . '-4.' . $Image->getExt();
-                               if (file_exists($filename)) {
-                                       unlink($filename);
-                               }
-                               $filename = $basepath . '/photo/' . $hash . '-5.' . $Image->getExt();
-                               if (file_exists($filename)) {
-                                       unlink($filename);
-                               }
-                               $filename = $basepath . '/photo/' . $hash . '-6.' . $Image->getExt();
-                               if (file_exists($filename)) {
-                                       unlink($filename);
-                               }
-                       }
-               } else {
-                       $photo_failure = true;
-               }
-
-               if ($photo_failure && $quit_on_error) {
-                       return false;
-               }
-
-               if ($photo_failure) {
-                       $photo = System::baseUrl() . '/images/person-175.jpg';
-                       $thumb = System::baseUrl() . '/images/person-80.jpg';
-                       $micro = System::baseUrl() . '/images/person-48.jpg';
-               }
-
-               return array($photo, $thumb, $micro);
-       }
-}
diff --git a/src/Model/Profile.php b/src/Model/Profile.php
deleted file mode 100644 (file)
index 0916e66..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-<?php
-
-/**
- * @file src/Model/Profile.php
- */
-
-namespace Friendica\Model;
-
-class Profile
-{
-       /**
-        * @brief Returns a formatted location string from the given profile array
-        *
-        * @param array $profile Profile array (Generated from the "profile" table)
-        *
-        * @return string Location string
-        */
-       public static function formatLocation(array $profile)
-       {
-               $location = '';
-
-               if ($profile['locality']) {
-                       $location .= $profile['locality'];
-               }
-
-               if ($profile['region'] && ($profile['locality'] != $profile['region'])) {
-                       if ($location) {
-                               $location .= ', ';
-                       }
-
-                       $location .= $profile['region'];
-               }
-
-               if ($profile['country-name']) {
-                       if ($location) {
-                               $location .= ', ';
-                       }
-
-                       $location .= $profile['country-name'];
-               }
-
-               return $location;
-       }
-}
index 54d2d3bc60f9a8bc222bfa2f24911f9b8b5954ec..72e3aea939dde21bee049afdc5106def4b2f0cc5 100644 (file)
@@ -11,9 +11,8 @@ use Friendica\Core\Config;
 use Friendica\Core\System;
 use Friendica\Core\Worker;
 use Friendica\Database\DBM;
-use Friendica\Model\Contact;
-use Friendica\Model\Photo;
-use Friendica\Object\Image;
+use Friendica\Object\Contact;
+use Friendica\Object\Photo;
 use dba;
 
 require_once 'boot.php';
@@ -382,32 +381,32 @@ class User
                        $filename = basename($photo);
                        $img_str = fetch_url($photo, true);
                        // guess mimetype from headers or filename
-                       $type = Image::guessType($photo, true);
+                       $type = Photo::guessImageType($photo, true);
 
 
-                       $Image = new Image($img_str, $type);
-                       if ($Image->isValid()) {
-                               $Image->scaleToSquare(175);
+                       $img = new Photo($img_str, $type);
+                       if ($img->isValid()) {
+                               $img->scaleImageSquare(175);
 
                                $hash = photo_new_resource();
 
-                               $r = Photo::store($Image, $newuid, 0, $hash, $filename, t('Profile Photos'), 4);
+                               $r = $img->store($newuid, 0, $hash, $filename, t('Profile Photos'), 4);
 
                                if ($r === false) {
                                        $photo_failure = true;
                                }
 
-                               $Image->scaleDown(80);
+                               $img->scaleImage(80);
 
-                               $r = Photo::store($Image, $newuid, 0, $hash, $filename, t('Profile Photos'), 5);
+                               $r = $img->store($newuid, 0, $hash, $filename, t('Profile Photos'), 5);
 
                                if ($r === false) {
                                        $photo_failure = true;
                                }
 
-                               $Image->scaleDown(48);
+                               $img->scaleImage(48);
 
-                               $r = Photo::store($Image, $newuid, 0, $hash, $filename, t('Profile Photos'), 6);
+                               $r = $img->store($newuid, 0, $hash, $filename, t('Profile Photos'), 6);
 
                                if ($r === false) {
                                        $photo_failure = true;
index 320bb43cc1c76fa4f3db62aa9c4cac67b913a76d..500aa7323fa42fc3b66ece4b4bdc9de1874202bf 100644 (file)
@@ -14,7 +14,7 @@ use Friendica\Core\System;
 use Friendica\Core\Cache;
 use Friendica\Core\Config;
 use Friendica\Database\DBM;
-use Friendica\Model\Profile;
+use Friendica\Object\Profile;
 use Friendica\Protocol\Email;
 use Friendica\Util\XML;
 
diff --git a/src/Object/Contact.php b/src/Object/Contact.php
new file mode 100644 (file)
index 0000000..f72ec02
--- /dev/null
@@ -0,0 +1,948 @@
+<?php
+
+/**
+ * @file src/Object/Contact.php
+ */
+
+namespace Friendica\Object;
+
+use Friendica\App;
+use Friendica\BaseObject;
+use Friendica\Core\PConfig;
+use Friendica\Core\System;
+use Friendica\Core\Worker;
+use Friendica\Database\DBM;
+use Friendica\Network\Probe;
+use Friendica\Object\Photo;
+use Friendica\Protocol\Diaspora;
+use Friendica\Protocol\DFRN;
+use Friendica\Protocol\OStatus;
+use Friendica\Protocol\Salmon;
+use dba;
+
+require_once 'boot.php';
+require_once 'include/text.php';
+
+/**
+ * @brief functions for interacting with a contact
+ */
+class Contact extends BaseObject
+{
+       /**
+        * Creates the self-contact for the provided user id
+        *
+        * @param int $uid
+        * @return bool Operation success
+        */
+       public static function createSelfFromUserId($uid)
+       {
+               // Only create the entry if it doesn't exist yet
+               if (dba::exists('contact', ['uid' => intval($uid), 'self'])) {
+                       return true;
+               }
+
+               $user = dba::select('user', ['uid', 'username', 'nickname'], ['uid' => intval($uid)], ['limit' => 1]);
+               if (!DBM::is_result($user)) {
+                       return false;
+               }
+
+               $return = dba::insert('contact', [
+                       'uid'         => $user['uid'],
+                       'created'     => datetime_convert(),
+                       'self'        => 1,
+                       'name'        => $user['username'],
+                       'nick'        => $user['nickname'],
+                       'photo'       => System::baseUrl() . '/photo/profile/' . $user['uid'] . '.jpg',
+                       'thumb'       => System::baseUrl() . '/photo/avatar/'  . $user['uid'] . '.jpg',
+                       'micro'       => System::baseUrl() . '/photo/micro/'   . $user['uid'] . '.jpg',
+                       'blocked'     => 0,
+                       'pending'     => 0,
+                       'url'         => System::baseUrl() . '/profile/' . $user['nickname'],
+                       'nurl'        => normalise_link(System::baseUrl() . '/profile/' . $user['nickname']),
+                       'addr'        => $user['nickname'] . '@' . substr(System::baseUrl(), strpos(System::baseUrl(), '://') + 3),
+                       'request'     => System::baseUrl() . '/dfrn_request/' . $user['nickname'],
+                       'notify'      => System::baseUrl() . '/dfrn_notify/'  . $user['nickname'],
+                       'poll'        => System::baseUrl() . '/dfrn_poll/'    . $user['nickname'],
+                       'confirm'     => System::baseUrl() . '/dfrn_confirm/' . $user['nickname'],
+                       'poco'        => System::baseUrl() . '/poco/'         . $user['nickname'],
+                       'name-date'   => datetime_convert(),
+                       'uri-date'    => datetime_convert(),
+                       'avatar-date' => datetime_convert(),
+                       'closeness'   => 0
+               ]);
+
+               return $return;
+       }
+
+       /**
+        * @brief Marks a contact for removal
+        *
+        * @param int $id contact id
+        * @return null
+        */
+       public static function remove($id)
+       {
+               // We want just to make sure that we don't delete our "self" contact
+               $r = dba::select('contact', array('uid'), array('id' => $id, 'self' => false), array('limit' => 1));
+
+               if (!DBM::is_result($r) || !intval($r['uid'])) {
+                       return;
+               }
+
+               $archive = PConfig::get($r['uid'], 'system', 'archive_removed_contacts');
+               if ($archive) {
+                       dba::update('contact', array('archive' => true, 'network' => 'none', 'writable' => false), array('id' => $id));
+                       return;
+               }
+
+               dba::delete('contact', array('id' => $id));
+
+               // Delete the rest in the background
+               Worker::add(PRIORITY_LOW, 'RemoveContact', $id);
+       }
+
+       /**
+        * @brief Sends an unfriend message. Does not remove the contact
+        *
+        * @param array $user    User unfriending
+        * @param array $contact Contact unfriended
+        * @return void
+        */
+       public static function terminateFriendship(array $user, array $contact)
+       {
+               if ($contact['network'] === NETWORK_OSTATUS) {
+                       // create an unfollow slap
+                       $item = array();
+                       $item['verb'] = NAMESPACE_OSTATUS . "/unfollow";
+                       $item['follow'] = $contact["url"];
+                       $slap = OStatus::salmon($item, $user);
+
+                       if ((x($contact, 'notify')) && (strlen($contact['notify']))) {
+                               Salmon::slapper($user, $contact['notify'], $slap);
+                       }
+               } elseif ($contact['network'] === NETWORK_DIASPORA) {
+                       Diaspora::sendUnshare($user, $contact);
+               } elseif ($contact['network'] === NETWORK_DFRN) {
+                       DFRN::deliver($user, $contact, 'placeholder', 1);
+               }
+       }
+
+       /**
+        * @brief Marks a contact for archival after a communication issue delay
+        *
+        * Contact has refused to recognise us as a friend. We will start a countdown.
+        * If they still don't recognise us in 32 days, the relationship is over,
+        * and we won't waste any more time trying to communicate with them.
+        * This provides for the possibility that their database is temporarily messed
+        * up or some other transient event and that there's a possibility we could recover from it.
+        *
+        * @param array $contact contact to mark for archival
+        * @return type
+        */
+       public static function markForArchival(array $contact)
+       {
+               // Contact already archived or "self" contact? => nothing to do
+               if ($contact['archive'] || $contact['self']) {
+                       return;
+               }
+
+               if ($contact['term-date'] <= NULL_DATE) {
+                       dba::update('contact', array('term-date' => datetime_convert()), array('id' => $contact['id']));
+
+                       if ($contact['url'] != '') {
+                               dba::update('contact', array('term-date' => datetime_convert()), array('`nurl` = ? AND `term-date` <= ? AND NOT `self`', normalise_link($contact['url']), NULL_DATE));
+                       }
+               } else {
+                       /* @todo
+                        * We really should send a notification to the owner after 2-3 weeks
+                        * so they won't be surprised when the contact vanishes and can take
+                        * remedial action if this was a serious mistake or glitch
+                        */
+
+                       /// @todo Check for contact vitality via probing
+                       $expiry = $contact['term-date'] . ' + 32 days ';
+                       if (datetime_convert() > datetime_convert('UTC', 'UTC', $expiry)) {
+                               /* Relationship is really truly dead. archive them rather than
+                                * delete, though if the owner tries to unarchive them we'll start
+                                * the whole process over again.
+                                */
+                               dba::update('contact', array('archive' => 1), array('id' => $contact['id']));
+
+                               if ($contact['url'] != '') {
+                                       dba::update('contact', array('archive' => 1), array('nurl' => normalise_link($contact['url']), 'self' => false));
+                               }
+                       }
+               }
+       }
+
+       /**
+        * @brief Cancels the archival countdown
+        *
+        * @see Contact::markForArchival()
+        *
+        * @param array $contact contact to be unmarked for archival
+        * @return null
+        */
+       public static function unmarkForArchival(array $contact)
+       {
+               $condition = array('`id` = ? AND (`term-date` > ? OR `archive`)', $contact['id'], NULL_DATE);
+               $exists = dba::exists('contact', $condition);
+
+               // We don't need to update, we never marked this contact for archival
+               if (!$exists) {
+                       return;
+               }
+
+               // It's a miracle. Our dead contact has inexplicably come back to life.
+               $fields = array('term-date' => NULL_DATE, 'archive' => false);
+               dba::update('contact', $fields, array('id' => $contact['id']));
+
+               if ($contact['url'] != '') {
+                       dba::update('contact', $fields, array('nurl' => normalise_link($contact['url'])));
+               }
+       }
+
+       /**
+        * @brief Get contact data for a given profile link
+        *
+        * The function looks at several places (contact table and gcontact table) for the contact
+        * It caches its result for the same script execution to prevent duplicate calls
+        *
+        * @param string $url     The profile link
+        * @param int    $uid     User id
+        * @param array  $default If not data was found take this data as default value
+        *
+        * @return array Contact data
+        */
+       public static function getDetailsByURL($url, $uid = -1, array $default = [])
+       {
+               static $cache = array();
+
+               if ($url == '') {
+                       return $default;
+               }
+
+               if ($uid == -1) {
+                       $uid = local_user();
+               }
+
+               if (isset($cache[$url][$uid])) {
+                       return $cache[$url][$uid];
+               }
+
+               $ssl_url = str_replace('http://', 'https://', $url);
+
+               // Fetch contact data from the contact table for the given user
+               $s = dba::p("SELECT `id`, `id` AS `cid`, 0 AS `gid`, 0 AS `zid`, `uid`, `url`, `nurl`, `alias`, `network`, `name`, `nick`, `addr`, `location`, `about`, `xmpp`,
+                       `keywords`, `gender`, `photo`, `thumb`, `micro`, `forum`, `prv`, (`forum` | `prv`) AS `community`, `contact-type`, `bd` AS `birthday`, `self`
+               FROM `contact` WHERE `nurl` = ? AND `uid` = ?", normalise_link($url), $uid);
+               $r = dba::inArray($s);
+
+               // Fetch contact data from the contact table for the given user, checking with the alias
+               if (!DBM::is_result($r)) {
+                       $s = dba::p("SELECT `id`, `id` AS `cid`, 0 AS `gid`, 0 AS `zid`, `uid`, `url`, `nurl`, `alias`, `network`, `name`, `nick`, `addr`, `location`, `about`, `xmpp`,
+                               `keywords`, `gender`, `photo`, `thumb`, `micro`, `forum`, `prv`, (`forum` | `prv`) AS `community`, `contact-type`, `bd` AS `birthday`, `self`
+                       FROM `contact` WHERE `alias` IN (?, ?, ?) AND `uid` = ?", normalise_link($url), $url, $ssl_url, $uid);
+                       $r = dba::inArray($s);
+               }
+
+               // Fetch the data from the contact table with "uid=0" (which is filled automatically)
+               if (!DBM::is_result($r)) {
+                       $s = dba::p("SELECT `id`, 0 AS `cid`, `id` AS `zid`, 0 AS `gid`, `uid`, `url`, `nurl`, `alias`, `network`, `name`, `nick`, `addr`, `location`, `about`, `xmpp`,
+                       `keywords`, `gender`, `photo`, `thumb`, `micro`, `forum`, `prv`, (`forum` | `prv`) AS `community`, `contact-type`, `bd` AS `birthday`, 0 AS `self`
+                       FROM `contact` WHERE `nurl` = ? AND `uid` = 0", normalise_link($url));
+                       $r = dba::inArray($s);
+               }
+
+               // Fetch the data from the contact table with "uid=0" (which is filled automatically) - checked with the alias
+               if (!DBM::is_result($r)) {
+                       $s = dba::p("SELECT `id`, 0 AS `cid`, `id` AS `zid`, 0 AS `gid`, `uid`, `url`, `nurl`, `alias`, `network`, `name`, `nick`, `addr`, `location`, `about`, `xmpp`,
+                       `keywords`, `gender`, `photo`, `thumb`, `micro`, `forum`, `prv`, (`forum` | `prv`) AS `community`, `contact-type`, `bd` AS `birthday`, 0 AS `self`
+                       FROM `contact` WHERE `alias` IN (?, ?, ?) AND `uid` = 0", normalise_link($url), $url, $ssl_url);
+                       $r = dba::inArray($s);
+               }
+
+               // Fetch the data from the gcontact table
+               if (!DBM::is_result($r)) {
+                       $s = dba::p("SELECT 0 AS `id`, 0 AS `cid`, `id` AS `gid`, 0 AS `zid`, 0 AS `uid`, `url`, `nurl`, `alias`, `network`, `name`, `nick`, `addr`, `location`, `about`, '' AS `xmpp`,
+                       `keywords`, `gender`, `photo`, `photo` AS `thumb`, `photo` AS `micro`, `community` AS `forum`, 0 AS `prv`, `community`, `contact-type`, `birthday`, 0 AS `self`
+                       FROM `gcontact` WHERE `nurl` = ?", normalise_link($url));
+                       $r = dba::inArray($s);
+               }
+
+               if (DBM::is_result($r)) {
+                       // If there is more than one entry we filter out the connector networks
+                       if (count($r) > 1) {
+                               foreach ($r as $id => $result) {
+                                       if ($result["network"] == NETWORK_STATUSNET) {
+                                               unset($r[$id]);
+                                       }
+                               }
+                       }
+
+                       $profile = array_shift($r);
+
+                       // "bd" always contains the upcoming birthday of a contact.
+                       // "birthday" might contain the birthday including the year of birth.
+                       if ($profile["birthday"] > '0001-01-01') {
+                               $bd_timestamp = strtotime($profile["birthday"]);
+                               $month = date("m", $bd_timestamp);
+                               $day = date("d", $bd_timestamp);
+
+                               $current_timestamp = time();
+                               $current_year = date("Y", $current_timestamp);
+                               $current_month = date("m", $current_timestamp);
+                               $current_day = date("d", $current_timestamp);
+
+                               $profile["bd"] = $current_year . "-" . $month . "-" . $day;
+                               $current = $current_year . "-" . $current_month . "-" . $current_day;
+
+                               if ($profile["bd"] < $current) {
+                                       $profile["bd"] = ( ++$current_year) . "-" . $month . "-" . $day;
+                               }
+                       } else {
+                               $profile["bd"] = '0001-01-01';
+                       }
+               } else {
+                       $profile = $default;
+               }
+
+               if (($profile["photo"] == "") && isset($default["photo"])) {
+                       $profile["photo"] = $default["photo"];
+               }
+
+               if (($profile["name"] == "") && isset($default["name"])) {
+                       $profile["name"] = $default["name"];
+               }
+
+               if (($profile["network"] == "") && isset($default["network"])) {
+                       $profile["network"] = $default["network"];
+               }
+
+               if (($profile["thumb"] == "") && isset($profile["photo"])) {
+                       $profile["thumb"] = $profile["photo"];
+               }
+
+               if (($profile["micro"] == "") && isset($profile["thumb"])) {
+                       $profile["micro"] = $profile["thumb"];
+               }
+
+               if ((($profile["addr"] == "") || ($profile["name"] == "")) && ($profile["gid"] != 0)
+                       && in_array($profile["network"], array(NETWORK_DFRN, NETWORK_DIASPORA, NETWORK_OSTATUS))
+               ) {
+                       Worker::add(PRIORITY_LOW, "UpdateGContact", $profile["gid"]);
+               }
+
+               // Show contact details of Diaspora contacts only if connected
+               if (($profile["cid"] == 0) && ($profile["network"] == NETWORK_DIASPORA)) {
+                       $profile["location"] = "";
+                       $profile["about"] = "";
+                       $profile["gender"] = "";
+                       $profile["birthday"] = '0001-01-01';
+               }
+
+               $cache[$url][$uid] = $profile;
+
+               return $profile;
+       }
+
+       /**
+        * @brief Get contact data for a given address
+        *
+        * The function looks at several places (contact table and gcontact table) for the contact
+        *
+        * @param string $addr The profile link
+        * @param int    $uid  User id
+        *
+        * @return array Contact data
+        */
+       public static function getDetailsByAddr($addr, $uid = -1)
+       {
+               static $cache = array();
+
+               if ($addr == '') {
+                       return array();
+               }
+
+               if ($uid == -1) {
+                       $uid = local_user();
+               }
+
+               // Fetch contact data from the contact table for the given user
+               $r = q("SELECT `id`, `id` AS `cid`, 0 AS `gid`, 0 AS `zid`, `uid`, `url`, `nurl`, `alias`, `network`, `name`, `nick`, `addr`, `location`, `about`, `xmpp`,
+                       `keywords`, `gender`, `photo`, `thumb`, `micro`, `forum`, `prv`, (`forum` | `prv`) AS `community`, `contact-type`, `bd` AS `birthday`, `self`
+               FROM `contact` WHERE `addr` = '%s' AND `uid` = %d", dbesc($addr), intval($uid));
+
+               // Fetch the data from the contact table with "uid=0" (which is filled automatically)
+               if (!DBM::is_result($r))
+                       $r = q("SELECT `id`, 0 AS `cid`, `id` AS `zid`, 0 AS `gid`, `uid`, `url`, `nurl`, `alias`, `network`, `name`, `nick`, `addr`, `location`, `about`, `xmpp`,
+                       `keywords`, `gender`, `photo`, `thumb`, `micro`, `forum`, `prv`, (`forum` | `prv`) AS `community`, `contact-type`, `bd` AS `birthday`, 0 AS `self`
+                       FROM `contact` WHERE `addr` = '%s' AND `uid` = 0", dbesc($addr));
+
+               // Fetch the data from the gcontact table
+               if (!DBM::is_result($r))
+                       $r = q("SELECT 0 AS `id`, 0 AS `cid`, `id` AS `gid`, 0 AS `zid`, 0 AS `uid`, `url`, `nurl`, `alias`, `network`, `name`, `nick`, `addr`, `location`, `about`, '' AS `xmpp`,
+                       `keywords`, `gender`, `photo`, `photo` AS `thumb`, `photo` AS `micro`, `community` AS `forum`, 0 AS `prv`, `community`, `contact-type`, `birthday`, 0 AS `self`
+                       FROM `gcontact` WHERE `addr` = '%s'", dbesc($addr));
+
+               if (!DBM::is_result($r)) {
+                       $data = Probe::uri($addr);
+
+                       $profile = self::getDetailsByURL($data['url'], $uid);
+               } else {
+                       $profile = $r[0];
+               }
+
+               return $profile;
+       }
+
+       /**
+        * @brief Returns the data array for the photo menu of a given contact
+        *
+        * @param array $contact contact
+        * @param int   $uid     optional, default 0
+        * @return array
+        */
+       public static function photoMenu(array $contact, $uid = 0)
+       {
+               // @todo Unused, to be removed
+               $a = get_app();
+
+               $contact_url = '';
+               $pm_url = '';
+               $status_link = '';
+               $photos_link = '';
+               $posts_link = '';
+               $contact_drop_link = '';
+               $poke_link = '';
+
+               if ($uid == 0) {
+                       $uid = local_user();
+               }
+
+               if ($contact['uid'] != $uid) {
+                       if ($uid == 0) {
+                               $profile_link = zrl($contact['url']);
+                               $menu = array('profile' => array(t('View Profile'), $profile_link, true));
+
+                               return $menu;
+                       }
+
+                       $r = dba::select('contact', array(), array('nurl' => $contact['nurl'], 'network' => $contact['network'], 'uid' => $uid), array('limit' => 1));
+                       if ($r) {
+                               return self::photoMenu($r, $uid);
+                       } else {
+                               $profile_link = zrl($contact['url']);
+                               $connlnk = 'follow/?url=' . $contact['url'];
+                               $menu = array(
+                                       'profile' => array(t('View Profile'), $profile_link, true),
+                                       'follow' => array(t('Connect/Follow'), $connlnk, true)
+                               );
+
+                               return $menu;
+                       }
+               }
+
+               $sparkle = false;
+               if ($contact['network'] === NETWORK_DFRN) {
+                       $sparkle = true;
+                       $profile_link = System::baseUrl() . '/redir/' . $contact['id'];
+               } else {
+                       $profile_link = $contact['url'];
+               }
+
+               if ($profile_link === 'mailbox') {
+                       $profile_link = '';
+               }
+
+               if ($sparkle) {
+                       $status_link = $profile_link . '?url=status';
+                       $photos_link = $profile_link . '?url=photos';
+                       $profile_link = $profile_link . '?url=profile';
+               }
+
+               if (in_array($contact['network'], array(NETWORK_DFRN, NETWORK_DIASPORA))) {
+                       $pm_url = System::baseUrl() . '/message/new/' . $contact['id'];
+               }
+
+               if ($contact['network'] == NETWORK_DFRN) {
+                       $poke_link = System::baseUrl() . '/poke/?f=&c=' . $contact['id'];
+               }
+
+               $contact_url = System::baseUrl() . '/contacts/' . $contact['id'];
+
+               $posts_link = System::baseUrl() . '/contacts/' . $contact['id'] . '/posts';
+               $contact_drop_link = System::baseUrl() . '/contacts/' . $contact['id'] . '/drop?confirm=1';
+
+               /**
+                * Menu array:
+                * "name" => [ "Label", "link", (bool)Should the link opened in a new tab? ]
+                */
+               $menu = array(
+                       'status' => array(t("View Status"), $status_link, true),
+                       'profile' => array(t("View Profile"), $profile_link, true),
+                       'photos' => array(t("View Photos"), $photos_link, true),
+                       'network' => array(t("Network Posts"), $posts_link, false),
+                       'edit' => array(t("View Contact"), $contact_url, false),
+                       'drop' => array(t("Drop Contact"), $contact_drop_link, false),
+                       'pm' => array(t("Send PM"), $pm_url, false),
+                       'poke' => array(t("Poke"), $poke_link, false),
+               );
+
+
+               $args = array('contact' => $contact, 'menu' => &$menu);
+
+               call_hooks('contact_photo_menu', $args);
+
+               $menucondensed = array();
+
+               foreach ($menu as $menuname => $menuitem) {
+                       if ($menuitem[1] != '') {
+                               $menucondensed[$menuname] = $menuitem;
+                       }
+               }
+
+               return $menucondensed;
+       }
+
+       /**
+        * @brief Returns ungrouped contact count or list for user
+        *
+        * Returns either the total number of ungrouped contacts for the given user
+        * id or a paginated list of ungrouped contacts.
+        *
+        * @param int $uid   uid
+        * @param int $start optional, default 0
+        * @param int $count optional, default 0
+        *
+        * @return array
+        */
+       public static function getUngroupedList($uid, $start = 0, $count = 0)
+       {
+               if (!$count) {
+                       $r = q(
+                               "SELECT COUNT(*) AS `total`
+                                FROM `contact`
+                                WHERE `uid` = %d
+                                AND NOT `self`
+                                AND NOT `blocked`
+                                AND NOT `pending`
+                                AND `id` NOT IN (
+                                       SELECT DISTINCT(`contact-id`)
+                                       FROM `group_member`
+                                       WHERE `uid` = %d
+                               )", intval($uid), intval($uid)
+                       );
+
+                       return $r;
+               }
+
+               $r = q(
+                       "SELECT *
+                       FROM `contact`
+                       WHERE `uid` = %d
+                       AND NOT `self`
+                       AND NOT `blocked`
+                       AND NOT `pending`
+                       AND `id` NOT IN (
+                               SELECT DISTINCT(`contact-id`)
+                               FROM `group_member` WHERE `uid` = %d
+                       )
+                       LIMIT %d, %d", intval($uid), intval($uid), intval($start), intval($count)
+               );
+               return $r;
+       }
+
+       /**
+        * @brief Fetch the contact id for a given url and user
+        *
+        * First lookup in the contact table to find a record matching either `url`, `nurl`,
+        * `addr` or `alias`.
+        *
+        * If there's no record and we aren't looking for a public contact, we quit.
+        * If there's one, we check that it isn't time to update the picture else we
+        * directly return the found contact id.
+        *
+        * Second, we probe the provided $url wether it's http://server.tld/profile or
+        * nick@server.tld. We quit if we can't get any info back.
+        *
+        * Third, we create the contact record if it doesn't exist
+        *
+        * Fourth, we update the existing record with the new data (avatar, alias, nick)
+        * if there's any updates
+        *
+        * @param string  $url       Contact URL
+        * @param integer $uid       The user id for the contact (0 = public contact)
+        * @param boolean $no_update Don't update the contact
+        *
+        * @return integer Contact ID
+        */
+       public static function getIdForURL($url, $uid = 0, $no_update = false)
+       {
+               logger("Get contact data for url " . $url . " and user " . $uid . " - " . System::callstack(), LOGGER_DEBUG);
+
+               $contact_id = 0;
+
+               if ($url == '') {
+                       return 0;
+               }
+
+               /// @todo Verify if we can't use Contact::getDetailsByUrl instead of the following
+               // We first try the nurl (http://server.tld/nick), most common case
+               $contact = dba::select('contact', array('id', 'avatar-date'), array('nurl' => normalise_link($url), 'uid' => $uid), array('limit' => 1));
+
+               // Then the addr (nick@server.tld)
+               if (!DBM::is_result($contact)) {
+                       $contact = dba::select('contact', array('id', 'avatar-date'), array('addr' => $url, 'uid' => $uid), array('limit' => 1));
+               }
+
+               // Then the alias (which could be anything)
+               if (!DBM::is_result($contact)) {
+                       // The link could be provided as http although we stored it as https
+                       $ssl_url = str_replace('http://', 'https://', $url);
+                       $r = dba::select('contact', array('id', 'avatar-date'), array('`alias` IN (?, ?, ?) AND `uid` = ?', $url, normalise_link($url), $ssl_url, $uid), array('limit' => 1));
+                       $contact = dba::fetch($r);
+                       dba::close($r);
+               }
+
+               if (DBM::is_result($contact)) {
+                       $contact_id = $contact["id"];
+
+                       // Update the contact every 7 days
+                       $update_contact = ($contact['avatar-date'] < datetime_convert('', '', 'now -7 days'));
+
+                       // We force the update if the avatar is empty
+                       if ($contact['avatar'] == '') {
+                               $update_contact = true;
+                       }
+
+                       if (!$update_contact || $no_update) {
+                               return $contact_id;
+                       }
+               } elseif ($uid != 0) {
+                       // Non-existing user-specific contact, exiting
+                       return 0;
+               }
+
+               $data = Probe::uri($url, "", $uid);
+
+               // Last try in gcontact for unsupported networks
+               if (!in_array($data["network"], array(NETWORK_DFRN, NETWORK_OSTATUS, NETWORK_DIASPORA, NETWORK_PUMPIO, NETWORK_MAIL))) {
+                       if ($uid != 0) {
+                               return 0;
+                       }
+
+                       // Get data from the gcontact table
+                       $gcontacts = dba::select('gcontact', array('name', 'nick', 'url', 'photo', 'addr', 'alias', 'network'), array('nurl' => normalise_link($url)), array('limit' => 1));
+                       if (!DBM::is_result($gcontacts)) {
+                               return 0;
+                       }
+
+                       $data = array_merge($data, $gcontacts);
+               }
+
+               if (!$contact_id && ($data["alias"] != '') && ($data["alias"] != $url)) {
+                       $contact_id = self::getIdForURL($data["alias"], $uid, true);
+               }
+
+               $url = $data["url"];
+               if (!$contact_id) {
+                       dba::insert(
+                               'contact', array('uid' => $uid, 'created' => datetime_convert(), 'url' => $data["url"],
+                               'nurl' => normalise_link($data["url"]), 'addr' => $data["addr"],
+                               'alias' => $data["alias"], 'notify' => $data["notify"], 'poll' => $data["poll"],
+                               'name' => $data["name"], 'nick' => $data["nick"], 'photo' => $data["photo"],
+                               'keywords' => $data["keywords"], 'location' => $data["location"], 'about' => $data["about"],
+                               'network' => $data["network"], 'pubkey' => $data["pubkey"],
+                               'rel' => CONTACT_IS_SHARING, 'priority' => $data["priority"],
+                               'batch' => $data["batch"], 'request' => $data["request"],
+                               'confirm' => $data["confirm"], 'poco' => $data["poco"],
+                               'name-date' => datetime_convert(), 'uri-date' => datetime_convert(),
+                               'avatar-date' => datetime_convert(), 'writable' => 1, 'blocked' => 0,
+                               'readonly' => 0, 'pending' => 0)
+                       );
+
+                       $s = dba::select('contact', array('id'), array('nurl' => normalise_link($data["url"]), 'uid' => $uid), array('order' => array('id'), 'limit' => 2));
+                       $contacts = dba::inArray($s);
+                       if (!DBM::is_result($contacts)) {
+                               return 0;
+                       }
+
+                       $contact_id = $contacts[0]["id"];
+
+                       // Update the newly created contact from data in the gcontact table
+                       $gcontact = dba::select('gcontact', array('location', 'about', 'keywords', 'gender'), array('nurl' => normalise_link($data["url"])), array('limit' => 1));
+                       if (DBM::is_result($gcontact)) {
+                               // Only use the information when the probing hadn't fetched these values
+                               if ($data['keywords'] != '') {
+                                       unset($gcontact['keywords']);
+                               }
+                               if ($data['location'] != '') {
+                                       unset($gcontact['location']);
+                               }
+                               if ($data['about'] != '') {
+                                       unset($gcontact['about']);
+                               }
+                               dba::update('contact', $gcontact, array('id' => $contact_id));
+                       }
+
+                       if (count($contacts) > 1 && $uid == 0 && $contact_id != 0 && $data["url"] != "") {
+                               dba::delete('contact', array("`nurl` = ? AND `uid` = 0 AND `id` != ? AND NOT `self`",
+                                       normalise_link($data["url"]), $contact_id));
+                       }
+               }
+
+               self::updateAvatar($data["photo"], $uid, $contact_id);
+
+               $fields = array('url', 'nurl', 'addr', 'alias', 'name', 'nick', 'keywords', 'location', 'about', 'avatar-date', 'pubkey');
+               $contact = dba::select('contact', $fields, array('id' => $contact_id), array('limit' => 1));
+
+               // This condition should always be true
+               if (!DBM::is_result($contact)) {
+                       return $contact_id;
+               }
+
+               $updated = array('addr' => $data['addr'],
+                       'alias' => $data['alias'],
+                       'url' => $data['url'],
+                       'nurl' => normalise_link($data['url']),
+                       'name' => $data['name'],
+                       'nick' => $data['nick']);
+
+               // Only fill the pubkey if it was empty before. We have to prevent identity theft.
+               if (!empty($contact['pubkey'])) {
+                       unset($contact['pubkey']);
+               } else {
+                       $updated['pubkey'] = $data['pubkey'];
+               }
+
+               if ($data['keywords'] != '') {
+                       $updated['keywords'] = $data['keywords'];
+               }
+               if ($data['location'] != '') {
+                       $updated['location'] = $data['location'];
+               }
+               if ($data['about'] != '') {
+                       $updated['about'] = $data['about'];
+               }
+
+               if (($data["addr"] != $contact["addr"]) || ($data["alias"] != $contact["alias"])) {
+                       $updated['uri-date'] = datetime_convert();
+               }
+               if (($data["name"] != $contact["name"]) || ($data["nick"] != $contact["nick"])) {
+                       $updated['name-date'] = datetime_convert();
+               }
+
+               $updated['avatar-date'] = datetime_convert();
+
+               dba::update('contact', $updated, array('id' => $contact_id), $contact);
+
+               return $contact_id;
+       }
+
+       /**
+        * @brief Checks if the contact is blocked
+        *
+        * @param int $cid contact id
+        *
+        * @return boolean Is the contact blocked?
+        */
+       public static function isBlocked($cid)
+       {
+               if ($cid == 0) {
+                       return false;
+               }
+
+               $blocked = dba::select('contact', array('blocked'), array('id' => $cid), array('limit' => 1));
+               if (!DBM::is_result($blocked)) {
+                       return false;
+               }
+               return (bool) $blocked['blocked'];
+       }
+
+       /**
+        * @brief Checks if the contact is hidden
+        *
+        * @param int $cid contact id
+        *
+        * @return boolean Is the contact hidden?
+        */
+       public static function isHidden($cid)
+       {
+               if ($cid == 0) {
+                       return false;
+               }
+
+               $hidden = dba::select('contact', array('hidden'), array('id' => $cid), array('limit' => 1));
+               if (!DBM::is_result($hidden)) {
+                       return false;
+               }
+               return (bool) $hidden['hidden'];
+       }
+
+       /**
+        * @brief Returns posts from a given contact url
+        *
+        * @param string $contact_url Contact URL
+        *
+        * @return string posts in HTML
+        */
+       public static function getPostsFromUrl($contact_url)
+       {
+               $a = self::getApp();
+
+               require_once 'include/conversation.php';
+
+               // There are no posts with "uid = 0" with connector networks
+               // This speeds up the query a lot
+               $r = q("SELECT `network`, `id` AS `author-id`, `contact-type` FROM `contact`
+                       WHERE `contact`.`nurl` = '%s' AND `contact`.`uid` = 0", dbesc(normalise_link($contact_url)));
+
+               if (!DBM::is_result($r)) {
+                       return '';
+               }
+
+               if (in_array($r[0]["network"], array(NETWORK_DFRN, NETWORK_DIASPORA, NETWORK_OSTATUS, ""))) {
+                       $sql = "(`item`.`uid` = 0 OR (`item`.`uid` = %d AND NOT `item`.`global`))";
+               } else {
+                       $sql = "`item`.`uid` = %d";
+               }
+
+               $author_id = intval($r[0]["author-id"]);
+
+               $contact = ($r[0]["contact-type"] == ACCOUNT_TYPE_COMMUNITY ? 'owner-id' : 'author-id');
+
+               $r = q(item_query() . " AND `item`.`" . $contact . "` = %d AND " . $sql .
+                       " ORDER BY `item`.`created` DESC LIMIT %d, %d", intval($author_id), intval(local_user()), intval($a->pager['start']), intval($a->pager['itemspage'])
+               );
+
+
+               $o = conversation($a, $r, 'community', false);
+
+               $o .= alt_pager($a, count($r));
+
+               return $o;
+       }
+
+       /**
+        * @brief Returns the account type name
+        *
+        * The function can be called with either the user or the contact array
+        *
+        * @param array $contact contact or user array
+        * @return string
+        */
+       public static function getAccountType(array $contact)
+       {
+               // There are several fields that indicate that the contact or user is a forum
+               // "page-flags" is a field in the user table,
+               // "forum" and "prv" are used in the contact table. They stand for PAGE_COMMUNITY and PAGE_PRVGROUP.
+               // "community" is used in the gcontact table and is true if the contact is PAGE_COMMUNITY or PAGE_PRVGROUP.
+               if ((isset($contact['page-flags']) && (intval($contact['page-flags']) == PAGE_COMMUNITY))
+                       || (isset($contact['page-flags']) && (intval($contact['page-flags']) == PAGE_PRVGROUP))
+                       || (isset($contact['forum']) && intval($contact['forum']))
+                       || (isset($contact['prv']) && intval($contact['prv']))
+                       || (isset($contact['community']) && intval($contact['community']))
+               ) {
+                       $type = ACCOUNT_TYPE_COMMUNITY;
+               } else {
+                       $type = ACCOUNT_TYPE_PERSON;
+               }
+
+               // The "contact-type" (contact table) and "account-type" (user table) are more general then the chaos from above.
+               if (isset($contact["contact-type"])) {
+                       $type = $contact["contact-type"];
+               }
+               if (isset($contact["account-type"])) {
+                       $type = $contact["account-type"];
+               }
+
+               switch ($type) {
+                       case ACCOUNT_TYPE_ORGANISATION:
+                               $account_type = t("Organisation");
+                               break;
+                       case ACCOUNT_TYPE_NEWS:
+                               $account_type = t('News');
+                               break;
+                       case ACCOUNT_TYPE_COMMUNITY:
+                               $account_type = t("Forum");
+                               break;
+                       default:
+                               $account_type = "";
+                               break;
+               }
+
+               return $account_type;
+       }
+
+       /**
+        * @brief Blocks a contact
+        *
+        * @param int $uid
+        * @return bool
+        */
+       public static function block($uid)
+       {
+               $return = dba::update('contact', ['blocked' => true], ['id' => $uid]);
+
+               return $return;
+       }
+
+       /**
+        * @brief Unblocks a contact
+        *
+        * @param int $uid
+        * @return bool
+        */
+       public static function unblock($uid)
+       {
+               $return = dba::update('contact', ['blocked' => false], ['id' => $uid]);
+
+               return $return;
+  }
+
+  /**
+   * @brief Updates the avatar links in a contact only if needed
+        *
+        * @param string $avatar Link to avatar picture
+        * @param int    $uid    User id of contact owner
+        * @param int    $cid    Contact id
+        * @param bool   $force  force picture update
+        *
+        * @return array Returns array of the different avatar sizes
+        */
+       public static function updateAvatar($avatar, $uid, $cid, $force = false)
+       {
+               // Limit = 1 returns the row so no need for dba:inArray()
+               $r = dba::select('contact', array('avatar', 'photo', 'thumb', 'micro', 'nurl'), array('id' => $cid), array('limit' => 1));
+               if (!DBM::is_result($r)) {
+                       return false;
+               } else {
+                       $data = array($r["photo"], $r["thumb"], $r["micro"]);
+               }
+
+               if (($r["avatar"] != $avatar) || $force) {
+                       $photos = Photo::importProfilePhoto($avatar, $uid, $cid, true);
+
+                       if ($photos) {
+                               dba::update(
+                                       'contact',
+                                       array('avatar' => $avatar, 'photo' => $photos[0], 'thumb' => $photos[1], 'micro' => $photos[2], 'avatar-date' => datetime_convert()),
+                                       array('id' => $cid)
+                               );
+
+                               // Update the public contact (contact id = 0)
+                               if ($uid != 0) {
+                                       $pcontact = dba::select('contact', array('id'), array('nurl' => $r[0]['nurl']), array('limit' => 1));
+                                       if (DBM::is_result($pcontact)) {
+                                               self::updateAvatar($avatar, 0, $pcontact['id'], $force);
+                                       }
+                               }
+
+                               return $photos;
+                       }
+               }
+
+               return $data;
+       }
+}
diff --git a/src/Object/Conversation.php b/src/Object/Conversation.php
new file mode 100644 (file)
index 0000000..3721086
--- /dev/null
@@ -0,0 +1,207 @@
+<?php
+/**
+ * @file src/Object/Conversation.php
+ */
+namespace Friendica\Object;
+
+use Friendica\BaseObject;
+use Friendica\Object\Item;
+
+require_once 'boot.php';
+require_once 'include/text.php';
+
+/**
+ * A list of threads
+ *
+ * We should think about making this a SPL Iterator
+ */
+class Conversation extends BaseObject
+{
+       private $threads = array();
+       private $mode = null;
+       private $writable = false;
+       private $profile_owner = 0;
+       private $preview = false;
+
+       /**
+        * Constructor
+        *
+        * @param string  $mode    The mode
+        * @param boolean $preview boolean value
+        */
+       public function __construct($mode, $preview)
+       {
+               $this->setMode($mode);
+               $this->preview = $preview;
+       }
+
+       /**
+        * Set the mode we'll be displayed on
+        *
+        * @param string $mode The mode to set
+        *
+        * @return void
+        */
+       private function setMode($mode)
+       {
+               if ($this->getMode() == $mode) {
+                       return;
+               }
+
+               $a = self::getApp();
+
+               switch ($mode) {
+                       case 'network':
+                       case 'notes':
+                               $this->profile_owner = local_user();
+                               $this->writable = true;
+                               break;
+                       case 'profile':
+                               $this->profile_owner = $a->profile['profile_uid'];
+                               $this->writable = can_write_wall($a, $this->profile_owner);
+                               break;
+                       case 'display':
+                               $this->profile_owner = $a->profile['uid'];
+                               $this->writable = can_write_wall($a, $this->profile_owner);
+                               break;
+                       default:
+                               logger('[ERROR] Conversation::setMode : Unhandled mode ('. $mode .').', LOGGER_DEBUG);
+                               return false;
+                               break;
+               }
+               $this->mode = $mode;
+       }
+
+       /**
+        * Get mode
+        *
+        * @return string
+        */
+       public function getMode()
+       {
+               return $this->mode;
+       }
+
+       /**
+        * Check if page is writable
+        *
+        * @return boolean
+        */
+       public function isWritable()
+       {
+               return $this->writable;
+       }
+
+       /**
+        * Check if page is a preview
+        *
+        * @return boolean
+        */
+       public function isPreview()
+       {
+               return $this->preview;
+       }
+
+       /**
+        * Get profile owner
+        *
+        * @return integer
+        */
+       public function getProfileOwner()
+       {
+               return $this->profile_owner;
+       }
+
+       /**
+        * Add a thread to the conversation
+        *
+        * @param object $item The item to insert
+        *
+        * @return mixed The inserted item on success
+        *               false on failure
+        */
+       public function addThread($item)
+       {
+               $item_id = $item->getId();
+
+               if (!$item_id) {
+                       logger('[ERROR] Conversation::addThread : Item has no ID!!', LOGGER_DEBUG);
+                       return false;
+               }
+
+               if ($this->getThread($item->getId())) {
+                       logger('[WARN] Conversation::addThread : Thread already exists ('. $item->getId() .').', LOGGER_DEBUG);
+                       return false;
+               }
+
+               /*
+                * Only add will be displayed
+                */
+               if ($item->getDataValue('network') === NETWORK_MAIL && local_user() != $item->getDataValue('uid')) {
+                       logger('[WARN] Conversation::addThread : Thread is a mail ('. $item->getId() .').', LOGGER_DEBUG);
+                       return false;
+               }
+
+               if ($item->getDataValue('verb') === ACTIVITY_LIKE || $item->getDataValue('verb') === ACTIVITY_DISLIKE) {
+                       logger('[WARN] Conversation::addThread : Thread is a (dis)like ('. $item->getId() .').', LOGGER_DEBUG);
+                       return false;
+               }
+
+               $item->setConversation($this);
+               $this->threads[] = $item;
+
+               return end($this->threads);
+       }
+
+       /**
+        * Get data in a form usable by a conversation template
+        *
+        * We should find a way to avoid using those arguments (at least most of them)
+        *
+        * @param object $conv_responses data
+        *
+        * @return mixed The data requested on success
+        *               false on failure
+        */
+       public function getTemplateData($conv_responses)
+       {
+               $a = self::getApp();
+               $result = array();
+               $i = 0;
+
+               foreach ($this->threads as $item) {
+                       if ($item->getDataValue('network') === NETWORK_MAIL && local_user() != $item->getDataValue('uid')) {
+                               continue;
+                       }
+
+                       $item_data = $item->getTemplateData($conv_responses);
+
+                       if (!$item_data) {
+                               logger('[ERROR] Conversation::getTemplateData : Failed to get item template data ('. $item->getId() .').', LOGGER_DEBUG);
+                               return false;
+                       }
+                       $result[] = $item_data;
+               }
+
+               return $result;
+       }
+
+       /**
+        * Get a thread based on its item id
+        *
+        * @param integer $id Item id
+        *
+        * @return mixed The found item on success
+        *               false on failure
+        */
+       private function getThread($id)
+       {
+               foreach ($this->threads as $item) {
+                       if ($item->getId() == $id) {
+                               return $item;
+                       }
+               }
+
+               return false;
+       }
+}
diff --git a/src/Object/Image.php b/src/Object/Image.php
deleted file mode 100644 (file)
index 79fbf3a..0000000
+++ /dev/null
@@ -1,1040 +0,0 @@
-<?php
-/**
- * @file src/Object/Image.php
- * @brief This file contains the Image class for image processing
- */
-namespace Friendica\Object;
-
-use Friendica\App;
-use Friendica\Core\Cache;
-use Friendica\Core\Config;
-use Friendica\Core\System;
-use Friendica\Database\DBM;
-use Friendica\Model\Photo;
-use Exception;
-use Imagick;
-use ImagickPixel;
-
-require_once "include/photos.php";
-
-/**
- * Class to handle images
- */
-class Image
-{
-       private $image;
-
-       /*
-        * Put back gd stuff, not everybody have Imagick
-        */
-       private $imagick;
-       private $width;
-       private $height;
-       private $valid;
-       private $type;
-       private $types;
-
-       /**
-        * @brief supported mimetypes and corresponding file extensions
-        * @return array
-        */
-       public static function supportedTypes()
-       {
-               if (class_exists('Imagick')) {
-                       // Imagick::queryFormats won't help us a lot there...
-                       // At least, not yet, other parts of friendica uses this array
-                       $t = array(
-                               'image/jpeg' => 'jpg',
-                               'image/png' => 'png',
-                               'image/gif' => 'gif'
-                       );
-               } else {
-                       $t = array();
-                       $t['image/jpeg'] ='jpg';
-                       if (imagetypes() & IMG_PNG) {
-                               $t['image/png'] = 'png';
-                       }
-               }
-
-               return $t;
-       }
-
-       /**
-        * @brief Constructor
-        * @param object  $data data
-        * @param boolean $type optional, default null
-        * @return object
-        */
-       public function __construct($data, $type = null)
-       {
-               $this->imagick = class_exists('Imagick');
-               $this->types = static::supportedTypes();
-               if (!array_key_exists($type, $this->types)) {
-                       $type='image/jpeg';
-               }
-               $this->type = $type;
-
-               if ($this->isImagick() && $this->loadData($data)) {
-                       return true;
-               } else {
-                       // Failed to load with Imagick, fallback
-                       $this->imagick = false;
-               }
-               return $this->loadData($data);
-       }
-
-       /**
-        * @brief Destructor
-        * @return void
-        */
-       public function __destruct()
-       {
-               if ($this->image) {
-                       if ($this->isImagick()) {
-                               $this->image->clear();
-                               $this->image->destroy();
-                               return;
-                       }
-                       if (is_resource($this->image)) {
-                               imagedestroy($this->image);
-                       }
-               }
-       }
-
-       /**
-        * @return boolean
-        */
-       public function isImagick()
-       {
-               return $this->imagick;
-       }
-
-       /**
-        * @brief Maps Mime types to Imagick formats
-        * @return arr With with image formats (mime type as key)
-        */
-       public static function getFormatsMap()
-       {
-               $m = array(
-                       'image/jpeg' => 'JPG',
-                       'image/png' => 'PNG',
-                       'image/gif' => 'GIF'
-               );
-               return $m;
-       }
-
-       /**
-        * @param object $data data
-        * @return boolean
-        */
-       private function loadData($data)
-       {
-               if ($this->isImagick()) {
-                       $this->image = new Imagick();
-                       try {
-                               $this->image->readImageBlob($data);
-                       } catch (Exception $e) {
-                               // Imagick couldn't use the data
-                               return false;
-                       }
-
-                       /*
-                        * Setup the image to the format it will be saved to
-                        */
-                       $map = self::getFormatsMap();
-                       $format = $map[$type];
-                       $this->image->setFormat($format);
-
-                       // Always coalesce, if it is not a multi-frame image it won't hurt anyway
-                       $this->image = $this->image->coalesceImages();
-
-                       /*
-                        * setup the compression here, so we'll do it only once
-                        */
-                       switch ($this->getType()) {
-                               case "image/png":
-                                       $quality = Config::get('system', 'png_quality');
-                                       if ((! $quality) || ($quality > 9)) {
-                                               $quality = PNG_QUALITY;
-                                       }
-                                       /*
-                                        * From http://www.imagemagick.org/script/command-line-options.php#quality:
-                                        *
-                                        * 'For the MNG and PNG image formats, the quality value sets
-                                        * the zlib compression level (quality / 10) and filter-type (quality % 10).
-                                        * The default PNG "quality" is 75, which means compression level 7 with adaptive PNG filtering,
-                                        * unless the image has a color map, in which case it means compression level 7 with no PNG filtering'
-                                        */
-                                       $quality = $quality * 10;
-                                       $this->image->setCompressionQuality($quality);
-                                       break;
-                               case "image/jpeg":
-                                       $quality = Config::get('system', 'jpeg_quality');
-                                       if ((! $quality) || ($quality > 100)) {
-                                               $quality = JPEG_QUALITY;
-                                       }
-                                       $this->image->setCompressionQuality($quality);
-                       }
-
-                       // The 'width' and 'height' properties are only used by non-Imagick routines.
-                       $this->width  = $this->image->getImageWidth();
-                       $this->height = $this->image->getImageHeight();
-                       $this->valid  = true;
-
-                       return true;
-               }
-
-               $this->valid = false;
-               $this->image = @imagecreatefromstring($data);
-               if ($this->image !== false) {
-                       $this->width  = imagesx($this->image);
-                       $this->height = imagesy($this->image);
-                       $this->valid  = true;
-                       imagealphablending($this->image, false);
-                       imagesavealpha($this->image, true);
-
-                       return true;
-               }
-
-               return false;
-       }
-
-       /**
-        * @return boolean
-        */
-       public function isValid()
-       {
-               if ($this->isImagick()) {
-                       return ($this->image !== false);
-               }
-               return $this->valid;
-       }
-
-       /**
-        * @return mixed
-        */
-       public function getWidth()
-       {
-               if (!$this->isValid()) {
-                       return false;
-               }
-
-               if ($this->isImagick()) {
-                       return $this->image->getImageWidth();
-               }
-               return $this->width;
-       }
-
-       /**
-        * @return mixed
-        */
-       public function getHeight()
-       {
-               if (!$this->isValid()) {
-                       return false;
-               }
-
-               if ($this->isImagick()) {
-                       return $this->image->getImageHeight();
-               }
-               return $this->height;
-       }
-
-       /**
-        * @return mixed
-        */
-       public function getImage()
-       {
-               if (!$this->isValid()) {
-                       return false;
-               }
-
-               if ($this->isImagick()) {
-                       /* Clean it */
-                       $this->image = $this->image->deconstructImages();
-                       return $this->image;
-               }
-               return $this->image;
-       }
-
-       /**
-        * @return mixed
-        */
-       public function getType()
-       {
-               if (!$this->isValid()) {
-                       return false;
-               }
-
-               return $this->type;
-       }
-
-       /**
-        * @return mixed
-        */
-       public function getExt()
-       {
-               if (!$this->isValid()) {
-                       return false;
-               }
-
-               return $this->types[$this->getType()];
-       }
-
-       /**
-        * @param integer $max max dimension
-        * @return mixed
-        */
-       public function scaleDown($max)
-       {
-               if (!$this->isValid()) {
-                       return false;
-               }
-
-               $width = $this->getWidth();
-               $height = $this->getHeight();
-
-               $dest_width = $dest_height = 0;
-
-               if ((! $width)|| (! $height)) {
-                       return false;
-               }
-
-               if ($width > $max && $height > $max) {
-                       // very tall image (greater than 16:9)
-                       // constrain the width - let the height float.
-
-                       if ((($height * 9) / 16) > $width) {
-                               $dest_width = $max;
-                               $dest_height = intval(($height * $max) / $width);
-                       } elseif ($width > $height) {
-                               // else constrain both dimensions
-                               $dest_width = $max;
-                               $dest_height = intval(($height * $max) / $width);
-                       } else {
-                               $dest_width = intval(($width * $max) / $height);
-                               $dest_height = $max;
-                       }
-               } else {
-                       if ($width > $max) {
-                               $dest_width = $max;
-                               $dest_height = intval(($height * $max) / $width);
-                       } else {
-                               if ($height > $max) {
-                                       // very tall image (greater than 16:9)
-                                       // but width is OK - don't do anything
-
-                                       if ((($height * 9) / 16) > $width) {
-                                               $dest_width = $width;
-                                               $dest_height = $height;
-                                       } else {
-                                               $dest_width = intval(($width * $max) / $height);
-                                               $dest_height = $max;
-                                       }
-                               } else {
-                                       $dest_width = $width;
-                                       $dest_height = $height;
-                               }
-                       }
-               }
-
-
-               if ($this->isImagick()) {
-                       /*
-                        * If it is not animated, there will be only one iteration here,
-                        * so don't bother checking
-                        */
-                       // Don't forget to go back to the first frame
-                       $this->image->setFirstIterator();
-                       do {
-                               // FIXME - implement horizantal bias for scaling as in followin GD functions
-                               // to allow very tall images to be constrained only horizontally.
-
-                               $this->image->scaleDown($dest_width, $dest_height);
-                       } while ($this->image->nextImage());
-
-                       // These may not be necessary any more
-                       $this->width  = $this->image->getImageWidth();
-                       $this->height = $this->image->getImageHeight();
-
-                       return;
-               }
-
-
-               $dest = imagecreatetruecolor($dest_width, $dest_height);
-               imagealphablending($dest, false);
-               imagesavealpha($dest, true);
-               if ($this->type=='image/png') {
-                       imagefill($dest, 0, 0, imagecolorallocatealpha($dest, 0, 0, 0, 127)); // fill with alpha
-               }
-               imagecopyresampled($dest, $this->image, 0, 0, 0, 0, $dest_width, $dest_height, $width, $height);
-               if ($this->image) {
-                       imagedestroy($this->image);
-               }
-               $this->image = $dest;
-               $this->width  = imagesx($this->image);
-               $this->height = imagesy($this->image);
-       }
-
-       /**
-        * @param integer $degrees degrees to rotate image
-        * @return mixed
-        */
-       public function rotate($degrees)
-       {
-               if (!$this->isValid()) {
-                       return false;
-               }
-
-               if ($this->isImagick()) {
-                       $this->image->setFirstIterator();
-                       do {
-                               $this->image->rotateImage(new ImagickPixel(), -$degrees); // ImageMagick rotates in the opposite direction of imagerotate()
-                       } while ($this->image->nextImage());
-                       return;
-               }
-
-               // if script dies at this point check memory_limit setting in php.ini
-               $this->image  = imagerotate($this->image, $degrees, 0);
-               $this->width  = imagesx($this->image);
-               $this->height = imagesy($this->image);
-       }
-
-       /**
-        * @param boolean $horiz optional, default true
-        * @param boolean $vert  optional, default false
-        * @return mixed
-        */
-       public function flip($horiz = true, $vert = false)
-       {
-               if (!$this->isValid()) {
-                       return false;
-               }
-
-               if ($this->isImagick()) {
-                       $this->image->setFirstIterator();
-                       do {
-                               if ($horiz) {
-                                       $this->image->flipImage();
-                               }
-                               if ($vert) {
-                                       $this->image->flopImage();
-                               }
-                       } while ($this->image->nextImage());
-                       return;
-               }
-
-               $w = imagesx($this->image);
-               $h = imagesy($this->image);
-               $flipped = imagecreate($w, $h);
-               if ($horiz) {
-                       for ($x = 0; $x < $w; $x++) {
-                               imagecopy($flipped, $this->image, $x, 0, $w - $x - 1, 0, 1, $h);
-                       }
-               }
-               if ($vert) {
-                       for ($y = 0; $y < $h; $y++) {
-                               imagecopy($flipped, $this->image, 0, $y, 0, $h - $y - 1, $w, 1);
-                       }
-               }
-               $this->image = $flipped;
-       }
-
-       /**
-        * @param string $filename filename
-        * @return mixed
-        */
-       public function orient($filename)
-       {
-               if ($this->isImagick()) {
-                       // based off comment on http://php.net/manual/en/imagick.getimageorientation.php
-                       $orientation = $this->image->getImageOrientation();
-                       switch ($orientation) {
-                               case Imagick::ORIENTATION_BOTTOMRIGHT:
-                                       $this->image->rotateimage("#000", 180);
-                                       break;
-                               case Imagick::ORIENTATION_RIGHTTOP:
-                                       $this->image->rotateimage("#000", 90);
-                                       break;
-                               case Imagick::ORIENTATION_LEFTBOTTOM:
-                                       $this->image->rotateimage("#000", -90);
-                                       break;
-                       }
-
-                       $this->image->setImageOrientation(Imagick::ORIENTATION_TOPLEFT);
-                       return true;
-               }
-               // based off comment on http://php.net/manual/en/function.imagerotate.php
-
-               if (!$this->isValid()) {
-                       return false;
-               }
-
-               if ((!function_exists('exif_read_data')) || ($this->getType() !== 'image/jpeg')) {
-                       return;
-               }
-
-               $exif = @exif_read_data($filename, null, true);
-               if (!$exif) {
-                       return;
-               }
-
-               $ort = $exif['IFD0']['Orientation'];
-
-               switch ($ort) {
-                       case 1: // nothing
-                               break;
-
-                       case 2: // horizontal flip
-                               $this->flip();
-                               break;
-
-                       case 3: // 180 rotate left
-                               $this->rotate(180);
-                               break;
-
-                       case 4: // vertical flip
-                               $this->flip(false, true);
-                               break;
-
-                       case 5: // vertical flip + 90 rotate right
-                               $this->flip(false, true);
-                               $this->rotate(-90);
-                               break;
-
-                       case 6: // 90 rotate right
-                               $this->rotate(-90);
-                               break;
-
-                       case 7: // horizontal flip + 90 rotate right
-                               $this->flip();
-                               $this->rotate(-90);
-                               break;
-
-                       case 8: // 90 rotate left
-                               $this->rotate(90);
-                               break;
-               }
-
-               //      logger('exif: ' . print_r($exif,true));
-               return $exif;
-       }
-
-       /**
-        * @param integer $min minimum dimension
-        * @return mixed
-        */
-       public function scaleUp($min)
-       {
-               if (!$this->isValid()) {
-                       return false;
-               }
-
-               $width = $this->getWidth();
-               $height = $this->getHeight();
-
-               $dest_width = $dest_height = 0;
-
-               if ((!$width)|| (!$height)) {
-                       return false;
-               }
-
-               if ($width < $min && $height < $min) {
-                       if ($width > $height) {
-                               $dest_width = $min;
-                               $dest_height = intval(($height * $min) / $width);
-                       } else {
-                               $dest_width = intval(($width * $min) / $height);
-                               $dest_height = $min;
-                       }
-               } else {
-                       if ($width < $min) {
-                               $dest_width = $min;
-                               $dest_height = intval(($height * $min) / $width);
-                       } else {
-                               if ($height < $min) {
-                                       $dest_width = intval(($width * $min) / $height);
-                                       $dest_height = $min;
-                               } else {
-                                       $dest_width = $width;
-                                       $dest_height = $height;
-                               }
-                       }
-               }
-
-               if ($this->isImagick()) {
-                       return $this->scaleDown($dest_width, $dest_height);
-               }
-
-               $dest = imagecreatetruecolor($dest_width, $dest_height);
-               imagealphablending($dest, false);
-               imagesavealpha($dest, true);
-               if ($this->type=='image/png') {
-                       imagefill($dest, 0, 0, imagecolorallocatealpha($dest, 0, 0, 0, 127)); // fill with alpha
-               }
-               imagecopyresampled($dest, $this->image, 0, 0, 0, 0, $dest_width, $dest_height, $width, $height);
-               if ($this->image) {
-                       imagedestroy($this->image);
-               }
-               $this->image = $dest;
-               $this->width  = imagesx($this->image);
-               $this->height = imagesy($this->image);
-       }
-
-       /**
-        * @param integer $dim dimension
-        * @return mixed
-        */
-       public function scaleToSquare($dim)
-       {
-               if (!$this->isValid()) {
-                       return false;
-               }
-
-               if ($this->isImagick()) {
-                       $this->image->setFirstIterator();
-                       do {
-                               $this->image->scaleDown($dim, $dim);
-                       } while ($this->image->nextImage());
-                       return;
-               }
-
-               $dest = imagecreatetruecolor($dim, $dim);
-               imagealphablending($dest, false);
-               imagesavealpha($dest, true);
-               if ($this->type=='image/png') {
-                       imagefill($dest, 0, 0, imagecolorallocatealpha($dest, 0, 0, 0, 127)); // fill with alpha
-               }
-               imagecopyresampled($dest, $this->image, 0, 0, 0, 0, $dim, $dim, $this->width, $this->height);
-               if ($this->image) {
-                       imagedestroy($this->image);
-               }
-               $this->image = $dest;
-               $this->width  = imagesx($this->image);
-               $this->height = imagesy($this->image);
-       }
-
-       /**
-        * @param integer $max maximum
-        * @param integer $x   x coordinate
-        * @param integer $y   y coordinate
-        * @param integer $w   width
-        * @param integer $h   height
-        * @return mixed
-        */
-       public function crop($max, $x, $y, $w, $h)
-       {
-               if (!$this->isValid()) {
-                       return false;
-               }
-
-               if ($this->isImagick()) {
-                       $this->image->setFirstIterator();
-                       do {
-                               $this->image->cropImage($w, $h, $x, $y);
-                               /*
-                                * We need to remove the canva,
-                                * or the image is not resized to the crop:
-                                * http://php.net/manual/en/imagick.cropimage.php#97232
-                                */
-                               $this->image->setImagePage(0, 0, 0, 0);
-                       } while ($this->image->nextImage());
-                       return $this->scaleDown($max);
-               }
-
-               $dest = imagecreatetruecolor($max, $max);
-               imagealphablending($dest, false);
-               imagesavealpha($dest, true);
-               if ($this->type=='image/png') {
-                       imagefill($dest, 0, 0, imagecolorallocatealpha($dest, 0, 0, 0, 127)); // fill with alpha
-               }
-               imagecopyresampled($dest, $this->image, 0, 0, $x, $y, $max, $max, $w, $h);
-               if ($this->image) {
-                       imagedestroy($this->image);
-               }
-               $this->image = $dest;
-               $this->width  = imagesx($this->image);
-               $this->height = imagesy($this->image);
-       }
-
-       /**
-        * @param string $path file path
-        * @return mixed
-        */
-       public function saveToFilePath($path)
-       {
-               if (!$this->isValid()) {
-                       return false;
-               }
-
-               $string = $this->asString();
-
-               $a = get_app();
-
-               $stamp1 = microtime(true);
-               file_put_contents($path, $string);
-               $a->save_timestamp($stamp1, "file");
-       }
-
-       /**
-        * @brief Magic method allowing string casting of an Image object
-        *
-        * Ex: $data = $Image->asString();
-        * can be replaced by
-        * $data = (string) $Image;
-        *
-        * @return string
-        */
-       public function __toString() {
-               return $this->asString();
-       }
-
-       /**
-        * @return mixed
-        */
-       public function asString()
-       {
-               if (!$this->isValid()) {
-                       return false;
-               }
-
-               if ($this->isImagick()) {
-                       /* Clean it */
-                       $this->image = $this->image->deconstructImages();
-                       $string = $this->image->getImagesBlob();
-                       return $string;
-               }
-
-               $quality = false;
-
-               ob_start();
-
-               // Enable interlacing
-               imageinterlace($this->image, true);
-
-               switch ($this->getType()) {
-                       case "image/png":
-                               $quality = Config::get('system', 'png_quality');
-                               if ((!$quality) || ($quality > 9)) {
-                                       $quality = PNG_QUALITY;
-                               }
-                               imagepng($this->image, null, $quality);
-                               break;
-                       case "image/jpeg":
-                               $quality = Config::get('system', 'jpeg_quality');
-                               if ((!$quality) || ($quality > 100)) {
-                                       $quality = JPEG_QUALITY;
-                               }
-                               imagejpeg($this->image, null, $quality);
-               }
-               $string = ob_get_contents();
-               ob_end_clean();
-
-               return $string;
-       }
-
-       /**
-        * Guess image mimetype from filename or from Content-Type header
-        *
-        * @param string  $filename Image filename
-        * @param boolean $fromcurl Check Content-Type header from curl request
-        *
-        * @return object
-        */
-       public static function guessType($filename, $fromcurl = false)
-       {
-               logger('Image: guessType: '.$filename . ($fromcurl?' from curl headers':''), LOGGER_DEBUG);
-               $type = null;
-               if ($fromcurl) {
-                       $a = get_app();
-                       $headers=array();
-                       $h = explode("\n", $a->get_curl_headers());
-                       foreach ($h as $l) {
-                               list($k,$v) = array_map("trim", explode(":", trim($l), 2));
-                               $headers[$k] = $v;
-                       }
-                       if (array_key_exists('Content-Type', $headers))
-                               $type = $headers['Content-Type'];
-               }
-               if (is_null($type)) {
-                       // Guessing from extension? Isn't that... dangerous?
-                       if (class_exists('Imagick') && file_exists($filename) && is_readable($filename)) {
-                               /**
-                                * Well, this not much better,
-                                * but at least it comes from the data inside the image,
-                                * we won't be tricked by a manipulated extension
-                                */
-                               $image = new Imagick($filename);
-                               $type = $image->getImageMimeType();
-                               $image->setInterlaceScheme(Imagick::INTERLACE_PLANE);
-                       } else {
-                               $ext = pathinfo($filename, PATHINFO_EXTENSION);
-                               $types = self::supportedTypes();
-                               $type = "image/jpeg";
-                               foreach ($types as $m => $e) {
-                                       if ($ext == $e) {
-                                               $type = $m;
-                                       }
-                               }
-                       }
-               }
-               logger('Image: guessType: type='.$type, LOGGER_DEBUG);
-               return $type;
-       }
-
-       /**
-        * @param string $url url
-        * @return object
-        */
-       public static function getInfoFromURL($url)
-       {
-               $data = array();
-
-               $data = Cache::get($url);
-
-               if (is_null($data) || !$data || !is_array($data)) {
-                       $img_str = fetch_url($url, true, $redirects, 4);
-                       $filesize = strlen($img_str);
-
-                       if (function_exists("getimagesizefromstring")) {
-                               $data = getimagesizefromstring($img_str);
-                       } else {
-                               $tempfile = tempnam(get_temppath(), "cache");
-
-                               $a = get_app();
-                               $stamp1 = microtime(true);
-                               file_put_contents($tempfile, $img_str);
-                               $a->save_timestamp($stamp1, "file");
-
-                               $data = getimagesize($tempfile);
-                               unlink($tempfile);
-                       }
-
-                       if ($data) {
-                               $data["size"] = $filesize;
-                       }
-
-                       Cache::set($url, $data);
-               }
-
-               return $data;
-       }
-
-       /**
-        * @param integer $width  width
-        * @param integer $height height
-        * @param integer $max    max
-        * @return array
-        */
-       public static function getScalingDimensions($width, $height, $max)
-       {
-               $dest_width = $dest_height = 0;
-
-               if ((!$width) || (!$height)) {
-                       return false;
-               }
-
-               if ($width > $max && $height > $max) {
-                       // very tall image (greater than 16:9)
-                       // constrain the width - let the height float.
-
-                       if ((($height * 9) / 16) > $width) {
-                               $dest_width = $max;
-                               $dest_height = intval(($height * $max) / $width);
-                       } elseif ($width > $height) {
-                               // else constrain both dimensions
-                               $dest_width = $max;
-                               $dest_height = intval(($height * $max) / $width);
-                       } else {
-                               $dest_width = intval(($width * $max) / $height);
-                               $dest_height = $max;
-                       }
-               } else {
-                       if ($width > $max) {
-                               $dest_width = $max;
-                               $dest_height = intval(($height * $max) / $width);
-                       } else {
-                               if ($height > $max) {
-                                       // very tall image (greater than 16:9)
-                                       // but width is OK - don't do anything
-
-                                       if ((($height * 9) / 16) > $width) {
-                                               $dest_width = $width;
-                                               $dest_height = $height;
-                                       } else {
-                                               $dest_width = intval(($width * $max) / $height);
-                                               $dest_height = $max;
-                                       }
-                               } else {
-                                       $dest_width = $width;
-                                       $dest_height = $height;
-                               }
-                       }
-               }
-               return array("width" => $dest_width, "height" => $dest_height);
-       }
-
-       /**
-        * @brief This function is used by the fromgplus addon
-        * @param object  $a         App
-        * @param integer $uid       user id
-        * @param string  $imagedata optional, default empty
-        * @param string  $url       optional, default empty
-        * @return array
-        */
-       public static function storePhoto(App $a, $uid, $imagedata = "", $url = "")
-       {
-               $r = q(
-                       "SELECT `user`.`nickname`, `user`.`page-flags`, `contact`.`id` FROM `user` INNER JOIN `contact` on `user`.`uid` = `contact`.`uid`
-                       WHERE `user`.`uid` = %d AND `user`.`blocked` = 0 AND `contact`.`self` = 1 LIMIT 1",
-                       intval($uid)
-               );
-
-               if (!DBM::is_result($r)) {
-                       logger("Can't detect user data for uid ".$uid, LOGGER_DEBUG);
-                       return(array());
-               }
-
-               $page_owner_nick  = $r[0]['nickname'];
-
-               /// @TODO
-               /// $default_cid      = $r[0]['id'];
-               /// $community_page   = (($r[0]['page-flags'] == PAGE_COMMUNITY) ? true : false);
-
-               if ((strlen($imagedata) == 0) && ($url == "")) {
-                       logger("No image data and no url provided", LOGGER_DEBUG);
-                       return(array());
-               } elseif (strlen($imagedata) == 0) {
-                       logger("Uploading picture from ".$url, LOGGER_DEBUG);
-
-                       $stamp1 = microtime(true);
-                       $imagedata = @file_get_contents($url);
-                       $a->save_timestamp($stamp1, "file");
-               }
-
-               $maximagesize = Config::get('system', 'maximagesize');
-
-               if (($maximagesize) && (strlen($imagedata) > $maximagesize)) {
-                       logger("Image exceeds size limit of ".$maximagesize, LOGGER_DEBUG);
-                       return(array());
-               }
-
-               $tempfile = tempnam(get_temppath(), "cache");
-
-               $stamp1 = microtime(true);
-               file_put_contents($tempfile, $imagedata);
-               $a->save_timestamp($stamp1, "file");
-
-               $data = getimagesize($tempfile);
-
-               if (!isset($data["mime"])) {
-                       unlink($tempfile);
-                       logger("File is no picture", LOGGER_DEBUG);
-                       return(array());
-               }
-
-               $Image = new Image($imagedata, $data["mime"]);
-
-               if (!$Image->isValid()) {
-                       unlink($tempfile);
-                       logger("Picture is no valid picture", LOGGER_DEBUG);
-                       return(array());
-               }
-
-               $Image->orient($tempfile);
-               unlink($tempfile);
-
-               $max_length = Config::get('system', 'max_image_length');
-               if (! $max_length) {
-                       $max_length = MAX_IMAGE_LENGTH;
-               }
-
-               if ($max_length > 0) {
-                       $Image->scaleDown($max_length);
-               }
-
-               $width = $Image->getWidth();
-               $height = $Image->getHeight();
-
-               $hash = photo_new_resource();
-
-               $smallest = 0;
-
-               // Pictures are always public by now
-               //$defperm = '<'.$default_cid.'>';
-               $defperm = "";
-               $visitor = 0;
-
-               $r = Photo::store($Image, $uid, $visitor, $hash, $tempfile, t('Wall Photos'), 0, 0, $defperm);
-
-               if (!$r) {
-                       logger("Picture couldn't be stored", LOGGER_DEBUG);
-                       return(array());
-               }
-
-               $image = array("page" => System::baseUrl().'/photos/'.$page_owner_nick.'/image/'.$hash,
-                       "full" => System::baseUrl()."/photo/{$hash}-0.".$Image->getExt());
-
-               if ($width > 800 || $height > 800) {
-                       $image["large"] = System::baseUrl()."/photo/{$hash}-0.".$Image->getExt();
-               }
-
-               if ($width > 640 || $height > 640) {
-                       $Image->scaleDown(640);
-                       $r = Photo::store($Image, $uid, $visitor, $hash, $tempfile, t('Wall Photos'), 1, 0, $defperm);
-                       if ($r) {
-                               $image["medium"] = System::baseUrl()."/photo/{$hash}-1.".$Image->getExt();
-                       }
-               }
-
-               if ($width > 320 || $height > 320) {
-                       $Image->scaleDown(320);
-                       $r = Photo::store($Image, $uid, $visitor, $hash, $tempfile, t('Wall Photos'), 2, 0, $defperm);
-                       if ($r) {
-                               $image["small"] = System::baseUrl()."/photo/{$hash}-2.".$Image->getExt();
-                       }
-               }
-
-               if ($width > 160 && $height > 160) {
-                       $x = 0;
-                       $y = 0;
-
-                       $min = $Image->getWidth();
-                       if ($min > 160) {
-                               $x = ($min - 160) / 2;
-                       }
-
-                       if ($Image->getHeight() < $min) {
-                               $min = $Image->getHeight();
-                               if ($min > 160) {
-                                       $y = ($min - 160) / 2;
-                               }
-                       }
-
-                       $min = 160;
-                       $Image->crop(160, $x, $y, $min, $min);
-
-                       $r = Photo::store($Image, $uid, $visitor, $hash, $tempfile, t('Wall Photos'), 3, 0, $defperm);
-                       if ($r) {
-                               $image["thumb"] = System::baseUrl()."/photo/{$hash}-3.".$Image->getExt();
-                       }
-               }
-
-               // Set the full image as preview image. This will be overwritten, if the picture is larger than 640.
-               $image["preview"] = $image["full"];
-
-               // Deactivated, since that would result in a cropped preview, if the picture wasn't larger than 320
-               //if (isset($image["thumb"]))
-               //  $image["preview"] = $image["thumb"];
-
-               // Unsure, if this should be activated or deactivated
-               //if (isset($image["small"]))
-               //  $image["preview"] = $image["small"];
-
-               if (isset($image["medium"])) {
-                       $image["preview"] = $image["medium"];
-               }
-
-               return($image);
-       }
-}
diff --git a/src/Object/Item.php b/src/Object/Item.php
new file mode 100644 (file)
index 0000000..1533908
--- /dev/null
@@ -0,0 +1,915 @@
+<?php
+/**
+ * @file src/Object/Item.php
+ */
+namespace Friendica\Object;
+
+use Friendica\BaseObject;
+use Friendica\Content\Feature;
+use Friendica\Core\Config;
+use Friendica\Core\PConfig;
+use Friendica\Database\DBM;
+use Friendica\Object\Contact;
+use dba;
+
+require_once 'include/text.php';
+require_once 'boot.php';
+require_once "include/conversation.php";
+
+/**
+ * An item
+ */
+class Item extends BaseObject
+{
+       private $data = array();
+       private $template = null;
+       private $available_templates = array(
+               'wall' => 'wall_thread.tpl',
+               'wall2wall' => 'wallwall_thread.tpl'
+       );
+       private $comment_box_template = 'comment_item.tpl';
+       private $toplevel = false;
+       private $writable = false;
+       private $children = array();
+       private $parent = null;
+       private $conversation = null;
+       private $redirect_url = null;
+       private $owner_url = '';
+       private $owner_photo = '';
+       private $owner_name = '';
+       private $wall_to_wall = false;
+       private $threaded = false;
+       private $visiting = false;
+
+       /**
+        * Constructor
+        *
+        * @param array $data data array
+        */
+       public function __construct($data)
+       {
+               $a = self::getApp();
+
+               $this->data = $data;
+               $this->setTemplate('wall');
+               $this->toplevel = ($this->getId() == $this->getDataValue('parent'));
+
+               if (is_array($_SESSION['remote'])) {
+                       foreach ($_SESSION['remote'] as $visitor) {
+                               if ($visitor['cid'] == $this->getDataValue('contact-id')) {
+                                       $this->visiting = true;
+                                       break;
+                               }
+                       }
+               }
+
+               $this->writable = ($this->getDataValue('writable') || $this->getDataValue('self'));
+
+               $ssl_state = ((local_user()) ? true : false);
+               $this->redirect_url = 'redir/' . $this->getDataValue('cid');
+
+               if (!$this->isToplevel()) {
+                       $this->threaded = true;
+               }
+
+               // Prepare the children
+               if (count($data['children'])) {
+                       foreach ($data['children'] as $item) {
+                               /*
+                                * Only add will be displayed
+                                */
+                               if ($item['network'] === NETWORK_MAIL && local_user() != $item['uid']) {
+                                       continue;
+                               } elseif (! visible_activity($item)) {
+                                       continue;
+                               }
+
+                               // You can always comment on Diaspora items
+                               if (($item['network'] == NETWORK_DIASPORA) && (local_user() == $item['uid'])) {
+                                       $item['writable'] = true;
+                               }
+
+                               $item['pagedrop'] = $data['pagedrop'];
+                               $child = new Item($item);
+                               $this->addChild($child);
+                       }
+               }
+       }
+
+       /**
+        * Get data in a form usable by a conversation template
+        *
+        * @param object  $conv_responses conversation responses
+        * @param integer $thread_level   default = 1
+        *
+        * @return mixed The data requested on success
+        *               false on failure
+        */
+       public function getTemplateData($conv_responses, $thread_level = 1)
+       {
+               require_once "mod/proxy.php";
+
+               $result = array();
+
+               $a = self::getApp();
+
+               $item = $this->getData();
+               $edited = false;
+               // If the time between "created" and "edited" differs we add
+               // a notice that the post was edited.
+               // Note: In some networks reshared items seem to have (sometimes) a difference
+               // between creation time and edit time of a second. Thats why we add the notice
+               // only if the difference is more than 1 second.
+               if (strtotime($item['edited']) - strtotime($item['created']) > 1) {
+                       $edited = array(
+                               'label'    => t('This entry was edited'),
+                               'date'     => datetime_convert('UTC', date_default_timezone_get(), $item['edited'], 'r'),
+                               'relative' => relative_date($item['edited'])
+                       );
+               }
+               $commentww = '';
+               $sparkle = '';
+               $buttons = '';
+               $dropping = false;
+               $star = false;
+               $ignore = false;
+               $isstarred = "unstarred";
+               $indent = '';
+               $shiny = '';
+               $osparkle = '';
+               $total_children = $this->countDescendants();
+
+               $conv = $this->getConversation();
+
+               $lock = ((($item['private'] == 1) || (($item['uid'] == local_user()) && (strlen($item['allow_cid']) || strlen($item['allow_gid'])
+                       || strlen($item['deny_cid']) || strlen($item['deny_gid']))))
+                       ? t('Private Message')
+                       : false);
+               $shareable = ((($conv->getProfileOwner() == local_user()) && ($item['private'] != 1)) ? true : false);
+               if (local_user() && link_compare($a->contact['url'], $item['author-link'])) {
+                       if ($item["event-id"] != 0) {
+                               $edpost = array("events/event/".$item['event-id'], t("Edit"));
+                       } else {
+                               $edpost = array("editpost/".$item['id'], t("Edit"));
+                       }
+               } else {
+                       $edpost = false;
+               }
+
+               if (($this->getDataValue('uid') == local_user()) || $this->isVisiting()) {
+                       $dropping = true;
+               }
+
+               $drop = array(
+                       'dropping' => $dropping,
+                       'pagedrop' => ((Feature::isEnabled($conv->getProfileOwner(), 'multi_delete')) ? $item['pagedrop'] : ''),
+                       'select'   => t('Select'),
+                       'delete'   => t('Delete'),
+               );
+
+               $filer = (($conv->getProfileOwner() == local_user()) ? t("save to folder") : false);
+
+               $diff_author    = ((link_compare($item['url'], $item['author-link'])) ? false : true);
+               $profile_name   = htmlentities(((strlen($item['author-name'])) && $diff_author) ? $item['author-name'] : $item['name']);
+               if ($item['author-link'] && (! $item['author-name'])) {
+                       $profile_name = $item['author-link'];
+               }
+
+               $sp = false;
+               $profile_link = best_link_url($item, $sp);
+               if ($profile_link === 'mailbox') {
+                       $profile_link = '';
+               }
+
+               if ($sp) {
+                       $sparkle = ' sparkle';
+               } else {
+                       $profile_link = zrl($profile_link);
+               }
+
+               if (!isset($item['author-thumb']) || ($item['author-thumb'] == "")) {
+                       $author_contact = Contact::getDetailsByURL($item['author-link'], $conv->getProfileOwner());
+                       if ($author_contact["thumb"]) {
+                               $item['author-thumb'] = $author_contact["thumb"];
+                       } else {
+                               $item['author-thumb'] = $item['author-avatar'];
+                       }
+               }
+
+               if (!isset($item['owner-thumb']) || ($item['owner-thumb'] == "")) {
+                       $owner_contact = Contact::getDetailsByURL($item['owner-link'], $conv->getProfileOwner());
+                       if ($owner_contact["thumb"]) {
+                               $item['owner-thumb'] = $owner_contact["thumb"];
+                       } else {
+                               $item['owner-thumb'] = $item['owner-avatar'];
+                       }
+               }
+
+               $locate = array('location' => $item['location'], 'coord' => $item['coord'], 'html' => '');
+               call_hooks('render_location', $locate);
+               $location = ((strlen($locate['html'])) ? $locate['html'] : render_location_dummy($locate));
+
+               $tags=array();
+               $hashtags = array();
+               $mentions = array();
+
+               /*foreach(explode(',',$item['tag']) as $tag){
+                       $tag = trim($tag);
+                       if ($tag!="") {
+                               $t = bbcode($tag);
+                               $tags[] = $t;
+                               if($t[0] == '#')
+                                       $hashtags[] = $t;
+                               elseif($t[0] == '@')
+                                       $mentions[] = $t;
+                       }
+               }*/
+
+               // process action responses - e.g. like/dislike/attend/agree/whatever
+               $response_verbs = array('like', 'dislike');
+
+               if ($item['object-type'] === ACTIVITY_OBJ_EVENT) {
+                       $response_verbs[] = 'attendyes';
+                       $response_verbs[] = 'attendno';
+                       $response_verbs[] = 'attendmaybe';
+                       if ($conv->isWritable()) {
+                               $isevent = true;
+                               $attend = array( t('I will attend'), t('I will not attend'), t('I might attend'));
+                       }
+               }
+
+               $responses = get_responses($conv_responses, $response_verbs, $this, $item);
+
+               foreach ($response_verbs as $value => $verbs) {
+                       $responses[$verbs]['output']  = ((x($conv_responses[$verbs], $item['uri'])) ? format_like($conv_responses[$verbs][$item['uri']], $conv_responses[$verbs][$item['uri'] . '-l'], $verbs, $item['uri']) : '');
+               }
+
+               /*
+                * We should avoid doing this all the time, but it depends on the conversation mode
+                * And the conv mode may change when we change the conv, or it changes its mode
+                * Maybe we should establish a way to be notified about conversation changes
+                */
+               $this->checkWallToWall();
+
+               if ($this->isWallToWall() && ($this->getOwnerUrl() == $this->getRedirectUrl())) {
+                       $osparkle = ' sparkle';
+               }
+
+               if ($this->isToplevel()) {
+                       if ($conv->getProfileOwner() == local_user()) {
+                               $isstarred = (($item['starred']) ? "starred" : "unstarred");
+
+                               $star = array(
+                                       'do'        => t("add star"),
+                                       'undo'      => t("remove star"),
+                                       'toggle'    => t("toggle star status"),
+                                       'classdo'   => (($item['starred']) ? "hidden" : ""),
+                                       'classundo' => (($item['starred']) ? "" : "hidden"),
+                                       'starred'   =>  t('starred'),
+                               );
+                               $r = dba::select('thread', array('ignored'), array('uid' => $item['uid'], 'iid' => $item['id']), array('limit' => 1));
+                               if (DBM::is_result($r)) {
+                                       $ignore = array(
+                                               'do'        => t("ignore thread"),
+                                               'undo'      => t("unignore thread"),
+                                               'toggle'    => t("toggle ignore status"),
+                                               'classdo'   => (($r['ignored']) ? "hidden" : ""),
+                                               'classundo' => (($r['ignored']) ? "" : "hidden"),
+                                               'ignored'   =>  t('ignored'),
+                                       );
+                               }
+
+                               $tagger = '';
+                               if (Feature::isEnabled($conv->getProfileOwner(), 'commtag')) {
+                                       $tagger = array(
+                                               'add'   => t("add tag"),
+                                               'class' => "",
+                                       );
+                               }
+                       }
+               } else {
+                       $indent = 'comment';
+               }
+
+               if ($conv->isWritable()) {
+                       $buttons = array(
+                               'like' => array( t("I like this \x28toggle\x29"), t("like")),
+                               'dislike' => ((Feature::isEnabled($conv->getProfileOwner(), 'dislike')) ? array( t("I don't like this \x28toggle\x29"), t("dislike")) : ''),
+                       );
+                       if ($shareable) {
+                               $buttons['share'] = array( t('Share this'), t('share'));
+                       }
+               }
+
+               $comment = $this->getCommentBox($indent);
+
+               if (strcmp(datetime_convert('UTC', 'UTC', $item['created']), datetime_convert('UTC', 'UTC', 'now - 12 hours')) > 0) {
+                       $shiny = 'shiny';
+               }
+
+               localize_item($item);
+
+               $body = prepare_body($item, true);
+
+               list($categories, $folders) = get_cats_and_terms($item);
+
+               $body_e       = $body;
+               $text_e       = strip_tags($body);
+               $name_e       = $profile_name;
+               $title_e      = $item['title'];
+               $location_e   = $location;
+               $owner_name_e = $this->getOwnerName();
+
+               // Disable features that aren't available in several networks
+
+               /// @todo Add NETWORK_DIASPORA when it will pass this information
+               if (!in_array($item["item_network"], array(NETWORK_DFRN)) && isset($buttons["dislike"])) {
+                       unset($buttons["dislike"], $isevent);
+                       $tagger = '';
+               }
+
+               if (($item["item_network"] == NETWORK_FEED) && isset($buttons["like"])) {
+                       unset($buttons["like"]);
+               }
+
+               if (($item["item_network"] == NETWORK_MAIL) && isset($buttons["like"])) {
+                       unset($buttons["like"]);
+               }
+
+               $tmp_item = array(
+                       'template'        => $this->getTemplate(),
+                       'type'            => implode("", array_slice(explode("/", $item['verb']), -1)),
+                       'tags'            => $item['tags'],
+                       'hashtags'        => $item['hashtags'],
+                       'mentions'        => $item['mentions'],
+                       'txt_cats'        => t('Categories:'),
+                       'txt_folders'     => t('Filed under:'),
+                       'has_cats'        => ((count($categories)) ? 'true' : ''),
+                       'has_folders'     => ((count($folders)) ? 'true' : ''),
+                       'categories'      => $categories,
+                       'folders'         => $folders,
+                       'body'            => $body_e,
+                       'text'            => $text_e,
+                       'id'              => $this->getId(),
+                       'guid'            => urlencode($item['guid']),
+                       'isevent'         => $isevent,
+                       'attend'          => $attend,
+                       'linktitle'       => sprintf(t('View %s\'s profile @ %s'), $profile_name, ((strlen($item['author-link'])) ? $item['author-link'] : $item['url'])),
+                       'olinktitle'      => sprintf(t('View %s\'s profile @ %s'), htmlentities($this->getOwnerName()), ((strlen($item['owner-link'])) ? $item['owner-link'] : $item['url'])),
+                       'to'              => t('to'),
+                       'via'             => t('via'),
+                       'wall'            => t('Wall-to-Wall'),
+                       'vwall'           => t('via Wall-To-Wall:'),
+                       'profile_url'     => $profile_link,
+                       'item_photo_menu' => item_photo_menu($item),
+                       'name'            => $name_e,
+                       'thumb'           => $a->remove_baseurl(proxy_url($item['author-thumb'], false, PROXY_SIZE_THUMB)),
+                       'osparkle'        => $osparkle,
+                       'sparkle'         => $sparkle,
+                       'title'           => $title_e,
+                       'localtime'       => datetime_convert('UTC', date_default_timezone_get(), $item['created'], 'r'),
+                       'ago'             => (($item['app']) ? sprintf(t('%s from %s'), relative_date($item['created']), $item['app']) : relative_date($item['created'])),
+                       'app'             => $item['app'],
+                       'created'         => relative_date($item['created']),
+                       'lock'            => $lock,
+                       'location'        => $location_e,
+                       'indent'          => $indent,
+                       'shiny'           => $shiny,
+                       'owner_url'       => $this->getOwnerUrl(),
+                       'owner_photo'     => $a->remove_baseurl(proxy_url($item['owner-thumb'], false, PROXY_SIZE_THUMB)),
+                       'owner_name'      => htmlentities($owner_name_e),
+                       'plink'           => get_plink($item),
+                       'edpost'          => ((Feature::isEnabled($conv->getProfileOwner(), 'edit_posts')) ? $edpost : ''),
+                       'isstarred'       => $isstarred,
+                       'star'            => ((Feature::isEnabled($conv->getProfileOwner(), 'star_posts')) ? $star : ''),
+                       'ignore'          => ((Feature::isEnabled($conv->getProfileOwner(), 'ignore_posts')) ? $ignore : ''),
+                       'tagger'          => $tagger,
+                       'filer'           => ((Feature::isEnabled($conv->getProfileOwner(), 'filing')) ? $filer : ''),
+                       'drop'            => $drop,
+                       'vote'            => $buttons,
+                       'like'            => $responses['like']['output'],
+                       'dislike'         => $responses['dislike']['output'],
+                       'responses'       => $responses,
+                       'switchcomment'   => t('Comment'),
+                       'comment'         => $comment,
+                       'previewing'      => ($conv->isPreview() ? ' preview ' : ''),
+                       'wait'            => t('Please wait'),
+                       'thread_level'    => $thread_level,
+                       'edited'          => $edited,
+                       'network'         => $item["item_network"],
+                       'network_name'    => network_to_name($item['item_network'], $profile_link),
+                       'received'        => $item['received'],
+                       'commented'       => $item['commented'],
+                       'created_date'    => $item['created'],
+               );
+
+               $arr = array('item' => $item, 'output' => $tmp_item);
+               call_hooks('display_item', $arr);
+
+               $result = $arr['output'];
+
+               $result['children'] = array();
+               $children = $this->getChildren();
+               $nb_children = count($children);
+               if ($nb_children > 0) {
+                       foreach ($children as $child) {
+                               $result['children'][] = $child->getTemplateData($conv_responses, $thread_level + 1);
+                       }
+                       // Collapse
+                       if (($nb_children > 2) || ($thread_level > 1)) {
+                               $result['children'][0]['comment_firstcollapsed'] = true;
+                               $result['children'][0]['num_comments'] = sprintf(tt('%d comment', '%d comments', $total_children), $total_children);
+                               $result['children'][0]['hidden_comments_num'] = $total_children;
+                               $result['children'][0]['hidden_comments_text'] = tt('comment', 'comments', $total_children);
+                               $result['children'][0]['hide_text'] = t('show more');
+                               if ($thread_level > 1) {
+                                       $result['children'][$nb_children - 1]['comment_lastcollapsed'] = true;
+                               } else {
+                                       $result['children'][$nb_children - 3]['comment_lastcollapsed'] = true;
+                               }
+                       }
+               }
+
+               if ($this->isToplevel()) {
+                       $result['total_comments_num'] = "$total_children";
+                       $result['total_comments_text'] = tt('comment', 'comments', $total_children);
+               }
+
+               $result['private'] = $item['private'];
+               $result['toplevel'] = ($this->isToplevel() ? 'toplevel_item' : '');
+
+               if ($this->isThreaded()) {
+                       $result['flatten'] = false;
+                       $result['threaded'] = true;
+               } else {
+                       $result['flatten'] = true;
+                       $result['threaded'] = false;
+               }
+
+               return $result;
+       }
+
+       /**
+        * @return integer
+        */
+       public function getId()
+       {
+               return $this->getDataValue('id');
+       }
+
+       /**
+        * @return boolean
+        */
+       public function isThreaded()
+       {
+               return $this->threaded;
+       }
+
+       /**
+        * Add a child item
+        *
+        * @param object $item The child item to add
+        *
+        * @return mixed
+        */
+       public function addChild(Item $item)
+       {
+               $item_id = $item->getId();
+               if (!$item_id) {
+                       logger('[ERROR] Item::addChild : Item has no ID!!', LOGGER_DEBUG);
+                       return false;
+               } elseif ($this->getChild($item->getId())) {
+                       logger('[WARN] Item::addChild : Item already exists ('. $item->getId() .').', LOGGER_DEBUG);
+                       return false;
+               }
+               /*
+                * Only add what will be displayed
+                */
+               if ($item->getDataValue('network') === NETWORK_MAIL && local_user() != $item->getDataValue('uid')) {
+                       return false;
+               } elseif (activity_match($item->getDataValue('verb'), ACTIVITY_LIKE) || activity_match($item->getDataValue('verb'), ACTIVITY_DISLIKE)) {
+                       return false;
+               }
+
+               $item->setParent($this);
+               $this->children[] = $item;
+
+               return end($this->children);
+       }
+
+       /**
+        * Get a child by its ID
+        *
+        * @param integer $id The child id
+        *
+        * @return mixed
+        */
+       public function getChild($id)
+       {
+               foreach ($this->getChildren() as $child) {
+                       if ($child->getId() == $id) {
+                               return $child;
+                       }
+               }
+
+               return null;
+       }
+
+       /**
+        * Get all our children
+        *
+        * @return object
+        */
+       public function getChildren()
+       {
+               return $this->children;
+       }
+
+       /**
+        * Set our parent
+        *
+        * @param object $item The item to set as parent
+        *
+        * @return void
+        */
+       protected function setParent($item)
+       {
+               $parent = $this->getParent();
+               if ($parent) {
+                       $parent->removeChild($this);
+               }
+
+               $this->parent = $item;
+               $this->setConversation($item->getConversation());
+       }
+
+       /**
+        * Remove our parent
+        *
+        * @return void
+        */
+       protected function removeParent()
+       {
+               $this->parent = null;
+               $this->conversation = null;
+       }
+
+       /**
+        * Remove a child
+        *
+        * @param object $item The child to be removed
+        *
+        * @return boolean Success or failure
+        */
+       public function removeChild($item)
+       {
+               $id = $item->getId();
+               foreach ($this->getChildren() as $key => $child) {
+                       if ($child->getId() == $id) {
+                               $child->removeParent();
+                               unset($this->children[$key]);
+                               // Reindex the array, in order to make sure there won't be any trouble on loops using count()
+                               $this->children = array_values($this->children);
+                               return true;
+                       }
+               }
+               logger('[WARN] Item::removeChild : Item is not a child ('. $id .').', LOGGER_DEBUG);
+               return false;
+       }
+
+       /**
+        * Get parent item
+        *
+        * @return object
+        */
+       protected function getParent()
+       {
+               return $this->parent;
+       }
+
+       /**
+        * Set conversation
+        *
+        * @param object $conv The conversation
+        *
+        * @return void
+        */
+       public function setConversation($conv)
+       {
+               $previous_mode = ($this->conversation ? $this->conversation->getMode() : '');
+
+               $this->conversation = $conv;
+
+               // Set it on our children too
+               foreach ($this->getChildren() as $child) {
+                       $child->setConversation($conv);
+               }
+       }
+
+       /**
+        * Get conversation
+        *
+        * @return object
+        */
+       public function getConversation()
+       {
+               return $this->conversation;
+       }
+
+       /**
+        * Get raw data
+        *
+        * We shouldn't need this
+        *
+        * @return array
+        */
+       public function getData()
+       {
+               return $this->data;
+       }
+
+       /**
+        * Get a data value
+        *
+        * @param object $name key
+        *
+        * @return mixed value on success
+        *               false on failure
+        */
+       public function getDataValue($name)
+       {
+               if (!isset($this->data[$name])) {
+                       // logger('[ERROR] Item::getDataValue : Item has no value name "'. $name .'".', LOGGER_DEBUG);
+                       return false;
+               }
+
+               return $this->data[$name];
+       }
+
+       /**
+        * Set template
+        *
+        * @param object $name template name
+        *
+        * @return void
+        */
+       private function setTemplate($name)
+       {
+               if (!x($this->available_templates, $name)) {
+                       logger('[ERROR] Item::setTemplate : Template not available ("'. $name .'").', LOGGER_DEBUG);
+                       return false;
+               }
+
+               $this->template = $this->available_templates[$name];
+       }
+
+       /**
+        * Get template
+        *
+        * @return object
+        */
+       private function getTemplate()
+       {
+               return $this->template;
+       }
+
+       /**
+        * Check if this is a toplevel post
+        *
+        * @return boolean
+        */
+       private function isToplevel()
+       {
+               return $this->toplevel;
+       }
+
+       /**
+        * Check if this is writable
+        *
+        * @return boolean
+        */
+       private function isWritable()
+       {
+               $conv = $this->getConversation();
+
+               if ($conv) {
+                       // This will allow us to comment on wall-to-wall items owned by our friends
+                       // and community forums even if somebody else wrote the post.
+
+                       // bug #517 - this fixes for conversation owner
+                       if ($conv->getMode() == 'profile' && $conv->getProfileOwner() == local_user()) {
+                               return true;
+                       }
+
+                       // this fixes for visitors
+                       return ($this->writable || ($this->isVisiting() && $conv->getMode() == 'profile'));
+               }
+               return $this->writable;
+       }
+
+       /**
+        * Count the total of our descendants
+        *
+        * @return integer
+        */
+       private function countDescendants()
+       {
+               $children = $this->getChildren();
+               $total = count($children);
+               if ($total > 0) {
+                       foreach ($children as $child) {
+                               $total += $child->countDescendants();
+                       }
+               }
+
+               return $total;
+       }
+
+       /**
+        * Get the template for the comment box
+        *
+        * @return string
+        */
+       private function getCommentBoxTemplate()
+       {
+               return $this->comment_box_template;
+       }
+
+       /**
+        * Get the comment box
+        *
+        * @param string $indent Indent value
+        *
+        * @return mixed The comment box string (empty if no comment box)
+        *               false on failure
+        */
+       private function getCommentBox($indent)
+       {
+               $a = self::getApp();
+
+               $comment_box = '';
+               $conv = $this->getConversation();
+               $template = get_markup_template($this->getCommentBoxTemplate());
+               $ww = '';
+               if (($conv->getMode() === 'network') && $this->isWallToWall()) {
+                       $ww = 'ww';
+               }
+
+               if ($conv->isWritable() && $this->isWritable()) {
+                       $qc = $qcomment =  null;
+
+                       /*
+                        * Hmmm, code depending on the presence of a particular plugin?
+                        * This should be better if done by a hook
+                        */
+                       if (in_array('qcomment', $a->plugins)) {
+                               $qc = ((local_user()) ? PConfig::get(local_user(), 'qcomment', 'words') : null);
+                               $qcomment = (($qc) ? explode("\n", $qc) : null);
+                       }
+
+                       $comment_box = replace_macros(
+                               $template,
+                               array(
+                               '$return_path' => $a->query_string,
+                               '$threaded'    => $this->isThreaded(),
+                               // '$jsreload'    => (($conv->getMode() === 'display') ? $_SESSION['return_url'] : ''),
+                               '$jsreload'    => '',
+                               '$type'        => (($conv->getMode() === 'profile') ? 'wall-comment' : 'net-comment'),
+                               '$id'          => $this->getId(),
+                               '$parent'      => $this->getId(),
+                               '$qcomment'    => $qcomment,
+                               '$profile_uid' =>  $conv->getProfileOwner(),
+                               '$mylink'      => $a->remove_baseurl($a->contact['url']),
+                               '$mytitle'     => t('This is you'),
+                               '$myphoto'     => $a->remove_baseurl($a->contact['thumb']),
+                               '$comment'     => t('Comment'),
+                               '$submit'      => t('Submit'),
+                               '$edbold'      => t('Bold'),
+                               '$editalic'    => t('Italic'),
+                               '$eduline'     => t('Underline'),
+                               '$edquote'     => t('Quote'),
+                               '$edcode'      => t('Code'),
+                               '$edimg'       => t('Image'),
+                               '$edurl'       => t('Link'),
+                               '$edvideo'     => t('Video'),
+                               '$preview'     => ((Feature::isEnabled($conv->getProfileOwner(), 'preview')) ? t('Preview') : ''),
+                               '$indent'      => $indent,
+                               '$sourceapp'   => t($a->sourcename),
+                               '$ww'          => (($conv->getMode() === 'network') ? $ww : ''),
+                               '$rand_num'    => random_digits(12))
+                       );
+               }
+
+               return $comment_box;
+       }
+
+       /**
+        * @return string
+        */
+       private function getRedirectUrl()
+       {
+               return $this->redirect_url;
+       }
+
+       /**
+        * Check if we are a wall to wall item and set the relevant properties
+        *
+        * @return void
+        */
+       protected function checkWallToWall()
+       {
+               $a = self::getApp();
+               $conv = $this->getConversation();
+               $this->wall_to_wall = false;
+
+               if ($this->isToplevel()) {
+                       if ($conv->getMode() !== 'profile') {
+                               if ($this->getDataValue('wall') && !$this->getDataValue('self')) {
+                                       // On the network page, I am the owner. On the display page it will be the profile owner.
+                                       // This will have been stored in $a->page_contact by our calling page.
+                                       // Put this person as the wall owner of the wall-to-wall notice.
+
+                                       $this->owner_url = zrl($a->page_contact['url']);
+                                       $this->owner_photo = $a->page_contact['thumb'];
+                                       $this->owner_name = $a->page_contact['name'];
+                                       $this->wall_to_wall = true;
+                               } elseif ($this->getDataValue('owner-link')) {
+                                       $owner_linkmatch = (($this->getDataValue('owner-link')) && link_compare($this->getDataValue('owner-link'), $this->getDataValue('author-link')));
+                                       $alias_linkmatch = (($this->getDataValue('alias')) && link_compare($this->getDataValue('alias'), $this->getDataValue('author-link')));
+                                       $owner_namematch = (($this->getDataValue('owner-name')) && $this->getDataValue('owner-name') == $this->getDataValue('author-name'));
+
+                                       if ((! $owner_linkmatch) && (! $alias_linkmatch) && (! $owner_namematch)) {
+                                               // The author url doesn't match the owner (typically the contact)
+                                               // and also doesn't match the contact alias.
+                                               // The name match is a hack to catch several weird cases where URLs are
+                                               // all over the park. It can be tricked, but this prevents you from
+                                               // seeing "Bob Smith to Bob Smith via Wall-to-wall" and you know darn
+                                               // well that it's the same Bob Smith.
+
+                                               // But it could be somebody else with the same name. It just isn't highly likely.
+
+
+                                               $this->owner_photo = $this->getDataValue('owner-avatar');
+                                               $this->owner_name = $this->getDataValue('owner-name');
+                                               $this->wall_to_wall = true;
+                                               // If it is our contact, use a friendly redirect link
+                                               if ((link_compare($this->getDataValue('owner-link'), $this->getDataValue('url')))
+                                                       && ($this->getDataValue('network') === NETWORK_DFRN)
+                                               ) {
+                                                       $this->owner_url = $this->getRedirectUrl();
+                                               } else {
+                                                       $this->owner_url = zrl($this->getDataValue('owner-link'));
+                                               }
+                                       }
+                               }
+                       }
+               }
+
+               if (!$this->wall_to_wall) {
+                       $this->setTemplate('wall');
+                       $this->owner_url = '';
+                       $this->owner_photo = '';
+                       $this->owner_name = '';
+               }
+       }
+
+       /**
+        * @return boolean
+        */
+       private function isWallToWall()
+       {
+               return $this->wall_to_wall;
+       }
+
+       /**
+        * @return string
+        */
+       private function getOwnerUrl()
+       {
+               return $this->owner_url;
+       }
+
+       /**
+        * @return string
+        */
+       private function getOwnerPhoto()
+       {
+               return $this->owner_photo;
+       }
+
+       /**
+        * @return string
+        */
+       private function getOwnerName()
+       {
+               return $this->owner_name;
+       }
+
+       /**
+        * @return boolean
+        */
+       private function isVisiting()
+       {
+               return $this->visiting;
+       }
+}
diff --git a/src/Object/Photo.php b/src/Object/Photo.php
new file mode 100644 (file)
index 0000000..a8bb3b4
--- /dev/null
@@ -0,0 +1,1166 @@
+<?php
+/**
+ * @file src/Object/Photo.php
+ * @brief This file contains the Photo class for image processing
+ */
+namespace Friendica\Object;
+
+use Friendica\App;
+use Friendica\Core\Cache;
+use Friendica\Core\Config;
+use Friendica\Core\System;
+use Friendica\Database\DBM;
+use dba;
+use Exception;
+use Imagick;
+use ImagickPixel;
+
+require_once "include/photos.php";
+
+/**
+ * Class to handle Photos
+ */
+class Photo
+{
+       private $image;
+
+       /*
+        * Put back gd stuff, not everybody have Imagick
+        */
+       private $imagick;
+       private $width;
+       private $height;
+       private $valid;
+       private $type;
+       private $types;
+
+       /**
+        * @brief supported mimetypes and corresponding file extensions
+        * @return array
+        */
+       public static function supportedTypes()
+       {
+               if (class_exists('Imagick')) {
+                       // Imagick::queryFormats won't help us a lot there...
+                       // At least, not yet, other parts of friendica uses this array
+                       $t = array(
+                               'image/jpeg' => 'jpg',
+                               'image/png' => 'png',
+                               'image/gif' => 'gif'
+                       );
+               } else {
+                       $t = array();
+                       $t['image/jpeg'] ='jpg';
+                       if (imagetypes() & IMG_PNG) {
+                               $t['image/png'] = 'png';
+                       }
+               }
+
+               return $t;
+       }
+
+       /**
+        * @brief Constructor
+        * @param object  $data data
+        * @param boolean $type optional, default null
+        * @return object
+        */
+       public function __construct($data, $type = null)
+       {
+               $this->imagick = class_exists('Imagick');
+               $this->types = static::supportedTypes();
+               if (!array_key_exists($type, $this->types)) {
+                       $type='image/jpeg';
+               }
+               $this->type = $type;
+
+               if ($this->isImagick() && $this->loadData($data)) {
+                       return true;
+               } else {
+                       // Failed to load with Imagick, fallback
+                       $this->imagick = false;
+               }
+               return $this->loadData($data);
+       }
+
+       /**
+        * @brief Destructor
+        * @return void
+        */
+       public function __destruct()
+       {
+               if ($this->image) {
+                       if ($this->isImagick()) {
+                               $this->image->clear();
+                               $this->image->destroy();
+                               return;
+                       }
+                       if (is_resource($this->image)) {
+                               imagedestroy($this->image);
+                       }
+               }
+       }
+
+       /**
+        * @return boolean
+        */
+       public function isImagick()
+       {
+               return $this->imagick;
+       }
+
+       /**
+        * @brief Maps Mime types to Imagick formats
+        * @return arr With with image formats (mime type as key)
+        */
+       public static function getFormatsMap()
+       {
+               $m = array(
+                       'image/jpeg' => 'JPG',
+                       'image/png' => 'PNG',
+                       'image/gif' => 'GIF'
+               );
+               return $m;
+       }
+
+       /**
+        * @param object $data data
+        * @return boolean
+        */
+       private function loadData($data)
+       {
+               if ($this->isImagick()) {
+                       $this->image = new Imagick();
+                       try {
+                               $this->image->readImageBlob($data);
+                       } catch (Exception $e) {
+                               // Imagick couldn't use the data
+                               return false;
+                       }
+
+                       /*
+                        * Setup the image to the format it will be saved to
+                        */
+                       $map = self::getFormatsMap();
+                       $format = $map[$type];
+                       $this->image->setFormat($format);
+
+                       // Always coalesce, if it is not a multi-frame image it won't hurt anyway
+                       $this->image = $this->image->coalesceImages();
+
+                       /*
+                        * setup the compression here, so we'll do it only once
+                        */
+                       switch ($this->getType()) {
+                               case "image/png":
+                                       $quality = Config::get('system', 'png_quality');
+                                       if ((! $quality) || ($quality > 9)) {
+                                               $quality = PNG_QUALITY;
+                                       }
+                                       /*
+                                        * From http://www.imagemagick.org/script/command-line-options.php#quality:
+                                        *
+                                        * 'For the MNG and PNG image formats, the quality value sets
+                                        * the zlib compression level (quality / 10) and filter-type (quality % 10).
+                                        * The default PNG "quality" is 75, which means compression level 7 with adaptive PNG filtering,
+                                        * unless the image has a color map, in which case it means compression level 7 with no PNG filtering'
+                                        */
+                                       $quality = $quality * 10;
+                                       $this->image->setCompressionQuality($quality);
+                                       break;
+                               case "image/jpeg":
+                                       $quality = Config::get('system', 'jpeg_quality');
+                                       if ((! $quality) || ($quality > 100)) {
+                                               $quality = JPEG_QUALITY;
+                                       }
+                                       $this->image->setCompressionQuality($quality);
+                       }
+
+                       // The 'width' and 'height' properties are only used by non-Imagick routines.
+                       $this->width  = $this->image->getImageWidth();
+                       $this->height = $this->image->getImageHeight();
+                       $this->valid  = true;
+
+                       return true;
+               }
+
+               $this->valid = false;
+               $this->image = @imagecreatefromstring($data);
+               if ($this->image !== false) {
+                       $this->width  = imagesx($this->image);
+                       $this->height = imagesy($this->image);
+                       $this->valid  = true;
+                       imagealphablending($this->image, false);
+                       imagesavealpha($this->image, true);
+
+                       return true;
+               }
+
+               return false;
+       }
+
+       /**
+        * @return boolean
+        */
+       public function isValid()
+       {
+               if ($this->isImagick()) {
+                       return ($this->image !== false);
+               }
+               return $this->valid;
+       }
+
+       /**
+        * @return mixed
+        */
+       public function getWidth()
+       {
+               if (!$this->isValid()) {
+                       return false;
+               }
+
+               if ($this->isImagick()) {
+                       return $this->image->getImageWidth();
+               }
+               return $this->width;
+       }
+
+       /**
+        * @return mixed
+        */
+       public function getHeight()
+       {
+               if (!$this->isValid()) {
+                       return false;
+               }
+
+               if ($this->isImagick()) {
+                       return $this->image->getImageHeight();
+               }
+               return $this->height;
+       }
+
+       /**
+        * @return mixed
+        */
+       public function getImage()
+       {
+               if (!$this->isValid()) {
+                       return false;
+               }
+
+               if ($this->isImagick()) {
+                       /* Clean it */
+                       $this->image = $this->image->deconstructImages();
+                       return $this->image;
+               }
+               return $this->image;
+       }
+
+       /**
+        * @return mixed
+        */
+       public function getType()
+       {
+               if (!$this->isValid()) {
+                       return false;
+               }
+
+               return $this->type;
+       }
+
+       /**
+        * @return mixed
+        */
+       public function getExt()
+       {
+               if (!$this->isValid()) {
+                       return false;
+               }
+
+               return $this->types[$this->getType()];
+       }
+
+       /**
+        * @param integer $max max dimension
+        * @return mixed
+        */
+       public function scaleImage($max)
+       {
+               if (!$this->isValid()) {
+                       return false;
+               }
+
+               $width = $this->getWidth();
+               $height = $this->getHeight();
+
+               $dest_width = $dest_height = 0;
+
+               if ((! $width)|| (! $height)) {
+                       return false;
+               }
+
+               if ($width > $max && $height > $max) {
+                       // very tall image (greater than 16:9)
+                       // constrain the width - let the height float.
+
+                       if ((($height * 9) / 16) > $width) {
+                               $dest_width = $max;
+                               $dest_height = intval(($height * $max) / $width);
+                       } elseif ($width > $height) {
+                               // else constrain both dimensions
+                               $dest_width = $max;
+                               $dest_height = intval(($height * $max) / $width);
+                       } else {
+                               $dest_width = intval(($width * $max) / $height);
+                               $dest_height = $max;
+                       }
+               } else {
+                       if ($width > $max) {
+                               $dest_width = $max;
+                               $dest_height = intval(($height * $max) / $width);
+                       } else {
+                               if ($height > $max) {
+                                       // very tall image (greater than 16:9)
+                                       // but width is OK - don't do anything
+
+                                       if ((($height * 9) / 16) > $width) {
+                                               $dest_width = $width;
+                                               $dest_height = $height;
+                                       } else {
+                                               $dest_width = intval(($width * $max) / $height);
+                                               $dest_height = $max;
+                                       }
+                               } else {
+                                       $dest_width = $width;
+                                       $dest_height = $height;
+                               }
+                       }
+               }
+
+
+               if ($this->isImagick()) {
+                       /*
+                        * If it is not animated, there will be only one iteration here,
+                        * so don't bother checking
+                        */
+                       // Don't forget to go back to the first frame
+                       $this->image->setFirstIterator();
+                       do {
+                               // FIXME - implement horizantal bias for scaling as in followin GD functions
+                               // to allow very tall images to be constrained only horizontally.
+
+                               $this->image->scaleImage($dest_width, $dest_height);
+                       } while ($this->image->nextImage());
+
+                       // These may not be necessary any more
+                       $this->width  = $this->image->getImageWidth();
+                       $this->height = $this->image->getImageHeight();
+
+                       return;
+               }
+
+
+               $dest = imagecreatetruecolor($dest_width, $dest_height);
+               imagealphablending($dest, false);
+               imagesavealpha($dest, true);
+               if ($this->type=='image/png') {
+                       imagefill($dest, 0, 0, imagecolorallocatealpha($dest, 0, 0, 0, 127)); // fill with alpha
+               }
+               imagecopyresampled($dest, $this->image, 0, 0, 0, 0, $dest_width, $dest_height, $width, $height);
+               if ($this->image) {
+                       imagedestroy($this->image);
+               }
+               $this->image = $dest;
+               $this->width  = imagesx($this->image);
+               $this->height = imagesy($this->image);
+       }
+
+       /**
+        * @param integer $degrees degrees to rotate image
+        * @return mixed
+        */
+       public function rotate($degrees)
+       {
+               if (!$this->isValid()) {
+                       return false;
+               }
+
+               if ($this->isImagick()) {
+                       $this->image->setFirstIterator();
+                       do {
+                               $this->image->rotateImage(new ImagickPixel(), -$degrees); // ImageMagick rotates in the opposite direction of imagerotate()
+                       } while ($this->image->nextImage());
+                       return;
+               }
+
+               // if script dies at this point check memory_limit setting in php.ini
+               $this->image  = imagerotate($this->image, $degrees, 0);
+               $this->width  = imagesx($this->image);
+               $this->height = imagesy($this->image);
+       }
+
+       /**
+        * @param boolean $horiz optional, default true
+        * @param boolean $vert  optional, default false
+        * @return mixed
+        */
+       public function flip($horiz = true, $vert = false)
+       {
+               if (!$this->isValid()) {
+                       return false;
+               }
+
+               if ($this->isImagick()) {
+                       $this->image->setFirstIterator();
+                       do {
+                               if ($horiz) {
+                                       $this->image->flipImage();
+                               }
+                               if ($vert) {
+                                       $this->image->flopImage();
+                               }
+                       } while ($this->image->nextImage());
+                       return;
+               }
+
+               $w = imagesx($this->image);
+               $h = imagesy($this->image);
+               $flipped = imagecreate($w, $h);
+               if ($horiz) {
+                       for ($x = 0; $x < $w; $x++) {
+                               imagecopy($flipped, $this->image, $x, 0, $w - $x - 1, 0, 1, $h);
+                       }
+               }
+               if ($vert) {
+                       for ($y = 0; $y < $h; $y++) {
+                               imagecopy($flipped, $this->image, 0, $y, 0, $h - $y - 1, $w, 1);
+                       }
+               }
+               $this->image = $flipped;
+       }
+
+       /**
+        * @param string $filename filename
+        * @return mixed
+        */
+       public function orient($filename)
+       {
+               if ($this->isImagick()) {
+                       // based off comment on http://php.net/manual/en/imagick.getimageorientation.php
+                       $orientation = $this->image->getImageOrientation();
+                       switch ($orientation) {
+                               case Imagick::ORIENTATION_BOTTOMRIGHT:
+                                       $this->image->rotateimage("#000", 180);
+                                       break;
+                               case Imagick::ORIENTATION_RIGHTTOP:
+                                       $this->image->rotateimage("#000", 90);
+                                       break;
+                               case Imagick::ORIENTATION_LEFTBOTTOM:
+                                       $this->image->rotateimage("#000", -90);
+                                       break;
+                       }
+
+                       $this->image->setImageOrientation(Imagick::ORIENTATION_TOPLEFT);
+                       return true;
+               }
+               // based off comment on http://php.net/manual/en/function.imagerotate.php
+
+               if (!$this->isValid()) {
+                       return false;
+               }
+
+               if ((!function_exists('exif_read_data')) || ($this->getType() !== 'image/jpeg')) {
+                       return;
+               }
+
+               $exif = @exif_read_data($filename, null, true);
+               if (!$exif) {
+                       return;
+               }
+
+               $ort = $exif['IFD0']['Orientation'];
+
+               switch ($ort) {
+                       case 1: // nothing
+                               break;
+
+                       case 2: // horizontal flip
+                               $this->flip();
+                               break;
+
+                       case 3: // 180 rotate left
+                               $this->rotate(180);
+                               break;
+
+                       case 4: // vertical flip
+                               $this->flip(false, true);
+                               break;
+
+                       case 5: // vertical flip + 90 rotate right
+                               $this->flip(false, true);
+                               $this->rotate(-90);
+                               break;
+
+                       case 6: // 90 rotate right
+                               $this->rotate(-90);
+                               break;
+
+                       case 7: // horizontal flip + 90 rotate right
+                               $this->flip();
+                               $this->rotate(-90);
+                               break;
+
+                       case 8: // 90 rotate left
+                               $this->rotate(90);
+                               break;
+               }
+
+               //      logger('exif: ' . print_r($exif,true));
+               return $exif;
+       }
+
+       /**
+        * @param integer $min minimum dimension
+        * @return mixed
+        */
+       public function scaleImageUp($min)
+       {
+               if (!$this->isValid()) {
+                       return false;
+               }
+
+               $width = $this->getWidth();
+               $height = $this->getHeight();
+
+               $dest_width = $dest_height = 0;
+
+               if ((!$width)|| (!$height)) {
+                       return false;
+               }
+
+               if ($width < $min && $height < $min) {
+                       if ($width > $height) {
+                               $dest_width = $min;
+                               $dest_height = intval(($height * $min) / $width);
+                       } else {
+                               $dest_width = intval(($width * $min) / $height);
+                               $dest_height = $min;
+                       }
+               } else {
+                       if ($width < $min) {
+                               $dest_width = $min;
+                               $dest_height = intval(($height * $min) / $width);
+                       } else {
+                               if ($height < $min) {
+                                       $dest_width = intval(($width * $min) / $height);
+                                       $dest_height = $min;
+                               } else {
+                                       $dest_width = $width;
+                                       $dest_height = $height;
+                               }
+                       }
+               }
+
+               if ($this->isImagick()) {
+                       return $this->scaleImage($dest_width, $dest_height);
+               }
+
+               $dest = imagecreatetruecolor($dest_width, $dest_height);
+               imagealphablending($dest, false);
+               imagesavealpha($dest, true);
+               if ($this->type=='image/png') {
+                       imagefill($dest, 0, 0, imagecolorallocatealpha($dest, 0, 0, 0, 127)); // fill with alpha
+               }
+               imagecopyresampled($dest, $this->image, 0, 0, 0, 0, $dest_width, $dest_height, $width, $height);
+               if ($this->image) {
+                       imagedestroy($this->image);
+               }
+               $this->image = $dest;
+               $this->width  = imagesx($this->image);
+               $this->height = imagesy($this->image);
+       }
+
+       /**
+        * @param integer $dim dimension
+        * @return mixed
+        */
+       public function scaleImageSquare($dim)
+       {
+               if (!$this->isValid()) {
+                       return false;
+               }
+
+               if ($this->isImagick()) {
+                       $this->image->setFirstIterator();
+                       do {
+                               $this->image->scaleImage($dim, $dim);
+                       } while ($this->image->nextImage());
+                       return;
+               }
+
+               $dest = imagecreatetruecolor($dim, $dim);
+               imagealphablending($dest, false);
+               imagesavealpha($dest, true);
+               if ($this->type=='image/png') {
+                       imagefill($dest, 0, 0, imagecolorallocatealpha($dest, 0, 0, 0, 127)); // fill with alpha
+               }
+               imagecopyresampled($dest, $this->image, 0, 0, 0, 0, $dim, $dim, $this->width, $this->height);
+               if ($this->image) {
+                       imagedestroy($this->image);
+               }
+               $this->image = $dest;
+               $this->width  = imagesx($this->image);
+               $this->height = imagesy($this->image);
+       }
+
+       /**
+        * @param integer $max maximum
+        * @param integer $x   x coordinate
+        * @param integer $y   y coordinate
+        * @param integer $w   width
+        * @param integer $h   height
+        * @return mixed
+        */
+       public function cropImage($max, $x, $y, $w, $h)
+       {
+               if (!$this->isValid()) {
+                       return false;
+               }
+
+               if ($this->isImagick()) {
+                       $this->image->setFirstIterator();
+                       do {
+                               $this->image->cropImage($w, $h, $x, $y);
+                               /*
+                                * We need to remove the canva,
+                                * or the image is not resized to the crop:
+                                * http://php.net/manual/en/imagick.cropimage.php#97232
+                                */
+                               $this->image->setImagePage(0, 0, 0, 0);
+                       } while ($this->image->nextImage());
+                       return $this->scaleImage($max);
+               }
+
+               $dest = imagecreatetruecolor($max, $max);
+               imagealphablending($dest, false);
+               imagesavealpha($dest, true);
+               if ($this->type=='image/png') {
+                       imagefill($dest, 0, 0, imagecolorallocatealpha($dest, 0, 0, 0, 127)); // fill with alpha
+               }
+               imagecopyresampled($dest, $this->image, 0, 0, $x, $y, $max, $max, $w, $h);
+               if ($this->image) {
+                       imagedestroy($this->image);
+               }
+               $this->image = $dest;
+               $this->width  = imagesx($this->image);
+               $this->height = imagesy($this->image);
+       }
+
+       /**
+        * @param string $path file path
+        * @return mixed
+        */
+       public function saveImage($path)
+       {
+               if (!$this->isValid()) {
+                       return false;
+               }
+
+               $string = $this->imageString();
+
+               $a = get_app();
+
+               $stamp1 = microtime(true);
+               file_put_contents($path, $string);
+               $a->save_timestamp($stamp1, "file");
+       }
+
+       /**
+        * @return mixed
+        */
+       public function imageString()
+       {
+               if (!$this->isValid()) {
+                       return false;
+               }
+
+               if ($this->isImagick()) {
+                       /* Clean it */
+                       $this->image = $this->image->deconstructImages();
+                       $string = $this->image->getImagesBlob();
+                       return $string;
+               }
+
+               $quality = false;
+
+               ob_start();
+
+               // Enable interlacing
+               imageinterlace($this->image, true);
+
+               switch ($this->getType()) {
+                       case "image/png":
+                               $quality = Config::get('system', 'png_quality');
+                               if ((!$quality) || ($quality > 9)) {
+                                       $quality = PNG_QUALITY;
+                               }
+                               imagepng($this->image, null, $quality);
+                               break;
+                       case "image/jpeg":
+                               $quality = Config::get('system', 'jpeg_quality');
+                               if ((!$quality) || ($quality > 100)) {
+                                       $quality = JPEG_QUALITY;
+                               }
+                               imagejpeg($this->image, null, $quality);
+               }
+               $string = ob_get_contents();
+               ob_end_clean();
+
+               return $string;
+       }
+
+       /**
+        * @param integer $uid       uid
+        * @param integer $cid       cid
+        * @param integer $rid       rid
+        * @param string  $filename  filename
+        * @param string  $album     album name
+        * @param integer $scale     scale
+        * @param integer $profile   optional, default = 0
+        * @param string  $allow_cid optional, default = ''
+        * @param string  $allow_gid optional, default = ''
+        * @param string  $deny_cid  optional, default = ''
+        * @param string  $deny_gid  optional, default = ''
+        * @param string  $desc      optional, default = ''
+        * @return object
+        */
+       public function store($uid, $cid, $rid, $filename, $album, $scale, $profile = 0, $allow_cid = '', $allow_gid = '', $deny_cid = '', $deny_gid = '', $desc = '')
+       {
+               $r = dba::select('photo', array('guid'), array("`resource-id` = ? AND `guid` != ?", $rid, ''), array('limit' => 1));
+               if (DBM::is_result($r)) {
+                       $guid = $r['guid'];
+               } else {
+                       $guid = get_guid();
+               }
+
+               $x = dba::select('photo', array('id'), array('resource-id' => $rid, 'uid' => $uid, 'contact-id' => $cid, 'scale' => $scale), array('limit' => 1));
+
+               $fields = array('uid' => $uid, 'contact-id' => $cid, 'guid' => $guid, 'resource-id' => $rid, 'created' => datetime_convert(), 'edited' => datetime_convert(),
+                               'filename' => basename($filename), 'type' => $this->getType(), 'album' => $album, 'height' => $this->getHeight(), 'width' => $this->getWidth(),
+                               'datasize' => strlen($this->imageString()), 'data' => $this->imageString(), 'scale' => $scale, 'profile' => $profile,
+                               'allow_cid' => $allow_cid, 'allow_gid' => $allow_gid, 'deny_cid' => $deny_cid, 'deny_gid' => $deny_gid, 'desc' => $desc);
+
+               if (DBM::is_result($x)) {
+                       $r = dba::update('photo', $fields, array('id' => $x['id']));
+               } else {
+                       $r = dba::insert('photo', $fields);
+               }
+
+               return $r;
+       }
+
+       /**
+        * Guess image mimetype from filename or from Content-Type header
+        *
+        * @param string  $filename Image filename
+        * @param boolean $fromcurl Check Content-Type header from curl request
+        *
+        * @return object
+        */
+       public static function guessImageType($filename, $fromcurl = false)
+       {
+               logger('Photo: guessImageType: '.$filename . ($fromcurl?' from curl headers':''), LOGGER_DEBUG);
+               $type = null;
+               if ($fromcurl) {
+                       $a = get_app();
+                       $headers=array();
+                       $h = explode("\n", $a->get_curl_headers());
+                       foreach ($h as $l) {
+                               list($k,$v) = array_map("trim", explode(":", trim($l), 2));
+                               $headers[$k] = $v;
+                       }
+                       if (array_key_exists('Content-Type', $headers))
+                               $type = $headers['Content-Type'];
+               }
+               if (is_null($type)) {
+                       // Guessing from extension? Isn't that... dangerous?
+                       if (class_exists('Imagick') && file_exists($filename) && is_readable($filename)) {
+                               /**
+                                * Well, this not much better,
+                                * but at least it comes from the data inside the image,
+                                * we won't be tricked by a manipulated extension
+                                */
+                               $image = new Imagick($filename);
+                               $type = $image->getImageMimeType();
+                               $image->setInterlaceScheme(Imagick::INTERLACE_PLANE);
+                       } else {
+                               $ext = pathinfo($filename, PATHINFO_EXTENSION);
+                               $types = self::supportedTypes();
+                               $type = "image/jpeg";
+                               foreach ($types as $m => $e) {
+                                       if ($ext == $e) {
+                                               $type = $m;
+                                       }
+                               }
+                       }
+               }
+               logger('Photo: guessImageType: type='.$type, LOGGER_DEBUG);
+               return $type;
+       }
+
+       /**
+        * @param string  $photo         photo
+        * @param integer $uid           user id
+        * @param integer $cid           contact id
+        * @param boolean $quit_on_error optional, default false
+        * @return array
+        */
+       public static function importProfilePhoto($photo, $uid, $cid, $quit_on_error = false)
+       {
+               $r = dba::select(
+                       'photo',
+                       array('resource-id'),
+                       array('uid' => $uid, 'contact-id' => $cid, 'scale' => 4, 'album' => 'Contact Photos'),
+                       array('limit' => 1)
+               );
+
+               if (DBM::is_result($r) && strlen($r['resource-id'])) {
+                       $hash = $r['resource-id'];
+               } else {
+                       $hash = photo_new_resource();
+               }
+       
+               $photo_failure = false;
+       
+               $filename = basename($photo);
+               $img_str = fetch_url($photo, true);
+       
+               if ($quit_on_error && ($img_str == "")) {
+                       return false;
+               }
+       
+               $type = self::guessImageType($photo, true);
+               $img = new Photo($img_str, $type);
+               if ($img->isValid()) {
+                       $img->scaleImageSquare(175);
+       
+                       $r = $img->store($uid, $cid, $hash, $filename, 'Contact Photos', 4);
+       
+                       if ($r === false) {
+                               $photo_failure = true;
+                       }
+       
+                       $img->scaleImage(80);
+       
+                       $r = $img->store($uid, $cid, $hash, $filename, 'Contact Photos', 5);
+       
+                       if ($r === false) {
+                               $photo_failure = true;
+                       }
+       
+                       $img->scaleImage(48);
+       
+                       $r = $img->store($uid, $cid, $hash, $filename, 'Contact Photos', 6);
+       
+                       if ($r === false) {
+                               $photo_failure = true;
+                       }
+       
+                       $suffix = '?ts='.time();
+       
+                       $photo = System::baseUrl() . '/photo/' . $hash . '-4.' . $img->getExt() . $suffix;
+                       $thumb = System::baseUrl() . '/photo/' . $hash . '-5.' . $img->getExt() . $suffix;
+                       $micro = System::baseUrl() . '/photo/' . $hash . '-6.' . $img->getExt() . $suffix;
+       
+                       // Remove the cached photo
+                       $a = get_app();
+                       $basepath = $a->get_basepath();
+       
+                       if (is_dir($basepath."/photo")) {
+                               $filename = $basepath.'/photo/'.$hash.'-4.'.$img->getExt();
+                               if (file_exists($filename)) {
+                                       unlink($filename);
+                               }
+                               $filename = $basepath.'/photo/'.$hash.'-5.'.$img->getExt();
+                               if (file_exists($filename)) {
+                                       unlink($filename);
+                               }
+                               $filename = $basepath.'/photo/'.$hash.'-6.'.$img->getExt();
+                               if (file_exists($filename)) {
+                                       unlink($filename);
+                               }
+                       }
+               } else {
+                       $photo_failure = true;
+               }
+       
+               if ($photo_failure && $quit_on_error) {
+                       return false;
+               }
+       
+               if ($photo_failure) {
+                       $photo = System::baseUrl() . '/images/person-175.jpg';
+                       $thumb = System::baseUrl() . '/images/person-80.jpg';
+                       $micro = System::baseUrl() . '/images/person-48.jpg';
+               }
+       
+               return array($photo, $thumb, $micro);
+       }
+
+       /**
+        * @param string $url url
+        * @return object
+        */
+       public static function getInfoFromURL($url)
+       {
+               $data = array();
+       
+               $data = Cache::get($url);
+       
+               if (is_null($data) || !$data || !is_array($data)) {
+                       $img_str = fetch_url($url, true, $redirects, 4);
+                       $filesize = strlen($img_str);
+       
+                       if (function_exists("getimagesizefromstring")) {
+                               $data = getimagesizefromstring($img_str);
+                       } else {
+                               $tempfile = tempnam(get_temppath(), "cache");
+       
+                               $a = get_app();
+                               $stamp1 = microtime(true);
+                               file_put_contents($tempfile, $img_str);
+                               $a->save_timestamp($stamp1, "file");
+       
+                               $data = getimagesize($tempfile);
+                               unlink($tempfile);
+                       }
+       
+                       if ($data) {
+                               $data["size"] = $filesize;
+                       }
+       
+                       Cache::set($url, $data);
+               }
+       
+               return $data;
+       }
+
+       /**
+        * @param integer $width  width
+        * @param integer $height height
+        * @param integer $max    max
+        * @return array
+        */
+       public static function scaleImageTo($width, $height, $max)
+       {
+               $dest_width = $dest_height = 0;
+       
+               if ((!$width) || (!$height)) {
+                       return false;
+               }
+       
+               if ($width > $max && $height > $max) {
+                       // very tall image (greater than 16:9)
+                       // constrain the width - let the height float.
+       
+                       if ((($height * 9) / 16) > $width) {
+                               $dest_width = $max;
+                               $dest_height = intval(($height * $max) / $width);
+                       } elseif ($width > $height) {
+                               // else constrain both dimensions
+                               $dest_width = $max;
+                               $dest_height = intval(($height * $max) / $width);
+                       } else {
+                               $dest_width = intval(($width * $max) / $height);
+                               $dest_height = $max;
+                       }
+               } else {
+                       if ($width > $max) {
+                               $dest_width = $max;
+                               $dest_height = intval(($height * $max) / $width);
+                       } else {
+                               if ($height > $max) {
+                                       // very tall image (greater than 16:9)
+                                       // but width is OK - don't do anything
+       
+                                       if ((($height * 9) / 16) > $width) {
+                                               $dest_width = $width;
+                                               $dest_height = $height;
+                                       } else {
+                                               $dest_width = intval(($width * $max) / $height);
+                                               $dest_height = $max;
+                                       }
+                               } else {
+                                       $dest_width = $width;
+                                       $dest_height = $height;
+                               }
+                       }
+               }
+               return array("width" => $dest_width, "height" => $dest_height);
+       }
+
+       /**
+        * @brief This function is used by the fromgplus addon
+        * @param object  $a         App
+        * @param integer $uid       user id
+        * @param string  $imagedata optional, default empty
+        * @param string  $url       optional, default empty
+        * @return array
+        */
+       public static function storePhoto(App $a, $uid, $imagedata = "", $url = "")
+       {
+               $r = q(
+                       "SELECT `user`.`nickname`, `user`.`page-flags`, `contact`.`id` FROM `user` INNER JOIN `contact` on `user`.`uid` = `contact`.`uid`
+                       WHERE `user`.`uid` = %d AND `user`.`blocked` = 0 AND `contact`.`self` = 1 LIMIT 1",
+                       intval($uid)
+               );
+       
+               if (!DBM::is_result($r)) {
+                       logger("Can't detect user data for uid ".$uid, LOGGER_DEBUG);
+                       return(array());
+               }
+       
+               $page_owner_nick  = $r[0]['nickname'];
+       
+               /// @TODO
+               /// $default_cid      = $r[0]['id'];
+               /// $community_page   = (($r[0]['page-flags'] == PAGE_COMMUNITY) ? true : false);
+       
+               if ((strlen($imagedata) == 0) && ($url == "")) {
+                       logger("No image data and no url provided", LOGGER_DEBUG);
+                       return(array());
+               } elseif (strlen($imagedata) == 0) {
+                       logger("Uploading picture from ".$url, LOGGER_DEBUG);
+       
+                       $stamp1 = microtime(true);
+                       $imagedata = @file_get_contents($url);
+                       $a->save_timestamp($stamp1, "file");
+               }
+       
+               $maximagesize = Config::get('system', 'maximagesize');
+       
+               if (($maximagesize) && (strlen($imagedata) > $maximagesize)) {
+                       logger("Image exceeds size limit of ".$maximagesize, LOGGER_DEBUG);
+                       return(array());
+               }
+       
+               $tempfile = tempnam(get_temppath(), "cache");
+       
+               $stamp1 = microtime(true);
+               file_put_contents($tempfile, $imagedata);
+               $a->save_timestamp($stamp1, "file");
+       
+               $data = getimagesize($tempfile);
+       
+               if (!isset($data["mime"])) {
+                       unlink($tempfile);
+                       logger("File is no picture", LOGGER_DEBUG);
+                       return(array());
+               }
+       
+               $ph = new Photo($imagedata, $data["mime"]);
+       
+               if (!$ph->isValid()) {
+                       unlink($tempfile);
+                       logger("Picture is no valid picture", LOGGER_DEBUG);
+                       return(array());
+               }
+       
+               $ph->orient($tempfile);
+               unlink($tempfile);
+       
+               $max_length = Config::get('system', 'max_image_length');
+               if (! $max_length) {
+                       $max_length = MAX_IMAGE_LENGTH;
+               }
+
+               if ($max_length > 0) {
+                       $ph->scaleImage($max_length);
+               }
+       
+               $width = $ph->getWidth();
+               $height = $ph->getHeight();
+       
+               $hash = photo_new_resource();
+       
+               $smallest = 0;
+       
+               // Pictures are always public by now
+               //$defperm = '<'.$default_cid.'>';
+               $defperm = "";
+               $visitor = 0;
+       
+               $r = $ph->store($uid, $visitor, $hash, $tempfile, t('Wall Photos'), 0, 0, $defperm);
+       
+               if (!$r) {
+                       logger("Picture couldn't be stored", LOGGER_DEBUG);
+                       return(array());
+               }
+       
+               $image = array("page" => System::baseUrl().'/photos/'.$page_owner_nick.'/image/'.$hash,
+                       "full" => System::baseUrl()."/photo/{$hash}-0.".$ph->getExt());
+       
+               if ($width > 800 || $height > 800) {
+                       $image["large"] = System::baseUrl()."/photo/{$hash}-0.".$ph->getExt();
+               }
+       
+               if ($width > 640 || $height > 640) {
+                       $ph->scaleImage(640);
+                       $r = $ph->store($uid, $visitor, $hash, $tempfile, t('Wall Photos'), 1, 0, $defperm);
+                       if ($r) {
+                               $image["medium"] = System::baseUrl()."/photo/{$hash}-1.".$ph->getExt();
+                       }
+               }
+       
+               if ($width > 320 || $height > 320) {
+                       $ph->scaleImage(320);
+                       $r = $ph->store($uid, $visitor, $hash, $tempfile, t('Wall Photos'), 2, 0, $defperm);
+                       if ($r) {
+                               $image["small"] = System::baseUrl()."/photo/{$hash}-2.".$ph->getExt();
+                       }
+               }
+       
+               if ($width > 160 && $height > 160) {
+                       $x = 0;
+                       $y = 0;
+               
+                       $min = $ph->getWidth();
+                       if ($min > 160) {
+                               $x = ($min - 160) / 2;
+                       }
+               
+                       if ($ph->getHeight() < $min) {
+                               $min = $ph->getHeight();
+                               if ($min > 160) {
+                                       $y = ($min - 160) / 2;
+                               }
+                       }
+       
+                       $min = 160;
+                       $ph->cropImage(160, $x, $y, $min, $min);
+               
+                       $r = $ph->store($uid, $visitor, $hash, $tempfile, t('Wall Photos'), 3, 0, $defperm);
+                       if ($r) {
+                               $image["thumb"] = System::baseUrl()."/photo/{$hash}-3.".$ph->getExt();
+                       }
+               }
+       
+               // Set the full image as preview image. This will be overwritten, if the picture is larger than 640.
+               $image["preview"] = $image["full"];
+       
+               // Deactivated, since that would result in a cropped preview, if the picture wasn't larger than 320
+               //if (isset($image["thumb"]))
+               //  $image["preview"] = $image["thumb"];
+       
+               // Unsure, if this should be activated or deactivated
+               //if (isset($image["small"]))
+               //  $image["preview"] = $image["small"];
+       
+               if (isset($image["medium"])) {
+                       $image["preview"] = $image["medium"];
+               }
+       
+               return($image);
+       }
+}
diff --git a/src/Object/Post.php b/src/Object/Post.php
deleted file mode 100644 (file)
index 231f2a5..0000000
+++ /dev/null
@@ -1,906 +0,0 @@
-<?php
-/**
- * @file src/Object/Post.php
- */
-namespace Friendica\Object;
-
-use Friendica\BaseObject;
-use Friendica\Content\Feature;
-use Friendica\Core\PConfig;
-use Friendica\Database\DBM;
-use Friendica\Model\Contact;
-use dba;
-
-require_once 'include/text.php';
-require_once 'boot.php';
-require_once 'include/conversation.php';
-
-/**
- * An item
- */
-class Post extends BaseObject
-{
-       private $data = array();
-       private $template = null;
-       private $available_templates = array(
-               'wall' => 'wall_thread.tpl',
-               'wall2wall' => 'wallwall_thread.tpl'
-       );
-       private $comment_box_template = 'comment_item.tpl';
-       private $toplevel = false;
-       private $writable = false;
-       private $children = array();
-       private $parent = null;
-       private $thread = null;
-       private $redirect_url = null;
-       private $owner_url = '';
-       private $owner_photo = '';
-       private $owner_name = '';
-       private $wall_to_wall = false;
-       private $threaded = false;
-       private $visiting = false;
-
-       /**
-        * Constructor
-        *
-        * @param array $data data array
-        */
-       public function __construct($data)
-       {
-               $a = self::getApp();
-
-               $this->data = $data;
-               $this->setTemplate('wall');
-               $this->toplevel = ($this->getId() == $this->getDataValue('parent'));
-
-               if (is_array($_SESSION['remote'])) {
-                       foreach ($_SESSION['remote'] as $visitor) {
-                               if ($visitor['cid'] == $this->getDataValue('contact-id')) {
-                                       $this->visiting = true;
-                                       break;
-                               }
-                       }
-               }
-
-               $this->writable = ($this->getDataValue('writable') || $this->getDataValue('self'));
-
-               $ssl_state = ((local_user()) ? true : false);
-               $this->redirect_url = 'redir/' . $this->getDataValue('cid');
-
-               if (!$this->isToplevel()) {
-                       $this->threaded = true;
-               }
-
-               // Prepare the children
-               if (count($data['children'])) {
-                       foreach ($data['children'] as $item) {
-                               /*
-                                * Only add will be displayed
-                                */
-                               if ($item['network'] === NETWORK_MAIL && local_user() != $item['uid']) {
-                                       continue;
-                               } elseif (! visible_activity($item)) {
-                                       continue;
-                               }
-
-                               // You can always comment on Diaspora items
-                               if (($item['network'] == NETWORK_DIASPORA) && (local_user() == $item['uid'])) {
-                                       $item['writable'] = true;
-                               }
-
-                               $item['pagedrop'] = $data['pagedrop'];
-                               $child = new Item($item);
-                               $this->addChild($child);
-                       }
-               }
-       }
-
-       /**
-        * Get data in a form usable by a conversation template
-        *
-        * @param object  $conv_responses conversation responses
-        * @param integer $thread_level   default = 1
-        *
-        * @return mixed The data requested on success
-        *               false on failure
-        */
-       public function getTemplateData($conv_responses, $thread_level = 1)
-       {
-               require_once "mod/proxy.php";
-
-               $result = array();
-
-               $a = self::getApp();
-
-               $item = $this->getData();
-               $edited = false;
-               // If the time between "created" and "edited" differs we add
-               // a notice that the post was edited.
-               // Note: In some networks reshared items seem to have (sometimes) a difference
-               // between creation time and edit time of a second. Thats why we add the notice
-               // only if the difference is more than 1 second.
-               if (strtotime($item['edited']) - strtotime($item['created']) > 1) {
-                       $edited = array(
-                               'label'    => t('This entry was edited'),
-                               'date'     => datetime_convert('UTC', date_default_timezone_get(), $item['edited'], 'r'),
-                               'relative' => relative_date($item['edited'])
-                       );
-               }
-               $commentww = '';
-               $sparkle = '';
-               $buttons = '';
-               $dropping = false;
-               $star = false;
-               $ignore = false;
-               $isstarred = "unstarred";
-               $indent = '';
-               $shiny = '';
-               $osparkle = '';
-               $total_children = $this->countDescendants();
-
-               $conv = $this->getThread();
-
-               $lock = ((($item['private'] == 1) || (($item['uid'] == local_user()) && (strlen($item['allow_cid']) || strlen($item['allow_gid'])
-                       || strlen($item['deny_cid']) || strlen($item['deny_gid']))))
-                       ? t('Private Message')
-                       : false);
-               $shareable = ((($conv->getProfileOwner() == local_user()) && ($item['private'] != 1)) ? true : false);
-               if (local_user() && link_compare($a->contact['url'], $item['author-link'])) {
-                       if ($item["event-id"] != 0) {
-                               $edpost = array("events/event/".$item['event-id'], t("Edit"));
-                       } else {
-                               $edpost = array("editpost/".$item['id'], t("Edit"));
-                       }
-               } else {
-                       $edpost = false;
-               }
-
-               if (($this->getDataValue('uid') == local_user()) || $this->isVisiting()) {
-                       $dropping = true;
-               }
-
-               $drop = array(
-                       'dropping' => $dropping,
-                       'pagedrop' => ((Feature::isEnabled($conv->getProfileOwner(), 'multi_delete')) ? $item['pagedrop'] : ''),
-                       'select'   => t('Select'),
-                       'delete'   => t('Delete'),
-               );
-
-               $filer = (($conv->getProfileOwner() == local_user()) ? t("save to folder") : false);
-
-               $diff_author    = ((link_compare($item['url'], $item['author-link'])) ? false : true);
-               $profile_name   = htmlentities(((strlen($item['author-name'])) && $diff_author) ? $item['author-name'] : $item['name']);
-               if ($item['author-link'] && (! $item['author-name'])) {
-                       $profile_name = $item['author-link'];
-               }
-
-               $sp = false;
-               $profile_link = best_link_url($item, $sp);
-               if ($profile_link === 'mailbox') {
-                       $profile_link = '';
-               }
-
-               if ($sp) {
-                       $sparkle = ' sparkle';
-               } else {
-                       $profile_link = zrl($profile_link);
-               }
-
-               if (!isset($item['author-thumb']) || ($item['author-thumb'] == "")) {
-                       $author_contact = Contact::getDetailsByURL($item['author-link'], $conv->getProfileOwner());
-                       if ($author_contact["thumb"]) {
-                               $item['author-thumb'] = $author_contact["thumb"];
-                       } else {
-                               $item['author-thumb'] = $item['author-avatar'];
-                       }
-               }
-
-               if (!isset($item['owner-thumb']) || ($item['owner-thumb'] == "")) {
-                       $owner_contact = Contact::getDetailsByURL($item['owner-link'], $conv->getProfileOwner());
-                       if ($owner_contact["thumb"]) {
-                               $item['owner-thumb'] = $owner_contact["thumb"];
-                       } else {
-                               $item['owner-thumb'] = $item['owner-avatar'];
-                       }
-               }
-
-               $locate = array('location' => $item['location'], 'coord' => $item['coord'], 'html' => '');
-               call_hooks('render_location', $locate);
-               $location = ((strlen($locate['html'])) ? $locate['html'] : render_location_dummy($locate));
-
-               $tags=array();
-               $hashtags = array();
-               $mentions = array();
-
-               /*foreach(explode(',',$item['tag']) as $tag){
-                       $tag = trim($tag);
-                       if ($tag!="") {
-                               $t = bbcode($tag);
-                               $tags[] = $t;
-                               if($t[0] == '#')
-                                       $hashtags[] = $t;
-                               elseif($t[0] == '@')
-                                       $mentions[] = $t;
-                       }
-               }*/
-
-               // process action responses - e.g. like/dislike/attend/agree/whatever
-               $response_verbs = array('like', 'dislike');
-
-               if ($item['object-type'] === ACTIVITY_OBJ_EVENT) {
-                       $response_verbs[] = 'attendyes';
-                       $response_verbs[] = 'attendno';
-                       $response_verbs[] = 'attendmaybe';
-                       if ($conv->isWritable()) {
-                               $isevent = true;
-                               $attend = array( t('I will attend'), t('I will not attend'), t('I might attend'));
-                       }
-               }
-
-               $responses = get_responses($conv_responses, $response_verbs, $this, $item);
-
-               foreach ($response_verbs as $value => $verbs) {
-                       $responses[$verbs]['output']  = ((x($conv_responses[$verbs], $item['uri'])) ? format_like($conv_responses[$verbs][$item['uri']], $conv_responses[$verbs][$item['uri'] . '-l'], $verbs, $item['uri']) : '');
-               }
-
-               /*
-                * We should avoid doing this all the time, but it depends on the conversation mode
-                * And the conv mode may change when we change the conv, or it changes its mode
-                * Maybe we should establish a way to be notified about conversation changes
-                */
-               $this->checkWallToWall();
-
-               if ($this->isWallToWall() && ($this->getOwnerUrl() == $this->getRedirectUrl())) {
-                       $osparkle = ' sparkle';
-               }
-
-               if ($this->isToplevel()) {
-                       if ($conv->getProfileOwner() == local_user()) {
-                               $isstarred = (($item['starred']) ? "starred" : "unstarred");
-
-                               $star = array(
-                                       'do'        => t("add star"),
-                                       'undo'      => t("remove star"),
-                                       'toggle'    => t("toggle star status"),
-                                       'classdo'   => (($item['starred']) ? "hidden" : ""),
-                                       'classundo' => (($item['starred']) ? "" : "hidden"),
-                                       'starred'   =>  t('starred'),
-                               );
-                               $r = dba::select('thread', array('ignored'), array('uid' => $item['uid'], 'iid' => $item['id']), array('limit' => 1));
-                               if (DBM::is_result($r)) {
-                                       $ignore = array(
-                                               'do'        => t("ignore thread"),
-                                               'undo'      => t("unignore thread"),
-                                               'toggle'    => t("toggle ignore status"),
-                                               'classdo'   => (($r['ignored']) ? "hidden" : ""),
-                                               'classundo' => (($r['ignored']) ? "" : "hidden"),
-                                               'ignored'   =>  t('ignored'),
-                                       );
-                               }
-
-                               $tagger = '';
-                               if (Feature::isEnabled($conv->getProfileOwner(), 'commtag')) {
-                                       $tagger = array(
-                                               'add'   => t("add tag"),
-                                               'class' => "",
-                                       );
-                               }
-                       }
-               } else {
-                       $indent = 'comment';
-               }
-
-               if ($conv->isWritable()) {
-                       $buttons = array(
-                               'like' => array( t("I like this \x28toggle\x29"), t("like")),
-                               'dislike' => ((Feature::isEnabled($conv->getProfileOwner(), 'dislike')) ? array( t("I don't like this \x28toggle\x29"), t("dislike")) : ''),
-                       );
-                       if ($shareable) {
-                               $buttons['share'] = array( t('Share this'), t('share'));
-                       }
-               }
-
-               $comment = $this->getCommentBox($indent);
-
-               if (strcmp(datetime_convert('UTC', 'UTC', $item['created']), datetime_convert('UTC', 'UTC', 'now - 12 hours')) > 0) {
-                       $shiny = 'shiny';
-               }
-
-               localize_item($item);
-
-               $body = prepare_body($item, true);
-
-               list($categories, $folders) = get_cats_and_terms($item);
-
-               $body_e       = $body;
-               $text_e       = strip_tags($body);
-               $name_e       = $profile_name;
-               $title_e      = $item['title'];
-               $location_e   = $location;
-               $owner_name_e = $this->getOwnerName();
-
-               // Disable features that aren't available in several networks
-
-               /// @todo Add NETWORK_DIASPORA when it will pass this information
-               if (!in_array($item["item_network"], array(NETWORK_DFRN)) && isset($buttons["dislike"])) {
-                       unset($buttons["dislike"], $isevent);
-                       $tagger = '';
-               }
-
-               if (($item["item_network"] == NETWORK_FEED) && isset($buttons["like"])) {
-                       unset($buttons["like"]);
-               }
-
-               if (($item["item_network"] == NETWORK_MAIL) && isset($buttons["like"])) {
-                       unset($buttons["like"]);
-               }
-
-               $tmp_item = array(
-                       'template'        => $this->getTemplate(),
-                       'type'            => implode("", array_slice(explode("/", $item['verb']), -1)),
-                       'tags'            => $item['tags'],
-                       'hashtags'        => $item['hashtags'],
-                       'mentions'        => $item['mentions'],
-                       'txt_cats'        => t('Categories:'),
-                       'txt_folders'     => t('Filed under:'),
-                       'has_cats'        => ((count($categories)) ? 'true' : ''),
-                       'has_folders'     => ((count($folders)) ? 'true' : ''),
-                       'categories'      => $categories,
-                       'folders'         => $folders,
-                       'body'            => $body_e,
-                       'text'            => $text_e,
-                       'id'              => $this->getId(),
-                       'guid'            => urlencode($item['guid']),
-                       'isevent'         => $isevent,
-                       'attend'          => $attend,
-                       'linktitle'       => sprintf(t('View %s\'s profile @ %s'), $profile_name, ((strlen($item['author-link'])) ? $item['author-link'] : $item['url'])),
-                       'olinktitle'      => sprintf(t('View %s\'s profile @ %s'), htmlentities($this->getOwnerName()), ((strlen($item['owner-link'])) ? $item['owner-link'] : $item['url'])),
-                       'to'              => t('to'),
-                       'via'             => t('via'),
-                       'wall'            => t('Wall-to-Wall'),
-                       'vwall'           => t('via Wall-To-Wall:'),
-                       'profile_url'     => $profile_link,
-                       'item_photo_menu' => item_photo_menu($item),
-                       'name'            => $name_e,
-                       'thumb'           => $a->remove_baseurl(proxy_url($item['author-thumb'], false, PROXY_SIZE_THUMB)),
-                       'osparkle'        => $osparkle,
-                       'sparkle'         => $sparkle,
-                       'title'           => $title_e,
-                       'localtime'       => datetime_convert('UTC', date_default_timezone_get(), $item['created'], 'r'),
-                       'ago'             => (($item['app']) ? sprintf(t('%s from %s'), relative_date($item['created']), $item['app']) : relative_date($item['created'])),
-                       'app'             => $item['app'],
-                       'created'         => relative_date($item['created']),
-                       'lock'            => $lock,
-                       'location'        => $location_e,
-                       'indent'          => $indent,
-                       'shiny'           => $shiny,
-                       'owner_url'       => $this->getOwnerUrl(),
-                       'owner_photo'     => $a->remove_baseurl(proxy_url($item['owner-thumb'], false, PROXY_SIZE_THUMB)),
-                       'owner_name'      => htmlentities($owner_name_e),
-                       'plink'           => get_plink($item),
-                       'edpost'          => ((Feature::isEnabled($conv->getProfileOwner(), 'edit_posts')) ? $edpost : ''),
-                       'isstarred'       => $isstarred,
-                       'star'            => ((Feature::isEnabled($conv->getProfileOwner(), 'star_posts')) ? $star : ''),
-                       'ignore'          => ((Feature::isEnabled($conv->getProfileOwner(), 'ignore_posts')) ? $ignore : ''),
-                       'tagger'          => $tagger,
-                       'filer'           => ((Feature::isEnabled($conv->getProfileOwner(), 'filing')) ? $filer : ''),
-                       'drop'            => $drop,
-                       'vote'            => $buttons,
-                       'like'            => $responses['like']['output'],
-                       'dislike'         => $responses['dislike']['output'],
-                       'responses'       => $responses,
-                       'switchcomment'   => t('Comment'),
-                       'comment'         => $comment,
-                       'previewing'      => ($conv->isPreview() ? ' preview ' : ''),
-                       'wait'            => t('Please wait'),
-                       'thread_level'    => $thread_level,
-                       'edited'          => $edited,
-                       'network'         => $item["item_network"],
-                       'network_name'    => network_to_name($item['item_network'], $profile_link),
-                       'received'        => $item['received'],
-                       'commented'       => $item['commented'],
-                       'created_date'    => $item['created'],
-               );
-
-               $arr = array('item' => $item, 'output' => $tmp_item);
-               call_hooks('display_item', $arr);
-
-               $result = $arr['output'];
-
-               $result['children'] = array();
-               $children = $this->getChildren();
-               $nb_children = count($children);
-               if ($nb_children > 0) {
-                       foreach ($children as $child) {
-                               $result['children'][] = $child->getTemplateData($conv_responses, $thread_level + 1);
-                       }
-                       // Collapse
-                       if (($nb_children > 2) || ($thread_level > 1)) {
-                               $result['children'][0]['comment_firstcollapsed'] = true;
-                               $result['children'][0]['num_comments'] = sprintf(tt('%d comment', '%d comments', $total_children), $total_children);
-                               $result['children'][0]['hidden_comments_num'] = $total_children;
-                               $result['children'][0]['hidden_comments_text'] = tt('comment', 'comments', $total_children);
-                               $result['children'][0]['hide_text'] = t('show more');
-                               if ($thread_level > 1) {
-                                       $result['children'][$nb_children - 1]['comment_lastcollapsed'] = true;
-                               } else {
-                                       $result['children'][$nb_children - 3]['comment_lastcollapsed'] = true;
-                               }
-                       }
-               }
-
-               if ($this->isToplevel()) {
-                       $result['total_comments_num'] = "$total_children";
-                       $result['total_comments_text'] = tt('comment', 'comments', $total_children);
-               }
-
-               $result['private'] = $item['private'];
-               $result['toplevel'] = ($this->isToplevel() ? 'toplevel_item' : '');
-
-               if ($this->isThreaded()) {
-                       $result['flatten'] = false;
-                       $result['threaded'] = true;
-               } else {
-                       $result['flatten'] = true;
-                       $result['threaded'] = false;
-               }
-
-               return $result;
-       }
-
-       /**
-        * @return integer
-        */
-       public function getId()
-       {
-               return $this->getDataValue('id');
-       }
-
-       /**
-        * @return boolean
-        */
-       public function isThreaded()
-       {
-               return $this->threaded;
-       }
-
-       /**
-        * Add a child item
-        *
-        * @param object $item The child item to add
-        *
-        * @return mixed
-        */
-       public function addChild(Item $item)
-       {
-               $item_id = $item->getId();
-               if (!$item_id) {
-                       logger('[ERROR] Item::addChild : Item has no ID!!', LOGGER_DEBUG);
-                       return false;
-               } elseif ($this->getChild($item->getId())) {
-                       logger('[WARN] Item::addChild : Item already exists ('. $item->getId() .').', LOGGER_DEBUG);
-                       return false;
-               }
-               /*
-                * Only add what will be displayed
-                */
-               if ($item->getDataValue('network') === NETWORK_MAIL && local_user() != $item->getDataValue('uid')) {
-                       return false;
-               } elseif (activity_match($item->getDataValue('verb'), ACTIVITY_LIKE) || activity_match($item->getDataValue('verb'), ACTIVITY_DISLIKE)) {
-                       return false;
-               }
-
-               $item->setParent($this);
-               $this->children[] = $item;
-
-               return end($this->children);
-       }
-
-       /**
-        * Get a child by its ID
-        *
-        * @param integer $id The child id
-        *
-        * @return mixed
-        */
-       public function getChild($id)
-       {
-               foreach ($this->getChildren() as $child) {
-                       if ($child->getId() == $id) {
-                               return $child;
-                       }
-               }
-
-               return null;
-       }
-
-       /**
-        * Get all our children
-        *
-        * @return object
-        */
-       public function getChildren()
-       {
-               return $this->children;
-       }
-
-       /**
-        * Set our parent
-        *
-        * @param object $item The item to set as parent
-        *
-        * @return void
-        */
-       protected function setParent($item)
-       {
-               $parent = $this->getParent();
-               if ($parent) {
-                       $parent->removeChild($this);
-               }
-
-               $this->parent = $item;
-               $this->setThread($item->getThread());
-       }
-
-       /**
-        * Remove our parent
-        *
-        * @return void
-        */
-       protected function removeParent()
-       {
-               $this->parent = null;
-               $this->thread = null;
-       }
-
-       /**
-        * Remove a child
-        *
-        * @param object $item The child to be removed
-        *
-        * @return boolean Success or failure
-        */
-       public function removeChild($item)
-       {
-               $id = $item->getId();
-               foreach ($this->getChildren() as $key => $child) {
-                       if ($child->getId() == $id) {
-                               $child->removeParent();
-                               unset($this->children[$key]);
-                               // Reindex the array, in order to make sure there won't be any trouble on loops using count()
-                               $this->children = array_values($this->children);
-                               return true;
-                       }
-               }
-               logger('[WARN] Item::removeChild : Item is not a child ('. $id .').', LOGGER_DEBUG);
-               return false;
-       }
-
-       /**
-        * Get parent item
-        *
-        * @return object
-        */
-       protected function getParent()
-       {
-               return $this->parent;
-       }
-
-       /**
-        * Set conversation
-        *
-        * @param object $conv The conversation
-        *
-        * @return void
-        */
-       public function setThread($conv)
-       {
-               $previous_mode = ($this->thread ? $this->thread->getMode() : '');
-
-               $this->thread = $conv;
-
-               // Set it on our children too
-               foreach ($this->getChildren() as $child) {
-                       $child->setThread($conv);
-               }
-       }
-
-       /**
-        * Get conversation
-        *
-        * @return object
-        */
-       public function getThread()
-       {
-               return $this->thread;
-       }
-
-       /**
-        * Get raw data
-        *
-        * We shouldn't need this
-        *
-        * @return array
-        */
-       public function getData()
-       {
-               return $this->data;
-       }
-
-       /**
-        * Get a data value
-        *
-        * @param object $name key
-        *
-        * @return mixed value on success
-        *               false on failure
-        */
-       public function getDataValue($name)
-       {
-               if (!isset($this->data[$name])) {
-                       // logger('[ERROR] Item::getDataValue : Item has no value name "'. $name .'".', LOGGER_DEBUG);
-                       return false;
-               }
-
-               return $this->data[$name];
-       }
-
-       /**
-        * Set template
-        *
-        * @param object $name template name
-        *
-        * @return void
-        */
-       private function setTemplate($name)
-       {
-               if (!x($this->available_templates, $name)) {
-                       logger('[ERROR] Item::setTemplate : Template not available ("'. $name .'").', LOGGER_DEBUG);
-                       return false;
-               }
-
-               $this->template = $this->available_templates[$name];
-       }
-
-       /**
-        * Get template
-        *
-        * @return object
-        */
-       private function getTemplate()
-       {
-               return $this->template;
-       }
-
-       /**
-        * Check if this is a toplevel post
-        *
-        * @return boolean
-        */
-       private function isToplevel()
-       {
-               return $this->toplevel;
-       }
-
-       /**
-        * Check if this is writable
-        *
-        * @return boolean
-        */
-       private function isWritable()
-       {
-               $conv = $this->getThread();
-
-               if ($conv) {
-                       // This will allow us to comment on wall-to-wall items owned by our friends
-                       // and community forums even if somebody else wrote the post.
-
-                       // bug #517 - this fixes for conversation owner
-                       if ($conv->getMode() == 'profile' && $conv->getProfileOwner() == local_user()) {
-                               return true;
-                       }
-
-                       // this fixes for visitors
-                       return ($this->writable || ($this->isVisiting() && $conv->getMode() == 'profile'));
-               }
-               return $this->writable;
-       }
-
-       /**
-        * Count the total of our descendants
-        *
-        * @return integer
-        */
-       private function countDescendants()
-       {
-               $children = $this->getChildren();
-               $total = count($children);
-               if ($total > 0) {
-                       foreach ($children as $child) {
-                               $total += $child->countDescendants();
-                       }
-               }
-
-               return $total;
-       }
-
-       /**
-        * Get the template for the comment box
-        *
-        * @return string
-        */
-       private function getCommentBoxTemplate()
-       {
-               return $this->comment_box_template;
-       }
-
-       /**
-        * Get the comment box
-        *
-        * @param string $indent Indent value
-        *
-        * @return mixed The comment box string (empty if no comment box)
-        *               false on failure
-        */
-       private function getCommentBox($indent)
-       {
-               $a = self::getApp();
-
-               $comment_box = '';
-               $conv = $this->getThread();
-               $template = get_markup_template($this->getCommentBoxTemplate());
-               $ww = '';
-               if (($conv->getMode() === 'network') && $this->isWallToWall()) {
-                       $ww = 'ww';
-               }
-
-               if ($conv->isWritable() && $this->isWritable()) {
-                       $qc = $qcomment =  null;
-
-                       /*
-                        * Hmmm, code depending on the presence of a particular plugin?
-                        * This should be better if done by a hook
-                        */
-                       if (in_array('qcomment', $a->plugins)) {
-                               $qc = ((local_user()) ? PConfig::get(local_user(), 'qcomment', 'words') : null);
-                               $qcomment = (($qc) ? explode("\n", $qc) : null);
-                       }
-
-                       $comment_box = replace_macros(
-                               $template,
-                               array(
-                               '$return_path' => $a->query_string,
-                               '$threaded'    => $this->isThreaded(),
-                               // '$jsreload'    => (($conv->getMode() === 'display') ? $_SESSION['return_url'] : ''),
-                               '$jsreload'    => '',
-                               '$type'        => (($conv->getMode() === 'profile') ? 'wall-comment' : 'net-comment'),
-                               '$id'          => $this->getId(),
-                               '$parent'      => $this->getId(),
-                               '$qcomment'    => $qcomment,
-                               '$profile_uid' =>  $conv->getProfileOwner(),
-                               '$mylink'      => $a->remove_baseurl($a->contact['url']),
-                               '$mytitle'     => t('This is you'),
-                               '$myphoto'     => $a->remove_baseurl($a->contact['thumb']),
-                               '$comment'     => t('Comment'),
-                               '$submit'      => t('Submit'),
-                               '$edbold'      => t('Bold'),
-                               '$editalic'    => t('Italic'),
-                               '$eduline'     => t('Underline'),
-                               '$edquote'     => t('Quote'),
-                               '$edcode'      => t('Code'),
-                               '$edimg'       => t('Image'),
-                               '$edurl'       => t('Link'),
-                               '$edvideo'     => t('Video'),
-                               '$preview'     => ((Feature::isEnabled($conv->getProfileOwner(), 'preview')) ? t('Preview') : ''),
-                               '$indent'      => $indent,
-                               '$sourceapp'   => t($a->sourcename),
-                               '$ww'          => (($conv->getMode() === 'network') ? $ww : ''),
-                               '$rand_num'    => random_digits(12))
-                       );
-               }
-
-               return $comment_box;
-       }
-
-       /**
-        * @return string
-        */
-       private function getRedirectUrl()
-       {
-               return $this->redirect_url;
-       }
-
-       /**
-        * Check if we are a wall to wall item and set the relevant properties
-        *
-        * @return void
-        */
-       protected function checkWallToWall()
-       {
-               $a = self::getApp();
-               $conv = $this->getThread();
-               $this->wall_to_wall = false;
-
-               if ($this->isToplevel()) {
-                       if ($conv->getMode() !== 'profile') {
-                               if ($this->getDataValue('wall') && !$this->getDataValue('self')) {
-                                       // On the network page, I am the owner. On the display page it will be the profile owner.
-                                       // This will have been stored in $a->page_contact by our calling page.
-                                       // Put this person as the wall owner of the wall-to-wall notice.
-
-                                       $this->owner_url = zrl($a->page_contact['url']);
-                                       $this->owner_photo = $a->page_contact['thumb'];
-                                       $this->owner_name = $a->page_contact['name'];
-                                       $this->wall_to_wall = true;
-                               } elseif ($this->getDataValue('owner-link')) {
-                                       $owner_linkmatch = (($this->getDataValue('owner-link')) && link_compare($this->getDataValue('owner-link'), $this->getDataValue('author-link')));
-                                       $alias_linkmatch = (($this->getDataValue('alias')) && link_compare($this->getDataValue('alias'), $this->getDataValue('author-link')));
-                                       $owner_namematch = (($this->getDataValue('owner-name')) && $this->getDataValue('owner-name') == $this->getDataValue('author-name'));
-
-                                       if ((! $owner_linkmatch) && (! $alias_linkmatch) && (! $owner_namematch)) {
-                                               // The author url doesn't match the owner (typically the contact)
-                                               // and also doesn't match the contact alias.
-                                               // The name match is a hack to catch several weird cases where URLs are
-                                               // all over the park. It can be tricked, but this prevents you from
-                                               // seeing "Bob Smith to Bob Smith via Wall-to-wall" and you know darn
-                                               // well that it's the same Bob Smith.
-
-                                               // But it could be somebody else with the same name. It just isn't highly likely.
-
-
-                                               $this->owner_photo = $this->getDataValue('owner-avatar');
-                                               $this->owner_name = $this->getDataValue('owner-name');
-                                               $this->wall_to_wall = true;
-                                               // If it is our contact, use a friendly redirect link
-                                               if ((link_compare($this->getDataValue('owner-link'), $this->getDataValue('url')))
-                                                       && ($this->getDataValue('network') === NETWORK_DFRN)
-                                               ) {
-                                                       $this->owner_url = $this->getRedirectUrl();
-                                               } else {
-                                                       $this->owner_url = zrl($this->getDataValue('owner-link'));
-                                               }
-                                       }
-                               }
-                       }
-               }
-
-               if (!$this->wall_to_wall) {
-                       $this->setTemplate('wall');
-                       $this->owner_url = '';
-                       $this->owner_photo = '';
-                       $this->owner_name = '';
-               }
-       }
-
-       /**
-        * @return boolean
-        */
-       private function isWallToWall()
-       {
-               return $this->wall_to_wall;
-       }
-
-       /**
-        * @return string
-        */
-       private function getOwnerUrl()
-       {
-               return $this->owner_url;
-       }
-
-       /**
-        * @return string
-        */
-       private function getOwnerName()
-       {
-               return $this->owner_name;
-       }
-
-       /**
-        * @return boolean
-        */
-       private function isVisiting()
-       {
-               return $this->visiting;
-       }
-}
diff --git a/src/Object/Profile.php b/src/Object/Profile.php
new file mode 100644 (file)
index 0000000..29925a9
--- /dev/null
@@ -0,0 +1,46 @@
+<?php
+
+/**
+ * @file src/Object/Profile.php
+ */
+
+namespace Friendica\Object;
+
+use Friendica\BaseObject;
+
+class Profile extends BaseObject
+{
+       /**
+        * @brief Returns a formatted location string from the given profile array
+        *
+        * @param array $profile Profile array (Generated from the "profile" table)
+        *
+        * @return string Location string
+        */
+       public static function formatLocation(array $profile)
+       {
+               $location = '';
+
+               if ($profile['locality']) {
+                       $location .= $profile['locality'];
+               }
+
+               if ($profile['region'] && ($profile['locality'] != $profile['region'])) {
+                       if ($location) {
+                               $location .= ', ';
+                       }
+
+                       $location .= $profile['region'];
+               }
+
+               if ($profile['country-name']) {
+                       if ($location) {
+                               $location .= ', ';
+                       }
+
+                       $location .= $profile['country-name'];
+               }
+
+               return $location;
+       }
+}
diff --git a/src/Object/Thread.php b/src/Object/Thread.php
deleted file mode 100644 (file)
index 2a72f0f..0000000
+++ /dev/null
@@ -1,207 +0,0 @@
-<?php
-/**
- * @file src/Object/Thread.php
- */
-namespace Friendica\Object;
-
-use Friendica\BaseObject;
-use Friendica\Object\Item;
-
-require_once 'boot.php';
-require_once 'include/text.php';
-
-/**
- * A list of threads
- *
- * We should think about making this a SPL Iterator
- */
-class Thread extends BaseObject
-{
-       private $parents = array();
-       private $mode = null;
-       private $writable = false;
-       private $profile_owner = 0;
-       private $preview = false;
-
-       /**
-        * Constructor
-        *
-        * @param string  $mode    The mode
-        * @param boolean $preview boolean value
-        */
-       public function __construct($mode, $preview)
-       {
-               $this->setMode($mode);
-               $this->preview = $preview;
-       }
-
-       /**
-        * Set the mode we'll be displayed on
-        *
-        * @param string $mode The mode to set
-        *
-        * @return void
-        */
-       private function setMode($mode)
-       {
-               if ($this->getMode() == $mode) {
-                       return;
-               }
-
-               $a = self::getApp();
-
-               switch ($mode) {
-                       case 'network':
-                       case 'notes':
-                               $this->profile_owner = local_user();
-                               $this->writable = true;
-                               break;
-                       case 'profile':
-                               $this->profile_owner = $a->profile['profile_uid'];
-                               $this->writable = can_write_wall($a, $this->profile_owner);
-                               break;
-                       case 'display':
-                               $this->profile_owner = $a->profile['uid'];
-                               $this->writable = can_write_wall($a, $this->profile_owner);
-                               break;
-                       default:
-                               logger('[ERROR] Conversation::setMode : Unhandled mode ('. $mode .').', LOGGER_DEBUG);
-                               return false;
-                               break;
-               }
-               $this->mode = $mode;
-       }
-
-       /**
-        * Get mode
-        *
-        * @return string
-        */
-       public function getMode()
-       {
-               return $this->mode;
-       }
-
-       /**
-        * Check if page is writable
-        *
-        * @return boolean
-        */
-       public function isWritable()
-       {
-               return $this->writable;
-       }
-
-       /**
-        * Check if page is a preview
-        *
-        * @return boolean
-        */
-       public function isPreview()
-       {
-               return $this->preview;
-       }
-
-       /**
-        * Get profile owner
-        *
-        * @return integer
-        */
-       public function getProfileOwner()
-       {
-               return $this->profile_owner;
-       }
-
-       /**
-        * Add a thread to the conversation
-        *
-        * @param object $item The item to insert
-        *
-        * @return mixed The inserted item on success
-        *               false on failure
-        */
-       public function addParent($item)
-       {
-               $item_id = $item->getId();
-
-               if (!$item_id) {
-                       logger('[ERROR] Conversation::addThread : Item has no ID!!', LOGGER_DEBUG);
-                       return false;
-               }
-
-               if ($this->getParent($item->getId())) {
-                       logger('[WARN] Conversation::addThread : Thread already exists ('. $item->getId() .').', LOGGER_DEBUG);
-                       return false;
-               }
-
-               /*
-                * Only add will be displayed
-                */
-               if ($item->getDataValue('network') === NETWORK_MAIL && local_user() != $item->getDataValue('uid')) {
-                       logger('[WARN] Conversation::addThread : Thread is a mail ('. $item->getId() .').', LOGGER_DEBUG);
-                       return false;
-               }
-
-               if ($item->getDataValue('verb') === ACTIVITY_LIKE || $item->getDataValue('verb') === ACTIVITY_DISLIKE) {
-                       logger('[WARN] Conversation::addThread : Thread is a (dis)like ('. $item->getId() .').', LOGGER_DEBUG);
-                       return false;
-               }
-
-               $item->setThread($this);
-               $this->parents[] = $item;
-
-               return end($this->parents);
-       }
-
-       /**
-        * Get data in a form usable by a conversation template
-        *
-        * We should find a way to avoid using those arguments (at least most of them)
-        *
-        * @param object $conv_responses data
-        *
-        * @return mixed The data requested on success
-        *               false on failure
-        */
-       public function getTemplateData($conv_responses)
-       {
-               $a = self::getApp();
-               $result = array();
-               $i = 0;
-
-               foreach ($this->parents as $item) {
-                       if ($item->getDataValue('network') === NETWORK_MAIL && local_user() != $item->getDataValue('uid')) {
-                               continue;
-                       }
-
-                       $item_data = $item->getTemplateData($conv_responses);
-
-                       if (!$item_data) {
-                               logger('[ERROR] Conversation::getTemplateData : Failed to get item template data ('. $item->getId() .').', LOGGER_DEBUG);
-                               return false;
-                       }
-                       $result[] = $item_data;
-               }
-
-               return $result;
-       }
-
-       /**
-        * Get a thread based on its item id
-        *
-        * @param integer $id Item id
-        *
-        * @return mixed The found item on success
-        *               false on failure
-        */
-       private function getParent($id)
-       {
-               foreach ($this->parents as $item) {
-                       if ($item->getId() == $id) {
-                               return $item;
-                       }
-               }
-
-               return false;
-       }
-}
index 35557067d7474ca4d7d85d522c0b1847fc33977a..2183a9c1e05698cdacd8c1bb42905121547af2e0 100644 (file)
@@ -6,7 +6,7 @@
 namespace Friendica;
 
 use Friendica\Core\Config;
-use Friendica\Object\Image;
+use Friendica\Object\Photo;
 use Friendica\Util\XML;
 
 use dba;
@@ -353,7 +353,7 @@ class ParseUrl
                                }
 
                                $src = self::completeUrl($attr["src"], $url);
-                               $photodata = Image::getInfoFromURL($src);
+                               $photodata = Photo::getInfoFromURL($src);
 
                                if (($photodata) && ($photodata[0] > 150) && ($photodata[1] > 150)) {
                                        if ($photodata[0] > 300) {
@@ -374,7 +374,7 @@ class ParseUrl
 
                        unset($siteinfo["image"]);
 
-                       $photodata = Image::getInfoFromURL($src);
+                       $photodata = Photo::getInfoFromURL($src);
 
                        if (($photodata) && ($photodata[0] > 10) && ($photodata[1] > 10)) {
                                $siteinfo["images"][] = array("src" => $src,
index 62ada9620ae902f7214dceaac15a840b593449fa..5af082905d847ecd7e0a3a0fd4614e9c1c002aae 100644 (file)
@@ -13,10 +13,10 @@ use Friendica\Core\Config;
 use Friendica\Core\System;
 use Friendica\Core\Worker;
 use Friendica\Database\DBM;
-use Friendica\Model\Contact;
-use Friendica\Model\GContact;
-use Friendica\Model\Profile;
-use Friendica\Object\Image;
+use Friendica\Model\GlobalContact;
+use Friendica\Object\Contact;
+use Friendica\Object\Photo;
+use Friendica\Object\Profile;
 use Friendica\Protocol\OStatus;
 use Friendica\Util\XML;
 
@@ -476,7 +476,7 @@ class DFRN
                        $uid
                );
                $photos = array();
-               $ext = Image::supportedTypes();
+               $ext = Photo::supportedTypes();
 
                foreach ($rp as $p) {
                        $photos[$p['scale']] = System::baseUrl().'/photo/'.$p['resource-id'].'-'.$p['scale'].'.'.$ext[$p['type']];
@@ -1678,9 +1678,9 @@ class DFRN
                        $poco["photo"] = $author["avatar"];
                        $poco["hide"] = $hide;
                        $poco["contact-type"] = $contact["contact-type"];
-                       $gcid = GContact::update($poco);
+                       $gcid = GlobalContact::update($poco);
 
-                       GContact::link($gcid, $importer["uid"], $contact["id"]);
+                       GlobalContact::link($gcid, $importer["uid"], $contact["id"]);
                }
 
                return($author);
index d6f1078f4c7f26a0c252418cd21e1aeae0238093..2cb5eb700b2258292f112d89b2866eb976ed3ee2 100644 (file)
@@ -16,10 +16,10 @@ use Friendica\Core\Config;
 use Friendica\Core\PConfig;
 use Friendica\Core\Worker;
 use Friendica\Database\DBM;
-use Friendica\Model\Contact;
-use Friendica\Model\GContact;
-use Friendica\Model\Profile;
+use Friendica\Model\GlobalContact;
 use Friendica\Network\Probe;
+use Friendica\Object\Contact;
+use Friendica\Object\Profile;
 use Friendica\Util\XML;
 
 use dba;
@@ -2247,9 +2247,9 @@ class Diaspora
                                        "addr" => $author, "nick" => $nick, "keywords" => $keywords,
                                        "hide" => !$searchable, "nsfw" => $nsfw);
 
-               $gcid = GContact::update($gcontact);
+               $gcid = GlobalContact::update($gcontact);
 
-               GContact::link($gcid, $importer["uid"], $contact["id"]);
+               GlobalContact::link($gcid, $importer["uid"], $contact["id"]);
 
                logger("Profile of contact ".$contact["id"]." stored for user ".$importer["uid"], LOGGER_DEBUG);
 
index 2a021c89e9a3dac70fdb5cd42d857c1b6725a697..9a2eaeb5b712767ab9bbf0e50a829d06249858ae 100644 (file)
@@ -9,10 +9,10 @@ use Friendica\Core\Cache;
 use Friendica\Core\Config;
 use Friendica\Core\System;
 use Friendica\Database\DBM;
-use Friendica\Model\Contact;
-use Friendica\Model\GContact;
+use Friendica\Model\GlobalContact;
 use Friendica\Network\Probe;
-use Friendica\Object\Image;
+use Friendica\Object\Contact;
+use Friendica\Object\Photo;
 use Friendica\Util\Lock;
 use Friendica\Util\XML;
 use dba;
@@ -226,9 +226,9 @@ class OStatus
                        $contact["generation"] = 2;
                        $contact["hide"] = false; // OStatus contacts are never hidden
                        $contact["photo"] = $author["author-avatar"];
-                       $gcid = GContact::update($contact);
+                       $gcid = GlobalContact::update($contact);
 
-                       GContact::link($gcid, $contact["uid"], $contact["id"]);
+                       GlobalContact::link($gcid, $contact["uid"], $contact["id"]);
                }
 
                return $author;
@@ -1323,7 +1323,7 @@ class OStatus
 
                switch ($siteinfo["type"]) {
                        case 'photo':
-                               $imgdata = Image::getInfoFromURL($siteinfo["image"]);
+                               $imgdata = Photo::getInfoFromURL($siteinfo["image"]);
                                $attributes = array("rel" => "enclosure",
                                                "href" => $siteinfo["image"],
                                                "type" => $imgdata["mime"],
@@ -1343,7 +1343,7 @@ class OStatus
                }
 
                if (!Config::get('system', 'ostatus_not_attach_preview') && ($siteinfo["type"] != "photo") && isset($siteinfo["image"])) {
-                       $imgdata = Image::getInfoFromURL($siteinfo["image"]);
+                       $imgdata = Photo::getInfoFromURL($siteinfo["image"]);
                        $attributes = array("rel" => "enclosure",
                                        "href" => $siteinfo["image"],
                                        "type" => $imgdata["mime"],
index 2b37a99624dab2cd5e5fe897697aefa065b6e9a8..84bfd4c4f180978940814c4589f000e47def6dd6 100644 (file)
@@ -12,9 +12,10 @@ namespace Friendica\Protocol;
 use Friendica\Core\Config;
 use Friendica\Core\Worker;
 use Friendica\Database\DBM;
-use Friendica\Model\GContact;
-use Friendica\Model\Profile;
+use Friendica\Model\GlobalContact;
 use Friendica\Network\Probe;
+use Friendica\Object\Photo;
+use Friendica\Object\Profile;
 use dba;
 use DOMDocument;
 use DomXPath;
@@ -192,10 +193,10 @@ class PortableContact
                                        "generation" => $generation);
 
                        try {
-                               $gcontact = GContact::sanitize($gcontact);
-                               $gcid = GContact::update($gcontact);
+                               $gcontact = GlobalContact::sanitize($gcontact);
+                               $gcid = GlobalContact::update($gcontact);
 
-                               GContact::link($gcid, $uid, $cid, $zcid);
+                               GlobalContact::link($gcid, $uid, $cid, $zcid);
                        } catch (Exception $e) {
                                logger($e->getMessage(), LOGGER_DEBUG);
                        }
@@ -424,7 +425,7 @@ class PortableContact
 
                                                $contact = array_merge($contact, $noscrape);
 
-                                               GContact::update($contact);
+                                               GlobalContact::update($contact);
 
                                                if (trim($noscrape["updated"]) != "") {
                                                        q(
@@ -446,7 +447,7 @@ class PortableContact
                if (!$force && !self::updateNeeded($gcontacts[0]["created"], $gcontacts[0]["updated"], $gcontacts[0]["last_failure"], $gcontacts[0]["last_contact"])) {
                        logger("Profile ".$profile." was last updated at ".$gcontacts[0]["updated"]." (cached)", LOGGER_DEBUG);
 
-                       GContact::update($contact);
+                       GlobalContact::update($contact);
                        return $gcontacts[0]["updated"];
                }
 
@@ -467,8 +468,8 @@ class PortableContact
                        $gcontact["server_url"] = $data["baseurl"];
 
                        try {
-                               $gcontact = GContact::sanitize($gcontact);
-                               GContact::update($gcontact);
+                               $gcontact = GlobalContact::sanitize($gcontact);
+                               GlobalContact::update($gcontact);
 
                                self::lastUpdated($data["url"], $force);
                        } catch (Exception $e) {
@@ -494,7 +495,7 @@ class PortableContact
 
                $contact["server_url"] = $data["baseurl"];
 
-               GContact::update($contact);
+               GlobalContact::update($contact);
 
                $feedret = z_fetch_url($data["poll"]);
 
@@ -1600,8 +1601,8 @@ class PortableContact
                                                "generation" => $generation);
 
                                try {
-                                       $gcontact = GContact::sanitize($gcontact);
-                                       GContact::update($gcontact);
+                                       $gcontact = GlobalContact::sanitize($gcontact);
+                                       GlobalContact::update($gcontact);
                                } catch (Exception $e) {
                                        logger($e->getMessage(), LOGGER_DEBUG);
                                }
index b59f096d7de3fcf8ea0e8aa9f5d9bb8a8c3d6e91..7df7d030cbd15da10c656e77d946139bb0dcd4b7 100644 (file)
@@ -10,9 +10,9 @@ use Friendica\App;
 use Friendica\Core\Cache;
 use Friendica\Core\Config;
 use Friendica\Database\DBM;
-use Friendica\Model\Contact;
-use Friendica\Model\GContact;
+use Friendica\Model\GlobalContact;
 use Friendica\Network\Probe;
+use Friendica\Object\Contact;
 use Friendica\Protocol\PortableContact;
 use dba;
 
@@ -280,7 +280,7 @@ class CronJobs
                $r = q("SELECT `uid` FROM `user` WHERE `verified` AND NOT `blocked` AND NOT `account_removed` AND NOT `account_expired`");
                if (DBM::is_result($r)) {
                        foreach ($r AS $user) {
-                               GContact::updateForUser($user["uid"]);
+                               GlobalContact::updateForUser($user["uid"]);
                        }
                }
 
index c20bb8d8f83cefd13f12e50c4f3c16fb87a13b2c..bb30fc3bf4bef41f477563ea661eeaef735fd48c 100644 (file)
@@ -9,7 +9,7 @@ use Friendica\App;
 use Friendica\Core\System;
 use Friendica\Core\Config;
 use Friendica\Database\DBM;
-use Friendica\Model\Contact;
+use Friendica\Object\Contact;
 use Friendica\Protocol\Diaspora;
 use Friendica\Protocol\DFRN;
 use Friendica\Protocol\Email;
index b3c03e905054b8c03c1d743fcdb4cd3365045281..96cfae00b61f3e43da5161864c5c0089e6bae876 100644 (file)
@@ -8,7 +8,7 @@ use Friendica\Core\Cache;
 use Friendica\Core\Config;
 use Friendica\Core\Worker;
 use Friendica\Database\DBM;
-use Friendica\Model\GContact;
+use Friendica\Model\GlobalContact;
 use Friendica\Network\Probe;
 use Friendica\Protocol\PortableContact;
 
@@ -90,7 +90,7 @@ class DiscoverPoCo {
                        }
                        logger($result, LOGGER_DEBUG);
                } elseif ($mode == 3) {
-                       GContact::updateSuggestions();
+                       GlobalContact::updateSuggestions();
                } elseif (($mode == 2) && Config::get('system', 'poco_completion')) {
                        self::discoverUsers();
                } elseif (($mode == 1) && ($search != "") && Config::get('system', 'poco_local_search')) {
@@ -102,7 +102,7 @@ class DiscoverPoCo {
 
                        // Query GNU Social servers for their users ("statistics" addon has to be enabled on the GS server)
                        if (!Config::get('system', 'ostatus_disabled')) {
-                               GContact::discoverGsUsers();
+                               GlobalContact::discoverGsUsers();
                        }
                }
 
@@ -256,7 +256,7 @@ class DiscoverPoCo {
 
                                        $data["server_url"] = $data["baseurl"];
 
-                                       GContact::update($data);
+                                       GlobalContact::update($data);
                                } else {
                                        logger("Profile ".$jj->url." is not responding or no Friendica contact - but network ".$data["network"], LOGGER_DEBUG);
                                }
@@ -297,7 +297,7 @@ class DiscoverPoCo {
                        $contact = Probe::uri($user->site_address."/".$user->name);
                        if ($contact["network"] != NETWORK_PHANTOM) {
                                $contact["about"] = $user->description;
-                               GContact::update($contact);
+                               GlobalContact::update($contact);
                        }
                }
        }
index 0d8c3765a8dea74d42e03dbc7a3bb4a1e55047af..2dd66336725be757b88a33665db31ee74d49cbe6 100644 (file)
@@ -8,7 +8,7 @@ namespace Friendica\Worker;
 use Friendica\Core\Cache;
 use Friendica\Core\Config;
 use Friendica\Database\DBM;
-use Friendica\Model\GContact;
+use Friendica\Model\GlobalContact;
 use Friendica\Network\Probe;
 use Friendica\Protocol\PortableContact;
 
@@ -47,7 +47,7 @@ class GProbe {
                        }
 
                        if (!in_array($arr["network"], array(NETWORK_FEED, NETWORK_PHANTOM))) {
-                               GContact::update($arr);
+                               GlobalContact::update($arr);
                        }
 
                        $r = q(
index 18fff2afda1c50f493811b8b83b870e1c127636c..a3a03055ec9f13040bc289652f5eb4e99cd3a923 100644 (file)
@@ -7,8 +7,8 @@ namespace Friendica\Worker;
 use Friendica\Core\Config;
 use Friendica\Core\Worker;
 use Friendica\Database\DBM;
-use Friendica\Model\Contact;
 use Friendica\Network\Probe;
+use Friendica\Object\Contact;
 use Friendica\Protocol\Diaspora;
 use Friendica\Protocol\OStatus;
 use Friendica\Protocol\Salmon;
index 9024d0d4c9008be47ec9eae5071efe9046febe2a..1190c77f5fc3e5a4db7fdeaed134accba2fc7896 100644 (file)
@@ -7,7 +7,7 @@ namespace Friendica\Worker;
 use Friendica\Core\Config;
 use Friendica\Core\PConfig;
 use Friendica\Database\DBM;
-use Friendica\Model\Contact;
+use Friendica\Object\Contact;
 use Friendica\Protocol\Email;
 use Friendica\Protocol\PortableContact;
 use dba;
index 751e15b587bf7dbbe06012210f00eca3530cc017..12a04995c93cb6b5c1ac3bc7c408774dc461ca6b 100644 (file)
@@ -6,8 +6,7 @@ use Friendica\Core\Config;
 use Friendica\Core\PConfig;
 use Friendica\Core\Worker;
 use Friendica\Database\DBM;
-use Friendica\Model\Photo;
-use Friendica\Object\Image;
+use Friendica\Object\Photo;
 
 /**
  *
@@ -154,10 +153,10 @@ function update_1014()
        $r = q("SELECT * FROM `photo` WHERE `scale` = 4");
        if (DBM::is_result($r)) {
                foreach ($r as $rr) {
-                       $Image = new Image($rr['data']);
-                       if ($Image->isValid()) {
-                               $Image->scaleDown(48);
-                               Photo::store($Image, $rr['uid'],$rr['contact-id'],$rr['resource-id'],$rr['filename'],$rr['album'],6,(($rr['profile']) ? 1 : 0));
+                       $ph = new Photo($rr['data']);
+                       if ($ph->isValid()) {
+                               $ph->scaleImage(48);
+                               $ph->store($rr['uid'],$rr['contact-id'],$rr['resource-id'],$rr['filename'],$rr['album'],6,(($rr['profile']) ? 1 : 0));
                        }
                }
        }
index 87044bb4e439599062de34287cc59aa91bbc194c..ab586b651017c5ec0acc08a9838b0c187c5dc4b7 100755 (executable)
@@ -29,7 +29,7 @@ if ($argc != 2 || $argv[1] == "-h" || $argv[1] == "--help" || $argv[1] == "-?")
 }
 
 use Friendica\BaseObject;
-use Friendica\Model\Contact;
+use Friendica\Object\Contact;
 
 require_once 'boot.php';
 require_once 'include/dba.php';
index 8b1713026970604ccd1aad323b92b777bd321626..0a6b48e4ebf7ec1a6b2a2256e9f1aee47b5b9a56 100644 (file)
@@ -12,7 +12,7 @@ use Friendica\Core\Config;
 use Friendica\Core\PConfig;
 use Friendica\Core\System;
 use Friendica\Database\DBM;
-use Friendica\Object\Image;
+use Friendica\Object\Photo;
 
 $frio = "view/theme/frio";
 
@@ -82,7 +82,7 @@ function frio_uninstall() {
  */
 function frio_item_photo_links(App $a, &$body_info)
 {
-       $phototypes = Image::supportedTypes();
+       $phototypes = Photo::supportedTypes();
        $occurence = 1;
        $p = bb_find_open_close($body_info['html'], "<a", ">");
 
index f661546b39fef5c5d0e06e5f77d7404df2d150d3..5d5162cd32afd62514b2470cb51d86a5f65121b7 100644 (file)
@@ -11,7 +11,7 @@
 
 use Friendica\App;
 use Friendica\Core\System;
-use Friendica\Object\Image;
+use Friendica\Object\Photo;
 
 function frost_init(App $a) {
        $a->videowidth = 400;
@@ -48,7 +48,7 @@ function frost_uninstall() {
 
 function frost_item_photo_links(App $a, &$body_info)
 {
-       $phototypes = Image::supportedTypes();
+       $phototypes = Photo::supportedTypes();
 
        $occurence = 1;
        $p = bb_find_open_close($body_info['html'], "<a", ">");
index b7c76b02ef0fafc93797d558db3e71d109801947..0f81200890be8b702c22761669b2a08b731f93ac 100644 (file)
@@ -15,7 +15,7 @@ use Friendica\Core\Config;
 use Friendica\Core\PConfig;
 use Friendica\Core\System;
 use Friendica\Database\DBM;
-use Friendica\Model\GContact;
+use Friendica\Model\GlobalContact;
 
 require_once "include/plugin.php";
 require_once "mod/proxy.php";
@@ -139,7 +139,7 @@ function vier_community_info() {
 
        // comunity_profiles
        if ($show_profiles) {
-               $r = GContact::suggestionQuery(local_user(), 0, 9);
+               $r = GlobalContact::suggestionQuery(local_user(), 0, 9);
 
                $tpl = get_markup_template('ch_directory_item.tpl');
                if (DBM::is_result($r)) {