]> git.mxchange.org Git - friendica.git/commitdiff
We now use memcache if configured and installed.
authorMichael Vogel <ike@pirati.ca>
Sun, 23 Oct 2016 21:59:40 +0000 (21:59 +0000)
committerMichael Vogel <ike@pirati.ca>
Sun, 23 Oct 2016 21:59:40 +0000 (21:59 +0000)
13 files changed:
boot.php
doc/htconfig.md
include/cache.php
include/dbstructure.php
include/identity.php
include/items.php
include/ostatus.php
include/session.php
include/socgraph.php
include/threads.php
mod/item.php
mod/photos.php
mod/profile.php

index aa5574e3c782ca3eb2512b2eb0072cf5f988fb62..85270e5305af968a8375289547f3a561be8d32fe 100644 (file)
--- a/boot.php
+++ b/boot.php
@@ -127,6 +127,10 @@ define ( 'CACHE_MONTH',            0 );
 define ( 'CACHE_WEEK',             1 );
 define ( 'CACHE_DAY',              2 );
 define ( 'CACHE_HOUR',             3 );
+define ( 'CACHE_HALF_HOUR',        4 );
+define ( 'CACHE_QUARTER_HOUR',     5 );
+define ( 'CACHE_FIVE_MINUTES',     6 );
+define ( 'CACHE_MINUTE',           7 );
 /* @}*/
 
 /**
index fa26236673612ed2bdb85769ad39393c6a239b0b..60216827571d582536dececd59604665ec748036 100644 (file)
@@ -40,6 +40,9 @@ line to your .htconfig.php:
 * max_batch_queue - Default value is 1000.
 * max_processes_backend - Maximum number of concurrent database processes for background tasks. Default value is 5.
 * max_processes_frontend - Maximum number of concurrent database processes for foreground tasks. Default value is 20.
+* memcache (Boolean) - Use memcache. To use memcache the PECL extension "memcache" has to be installed and activated.
+* memcache_host - Hostname of the memcache daemon. Default is '127.0.0.1'.
+* memcache_port- Portnumberof the memcache daemon. Default is 11211.
 * no_oembed (Boolean) - Don't use OEmbed to fetch more information about a link.
 * no_oembed_rich_content (Boolean) - Don't show the rich content (e.g. embedded PDF).
 * no_smilies (Boolean) - Don't show smilies.
index d0b0dfafda9c4fc011102bf6a2fa0cd3cbc00d1b..45938dddf86b736d22b45bf8dcd849e4efb0f821 100644 (file)
 <?php
+/**
+ * @file include/cache.php
+ *
+ * @brief Class for storing data for a short time
+ */
+
+use \Friendica\Core\Config;
+use \Friendica\Core\PConfig;
+
+class Cache {
        /**
-        *  cache api
+        * @brief Check for memcache and open a connection if configured
+        *
+        * @return object|boolean The memcache object - or "false" if not successful
         */
+       public static function memcache() {
+               if (!function_exists('memcache_connect')) {
+                       return false;
+               }
+
+               if (!Config::get('system', 'memcache')) {
+                       return false;
+               }
+
+               $memcache_host = Config::get('system', 'memcache_host', '127.0.0.1');
+               $memcache_port = Config::get('system', 'memcache_port', 11211);
 
-       class Cache {
-               public static function get($key) {
+               $memcache = new Memcache;
 
-                       $r = q("SELECT `v` FROM `cache` WHERE `k`='%s' limit 1",
-                               dbesc($key)
-                       );
+               if (!$memcache->connect($memcache_host, $memcache_port)) {
+                       return false;
+               }
 
-                       if (count($r))
-                               return $r[0]['v'];
+               return $memcache;
+       }
+
+       /**
+        * @brief Return the duration for a given cache level
+        *
+        * @param integer $level Cache level
+        *
+        * @return integer The cache duration in seconds
+        */
+       private function duration($level) {
+               switch($level) {
+                       case CACHE_MONTH;
+                               $seconds = 2592000;
+                               break;
+                       case CACHE_WEEK;
+                               $seconds = 604800;
+                               break;
+                       case CACHE_DAY;
+                               $seconds = 86400;
+                               break;
+                       case CACHE_HOUR;
+                               $seconds = 3600;
+                               break;
+                       case CACHE_HALF_HOUR;
+                               $seconds = 1800;
+                               break;
+                       case CACHE_QUARTER_HOUR;
+                               $seconds = 900;
+                               break;
+                       case CACHE_FIVE_MINUTES;
+                               $seconds = 300;
+                               break;
+                       case CACHE_MINUTE;
+                               $seconds = 60;
+                               break;
+               }
+               return $seconds;
+       }
+
+       /**
+        * @brief Fetch cached data according to the key
+        *
+        * @param string $key The key to the cached data
+        *
+        * @return mixed Cached $value or "null" if not found
+        */
+       public static function get($key) {
+
+               $memcache = self::memcache();
+               if (is_object($memcache)) {
+                       // We fetch with the hostname as key to avoid problems with other applications
+                       $value = $memcache->get(get_app()->get_hostname().":".$key);
+                       if (!is_bool($value)) {
+                               return unserialize($value);
+                       }
 
                        return null;
                }
 
-               public static function set($key,$value, $duration = CACHE_MONTH) {
+               // Frequently clear cache
+               self::clear($duration);
 
-                       q("REPLACE INTO `cache` (`k`,`v`,`expire_mode`,`updated`) VALUES ('%s','%s',%d,'%s')",
-                                       dbesc($key),
-                                       dbesc($value),
-                                       intval($duration),
-                                       dbesc(datetime_convert()));
+               $r = q("SELECT `v` FROM `cache` WHERE `k`='%s' LIMIT 1",
+                       dbesc($key)
+               );
 
+               if (count($r)) {
+                       return $r[0]['v'];
                }
 
+               return null;
+       }
 
-/*
- *
- * Leaving this legacy code temporaily to see how REPLACE fares
- * as opposed to non-atomic checks when faced with fast moving key duplication.
- * As a MySQL extension it isn't portable, but we're not yet very portable.
- */
+       /**
+        * @brief Put data in the cache according to the key
+        *
+        * @param string $key The key to the cached data
+        * @param mixed $valie The value that is about to be stored
+        * @param integer $duration The cache lifespan
+        */
+       public static function set($key, $value, $duration = CACHE_MONTH) {
+
+               // Do we have an installed memcache? Use it instead.
+               $memcache = self::memcache();
+               if (is_object($memcache)) {
+                       // We store with the hostname as key to avoid problems with other applications
+                       $memcache->set(get_app()->get_hostname().":".$key, serialize($value), MEMCACHE_COMPRESSED, self::duration($duration));
+                       return;
+               }
 
-/*
- *                     $r = q("SELECT * FROM `cache` WHERE `k`='%s' limit 1",
- *                             dbesc($key)
- *                     );
- *                     if(count($r)) {
- *                             q("UPDATE `cache` SET `v` = '%s', `updated = '%s' WHERE `k` = '%s'",
- *                                     dbesc($value),
- *                                     dbesc(datetime_convert()),
- *                                     dbesc($key));
- *                     }
- *                     else {
- *                             q("INSERT INTO `cache` (`k`,`v`,`updated`) VALUES ('%s','%s','%s')",
- *                                     dbesc($key),
- *                                     dbesc($value),
- *                                     dbesc(datetime_convert()));
- *                     }
- *             }
- */
+               /// @todo store the cache data in the same way like the config data
+               q("REPLACE INTO `cache` (`k`,`v`,`expire_mode`,`updated`) VALUES ('%s','%s',%d,'%s')",
+                               dbesc($key),
+                               dbesc($value),
+                               intval($duration),
+                               dbesc(datetime_convert()));
+       }
 
+       /**
+        * @brief Remove outdated data from the cache
+        *
+        * @param integer $maxlevel The maximum cache level that is to be cleared
+        */
+       public static function clear($max_level = CACHE_MONTH) {
+
+               // Clear long lasting cache entries only once a day
+               if (get_config("system", "cache_cleared_day") < time() - self::duration(CACHE_DAY)) {
+                       if ($max_level == CACHE_MONTH) {
+                               q("DELETE FROM `cache` WHERE `updated` < '%s' AND `expire_mode` = %d",
+                                       dbesc(datetime_convert('UTC','UTC',"now - 30 days")), intval(CACHE_MONTH));
+                       }
+
+                       if ($max_level <= CACHE_WEEK) {
+                               q("DELETE FROM `cache` WHERE `updated` < '%s' AND `expire_mode` = %d",
+                                       dbesc(datetime_convert('UTC','UTC',"now - 7 days")), intval(CACHE_WEEK));
+                       }
+
+                       if ($max_level <= CACHE_DAY) {
+                               q("DELETE FROM `cache` WHERE `updated` < '%s' AND `expire_mode` = %d",
+                               dbesc(datetime_convert('UTC','UTC',"now - 1 days")), intval(CACHE_DAY));
+                       }
+                       set_config("system", "cache_cleared_day", time());
+               }
 
-               public static function clear(){
+               if (($max_level <= CACHE_HOUR) AND (get_config("system", "cache_cleared_hour")) < time() - self::duration(CACHE_HOUR)) {
                        q("DELETE FROM `cache` WHERE `updated` < '%s' AND `expire_mode` = %d",
-                               dbesc(datetime_convert('UTC','UTC',"now - 30 days")), intval(CACHE_MONTH));
+                               dbesc(datetime_convert('UTC','UTC',"now - 1 hours")), intval(CACHE_HOUR));
+
+                       set_config("system", "cache_cleared_hour", time());
+               }
 
+               if (($max_level <= CACHE_HALF_HOUR) AND (get_config("system", "cache_cleared_half_hour")) < time() - self::duration(CACHE_HALF_HOUR)) {
                        q("DELETE FROM `cache` WHERE `updated` < '%s' AND `expire_mode` = %d",
-                               dbesc(datetime_convert('UTC','UTC',"now - 7 days")), intval(CACHE_WEEK));
+                               dbesc(datetime_convert('UTC','UTC',"now - 30 minutes")), intval(CACHE_HALF_HOUR));
 
+                       set_config("system", "cache_cleared_half_hour", time());
+               }
+
+               if (($max_level <= CACHE_QUARTER_HOUR) AND (get_config("system", "cache_cleared_hour")) < time() - self::duration(CACHE_QUARTER_HOUR)) {
                        q("DELETE FROM `cache` WHERE `updated` < '%s' AND `expire_mode` = %d",
-                               dbesc(datetime_convert('UTC','UTC',"now - 1 days")), intval(CACHE_DAY));
+                               dbesc(datetime_convert('UTC','UTC',"now - 15 minutes")), intval(CACHE_QUARTER_HOUR));
 
+                       set_config("system", "cache_cleared_quarter_hour", time());
+               }
+
+               if (($max_level <= CACHE_FIVE_MINUTES) AND (get_config("system", "cache_cleared_five_minute")) < time() - self::duration(CACHE_FIVE_MINUTES)) {
                        q("DELETE FROM `cache` WHERE `updated` < '%s' AND `expire_mode` = %d",
-                               dbesc(datetime_convert('UTC','UTC',"now - 1 hours")), intval(CACHE_HOUR));
+                               dbesc(datetime_convert('UTC','UTC',"now - 5 minutes")), intval(CACHE_FIVE_MINUTES));
+
+                       set_config("system", "cache_cleared_five_minute", time());
                }
 
-       }
+               if (($max_level <= CACHE_MINUTE) AND (get_config("system", "cache_cleared_minute")) < time() - self::duration(CACHE_MINUTE)) {
+                       q("DELETE FROM `cache` WHERE `updated` < '%s' AND `expire_mode` = %d",
+                               dbesc(datetime_convert('UTC','UTC',"now - 1 minutes")), intval(CACHE_MINUTE));
 
+                       set_config("system", "cache_cleared_minute", time());
+               }
+       }
+}
index b0f90ae245a681c3cc6e4d457d0a71594190f51e..3d14615327c2b206aae401cd8aa375da23ae9bdb 100644 (file)
@@ -443,6 +443,7 @@ function db_definition($charset) {
                        "indexes" => array(
                                        "PRIMARY" => array("k".db_index_suffix($charset)),
                                        "updated" => array("updated"),
+                                       "expire_mode_updated" => array("expire_mode", "updated"),
                                        )
                        );
        $database["challenge"] = array(
index b3dbea8fc6ab860974fdf06f58e13919d04ac31a..a30d81cf3a4d371a4b44c31cc5089d40e6945e85 100644 (file)
@@ -149,17 +149,23 @@ function get_profiledata_by_nick($nickname, $uid = 0, $profile = 0) {
 
        if($profile) {
                $profile_int = intval($profile);
-               $r = q("SELECT `profile`.`uid` AS `profile_uid`, `profile`.* , `contact`.`avatar-date` AS picdate, `contact`.`addr`, `user`.* FROM `profile`
-                               INNER JOIN `contact` on `contact`.`uid` = `profile`.`uid` INNER JOIN `user` ON `profile`.`uid` = `user`.`uid`
-                               WHERE `user`.`nickname` = '%s' AND `profile`.`id` = %d AND `contact`.`self` = 1 LIMIT 1",
+               $r = q("SELECT `contact`.`id` AS `contact_id`, `profile`.`uid` AS `profile_uid`, `profile`.*,
+                               `contact`.`avatar-date` AS picdate, `contact`.`addr`, `user`.*
+                       FROM `profile`
+                       INNER JOIN `contact` on `contact`.`uid` = `profile`.`uid` AND `contact`.`self`
+                       INNER JOIN `user` ON `profile`.`uid` = `user`.`uid`
+                       WHERE `user`.`nickname` = '%s' AND `profile`.`id` = %d LIMIT 1",
                                dbesc($nickname),
                                intval($profile_int)
                );
        }
        if((!$r) && (!count($r))) {
-               $r = q("SELECT `profile`.`uid` AS `profile_uid`, `profile`.* , `contact`.`avatar-date` AS picdate, `contact`.`addr`, `user`.* FROM `profile`
-                               INNER JOIN `contact` ON `contact`.`uid` = `profile`.`uid` INNER JOIN `user` ON `profile`.`uid` = `user`.`uid`
-                               WHERE `user`.`nickname` = '%s' AND `profile`.`is-default` = 1 AND `contact`.`self` = 1 LIMIT 1",
+               $r = q("SELECT `contact`.`id` AS `contact_id`, `profile`.`uid` AS `profile_uid`, `profile`.*,
+                               `contact`.`avatar-date` AS picdate, `contact`.`addr`, `user`.*
+                       FROM `profile`
+                       INNER JOIN `contact` ON `contact`.`uid` = `profile`.`uid` AND `contact`.`self`
+                       INNER JOIN `user` ON `profile`.`uid` = `user`.`uid`
+                       WHERE `user`.`nickname` = '%s' AND `profile`.`is-default` LIMIT 1",
                                dbesc($nickname)
                );
        }
index 27c198d89420fe1c126886b22d2581f8d271207d..98927e658529c72ecf4add909f84be088d0cf7df 100644 (file)
@@ -770,7 +770,6 @@ function item_store($arr,$force_parent = false, $notify = false, $dontcache = fa
 
        logger('item_store: ' . print_r($arr,true), LOGGER_DATA);
 
-       q("COMMIT;");
        q("START TRANSACTION;");
 
        $r = dbq("INSERT INTO `item` (`"
@@ -887,13 +886,16 @@ function item_store($arr,$force_parent = false, $notify = false, $dontcache = fa
        create_tags_from_item($current_post);
        create_files_from_item($current_post);
 
-       q("COMMIT");
-
        // Only check for notifications on start posts
        if ($arr['parent-uri'] === $arr['uri']) {
                add_thread($current_post);
+               q("COMMIT");
+
+               add_shadow_thread($current_post);
        } else {
                update_thread($parent_id);
+               q("COMMIT");
+
                add_shadow_entry($arr);
        }
 
index 5dcc7d5a7e42fe4562054a6bd5594daf8dc45a8b..83bc493e3912e0f614768c4d043bccf132b550f5 100644 (file)
@@ -813,7 +813,8 @@ class ostatus {
                                WHERE `term`.`uid` = %d AND `term`.`otype` = %d AND `term`.`type` = %d AND `term`.`url` = '%s'))",
                                intval($uid), intval(TERM_OBJ_POST), intval(TERM_CONVERSATION), dbesc($conversation_url));
 
-/*
+/*             2016-10-23: The old query will be kept until we are sure that the query above is a good and fast replacement
+
                $parents = q("SELECT `id`, `parent`, `uri`, `contact-id`, `type`, `verb`, `visible` FROM `item` WHERE `id` IN
                                (SELECT `parent` FROM `item` WHERE `id` IN
                                        (SELECT `oid` FROM `term` WHERE `uid` = %d AND `otype` = %d AND `type` = %d AND `url` = '%s'))",
@@ -1981,8 +1982,9 @@ class ostatus {
                                intval($owner["uid"]), intval($owner["id"]),
                                intval($authorid), dbesc($check_date),
                                dbesc(NETWORK_OSTATUS), dbesc(NETWORK_DFRN));
-/*
-               // We keep this old query until we are sure that the new one works better
+
+/*             2016-10-23: The old query will be kept until we are sure that the query above is a good and fast replacement
+
                $items = q("SELECT `item`.*, `item`.`id` AS `item_id` FROM `item`
                                STRAIGHT_JOIN `thread` ON `thread`.`iid` = `item`.`parent`
                                LEFT JOIN `item` AS `thritem` ON `thritem`.`uri`=`item`.`thr-parent` AND `thritem`.`uid`=`item`.`uid`
index 8f9d64606c00b3dda205e4e85badcca6316f8571..c69a4023176889f441cc27023043e7e2dc67b33d 100644 (file)
@@ -1,43 +1,62 @@
 <?php
-
 // Session management functions. These provide database storage of PHP
 // session info.
 
+require_once('include/cache.php');
+
 $session_exists = 0;
 $session_expire = 180000;
 
-if(! function_exists('ref_session_open')) {
-function ref_session_open ($s,$n) {
+function ref_session_open($s, $n) {
        return true;
-}}
+}
 
-if(! function_exists('ref_session_read')) {
-function ref_session_read ($id) {
+function ref_session_read($id) {
        global $session_exists;
-       if(x($id))
-               $r = q("SELECT `data` FROM `session` WHERE `sid`= '%s'", dbesc($id));
 
-       if(count($r)) {
+       if (!x($id)) {
+               return '';
+       }
+
+       $memcache = cache::memcache();
+       if (is_object($memcache)) {
+               $data = $memcache->get(get_app()->get_hostname().":session:".$id);
+               if (!is_bool($data)) {
+                       return $data;
+               }
+               logger("no data for session $id", LOGGER_TRACE);
+               return '';
+       }
+
+       $r = q("SELECT `data` FROM `session` WHERE `sid`= '%s'", dbesc($id));
+
+       if (dbm::is_result($r)) {
                $session_exists = true;
                return $r[0]['data'];
        } else {
                logger("no data for session $id", LOGGER_TRACE);
        }
+
        return '';
-}}
+}
 
-if(! function_exists('ref_session_write')) {
-function ref_session_write ($id,$data) {
+function ref_session_write($id, $data) {
        global $session_exists, $session_expire;
 
-       if(! $id || ! $data) {
+       if (!$id || !$data) {
                return false;
        }
 
        $expire = time() + $session_expire;
        $default_expire = time() + 300;
 
-       if($session_exists) {
+       $memcache = cache::memcache();
+       if (is_object($memcache)) {
+               $memcache->set(get_app()->get_hostname().":session:".$id, $data, MEMCACHE_COMPRESSED, $expire);
+               return true;
+       }
+
+       if ($session_exists) {
                $r = q("UPDATE `session`
                                SET `data` = '%s'
                                WHERE `data` != '%s' AND `sid` = '%s'",
@@ -53,24 +72,30 @@ function ref_session_write ($id,$data) {
                                dbesc($id), dbesc($default_expire), dbesc($data));
 
        return true;
-}}
+}
 
-if(! function_exists('ref_session_close')) {
 function ref_session_close() {
        return true;
-}}
+}
+
+function ref_session_destroy($id) {
+       $memcache = cache::memcache();
+
+       if (is_object($memcache)) {
+               $memcache->delete(get_app()->get_hostname().":session:".$id);
+               return true;
+       }
 
-if(! function_exists('ref_session_destroy')) {
-function ref_session_destroy ($id) {
        q("DELETE FROM `session` WHERE `sid` = '%s'", dbesc($id));
+
        return true;
-}}
+}
 
-if(! function_exists('ref_session_gc')) {
 function ref_session_gc($expire) {
        q("DELETE FROM `session` WHERE `expire` < %d", dbesc(time()));
+
        return true;
-}}
+}
 
 $gc_probability = 50;
 
@@ -78,7 +103,8 @@ ini_set('session.gc_probability', $gc_probability);
 ini_set('session.use_only_cookies', 1);
 ini_set('session.cookie_httponly', 1);
 
-if (!get_config('system', 'disable_database_session'))
+if (!get_config('system', 'disable_database_session')) {
        session_set_save_handler('ref_session_open', 'ref_session_close',
                                'ref_session_read', 'ref_session_write',
                                'ref_session_destroy', 'ref_session_gc');
+}
index a41861d6eae0b33978797ad63fc5c201b3b0cc1c..e1b5cdbf9acfaf1d02554566b9e95ea5f4c946a6 100644 (file)
@@ -1075,8 +1075,14 @@ function all_friends($uid,$cid,$start = 0, $limit = 80) {
 
 function suggestion_query($uid, $start = 0, $limit = 80) {
 
-       if(! $uid)
+       if (!$uid) {
                return array();
+       }
+
+       $list = Cache::get("suggestion_query:".$uid.":".$start.":".$limit);
+       if (!is_null($list)) {
+               return $list;
+       }
 
        $network = array(NETWORK_DFRN);
 
@@ -1087,9 +1093,10 @@ function suggestion_query($uid, $start = 0, $limit = 80) {
                $network[] = NETWORK_OSTATUS;
 
        $sql_network = implode("', '", $network);
-       //$sql_network = "'".$sql_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 )
@@ -1108,8 +1115,10 @@ function suggestion_query($uid, $start = 0, $limit = 80) {
                intval($limit)
        );
 
-       if(count($r) && count($r) >= ($limit -1))
+       if(count($r) && count($r) >= ($limit -1)) {
+               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`
@@ -1138,6 +1147,7 @@ function suggestion_query($uid, $start = 0, $limit = 80) {
        while (sizeof($list) > ($limit))
                array_pop($list);
 
+       Cache::set("suggestion_query:".$uid.":".$start.":".$limit, $list, CACHE_FIVE_MINUTES);
        return $list;
 }
 
index 2e02e7ada3290ae0ecb690cad1d6ca912e307379..a487d6e01f859bfb66da61b0f60bb3935314612c 100644 (file)
@@ -18,42 +18,61 @@ function add_thread($itemid, $onlyshadow = false) {
                                .implode("', '", array_values($item))
                                ."')");
 
-               logger("add_thread: Add thread for item ".$itemid." - ".print_r($result, true), LOGGER_DEBUG);
+               logger("Add thread for item ".$itemid." - ".print_r($result, true), LOGGER_DEBUG);
        }
+}
+
+function add_shadow_thread($itemid) {
+       $items = q("SELECT `uid`, `wall`, `private`, `moderated`, `visible`, `contact-id`, `deleted`, `network`
+               FROM `item` WHERE `id` = %d AND (`parent` = %d OR `parent` = 0) LIMIT 1", intval($itemid), intval($itemid));
+
+       if (!dbm::is_result($items)) {
+               return;
+       }
+
+       $item = $items[0];
 
        // is it already a copy?
-       if (($itemid == 0) OR ($item['uid'] == 0))
+       if (($itemid == 0) OR ($item['uid'] == 0)) {
                return;
+       }
 
        // Is it a visible public post?
-       if (!$item["visible"] OR $item["deleted"] OR $item["moderated"] OR $item["private"])
+       if (!$item["visible"] OR $item["deleted"] OR $item["moderated"] OR $item["private"]) {
                return;
+       }
 
        // is it an entry from a connector? Only add an entry for natively connected networks
-       if (!in_array($item["network"], array(NETWORK_DFRN, NETWORK_DIASPORA, NETWORK_OSTATUS, "")))
+       if (!in_array($item["network"], array(NETWORK_DFRN, NETWORK_DIASPORA, NETWORK_OSTATUS, ""))) {
                return;
+       }
 
        // Only do these checks if the post isn't a wall post
        if (!$item["wall"]) {
                // Check, if hide-friends is activated - then don't do a shadow entry
                $r = q("SELECT `hide-friends` FROM `profile` WHERE `is-default` AND `uid` = %d AND NOT `hide-friends`",
                        $item['uid']);
-               if (!count($r))
+
+               if (!dbm::is_result($r)) {
                        return;
+               }
+
                // Check if the contact is hidden or blocked
                $r = q("SELECT `id` FROM `contact` WHERE NOT `hidden` AND NOT `blocked` AND `id` = %d",
                        $item['contact-id']);
-               if (!count($r))
+
+               if (!dbm::is_result($r)) {
                        return;
+               }
        }
 
        // Only add a shadow, if the profile isn't hidden
        $r = q("SELECT `uid` FROM `user` where `uid` = %d AND NOT `hidewall`", $item['uid']);
-       if (!count($r))
+       if (!dbm::is_result($r)) {
                return;
+       }
 
-       $item = q("SELECT * FROM `item` WHERE `id` = %d",
-               intval($itemid));
+       $item = q("SELECT * FROM `item` WHERE `id` = %d", intval($itemid));
 
        if (count($item) AND ($item[0]["allow_cid"] == '')  AND ($item[0]["allow_gid"] == '') AND
                ($item[0]["deny_cid"] == '') AND ($item[0]["deny_gid"] == '')) {
@@ -61,7 +80,7 @@ function add_thread($itemid, $onlyshadow = false) {
                $r = q("SELECT `id` FROM `item` WHERE `uri` = '%s' AND `uid` = 0 LIMIT 1",
                        dbesc($item['uri']));
 
-               if (!$r) {
+               if (!dbm::is_result($r)) {
                        // Preparing public shadow (removing user specific data)
                        require_once("include/items.php");
                        require_once("include/Contact.php");
@@ -72,7 +91,7 @@ function add_thread($itemid, $onlyshadow = false) {
                        $item[0]['contact-id'] = get_contact($item[0]['author-link'], 0);
                        $public_shadow = item_store($item[0], false, false, true);
 
-                       logger("add_thread: Stored public shadow for post ".$itemid." under id ".$public_shadow, LOGGER_DEBUG);
+                       logger("Stored public shadow for thread ".$itemid." under id ".$public_shadow, LOGGER_DEBUG);
                }
        }
 }
@@ -193,8 +212,10 @@ function update_threads() {
 
        logger("update_threads: fetched messages: ".count($messages));
 
-       while ($message = $db->qfetch())
+       while ($message = $db->qfetch()) {
                add_thread($message["id"]);
+               add_shadow_thread($message["id"]);
+       }
        $db->qclose();
 }
 
@@ -227,7 +248,7 @@ function update_shadow_copy() {
 
        logger("fetched messages: ".count($messages));
        while ($message = $db->qfetch())
-               add_thread($message["iid"], true);
+               add_shadow_thread($message["iid"]);
 
        $db->qclose();
 }
index 94ff6b93d4f1836ad6353df1c0646cc5a9ce6b42..a56dde3c19f3ce057b128024fae94857fcfff763 100644 (file)
@@ -788,7 +788,6 @@ function item_post(&$a) {
        } else
                $post_id = 0;
 
-       q("COMMIT;");
        q("START TRANSACTION;");
 
        $r = q("INSERT INTO `item` (`guid`, `extid`, `uid`,`type`,`wall`,`gravity`, `network`, `contact-id`,
@@ -990,12 +989,14 @@ function item_post(&$a) {
        create_tags_from_item($post_id);
        create_files_from_item($post_id);
 
-       q("COMMIT");
-
-       if ($post_id == $parent)
+       if ($post_id == $parent) {
                add_thread($post_id);
-       else {
+               q("COMMIT");
+
+               add_shadow_thread($post_id);
+       } else {
                update_thread($parent, true);
+               q("COMMIT");
 
                // Insert an item entry for UID=0 for global entries
                // We have to remove or change some data before that,
index 19d3d1c6c4be9a3cd22adba2ee14607e4badc8c3..34e5eb4ba34d7e5fa96de96a188701fedb63ca4b 100644 (file)
@@ -53,12 +53,18 @@ function photos_init(&$a) {
 
                $sql_extra = permissions_sql($a->data['user']['uid']);
 
-               $albums = qu("SELECT count(distinct `resource-id`) AS `total`, `album` FROM `photo` USE INDEX (`uid_album_created`) WHERE `uid` = %d  AND `album` != '%s' AND `album` != '%s'
-                       $sql_extra GROUP BY `album` ORDER BY `created` DESC",
-                       intval($a->data['user']['uid']),
-                       dbesc('Contact Photos'),
-                       dbesc( t('Contact Photos'))
-               );
+               $albums = Cache::get("photos-albums:".$a->data['user']['uid']);
+               if (is_null($albums)) {
+                       /// @todo This query needs to be renewed. It is really slow
+                       // At this time we just store the data in the cache
+                       $albums = qu("SELECT count(distinct `resource-id`) AS `total`, `album` FROM `photo` USE INDEX (`uid_album_created`) WHERE `uid` = %d  AND `album` != '%s' AND `album` != '%s'
+                               $sql_extra GROUP BY `album` ORDER BY `created` DESC",
+                               intval($a->data['user']['uid']),
+                               dbesc('Contact Photos'),
+                               dbesc( t('Contact Photos'))
+                       );
+                       Cache::set("photos-albums:".$a->data['user']['uid'], $albums, CACHE_FIVE_MINUTES);
+               }
 
                $albums_visible = ((intval($a->data['user']['hidewall']) && (! local_user()) && (! remote_user())) ? false : true);
 
index a8a6ad3885d679a4bb40535c5df5191813655dd2..279f8635231591e8e2444fa54453aa12169023bc 100644 (file)
@@ -282,16 +282,20 @@ function profile_content(&$a, $update = 0) {
                $pager_sql = sprintf(" LIMIT %d, %d ",intval($a->pager['start']), intval($a->pager['itemspage']));
 
                $r = q("SELECT `thread`.`iid` AS `item_id`, `thread`.`network` AS `item_network`
-                       FROM `thread` FORCE INDEX (`uid_created`) INNER JOIN `item` ON `item`.`id` = `thread`.`iid`
-                       $sql_post_table INNER JOIN `contact` ON `contact`.`id` = `thread`.`contact-id`
-                       AND `contact`.`blocked` = 0 AND `contact`.`pending` = 0
-                       WHERE `thread`.`uid` = %d AND `thread`.`visible` = 1 AND `thread`.`deleted` = 0
-                       and `thread`.`moderated` = 0
-                       AND `thread`.`wall` = 1
-                       $sql_extra $sql_extra2
-                       ORDER BY `thread`.`created` DESC $pager_sql ",
-                       intval($a->profile['profile_uid'])
-
+                       FROM `thread`
+                       STRAIGHT_JOIN `item` ON `item`.`id` = `thread`.`iid`
+                       $sql_post_table
+                       STRAIGHT_JOIN `contact` ON `contact`.`id` = `thread`.`contact-id`
+                               AND NOT `contact`.`blocked` AND NOT `contact`.`pending`
+                       WHERE `thread`.`uid` = %d AND `thread`.`visible`
+                               AND `thread`.`contact-id` = %d
+                               AND NOT `thread`.`deleted`
+                               AND NOT `thread`.`moderated`
+                               AND `thread`.`wall`
+                               $sql_extra $sql_extra2
+                       ORDER BY `thread`.`created` DESC $pager_sql",
+                       intval($a->profile['profile_uid']),
+                       intval($a->profile['contact_id'])
                );
        }