diff options
Diffstat (limited to 'Zotlabs')
-rw-r--r-- | Zotlabs/Lib/PConfig.php | 107 | ||||
-rw-r--r-- | Zotlabs/Module/Network.php | 6 | ||||
-rw-r--r-- | Zotlabs/Module/Photo.php | 36 | ||||
-rw-r--r-- | Zotlabs/Module/Ping.php | 2 | ||||
-rw-r--r-- | Zotlabs/Update/_1225.php | 26 |
5 files changed, 145 insertions, 32 deletions
diff --git a/Zotlabs/Lib/PConfig.php b/Zotlabs/Lib/PConfig.php index ec0792ce1..b9384cf6b 100644 --- a/Zotlabs/Lib/PConfig.php +++ b/Zotlabs/Lib/PConfig.php @@ -57,6 +57,7 @@ class PConfig { \App::$config[$uid][$c]['config_loaded'] = true; } \App::$config[$uid][$c][$k] = $rr['v']; + \App::$config[$uid][$c]['pcfgud:'.$k] = $rr['updated']; } } } @@ -113,7 +114,7 @@ class PConfig { * The value to store * @return mixed Stored $value or false */ - static public function Set($uid, $family, $key, $value) { + static public function Set($uid, $family, $key, $value, $updated=NULL) { // this catches subtle errors where this function has been called // with local_channel() when not logged in (which returns false) @@ -130,29 +131,74 @@ class PConfig { $dbvalue = ((is_array($value)) ? serialize($value) : $value); $dbvalue = ((is_bool($dbvalue)) ? intval($dbvalue) : $dbvalue); + if (! $updated) { + $updated = datetime_convert(); + } + + $hash = hash('sha256',$family.':'.$key); + + if (self::Get($uid, 'hz_delpconfig', $hash) !== false) { + if (Get($uid, 'hz_delpconfig', $hash) > $updated) { + logger('Refusing to update pconfig with outdated info (Item deleted more recently).', LOGGER_NORMAL, LOG_ERR); + return self::Get($uid,$family,$key); + } else { + self::Delete($uid,'hz_delpconfig',$hash); + } + } + if(self::Get($uid, $family, $key) === false) { if(! array_key_exists($uid, \App::$config)) \App::$config[$uid] = array(); if(! array_key_exists($family, \App::$config[$uid])) \App::$config[$uid][$family] = array(); - $ret = q("INSERT INTO pconfig ( uid, cat, k, v ) VALUES ( %d, '%s', '%s', '%s' ) ", + + $ret = q("INSERT INTO pconfig ( uid, cat, k, v, updated ) VALUES ( %d, '%s', '%s', '%s', '%s' ) ", intval($uid), dbesc($family), dbesc($key), - dbesc($dbvalue) + dbesc($dbvalue), + dbesc($updated) ); + + // There is a possible race condition if another process happens + // to insert something after this thread has Loaded and now. We should + // at least make a note of it if it happens. + + if (!$ret) { + logger("Error: Insert to pconfig failed.",LOGGER_NORMAL, LOG_ERR); + } + + \App::$config[$uid][$family]['pcfgud:'.$key] = $updated; + } else { + $new = (\App::$config[$uid][$family]['pcfgud:'.$key] < $updated); - $ret = q("UPDATE pconfig SET v = '%s' WHERE uid = %d and cat = '%s' AND k = '%s'", - dbesc($dbvalue), - intval($uid), - dbesc($family), - dbesc($key) - ); + if ($new) { + + // @NOTE There is still a possible race condition under limited circumstances + // where a value will be updated by another thread with more current data than + // we have. At this point there is no easy way to test for it, so we update + // and hope for the best. + + $ret = q("UPDATE pconfig SET v = '%s', updated = '%s' WHERE uid = %d and cat = '%s' AND k = '%s' ", + dbesc($dbvalue), + dbesc($updated), + intval($uid), + dbesc($family), + dbesc($key) + ); + + \App::$config[$uid][$family]['pcfgud:'.$key] = $updated; + + } else { + logger('Refusing to update pconfig with outdated info.', LOGGER_NORMAL, LOG_ERR); + return self::Get($uid, $family, $key); + } } + // keep a separate copy for all variables which were // set in the life of this page. We need this to // synchronise channel clones. @@ -163,7 +209,11 @@ class PConfig { \App::$config[$uid]['transient'][$family] = array(); \App::$config[$uid][$family][$key] = $value; - \App::$config[$uid]['transient'][$family][$key] = $value; + + if ($new) { + \App::$config[$uid]['transient'][$family][$key] = $value; + \App::$config[$uid]['transient'][$family]['pcfgud:'.$key] = $updated; + } if($ret) return $value; @@ -186,18 +236,29 @@ class PConfig { * The configuration key to delete * @return mixed */ - static public function Delete($uid, $family, $key) { + static public function Delete($uid, $family, $key, $updated = NULL) { if(is_null($uid) || $uid === false) return false; + $updated = ($updated) ? $updated : datetime_convert(); + + $newer = (\App::$config[$uid][$family]['pcfgud:'.$key] < $updated); + + if (! $newer) { + logger('Refusing to delete pconfig with outdated delete request.', LOGGER_NORMAL, LOG_ERR); + return false; + } + $ret = false; - if(array_key_exists($uid,\App::$config) - && is_array(\App::$config['uid']) - && array_key_exists($family,\App::$config['uid']) - && array_key_exists($key, \App::$config[$uid][$family])) + if (isset(\App::$config[$uid][$family][$key])) { unset(\App::$config[$uid][$family][$key]); + } + + if (isset(\App::$config[$uid][$family]['pcfgud:'.$key])) { + unset(\App::$config[$uid][$family]['pcfgud:'.$key]); + } $ret = q("DELETE FROM pconfig WHERE uid = %d AND cat = '%s' AND k = '%s'", intval($uid), @@ -205,6 +266,22 @@ class PConfig { dbesc($key) ); + if ($family != 'hz_delpconfig') { + $hash = hash('sha256',$family.':'.$key); + set_pconfig($uid,'hz_delpconfig',$hash,$updated); + } + + // Synchronize delete with clones. + + if(! array_key_exists('transient', \App::$config[$uid])) + \App::$config[$uid]['transient'] = array(); + if(! array_key_exists($family, \App::$config[$uid]['transient'])) + \App::$config[$uid]['transient'][$family] = array(); + + if ($new) { + \App::$config[$uid]['transient'][$family]['pcfgdel:'.$key] = $updated; + } + return $ret; } diff --git a/Zotlabs/Module/Network.php b/Zotlabs/Module/Network.php index 294e11c52..b93faa612 100644 --- a/Zotlabs/Module/Network.php +++ b/Zotlabs/Module/Network.php @@ -258,6 +258,10 @@ class Network extends \Zotlabs\Web\Controller { } elseif($pf && $unseen && $nouveau) { + $vnotify = get_pconfig(local_channel(), 'system', 'vnotify'); + if(! ($vnotify & VNOTIFY_LIKE)) + $likes_sql = " AND verb NOT IN ('" . dbesc(ACTIVITY_LIKE) . "', '" . dbesc(ACTIVITY_DISLIKE) . "') "; + // This is for nouveau view public forum cid queries (if a forum notification is clicked) $p = q("SELECT oid AS parent FROM term WHERE uid = %d AND ttype = %d AND term = '%s'", intval(local_channel()), @@ -269,7 +273,7 @@ class Network extends \Zotlabs\Web\Controller { if($p_str) $p_sql = " OR item.parent IN ( $p_str ) "; - $sql_extra = " AND ( owner_xchan = '" . protect_sprintf(dbesc($cid_r[0]['abook_xchan'])) . "' OR owner_xchan = '" . protect_sprintf(dbesc($cid_r[0]['abook_xchan'])) . "' $p_sql ) AND item_unseen = 1 "; + $sql_extra = " AND ( owner_xchan = '" . protect_sprintf(dbesc($cid_r[0]['abook_xchan'])) . "' OR owner_xchan = '" . protect_sprintf(dbesc($cid_r[0]['abook_xchan'])) . "' $p_sql ) AND item_unseen = 1 $likes_sql "; } else { // This is for threaded view cid queries (e.g. if a forum is selected from the forum filter) diff --git a/Zotlabs/Module/Photo.php b/Zotlabs/Module/Photo.php index 8efc00707..d76fca278 100644 --- a/Zotlabs/Module/Photo.php +++ b/Zotlabs/Module/Photo.php @@ -33,25 +33,24 @@ class Photo extends \Zotlabs\Web\Controller { $observer_xchan = get_observer_hash(); - $default = z_root() . '/' . get_default_profile_photo(); - if(isset($type)) { /** * Profile photos - Access controls on default profile photos are not honoured since they need to be exchanged with remote sites. * */ - + + $default = get_default_profile_photo(); + if($type === 'profile') { switch($res) { - case 'm': $resolution = 5; - $default = z_root() . '/' . get_default_profile_photo(80); + $default = get_default_profile_photo(80); break; case 's': $resolution = 6; - $default = z_root() . '/' . get_default_profile_photo(48); + $default = get_default_profile_photo(48); break; case 'l': default: @@ -60,6 +59,8 @@ class Photo extends \Zotlabs\Web\Controller { } } + $modified = filemtime($default); + $default = z_root() . '/' . $default; $uid = $person; $d = [ 'imgscale' => $resolution, 'channel_id' => $uid, 'default' => $default, 'data' => '', 'mimetype' => '' ]; @@ -78,6 +79,7 @@ class Photo extends \Zotlabs\Web\Controller { intval(PHOTO_PROFILE) ); if($r) { + $modified = strtotime($r[0]['edited']); $data = dbunescbin($r[0]['content']); $mimetype = $r[0]['mimetype']; } @@ -164,9 +166,9 @@ class Photo extends \Zotlabs\Web\Controller { if($exists && $allowed) { $data = dbunescbin($e[0]['content']); $mimetype = $e[0]['mimetype']; - if(intval($e[0]['os_storage'])) { + $modified = strtotime($e[0]['edited']); + if(intval($e[0]['os_storage'])) $streaming = $data; - } } else { if(! $allowed) { @@ -183,7 +185,6 @@ class Photo extends \Zotlabs\Web\Controller { if(! isset($data)) { if(isset($resolution)) { switch($resolution) { - case 4: $data = fetch_image_from_url(z_root() . '/' . get_default_profile_photo(),$mimetype); break; @@ -210,10 +211,14 @@ class Photo extends \Zotlabs\Web\Controller { } } + // @FIXME Seems never invoked // Writing in cachefile - if (isset($cachefile) && $cachefile != '') + if (isset($cachefile) && $cachefile != '') { file_put_contents($cachefile, $data); - + $modified = filemtime($cachefile); + } + + if(function_exists('header_remove')) { header_remove('Pragma'); header_remove('pragma'); @@ -240,15 +245,16 @@ class Photo extends \Zotlabs\Web\Controller { // This has performance considerations but we highly recommend you // leave it alone. - $cache = get_config('system','photo_cache_time'); - if(! $cache) - $cache = (3600 * 24); // 1 day - + $cache = get_config('system','photo_cache_time', 86400); // 1 day by default + header("Expires: " . gmdate("D, d M Y H:i:s", time() + $cache) . " GMT"); header("Cache-Control: max-age=" . $cache); } + header("Last-Modified: " . gmdate("D, d M Y H:i:s", $modified) . " GMT"); + header("Content-Length: " . strlen($data)); + // If it's a file resource, stream it. if($streaming && $channel) { diff --git a/Zotlabs/Module/Ping.php b/Zotlabs/Module/Ping.php index cf5b2e004..f660c3b55 100644 --- a/Zotlabs/Module/Ping.php +++ b/Zotlabs/Module/Ping.php @@ -650,7 +650,7 @@ class Ping extends \Zotlabs\Web\Controller { $p_sql = (($p_str) ? "OR parent IN ( $p_str )" : ''); $r = q("select count(id) as unseen from item - where uid = %d and ( owner_xchan = '%s' OR author_xchan = '%s' $p_sql ) and item_unseen = 1 $item_normal", + where uid = %d and ( owner_xchan = '%s' OR author_xchan = '%s' $p_sql ) and item_unseen = 1 $item_normal $sql_extra", intval(local_channel()), dbesc($forums[$x]['xchan_hash']), dbesc($forums[$x]['xchan_hash']) diff --git a/Zotlabs/Update/_1225.php b/Zotlabs/Update/_1225.php new file mode 100644 index 000000000..a7d866154 --- /dev/null +++ b/Zotlabs/Update/_1225.php @@ -0,0 +1,26 @@ +<?php + +namespace Zotlabs\Update; + +class _1225 { + + function run() { + + if(ACTIVE_DBTYPE == DBTYPE_POSTGRES) { + $r1 = q("ALTER TABLE pconfig ADD updated timestamp NOT NULL DEFAULT '0001-01-01 00:00:00' "); + $r2 = q("create index \"pconfig_updated_idx\" on pconfig (\"updated\")"); + + $r = ($r1 && $r2); + } + else { + $r = q("ALTER TABLE `pconfig` ADD `updated` datetime NOT NULL DEFAULT '0001-01-01 00:00:00' , + ADD INDEX `pconfig_updated` (`updated`)"); + } + + if($r) + return UPDATE_SUCCESS; + return UPDATE_FAILED; + + } + +} |