We now use memcache if configured and installed.
This commit is contained in:
parent
deb2fee2f0
commit
ee5ada6991
13 changed files with 339 additions and 130 deletions
4
boot.php
4
boot.php
|
@ -127,6 +127,10 @@ define ( 'CACHE_MONTH', 0 );
|
||||||
define ( 'CACHE_WEEK', 1 );
|
define ( 'CACHE_WEEK', 1 );
|
||||||
define ( 'CACHE_DAY', 2 );
|
define ( 'CACHE_DAY', 2 );
|
||||||
define ( 'CACHE_HOUR', 3 );
|
define ( 'CACHE_HOUR', 3 );
|
||||||
|
define ( 'CACHE_HALF_HOUR', 4 );
|
||||||
|
define ( 'CACHE_QUARTER_HOUR', 5 );
|
||||||
|
define ( 'CACHE_FIVE_MINUTES', 6 );
|
||||||
|
define ( 'CACHE_MINUTE', 7 );
|
||||||
/* @}*/
|
/* @}*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -40,6 +40,9 @@ line to your .htconfig.php:
|
||||||
* max_batch_queue - Default value is 1000.
|
* 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_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.
|
* 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 (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_oembed_rich_content (Boolean) - Don't show the rich content (e.g. embedded PDF).
|
||||||
* no_smilies (Boolean) - Don't show smilies.
|
* no_smilies (Boolean) - Don't show smilies.
|
||||||
|
|
|
@ -1,72 +1,195 @@
|
||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
* cache api
|
* @file include/cache.php
|
||||||
|
*
|
||||||
|
* @brief Class for storing data for a short time
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
use \Friendica\Core\Config;
|
||||||
|
use \Friendica\Core\PConfig;
|
||||||
|
|
||||||
class Cache {
|
class Cache {
|
||||||
|
/**
|
||||||
|
* @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);
|
||||||
|
|
||||||
|
$memcache = new Memcache;
|
||||||
|
|
||||||
|
if (!$memcache->connect($memcache_host, $memcache_port)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
public static function get($key) {
|
||||||
|
|
||||||
$r = q("SELECT `v` FROM `cache` WHERE `k`='%s' limit 1",
|
$memcache = self::memcache();
|
||||||
dbesc($key)
|
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 (count($r))
|
if (!is_bool($value)) {
|
||||||
return $r[0]['v'];
|
return unserialize($value);
|
||||||
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Frequently clear cache
|
||||||
|
self::clear($duration);
|
||||||
|
|
||||||
|
$r = q("SELECT `v` FROM `cache` WHERE `k`='%s' LIMIT 1",
|
||||||
|
dbesc($key)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (count($r)) {
|
||||||
|
return $r[0]['v'];
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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) {
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @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')",
|
q("REPLACE INTO `cache` (`k`,`v`,`expire_mode`,`updated`) VALUES ('%s','%s',%d,'%s')",
|
||||||
dbesc($key),
|
dbesc($key),
|
||||||
dbesc($value),
|
dbesc($value),
|
||||||
intval($duration),
|
intval($duration),
|
||||||
dbesc(datetime_convert()));
|
dbesc(datetime_convert()));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
/*
|
* @brief Remove outdated data from the cache
|
||||||
*
|
*
|
||||||
* Leaving this legacy code temporaily to see how REPLACE fares
|
* @param integer $maxlevel The maximum cache level that is to be cleared
|
||||||
* 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.
|
|
||||||
*/
|
*/
|
||||||
|
public static function clear($max_level = CACHE_MONTH) {
|
||||||
|
|
||||||
/*
|
// Clear long lasting cache entries only once a day
|
||||||
* $r = q("SELECT * FROM `cache` WHERE `k`='%s' limit 1",
|
if (get_config("system", "cache_cleared_day") < time() - self::duration(CACHE_DAY)) {
|
||||||
* dbesc($key)
|
if ($max_level == CACHE_MONTH) {
|
||||||
* );
|
|
||||||
* 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()));
|
|
||||||
* }
|
|
||||||
* }
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
public static function clear(){
|
|
||||||
q("DELETE FROM `cache` WHERE `updated` < '%s' AND `expire_mode` = %d",
|
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 - 30 days")), intval(CACHE_MONTH));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($max_level <= CACHE_WEEK) {
|
||||||
q("DELETE FROM `cache` WHERE `updated` < '%s' AND `expire_mode` = %d",
|
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 - 7 days")), intval(CACHE_WEEK));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($max_level <= CACHE_DAY) {
|
||||||
q("DELETE FROM `cache` WHERE `updated` < '%s' AND `expire_mode` = %d",
|
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 - 1 days")), intval(CACHE_DAY));
|
||||||
|
}
|
||||||
|
set_config("system", "cache_cleared_day", time());
|
||||||
|
}
|
||||||
|
|
||||||
|
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",
|
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 - 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 - 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 - 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 - 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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -443,6 +443,7 @@ function db_definition($charset) {
|
||||||
"indexes" => array(
|
"indexes" => array(
|
||||||
"PRIMARY" => array("k".db_index_suffix($charset)),
|
"PRIMARY" => array("k".db_index_suffix($charset)),
|
||||||
"updated" => array("updated"),
|
"updated" => array("updated"),
|
||||||
|
"expire_mode_updated" => array("expire_mode", "updated"),
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
$database["challenge"] = array(
|
$database["challenge"] = array(
|
||||||
|
|
|
@ -149,17 +149,23 @@ function get_profiledata_by_nick($nickname, $uid = 0, $profile = 0) {
|
||||||
|
|
||||||
if($profile) {
|
if($profile) {
|
||||||
$profile_int = intval($profile);
|
$profile_int = intval($profile);
|
||||||
$r = q("SELECT `profile`.`uid` AS `profile_uid`, `profile`.* , `contact`.`avatar-date` AS picdate, `contact`.`addr`, `user`.* FROM `profile`
|
$r = q("SELECT `contact`.`id` AS `contact_id`, `profile`.`uid` AS `profile_uid`, `profile`.*,
|
||||||
INNER JOIN `contact` on `contact`.`uid` = `profile`.`uid` INNER JOIN `user` ON `profile`.`uid` = `user`.`uid`
|
`contact`.`avatar-date` AS picdate, `contact`.`addr`, `user`.*
|
||||||
WHERE `user`.`nickname` = '%s' AND `profile`.`id` = %d AND `contact`.`self` = 1 LIMIT 1",
|
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),
|
dbesc($nickname),
|
||||||
intval($profile_int)
|
intval($profile_int)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if((!$r) && (!count($r))) {
|
if((!$r) && (!count($r))) {
|
||||||
$r = q("SELECT `profile`.`uid` AS `profile_uid`, `profile`.* , `contact`.`avatar-date` AS picdate, `contact`.`addr`, `user`.* FROM `profile`
|
$r = q("SELECT `contact`.`id` AS `contact_id`, `profile`.`uid` AS `profile_uid`, `profile`.*,
|
||||||
INNER JOIN `contact` ON `contact`.`uid` = `profile`.`uid` INNER JOIN `user` ON `profile`.`uid` = `user`.`uid`
|
`contact`.`avatar-date` AS picdate, `contact`.`addr`, `user`.*
|
||||||
WHERE `user`.`nickname` = '%s' AND `profile`.`is-default` = 1 AND `contact`.`self` = 1 LIMIT 1",
|
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)
|
dbesc($nickname)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -770,7 +770,6 @@ function item_store($arr,$force_parent = false, $notify = false, $dontcache = fa
|
||||||
|
|
||||||
logger('item_store: ' . print_r($arr,true), LOGGER_DATA);
|
logger('item_store: ' . print_r($arr,true), LOGGER_DATA);
|
||||||
|
|
||||||
q("COMMIT;");
|
|
||||||
q("START TRANSACTION;");
|
q("START TRANSACTION;");
|
||||||
|
|
||||||
$r = dbq("INSERT INTO `item` (`"
|
$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_tags_from_item($current_post);
|
||||||
create_files_from_item($current_post);
|
create_files_from_item($current_post);
|
||||||
|
|
||||||
q("COMMIT");
|
|
||||||
|
|
||||||
// Only check for notifications on start posts
|
// Only check for notifications on start posts
|
||||||
if ($arr['parent-uri'] === $arr['uri']) {
|
if ($arr['parent-uri'] === $arr['uri']) {
|
||||||
add_thread($current_post);
|
add_thread($current_post);
|
||||||
|
q("COMMIT");
|
||||||
|
|
||||||
|
add_shadow_thread($current_post);
|
||||||
} else {
|
} else {
|
||||||
update_thread($parent_id);
|
update_thread($parent_id);
|
||||||
|
q("COMMIT");
|
||||||
|
|
||||||
add_shadow_entry($arr);
|
add_shadow_entry($arr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -813,7 +813,8 @@ class ostatus {
|
||||||
WHERE `term`.`uid` = %d AND `term`.`otype` = %d AND `term`.`type` = %d AND `term`.`url` = '%s'))",
|
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));
|
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
|
$parents = q("SELECT `id`, `parent`, `uri`, `contact-id`, `type`, `verb`, `visible` FROM `item` WHERE `id` IN
|
||||||
(SELECT `parent` 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'))",
|
(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($owner["uid"]), intval($owner["id"]),
|
||||||
intval($authorid), dbesc($check_date),
|
intval($authorid), dbesc($check_date),
|
||||||
dbesc(NETWORK_OSTATUS), dbesc(NETWORK_DFRN));
|
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`
|
$items = q("SELECT `item`.*, `item`.`id` AS `item_id` FROM `item`
|
||||||
STRAIGHT_JOIN `thread` ON `thread`.`iid` = `item`.`parent`
|
STRAIGHT_JOIN `thread` ON `thread`.`iid` = `item`.`parent`
|
||||||
LEFT JOIN `item` AS `thritem` ON `thritem`.`uri`=`item`.`thr-parent` AND `thritem`.`uid`=`item`.`uid`
|
LEFT JOIN `item` AS `thritem` ON `thritem`.`uri`=`item`.`thr-parent` AND `thritem`.`uid`=`item`.`uid`
|
||||||
|
|
|
@ -1,32 +1,45 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
// Session management functions. These provide database storage of PHP
|
// Session management functions. These provide database storage of PHP
|
||||||
// session info.
|
// session info.
|
||||||
|
|
||||||
|
require_once('include/cache.php');
|
||||||
|
|
||||||
$session_exists = 0;
|
$session_exists = 0;
|
||||||
$session_expire = 180000;
|
$session_expire = 180000;
|
||||||
|
|
||||||
if(! function_exists('ref_session_open')) {
|
|
||||||
function ref_session_open($s, $n) {
|
function ref_session_open($s, $n) {
|
||||||
return true;
|
return true;
|
||||||
}}
|
}
|
||||||
|
|
||||||
if(! function_exists('ref_session_read')) {
|
|
||||||
function ref_session_read($id) {
|
function ref_session_read($id) {
|
||||||
global $session_exists;
|
global $session_exists;
|
||||||
if(x($id))
|
|
||||||
|
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));
|
$r = q("SELECT `data` FROM `session` WHERE `sid`= '%s'", dbesc($id));
|
||||||
|
|
||||||
if(count($r)) {
|
if (dbm::is_result($r)) {
|
||||||
$session_exists = true;
|
$session_exists = true;
|
||||||
return $r[0]['data'];
|
return $r[0]['data'];
|
||||||
} else {
|
} else {
|
||||||
logger("no data for session $id", LOGGER_TRACE);
|
logger("no data for session $id", LOGGER_TRACE);
|
||||||
}
|
}
|
||||||
return '';
|
|
||||||
}}
|
|
||||||
|
|
||||||
if(! function_exists('ref_session_write')) {
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
function ref_session_write($id, $data) {
|
function ref_session_write($id, $data) {
|
||||||
global $session_exists, $session_expire;
|
global $session_exists, $session_expire;
|
||||||
|
|
||||||
|
@ -37,6 +50,12 @@ function ref_session_write ($id,$data) {
|
||||||
$expire = time() + $session_expire;
|
$expire = time() + $session_expire;
|
||||||
$default_expire = time() + 300;
|
$default_expire = time() + 300;
|
||||||
|
|
||||||
|
$memcache = cache::memcache();
|
||||||
|
if (is_object($memcache)) {
|
||||||
|
$memcache->set(get_app()->get_hostname().":session:".$id, $data, MEMCACHE_COMPRESSED, $expire);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if ($session_exists) {
|
if ($session_exists) {
|
||||||
$r = q("UPDATE `session`
|
$r = q("UPDATE `session`
|
||||||
SET `data` = '%s'
|
SET `data` = '%s'
|
||||||
|
@ -53,24 +72,30 @@ function ref_session_write ($id,$data) {
|
||||||
dbesc($id), dbesc($default_expire), dbesc($data));
|
dbesc($id), dbesc($default_expire), dbesc($data));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}}
|
}
|
||||||
|
|
||||||
if(! function_exists('ref_session_close')) {
|
|
||||||
function ref_session_close() {
|
function ref_session_close() {
|
||||||
return true;
|
return true;
|
||||||
}}
|
}
|
||||||
|
|
||||||
if(! function_exists('ref_session_destroy')) {
|
|
||||||
function ref_session_destroy($id) {
|
function ref_session_destroy($id) {
|
||||||
q("DELETE FROM `session` WHERE `sid` = '%s'", dbesc($id));
|
$memcache = cache::memcache();
|
||||||
return true;
|
|
||||||
}}
|
if (is_object($memcache)) {
|
||||||
|
$memcache->delete(get_app()->get_hostname().":session:".$id);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
q("DELETE FROM `session` WHERE `sid` = '%s'", dbesc($id));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if(! function_exists('ref_session_gc')) {
|
|
||||||
function ref_session_gc($expire) {
|
function ref_session_gc($expire) {
|
||||||
q("DELETE FROM `session` WHERE `expire` < %d", dbesc(time()));
|
q("DELETE FROM `session` WHERE `expire` < %d", dbesc(time()));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}}
|
}
|
||||||
|
|
||||||
$gc_probability = 50;
|
$gc_probability = 50;
|
||||||
|
|
||||||
|
@ -78,7 +103,8 @@ ini_set('session.gc_probability', $gc_probability);
|
||||||
ini_set('session.use_only_cookies', 1);
|
ini_set('session.use_only_cookies', 1);
|
||||||
ini_set('session.cookie_httponly', 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',
|
session_set_save_handler('ref_session_open', 'ref_session_close',
|
||||||
'ref_session_read', 'ref_session_write',
|
'ref_session_read', 'ref_session_write',
|
||||||
'ref_session_destroy', 'ref_session_gc');
|
'ref_session_destroy', 'ref_session_gc');
|
||||||
|
}
|
||||||
|
|
|
@ -1075,8 +1075,14 @@ function all_friends($uid,$cid,$start = 0, $limit = 80) {
|
||||||
|
|
||||||
function suggestion_query($uid, $start = 0, $limit = 80) {
|
function suggestion_query($uid, $start = 0, $limit = 80) {
|
||||||
|
|
||||||
if(! $uid)
|
if (!$uid) {
|
||||||
return array();
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
|
$list = Cache::get("suggestion_query:".$uid.":".$start.":".$limit);
|
||||||
|
if (!is_null($list)) {
|
||||||
|
return $list;
|
||||||
|
}
|
||||||
|
|
||||||
$network = array(NETWORK_DFRN);
|
$network = array(NETWORK_DFRN);
|
||||||
|
|
||||||
|
@ -1087,9 +1093,10 @@ function suggestion_query($uid, $start = 0, $limit = 80) {
|
||||||
$network[] = NETWORK_OSTATUS;
|
$network[] = NETWORK_OSTATUS;
|
||||||
|
|
||||||
$sql_network = implode("', '", $network);
|
$sql_network = implode("', '", $network);
|
||||||
//$sql_network = "'".$sql_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
|
$r = q("SELECT count(glink.gcid) as `total`, gcontact.* from gcontact
|
||||||
INNER JOIN `glink` ON `glink`.`gcid` = `gcontact`.`id`
|
INNER JOIN `glink` ON `glink`.`gcid` = `gcontact`.`id`
|
||||||
where uid = %d and not gcontact.nurl in ( select nurl from contact where uid = %d )
|
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)
|
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;
|
return $r;
|
||||||
|
}
|
||||||
|
|
||||||
$r2 = q("SELECT gcontact.* FROM gcontact
|
$r2 = q("SELECT gcontact.* FROM gcontact
|
||||||
INNER JOIN `glink` ON `glink`.`gcid` = `gcontact`.`id`
|
INNER JOIN `glink` ON `glink`.`gcid` = `gcontact`.`id`
|
||||||
|
@ -1138,6 +1147,7 @@ function suggestion_query($uid, $start = 0, $limit = 80) {
|
||||||
while (sizeof($list) > ($limit))
|
while (sizeof($list) > ($limit))
|
||||||
array_pop($list);
|
array_pop($list);
|
||||||
|
|
||||||
|
Cache::set("suggestion_query:".$uid.":".$start.":".$limit, $list, CACHE_FIVE_MINUTES);
|
||||||
return $list;
|
return $list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,42 +18,61 @@ function add_thread($itemid, $onlyshadow = false) {
|
||||||
.implode("', '", array_values($item))
|
.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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// is it already a copy?
|
function add_shadow_thread($itemid) {
|
||||||
if (($itemid == 0) OR ($item['uid'] == 0))
|
$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;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$item = $items[0];
|
||||||
|
|
||||||
|
// is it already a copy?
|
||||||
|
if (($itemid == 0) OR ($item['uid'] == 0)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Is it a visible public post?
|
// 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;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// is it an entry from a connector? Only add an entry for natively connected networks
|
// 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;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Only do these checks if the post isn't a wall post
|
// Only do these checks if the post isn't a wall post
|
||||||
if (!$item["wall"]) {
|
if (!$item["wall"]) {
|
||||||
// Check, if hide-friends is activated - then don't do a shadow entry
|
// 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`",
|
$r = q("SELECT `hide-friends` FROM `profile` WHERE `is-default` AND `uid` = %d AND NOT `hide-friends`",
|
||||||
$item['uid']);
|
$item['uid']);
|
||||||
if (!count($r))
|
|
||||||
|
if (!dbm::is_result($r)) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Check if the contact is hidden or blocked
|
// Check if the contact is hidden or blocked
|
||||||
$r = q("SELECT `id` FROM `contact` WHERE NOT `hidden` AND NOT `blocked` AND `id` = %d",
|
$r = q("SELECT `id` FROM `contact` WHERE NOT `hidden` AND NOT `blocked` AND `id` = %d",
|
||||||
$item['contact-id']);
|
$item['contact-id']);
|
||||||
if (!count($r))
|
|
||||||
|
if (!dbm::is_result($r)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Only add a shadow, if the profile isn't hidden
|
// Only add a shadow, if the profile isn't hidden
|
||||||
$r = q("SELECT `uid` FROM `user` where `uid` = %d AND NOT `hidewall`", $item['uid']);
|
$r = q("SELECT `uid` FROM `user` where `uid` = %d AND NOT `hidewall`", $item['uid']);
|
||||||
if (!count($r))
|
if (!dbm::is_result($r)) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
$item = q("SELECT * FROM `item` WHERE `id` = %d",
|
$item = q("SELECT * FROM `item` WHERE `id` = %d", intval($itemid));
|
||||||
intval($itemid));
|
|
||||||
|
|
||||||
if (count($item) AND ($item[0]["allow_cid"] == '') AND ($item[0]["allow_gid"] == '') AND
|
if (count($item) AND ($item[0]["allow_cid"] == '') AND ($item[0]["allow_gid"] == '') AND
|
||||||
($item[0]["deny_cid"] == '') AND ($item[0]["deny_gid"] == '')) {
|
($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",
|
$r = q("SELECT `id` FROM `item` WHERE `uri` = '%s' AND `uid` = 0 LIMIT 1",
|
||||||
dbesc($item['uri']));
|
dbesc($item['uri']));
|
||||||
|
|
||||||
if (!$r) {
|
if (!dbm::is_result($r)) {
|
||||||
// Preparing public shadow (removing user specific data)
|
// Preparing public shadow (removing user specific data)
|
||||||
require_once("include/items.php");
|
require_once("include/items.php");
|
||||||
require_once("include/Contact.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);
|
$item[0]['contact-id'] = get_contact($item[0]['author-link'], 0);
|
||||||
$public_shadow = item_store($item[0], false, false, true);
|
$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));
|
logger("update_threads: fetched messages: ".count($messages));
|
||||||
|
|
||||||
while ($message = $db->qfetch())
|
while ($message = $db->qfetch()) {
|
||||||
add_thread($message["id"]);
|
add_thread($message["id"]);
|
||||||
|
add_shadow_thread($message["id"]);
|
||||||
|
}
|
||||||
$db->qclose();
|
$db->qclose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -227,7 +248,7 @@ function update_shadow_copy() {
|
||||||
|
|
||||||
logger("fetched messages: ".count($messages));
|
logger("fetched messages: ".count($messages));
|
||||||
while ($message = $db->qfetch())
|
while ($message = $db->qfetch())
|
||||||
add_thread($message["iid"], true);
|
add_shadow_thread($message["iid"]);
|
||||||
|
|
||||||
$db->qclose();
|
$db->qclose();
|
||||||
}
|
}
|
||||||
|
|
|
@ -788,7 +788,6 @@ function item_post(&$a) {
|
||||||
} else
|
} else
|
||||||
$post_id = 0;
|
$post_id = 0;
|
||||||
|
|
||||||
q("COMMIT;");
|
|
||||||
q("START TRANSACTION;");
|
q("START TRANSACTION;");
|
||||||
|
|
||||||
$r = q("INSERT INTO `item` (`guid`, `extid`, `uid`,`type`,`wall`,`gravity`, `network`, `contact-id`,
|
$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_tags_from_item($post_id);
|
||||||
create_files_from_item($post_id);
|
create_files_from_item($post_id);
|
||||||
|
|
||||||
|
if ($post_id == $parent) {
|
||||||
|
add_thread($post_id);
|
||||||
q("COMMIT");
|
q("COMMIT");
|
||||||
|
|
||||||
if ($post_id == $parent)
|
add_shadow_thread($post_id);
|
||||||
add_thread($post_id);
|
} else {
|
||||||
else {
|
|
||||||
update_thread($parent, true);
|
update_thread($parent, true);
|
||||||
|
q("COMMIT");
|
||||||
|
|
||||||
// Insert an item entry for UID=0 for global entries
|
// Insert an item entry for UID=0 for global entries
|
||||||
// We have to remove or change some data before that,
|
// We have to remove or change some data before that,
|
||||||
|
|
|
@ -53,12 +53,18 @@ function photos_init(&$a) {
|
||||||
|
|
||||||
$sql_extra = permissions_sql($a->data['user']['uid']);
|
$sql_extra = permissions_sql($a->data['user']['uid']);
|
||||||
|
|
||||||
|
$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'
|
$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",
|
$sql_extra GROUP BY `album` ORDER BY `created` DESC",
|
||||||
intval($a->data['user']['uid']),
|
intval($a->data['user']['uid']),
|
||||||
dbesc('Contact Photos'),
|
dbesc('Contact Photos'),
|
||||||
dbesc( t('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);
|
$albums_visible = ((intval($a->data['user']['hidewall']) && (! local_user()) && (! remote_user())) ? false : true);
|
||||||
|
|
||||||
|
|
|
@ -282,16 +282,20 @@ function profile_content(&$a, $update = 0) {
|
||||||
$pager_sql = sprintf(" LIMIT %d, %d ",intval($a->pager['start']), intval($a->pager['itemspage']));
|
$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`
|
$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`
|
FROM `thread`
|
||||||
$sql_post_table INNER JOIN `contact` ON `contact`.`id` = `thread`.`contact-id`
|
STRAIGHT_JOIN `item` ON `item`.`id` = `thread`.`iid`
|
||||||
AND `contact`.`blocked` = 0 AND `contact`.`pending` = 0
|
$sql_post_table
|
||||||
WHERE `thread`.`uid` = %d AND `thread`.`visible` = 1 AND `thread`.`deleted` = 0
|
STRAIGHT_JOIN `contact` ON `contact`.`id` = `thread`.`contact-id`
|
||||||
and `thread`.`moderated` = 0
|
AND NOT `contact`.`blocked` AND NOT `contact`.`pending`
|
||||||
AND `thread`.`wall` = 1
|
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
|
$sql_extra $sql_extra2
|
||||||
ORDER BY `thread`.`created` DESC $pager_sql",
|
ORDER BY `thread`.`created` DESC $pager_sql",
|
||||||
intval($a->profile['profile_uid'])
|
intval($a->profile['profile_uid']),
|
||||||
|
intval($a->profile['contact_id'])
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue