1
0
Fork 0

This merge brings back dbm::is_result() where I could find it.

Merge branch 'develop' of github.com:friendica/friendica into rhaeder-develop

Signed-off-by: Roland Haeder <roland@mxchange.org>
This commit is contained in:
Roland Häder 2016-09-18 23:21:18 +02:00
commit c825cc8d0d
No known key found for this signature in database
GPG key ID: B72F8185C6C7BD78
691 changed files with 128914 additions and 43052 deletions

View file

@ -45,10 +45,10 @@ function user_remove($uid) {
// don't delete yet, will be done later when contacts have deleted my stuff
// q("DELETE FROM `user` WHERE `uid` = %d", intval($uid));
q("UPDATE `user` SET `account_removed` = 1, `account_expires_on` = UTC_TIMESTAMP() WHERE `uid` = %d", intval($uid));
proc_run('php', "include/notifier.php", "removeme", $uid);
proc_run(PRIORITY_HIGH, "include/notifier.php", "removeme", $uid);
// Send an update to the directory
proc_run('php', "include/directory.php", $r[0]['url']);
proc_run(PRIORITY_LOW, "include/directory.php", $r[0]['url']);
if($uid == local_user()) {
unset($_SESSION['authenticated']);
@ -192,72 +192,97 @@ function unmark_for_death($contact) {
);
}}
function get_contact_details_by_url($url, $uid = -1) {
/**
* @brief Get contact data for a given profile link
*
* The function looks at several places (contact table and gcontact table) for the contact
*
* @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
*/
function get_contact_details_by_url($url, $uid = -1, $default = array()) {
if ($uid == -1)
$uid = local_user();
$r = q("SELECT `id` AS `gid`, `url`, `name`, `nick`, `addr`, `photo`, `location`, `about`, `keywords`, `gender`, `community`, `network` FROM `gcontact` WHERE `nurl` = '%s' LIMIT 1",
dbesc(normalise_link($url)));
if ($r) {
$profile = $r[0];
if ((($profile["addr"] == "") OR ($profile["name"] == "")) AND
in_array($profile["network"], array(NETWORK_DFRN, NETWORK_DIASPORA, NETWORK_OSTATUS)))
proc_run('php',"include/update_gcontact.php", $profile["gid"]);
}
// Fetching further contact data from the contact table
$r = q("SELECT `id`, `uid`, `url`, `network`, `name`, `nick`, `addr`, `location`, `about`, `keywords`, `gender`, `photo`, `thumb`, `addr`, `forum`, `prv`, `bd`, `self` FROM `contact` WHERE `nurl` = '%s' AND `uid` = %d AND `network` IN ('%s', '')",
dbesc(normalise_link($url)), intval($uid), dbesc($profile["network"]));
if (!count($r) AND !isset($profile))
$r = q("SELECT `id`, `uid`, `url`, `network`, `name`, `nick`, `addr`, `location`, `about`, `keywords`, `gender`, `photo`, `thumb`, `addr`, `forum`, `prv`, `bd`, `self` FROM `contact` WHERE `nurl` = '%s' AND `uid` = %d",
// 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`,
`keywords`, `gender`, `photo`, `thumb`, `micro`, `forum`, `prv`, (`forum` | `prv`) AS `community`, `bd` AS `birthday`, `self`
FROM `contact` WHERE `nurl` = '%s' AND `uid` = %d",
dbesc(normalise_link($url)), intval($uid));
if (!count($r) AND !isset($profile))
$r = q("SELECT `id`, `uid`, `url`, `network`, `name`, `nick`, `addr`, `location`, `about`, `keywords`, `gender`, `photo`, `thumb`, `addr`, `forum`, `prv`, `bd` FROM `contact` WHERE `nurl` = '%s' AND `uid` = 0",
dbesc(normalise_link($url)));
// Fetch the data from the contact table with "uid=0" (which is filled automatically)
if (!$r)
$r = q("SELECT `id`, 0 AS `cid`, `id` AS `zid`, 0 AS `gid`, `uid`, `url`, `nurl`, `alias`, `network`, `name`, `nick`, `addr`, `location`, `about`,
`keywords`, `gender`, `photo`, `thumb`, `micro`, `forum`, `prv`, (`forum` | `prv`) AS `community`, `bd` AS `birthday`, 0 AS `self`
FROM `contact` WHERE `nurl` = '%s' AND `uid` = 0",
dbesc(normalise_link($url)));
// Fetch the data from the gcontact table
if (!$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`,
`keywords`, `gender`, `photo`, `photo` AS `thumb`, `photo` AS `micro`, `community` AS `forum`, 0 AS `prv`, `community`, `birthday`, 0 AS `self`
FROM `gcontact` WHERE `nurl` = '%s'",
dbesc(normalise_link($url)));
if ($r) {
if (!isset($profile["url"]) AND $r[0]["url"])
$profile["url"] = $r[0]["url"];
if (!isset($profile["name"]) AND $r[0]["name"])
$profile["name"] = $r[0]["name"];
if (!isset($profile["nick"]) AND $r[0]["nick"])
$profile["nick"] = $r[0]["nick"];
if (!isset($profile["addr"]) AND $r[0]["addr"])
$profile["addr"] = $r[0]["addr"];
if ((!isset($profile["photo"]) OR $r[0]["self"]) AND $r[0]["photo"])
$profile["photo"] = $r[0]["photo"];
if (!isset($profile["location"]) AND $r[0]["location"])
$profile["location"] = $r[0]["location"];
if (!isset($profile["about"]) AND $r[0]["about"])
$profile["about"] = $r[0]["about"];
if (!isset($profile["keywords"]) AND $r[0]["keywords"])
$profile["keywords"] = $r[0]["keywords"];
if (!isset($profile["gender"]) AND $r[0]["gender"])
$profile["gender"] = $r[0]["gender"];
if (isset($r[0]["forum"]) OR isset($r[0]["prv"]))
$profile["community"] = ($r[0]["forum"] OR $r[0]["prv"]);
if (!isset($profile["network"]) AND $r[0]["network"])
$profile["network"] = $r[0]["network"];
if (!isset($profile["addr"]) AND $r[0]["addr"])
$profile["addr"] = $r[0]["addr"];
if (!isset($profile["bd"]) AND $r[0]["bd"])
$profile["bd"] = $r[0]["bd"];
if (isset($r[0]["thumb"]))
$profile["thumb"] = $r[0]["thumb"];
if ($r[0]["uid"] == 0)
$profile["cid"] = 0;
else
$profile["cid"] = $r[0]["id"];
} else
$profile["cid"] = 0;
// 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"] != "0000-00-00") {
$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"] = "0000-00-00";
} else
$profile = $default;
if (($profile["photo"] == "") AND isset($default["photo"]))
$profile["photo"] = $default["photo"];
if (($profile["name"] == "") AND isset($default["name"]))
$profile["name"] = $default["name"];
if (($profile["network"] == "") AND isset($default["network"]))
$profile["network"] = $default["network"];
if (($profile["thumb"] == "") AND isset($profile["photo"]))
$profile["thumb"] = $profile["photo"];
if (($profile["micro"] == "") AND isset($profile["thumb"]))
$profile["micro"] = $profile["thumb"];
if ((($profile["addr"] == "") OR ($profile["name"] == "")) AND ($profile["gid"] != 0) AND
in_array($profile["network"], array(NETWORK_DFRN, NETWORK_DIASPORA, NETWORK_OSTATUS)))
proc_run(PRIORITY_LOW, "include/update_gcontact.php", $profile["gid"]);
// Show contact details of Diaspora contacts only if connected
if (($profile["cid"] == 0) AND ($profile["network"] == NETWORK_DIASPORA)) {
$profile["location"] = "";
$profile["about"] = "";
$profile["gender"] = "";
$profile["birthday"] = "0000-00-00";
}
return($profile);
@ -368,7 +393,7 @@ function random_profile() {
ORDER BY rand() LIMIT 1",
dbesc(NETWORK_DFRN));
if(dba::is_result($r))
if(dbm::is_result($r))
return dirname($r[0]['url']);
return '';
}
@ -438,8 +463,18 @@ function get_contact($url, $uid = 0) {
$data = probe_url($url);
// Does this address belongs to a valid network?
if (!in_array($data["network"], array(NETWORK_DFRN, NETWORK_OSTATUS, NETWORK_DIASPORA)))
return 0;
if (!in_array($data["network"], array(NETWORK_DFRN, NETWORK_OSTATUS, NETWORK_DIASPORA))) {
if ($uid != 0)
return 0;
// Get data from the gcontact table
$r = q("SELECT `name`, `nick`, `url`, `photo`, `addr`, `alias`, `network` FROM `gcontact` WHERE `nurl` = '%s'",
dbesc(normalise_link($url)));
if (!$r)
return 0;
$data = $r[0];
}
$url = $data["url"];
@ -477,6 +512,16 @@ function get_contact($url, $uid = 0) {
return 0;
$contactid = $contact[0]["id"];
// Update the newly created contact from data in the gcontact table
$r = q("SELECT `location`, `about`, `keywords`, `gender` FROM `gcontact` WHERE `nurl` = '%s'",
dbesc(normalise_link($data["url"])));
if ($r) {
logger("Update contact ".$data["url"]);
q("UPDATE `contact` SET `location` = '%s', `about` = '%s', `keywords` = '%s', `gender` = '%s' WHERE `id` = %d",
dbesc($r["location"]), dbesc($r["about"]), dbesc($r["keywords"]),
dbesc($r["gender"]), intval($contactid));
}
}
if ((count($contact) > 1) AND ($uid == 0) AND ($contactid != 0) AND ($url != ""))
@ -586,11 +631,11 @@ function posts_from_contact($a, $contact_id) {
$r = q("SELECT `item`.`uri`, `item`.*, `item`.`id` AS `item_id`,
`author-name` AS `name`, `owner-avatar` AS `photo`,
`owner-link` AS `url`, `owner-avatar` AS `thumb`
FROM `item` FORCE INDEX (`uid_contactid_created`)
FROM `item` FORCE INDEX (`uid_contactid_id`)
WHERE `item`.`uid` = %d AND `contact-id` = %d
AND `author-link` IN ('%s', '%s')
AND NOT `deleted` AND NOT `moderated` AND `visible`
ORDER BY `item`.`created` DESC LIMIT %d, %d",
ORDER BY `item`.`id` DESC LIMIT %d, %d",
intval(local_user()),
intval($contact_id),
dbesc(str_replace("https://", "http://", $contact["url"])),

236
include/Core/Config.php Normal file
View file

@ -0,0 +1,236 @@
<?php
namespace Friendica\Core;
/**
* @file include/Core/Config.php
*
* @brief Contains the class with methods for system configuration
*/
/**
* @brief Arbitrary sytem configuration storage
* Note:
* Please do not store booleans - convert to 0/1 integer values
* The Config::get() functions return boolean false for keys that are unset,
* and this could lead to subtle bugs.
*
* There are a few places in the code (such as the admin panel) where boolean
* configurations need to be fixed as of 10/08/2011.
*/
class Config {
/**
* @brief Loads all configuration values of family into a cached storage.
*
* All configuration values of the system are stored in global cache
* which is available under the global variable $a->config
*
* @param string $family
* The category of the configuration value
* @return void
*/
public static function load($family) {
global $a;
$r = q("SELECT `v`, `k` FROM `config` WHERE `cat` = '%s'", dbesc($family));
if(count($r)) {
foreach($r as $rr) {
$k = $rr['k'];
if ($family === 'config') {
$a->config[$k] = $rr['v'];
} else {
$a->config[$family][$k] = $rr['v'];
}
}
} else if ($family != 'config') {
// Negative caching
$a->config[$family] = "!<unset>!";
}
}
/**
* @brief Get a particular user's config variable given the category name
* ($family) and a key.
*
* Get a particular config value from the given category ($family)
* and the $key from a cached storage in $a->config[$uid].
* $instore is only used by the set_config function
* to determine if the key already exists in the DB
* If a key is found in the DB but doesn't exist in
* local config cache, pull it into the cache so we don't have
* to hit the DB again for this item.
*
* @param string $family
* The category of the configuration value
* @param string $key
* The configuration key to query
* @param mixed $default_value optional
* The value to return if key is not set (default: null)
* @param boolean $refresh optional
* If true the config is loaded from the db and not from the cache (default: false)
* @return mixed Stored value or null if it does not exist
*/
public static function get($family, $key, $default_value=null, $refresh = false) {
global $a;
if(! $instore) {
// Looking if the whole family isn't set
if(isset($a->config[$family])) {
if($a->config[$family] === '!<unset>!') {
return $default_value;
}
}
if(isset($a->config[$family][$key])) {
if($a->config[$family][$key] === '!<unset>!') {
return $default_value;
}
return $a->config[$family][$key];
}
}
// If APC is enabled then fetch the data from there, else try XCache
/*if (function_exists("apc_fetch") AND function_exists("apc_exists"))
if (apc_exists($family."|".$key)) {
$val = apc_fetch($family."|".$key);
$a->config[$family][$key] = $val;
if ($val === '!<unset>!')
return false;
else
return $val;
}
elseif (function_exists("xcache_fetch") AND function_exists("xcache_isset"))
if (xcache_isset($family."|".$key)) {
$val = xcache_fetch($family."|".$key);
$a->config[$family][$key] = $val;
if ($val === '!<unset>!')
return false;
else
return $val;
}
*/
$ret = q("SELECT `v` FROM `config` WHERE `cat` = '%s' AND `k` = '%s' LIMIT 1",
dbesc($family),
dbesc($key)
);
if(count($ret)) {
// manage array value
$val = (preg_match("|^a:[0-9]+:{.*}$|s", $ret[0]['v'])?unserialize( $ret[0]['v']):$ret[0]['v']);
$a->config[$family][$key] = $val;
// If APC is enabled then store the data there, else try XCache
/*if (function_exists("apc_store"))
apc_store($family."|".$key, $val, 600);
elseif (function_exists("xcache_set"))
xcache_set($family."|".$key, $val, 600);*/
return $val;
}
else {
$a->config[$family][$key] = '!<unset>!';
// If APC is enabled then store the data there, else try XCache
/*if (function_exists("apc_store"))
apc_store($family."|".$key, '!<unset>!', 600);
elseif (function_exists("xcache_set"))
xcache_set($family."|".$key, '!<unset>!', 600);*/
}
return $default_value;
}
/**
* @brief Sets a configuration value for system config
*
* Stores a config value ($value) in the category ($family) under the key ($key)
* for the user_id $uid.
*
* Note: Please do not store booleans - convert to 0/1 integer values!
*
* @param string $family
* The category of the configuration value
* @param string $key
* The configuration key to set
* @param string $value
* The value to store
* @return mixed Stored $value or false if the database update failed
*/
public static function set($family,$key,$value) {
global $a;
// If $a->config[$family] has been previously set to '!<unset>!', then
// $a->config[$family][$key] will evaluate to $a->config[$family][0], and
// $a->config[$family][$key] = $value will be equivalent to
// $a->config[$family][0] = $value[0] (this causes infuriating bugs),
// so unset the family before assigning a value to a family's key
if($a->config[$family] === '!<unset>!')
unset($a->config[$family]);
// manage array value
$dbvalue = (is_array($value)?serialize($value):$value);
$dbvalue = (is_bool($dbvalue) ? intval($dbvalue) : $dbvalue);
if(is_null(self::get($family,$key,null,true))) {
$a->config[$family][$key] = $value;
$ret = q("INSERT INTO `config` ( `cat`, `k`, `v` ) VALUES ( '%s', '%s', '%s' ) ",
dbesc($family),
dbesc($key),
dbesc($dbvalue)
);
if($ret)
return $value;
return $ret;
}
$ret = q("UPDATE `config` SET `v` = '%s' WHERE `cat` = '%s' AND `k` = '%s'",
dbesc($dbvalue),
dbesc($family),
dbesc($key)
);
$a->config[$family][$key] = $value;
// If APC is enabled then store the data there, else try XCache
/*if (function_exists("apc_store"))
apc_store($family."|".$key, $value, 600);
elseif (function_exists("xcache_set"))
xcache_set($family."|".$key, $value, 600);*/
if($ret)
return $value;
return $ret;
}
/**
* @brief Deletes the given key from the system configuration.
*
* Removes the configured value from the stored cache in $a->config
* and removes it from the database.
*
* @param string $family
* The category of the configuration value
* @param string $key
* The configuration key to delete
* @return mixed
*/
public static function delete($family,$key) {
global $a;
if(x($a->config[$family],$key))
unset($a->config[$family][$key]);
$ret = q("DELETE FROM `config` WHERE `cat` = '%s' AND `k` = '%s'",
dbesc($family),
dbesc($key)
);
// If APC is enabled then delete the data from there, else try XCache
/*if (function_exists("apc_delete"))
apc_delete($family."|".$key);
elseif (function_exists("xcache_unset"))
xcache_unset($family."|".$key);*/
return $ret;
}
}

222
include/Core/PConfig.php Normal file
View file

@ -0,0 +1,222 @@
<?php
namespace Friendica\Core;
/**
* @file include/Core/PConfig.php
* @brief contains the class with methods for the management
* of the user configuration
*/
/**
* @brief Management of user configuration storage
* Note:
* Please do not store booleans - convert to 0/1 integer values
* The PConfig::get() functions return boolean false for keys that are unset,
* and this could lead to subtle bugs.
*/
class PConfig {
/**
* @brief Loads all configuration values of a user's config family into a cached storage.
*
* All configuration values of the given user are stored in global cache
* which is available under the global variable $a->config[$uid].
*
* @param string $uid
* The user_id
* @param string $family
* The category of the configuration value
* @return void
*/
public static function load($uid,$family) {
global $a;
$r = q("SELECT `v`,`k` FROM `pconfig` WHERE `cat` = '%s' AND `uid` = %d",
dbesc($family),
intval($uid)
);
if(count($r)) {
foreach($r as $rr) {
$k = $rr['k'];
$a->config[$uid][$family][$k] = $rr['v'];
}
} else if ($family != 'config') {
// Negative caching
$a->config[$uid][$family] = "!<unset>!";
}
}
/**
* @brief Get a particular user's config variable given the category name
* ($family) and a key.
*
* Get a particular user's config value from the given category ($family)
* and the $key from a cached storage in $a->config[$uid].
*
* @param string $uid
* The user_id
* @param string $family
* The category of the configuration value
* @param string $key
* The configuration key to query
* @param mixed $default_value optional
* The value to return if key is not set (default: null)
* @param boolean $refresh optional
* If true the config is loaded from the db and not from the cache (default: false)
* @return mixed Stored value or null if it does not exist
*/
public static function get($uid, $family, $key, $default_value = null, $refresh = false) {
global $a;
if(! $instore) {
// Looking if the whole family isn't set
if(isset($a->config[$uid][$family])) {
if($a->config[$uid][$family] === '!<unset>!') {
return $default_value;
}
}
if(isset($a->config[$uid][$family][$key])) {
if($a->config[$uid][$family][$key] === '!<unset>!') {
return $default_value;
}
return $a->config[$uid][$family][$key];
}
}
// If APC is enabled then fetch the data from there, else try XCache
/*if (function_exists("apc_fetch") AND function_exists("apc_exists"))
if (apc_exists($uid."|".$family."|".$key)) {
$val = apc_fetch($uid."|".$family."|".$key);
$a->config[$uid][$family][$key] = $val;
if ($val === '!<unset>!')
return false;
else
return $val;
}
elseif (function_exists("xcache_get") AND function_exists("xcache_isset"))
if (xcache_isset($uid."|".$family."|".$key)) {
$val = xcache_get($uid."|".$family."|".$key);
$a->config[$uid][$family][$key] = $val;
if ($val === '!<unset>!')
return false;
else
return $val;
}*/
$ret = q("SELECT `v` FROM `pconfig` WHERE `uid` = %d AND `cat` = '%s' AND `k` = '%s' LIMIT 1",
intval($uid),
dbesc($family),
dbesc($key)
);
if(count($ret)) {
$val = (preg_match("|^a:[0-9]+:{.*}$|s", $ret[0]['v'])?unserialize( $ret[0]['v']):$ret[0]['v']);
$a->config[$uid][$family][$key] = $val;
// If APC is enabled then store the data there, else try XCache
/*if (function_exists("apc_store"))
apc_store($uid."|".$family."|".$key, $val, 600);
elseif (function_exists("xcache_set"))
xcache_set($uid."|".$family."|".$key, $val, 600);*/
return $val;
}
else {
$a->config[$uid][$family][$key] = '!<unset>!';
// If APC is enabled then store the data there, else try XCache
/*if (function_exists("apc_store"))
apc_store($uid."|".$family."|".$key, '!<unset>!', 600);
elseif (function_exists("xcache_set"))
xcache_set($uid."|".$family."|".$key, '!<unset>!', 600);*/
}
return $default_value;
}
/**
* @brief Sets a configuration value for a user
*
* Stores a config value ($value) in the category ($family) under the key ($key)
* for the user_id $uid.
*
* @note Please do not store booleans - convert to 0/1 integer values!
*
* @param string $uid
* The user_id
* @param string $family
* The category of the configuration value
* @param string $key
* The configuration key to set
* @param string $value
* The value to store
* @return mixed Stored $value or false
*/
public static function set($uid,$family,$key,$value) {
global $a;
// manage array value
$dbvalue = (is_array($value)?serialize($value):$value);
if(is_null(self::get($uid,$family,$key,null, true))) {
$a->config[$uid][$family][$key] = $value;
$ret = q("INSERT INTO `pconfig` ( `uid`, `cat`, `k`, `v` ) VALUES ( %d, '%s', '%s', '%s' ) ",
intval($uid),
dbesc($family),
dbesc($key),
dbesc($dbvalue)
);
if($ret)
return $value;
return $ret;
}
$ret = q("UPDATE `pconfig` SET `v` = '%s' WHERE `uid` = %d AND `cat` = '%s' AND `k` = '%s'",
dbesc($dbvalue),
intval($uid),
dbesc($family),
dbesc($key)
);
$a->config[$uid][$family][$key] = $value;
// If APC is enabled then store the data there, else try XCache
/*if (function_exists("apc_store"))
apc_store($uid."|".$family."|".$key, $value, 600);
elseif (function_exists("xcache_set"))
xcache_set($uid."|".$family."|".$key, $value, 600);*/
if($ret)
return $value;
return $ret;
}
/**
* @brief Deletes the given key from the users's configuration.
*
* Removes the configured value from the stored cache in $a->config[$uid]
* and removes it from the database.
*
* @param string $uid The user_id
* @param string $family
* The category of the configuration value
* @param string $key
* The configuration key to delete
* @return mixed
*/
public static function delete($uid,$family,$key) {
global $a;
if(x($a->config[$uid][$family],$key))
unset($a->config[$uid][$family][$key]);
$ret = q("DELETE FROM `pconfig` WHERE `uid` = %d AND `cat` = '%s' AND `k` = '%s'",
intval($uid),
dbesc($family),
dbesc($key)
);
return $ret;
}
}

View file

@ -30,8 +30,8 @@ class Emailer {
// generate a mime boundary
$mimeBoundary =rand(0,9)."-"
.rand(10000000000,99999999999)."-"
.rand(10000000000,99999999999)."=:"
.rand(100000000,999999999)."-"
.rand(100000000,999999999)."=:"
.rand(10000,99999);
// generate a multipart/alternative message header

View file

@ -26,6 +26,7 @@ class ForumManager {
* 'name' => forum name
* 'id' => number of the key from the array
* 'micro' => contact photo in format micro
* 'thumb' => contact photo in format thumb
*/
public static function get_list($uid, $showhidden = true, $lastitem, $showprivate = false) {
@ -38,7 +39,7 @@ class ForumManager {
$select = '(`forum` OR `prv`)';
}
$contacts = q("SELECT `contact`.`id`, `contact`.`url`, `contact`.`name`, `contact`.`micro` FROM `contact`
$contacts = q("SELECT `contact`.`id`, `contact`.`url`, `contact`.`name`, `contact`.`micro`, `contact`.`thumb` FROM `contact`
WHERE `network`= 'dfrn' AND $select AND `uid` = %d
AND NOT `blocked` AND NOT `hidden` AND NOT `pending` AND NOT `archive`
AND `success_update` > `failure_update`
@ -55,6 +56,7 @@ class ForumManager {
'name' => $contact['name'],
'id' => $contact['id'],
'micro' => $contact['micro'],
'thumb' => $contact['thumb'],
);
}
return($forumlist);
@ -86,7 +88,7 @@ class ForumManager {
$total = count($contacts);
$visible_forums = 10;
if(dba::is_result($contacts)) {
if(dbm::is_result($contacts)) {
$id = 0;

View file

@ -1,21 +1,24 @@
<?php
/**
* @file include/NotificationsManager.php
* @brief Methods for read and write notifications from/to database
* or for formatting notifications
*/
require_once('include/html2plain.php');
require_once("include/datetime.php");
require_once("include/bbcode.php");
/**
* @brief Read and write notifications from/to database
* @brief Methods for read and write notifications from/to database
* or for formatting notifications
*/
class NotificationsManager {
private $a;
public function __construct() {
$this->a = get_app();
}
private $a;
public function __construct() {
$this->a = get_app();
}
/**
* @brief set some extra note properties
*
@ -28,109 +31,780 @@ class NotificationsManager {
* - msg_html: message as html string
* - msg_plain: message as plain text string
*/
private function _set_extra($notes) {
$rets = array();
foreach($notes as $n) {
$local_time = datetime_convert('UTC',date_default_timezone_get(),$n['date']);
$n['timestamp'] = strtotime($local_time);
$n['date_rel'] = relative_date($n['date']);
$n['msg_html'] = bbcode($n['msg'], false, false, false, false);
$n['msg_plain'] = explode("\n",trim(html2plain($n['msg_html'], 0)))[0];
$rets[] = $n;
}
return $rets;
}
private function _set_extra($notes) {
$rets = array();
foreach($notes as $n) {
$local_time = datetime_convert('UTC',date_default_timezone_get(),$n['date']);
$n['timestamp'] = strtotime($local_time);
$n['date_rel'] = relative_date($n['date']);
$n['msg_html'] = bbcode($n['msg'], false, false, false, false);
$n['msg_plain'] = explode("\n",trim(html2plain($n['msg_html'], 0)))[0];
$rets[] = $n;
}
return $rets;
}
/**
* @brief get all notifications for local_user()
*
* @param array $filter optional Array "column name"=>value: filter query by columns values
* @param string $order optional Space separated list of column to sort by. prepend name with "+" to sort ASC, "-" to sort DESC. Default to "-date"
* @param string $limit optional Query limits
*
* @return array of results or false on errors
*/
public function getAll($filter = array(), $order="-date", $limit="") {
$filter_str = array();
$filter_sql = "";
foreach($filter as $column => $value) {
$filter_str[] = sprintf("`%s` = '%s'", $column, dbesc($value));
}
if (count($filter_str)>0) {
$filter_sql = "AND ".implode(" AND ", $filter_str);
}
$aOrder = explode(" ", $order);
$asOrder = array();
foreach($aOrder as $o) {
$dir = "asc";
if ($o[0]==="-") {
$dir = "desc";
$o = substr($o,1);
}
if ($o[0]==="+") {
$dir = "asc";
$o = substr($o,1);
}
$asOrder[] = "$o $dir";
}
$order_sql = implode(", ", $asOrder);
if ($limit!="") $limit = " LIMIT ".$limit;
$r = q("SELECT * FROM `notify` WHERE `uid` = %d $filter_sql ORDER BY $order_sql $limit",
/**
* @brief Get all notifications for local_user()
*
* @param array $filter optional Array "column name"=>value: filter query by columns values
* @param string $order optional Space separated list of column to sort by. prepend name with "+" to sort ASC, "-" to sort DESC. Default to "-date"
* @param string $limit optional Query limits
*
* @return array of results or false on errors
*/
public function getAll($filter = array(), $order="-date", $limit="") {
$filter_str = array();
$filter_sql = "";
foreach($filter as $column => $value) {
$filter_str[] = sprintf("`%s` = '%s'", $column, dbesc($value));
}
if (count($filter_str)>0) {
$filter_sql = "AND ".implode(" AND ", $filter_str);
}
$aOrder = explode(" ", $order);
$asOrder = array();
foreach($aOrder as $o) {
$dir = "asc";
if ($o[0]==="-") {
$dir = "desc";
$o = substr($o,1);
}
if ($o[0]==="+") {
$dir = "asc";
$o = substr($o,1);
}
$asOrder[] = "$o $dir";
}
$order_sql = implode(", ", $asOrder);
if($limit!="")
$limit = " LIMIT ".$limit;
$r = q("SELECT * FROM `notify` WHERE `uid` = %d $filter_sql ORDER BY $order_sql $limit",
intval(local_user())
);
if(dbm::is_result($r))
return $this->_set_extra($r);
return false;
}
/**
* @brief Get one note for local_user() by $id value
*
* @param int $id
* @return array note values or null if not found
*/
public function getByID($id) {
$r = q("SELECT * FROM `notify` WHERE `id` = %d AND `uid` = %d LIMIT 1",
intval($id),
intval(local_user())
);
if ($r!==false && count($r)>0) return $this->_set_extra($r);
return false;
}
/**
* @brief get one note for local_user() by $id value
*
* @param int $id
* @return array note values or null if not found
*/
public function getByID($id) {
$r = q("SELECT * FROM `notify` WHERE `id` = %d AND `uid` = %d LIMIT 1",
intval($id),
intval(local_user())
);
if($r!==false && count($r)>0) {
return $this->_set_extra($r)[0];
}
return null;
}
/**
* @brief set seen state of $note of local_user()
*
* @param array $note
* @param bool $seen optional true or false, default true
* @return bool true on success, false on errors
*/
public function setSeen($note, $seen = true) {
return q("UPDATE `notify` SET `seen` = %d WHERE ( `link` = '%s' OR ( `parent` != 0 AND `parent` = %d AND `otype` = '%s' )) AND `uid` = %d",
intval($seen),
dbesc($note['link']),
intval($note['parent']),
dbesc($note['otype']),
intval(local_user())
);
}
/**
* @brief set seen state of all notifications of local_user()
*
* @param bool $seen optional true or false. default true
* @return bool true on success, false on error
*/
public function setAllSeen($seen = true) {
return q("UPDATE `notify` SET `seen` = %d WHERE `uid` = %d",
intval($seen),
if(dbm::is_result($r)) {
return $this->_set_extra($r)[0];
}
return null;
}
/**
* @brief set seen state of $note of local_user()
*
* @param array $note
* @param bool $seen optional true or false, default true
* @return bool true on success, false on errors
*/
public function setSeen($note, $seen = true) {
return q("UPDATE `notify` SET `seen` = %d WHERE ( `link` = '%s' OR ( `parent` != 0 AND `parent` = %d AND `otype` = '%s' )) AND `uid` = %d",
intval($seen),
dbesc($note['link']),
intval($note['parent']),
dbesc($note['otype']),
intval(local_user())
);
}
}
/**
* @brief set seen state of all notifications of local_user()
*
* @param bool $seen optional true or false. default true
* @return bool true on success, false on error
*/
public function setAllSeen($seen = true) {
return q("UPDATE `notify` SET `seen` = %d WHERE `uid` = %d",
intval($seen),
intval(local_user())
);
}
/**
* @brief List of pages for the Notifications TabBar
*
* @param app $a The
* @return array with with notifications TabBar data
*/
public function getTabs() {
$tabs = array(
array(
'label' => t('System'),
'url'=>'notifications/system',
'sel'=> (($this->a->argv[1] == 'system') ? 'active' : ''),
'id' => 'system-tab',
'accesskey' => 'y',
),
array(
'label' => t('Network'),
'url'=>'notifications/network',
'sel'=> (($this->a->argv[1] == 'network') ? 'active' : ''),
'id' => 'network-tab',
'accesskey' => 'w',
),
array(
'label' => t('Personal'),
'url'=>'notifications/personal',
'sel'=> (($this->a->argv[1] == 'personal') ? 'active' : ''),
'id' => 'personal-tab',
'accesskey' => 'r',
),
array(
'label' => t('Home'),
'url' => 'notifications/home',
'sel'=> (($this->a->argv[1] == 'home') ? 'active' : ''),
'id' => 'home-tab',
'accesskey' => 'h',
),
array(
'label' => t('Introductions'),
'url' => 'notifications/intros',
'sel'=> (($this->a->argv[1] == 'intros') ? 'active' : ''),
'id' => 'intro-tab',
'accesskey' => 'i',
),
);
return $tabs;
}
/**
* @brief Format the notification query in an usable array
*
* @param array $notifs The array from the db query
* @param string $ident The notifications identifier (e.g. network)
* @return array
* string 'label' => The type of the notification
* string 'link' => URL to the source
* string 'image' => The avatar image
* string 'text' => The notification text
* string 'when' => Relative date of the notification
* bool 'seen' => Is the notification marked as "seen"
*/
private function formatNotifs($notifs, $ident = "") {
$notif = array();
$arr = array();
if (dbm::is_result($notifs)) {
foreach ($notifs as $it) {
// Because we use different db tables for the notification query
// we have sometimes $it['unseen'] and sometimes $it['seen].
// So we will have to transform $it['unseen']
if($it['unseen'])
$it['seen'] = ($it['unseen'] > 0 ? false : true);
// Depending on the identifier of the notification we need to use different defaults
switch ($ident) {
case 'system':
$default_item_label = 'notify';
$default_item_link = $this->a->get_baseurl(true).'/notify/view/'. $it['id'];
$default_item_image = proxy_url($it['photo'], false, PROXY_SIZE_MICRO);
$default_item_text = strip_tags(bbcode($it['msg']));
$default_item_when = relative_date($it['date']);
$default_tpl = $tpl_notify;
break;
case 'home':
$default_item_label = 'comment';
$default_item_link = $this->a->get_baseurl(true).'/display/'.$it['pguid'];
$default_item_image = proxy_url($it['author-avatar'], false, PROXY_SIZE_MICRO);
$default_item_text = sprintf( t("%s commented on %s's post"), $it['author-name'], $it['pname']);
$default_item_when = relative_date($it['created']);
$default_tpl = $tpl_item_comments;
break;
default:
$default_item_label = (($it['id'] == $it['parent']) ? 'post' : 'comment');
$default_item_link = $this->a->get_baseurl(true).'/display/'.$it['pguid'];
$default_item_image = proxy_url($it['author-avatar'], false, PROXY_SIZE_MICRO);
$default_item_text = (($it['id'] == $it['parent'])
? sprintf( t("%s created a new post"), $it['author-name'])
: sprintf( t("%s commented on %s's post"), $it['author-name'], $it['pname']));
$default_item_when = relative_date($it['created']);
$default_tpl = (($it['id'] == $it['parent']) ? $tpl_item_posts : $tpl_item_comments);
}
// Transform the different types of notification in an usable array
switch($it['verb']){
case ACTIVITY_LIKE:
$notif = array(
'label' => 'like',
'link' => $this->a->get_baseurl(true).'/display/'.$it['pguid'],
'$image' => proxy_url($it['author-avatar'], false, PROXY_SIZE_MICRO),
'text' => sprintf( t("%s liked %s's post"), $it['author-name'], $it['pname']),
'when' => relative_date($it['created']),
'seen' => $it['seen']
);
break;
case ACTIVITY_DISLIKE:
$notif = array(
'label' => 'dislike',
'link' => $this->a->get_baseurl(true).'/display/'.$it['pguid'],
'image' => proxy_url($it['author-avatar'], false, PROXY_SIZE_MICRO),
'text' => sprintf( t("%s disliked %s's post"), $it['author-name'], $it['pname']),
'when' => relative_date($it['created']),
'seen' => $it['seen']
);
break;
case ACTIVITY_ATTEND:
$notif = array(
'label' => 'attend',
'link' => $this->a->get_baseurl(true).'/display/'.$it['pguid'],
'image' => proxy_url($it['author-avatar'], false, PROXY_SIZE_MICRO),
'text' => sprintf( t("%s is attending %s's event"), $it['author-name'], $it['pname']),
'when' => relative_date($it['created']),
'seen' => $it['seen']
);
break;
case ACTIVITY_ATTENDNO:
$notif = array(
'label' => 'attendno',
'link' => $this->a->get_baseurl(true).'/display/'.$it['pguid'],
'image' => proxy_url($it['author-avatar'], false, PROXY_SIZE_MICRO),
'text' => sprintf( t("%s is not attending %s's event"), $it['author-name'], $it['pname']),
'when' => relative_date($it['created']),
'seen' => $it['seen']
);
break;
case ACTIVITY_ATTENDMAYBE:
$notif = array(
'label' => 'attendmaybe',
'link' => $this->a->get_baseurl(true).'/display/'.$it['pguid'],
'image' => proxy_url($it['author-avatar'], false, PROXY_SIZE_MICRO),
'text' => sprintf( t("%s may attend %s's event"), $it['author-name'], $it['pname']),
'when' => relative_date($it['created']),
'seen' => $it['seen']
);
break;
case ACTIVITY_FRIEND:
$xmlhead="<"."?xml version='1.0' encoding='UTF-8' ?".">";
$obj = parse_xml_string($xmlhead.$it['object']);
$it['fname'] = $obj->title;
$notif = array(
'label' => 'friend',
'link' => $this->a->get_baseurl(true).'/display/'.$it['pguid'],
'image' => proxy_url($it['author-avatar'], false, PROXY_SIZE_MICRO),
'text' => sprintf( t("%s is now friends with %s"), $it['author-name'], $it['fname']),
'when' => relative_date($it['created']),
'seen' => $it['seen']
);
break;
default:
$notif = array(
'label' => $default_item_label,
'link' => $default_item_link,
'image' => $default_item_image,
'text' => $default_item_text,
'when' => $default_item_when,
'seen' => $it['seen']
);
}
$arr[] = $notif;
}
}
return $arr;
}
/**
* @brief Total number of network notifications
* @param int|string $seen
* If 0 only include notifications into the query
* which aren't marked as "seen"
* @return int Number of network notifications
*/
private function networkTotal($seen = 0) {
$sql_seen = "";
if($seen === 0)
$sql_seen = " AND `item`.`unseen` = 1 ";
$r = q("SELECT COUNT(*) AS `total`
FROM `item` INNER JOIN `item` AS `pitem` ON `pitem`.`id`=`item`.`parent`
WHERE `item`.`visible` = 1 AND `pitem`.`parent` != 0 AND
`item`.`deleted` = 0 AND `item`.`uid` = %d AND `item`.`wall` = 0
$sql_seen",
intval(local_user())
);
if(dbm::is_result($r))
return $r[0]['total'];
return 0;
}
/**
* @brief Get network notifications
*
* @param int|string $seen
* If 0 only include notifications into the query
* which aren't marked as "seen"
* @param int $start Start the query at this point
* @param int $limit Maximum number of query results
*
* @return array with
* string 'ident' => Notification identifier
* int 'total' => Total number of available network notifications
* array 'notifications' => Network notifications
*/
public function networkNotifs($seen = 0, $start = 0, $limit = 80) {
$ident = 'network';
$total = $this->networkTotal($seen);
$notifs = array();
$sql_seen = "";
if($seen === 0)
$sql_seen = " AND `item`.`unseen` = 1 ";
$r = q("SELECT `item`.`id`,`item`.`parent`, `item`.`verb`, `item`.`author-name`, `item`.`unseen`,
`item`.`author-link`, `item`.`author-avatar`, `item`.`created`, `item`.`object` AS `object`,
`pitem`.`author-name` AS `pname`, `pitem`.`author-link` AS `plink`, `pitem`.`guid` AS `pguid`
FROM `item` INNER JOIN `item` AS `pitem` ON `pitem`.`id`=`item`.`parent`
WHERE `item`.`visible` = 1 AND `pitem`.`parent` != 0 AND
`item`.`deleted` = 0 AND `item`.`uid` = %d AND `item`.`wall` = 0
$sql_seen
ORDER BY `item`.`created` DESC LIMIT %d, %d ",
intval(local_user()),
intval($start),
intval($limit)
);
if(dbm::is_result($r))
$notifs = $this->formatNotifs($r, $ident);
$arr = array (
'notifications' => $notifs,
'ident' => $ident,
'total' => $total,
);
return $arr;
}
/**
* @brief Total number of system notifications
* @param int|string $seen
* If 0 only include notifications into the query
* which aren't marked as "seen"
* @return int Number of system notifications
*/
private function systemTotal($seen = 0) {
$sql_seen = "";
if($seen === 0)
$sql_seen = " AND `seen` = 0 ";
$r = q("SELECT COUNT(*) AS `total` FROM `notify` WHERE `uid` = %d $sql_seen",
intval(local_user())
);
if(dbm::is_result($r))
return $r[0]['total'];
return 0;
}
/**
* @brief Get system notifications
*
* @param int|string $seen
* If 0 only include notifications into the query
* which aren't marked as "seen"
* @param int $start Start the query at this point
* @param int $limit Maximum number of query results
*
* @return array with
* string 'ident' => Notification identifier
* int 'total' => Total number of available system notifications
* array 'notifications' => System notifications
*/
public function systemNotifs($seen = 0, $start = 0, $limit = 80) {
$ident = 'system';
$total = $this->systemTotal($seen);
$notifs = array();
$sql_seen = "";
if($seen === 0)
$sql_seen = " AND `seen` = 0 ";
$r = q("SELECT `id`, `photo`, `msg`, `date`, `seen` FROM `notify`
WHERE `uid` = %d $sql_seen ORDER BY `date` DESC LIMIT %d, %d ",
intval(local_user()),
intval($start),
intval($limit)
);
if(dbm::is_result($r))
$notifs = $this->formatNotifs($r, $ident);
$arr = array (
'notifications' => $notifs,
'ident' => $ident,
'total' => $total,
);
return $arr;
}
/**
* @brief Addional SQL query string for the personal notifications
*
* @return string The additional sql query
*/
private function _personal_sql_extra() {
$myurl = $this->a->get_baseurl(true) . '/profile/'. $this->a->user['nickname'];
$myurl = substr($myurl,strpos($myurl,'://')+3);
$myurl = str_replace(array('www.','.'),array('','\\.'),$myurl);
$diasp_url = str_replace('/profile/','/u/',$myurl);
$sql_extra = sprintf(" AND ( `item`.`author-link` regexp '%s' or `item`.`tag` regexp '%s' or `item`.`tag` regexp '%s' ) ",
dbesc($myurl . '$'),
dbesc($myurl . '\\]'),
dbesc($diasp_url . '\\]')
);
return $sql_extra;
}
/**
* @brief Total number of personal notifications
* @param int|string $seen
* If 0 only include notifications into the query
* which aren't marked as "seen"
* @return int Number of personal notifications
*/
private function personalTotal($seen = 0) {
$sql_seen = "";
$sql_extra = $this->_personal_sql_extra();
if($seen === 0)
$sql_seen = " AND `item`.`unseen` = 1 ";
$r = q("SELECT COUNT(*) AS `total`
FROM `item` INNER JOIN `item` AS `pitem` ON `pitem`.`id`=`item`.`parent`
WHERE `item`.`visible` = 1
$sql_extra
$sql_seen
AND `item`.`deleted` = 0 AND `item`.`uid` = %d AND `item`.`wall` = 0 " ,
intval(local_user())
);
if(dbm::is_result($r))
return $r[0]['total'];
return 0;
}
/**
* @brief Get personal notifications
*
* @param int|string $seen
* If 0 only include notifications into the query
* which aren't marked as "seen"
* @param int $start Start the query at this point
* @param int $limit Maximum number of query results
*
* @return array with
* string 'ident' => Notification identifier
* int 'total' => Total number of available personal notifications
* array 'notifications' => Personal notifications
*/
public function personalNotifs($seen = 0, $start = 0, $limit = 80) {
$ident = 'personal';
$total = $this->personalTotal($seen);
$sql_extra = $this->_personal_sql_extra();
$notifs = array();
$sql_seen = "";
if($seen === 0)
$sql_seen = " AND `item`.`unseen` = 1 ";
$r = q("SELECT `item`.`id`,`item`.`parent`, `item`.`verb`, `item`.`author-name`, `item`.`unseen`,
`item`.`author-link`, `item`.`author-avatar`, `item`.`created`, `item`.`object` AS `object`,
`pitem`.`author-name` AS `pname`, `pitem`.`author-link` AS `plink`, `pitem`.`guid` AS `pguid`,
FROM `item` INNER JOIN `item` AS `pitem` ON `pitem`.`id`=`item`.`parent`
WHERE `item`.`visible` = 1
$sql_extra
$sql_seen
AND `item`.`deleted` = 0 AND `item`.`uid` = %d AND `item`.`wall` = 0
ORDER BY `item`.`created` DESC LIMIT %d, %d " ,
intval(local_user()),
intval($start),
intval($limit)
);
if(dbm::is_result($r))
$notifs = $this->formatNotifs($r, $ident);
$arr = array (
'notifications' => $notifs,
'ident' => $ident,
'total' => $total,
);
return $arr;
}
/**
* @brief Total number of home notifications
* @param int|string $seen
* If 0 only include notifications into the query
* which aren't marked as "seen"
* @return int Number of home notifications
*/
private function homeTotal($seen = 0) {
$sql_seen = "";
if($seen === 0)
$sql_seen = " AND `item`.`unseen` = 1 ";
$r = q("SELECT COUNT(*) AS `total` FROM `item`
WHERE `item`.`visible` = 1 AND
`item`.`deleted` = 0 AND `item`.`uid` = %d AND `item`.`wall` = 1
$sql_seen",
intval(local_user())
);
if(dbm::is_result($r))
return $r[0]['total'];
return 0;
}
/**
* @brief Get home notifications
*
* @param int|string $seen
* If 0 only include notifications into the query
* which aren't marked as "seen"
* @param int $start Start the query at this point
* @param int $limit Maximum number of query results
*
* @return array with
* string 'ident' => Notification identifier
* int 'total' => Total number of available home notifications
* array 'notifications' => Home notifications
*/
public function homeNotifs($seen = 0, $start = 0, $limit = 80) {
$ident = 'home';
$total = $this->homeTotal($seen);
$notifs = array();
$sql_seen = "";
if($seen === 0)
$sql_seen = " AND `item`.`unseen` = 1 ";
$r = q("SELECT `item`.`id`,`item`.`parent`, `item`.`verb`, `item`.`author-name`, `item`.`unseen`,
`item`.`author-link`, `item`.`author-avatar`, `item`.`created`, `item`.`object` as `object`,
`pitem`.`author-name` as `pname`, `pitem`.`author-link` as `plink`, `pitem`.`guid` as `pguid`
FROM `item` INNER JOIN `item` as `pitem` ON `pitem`.`id`=`item`.`parent`
WHERE `item`.`visible` = 1 AND
`item`.`deleted` = 0 AND `item`.`uid` = %d AND `item`.`wall` = 1
$sql_seen
ORDER BY `item`.`created` DESC LIMIT %d, %d ",
intval(local_user()),
intval($start),
intval($limit)
);
if(dbm::is_result($r))
$notifs = $this->formatNotifs($r, $ident);
$arr = array (
'notifications' => $notifs,
'ident' => $ident,
'total' => $total,
);
return $arr;
}
/**
* @brief Total number of introductions
* @param bool $all
* If false only include introductions into the query
* which aren't marked as ignored
* @return int Number of introductions
*/
private function introTotal($all = false) {
$sql_extra = "";
if(!$all)
$sql_extra = " AND `ignore` = 0 ";
$r = q("SELECT COUNT(*) AS `total` FROM `intro`
WHERE `intro`.`uid` = %d $sql_extra AND `intro`.`blocked` = 0 ",
intval($_SESSION['uid'])
);
if(dbm::is_result($r))
return $r[0]['total'];
return 0;
}
/**
* @brief Get introductions
*
* @param bool $all
* If false only include introductions into the query
* which aren't marked as ignored
* @param int $start Start the query at this point
* @param int $limit Maximum number of query results
*
* @return array with
* string 'ident' => Notification identifier
* int 'total' => Total number of available introductions
* array 'notifications' => Introductions
*/
public function introNotifs($all = false, $start = 0, $limit = 80) {
$ident = 'introductions';
$total = $this->introTotal($seen);
$notifs = array();
$sql_extra = "";
if(!$all)
$sql_extra = " AND `ignore` = 0 ";
/// @todo Fetch contact details by "get_contact_details_by_url" instead of queries to contact, fcontact and gcontact
$r = q("SELECT `intro`.`id` AS `intro_id`, `intro`.*, `contact`.*, `fcontact`.`name` AS `fname`,`fcontact`.`url` AS `furl`,`fcontact`.`photo` AS `fphoto`,`fcontact`.`request` AS `frequest`,
`gcontact`.`location` AS `glocation`, `gcontact`.`about` AS `gabout`,
`gcontact`.`keywords` AS `gkeywords`, `gcontact`.`gender` AS `ggender`,
`gcontact`.`network` AS `gnetwork`
FROM `intro`
LEFT JOIN `contact` ON `contact`.`id` = `intro`.`contact-id`
LEFT JOIN `gcontact` ON `gcontact`.`nurl` = `contact`.`nurl`
LEFT JOIN `fcontact` ON `intro`.`fid` = `fcontact`.`id`
WHERE `intro`.`uid` = %d $sql_extra AND `intro`.`blocked` = 0
LIMIT %d, %d",
intval($_SESSION['uid']),
intval($start),
intval($limit)
);
if(dbm::is_result($r))
$notifs = $this->formatIntros($r);
$arr = array (
'ident' => $ident,
'total' => $total,
'notifications' => $notifs,
);
return $arr;
}
/**
* @brief Format the notification query in an usable array
*
* @param array $intros The array from the db query
* @return array with the introductions
*/
private function formatIntros($intros) {
$knowyou = '';
foreach($intros as $it) {
// There are two kind of introduction. Contacts suggested by other contacts and normal connection requests.
// We have to distinguish between these two because they use different data.
// Contact suggestions
if($it['fid']) {
$return_addr = bin2hex($this->a->user['nickname'] . '@' . $this->a->get_hostname() . (($this->a->path) ? '/' . $this->a->path : ''));
$intro = array(
'label' => 'friend_suggestion',
'notify_type' => t('Friend Suggestion'),
'intro_id' => $it['intro_id'],
'madeby' => $it['name'],
'contact_id' => $it['contact-id'],
'photo' => ((x($it,'fphoto')) ? proxy_url($it['fphoto'], false, PROXY_SIZE_SMALL) : "images/person-175.jpg"),
'name' => $it['fname'],
'url' => zrl($it['furl']),
'hidden' => $it['hidden'] == 1,
'post_newfriend' => (intval(get_pconfig(local_user(),'system','post_newfriend')) ? '1' : 0),
'knowyou' => $knowyou,
'note' => $it['note'],
'request' => $it['frequest'] . '?addr=' . $return_addr,
);
// Normal connection requests
} else {
// Probe the contact url to get missing data
$ret = probe_url($it["url"]);
if ($it['gnetwork'] == "")
$it['gnetwork'] = $ret["network"];
// Don't show these data until you are connected. Diaspora is doing the same.
if($it['gnetwork'] === NETWORK_DIASPORA) {
$it['glocation'] = "";
$it['gabout'] = "";
$it['ggender'] = "";
}
$intro = array(
'label' => (($it['network'] !== NETWORK_OSTATUS) ? 'friend_request' : 'follower'),
'notify_type' => (($it['network'] !== NETWORK_OSTATUS) ? t('Friend/Connect Request') : t('New Follower')),
'dfrn_id' => $it['issued-id'],
'uid' => $_SESSION['uid'],
'intro_id' => $it['intro_id'],
'contact_id' => $it['contact-id'],
'photo' => ((x($it,'photo')) ? proxy_url($it['photo'], false, PROXY_SIZE_SMALL) : "images/person-175.jpg"),
'name' => $it['name'],
'location' => bbcode($it['glocation'], false, false),
'about' => bbcode($it['gabout'], false, false),
'keywords' => $it['gkeywords'],
'gender' => $it['ggender'],
'hidden' => $it['hidden'] == 1,
'post_newfriend' => (intval(get_pconfig(local_user(),'system','post_newfriend')) ? '1' : 0),
'url' => $it['url'],
'zrl' => zrl($it['url']),
'addr' => $ret['addr'],
'network' => $it['gnetwork'],
'knowyou' => $it['knowyou'],
'note' => $it['note'],
);
}
$arr[] = $intro;
}
return $arr;
}
}

View file

@ -589,7 +589,7 @@ class Photo {
$r = q("select `guid` from photo where `resource-id` = '%s' and `guid` != '' limit 1",
dbesc($rid)
);
if(dba::is_result($r))
if(dbm::is_result($r))
$guid = $r[0]['guid'];
else
$guid = get_guid();
@ -823,9 +823,12 @@ function get_photo_info($url) {
$data = Cache::get($url);
if (is_null($data)) {
$img_str = fetch_url($url, true, $redirects, 4);
// Unserialise to be able to check in the next step if the cached data is alright.
if (!is_null($data))
$data = unserialize($data);
if (is_null($data) OR !$data) {
$img_str = fetch_url($url, true, $redirects, 4);
$filesize = strlen($img_str);
if (function_exists("getimagesizefromstring"))
@ -846,8 +849,7 @@ function get_photo_info($url) {
$data["size"] = $filesize;
Cache::set($url, serialize($data));
} else
$data = unserialize($data);
}
return $data;
}

1124
include/Probe.php Normal file

File diff suppressed because it is too large Load diff

View file

@ -1,335 +1,5 @@
<?php
require_once('library/HTML5/Parser.php');
require_once('include/crypto.php');
require_once('include/feed.php');
if(! function_exists('scrape_dfrn')) {
function scrape_dfrn($url, $dont_probe = false) {
$a = get_app();
$ret = array();
logger('scrape_dfrn: url=' . $url);
// Try to fetch the data from noscrape. This is faster than parsing the HTML
$noscrape = str_replace("/hcard/", "/noscrape/", $url);
$noscrapejson = fetch_url($noscrape);
$noscrapedata = array();
if ($noscrapejson) {
$noscrapedata = json_decode($noscrapejson, true);
if (is_array($noscrapedata)) {
if ($noscrapedata["nick"] != "")
return($noscrapedata);
else
unset($noscrapedata["nick"]);
} else
$noscrapedata = array();
}
$s = fetch_url($url);
if (!$s)
return $ret;
if (!$dont_probe) {
$probe = probe_url($url);
if (isset($probe["addr"]))
$ret["addr"] = $probe["addr"];
}
$headers = $a->get_curl_headers();
logger('scrape_dfrn: headers=' . $headers, LOGGER_DEBUG);
$lines = explode("\n",$headers);
if(count($lines)) {
foreach($lines as $line) {
// don't try and run feeds through the html5 parser
if(stristr($line,'content-type:') && ((stristr($line,'application/atom+xml')) || (stristr($line,'application/rss+xml'))))
return ret;
}
}
try {
$dom = HTML5_Parser::parse($s);
} catch (DOMException $e) {
logger('scrape_dfrn: parse error: ' . $e);
}
if(! $dom)
return $ret;
$items = $dom->getElementsByTagName('link');
// get DFRN link elements
foreach($items as $item) {
$x = $item->getAttribute('rel');
if(($x === 'alternate') && ($item->getAttribute('type') === 'application/atom+xml'))
$ret['feed_atom'] = $item->getAttribute('href');
if(substr($x,0,5) == "dfrn-") {
$ret[$x] = $item->getAttribute('href');
}
if($x === 'lrdd') {
$decoded = urldecode($item->getAttribute('href'));
if(preg_match('/acct:([^@]*)@/',$decoded,$matches))
$ret['nick'] = $matches[1];
}
}
// Pull out hCard profile elements
$largest_photo = 0;
$items = $dom->getElementsByTagName('*');
foreach($items as $item) {
if(attribute_contains($item->getAttribute('class'), 'vcard')) {
$level2 = $item->getElementsByTagName('*');
foreach($level2 as $x) {
if(attribute_contains($x->getAttribute('class'),'fn')) {
$ret['fn'] = $x->textContent;
}
if((attribute_contains($x->getAttribute('class'),'photo'))
|| (attribute_contains($x->getAttribute('class'),'avatar'))) {
$size = intval($x->getAttribute('width'));
// dfrn prefers 175, so if we find this, we set largest_size so it can't be topped.
if(($size > $largest_photo) || ($size == 175) || (! $largest_photo)) {
$ret['photo'] = $x->getAttribute('src');
$largest_photo = (($size == 175) ? 9999 : $size);
}
}
if(attribute_contains($x->getAttribute('class'),'key')) {
$ret['key'] = $x->textContent;
}
}
}
}
return array_merge($ret, $noscrapedata);
}}
if(! function_exists('validate_dfrn')) {
function validate_dfrn($a) {
$errors = 0;
if(! x($a,'key'))
$errors ++;
if(! x($a,'dfrn-request'))
$errors ++;
if(! x($a,'dfrn-confirm'))
$errors ++;
if(! x($a,'dfrn-notify'))
$errors ++;
if(! x($a,'dfrn-poll'))
$errors ++;
return $errors;
}}
if(! function_exists('scrape_meta')) {
function scrape_meta($url) {
$a = get_app();
$ret = array();
logger('scrape_meta: url=' . $url);
$s = fetch_url($url);
if(! $s)
return $ret;
$headers = $a->get_curl_headers();
logger('scrape_meta: headers=' . $headers, LOGGER_DEBUG);
$lines = explode("\n",$headers);
if(count($lines)) {
foreach($lines as $line) {
// don't try and run feeds through the html5 parser
if(stristr($line,'content-type:') && ((stristr($line,'application/atom+xml')) || (stristr($line,'application/rss+xml'))))
return ret;
}
}
try {
$dom = HTML5_Parser::parse($s);
} catch (DOMException $e) {
logger('scrape_meta: parse error: ' . $e);
}
if(! $dom)
return $ret;
$items = $dom->getElementsByTagName('meta');
// get DFRN link elements
foreach($items as $item) {
$x = $item->getAttribute('name');
if(substr($x,0,5) == "dfrn-")
$ret[$x] = $item->getAttribute('content');
}
return $ret;
}}
if(! function_exists('scrape_vcard')) {
function scrape_vcard($url) {
$a = get_app();
$ret = array();
logger('scrape_vcard: url=' . $url);
$s = fetch_url($url);
if(! $s)
return $ret;
$headers = $a->get_curl_headers();
$lines = explode("\n",$headers);
if(count($lines)) {
foreach($lines as $line) {
// don't try and run feeds through the html5 parser
if(stristr($line,'content-type:') && ((stristr($line,'application/atom+xml')) || (stristr($line,'application/rss+xml'))))
return ret;
}
}
try {
$dom = HTML5_Parser::parse($s);
} catch (DOMException $e) {
logger('scrape_vcard: parse error: ' . $e);
}
if(! $dom)
return $ret;
// Pull out hCard profile elements
$largest_photo = 0;
$items = $dom->getElementsByTagName('*');
foreach($items as $item) {
if(attribute_contains($item->getAttribute('class'), 'vcard')) {
$level2 = $item->getElementsByTagName('*');
foreach($level2 as $x) {
if(attribute_contains($x->getAttribute('class'),'fn'))
$ret['fn'] = $x->textContent;
if((attribute_contains($x->getAttribute('class'),'photo'))
|| (attribute_contains($x->getAttribute('class'),'avatar'))) {
$size = intval($x->getAttribute('width'));
if(($size > $largest_photo) || (! $largest_photo)) {
$ret['photo'] = $x->getAttribute('src');
$largest_photo = $size;
}
}
if((attribute_contains($x->getAttribute('class'),'nickname'))
|| (attribute_contains($x->getAttribute('class'),'uid'))) {
$ret['nick'] = $x->textContent;
}
}
}
}
return $ret;
}}
if(! function_exists('scrape_feed')) {
function scrape_feed($url) {
$a = get_app();
$ret = array();
$cookiejar = tempnam(get_temppath(), 'cookiejar-scrape-feed-');
$s = fetch_url($url, false, $redirects, 0, Null, $cookiejar);
unlink($cookiejar);
$headers = $a->get_curl_headers();
$code = $a->get_curl_code();
logger('scrape_feed: returns: ' . $code . ' headers=' . $headers, LOGGER_DEBUG);
if(! $s) {
logger('scrape_feed: no data returned for ' . $url);
return $ret;
}
$lines = explode("\n",$headers);
if(count($lines)) {
foreach($lines as $line) {
if(stristr($line,'content-type:')) {
if(stristr($line,'application/atom+xml') || stristr($s,'<feed')) {
$ret['feed_atom'] = $url;
return $ret;
}
if(stristr($line,'application/rss+xml') || stristr($s,'<rss')) {
$ret['feed_rss'] = $url;
return $ret;
}
}
}
// perhaps an RSS version 1 feed with a generic or incorrect content-type?
if(stristr($s,'</item>')) {
$ret['feed_rss'] = $url;
return $ret;
}
}
$basename = implode('/', array_slice(explode('/',$url),0,3)) . '/';
$doc = new DOMDocument();
@$doc->loadHTML($s);
$xpath = new DomXPath($doc);
$base = $xpath->query("//base");
foreach ($base as $node) {
$attr = array();
if ($node->attributes->length)
foreach ($node->attributes as $attribute)
$attr[$attribute->name] = $attribute->value;
if ($attr["href"] != "")
$basename = $attr["href"] ;
}
$list = $xpath->query("//link");
foreach ($list as $node) {
$attr = array();
if ($node->attributes->length)
foreach ($node->attributes as $attribute)
$attr[$attribute->name] = $attribute->value;
if (($attr["rel"] == "alternate") AND ($attr["type"] == "application/atom+xml"))
$ret["feed_atom"] = $attr["href"];
if (($attr["rel"] == "alternate") AND ($attr["type"] == "application/rss+xml"))
$ret["feed_rss"] = $attr["href"];
}
// Drupal and perhaps others only provide relative URLs. Turn them into absolute.
if(x($ret,'feed_atom') && (! strstr($ret['feed_atom'],'://')))
$ret['feed_atom'] = $basename . $ret['feed_atom'];
if(x($ret,'feed_rss') && (! strstr($ret['feed_rss'],'://')))
$ret['feed_rss'] = $basename . $ret['feed_rss'];
return $ret;
}}
require_once('include/Probe.php');
/**
*
@ -349,594 +19,17 @@ function scrape_feed($url) {
*
*/
define ( 'PROBE_NORMAL', 0);
define ( 'PROBE_DIASPORA', 1);
define('PROBE_NORMAL', 0);
define('PROBE_DIASPORA', 1);
function probe_url($url, $mode = PROBE_NORMAL, $level = 1) {
require_once('include/email.php');
$result = array();
if ($mode == PROBE_DIASPORA)
$network = NETWORK_DIASPORA;
else
$network = "";
if (!$url)
return $result;
$data = Probe::uri($url, $network);
$result = Cache::get("probe_url:".$mode.":".$url);
if (!is_null($result)) {
$result = unserialize($result);
return $result;
}
$original_url = $url;
$network = null;
$diaspora = false;
$diaspora_base = '';
$diaspora_guid = '';
$diaspora_key = '';
$has_lrdd = false;
$email_conversant = false;
$connectornetworks = false;
$appnet = false;
if (strpos($url,'twitter.com')) {
$connectornetworks = true;
$network = NETWORK_TWITTER;
}
$lastfm = ((strpos($url,'last.fm/user') !== false) ? true : false);
$at_addr = ((strpos($url,'@') !== false) ? true : false);
if((!$appnet) && (!$lastfm) && !$connectornetworks) {
if(strpos($url,'mailto:') !== false && $at_addr) {
$url = str_replace('mailto:','',$url);
$links = array();
}
else
$links = lrdd($url);
if ((count($links) == 0) AND strstr($url, "/index.php")) {
$url = str_replace("/index.php", "", $url);
$links = lrdd($url);
}
if (count($links)) {
$has_lrdd = true;
logger('probe_url: found lrdd links: ' . print_r($links,true), LOGGER_DATA);
foreach($links as $link) {
if($link['@attributes']['rel'] === NAMESPACE_ZOT)
$zot = unamp($link['@attributes']['href']);
if($link['@attributes']['rel'] === NAMESPACE_DFRN)
$dfrn = unamp($link['@attributes']['href']);
if($link['@attributes']['rel'] === 'salmon')
$notify = unamp($link['@attributes']['href']);
if($link['@attributes']['rel'] === NAMESPACE_FEED)
$poll = unamp($link['@attributes']['href']);
if($link['@attributes']['rel'] === 'http://microformats.org/profile/hcard')
$hcard = unamp($link['@attributes']['href']);
if($link['@attributes']['rel'] === 'http://webfinger.net/rel/profile-page')
$profile = unamp($link['@attributes']['href']);
if($link['@attributes']['rel'] === 'http://portablecontacts.net/spec/1.0')
$poco = unamp($link['@attributes']['href']);
if($link['@attributes']['rel'] === 'http://joindiaspora.com/seed_location') {
$diaspora_base = unamp($link['@attributes']['href']);
$diaspora = true;
}
if($link['@attributes']['rel'] === 'http://joindiaspora.com/guid') {
$diaspora_guid = unamp($link['@attributes']['href']);
$diaspora = true;
}
if($link['@attributes']['rel'] === 'diaspora-public-key') {
$diaspora_key = base64_decode(unamp($link['@attributes']['href']));
if(strstr($diaspora_key,'RSA '))
$pubkey = rsatopem($diaspora_key);
else
$pubkey = $diaspora_key;
$diaspora = true;
}
if(($link['@attributes']['rel'] === 'http://ostatus.org/schema/1.0/subscribe') AND ($mode == PROBE_NORMAL)) {
$diaspora = false;
}
}
// Status.Net can have more than one profile URL. We need to match the profile URL
// to a contact on incoming messages to prevent spam, and we won't know which one
// to match. So in case of two, one of them is stored as an alias. Only store URL's
// and not webfinger user@host aliases. If they've got more than two non-email style
// aliases, let's hope we're lucky and get one that matches the feed author-uri because
// otherwise we're screwed.
$backup_alias = "";
foreach($links as $link) {
if($link['@attributes']['rel'] === 'alias') {
if(strpos($link['@attributes']['href'],'@') === false) {
if(isset($profile)) {
$alias_url = $link['@attributes']['href'];
if(($alias_url !== $profile) AND ($backup_alias == "") AND
($alias_url !== str_replace("/index.php", "", $profile)))
$backup_alias = $alias_url;
if(($alias_url !== $profile) AND !strstr($alias_url, "index.php") AND
($alias_url !== str_replace("/index.php", "", $profile)))
$alias = $alias_url;
}
else
$profile = unamp($link['@attributes']['href']);
}
}
}
if ($alias == "")
$alias = $backup_alias;
// If the profile is different from the url then the url is abviously an alias
if (($alias == "") AND ($profile != "") AND !$at_addr AND (normalise_link($profile) != normalise_link($url)))
$alias = $url;
}
elseif($mode == PROBE_NORMAL) {
// Check email
$orig_url = $url;
if((strpos($orig_url,'@')) && validate_email($orig_url)) {
$x = q("SELECT `prvkey` FROM `user` WHERE `uid` = %d LIMIT 1",
intval(local_user())
);
$r = q("SELECT * FROM `mailacct` WHERE `uid` = %d AND `server` != '' LIMIT 1",
intval(local_user())
);
if(count($x) && count($r)) {
$mailbox = construct_mailbox_name($r[0]);
$password = '';
openssl_private_decrypt(hex2bin($r[0]['pass']),$password,$x[0]['prvkey']);
$mbox = email_connect($mailbox,$r[0]['user'],$password);
if(! $mbox)
logger('probe_url: email_connect failed.');
unset($password);
}
if($mbox) {
$msgs = email_poll($mbox,$orig_url);
logger('probe_url: searching ' . $orig_url . ', ' . count($msgs) . ' messages found.', LOGGER_DEBUG);
if(count($msgs)) {
$addr = $orig_url;
$network = NETWORK_MAIL;
$name = substr($url,0,strpos($url,'@'));
$phost = substr($url,strpos($url,'@')+1);
$profile = 'http://' . $phost;
// fix nick character range
$vcard = array('fn' => $name, 'nick' => $name, 'photo' => avatar_img($url));
$notify = 'smtp ' . random_string();
$poll = 'email ' . random_string();
$priority = 0;
$x = email_msg_meta($mbox,$msgs[0]);
if(stristr($x[0]->from,$orig_url))
$adr = imap_rfc822_parse_adrlist($x[0]->from,'');
elseif(stristr($x[0]->to,$orig_url))
$adr = imap_rfc822_parse_adrlist($x[0]->to,'');
if(isset($adr)) {
foreach($adr as $feadr) {
if((strcasecmp($feadr->mailbox,$name) == 0)
&&(strcasecmp($feadr->host,$phost) == 0)
&& (strlen($feadr->personal))) {
$personal = imap_mime_header_decode($feadr->personal);
$vcard['fn'] = "";
foreach($personal as $perspart)
if ($perspart->charset != "default")
$vcard['fn'] .= iconv($perspart->charset, 'UTF-8//IGNORE', $perspart->text);
else
$vcard['fn'] .= $perspart->text;
$vcard['fn'] = notags($vcard['fn']);
}
}
}
}
imap_close($mbox);
}
}
}
}
if($mode == PROBE_NORMAL) {
if(strlen($zot)) {
$s = fetch_url($zot);
if($s) {
$j = json_decode($s);
if($j) {
$network = NETWORK_ZOT;
$vcard = array(
'fn' => $j->fullname,
'nick' => $j->nickname,
'photo' => $j->photo
);
$profile = $j->url;
$notify = $j->post;
$pubkey = $j->pubkey;
$poll = 'N/A';
}
}
}
if(strlen($dfrn)) {
$ret = scrape_dfrn(($hcard) ? $hcard : $dfrn, true);
if(is_array($ret) && x($ret,'dfrn-request')) {
$network = NETWORK_DFRN;
$request = $ret['dfrn-request'];
$confirm = $ret['dfrn-confirm'];
$notify = $ret['dfrn-notify'];
$poll = $ret['dfrn-poll'];
$vcard = array();
$vcard['fn'] = $ret['fn'];
$vcard['nick'] = $ret['nick'];
$vcard['photo'] = $ret['photo'];
}
}
}
// Scrape the public key from the hcard.
// Diaspora will remove it from the webfinger somewhere in the future.
if (($hcard != "") AND ($pubkey == "")) {
$ret = scrape_dfrn(($hcard) ? $hcard : $dfrn, true);
if (isset($ret["key"])) {
$hcard_key = $ret["key"];
if(strstr($hcard_key,'RSA '))
$pubkey = rsatopem($hcard_key);
else
$pubkey = $hcard_key;
}
}
if($diaspora && $diaspora_base && $diaspora_guid) {
$diaspora_notify = $diaspora_base.'receive/users/'.$diaspora_guid;
if($mode == PROBE_DIASPORA || !$notify || ($notify == $diaspora_notify)) {
$notify = $diaspora_notify;
$batch = $diaspora_base . 'receive/public' ;
}
if(strpos($url,'@'))
$addr = str_replace('acct:', '', $url);
}
if($network !== NETWORK_ZOT && $network !== NETWORK_DFRN && $network !== NETWORK_MAIL) {
if($diaspora)
$network = NETWORK_DIASPORA;
elseif($has_lrdd AND ($notify))
$network = NETWORK_OSTATUS;
if(strpos($url,'@'))
$addr = str_replace('acct:', '', $url);
$priority = 0;
if($hcard && ! $vcard) {
$vcard = scrape_vcard($hcard);
// Google doesn't use absolute url in profile photos
if((x($vcard,'photo')) && substr($vcard['photo'],0,1) == '/') {
$h = @parse_url($hcard);
if($h)
$vcard['photo'] = $h['scheme'] . '://' . $h['host'] . $vcard['photo'];
}
logger('probe_url: scrape_vcard: ' . print_r($vcard,true), LOGGER_DATA);
}
if($diaspora && $addr) {
// Diaspora returns the name as the nick. As the nick will never be updated,
// let's use the Diaspora nickname (the first part of the handle) as the nick instead
$addr_parts = explode('@', $addr);
$vcard['nick'] = $addr_parts[0];
}
if($lastfm) {
$profile = $url;
$poll = str_replace(array('www.','last.fm/'),array('','ws.audioscrobbler.com/1.0/'),$url) . '/recenttracks.rss';
$vcard['nick'] = basename($url);
$vcard['fn'] = $vcard['nick'] . t(' on Last.fm');
$network = NETWORK_FEED;
}
if(! x($vcard,'fn'))
if(x($vcard,'nick'))
$vcard['fn'] = $vcard['nick'];
$check_feed = false;
if(stristr($url,'tumblr.com') && (! stristr($url,'/rss'))) {
$poll = $url . '/rss';
$check_feed = true;
// Will leave it to others to figure out how to grab the avatar, which is on the $url page in the open graph meta links
}
if($appnet || ! $poll)
$check_feed = true;
if((! isset($vcard)) || (! x($vcard,'fn')) || (! $profile))
$check_feed = true;
if(($at_addr) && (! count($links)))
$check_feed = false;
if ($connectornetworks)
$check_feed = false;
if($check_feed) {
$feedret = scrape_feed(($poll) ? $poll : $url);
logger('probe_url: scrape_feed ' . (($poll)? $poll : $url) . ' returns: ' . print_r($feedret,true), LOGGER_DATA);
if(count($feedret) && ($feedret['feed_atom'] || $feedret['feed_rss'])) {
$poll = ((x($feedret,'feed_atom')) ? unamp($feedret['feed_atom']) : unamp($feedret['feed_rss']));
if(! x($vcard))
$vcard = array();
}
if(x($feedret,'photo') && (! x($vcard,'photo')))
$vcard['photo'] = $feedret['photo'];
$cookiejar = tempnam(get_temppath(), 'cookiejar-scrape-feed-');
$xml = fetch_url($poll, false, $redirects, 0, Null, $cookiejar);
unlink($cookiejar);
logger('probe_url: fetch feed: ' . $poll . ' returns: ' . $xml, LOGGER_DATA);
if ($xml == "") {
logger("scrape_feed: XML is empty for feed ".$poll);
$network = NETWORK_PHANTOM;
} else {
$data = feed_import($xml,$dummy1,$dummy2, $dummy3, true);
if (!is_array($data)) {
logger("scrape_feed: This doesn't seem to be a feed: ".$poll);
$network = NETWORK_PHANTOM;
} else {
if (($vcard["photo"] == "") AND ($data["header"]["author-avatar"] != ""))
$vcard["photo"] = $data["header"]["author-avatar"];
if (($vcard["fn"] == "") AND ($data["header"]["author-name"] != ""))
$vcard["fn"] = $data["header"]["author-name"];
if (($vcard["nick"] == "") AND ($data["header"]["author-nick"] != ""))
$vcard["nick"] = $data["header"]["author-nick"];
if ($network == NETWORK_OSTATUS) {
if ($data["header"]["author-id"] != "")
$alias = $data["header"]["author-id"];
if ($data["header"]["author-link"] != "")
$profile = $data["header"]["author-link"];
} elseif(!$profile AND ($data["header"]["author-link"] != "") AND !in_array($network, array("", NETWORK_FEED)))
$profile = $data["header"]["author-link"];
}
}
// Workaround for misconfigured Friendica servers
if (($network == "") AND (strstr($url, "/profile/"))) {
$noscrape = str_replace("/profile/", "/noscrape/", $url);
$noscrapejson = fetch_url($noscrape);
if ($noscrapejson) {
$network = NETWORK_DFRN;
$poco = str_replace("/profile/", "/poco/", $url);
$noscrapedata = json_decode($noscrapejson, true);
if (isset($noscrapedata["addr"]))
$addr = $noscrapedata["addr"];
if (isset($noscrapedata["fn"]))
$vcard["fn"] = $noscrapedata["fn"];
if (isset($noscrapedata["key"]))
$pubkey = $noscrapedata["key"];
if (isset($noscrapedata["photo"]))
$vcard["photo"] = $noscrapedata["photo"];
if (isset($noscrapedata["dfrn-request"]))
$request = $noscrapedata["dfrn-request"];
if (isset($noscrapedata["dfrn-confirm"]))
$confirm = $noscrapedata["dfrn-confirm"];
if (isset($noscrapedata["dfrn-notify"]))
$notify = $noscrapedata["dfrn-notify"];
if (isset($noscrapedata["dfrn-poll"]))
$poll = $noscrapedata["dfrn-poll"];
}
}
if(! $network)
$network = NETWORK_FEED;
if(! x($vcard,'nick')) {
$vcard['nick'] = strtolower(notags(unxmlify($vcard['fn'])));
if(strpos($vcard['nick'],' '))
$vcard['nick'] = trim(substr($vcard['nick'],0,strpos($vcard['nick'],' ')));
}
if(! $priority)
$priority = 2;
}
}
if(! x($vcard,'photo')) {
$a = get_app();
$vcard['photo'] = App::get_baseurl() . '/images/person-175.jpg' ;
}
if(! $profile)
$profile = $url;
// No human could be associated with this link, use the URL as the contact name
if(($network === NETWORK_FEED) && ($poll) && (! x($vcard,'fn')))
$vcard['fn'] = $url;
if (($notify != "") AND ($poll != "")) {
$baseurl = matching_url(normalise_link($notify), normalise_link($poll));
$baseurl2 = matching_url($baseurl, normalise_link($profile));
if ($baseurl2 != "")
$baseurl = $baseurl2;
}
if (($baseurl == "") AND ($notify != ""))
$baseurl = matching_url(normalise_link($profile), normalise_link($notify));
if (($baseurl == "") AND ($poll != ""))
$baseurl = matching_url(normalise_link($profile), normalise_link($poll));
if (substr($baseurl, -10) == "/index.php")
$baseurl = str_replace("/index.php", "", $baseurl);
if ($network == "")
$network = NETWORK_PHANTOM;
$baseurl = rtrim($baseurl, "/");
if(strpos($url,'@') AND ($addr == "") AND ($network == NETWORK_DFRN))
$addr = str_replace('acct:', '', $url);
$vcard['fn'] = notags($vcard['fn']);
$vcard['nick'] = str_replace(' ','',notags($vcard['nick']));
$result['name'] = $vcard['fn'];
$result['nick'] = $vcard['nick'];
$result['url'] = $profile;
$result['addr'] = $addr;
$result['batch'] = $batch;
$result['notify'] = $notify;
$result['poll'] = $poll;
$result['request'] = $request;
$result['confirm'] = $confirm;
$result['poco'] = $poco;
$result['photo'] = $vcard['photo'];
$result['priority'] = $priority;
$result['network'] = $network;
$result['alias'] = $alias;
$result['pubkey'] = $pubkey;
$result['baseurl'] = $baseurl;
logger('probe_url: ' . print_r($result,true), LOGGER_DEBUG);
if ($level == 1) {
// Trying if it maybe a diaspora account
if (($result['network'] == NETWORK_FEED) OR ($result['addr'] == "")) {
require_once('include/bbcode.php');
$address = GetProfileUsername($url, "", true);
$result2 = probe_url($address, $mode, ++$level);
if ($result2['network'] != "")
$result = $result2;
}
// Maybe it's some non standard GNU Social installation (Single user, subfolder or no uri rewrite)
if (($result['network'] == NETWORK_FEED) AND ($result['baseurl'] != "") AND ($result['nick'] != "")) {
$addr = $result['nick'].'@'.str_replace("http://", "", $result['baseurl']);
$result2 = probe_url($addr, $mode, ++$level);
if (($result2['network'] != "") AND ($result2['network'] != NETWORK_FEED))
$result = $result2;
}
// Quickfix for Hubzilla systems with enabled OStatus plugin
if (($result['network'] == NETWORK_DIASPORA) AND ($result["batch"] == "")) {
$result2 = probe_url($url, PROBE_DIASPORA, ++$level);
if ($result2['network'] == NETWORK_DIASPORA) {
$addr = $result["addr"];
$result = $result2;
if (($result["addr"] == "") AND ($addr != ""))
$result["addr"] = $addr;
}
}
}
// Only store into the cache if the value seems to be valid
if ($result['network'] != NETWORK_PHANTOM) {
Cache::set("probe_url:".$mode.":".$original_url,serialize($result), CACHE_DAY);
/// @todo temporary fix - we need a real contact update function that updates only changing fields
/// The biggest problem is the avatar picture that could have a reduced image size.
/// It should only be updated if the existing picture isn't existing anymore.
if (($result['network'] != NETWORK_FEED) AND ($mode == PROBE_NORMAL) AND
$result["name"] AND $result["nick"] AND $result["url"] AND $result["addr"] AND $result["poll"])
q("UPDATE `contact` SET `name` = '%s', `nick` = '%s', `url` = '%s', `addr` = '%s',
`notify` = '%s', `poll` = '%s', `alias` = '%s', `success_update` = '%s'
WHERE `nurl` = '%s' AND NOT `self` AND `uid` = 0",
dbesc($result["name"]),
dbesc($result["nick"]),
dbesc($result["url"]),
dbesc($result["addr"]),
dbesc($result["notify"]),
dbesc($result["poll"]),
dbesc($result["alias"]),
dbesc(datetime_convert()),
dbesc(normalise_link($result['url']))
);
}
return $result;
}
/**
* @brief Find the matching part between two url
*
* @param string $url1
* @param string $url2
* @return string The matching part
*/
function matching_url($url1, $url2) {
if (($url1 == "") OR ($url2 == ""))
return "";
$url1 = normalise_link($url1);
$url2 = normalise_link($url2);
$parts1 = parse_url($url1);
$parts2 = parse_url($url2);
if (!isset($parts1["host"]) OR !isset($parts2["host"]))
return "";
if ($parts1["scheme"] != $parts2["scheme"])
return "";
if ($parts1["host"] != $parts2["host"])
return "";
if ($parts1["port"] != $parts2["port"])
return "";
$match = $parts1["scheme"]."://".$parts1["host"];
if ($parts1["port"])
$match .= ":".$parts1["port"];
$pathparts1 = explode("/", $parts1["path"]);
$pathparts2 = explode("/", $parts2["path"]);
$i = 0;
$path = "";
do {
$path1 = $pathparts1[$i];
$path2 = $pathparts2[$i];
if ($path1 == $path2)
$path .= $path1."/";
} while (($path1 == $path2) AND ($i++ <= count($pathparts1)));
$match .= $path;
return normalise_link($match);
return $data;
}

View file

@ -1,7 +1,8 @@
<?php
/**
* @file include/smilies.php
* @file include/Smilies.php
* @brief This file contains the Smilies class which contains functions to handle smiles
*/
/**
@ -63,41 +64,41 @@ class Smilies {
);
$icons = array(
'<img class="smiley" src="' . app::get_baseurl() . '/images/smiley-heart.gif" alt="&lt;3" />',
'<img class="smiley" src="' . app::get_baseurl() . '/images/smiley-brokenheart.gif" alt="&lt;/3" />',
'<img class="smiley" src="' . app::get_baseurl() . '/images/smiley-brokenheart.gif" alt="&lt;\\3" />',
'<img class="smiley" src="' . app::get_baseurl() . '/images/smiley-smile.gif" alt=":-)" />',
'<img class="smiley" src="' . app::get_baseurl() . '/images/smiley-wink.gif" alt=";-)" />',
'<img class="smiley" src="' . app::get_baseurl() . '/images/smiley-frown.gif" alt=":-(" />',
'<img class="smiley" src="' . app::get_baseurl() . '/images/smiley-tongue-out.gif" alt=":-P" />',
'<img class="smiley" src="' . app::get_baseurl() . '/images/smiley-tongue-out.gif" alt=":-p" />',
'<img class="smiley" src="' . app::get_baseurl() . '/images/smiley-kiss.gif" alt=":-\"" />',
'<img class="smiley" src="' . app::get_baseurl() . '/images/smiley-kiss.gif" alt=":-\"" />',
'<img class="smiley" src="' . app::get_baseurl() . '/images/smiley-kiss.gif" alt=":-x" />',
'<img class="smiley" src="' . app::get_baseurl() . '/images/smiley-kiss.gif" alt=":-X" />',
'<img class="smiley" src="' . app::get_baseurl() . '/images/smiley-laughing.gif" alt=":-D" />',
'<img class="smiley" src="' . app::get_baseurl() . '/images/smiley-surprised.gif" alt="8-|" />',
'<img class="smiley" src="' . app::get_baseurl() . '/images/smiley-surprised.gif" alt="8-O" />',
'<img class="smiley" src="' . app::get_baseurl() . '/images/smiley-surprised.gif" alt=":-O" />',
'<img class="smiley" src="' . app::get_baseurl() . '/images/smiley-thumbsup.gif" alt="\\o/" />',
'<img class="smiley" src="' . app::get_baseurl() . '/images/smiley-Oo.gif" alt="o.O" />',
'<img class="smiley" src="' . app::get_baseurl() . '/images/smiley-Oo.gif" alt="O.o" />',
'<img class="smiley" src="' . app::get_baseurl() . '/images/smiley-Oo.gif" alt="o_O" />',
'<img class="smiley" src="' . app::get_baseurl() . '/images/smiley-Oo.gif" alt="O_o" />',
'<img class="smiley" src="' . app::get_baseurl() . '/images/smiley-cry.gif" alt=":\'(" />',
'<img class="smiley" src="' . app::get_baseurl() . '/images/smiley-foot-in-mouth.gif" alt=":-!" />',
'<img class="smiley" src="' . app::get_baseurl() . '/images/smiley-undecided.gif" alt=":-/" />',
'<img class="smiley" src="' . app::get_baseurl() . '/images/smiley-embarassed.gif" alt=":-[" />',
'<img class="smiley" src="' . app::get_baseurl() . '/images/smiley-cool.gif" alt="8-)" />',
'<img class="smiley" src="' . app::get_baseurl() . '/images/beer_mug.gif" alt=":beer" />',
'<img class="smiley" src="' . app::get_baseurl() . '/images/beer_mug.gif" alt=":homebrew" />',
'<img class="smiley" src="' . app::get_baseurl() . '/images/coffee.gif" alt=":coffee" />',
'<img class="smiley" src="' . app::get_baseurl() . '/images/smiley-facepalm.gif" alt=":facepalm" />',
'<img class="smiley" src="' . app::get_baseurl() . '/images/like.gif" alt=":like" />',
'<img class="smiley" src="' . app::get_baseurl() . '/images/dislike.gif" alt=":dislike" />',
'<a href="http://friendica.com">~friendica <img class="smiley" src="' . app::get_baseurl() . '/images/friendica-16.png" alt="~friendica" /></a>',
'<a href="http://redmatrix.me/">red<img class="smiley" src="' . app::get_baseurl() . '/images/rm-16.png" alt="red" />matrix</a>',
'<a href="http://redmatrix.me/">red<img class="smiley" src="' . app::get_baseurl() . '/images/rm-16.png" alt="red" />matrix</a>'
'<img class="smiley" src="' . app::get_baseurl() . '/images/smiley-heart.gif" alt="&lt;3" title="&lt;3" />',
'<img class="smiley" src="' . app::get_baseurl() . '/images/smiley-brokenheart.gif" alt="&lt;/3" title="&lt;/3" />',
'<img class="smiley" src="' . app::get_baseurl() . '/images/smiley-brokenheart.gif" alt="&lt;\\3" title="&lt;\\3" />',
'<img class="smiley" src="' . app::get_baseurl() . '/images/smiley-smile.gif" alt=":-)" title=":-)" />',
'<img class="smiley" src="' . app::get_baseurl() . '/images/smiley-wink.gif" alt=";-)" title=";-)" />',
'<img class="smiley" src="' . app::get_baseurl() . '/images/smiley-frown.gif" alt=":-(" title=":-(" />',
'<img class="smiley" src="' . app::get_baseurl() . '/images/smiley-tongue-out.gif" alt=":-P" title=":-P" />',
'<img class="smiley" src="' . app::get_baseurl() . '/images/smiley-tongue-out.gif" alt=":-p" title=":-P" />',
'<img class="smiley" src="' . app::get_baseurl() . '/images/smiley-kiss.gif" alt=":-\" title=":-\" />',
'<img class="smiley" src="' . app::get_baseurl() . '/images/smiley-kiss.gif" alt=":-\" title=":-\" />',
'<img class="smiley" src="' . app::get_baseurl() . '/images/smiley-kiss.gif" alt=":-x" title=":-x" />',
'<img class="smiley" src="' . app::get_baseurl() . '/images/smiley-kiss.gif" alt=":-X" title=":-X" />',
'<img class="smiley" src="' . app::get_baseurl() . '/images/smiley-laughing.gif" alt=":-D" title=":-D" />',
'<img class="smiley" src="' . app::get_baseurl() . '/images/smiley-surprised.gif" alt="8-|" title="8-|" />',
'<img class="smiley" src="' . app::get_baseurl() . '/images/smiley-surprised.gif" alt="8-O" title="8-O" />',
'<img class="smiley" src="' . app::get_baseurl() . '/images/smiley-surprised.gif" alt=":-O" title="8-O" />',
'<img class="smiley" src="' . app::get_baseurl() . '/images/smiley-thumbsup.gif" alt="\\o/" title="\\o/" />',
'<img class="smiley" src="' . app::get_baseurl() . '/images/smiley-Oo.gif" alt="o.O" title="o.O" />',
'<img class="smiley" src="' . app::get_baseurl() . '/images/smiley-Oo.gif" alt="O.o" title="O.o" />',
'<img class="smiley" src="' . app::get_baseurl() . '/images/smiley-Oo.gif" alt="o_O" title="o_O" />',
'<img class="smiley" src="' . app::get_baseurl() . '/images/smiley-Oo.gif" alt="O_o" title="O_o" />',
'<img class="smiley" src="' . app::get_baseurl() . '/images/smiley-cry.gif" alt=":\'(" title=":\'("/>',
'<img class="smiley" src="' . app::get_baseurl() . '/images/smiley-foot-in-mouth.gif" alt=":-!" title=":-!" />',
'<img class="smiley" src="' . app::get_baseurl() . '/images/smiley-undecided.gif" alt=":-/" title=":-/" />',
'<img class="smiley" src="' . app::get_baseurl() . '/images/smiley-embarassed.gif" alt=":-[" title=":-[" />',
'<img class="smiley" src="' . app::get_baseurl() . '/images/smiley-cool.gif" alt="8-)" title="8-)" />',
'<img class="smiley" src="' . app::get_baseurl() . '/images/beer_mug.gif" alt=":beer" title=":beer" />',
'<img class="smiley" src="' . app::get_baseurl() . '/images/beer_mug.gif" alt=":homebrew" title=":homebrew" />',
'<img class="smiley" src="' . app::get_baseurl() . '/images/coffee.gif" alt=":coffee" title=":coffee" />',
'<img class="smiley" src="' . app::get_baseurl() . '/images/smiley-facepalm.gif" alt=":facepalm" title=":facepalm" />',
'<img class="smiley" src="' . app::get_baseurl() . '/images/like.gif" alt=":like" title=":like" />',
'<img class="smiley" src="' . app::get_baseurl() . '/images/dislike.gif" alt=":dislike" title=":dislike" />',
'<a href="http://friendica.com">~friendica <img class="smiley" src="' . app::get_baseurl() . '/images/friendica-16.png" alt="~friendica" title="~friendica" /></a>',
'<a href="http://redmatrix.me/">red<img class="smiley" src="' . app::get_baseurl() . '/images/rm-16.png" alt="red#" title="red#" />matrix</a>',
'<a href="http://redmatrix.me/">red<img class="smiley" src="' . app::get_baseurl() . '/images/rm-16.png" alt="red#matrix" title="red#matrix" />matrix</a>'
);
$params = array('texts' => $texts, 'icons' => $icons);

View file

@ -33,7 +33,7 @@ function group_select($selname,$selclass,$preselected = false,$size = 4) {
call_hooks($a->module . '_pre_' . $selname, $arr);
if(dba::is_result($r)) {
if(dbm::is_result($r)) {
foreach($r as $rr) {
if((is_array($preselected)) && in_array($rr['id'], $preselected))
$selected = " selected=\"selected\" ";
@ -144,7 +144,7 @@ function contact_selector($selname, $selclass, $preselected = false, $options) {
call_hooks($a->module . '_pre_' . $selname, $arr);
if(dba::is_result($r)) {
if(dbm::is_result($r)) {
foreach($r as $rr) {
if((is_array($preselected)) && in_array($rr['id'], $preselected))
$selected = " selected=\"selected\" ";
@ -220,7 +220,7 @@ function contact_select($selname, $selclass, $preselected = false, $size = 4, $p
$receiverlist = array();
if(dba::is_result($r)) {
if(dbm::is_result($r)) {
foreach($r as $rr) {
if((is_array($preselected)) && in_array($rr['id'], $preselected))
$selected = " selected=\"selected\" ";
@ -314,7 +314,7 @@ function populate_acl($user = null, $show_jotnets = false) {
$r = q("SELECT `pubmail` FROM `mailacct` WHERE `uid` = %d AND `server` != '' LIMIT 1",
intval(local_user())
);
if(dba::is_result($r)) {
if(dbm::is_result($r)) {
$mail_enabled = true;
if(intval($r[0]['pubmail']))
$pubmail_enabled = true;
@ -399,7 +399,7 @@ function acl_lookup(&$a, $out_type = 'json') {
$count = (x($_REQUEST,'count') ? $_REQUEST['count'] : 100);
$search = (x($_REQUEST,'search') ? $_REQUEST['search'] : "");
$type = (x($_REQUEST,'type') ? $_REQUEST['type'] : "");
$mode = (x($_REQUEST,'mode') ? $_REQUEST['mode'] : "");
$mode = (x($_REQUEST,'smode') ? $_REQUEST['smode'] : "");
$conv_id = (x($_REQUEST,'conversation') ? $_REQUEST['conversation'] : null);
// For use with jquery.textcomplete for private mail completion
@ -481,11 +481,11 @@ function acl_lookup(&$a, $out_type = 'json') {
if ($type=='' || $type=='g'){
$r = q("SELECT `group`.`id`, `group`.`name`, GROUP_CONCAT(DISTINCT `group_member`.`contact-id` SEPARATOR ',') AS uids
FROM `group`,`group_member`
WHERE `group`.`deleted` = 0 AND `group`.`uid` = %d
AND `group_member`.`gid`=`group`.`id`
FROM `group`
INNER JOIN `group_member` ON `group_member`.`gid`=`group`.`id` AND `group_member`.`uid` = `group`.`uid`
WHERE NOT `group`.`deleted` AND `group`.`uid` = %d
$sql_extra
GROUP BY `group`.`id`
GROUP BY `group`.`name`
ORDER BY `group`.`name`
LIMIT %d,%d",
intval(local_user()),
@ -577,7 +577,7 @@ function acl_lookup(&$a, $out_type = 'json') {
$r = array();
if(dba::is_result($r)) {
if(dbm::is_result($r)) {
foreach($r as $g){
$contacts[] = array(
"type" => "c",
@ -612,7 +612,7 @@ function acl_lookup(&$a, $out_type = 'json') {
dbesc($search),
implode("','", $known_contacts)
);
if (dba::is_result($r)){
if (dbm::is_result($r)){
foreach($r as $row) {
// nickname..
$up = parse_url($row['author-link']);
@ -690,7 +690,7 @@ function navbar_complete(&$a) {
$localsearch = get_config('system','poco_local_search');
$search = $prefix.notags(trim($_REQUEST['search']));
$mode = $_REQUEST['mode'];
$mode = $_REQUEST['smode'];
// don't search if search term has less than 2 characters
if(! $search || mb_strlen($search) < 2)

File diff suppressed because it is too large Load diff

View file

@ -50,7 +50,7 @@ if (isset($_SESSION) && x($_SESSION,'authenticated') && (!x($_POST,'auth-params'
$r = q("SELECT * FROM `contact` WHERE `id` = %d LIMIT 1",
intval($_SESSION['visitor_id'])
);
if (dba::is_result($r)) {
if (dbm::is_result($r)) {
$a->contact = $r[0];
}
}
@ -169,7 +169,7 @@ if (isset($_SESSION) && x($_SESSION,'authenticated') && (!x($_POST,'auth-params'
dbesc(trim($_POST['username'])),
dbesc($encrypted)
);
if (dba::is_result($r))
if (dbm::is_result($r))
$record = $r[0];
}

View file

@ -75,7 +75,7 @@ class exAuth
public function __construct($sLogFile, $bDebug)
{
global $db;
global $a, $db;
// setter
$this->sLogFile = $sLogFile;
@ -135,36 +135,30 @@ class exAuth
} else {
// ovdje provjeri prijavu
$sUser = str_replace(array("%20", "(a)"), array(" ", "@"), $aCommand[1]);
$this->writeDebugLog("[debug] doing auth for ". $sUser);
//$sQuery = "SELECT `uid`, `password` FROM `user` WHERE `password`='".hash('whirlpool',$aCommand[3])."' AND `nickname`='". $db->escape($sUser) ."'";
$sQuery = "SELECT `uid`, `password` FROM `user` WHERE `nickname`='". $db->escape($sUser) ."'";
$this->writeDebugLog("[debug] using query ". $sQuery);
if ($oResult = q($sQuery)){
$uid = $oResult[0]["uid"];
$Error = ($oResult[0]["password"] != hash('whirlpool',$aCommand[3]));
/*
if ($oResult[0]["password"] == hash('whirlpool',$aCommand[3])) {
// korisnik OK
$this->writeLog("[exAuth] authentificated user ". $sUser ."@". $aCommand[2]);
fwrite(STDOUT, pack("nn", 2, 1));
} else {
// korisnik nije OK
$this->writeLog("[exAuth] authentification failed for user ". $sUser ."@". $aCommand[2]);
fwrite(STDOUT, pack("nn", 2, 0));
}
$oResult->close();
*/
} else {
$this->writeLog("[MySQL] invalid query: ". $sQuery);
$Error = true;
$uid = -1;
}
if ($Error) {
$oConfig = q("SELECT `v` FROM `pconfig` WHERE `uid`=%d AND `cat` = 'xmpp' AND `k`='password' LIMIT 1;", intval($uid));
$this->writeLog("[exAuth] got password ".$oConfig[0]["v"]);
$Error = ($aCommand[3] != $oConfig[0]["v"]);
}
$this->writeDebugLog("[debug] doing auth for ".$sUser."@".$aCommand[2]);
// If the hostnames doesn't match, we try to authenticate remotely
if ($a->get_hostname() != $aCommand[2])
$Error = !$this->check_credentials($aCommand[2], $aCommand[1], $aCommand[3], true);
else {
//$sQuery = "SELECT `uid`, `password` FROM `user` WHERE `password`='".hash('whirlpool',$aCommand[3])."' AND `nickname`='". $db->escape($sUser) ."'";
$sQuery = "SELECT `uid`, `password` FROM `user` WHERE `nickname`='". $db->escape($sUser) ."'";
$this->writeDebugLog("[debug] using query ". $sQuery);
if ($oResult = q($sQuery)){
$uid = $oResult[0]["uid"];
$Error = ($oResult[0]["password"] != hash('whirlpool',$aCommand[3]));
} else {
$this->writeLog("[MySQL] invalid query: ". $sQuery);
$Error = true;
$uid = -1;
}
if ($Error) {
$oConfig = q("SELECT `v` FROM `pconfig` WHERE `uid`=%d AND `cat` = 'xmpp' AND `k`='password' LIMIT 1;", intval($uid));
$this->writeLog("[exAuth] got password ".$oConfig[0]["v"]);
$Error = ($aCommand[3] != $oConfig[0]["v"]);
}
}
if ($Error) {
$this->writeLog("[exAuth] authentification failed for user ". $sUser ."@". $aCommand[2]);
fwrite(STDOUT, pack("nn", 2, 0));
@ -207,6 +201,27 @@ class exAuth
}
}
private function check_credentials($host, $user, $password, $ssl) {
$url = ($ssl ? "https":"http")."://".$host."/api/account/verify_credentials.json";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_NOBODY, true);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($ch, CURLOPT_USERPWD, $user.':'.$password);
$header = curl_exec($ch);
$curl_info = @curl_getinfo($ch);
$http_code = $curl_info["http_code"];
curl_close($ch);
return($http_code == 200);
}
private function writeLog($sMessage)
{
if (is_resource($this->rLogFile)) {

View file

@ -6,4 +6,5 @@ $vendorDir = dirname(dirname(dirname(__FILE__)))."/library";
$baseDir = dirname($vendorDir);
return array(
'Friendica\\' => array($baseDir . '/include'),
);

View file

@ -34,7 +34,6 @@ function bb_map_location($match) {
function bb_attachment($Text, $simplehtml = false, $tryoembed = true) {
$data = get_attachment_data($Text);
if (!$data)
return $Text;
@ -85,7 +84,7 @@ function bb_attachment($Text, $simplehtml = false, $tryoembed = true) {
$text .= $oembed;
if (trim($data["description"]) != "")
$text .= sprintf('<blockquote>%s</blockquote></span>', trim($data["description"]));
$text .= sprintf('<blockquote>%s</blockquote></span>', trim(bbcode($data["description"])));
}
}
return $data["text"].$text.$data["after"];
@ -101,8 +100,14 @@ function bb_remove_share_information($Text, $plaintext = false, $nolink = false)
if ($nolink)
return $data["text"].$data["after"];
if ($plaintext)
$title = htmlentities($data["title"], ENT_QUOTES, 'UTF-8', false);
$text = htmlentities($data["text"], ENT_QUOTES, 'UTF-8', false);
if ($plaintext OR (($title != "") AND strstr($text, $title)))
$data["title"] = $data["url"];
elseif (($text != "") AND strstr($title, $text)) {
$data["text"] = $data["title"];
$data["title"] = $data["url"];
}
if (($data["text"] == "") AND ($data["title"] != "") AND ($data["url"] == ""))
return $data["title"].$data["after"];
@ -115,10 +120,10 @@ function bb_remove_share_information($Text, $plaintext = false, $nolink = false)
if (($data["url"] != "") AND ($data["title"] != ""))
$text .= "\n[url=".$data["url"]."]".$data["title"]."[/url]";
elseif (($link != ""))
elseif (($data["url"] != ""))
$text .= "\n".$data["url"];
return $text.$data["after"];
return $text."\n".$data["after"];
}
function bb_cleanstyle($st) {
@ -390,36 +395,40 @@ function bb_ShareAttributes($share, $simplehtml) {
$itemcache = get_itemcachepath();
preg_match("/posted='(.*?)'/ism", $attributes, $matches);
if ($matches[1] != "")
$posted = $matches[1];
preg_match('/posted="(.*?)"/ism', $attributes, $matches);
if ($matches[1] != "")
$posted = $matches[1];
// relative dates only make sense when they aren't cached
if ($itemcache == "") {
preg_match("/posted='(.*?)'/ism", $attributes, $matches);
if ($matches[1] != "")
$posted = $matches[1];
preg_match('/posted="(.*?)"/ism', $attributes, $matches);
if ($matches[1] != "")
$posted = $matches[1];
if ($itemcache == "")
$reldate = (($posted) ? " " . relative_date($posted) : '');
}
// We only call this so that a previously unknown contact can be added.
// This is important for the function "get_contact_details_by_url".
// This function then can fetch an entry from the contact table.
get_contact($profile, 0);
$data = get_contact_details_by_url($profile);
if (isset($data["name"]) AND isset($data["addr"]))
if (isset($data["name"]) AND ($data["name"] != "") AND isset($data["addr"]) AND ($data["addr"] != ""))
$userid_compact = $data["name"]." (".$data["addr"].")";
else
$userid_compact = GetProfileUsername($profile,$author, true);
if (isset($data["addr"]))
if (isset($data["addr"]) AND ($data["addr"] != ""))
$userid = $data["addr"];
else
$userid = GetProfileUsername($profile,$author, false);
if (isset($data["name"]))
if (isset($data["name"]) AND ($data["name"] != ""))
$author = $data["name"];
if (isset($data["photo"]))
$avatar = $data["photo"];
if (isset($data["micro"]) AND ($data["micro"] != ""))
$avatar = $data["micro"];
$preshare = trim($share[1]);
@ -483,13 +492,22 @@ function bb_ShareAttributes($share, $simplehtml) {
$text .= "<br /><br />".$link;
break;
default:
$headline = trim($share[1]).'<div class="shared_header">';
if ($avatar != "")
$headline .= '<img src="'.proxy_url($avatar, false, PROXY_SIZE_MICRO).'" height="32" width="32" >';
$text = trim($share[1])."\n";
$headline .= sprintf(t('<span><a href="%s" target="_blank">%s</a> wrote the following <a href="%s" target="_blank">post</a>'.$reldate.':</span>'), $profile, $author, $link);
$headline .= "</div>";
$text = $headline.'<blockquote class="shared_content">'.trim($share[3])."</blockquote>";
$avatar = proxy_url($avatar, false, PROXY_SIZE_THUMB);
$tpl = get_markup_template('shared_content.tpl');
$text .= replace_macros($tpl,
array(
'$profile' => $profile,
'$avatar' => $avatar,
'$author' => $author,
'$link' => $link,
'$posted' => $posted,
'$reldate' => $reldate,
'$content' => trim($share[3])
)
);
break;
}
return($text);
@ -705,6 +723,13 @@ function bb_CleanPictureLinks($text) {
return ($text);
}
function bb_highlight($match) {
if(in_array(strtolower($match[1]),['php','css','mysql','sql','abap','diff','html','perl','ruby',
'vbscript','avrc','dtd','java','xml','cpp','python','javascript','js','sh']))
return text_highlight($match[2],strtolower($match[1]));
return $match[0];
}
// BBcode 2 HTML was written by WAY2WEB.net
// extended to work with Mistpark/Friendica - Mike Macgirvin
@ -757,6 +782,11 @@ function bbcode($Text,$preserve_nl = false, $tryoembed = true, $simplehtml = fal
if (!$tryoembed)
$Text = preg_replace("/\[share(.*?)avatar\s?=\s?'.*?'\s?(.*?)\]\s?(.*?)\s?\[\/share\]\s?/ism","\n[share$1$2]$3[/share]",$Text);
// Check for [code] text here, before the linefeeds are messed with.
// The highlighter will unescape and re-escape the content.
if (strpos($Text,'[code=') !== false) {
$Text = preg_replace_callback("/\[code=(.*?)\](.*?)\[\/code\]/ism", 'bb_highlight', $Text);
}
// Convert new line chars to html <br /> tags
// nlbr seems to be hopelessly messed up
@ -803,7 +833,10 @@ function bbcode($Text,$preserve_nl = false, $tryoembed = true, $simplehtml = fal
$Text = preg_replace("/([@])\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism",
'$1<span class="vcard"><a href="$2" class="url" title="$3"><span class="fn nickname mention">$3</span></a></span>',
$Text);
elseif (!$simplehtml)
$Text = preg_replace("/([@])\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism",
'$1<a href="$2" class="userinfo mention" title="$3">$3</a>',
$Text);
// Bookmarks in red - will be converted to bookmarks in friendica
$Text = preg_replace("/#\^\[url\]([$URLSearchString]*)\[\/url\]/ism", '[bookmark=$1]$1[/bookmark]', $Text);
@ -845,6 +878,9 @@ function bbcode($Text,$preserve_nl = false, $tryoembed = true, $simplehtml = fal
if ($tryoembed)
$Text = preg_replace_callback("/\[url\]([$URLSearchString]*)\[\/url\]/ism",'tryoembed',$Text);
$Text = preg_replace("/([#])\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism",
'$1<a href="$2" class="tag" title="$3">$3</a>', $Text);
$Text = preg_replace("/\[url\]([$URLSearchString]*)\[\/url\]/ism", '<a href="$1" target="_blank">$1</a>', $Text);
$Text = preg_replace("/\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism", '<a href="$1" target="_blank">$2</a>', $Text);
//$Text = preg_replace("/\[url\=([$URLSearchString]*)\]([$URLSearchString]*)\[\/url\]/ism", '<a href="$1" target="_blank">$2</a>', $Text);
@ -884,6 +920,9 @@ function bbcode($Text,$preserve_nl = false, $tryoembed = true, $simplehtml = fal
$Text = preg_replace("(\[h5\](.*?)\[\/h5\])ism",'<h5>$1</h5>',$Text);
$Text = preg_replace("(\[h6\](.*?)\[\/h6\])ism",'<h6>$1</h6>',$Text);
// Check for paragraph
$Text = preg_replace("(\[p\](.*?)\[\/p\])ism",'<p>$1</p>',$Text);
// Check for bold text
$Text = preg_replace("(\[b\](.*?)\[\/b\])ism",'<strong>$1</strong>',$Text);
@ -1103,6 +1142,7 @@ function bbcode($Text,$preserve_nl = false, $tryoembed = true, $simplehtml = fal
$Text = preg_replace("/\[event\-finish\](.*?)\[\/event\-finish\]/ism",'',$Text);
$Text = preg_replace("/\[event\-location\](.*?)\[\/event\-location\]/ism",'',$Text);
$Text = preg_replace("/\[event\-adjust\](.*?)\[\/event\-adjust\]/ism",'',$Text);
$Text = preg_replace("/\[event\-id\](.*?)\[\/event\-id\]/ism",'',$Text);
}

View file

@ -10,7 +10,7 @@
dbesc($key)
);
if (dba::is_result($r))
if (dbm::is_result($r))
return $r[0]['v'];
return null;
@ -38,7 +38,7 @@
* $r = q("SELECT * FROM `cache` WHERE `k`='%s' limit 1",
* dbesc($key)
* );
* if(dba::is_result($r)) {
* if(dbm::is_result($r)) {
* q("UPDATE `cache` SET `v` = '%s', `updated = '%s' WHERE `k` = '%s'",
* dbesc($value),
* dbesc(datetime_convert()),

View file

@ -11,7 +11,7 @@ function cli_startup() {
if(is_null($a)) {
$a = new App;
}
if(is_null($db)) {
@include(".htconfig.php");
require_once("dba.php");

View file

@ -1,8 +1,8 @@
<?php
/**
*
* Arbitrary configuration storage
* @file include/config.php
*
* @brief (Deprecated) Arbitrary configuration storage
* Note:
* Please do not store booleans - convert to 0/1 integer values
* The get_?config() functions return boolean false for keys that are unset,
@ -12,330 +12,140 @@
* configurations need to be fixed as of 10/08/2011.
*/
use \Friendica\Core\Config;
use \Friendica\Core\PConfig;
// retrieve a "family" of config variables from database to cached storage
if(! function_exists('load_config')) {
/**
* @brief (Deprecated) Loads all configuration values of family into a cached storage.
*
* Note: This function is deprecated. Use Config::load() instead.
*
* @param string $family
* The category of the configuration value
* @return void
*/
function load_config($family) {
global $a;
return Config::load($family);
}
$r = q("SELECT `v`, `k` FROM `config` WHERE `cat` = '%s'", dbesc($family));
if(dba::is_result($r)) {
foreach($r as $rr) {
$k = $rr['k'];
if ($family === 'config') {
$a->config[$k] = $rr['v'];
} else {
$a->config[$family][$k] = $rr['v'];
}
}
} else if ($family != 'config') {
// Negative caching
$a->config[$family] = "!<unset>!";
}
}}
/**
* @brief (Deprecated) Get a particular user's config variable given the category name
* ($family) and a key.
*
* Note: This function is deprecated. Use Config::get() instead.
*
* @param string $family
* The category of the configuration value
* @param string $key
* The configuration key to query
* @param boolean $refresh
* If true the config is loaded from the db and not from the cache
* @return mixed Stored value or false if it does not exist
*/
function get_config($family, $key, $refresh = false) {
$v = Config::get($family, $key, false, $refresh);
return $v;
}
// get a particular config variable given the family name
// and key. Returns false if not set.
// $instore is only used by the set_config function
// to determine if the key already exists in the DB
// If a key is found in the DB but doesn't exist in
// local config cache, pull it into the cache so we don't have
// to hit the DB again for this item.
if(! function_exists('get_config')) {
function get_config($family, $key, $instore = false) {
global $a;
if(! $instore) {
// Looking if the whole family isn't set
if(isset($a->config[$family])) {
if($a->config[$family] === '!<unset>!') {
return false;
}
}
if(isset($a->config[$family][$key])) {
if($a->config[$family][$key] === '!<unset>!') {
return false;
}
return $a->config[$family][$key];
}
}
// If APC is enabled then fetch the data from there, else try XCache
/*if (function_exists("apc_fetch") AND function_exists("apc_exists"))
if (apc_exists($family."|".$key)) {
$val = apc_fetch($family."|".$key);
$a->config[$family][$key] = $val;
if ($val === '!<unset>!')
return false;
else
return $val;
}
elseif (function_exists("xcache_fetch") AND function_exists("xcache_isset"))
if (xcache_isset($family."|".$key)) {
$val = xcache_fetch($family."|".$key);
$a->config[$family][$key] = $val;
if ($val === '!<unset>!')
return false;
else
return $val;
}
*/
$ret = q("SELECT `v` FROM `config` WHERE `cat` = '%s' AND `k` = '%s' LIMIT 1",
dbesc($family),
dbesc($key)
);
if(count($ret)) {
// manage array value
$val = (preg_match("|^a:[0-9]+:{.*}$|s", $ret[0]['v'])?unserialize( $ret[0]['v']):$ret[0]['v']);
$a->config[$family][$key] = $val;
// If APC is enabled then store the data there, else try XCache
/*if (function_exists("apc_store"))
apc_store($family."|".$key, $val, 600);
elseif (function_exists("xcache_set"))
xcache_set($family."|".$key, $val, 600);*/
return $val;
}
else {
$a->config[$family][$key] = '!<unset>!';
// If APC is enabled then store the data there, else try XCache
/*if (function_exists("apc_store"))
apc_store($family."|".$key, '!<unset>!', 600);
elseif (function_exists("xcache_set"))
xcache_set($family."|".$key, '!<unset>!', 600);*/
}
return false;
}}
// Store a config value ($value) in the category ($family)
// under the key ($key)
// Return the value, or false if the database update failed
if(! function_exists('set_config')) {
/**
* @brief (Deprecated) Sets a configuration value for system config
*
* Note: This function is deprecated. Use Config::set() instead.
*
* @param string $family
* The category of the configuration value
* @param string $key
* The configuration key to set
* @param string $value
* The value to store
* @return mixed Stored $value or false if the database update failed
*/
function set_config($family,$key,$value) {
global $a;
return Config::set($family, $key, $value);
}
// If $a->config[$family] has been previously set to '!<unset>!', then
// $a->config[$family][$key] will evaluate to $a->config[$family][0], and
// $a->config[$family][$key] = $value will be equivalent to
// $a->config[$family][0] = $value[0] (this causes infuriating bugs),
// so unset the family before assigning a value to a family's key
if($a->config[$family] === '!<unset>!')
unset($a->config[$family]);
// manage array value
$dbvalue = (is_array($value)?serialize($value):$value);
$dbvalue = (is_bool($dbvalue) ? intval($dbvalue) : $dbvalue);
if(get_config($family,$key,true) === false) {
$a->config[$family][$key] = $value;
$ret = q("INSERT INTO `config` ( `cat`, `k`, `v` ) VALUES ( '%s', '%s', '%s' ) ",
dbesc($family),
dbesc($key),
dbesc($dbvalue)
);
if($ret)
return $value;
return $ret;
}
$ret = q("UPDATE `config` SET `v` = '%s' WHERE `cat` = '%s' AND `k` = '%s'",
dbesc($dbvalue),
dbesc($family),
dbesc($key)
);
$a->config[$family][$key] = $value;
// If APC is enabled then store the data there, else try XCache
/*if (function_exists("apc_store"))
apc_store($family."|".$key, $value, 600);
elseif (function_exists("xcache_set"))
xcache_set($family."|".$key, $value, 600);*/
if($ret)
return $value;
return $ret;
}}
if(! function_exists('load_pconfig')) {
function load_pconfig($uid,$family) {
global $a;
$r = q("SELECT `v`,`k` FROM `pconfig` WHERE `cat` = '%s' AND `uid` = %d",
dbesc($family),
intval($uid)
);
if(dba::is_result($r)) {
foreach($r as $rr) {
$k = $rr['k'];
$a->config[$uid][$family][$k] = $rr['v'];
}
} else if ($family != 'config') {
// Negative caching
$a->config[$uid][$family] = "!<unset>!";
}
}}
if(! function_exists('get_pconfig')) {
function get_pconfig($uid,$family, $key, $instore = false) {
global $a;
if(! $instore) {
// Looking if the whole family isn't set
if(isset($a->config[$uid][$family])) {
if($a->config[$uid][$family] === '!<unset>!') {
return false;
}
}
if(isset($a->config[$uid][$family][$key])) {
if($a->config[$uid][$family][$key] === '!<unset>!') {
return false;
}
return $a->config[$uid][$family][$key];
}
}
// If APC is enabled then fetch the data from there, else try XCache
/*if (function_exists("apc_fetch") AND function_exists("apc_exists"))
if (apc_exists($uid."|".$family."|".$key)) {
$val = apc_fetch($uid."|".$family."|".$key);
$a->config[$uid][$family][$key] = $val;
if ($val === '!<unset>!')
return false;
else
return $val;
}
elseif (function_exists("xcache_get") AND function_exists("xcache_isset"))
if (xcache_isset($uid."|".$family."|".$key)) {
$val = xcache_get($uid."|".$family."|".$key);
$a->config[$uid][$family][$key] = $val;
if ($val === '!<unset>!')
return false;
else
return $val;
}*/
$ret = q("SELECT `v` FROM `pconfig` WHERE `uid` = %d AND `cat` = '%s' AND `k` = '%s' LIMIT 1",
intval($uid),
dbesc($family),
dbesc($key)
);
if(count($ret)) {
$val = (preg_match("|^a:[0-9]+:{.*}$|s", $ret[0]['v'])?unserialize( $ret[0]['v']):$ret[0]['v']);
$a->config[$uid][$family][$key] = $val;
// If APC is enabled then store the data there, else try XCache
/*if (function_exists("apc_store"))
apc_store($uid."|".$family."|".$key, $val, 600);
elseif (function_exists("xcache_set"))
xcache_set($uid."|".$family."|".$key, $val, 600);*/
return $val;
}
else {
$a->config[$uid][$family][$key] = '!<unset>!';
// If APC is enabled then store the data there, else try XCache
/*if (function_exists("apc_store"))
apc_store($uid."|".$family."|".$key, '!<unset>!', 600);
elseif (function_exists("xcache_set"))
xcache_set($uid."|".$family."|".$key, '!<unset>!', 600);*/
}
return false;
}}
if(! function_exists('del_config')) {
/**
* @brief (Deprecated) Deletes the given key from the system configuration.
*
* Note: This function is deprecated. Use Config::delete() instead.
*
* @param string $family
* The category of the configuration value
* @param string $key
* The configuration key to delete
* @return mixed
*/
function del_config($family,$key) {
return Config::delete($family, $key);
}
global $a;
if(x($a->config[$family],$key))
unset($a->config[$family][$key]);
$ret = q("DELETE FROM `config` WHERE `cat` = '%s' AND `k` = '%s'",
dbesc($family),
dbesc($key)
);
// If APC is enabled then delete the data from there, else try XCache
/*if (function_exists("apc_delete"))
apc_delete($family."|".$key);
elseif (function_exists("xcache_unset"))
xcache_unset($family."|".$key);*/
/**
* @brief (Deprecated) Loads all configuration values of a user's config family into a cached storage.
*
* Note: This function is deprecated. Use PConfig::load() instead.
*
* @param string $uid
* The user_id
* @param string $family
* The category of the configuration value
* @return void
*/
function load_pconfig($uid,$family) {
return PConfig::load($uid, $family);
}
return $ret;
}}
/**
* @brief (Deprecated) Get a particular user's config variable given the category name
* ($family) and a key.
*
* Note: This function is deprecated. Use PConfig::get() instead.
*
* @param string $uid
* The user_id
* @param string $family
* The category of the configuration value
* @param string $key
* The configuration key to query
* @param boolean $refresh
* If true the config is loaded from the db and not from the cache
* @return mixed Stored value or false if it does not exist
*/
function get_pconfig($uid, $family, $key, $refresh = false) {
$v = PConfig::get($uid, $family, $key, false, $refresh);
return $v;
}
// Same as above functions except these are for personal config storage and take an
// additional $uid argument.
if(! function_exists('set_pconfig')) {
/**
* @brief (Deprecated) Sets a configuration value for a user
*
* Note: This function is deprecated. Use PConfig::set() instead.
*
* @param string $uid
* The user_id
* @param string $family
* The category of the configuration value
* @param string $key
* The configuration key to set
* @param string $value
* The value to store
* @return mixed Stored $value or false
*/
function set_pconfig($uid,$family,$key,$value) {
return PConfig::set($uid, $family, $key, $value);
}
global $a;
// manage array value
$dbvalue = (is_array($value)?serialize($value):$value);
if(get_pconfig($uid,$family,$key,true) === false) {
$a->config[$uid][$family][$key] = $value;
$ret = q("INSERT INTO `pconfig` ( `uid`, `cat`, `k`, `v` ) VALUES ( %d, '%s', '%s', '%s' ) ",
intval($uid),
dbesc($family),
dbesc($key),
dbesc($dbvalue)
);
if($ret)
return $value;
return $ret;
}
$ret = q("UPDATE `pconfig` SET `v` = '%s' WHERE `uid` = %d AND `cat` = '%s' AND `k` = '%s'",
dbesc($dbvalue),
intval($uid),
dbesc($family),
dbesc($key)
);
$a->config[$uid][$family][$key] = $value;
// If APC is enabled then store the data there, else try XCache
/*if (function_exists("apc_store"))
apc_store($uid."|".$family."|".$key, $value, 600);
elseif (function_exists("xcache_set"))
xcache_set($uid."|".$family."|".$key, $value, 600);*/
if($ret)
return $value;
return $ret;
}}
if(! function_exists('del_pconfig')) {
/**
* @brief (Deprecated) Deletes the given key from the users's configuration.
*
* Note: This function is deprecated. Use PConfig::delete() instead.
*
* @param string $uid The user_id
* @param string $family
* The category of the configuration value
* @param string $key
* The configuration key to delete
* @return mixed
*/
function del_pconfig($uid,$family,$key) {
global $a;
if(x($a->config[$uid][$family],$key))
unset($a->config[$uid][$family][$key]);
$ret = q("DELETE FROM `pconfig` WHERE `uid` = %d AND `cat` = '%s' AND `k` = '%s'",
intval($uid),
dbesc($family),
dbesc($key)
);
return $ret;
}}
return PConfig::delete($uid, $family, $key);
}

View file

@ -7,12 +7,12 @@ function contact_profile_assign($current,$foreign_net) {
$disabled = (($foreign_net) ? ' disabled="true" ' : '');
$o .= "<select id=\"contact-profile-selector\" $disabled name=\"profile-assign\" />\r\n";
$o .= "<select id=\"contact-profile-selector\" class=\"form-control\" $disabled name=\"profile-assign\" />\r\n";
$r = q("SELECT `id`, `profile-name` FROM `profile` WHERE `uid` = %d",
intval($_SESSION['uid']));
intval($_SESSION['uid']));
if(dba::is_result($r)) {
if(dbm::is_result($r)) {
foreach($r as $rr) {
$selected = (($rr['id'] == $current) ? " selected=\"selected\" " : "");
$o .= "<option value=\"{$rr['id']}\" $selected >{$rr['profile-name']}</option>\r\n";

View file

@ -93,7 +93,7 @@ function networks_widget($baseurl,$selected = '') {
);
$nets = array();
if(dba::is_result($r)) {
if(dbm::is_result($r)) {
require_once('include/contact_selectors.php');
foreach($r as $rr) {
if($rr['network'])
@ -204,13 +204,13 @@ function common_friends_visitor_widget($profile_uid) {
dbesc(normalise_link(get_my_url())),
intval($profile_uid)
);
if(dba::is_result($r))
if(dbm::is_result($r))
$cid = $r[0]['id'];
else {
$r = q("select id from gcontact where nurl = '%s' limit 1",
dbesc(normalise_link(get_my_url()))
);
if(dba::is_result($r))
if(dbm::is_result($r))
$zcid = $r[0]['id'];
}
}

View file

@ -373,6 +373,84 @@ function visible_activity($item) {
return true;
}
/**
* @brief SQL query for items
*/
function item_query() {
return "SELECT ".item_fieldlists()." FROM `item` ".
item_joins()." WHERE ".item_condition();
}
/**
* @brief List of all data fields that are needed for displaying items
*/
function item_fieldlists() {
/*
These Fields are not added below (yet). They are here to for bug search.
`item`.`type`,
`item`.`extid`,
`item`.`received`,
`item`.`changed`,
`item`.`moderated`,
`item`.`target-type`,
`item`.`target`,
`item`.`resource-id`,
`item`.`tag`,
`item`.`inform`,
`item`.`pubmail`,
`item`.`visible`,
`item`.`spam`,
`item`.`bookmark`,
`item`.`unseen`,
`item`.`deleted`,
`item`.`origin`,
`item`.`forum_mode`,
`item`.`last-child`,
`item`.`mention`,
`item`.`global`,
`item`.`gcontact-id`,
`item`.`shadow`,
*/
return "`item`.`author-link`, `item`.`author-name`, `item`.`author-avatar`,
`item`.`owner-link`, `item`.`owner-name`, `item`.`owner-avatar`,
`item`.`contact-id`, `item`.`uid`, `item`.`id`, `item`.`parent`,
`item`.`uri`, `item`.`thr-parent`, `item`.`parent-uri`,
`item`.`commented`, `item`.`created`, `item`.`edited`,
`item`.`verb`, `item`.`object-type`, `item`.`postopts`, `item`.`plink`,
`item`.`guid`, `item`.`wall`, `item`.`private`, `item`.`starred`,
`item`.`title`, `item`.`body`, `item`.`file`, `item`.`event-id`,
`item`.`location`, `item`.`coord`, `item`.`app`, `item`.`attach`,
`item`.`rendered-hash`, `item`.`rendered-html`, `item`.`object`,
`item`.`allow_cid`, `item`.`allow_gid`, `item`.`deny_cid`, `item`.`deny_gid`,
`item`.`id` AS `item_id`, `item`.`network` AS `item_network`,
`author`.`thumb` AS `author-thumb`, `owner`.`thumb` AS `owner-thumb`,
`contact`.`network`, `contact`.`url`, `contact`.`name`, `contact`.`writable`,
`contact`.`self`, `contact`.`id` AS `cid`, `contact`.`alias`";
}
/**
* @brief SQL join for contacts that are needed for displaying items
*/
function item_joins() {
return "STRAIGHT_JOIN `contact` ON `contact`.`id` = `item`.`contact-id` AND
NOT `contact`.`blocked` AND NOT `contact`.`pending`
LEFT JOIN `contact` AS `author` ON `author`.`id`=`item`.`author-id`
LEFT JOIN `contact` AS `owner` ON `owner`.`id`=`item`.`owner-id`";
}
/**
* @brief SQL condition for items that are needed for displaying items
*/
function item_condition() {
return "`item`.`visible` AND NOT `item`.`deleted` AND NOT `item`.`moderated`";
}
/**
* "Render" a conversation or list of items for HTML display.
@ -389,6 +467,7 @@ if(!function_exists('conversation')) {
function conversation(&$a, $items, $mode, $update, $preview = false) {
require_once('include/bbcode.php');
require_once('include/Contact.php');
require_once('mod/proxy.php');
$ssl_state = ((local_user()) ? true : false);
@ -494,8 +573,6 @@ function conversation(&$a, $items, $mode, $update, $preview = false) {
else
$return_url = $_SESSION['return_url'] = $a->query_string;
load_contact_links(local_user());
$cb = array('items' => $items, 'mode' => $mode, 'update' => $update, 'preview' => $preview);
call_hooks('conversation_start',$cb);
@ -544,7 +621,6 @@ function conversation(&$a, $items, $mode, $update, $preview = false) {
$comment = '';
$owner_url = '';
$owner_photo = '';
$owner_name = '';
$sparkle = '';
@ -589,18 +665,6 @@ function conversation(&$a, $items, $mode, $update, $preview = false) {
$tags[] = $prefix."<a href=\"".$tag["url"]."\" target=\"_blank\">".$tag["term"]."</a>";
}
/*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;
}
}*/
$sp = false;
$profile_link = best_link_url($item,$sp);
if($profile_link === 'mailbox')
@ -610,11 +674,21 @@ function conversation(&$a, $items, $mode, $update, $preview = false) {
else
$profile_link = zrl($profile_link);
$normalised = normalise_link((strlen($item['author-link'])) ? $item['author-link'] : $item['url']);
if(($normalised != 'mailbox') && (x($a->contacts[$normalised])))
$profile_avatar = $a->contacts[$normalised]['thumb'];
else
$profile_avatar = $a->remove_baseurl(((strlen($item['author-avatar'])) ? $item['author-avatar'] : $item['thumb']));
if (!isset($item['author-thumb']) OR ($item['author-thumb'] == "")) {
$author_contact = get_contact_details_by_url($item['author-link'], $profile_owner);
if ($author_contact["thumb"])
$item['author-thumb'] = $author_contact["thumb"];
else
$item['author-thumb'] = $item['author-avatar'];
}
if (!isset($item['owner-thumb']) OR ($item['owner-thumb'] == "")) {
$owner_contact = get_contact_details_by_url($item['owner-link'], $profile_owner);
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);
@ -668,17 +742,21 @@ function conversation(&$a, $items, $mode, $update, $preview = false) {
$owner_name_e = $owner_name;
}
if ($item['item_network'] == "")
$item['item_network'] = $item['network'];
$tmp_item = array(
'template' => $tpl,
'id' => (($preview) ? 'P0' : $item['item_id']),
'network' => $item['item_network'],
'network_name' => network_to_name($item['item_network'], $profile_link),
'linktitle' => sprintf( t('View %s\'s profile @ %s'), $profile_name, ((strlen($item['author-link'])) ? $item['author-link'] : $item['url'])),
'profile_url' => $profile_link,
'item_photo_menu' => item_photo_menu($item),
'name' => $profile_name_e,
'sparkle' => $sparkle,
'lock' => $lock,
'thumb' => proxy_url($profile_avatar, false, PROXY_SIZE_THUMB),
'thumb' => App::remove_baseurl(proxy_url($item['author-thumb'], false, PROXY_SIZE_THUMB)),
'title' => $item['title_e'],
'body' => $body_e,
'tags' => $tags_e,
@ -697,7 +775,7 @@ function conversation(&$a, $items, $mode, $update, $preview = false) {
'indent' => '',
'owner_name' => $owner_name_e,
'owner_url' => $owner_url,
'owner_photo' => proxy_url($owner_photo, false, PROXY_SIZE_THUMB),
'owner_photo' => App::remove_baseurl(proxy_url($item['owner-thumb'], false, PROXY_SIZE_THUMB)),
'plink' => get_plink($item),
'edpost' => false,
'isstarred' => $isstarred,
@ -801,23 +879,13 @@ function conversation(&$a, $items, $mode, $update, $preview = false) {
function best_link_url($item,&$sparkle,$ssl_state = false) {
$a = get_app();
$best_url = '';
$sparkle = false;
$clean_url = normalise_link($item['author-link']);
if((local_user()) && (local_user() == $item['uid'])) {
if(isset($a->contacts) && x($a->contacts,$clean_url)) {
if($a->contacts[$clean_url]['network'] === NETWORK_DFRN) {
$best_url = 'redir/'.$a->contacts[$clean_url]['id'];
$sparkle = true;
} else
$best_url = $a->contacts[$clean_url]['url'];
}
} elseif (local_user()) {
$r = q("SELECT `id` FROM `contact` WHERE `network` = '%s' AND `uid` = %d AND `nurl` = '%s' LIMIT 1",
if (local_user()) {
$r = q("SELECT `id` FROM `contact` WHERE `network` = '%s' AND `uid` = %d AND `nurl` = '%s' AND NOT `pending` LIMIT 1",
dbesc(NETWORK_DFRN), intval(local_user()), dbesc(normalise_link($clean_url)));
if ($r) {
$best_url = 'redir/'.$r[0]['id'];
@ -837,15 +905,12 @@ function best_link_url($item,&$sparkle,$ssl_state = false) {
if(! function_exists('item_photo_menu')){
function item_photo_menu($item){
$a = get_app();
$ssl_state = false;
if(local_user()) {
if(local_user())
$ssl_state = true;
if(! count($a->contacts))
load_contact_links(local_user());
}
$sub_link="";
$poke_link="";
$contact_url="";
@ -853,6 +918,7 @@ function item_photo_menu($item){
$status_link="";
$photos_link="";
$posts_link="";
$network = "";
if((local_user()) && local_user() == $item['uid'] && $item['parent'] == $item['id'] && (! $item['self'])) {
$sub_link = 'javascript:dosubthread(' . $item['id'] . '); return false;';
@ -863,46 +929,32 @@ function item_photo_menu($item){
if($profile_link === 'mailbox')
$profile_link = '';
$cid = 0;
$network = "";
$rel = 0;
$r = q("SELECT `id`, `network`, `rel` FROM `contact` WHERE `uid` = %d AND `nurl` = '%s' LIMIT 1",
intval(local_user()), dbesc(normalise_link($item['author-link'])));
if ($r) {
$cid = $r[0]["id"];
$network = $r[0]["network"];
$rel = $r[0]["rel"];
}
if($sparkle) {
$cid = intval(basename($profile_link));
$status_link = $profile_link . "?url=status";
$photos_link = $profile_link . "?url=photos";
$profile_link = $profile_link . "?url=profile";
$pm_url = 'message/new/' . $cid;
$status_link = $profile_link."?url=status";
$photos_link = $profile_link."?url=photos";
$profile_link = $profile_link."?url=profile";
$zurl = '';
}
else {
} else
$profile_link = zrl($profile_link);
if(local_user() && local_user() == $item['uid'] && link_compare($item['url'],$item['author-link'])) {
$cid = $item['contact-id'];
} else {
$r = q("SELECT `id`, `network` FROM `contact` WHERE `uid` = %d AND `nurl` = '%s' LIMIT 1",
intval(local_user()), dbesc(normalise_link($item['author-link'])));
if ($r) {
$cid = $r[0]["id"];
if ($r[0]["network"] == NETWORK_DIASPORA)
$pm_url = 'message/new/' . $cid;
} else
$cid = 0;
}
}
if(($cid) && (! $item['self'])) {
$poke_link = 'poke/?f=&c=' . $cid;
$contact_url = 'contacts/' . $cid;
$posts_link = 'contacts/' . $cid . '/posts';
$clean_url = normalise_link($item['author-link']);
if((local_user()) && (local_user() == $item['uid'])) {
if(isset($a->contacts) && x($a->contacts,$clean_url)) {
if($a->contacts[$clean_url]['network'] === NETWORK_DIASPORA) {
$pm_url = 'message/new/' . $cid;
}
}
}
if($cid && !$item['self']) {
$poke_link = 'poke/?f=&c='.$cid;
$contact_url = 'contacts/'.$cid;
$posts_link = 'contacts/'.$cid.'/posts';
if (in_array($network, array(NETWORK_DFRN, NETWORK_DIASPORA)))
$pm_url = 'message/new/'.$cid;
}
if (local_user()) {
@ -916,10 +968,10 @@ function item_photo_menu($item){
t("Send PM") => $pm_url
);
if ($a->contacts[$clean_url]['network'] === NETWORK_DFRN)
if ($network == NETWORK_DFRN)
$menu[t("Poke")] = $poke_link;
if ((($cid == 0) OR ($a->contacts[$clean_url]['rel'] == CONTACT_IS_FOLLOWER)) AND
if ((($cid == 0) OR ($rel == CONTACT_IS_FOLLOWER)) AND
in_array($item['network'], array(NETWORK_DFRN, NETWORK_OSTATUS, NETWORK_DIASPORA)))
$menu[t("Connect/Follow")] = "follow?url=".urlencode($item['author-link']);
} else
@ -1228,6 +1280,10 @@ function status_editor($a,$x, $notes_cid = 0, $popup=false) {
'$private' => t('Private post'),
'$is_private' => $private_post,
'$public_link' => $public_post_link,
//jot nav tab (used in some themes)
'$message' => t('Message'),
'$browser' => t('Browser'),
));

View file

@ -27,7 +27,6 @@ function cron_run(&$argv, &$argc){
unset($db_host, $db_user, $db_pass, $db_data);
};
require_once('include/session.php');
require_once('include/datetime.php');
require_once('include/items.php');
@ -70,53 +69,48 @@ function cron_run(&$argv, &$argc){
// run queue delivery process in the background
proc_run('php',"include/queue.php");
proc_run(PRIORITY_NEGLIGIBLE,"include/queue.php");
// run the process to discover global contacts in the background
proc_run('php',"include/discover_poco.php");
proc_run(PRIORITY_LOW,"include/discover_poco.php");
// run the process to update locally stored global contacts in the background
proc_run('php',"include/discover_poco.php", "checkcontact");
proc_run(PRIORITY_LOW,"include/discover_poco.php", "checkcontact");
// expire any expired accounts
// Expire and remove user entries
cron_expire_and_remove_users();
q("UPDATE user SET `account_expired` = 1 where `account_expired` = 0
AND `account_expires_on` != '0000-00-00 00:00:00'
AND `account_expires_on` < UTC_TIMESTAMP() ");
// If the worker is active, split the jobs in several sub processes
if (get_config("system", "worker")) {
// Check OStatus conversations
proc_run(PRIORITY_MEDIUM, "include/cronjobs.php", "ostatus_mentions");
// delete user and contact records for recently removed accounts
// Check every conversation
proc_run(PRIORITY_MEDIUM, "include/cronjobs.php", "ostatus_conversations");
$r = q("SELECT * FROM `user` WHERE `account_removed` = 1 AND `account_expires_on` < UTC_TIMESTAMP() - INTERVAL 3 DAY");
if ($r) {
foreach($r as $user) {
q("DELETE FROM `contact` WHERE `uid` = %d", intval($user['uid']));
q("DELETE FROM `user` WHERE `uid` = %d", intval($user['uid']));
}
// Call possible post update functions
proc_run(PRIORITY_LOW, "include/cronjobs.php", "post_update");
// update nodeinfo data
proc_run(PRIORITY_LOW, "include/cronjobs.php", "nodeinfo");
} else {
// Check OStatus conversations
// Check only conversations with mentions (for a longer time)
ostatus::check_conversations(true);
// Check every conversation
ostatus::check_conversations(false);
// Call possible post update functions
// see include/post_update.php for more details
post_update();
// update nodeinfo data
nodeinfo_cron();
}
$abandon_days = intval(get_config('system','account_abandon_days'));
if($abandon_days < 1)
$abandon_days = 0;
// Check OStatus conversations
// Check only conversations with mentions (for a longer time)
ostatus::check_conversations(true);
// Check every conversation
ostatus::check_conversations(false);
// Call possible post update functions
// see include/post_update.php for more details
post_update();
// update nodeinfo data
nodeinfo_cron();
/// @TODO Regenerate usage statistics
// q("ANALYZE TABLE `item`");
// once daily run birthday_updates and then expire in background
$d1 = get_config('system','last_expire_day');
@ -126,11 +120,11 @@ function cron_run(&$argv, &$argc){
update_contact_birthdays();
proc_run('php',"include/discover_poco.php", "suggestions");
proc_run(PRIORITY_LOW,"include/discover_poco.php", "suggestions");
set_config('system','last_expire_day',$d2);
proc_run('php','include/expire.php');
proc_run(PRIORITY_LOW,'include/expire.php');
}
// Clear cache entries
@ -142,28 +136,64 @@ function cron_run(&$argv, &$argc){
// Repair entries in the database
cron_repair_database();
// Poll contacts
cron_poll_contacts($argc, $argv);
logger('cron: end');
set_config('system','last_cron', time());
return;
}
/**
* @brief Expire and remove user entries
*/
function cron_expire_and_remove_users() {
// expire any expired accounts
q("UPDATE user SET `account_expired` = 1 where `account_expired` = 0
AND `account_expires_on` != '0000-00-00 00:00:00'
AND `account_expires_on` < UTC_TIMESTAMP() ");
// delete user and contact records for recently removed accounts
$r = q("SELECT * FROM `user` WHERE `account_removed` AND `account_expires_on` < UTC_TIMESTAMP() - INTERVAL 3 DAY");
if ($r) {
foreach($r as $user) {
q("DELETE FROM `contact` WHERE `uid` = %d", intval($user['uid']));
q("DELETE FROM `user` WHERE `uid` = %d", intval($user['uid']));
}
}
}
/**
* @brief Poll contacts for unreceived messages
*
* @param Integer $argc Number of command line arguments
* @param Array $argv Array of command line arguments
*/
function cron_poll_contacts($argc, $argv) {
$manual_id = 0;
$generation = 0;
$force = false;
$restart = false;
if(($argc > 1) && ($argv[1] == 'force'))
if (($argc > 1) && ($argv[1] == 'force'))
$force = true;
if(($argc > 1) && ($argv[1] == 'restart')) {
if (($argc > 1) && ($argv[1] == 'restart')) {
$restart = true;
$generation = intval($argv[2]);
if(! $generation)
if (!$generation)
killme();
}
if(($argc > 1) && intval($argv[1])) {
if (($argc > 1) && intval($argv[1])) {
$manual_id = intval($argv[1]);
$force = true;
}
$interval = intval(get_config('system','poll_interval'));
if(! $interval)
if (!$interval)
$interval = ((get_config('system','delivery_interval') === false) ? 3 : intval(get_config('system','delivery_interval')));
// If we are using the worker we don't need a delivery interval
@ -180,6 +210,10 @@ function cron_run(&$argv, &$argc){
// and which have a polling address and ignore Diaspora since
// we are unable to match those posts with a Diaspora GUID and prevent duplicates.
$abandon_days = intval(get_config('system','account_abandon_days'));
if($abandon_days < 1)
$abandon_days = 0;
$abandon_sql = (($abandon_days)
? sprintf(" AND `user`.`login_date` > UTC_TIMESTAMP() - INTERVAL %d DAY ", intval($abandon_days))
: ''
@ -200,11 +234,11 @@ function cron_run(&$argv, &$argc){
dbesc(NETWORK_MAIL2)
);
if(! count($contacts)) {
if (!count($contacts)) {
return;
}
foreach($contacts as $c) {
foreach ($contacts as $c) {
$res = q("SELECT * FROM `contact` WHERE `id` = %d LIMIT 1",
intval($c['id'])
@ -266,24 +300,18 @@ function cron_run(&$argv, &$argc){
$update = true;
break;
}
if(!$update)
if (!$update)
continue;
}
logger("Polling ".$contact["network"]." ".$contact["id"]." ".$contact["nick"]." ".$contact["name"]);
proc_run('php','include/onepoll.php',$contact['id']);
proc_run(PRIORITY_MEDIUM,'include/onepoll.php',$contact['id']);
if($interval)
@time_sleep_until(microtime(true) + (float) $interval);
}
}
logger('cron: end');
set_config('system','last_cron', time());
return;
}
/**
@ -382,7 +410,7 @@ function cron_repair_diaspora(&$a) {
$r = q("SELECT `id`, `url` FROM `contact`
WHERE `network` = '%s' AND (`batch` = '' OR `notify` = '' OR `poll` = '' OR pubkey = '')
ORDER BY RAND() LIMIT 50", dbesc(NETWORK_DIASPORA));
if ($r) {
if (dbm::is_result($r)) {
foreach ($r AS $contact) {
if (poco_reachable($contact["url"])) {
$data = probe_url($contact["url"]);
@ -410,6 +438,12 @@ function cron_repair_database() {
// There was an issue where the nick vanishes from the contact table
q("UPDATE `contact` INNER JOIN `user` ON `contact`.`uid` = `user`.`uid` SET `nick` = `nickname` WHERE `self` AND `nick`=''");
// Update the global contacts for local users
$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)
update_gcontact_for_user($user["uid"]);
/// @todo
/// - remove thread entries without item
/// - remove sign entries without item

View file

@ -31,6 +31,17 @@ function cronhooks_run(&$argv, &$argc){
return;
}
load_hooks();
if (($argc == 2) AND is_array($a->hooks) AND array_key_exists("cron", $a->hooks)) {
foreach ($a->hooks["cron"] as $hook)
if ($hook[1] == $argv[1]) {
logger("Calling cron hook '".$hook[1]."'", LOGGER_DEBUG);
call_single_hook($a, $name, $hook, $data);
}
return;
}
$last = get_config('system','last_cronhook');
$poll_interval = intval(get_config('system','cronhook_interval'));
@ -47,13 +58,17 @@ function cronhooks_run(&$argv, &$argc){
$a->set_baseurl(get_config('system','url'));
load_hooks();
logger('cronhooks: start');
$d = datetime_convert();
call_hooks('cron', $d);
if (get_config("system", "worker") AND is_array($a->hooks) AND array_key_exists("cron", $a->hooks)) {
foreach ($a->hooks["cron"] as $hook) {
logger("Calling cronhooks for '".$hook[1]."'", LOGGER_DEBUG);
proc_run(PRIORITY_MEDIUM, "include/cronhooks.php", $hook[1]);
}
} else
call_hooks('cron', $d);
logger('cronhooks: end');

77
include/cronjobs.php Normal file
View file

@ -0,0 +1,77 @@
<?php
if (!file_exists("boot.php") AND (sizeof($_SERVER["argv"]) != 0)) {
$directory = dirname($_SERVER["argv"][0]);
if (substr($directory, 0, 1) != "/")
$directory = $_SERVER["PWD"]."/".$directory;
$directory = realpath($directory."/..");
chdir($directory);
}
require_once("boot.php");
function cronjobs_run(&$argv, &$argc){
global $a, $db;
if(is_null($a)) {
$a = new App;
}
if(is_null($db)) {
@include(".htconfig.php");
require_once("include/dba.php");
$db = new dba($db_host, $db_user, $db_pass, $db_data);
unset($db_host, $db_user, $db_pass, $db_data);
};
require_once('include/session.php');
require_once('include/datetime.php');
require_once('include/ostatus.php');
require_once('include/post_update.php');
require_once('mod/nodeinfo.php');
load_config('config');
load_config('system');
$a->set_baseurl(get_config('system','url'));
// No parameter set? So return
if ($argc <= 1)
return;
// Check OStatus conversations
// Check only conversations with mentions (for a longer time)
if ($argv[1] == 'ostatus_mentions') {
ostatus::check_conversations(true);
return;
}
// Check every conversation
if ($argv[1] == 'ostatus_conversations') {
ostatus::check_conversations(false);
return;
}
// Call possible post update functions
// see include/post_update.php for more details
if ($argv[1] == 'post_update') {
post_update();
return;
}
// update nodeinfo data
if ($argv[1] == 'nodeinfo') {
nodeinfo_cron();
return;
}
return;
}
if (array_search(__file__,get_included_files())===0){
cronjobs_run($_SERVER["argv"],$_SERVER["argc"]);
killme();
}

View file

@ -162,7 +162,7 @@ function datetime_convert($from = 'UTC', $to = 'UTC', $s = 'now', $fmt = "Y-m-d
* @brief Wrapper for date selector, tailored for use in birthday fields.
*
* @param string $dob Date of Birth
* @return string
* @return string Formatted html
*/
function dob($dob) {
list($year,$month,$day) = sscanf($dob,'%4d-%2d-%2d');
@ -175,7 +175,18 @@ function dob($dob) {
else
$value = (($year) ? datetime_convert('UTC','UTC',$dob,'Y-m-d') : datetime_convert('UTC','UTC',$dob,'m-d'));
$o = '<input type="text" name="dob" value="' . $value . '" placeholder="' . t('YYYY-MM-DD or MM-DD') . '" />';
$age = ((intval($value)) ? age($value, $a->user["timezone"], $a->user["timezone"]) : "");
$o = replace_macros(get_markup_template("field_input.tpl"), array(
'$field' => array(
'dob',
t('Birthday:'),
$value,
(((intval($age)) > 0 ) ? t('Age: ') . $age : ""),
'',
'placeholder="' . t('YYYY-MM-DD or MM-DD') . '"'
)
));
// if ($dob && $dob != '0000-00-00')
// $o = datesel($f,mktime(0,0,0,0,0,1900),mktime(),mktime(0,0,0,$month,$day,$year),'dob');
@ -202,7 +213,7 @@ function dob($dob) {
* @return string Parsed HTML output.
*/
function datesel($format, $min, $max, $default, $id = 'datepicker') {
return datetimesel($format,$min,$max,$default,$id,true,false, '','');
return datetimesel($format,$min,$max,$default,'',$id,true,false, '','');
}
/**
@ -220,7 +231,7 @@ function datesel($format, $min, $max, $default, $id = 'datepicker') {
* @return string Parsed HTML output.
*/
function timesel($format, $h, $m, $id='timepicker') {
return datetimesel($format,new DateTime(),new DateTime(),new DateTime("$h:$m"),$id,false,true);
return datetimesel($format,new DateTime(),new DateTime(),new DateTime("$h:$m"),'',$id,false,true);
}
/**
@ -251,7 +262,7 @@ function timesel($format, $h, $m, $id='timepicker') {
* @todo Once browser support is better this could probably be replaced with
* native HTML5 date picker.
*/
function datetimesel($format, $min, $max, $default, $id = 'datetimepicker', $pickdate = true, $picktime = true, $minfrom = '', $maxfrom = '', $required = false) {
function datetimesel($format, $min, $max, $default, $label, $id = 'datetimepicker', $pickdate = true, $picktime = true, $minfrom = '', $maxfrom = '', $required = false) {
// First day of the week (0 = Sunday)
$firstDay = get_pconfig(local_user(),'system','first_day_of_week');
@ -273,7 +284,7 @@ function datetimesel($format, $min, $max, $default, $id = 'datetimepicker', $pic
$minjs = $min ? ",minDate: new Date({$min->getTimestamp()}*1000), yearStart: " . $min->format('Y') : '';
$maxjs = $max ? ",maxDate: new Date({$max->getTimestamp()}*1000), yearEnd: " . $max->format('Y') : '';
$input_text = $default ? 'value="' . date($dateformat, $default->getTimestamp()) . '"' : '';
$input_text = $default ? date($dateformat, $default->getTimestamp()) : '';
$defaultdatejs = $default ? ",defaultDate: new Date({$default->getTimestamp()}*1000)" : '';
$pickers = '';
@ -283,9 +294,9 @@ function datetimesel($format, $min, $max, $default, $id = 'datetimepicker', $pic
$extra_js = '';
$pickers .= ",dayOfWeekStart: ".$firstDay.",lang:'".$lang."'";
if($minfrom != '')
$extra_js .= "\$('#$minfrom').data('xdsoft_datetimepicker').setOptions({onChangeDateTime: function (currentDateTime) { \$('#$id').data('xdsoft_datetimepicker').setOptions({minDate: currentDateTime})}})";
$extra_js .= "\$('#id_$minfrom').data('xdsoft_datetimepicker').setOptions({onChangeDateTime: function (currentDateTime) { \$('#id_$id').data('xdsoft_datetimepicker').setOptions({minDate: currentDateTime})}})";
if($maxfrom != '')
$extra_js .= "\$('#$maxfrom').data('xdsoft_datetimepicker').setOptions({onChangeDateTime: function (currentDateTime) { \$('#$id').data('xdsoft_datetimepicker').setOptions({maxDate: currentDateTime})}})";
$extra_js .= "\$('#id_$maxfrom').data('xdsoft_datetimepicker').setOptions({onChangeDateTime: function (currentDateTime) { \$('#id_$id').data('xdsoft_datetimepicker').setOptions({maxDate: currentDateTime})}})";
$readable_format = $dateformat;
$readable_format = str_replace('Y','yyyy',$readable_format);
@ -294,10 +305,13 @@ function datetimesel($format, $min, $max, $default, $id = 'datetimepicker', $pic
$readable_format = str_replace('H','HH',$readable_format);
$readable_format = str_replace('i','MM',$readable_format);
$o .= "<div class='date'><input type='text' placeholder='$readable_format' name='$id' id='$id' $input_text />";
$o .= '</div>';
$tpl = get_markup_template('field_input.tpl');
$o .= replace_macros($tpl,array(
'$field' => array($id, $label, $input_text, '', (($required) ? '*' : ''), 'placeholder="' . $readable_format . '"'),
));
$o .= "<script type='text/javascript'>";
$o .= "\$(function () {var picker = \$('#$id').datetimepicker({step:5,format:'$dateformat' $minjs $maxjs $pickers $defaultdatejs}); $extra_js})";
$o .= "\$(function () {var picker = \$('#id_$id').datetimepicker({step:5,format:'$dateformat' $minjs $maxjs $pickers $defaultdatejs}); $extra_js})";
$o .= "</script>";
return $o;
@ -544,7 +558,7 @@ function update_contact_birthdays() {
// In-network birthdays are handled within local_delivery
$r = q("SELECT * FROM contact WHERE `bd` != '' AND `bd` != '0000-00-00' AND SUBSTRING(`bd`,1,4) != `bdyear` ");
if(dba::is_result($r)) {
if(dbm::is_result($r)) {
foreach($r as $rr) {
logger('update_contact_birthday: ' . $rr['bd']);

View file

@ -1,4 +1,5 @@
<?php
require_once("dbm.php");
# if PDO is avaible for mysql, use the new database abstraction
# TODO: PDO is disabled for release 3.3. We need to investigate why
@ -65,6 +66,8 @@ class dba {
if(! mysqli_connect_errno()) {
$this->connected = true;
}
if (isset($a->config["system"]["db_charset"]))
$this->db->set_charset($a->config["system"]["db_charset"]);
}
else {
$this->mysqli = false;
@ -72,6 +75,8 @@ class dba {
if($this->db && mysql_select_db($db,$this->db)) {
$this->connected = true;
}
if (isset($a->config["system"]["db_charset"]))
mysql_set_charset($a->config["system"]["db_charset"], $this->db);
}
if(! $this->connected) {
$this->db = null;
@ -94,6 +99,14 @@ class dba {
$this->error = '';
// Check the connection (This can reconnect the connection - if configured)
if ($this->mysqli)
$connected = $this->db->ping();
else
$connected = mysql_ping($this->db);
$connstr = ($connected ? "Connected": "Disonnected");
$stamp1 = microtime(true);
if($this->mysqli)
@ -106,6 +119,9 @@ class dba {
$a->save_timestamp($stamp1, "database");
if (strtolower(substr($sql, 0, 6)) != "select")
$a->save_timestamp($stamp1, "database_write");
if(x($a->config,'system') && x($a->config['system'],'db_log')) {
if (($duration > $a->config["system"]["db_loglimit"])) {
$duration = round($duration, 3);
@ -118,14 +134,17 @@ class dba {
}
if($this->mysqli) {
if($this->db->errno)
if($this->db->errno) {
$this->error = $this->db->error;
$this->errorno = $this->db->errno;
}
} elseif(mysql_errno($this->db)) {
$this->error = mysql_error($this->db);
$this->errorno = mysql_errno($this->db);
}
elseif(mysql_errno($this->db))
$this->error = mysql_error($this->db);
if(strlen($this->error)) {
logger('dba: ' . $this->error);
logger('DB Error ('.$connstr.') '.$this->errorno.': '.$this->error);
}
if($this->debug) {
@ -230,16 +249,6 @@ class dba {
}
}
/**
* Checks if $array is a filled array with at least one entry.
*
* @param $array mixed A filled array with at least one entry
* @return Whether $array is a filled array
*/
public static function is_result ($array) {
return (is_array($array) && count($array) > 0);
}
function __destruct() {
if ($this->db)
if($this->mysqli)

View file

@ -232,16 +232,6 @@ class dba {
}
}
/**
* Checks if $array is a filled array with at least one entry.
*
* @param $array mixed A filled array with at least one entry
* @return Whether $array is a filled array
*/
public function is_result ($array) {
return (is_array($array) && count($array) > 0);
}
function __destruct() {
if ($this->db)
\DDDBL\disconnect();

49
include/dbm.php Normal file
View file

@ -0,0 +1,49 @@
<?php
/**
* @brief This class contain functions for the database management
*
*/
class dbm {
/**
* @brief Return a list of database processes
*
* @return array
* 'list' => List of processes, separated in their different states
* 'amount' => Number of concurrent database processes
*/
public static function processlist() {
$r = q("SHOW PROCESSLIST");
$s = array();
$processes = 0;
$states = array();
foreach ($r AS $process) {
$state = trim($process["State"]);
// Filter out all non blocking processes
if (!in_array($state, array("", "init", "statistics", "updating"))) {
++$states[$state];
++$processes;
}
}
$statelist = "";
foreach ($states AS $state => $usage) {
if ($statelist != "")
$statelist .= ", ";
$statelist .= $state.": ".$usage;
}
return(array("list" => $statelist, "amount" => $processes));
}
/**
* Checks if $array is a filled array with at least one entry.
*
* @param $array mixed A filled array with at least one entry
* @return Whether $array is a filled array
*/
public static function is_result($array) {
return (is_array($array) && count($array) > 0);
}
}
?>

View file

@ -260,6 +260,13 @@ function db_field_command($parameters, $create = true) {
function db_create_table($name, $fields, $verbose, $action, $indexes=null) {
global $a, $db;
if (isset($a->config["system"]["db_charset"]))
$charset = $a->config["system"]["db_charset"];
elseif ($verbose)
$charset = "utf8mb4";
else
$charset = "utf8";
$r = true;
$sql = "";
@ -282,7 +289,7 @@ function db_create_table($name, $fields, $verbose, $action, $indexes=null) {
$sql = implode(",\n\t", $sql_rows);
$sql = sprintf("CREATE TABLE IF NOT EXISTS `%s` (\n\t", dbesc($name)).$sql."\n) DEFAULT CHARSET=utf8";
$sql = sprintf("CREATE TABLE IF NOT EXISTS `%s` (\n\t", dbesc($name)).$sql."\n) DEFAULT CHARSET=".$charset;
if ($verbose)
echo $sql.";\n";
@ -365,10 +372,10 @@ function db_definition() {
"data" => array("type" => "longblob", "not null" => "1"),
"created" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
"edited" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
"allow_cid" => array("type" => "mediumtext", "not null" => "1"),
"allow_gid" => array("type" => "mediumtext", "not null" => "1"),
"deny_cid" => array("type" => "mediumtext", "not null" => "1"),
"deny_gid" => array("type" => "mediumtext", "not null" => "1"),
"allow_cid" => array("type" => "mediumtext"),
"allow_gid" => array("type" => "mediumtext"),
"deny_cid" => array("type" => "mediumtext"),
"deny_gid" => array("type" => "mediumtext"),
),
"indexes" => array(
"PRIMARY" => array("id"),
@ -389,7 +396,7 @@ function db_definition() {
$database["cache"] = array(
"fields" => array(
"k" => array("type" => "varchar(255)", "not null" => "1", "primary" => "1"),
"v" => array("type" => "text", "not null" => "1"),
"v" => array("type" => "text"),
"expire_mode" => array("type" => "int(11)", "not null" => "1", "default" => "0"),
"updated" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
),
@ -429,7 +436,7 @@ function db_definition() {
"id" => array("type" => "int(10) unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
"cat" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"k" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"v" => array("type" => "text", "not null" => "1"),
"v" => array("type" => "text"),
),
"indexes" => array(
"PRIMARY" => array("id"),
@ -449,29 +456,29 @@ function db_definition() {
"name" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"nick" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"location" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"about" => array("type" => "text", "not null" => "1"),
"keywords" => array("type" => "text", "not null" => "1"),
"about" => array("type" => "text"),
"keywords" => array("type" => "text"),
"gender" => array("type" => "varchar(32)", "not null" => "1", "default" => ""),
"attag" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"avatar" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"photo" => array("type" => "text", "not null" => "1"),
"thumb" => array("type" => "text", "not null" => "1"),
"micro" => array("type" => "text", "not null" => "1"),
"site-pubkey" => array("type" => "text", "not null" => "1"),
"photo" => array("type" => "text"),
"thumb" => array("type" => "text"),
"micro" => array("type" => "text"),
"site-pubkey" => array("type" => "text"),
"issued-id" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"dfrn-id" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"url" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"nurl" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"addr" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"alias" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"pubkey" => array("type" => "text", "not null" => "1"),
"prvkey" => array("type" => "text", "not null" => "1"),
"pubkey" => array("type" => "text"),
"prvkey" => array("type" => "text"),
"batch" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"request" => array("type" => "text", "not null" => "1"),
"notify" => array("type" => "text", "not null" => "1"),
"poll" => array("type" => "text", "not null" => "1"),
"confirm" => array("type" => "text", "not null" => "1"),
"poco" => array("type" => "text", "not null" => "1"),
"request" => array("type" => "text"),
"notify" => array("type" => "text"),
"poll" => array("type" => "text"),
"confirm" => array("type" => "text"),
"poco" => array("type" => "text"),
"aes_allow" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
"ret-aes" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
"usehub" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
@ -495,15 +502,15 @@ function db_definition() {
"archive" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
"pending" => array("type" => "tinyint(1)", "not null" => "1", "default" => "1"),
"rating" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
"reason" => array("type" => "text", "not null" => "1"),
"reason" => array("type" => "text"),
"closeness" => array("type" => "tinyint(2)", "not null" => "1", "default" => "99"),
"info" => array("type" => "mediumtext", "not null" => "1"),
"info" => array("type" => "mediumtext"),
"profile-id" => array("type" => "int(11)", "not null" => "1", "default" => "0"),
"bdyear" => array("type" => "varchar(4)", "not null" => "1", "default" => ""),
"bd" => array("type" => "date", "not null" => "1", "default" => "0000-00-00"),
"notify_new_posts" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
"fetch_further_information" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
"ffi_keyword_blacklist" => array("type" => "mediumtext", "not null" => "1"),
"ffi_keyword_blacklist" => array("type" => "mediumtext"),
),
"indexes" => array(
"PRIMARY" => array("id"),
@ -515,12 +522,12 @@ function db_definition() {
"fields" => array(
"id" => array("type" => "int(10) unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
"guid" => array("type" => "varchar(64)", "not null" => "1", "default" => ""),
"recips" => array("type" => "mediumtext", "not null" => "1"),
"recips" => array("type" => "mediumtext"),
"uid" => array("type" => "int(11)", "not null" => "1", "default" => "0"),
"creator" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"created" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
"updated" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
"subject" => array("type" => "mediumtext", "not null" => "1"),
"subject" => array("type" => "mediumtext"),
),
"indexes" => array(
"PRIMARY" => array("id"),
@ -548,17 +555,17 @@ function db_definition() {
"edited" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
"start" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
"finish" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
"summary" => array("type" => "text", "not null" => "1"),
"desc" => array("type" => "text", "not null" => "1"),
"location" => array("type" => "text", "not null" => "1"),
"summary" => array("type" => "text"),
"desc" => array("type" => "text"),
"location" => array("type" => "text"),
"type" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"nofinish" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
"adjust" => array("type" => "tinyint(1)", "not null" => "1", "default" => "1"),
"ignore" => array("type" => "tinyint(1) unsigned", "not null" => "1", "default" => "0"),
"allow_cid" => array("type" => "mediumtext", "not null" => "1"),
"allow_gid" => array("type" => "mediumtext", "not null" => "1"),
"deny_cid" => array("type" => "mediumtext", "not null" => "1"),
"deny_gid" => array("type" => "mediumtext", "not null" => "1"),
"allow_cid" => array("type" => "mediumtext"),
"allow_gid" => array("type" => "mediumtext"),
"deny_cid" => array("type" => "mediumtext"),
"deny_gid" => array("type" => "mediumtext"),
),
"indexes" => array(
"PRIMARY" => array("id"),
@ -568,6 +575,7 @@ function db_definition() {
$database["fcontact"] = array(
"fields" => array(
"id" => array("type" => "int(10) unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
"guid" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"url" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"name" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"photo" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
@ -581,7 +589,7 @@ function db_definition() {
"priority" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
"network" => array("type" => "varchar(32)", "not null" => "1", "default" => ""),
"alias" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"pubkey" => array("type" => "text", "not null" => "1"),
"pubkey" => array("type" => "text"),
"updated" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
),
"indexes" => array(
@ -605,7 +613,7 @@ function db_definition() {
"id" => array("type" => "int(11)", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
"server" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"posturl" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"key" => array("type" => "text", "not null" => "1"),
"key" => array("type" => "text"),
),
"indexes" => array(
"PRIMARY" => array("id"),
@ -621,7 +629,7 @@ function db_definition() {
"url" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"request" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"photo" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"note" => array("type" => "text", "not null" => "1"),
"note" => array("type" => "text"),
"created" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
),
"indexes" => array(
@ -654,8 +662,8 @@ function db_definition() {
"last_contact" => array("type" => "datetime", "default" => "0000-00-00 00:00:00"),
"last_failure" => array("type" => "datetime", "default" => "0000-00-00 00:00:00"),
"location" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"about" => array("type" => "text", "not null" => "1"),
"keywords" => array("type" => "text", "not null" => "1"),
"about" => array("type" => "text"),
"keywords" => array("type" => "text"),
"gender" => array("type" => "varchar(32)", "not null" => "1", "default" => ""),
"birthday" => array("type" => "varchar(32)", "not null" => "1", "default" => "0000-00-00"),
"community" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
@ -663,7 +671,7 @@ function db_definition() {
"nsfw" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
"network" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"addr" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"notify" => array("type" => "text", "not null" => "1"),
"notify" => array("type" => "text"),
"alias" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"generation" => array("type" => "tinyint(3)", "not null" => "1", "default" => "0"),
"server_url" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
@ -725,7 +733,7 @@ function db_definition() {
"nurl" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"version" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"site_name" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"info" => array("type" => "text", "not null" => "1"),
"info" => array("type" => "text"),
"register_policy" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
"poco" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"noscrape" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
@ -762,7 +770,7 @@ function db_definition() {
"contact-id" => array("type" => "int(11)", "not null" => "1", "default" => "0"),
"knowyou" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
"duplex" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
"note" => array("type" => "text", "not null" => "1"),
"note" => array("type" => "text"),
"hash" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"datetime" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
"blocked" => array("type" => "tinyint(1)", "not null" => "1", "default" => "1"),
@ -792,34 +800,36 @@ function db_definition() {
"commented" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
"received" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
"changed" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
"owner-id" => array("type" => "int(11)", "not null" => "1", "default" => "0"),
"owner-name" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"owner-link" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"owner-avatar" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"author-id" => array("type" => "int(11)", "not null" => "1", "default" => "0"),
"author-name" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"author-link" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"author-avatar" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"title" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"body" => array("type" => "mediumtext", "not null" => "1"),
"body" => array("type" => "mediumtext"),
"app" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"verb" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"object-type" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"object" => array("type" => "text", "not null" => "1"),
"object" => array("type" => "text"),
"target-type" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"target" => array("type" => "text", "not null" => "1"),
"postopts" => array("type" => "text", "not null" => "1"),
"target" => array("type" => "text"),
"postopts" => array("type" => "text"),
"plink" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"resource-id" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"event-id" => array("type" => "int(11)", "not null" => "1", "default" => "0"),
"tag" => array("type" => "mediumtext", "not null" => "1"),
"attach" => array("type" => "mediumtext", "not null" => "1"),
"inform" => array("type" => "mediumtext", "not null" => "1"),
"file" => array("type" => "mediumtext", "not null" => "1"),
"tag" => array("type" => "mediumtext"),
"attach" => array("type" => "mediumtext"),
"inform" => array("type" => "mediumtext"),
"file" => array("type" => "mediumtext"),
"location" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"coord" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"allow_cid" => array("type" => "mediumtext", "not null" => "1"),
"allow_gid" => array("type" => "mediumtext", "not null" => "1"),
"deny_cid" => array("type" => "mediumtext", "not null" => "1"),
"deny_gid" => array("type" => "mediumtext", "not null" => "1"),
"allow_cid" => array("type" => "mediumtext"),
"allow_gid" => array("type" => "mediumtext"),
"deny_cid" => array("type" => "mediumtext"),
"deny_gid" => array("type" => "mediumtext"),
"private" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
"pubmail" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
"moderated" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
@ -835,7 +845,7 @@ function db_definition() {
"mention" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
"network" => array("type" => "varchar(32)", "not null" => "1", "default" => ""),
"rendered-hash" => array("type" => "varchar(32)", "not null" => "1", "default" => ""),
"rendered-html" => array("type" => "mediumtext", "not null" => "1"),
"rendered-html" => array("type" => "mediumtext"),
"global" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
),
"indexes" => array(
@ -847,7 +857,7 @@ function db_definition() {
"extid" => array("extid"),
"uid_id" => array("uid","id"),
"uid_created" => array("uid","created"),
"uid_unseen" => array("uid","unseen"),
"uid_unseen_contactid" => array("uid","unseen","contact-id"),
"uid_network_received" => array("uid","network","received"),
"uid_received" => array("uid","received"),
"uid_network_commented" => array("uid","network","commented"),
@ -855,15 +865,18 @@ function db_definition() {
"uid_title" => array("uid","title"),
"uid_thrparent" => array("uid","thr-parent"),
"uid_parenturi" => array("uid","parent-uri"),
"uid_contactid_id" => array("uid","contact-id","id"),
"uid_contactid_created" => array("uid","contact-id","created"),
"gcontactid_uid_created" => array("gcontact-id","uid","created"),
"authorid_created" => array("author-id","created"),
"ownerid_created" => array("owner-id","created"),
"wall_body" => array("wall","body(6)"),
"uid_visible_moderated_created" => array("uid","visible","moderated","created"),
"uid_uri" => array("uid","uri"),
"uid_wall_created" => array("uid","wall","created"),
"resource-id" => array("resource-id"),
"uid_type" => array("uid","type"),
"uid_starred" => array("uid","starred"),
"uid_starred_id" => array("uid","starred", "id"),
"contactid_allowcid_allowpid_denycid_denygid" => array("contact-id","allow_cid(10)","allow_gid(10)","deny_cid(10)","deny_gid(10)"),
"uid_wall_parent_created" => array("uid","wall","parent","created"),
"uid_type_changed" => array("uid","type","changed"),
@ -913,7 +926,7 @@ function db_definition() {
"contact-id" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"convid" => array("type" => "int(11) unsigned", "not null" => "1", "default" => "0"),
"title" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"body" => array("type" => "mediumtext", "not null" => "1"),
"body" => array("type" => "mediumtext"),
"seen" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
"reply" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
"replied" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
@ -941,7 +954,7 @@ function db_definition() {
"ssltype" => array("type" => "varchar(16)", "not null" => "1", "default" => ""),
"mailbox" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"user" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"pass" => array("type" => "text", "not null" => "1"),
"pass" => array("type" => "text"),
"reply_to" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"action" => array("type" => "int(11)", "not null" => "1", "default" => "0"),
"movetofolder" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
@ -972,7 +985,7 @@ function db_definition() {
"url" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"photo" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"date" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
"msg" => array("type" => "mediumtext", "not null" => "1"),
"msg" => array("type" => "mediumtext"),
"uid" => array("type" => "int(11)", "not null" => "1", "default" => "0"),
"link" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"iid" => array("type" => "int(11)", "not null" => "1", "default" => "0"),
@ -1003,7 +1016,7 @@ function db_definition() {
$database["oembed"] = array(
"fields" => array(
"url" => array("type" => "varchar(255)", "not null" => "1", "primary" => "1"),
"content" => array("type" => "text", "not null" => "1"),
"content" => array("type" => "text"),
"created" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
),
"indexes" => array(
@ -1016,7 +1029,7 @@ function db_definition() {
"url" => array("type" => "varchar(255)", "not null" => "1", "primary" => "1"),
"guessing" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0", "primary" => "1"),
"oembed" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0", "primary" => "1"),
"content" => array("type" => "text", "not null" => "1"),
"content" => array("type" => "text"),
"created" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
),
"indexes" => array(
@ -1030,7 +1043,7 @@ function db_definition() {
"uid" => array("type" => "int(11)", "not null" => "1", "default" => "0"),
"cat" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"k" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"v" => array("type" => "mediumtext", "not null" => "1"),
"v" => array("type" => "mediumtext"),
),
"indexes" => array(
"PRIMARY" => array("id"),
@ -1047,7 +1060,7 @@ function db_definition() {
"created" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
"edited" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
"title" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"desc" => array("type" => "text", "not null" => "1"),
"desc" => array("type" => "text"),
"album" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"filename" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"type" => array("type" => "varchar(128)", "not null" => "1", "default" => "image/jpeg"),
@ -1057,10 +1070,10 @@ function db_definition() {
"data" => array("type" => "mediumblob", "not null" => "1"),
"scale" => array("type" => "tinyint(3)", "not null" => "1", "default" => "0"),
"profile" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
"allow_cid" => array("type" => "mediumtext", "not null" => "1"),
"allow_gid" => array("type" => "mediumtext", "not null" => "1"),
"deny_cid" => array("type" => "mediumtext", "not null" => "1"),
"deny_gid" => array("type" => "mediumtext", "not null" => "1"),
"allow_cid" => array("type" => "mediumtext"),
"allow_gid" => array("type" => "mediumtext"),
"deny_cid" => array("type" => "mediumtext"),
"deny_gid" => array("type" => "mediumtext"),
),
"indexes" => array(
"PRIMARY" => array("id"),
@ -1073,16 +1086,16 @@ function db_definition() {
"fields" => array(
"id" => array("type" => "int(11)", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
"uid" => array("type" => "int(11)", "not null" => "1", "default" => "0"),
"q0" => array("type" => "mediumtext", "not null" => "1"),
"q1" => array("type" => "mediumtext", "not null" => "1"),
"q2" => array("type" => "mediumtext", "not null" => "1"),
"q3" => array("type" => "mediumtext", "not null" => "1"),
"q4" => array("type" => "mediumtext", "not null" => "1"),
"q5" => array("type" => "mediumtext", "not null" => "1"),
"q6" => array("type" => "mediumtext", "not null" => "1"),
"q7" => array("type" => "mediumtext", "not null" => "1"),
"q8" => array("type" => "mediumtext", "not null" => "1"),
"q9" => array("type" => "mediumtext", "not null" => "1"),
"q0" => array("type" => "mediumtext"),
"q1" => array("type" => "mediumtext"),
"q2" => array("type" => "mediumtext"),
"q3" => array("type" => "mediumtext"),
"q4" => array("type" => "mediumtext"),
"q5" => array("type" => "mediumtext"),
"q6" => array("type" => "mediumtext"),
"q7" => array("type" => "mediumtext"),
"q8" => array("type" => "mediumtext"),
"q9" => array("type" => "mediumtext"),
),
"indexes" => array(
"PRIMARY" => array("id"),
@ -1101,6 +1114,17 @@ function db_definition() {
"choice" => array("choice"),
)
);
$database["process"] = array(
"fields" => array(
"pid" => array("type" => "int(10) unsigned", "not null" => "1", "primary" => "1"),
"command" => array("type" => "varchar(32)", "not null" => "1", "default" => ""),
"created" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
),
"indexes" => array(
"PRIMARY" => array("pid"),
"command" => array("command"),
)
);
$database["profile"] = array(
"fields" => array(
"id" => array("type" => "int(11)", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
@ -1119,26 +1143,26 @@ function db_definition() {
"hometown" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"gender" => array("type" => "varchar(32)", "not null" => "1", "default" => ""),
"marital" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"with" => array("type" => "text", "not null" => "1"),
"with" => array("type" => "text"),
"howlong" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
"sexual" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"politic" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"religion" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"pub_keywords" => array("type" => "text", "not null" => "1"),
"prv_keywords" => array("type" => "text", "not null" => "1"),
"likes" => array("type" => "text", "not null" => "1"),
"dislikes" => array("type" => "text", "not null" => "1"),
"about" => array("type" => "text", "not null" => "1"),
"pub_keywords" => array("type" => "text"),
"prv_keywords" => array("type" => "text"),
"likes" => array("type" => "text"),
"dislikes" => array("type" => "text"),
"about" => array("type" => "text"),
"summary" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"music" => array("type" => "text", "not null" => "1"),
"book" => array("type" => "text", "not null" => "1"),
"tv" => array("type" => "text", "not null" => "1"),
"film" => array("type" => "text", "not null" => "1"),
"interest" => array("type" => "text", "not null" => "1"),
"romance" => array("type" => "text", "not null" => "1"),
"work" => array("type" => "text", "not null" => "1"),
"education" => array("type" => "text", "not null" => "1"),
"contact" => array("type" => "text", "not null" => "1"),
"music" => array("type" => "text"),
"book" => array("type" => "text"),
"tv" => array("type" => "text"),
"film" => array("type" => "text"),
"interest" => array("type" => "text"),
"romance" => array("type" => "text"),
"work" => array("type" => "text"),
"education" => array("type" => "text"),
"contact" => array("type" => "text"),
"homepage" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"photo" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"thumb" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
@ -1185,7 +1209,7 @@ function db_definition() {
"network" => array("type" => "varchar(32)", "not null" => "1", "default" => ""),
"created" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
"last" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
"content" => array("type" => "mediumtext", "not null" => "1"),
"content" => array("type" => "mediumtext"),
"batch" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
),
"indexes" => array(
@ -1226,7 +1250,7 @@ function db_definition() {
"fields" => array(
"id" => array("type" => "bigint(20) unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
"sid" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"data" => array("type" => "text", "not null" => "1"),
"data" => array("type" => "text"),
"expire" => array("type" => "int(10) unsigned", "not null" => "1", "default" => "0"),
),
"indexes" => array(
@ -1239,8 +1263,8 @@ function db_definition() {
"fields" => array(
"id" => array("type" => "int(10) unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
"iid" => array("type" => "int(10) unsigned", "not null" => "1", "default" => "0"),
"signed_text" => array("type" => "mediumtext", "not null" => "1"),
"signature" => array("type" => "text", "not null" => "1"),
"signed_text" => array("type" => "mediumtext"),
"signature" => array("type" => "text"),
"signer" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
),
"indexes" => array(
@ -1296,6 +1320,8 @@ function db_definition() {
"uid" => array("type" => "int(10) unsigned", "not null" => "1", "default" => "0"),
"contact-id" => array("type" => "int(11) unsigned", "not null" => "1", "default" => "0"),
"gcontact-id" => array("type" => "int(11) unsigned", "not null" => "1", "default" => "0"),
"owner-id" => array("type" => "int(11) unsigned", "not null" => "1", "default" => "0"),
"author-id" => array("type" => "int(11) unsigned", "not null" => "1", "default" => "0"),
"created" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
"edited" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
"commented" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
@ -1335,7 +1361,7 @@ function db_definition() {
$database["tokens"] = array(
"fields" => array(
"id" => array("type" => "varchar(40)", "not null" => "1", "primary" => "1"),
"secret" => array("type" => "text", "not null" => "1"),
"secret" => array("type" => "text"),
"client_id" => array("type" => "varchar(20)", "not null" => "1", "default" => ""),
"expires" => array("type" => "int(11)", "not null" => "1", "default" => "0"),
"scope" => array("type" => "varchar(200)", "not null" => "1", "default" => ""),
@ -1361,10 +1387,10 @@ function db_definition() {
"default-location" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"allow_location" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
"theme" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"pubkey" => array("type" => "text", "not null" => "1"),
"prvkey" => array("type" => "text", "not null" => "1"),
"spubkey" => array("type" => "text", "not null" => "1"),
"sprvkey" => array("type" => "text", "not null" => "1"),
"pubkey" => array("type" => "text"),
"prvkey" => array("type" => "text"),
"spubkey" => array("type" => "text"),
"sprvkey" => array("type" => "text"),
"verified" => array("type" => "tinyint(1) unsigned", "not null" => "1", "default" => "0"),
"blocked" => array("type" => "tinyint(1) unsigned", "not null" => "1", "default" => "0"),
"blockwall" => array("type" => "tinyint(1) unsigned", "not null" => "1", "default" => "0"),
@ -1384,11 +1410,11 @@ function db_definition() {
"expire_notification_sent" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
"service_class" => array("type" => "varchar(32)", "not null" => "1", "default" => ""),
"def_gid" => array("type" => "int(11)", "not null" => "1", "default" => "0"),
"allow_cid" => array("type" => "mediumtext", "not null" => "1"),
"allow_gid" => array("type" => "mediumtext", "not null" => "1"),
"deny_cid" => array("type" => "mediumtext", "not null" => "1"),
"deny_gid" => array("type" => "mediumtext", "not null" => "1"),
"openidserver" => array("type" => "text", "not null" => "1"),
"allow_cid" => array("type" => "mediumtext"),
"allow_gid" => array("type" => "mediumtext"),
"deny_cid" => array("type" => "mediumtext"),
"deny_gid" => array("type" => "mediumtext"),
"openidserver" => array("type" => "text"),
),
"indexes" => array(
"PRIMARY" => array("uid"),
@ -1408,7 +1434,7 @@ function db_definition() {
$database["workerqueue"] = array(
"fields" => array(
"id" => array("type" => "int(11)", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
"parameter" => array("type" => "text", "not null" => "1"),
"parameter" => array("type" => "text"),
"priority" => array("type" => "tinyint(3) unsigned", "not null" => "1", "default" => "0"),
"created" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
"pid" => array("type" => "int(11)", "not null" => "1", "default" => "0"),
@ -1445,6 +1471,7 @@ function dbstructure_run(&$argv, &$argc) {
switch ($argv[1]) {
case "update":
update_structure(true, true);
set_config('system','build',DB_UPDATE_VERSION);
return;
case "dumpsql":
print_structure(db_definition());

View file

@ -254,7 +254,7 @@ function delivery_run(&$argv, &$argc){
intval($contact_id)
);
if (dba::is_result($r))
if (dbm::is_result($r))
$contact = $r[0];
if ($contact['self'])
@ -416,7 +416,7 @@ function delivery_run(&$argv, &$argc){
intval($argv[2]),
intval($uid)
);
if (dba::is_result($r))
if (dbm::is_result($r))
$it = $r[0];
}
if (!$it)

View file

@ -68,10 +68,11 @@ class dfrn {
* @param string $owner_nick Owner nick name
* @param string $last_update Date of the last update
* @param int $direction Can be -1, 0 or 1.
* @param boolean $onlyheader Output only the header without content? (Default is "no")
*
* @return string DFRN feed entries
*/
public static function feed($dfrn_id, $owner_nick, $last_update, $direction = 0) {
public static function feed($dfrn_id, $owner_nick, $last_update, $direction = 0, $onlyheader = false) {
$a = get_app();
@ -196,7 +197,6 @@ class dfrn {
`contact`.`name`, `contact`.`network`, `contact`.`photo`, `contact`.`url`,
`contact`.`name-date`, `contact`.`uri-date`, `contact`.`avatar-date`,
`contact`.`thumb`, `contact`.`dfrn-id`, `contact`.`self`,
`contact`.`id` AS `contact-id`, `contact`.`uid` AS `contact-uid`,
`sign`.`signed_text`, `sign`.`signature`, `sign`.`signer`
FROM `item` $sql_post_table
INNER JOIN `contact` ON `contact`.`id` = `item`.`contact-id`
@ -234,7 +234,7 @@ class dfrn {
// This hook can't work anymore
// call_hooks('atom_feed', $atom);
if(! count($items)) {
if (!count($items) OR $onlyheader) {
$atom = trim($doc->saveXML());
call_hooks('atom_feed_end', $atom);
@ -368,6 +368,8 @@ class dfrn {
xml::add_element($doc, $relocate, "dfrn:url", $owner['url']);
xml::add_element($doc, $relocate, "dfrn:name", $owner['name']);
xml::add_element($doc, $relocate, "dfrn:addr", $owner['addr']);
xml::add_element($doc, $relocate, "dfrn:avatar", $owner['avatar']);
xml::add_element($doc, $relocate, "dfrn:photo", $photos[4]);
xml::add_element($doc, $relocate, "dfrn:thumb", $photos[5]);
xml::add_element($doc, $relocate, "dfrn:micro", $photos[6]);
@ -462,38 +464,53 @@ class dfrn {
*/
private function add_author($doc, $owner, $authorelement, $public) {
// Is the profile hidden or shouldn't be published in the net? Then add the "hide" element
$r = q("SELECT `id` FROM `profile` INNER JOIN `user` ON `user`.`uid` = `profile`.`uid`
WHERE (`hidewall` OR NOT `net-publish`) AND `user`.`uid` = %d",
intval($owner['uid']));
if ($r)
$hidewall = true;
else
$hidewall = false;
$author = $doc->createElement($authorelement);
$namdate = datetime_convert('UTC', 'UTC', $owner['name-date'].'+00:00' , ATOM_TIME);
$namdate = datetime_convert('UTC', 'UTC', $owner['name-date'].'+00:00', ATOM_TIME);
$uridate = datetime_convert('UTC', 'UTC', $owner['uri-date'].'+00:00', ATOM_TIME);
$picdate = datetime_convert('UTC', 'UTC', $owner['avatar-date'].'+00:00', ATOM_TIME);
$attributes = array("dfrn:updated" => $namdate);
if (!$public OR !$hidewall)
$attributes = array("dfrn:updated" => $namdate);
else
$attributes = array();
xml::add_element($doc, $author, "name", $owner["name"], $attributes);
$attributes = array("dfrn:updated" => $namdate);
xml::add_element($doc, $author, "uri", app::get_baseurl().'/profile/'.$owner["nickname"], $attributes);
$attributes = array("dfrn:updated" => $namdate);
xml::add_element($doc, $author, "dfrn:handle", $owner["addr"], $attributes);
$attributes = array("rel" => "photo", "type" => "image/jpeg", "dfrn:updated" => $picdate,
$attributes = array("rel" => "photo", "type" => "image/jpeg",
"media:width" => 175, "media:height" => 175, "href" => $owner['photo']);
if (!$public OR !$hidewall)
$attributes["dfrn:updated"] = $picdate;
xml::add_element($doc, $author, "link", "", $attributes);
$attributes = array("rel" => "avatar", "type" => "image/jpeg", "dfrn:updated" => $picdate,
"media:width" => 175, "media:height" => 175, "href" => $owner['photo']);
$attributes["rel"] = "avatar";
xml::add_element($doc, $author, "link", "", $attributes);
if ($hidewall)
xml::add_element($doc, $author, "dfrn:hide", "true");
// The following fields will only be generated if the data isn't meant for a public feed
if ($public)
return $author;
$birthday = feed_birthday($owner['uid'], $owner['timezone']);
if ($birthday)
xml::add_element($doc, $author, "dfrn:birthday", $birthday);
// The following fields will only be generated if this isn't for a public feed
if ($public)
return $author;
// Only show contact details when we are allowed to
$r = q("SELECT `profile`.`about`, `profile`.`name`, `profile`.`homepage`, `user`.`nickname`, `user`.`timezone`,
`profile`.`locality`, `profile`.`region`, `profile`.`country-name`, `profile`.`pub_keywords`, `profile`.`dob`
@ -1126,7 +1143,7 @@ class dfrn {
$author["link"] = $xpath->evaluate($element."/atom:uri/text()", $context)->item(0)->nodeValue;
$r = q("SELECT `id`, `uid`, `url`, `network`, `avatar-date`, `name-date`, `uri-date`, `addr`,
`name`, `nick`, `about`, `location`, `keywords`, `bdyear`, `bd`
`name`, `nick`, `about`, `location`, `keywords`, `bdyear`, `bd`, `hidden`
FROM `contact` WHERE `uid` = %d AND `nurl` = '%s' AND `network` != '%s'",
intval($importer["uid"]), dbesc(normalise_link($author["link"])), dbesc(NETWORK_STATUSNET));
if ($r) {
@ -1210,6 +1227,16 @@ class dfrn {
/// - poco:region
/// - poco:country
// If the "hide" element is present then the profile isn't searchable.
$hide = intval($xpath->evaluate($element."/dfrn:hide/text()", $context)->item(0)->nodeValue == "true");
logger("Hidden status for contact ".$contact["url"].": ".$hide, LOGGER_DEBUG);
// If the contact isn't searchable then set the contact to "hidden".
// Problem: This can be manually overridden by the user.
if ($hide)
$contact["hidden"] = true;
// Save the keywords into the contact table
$tags = array();
$tagelements = $xpath->evaluate($element."/poco:tags/text()", $context);
@ -1262,17 +1289,17 @@ class dfrn {
unset($fields["name-date"]);
unset($fields["uri-date"]);
// Update check for this field has to be done differently
// Update check for this field has to be done differently
$datefields = array("name-date", "uri-date");
foreach ($datefields AS $field)
if (strtotime($contact[$field]) > strtotime($r[0][$field])) {
logger("Difference for contact ".$contact["id"]." in field '".$field."'. Old value: '".$contact[$field]."', new value '".$r[0][$field]."'", LOGGER_DEBUG);
logger("Difference for contact ".$contact["id"]." in field '".$field."'. New value: '".$contact[$field]."', old value '".$r[0][$field]."'", LOGGER_DEBUG);
$update = true;
}
foreach ($fields AS $field => $data)
if ($contact[$field] != $r[0][$field]) {
logger("Difference for contact ".$contact["id"]." in field '".$field."'. Old value: '".$contact[$field]."', new value '".$r[0][$field]."'", LOGGER_DEBUG);
logger("Difference for contact ".$contact["id"]." in field '".$field."'. New value: '".$contact[$field]."', old value '".$r[0][$field]."'", LOGGER_DEBUG);
$update = true;
}
@ -1280,13 +1307,13 @@ class dfrn {
logger("Update contact data for contact ".$contact["id"]." (".$contact["nick"].")", LOGGER_DEBUG);
q("UPDATE `contact` SET `name` = '%s', `nick` = '%s', `about` = '%s', `location` = '%s',
`addr` = '%s', `keywords` = '%s', `bdyear` = '%s', `bd` = '%s',
`addr` = '%s', `keywords` = '%s', `bdyear` = '%s', `bd` = '%s', `hidden` = %d,
`name-date` = '%s', `uri-date` = '%s'
WHERE `id` = %d AND `network` = '%s'",
dbesc($contact["name"]), dbesc($contact["nick"]), dbesc($contact["about"]), dbesc($contact["location"]),
dbesc($contact["addr"]), dbesc($contact["keywords"]), dbesc($contact["bdyear"]),
dbesc($contact["bd"]), dbesc($contact["name-date"]), dbesc($contact["uri-date"]),
intval($contact["id"]), dbesc($contact["network"]));
dbesc($contact["bd"]), intval($contact["hidden"]), dbesc($contact["name-date"]),
dbesc($contact["uri-date"]), intval($contact["id"]), dbesc($contact["network"]));
}
update_contact_avatar($author["avatar"], $importer["uid"], $contact["id"],
@ -1299,6 +1326,7 @@ class dfrn {
$poco["generation"] = 2;
$poco["photo"] = $author["avatar"];
$poco["hide"] = $hide;
update_gcontact($poco);
}
@ -1430,7 +1458,7 @@ class dfrn {
dbesc(normalise_link($suggest["url"])),
intval($suggest["uid"])
);
if(dba::is_result($r))
if(dbm::is_result($r))
return false;
// Do we already have an fcontact record for this person?
@ -1441,7 +1469,7 @@ class dfrn {
dbesc($suggest["name"]),
dbesc($suggest["request"])
);
if(dba::is_result($r)) {
if(dbm::is_result($r)) {
$fid = $r[0]["id"];
// OK, we do. Do we already have an introduction for this person ?
@ -1449,7 +1477,7 @@ class dfrn {
intval($suggest["uid"]),
intval($fid)
);
if(dba::is_result($r))
if(dbm::is_result($r))
return false;
}
if(!$fid)
@ -1464,7 +1492,7 @@ class dfrn {
dbesc($suggest["name"]),
dbesc($suggest["request"])
);
if(dba::is_result($r))
if(dbm::is_result($r))
$fid = $r[0]["id"];
else
// database record did not get created. Quietly give up.
@ -1519,7 +1547,9 @@ class dfrn {
$relocate["uid"] = $importer["importer_uid"];
$relocate["cid"] = $importer["id"];
$relocate["url"] = $xpath->query("dfrn:url/text()", $relocation)->item(0)->nodeValue;
$relocate["addr"] = $xpath->query("dfrn:addr/text()", $relocation)->item(0)->nodeValue;
$relocate["name"] = $xpath->query("dfrn:name/text()", $relocation)->item(0)->nodeValue;
$relocate["avatar"] = $xpath->query("dfrn:avatar/text()", $relocation)->item(0)->nodeValue;
$relocate["photo"] = $xpath->query("dfrn:photo/text()", $relocation)->item(0)->nodeValue;
$relocate["thumb"] = $xpath->query("dfrn:thumb/text()", $relocation)->item(0)->nodeValue;
$relocate["micro"] = $xpath->query("dfrn:micro/text()", $relocation)->item(0)->nodeValue;
@ -1529,6 +1559,12 @@ class dfrn {
$relocate["poll"] = $xpath->query("dfrn:poll/text()", $relocation)->item(0)->nodeValue;
$relocate["sitepubkey"] = $xpath->query("dfrn:sitepubkey/text()", $relocation)->item(0)->nodeValue;
if (($relocate["avatar"] == "") AND ($relocate["photo"] != ""))
$relocate["avatar"] = $relocate["photo"];
if ($relocate["addr"] == "")
$relocate["addr"] = preg_replace("=(https?://)(.*)/profile/(.*)=ism", "$3@$2", $relocate["url"]);
// update contact
$r = q("SELECT `photo`, `url` FROM `contact` WHERE `id` = %d AND `uid` = %d;",
intval($importer["id"]),
@ -1538,51 +1574,83 @@ class dfrn {
$old = $r[0];
$x = q("UPDATE `contact` SET
// Update the gcontact entry
$relocate["server_url"] = preg_replace("=(https?://)(.*)/profile/(.*)=ism", "$1$2", $relocate["url"]);
$x = q("UPDATE `gcontact` SET
`name` = '%s',
`photo` = '%s',
`thumb` = '%s',
`micro` = '%s',
`url` = '%s',
`nurl` = '%s',
`addr` = '%s',
`connect` = '%s',
`notify` = '%s',
`server_url` = '%s'
WHERE `nurl` = '%s';",
dbesc($relocate["name"]),
dbesc($relocate["avatar"]),
dbesc($relocate["url"]),
dbesc(normalise_link($relocate["url"])),
dbesc($relocate["addr"]),
dbesc($relocate["addr"]),
dbesc($relocate["notify"]),
dbesc($relocate["server_url"]),
dbesc(normalise_link($old["url"])));
// Update the contact table. We try to find every entry.
$x = q("UPDATE `contact` SET
`name` = '%s',
`avatar` = '%s',
`url` = '%s',
`nurl` = '%s',
`addr` = '%s',
`request` = '%s',
`confirm` = '%s',
`notify` = '%s',
`poll` = '%s',
`site-pubkey` = '%s'
WHERE `id` = %d AND `uid` = %d;",
WHERE (`id` = %d AND `uid` = %d) OR (`nurl` = '%s');",
dbesc($relocate["name"]),
dbesc($relocate["photo"]),
dbesc($relocate["thumb"]),
dbesc($relocate["micro"]),
dbesc($relocate["avatar"]),
dbesc($relocate["url"]),
dbesc(normalise_link($relocate["url"])),
dbesc($relocate["addr"]),
dbesc($relocate["request"]),
dbesc($relocate["confirm"]),
dbesc($relocate["notify"]),
dbesc($relocate["poll"]),
dbesc($relocate["sitepubkey"]),
intval($importer["id"]),
intval($importer["importer_uid"]));
intval($importer["importer_uid"]),
dbesc(normalise_link($old["url"])));
update_contact_avatar($relocate["avatar"], $importer["importer_uid"], $importer["id"], true);
if ($x === false)
return false;
// update items
/// @todo This is an extreme performance killer
$fields = array(
'owner-link' => array($old["url"], $relocate["url"]),
'author-link' => array($old["url"], $relocate["url"]),
'owner-avatar' => array($old["photo"], $relocate["photo"]),
'author-avatar' => array($old["photo"], $relocate["photo"]),
//'owner-avatar' => array($old["photo"], $relocate["photo"]),
//'author-avatar' => array($old["photo"], $relocate["photo"]),
);
foreach ($fields as $n=>$f){
$x = q("UPDATE `item` SET `%s` = '%s' WHERE `%s` = '%s' AND `uid` = %d",
$n, dbesc($f[1]),
foreach ($fields as $n=>$f) {
$r = q("SELECT `id` FROM `item` WHERE `%s` = '%s' AND `uid` = %d LIMIT 1",
$n, dbesc($f[0]),
intval($importer["importer_uid"]));
if ($x === false)
return false;
if ($r) {
$x = q("UPDATE `item` SET `%s` = '%s' WHERE `%s` = '%s' AND `uid` = %d",
$n, dbesc($f[1]),
$n, dbesc($f[0]),
intval($importer["importer_uid"]));
if ($x === false)
return false;
}
}
/// @TODO
/// merge with current record, current contents have priority
@ -1624,7 +1692,7 @@ class dfrn {
$changed = true;
if ($entrytype == DFRN_REPLY_RC)
proc_run("php", "include/notifier.php","comment-import", $current["id"]);
proc_run(PRIORITY_HIGH, "include/notifier.php","comment-import", $current["id"]);
}
// update last-child if it changes
@ -2120,7 +2188,7 @@ class dfrn {
dbesc($item["uri"]),
intval($importer["uid"])
);
if(dba::is_result($r))
if(dbm::is_result($r))
$ev["id"] = $r[0]["id"];
$event_id = event_store($ev);
@ -2141,7 +2209,7 @@ class dfrn {
}
// Update content if 'updated' changes
if(dba::is_result($r)) {
if(dbm::is_result($r)) {
if (self::update_content($r[0], $item, $importer, $entrytype))
logger("Item ".$item["uri"]." was updated.", LOGGER_DEBUG);
else
@ -2163,7 +2231,7 @@ class dfrn {
intval($posted_id),
intval($importer["importer_uid"])
);
if(dba::is_result($r)) {
if(dbm::is_result($r)) {
$parent = $r[0]["parent"];
$parent_uri = $r[0]["parent-uri"];
}
@ -2184,7 +2252,7 @@ class dfrn {
if($posted_id AND $parent AND ($entrytype == DFRN_REPLY_RC)) {
logger("Notifying followers about comment ".$posted_id, LOGGER_DEBUG);
proc_run("php", "include/notifier.php", "comment-import", $posted_id);
proc_run(PRIORITY_HIGH, "include/notifier.php", "comment-import", $posted_id);
}
return true;
@ -2345,7 +2413,7 @@ class dfrn {
dbesc($item["parent-uri"]),
intval($importer["uid"])
);
if(dba::is_result($r)) {
if(dbm::is_result($r)) {
q("UPDATE `item` SET `last-child` = 1 WHERE `id` = %d",
intval($r[0]["id"])
);
@ -2355,7 +2423,7 @@ class dfrn {
if($entrytype == DFRN_REPLY_RC) {
logger("Notifying followers about deletion of post ".$item["id"], LOGGER_DEBUG);
proc_run("php", "include/notifier.php","drop", $item["id"]);
proc_run(PRIORITY_HIGH, "include/notifier.php","drop", $item["id"]);
}
}
}

View file

@ -3,40 +3,9 @@
* @file include/diaspora.php
* @brief The implementation of the diaspora protocol
*
* Checklist:
*
* Checked:
* - send status
* - send comment
* - send like
* - send mail
* - send status retraction
* - send comment retraction on own post
* - send like retraction on own post
* - send comment retraction on diaspora post
* - send like retraction on diaspora post
* - receive status
* - receive reshare
* - receive comment
* - receive like
* - receive connect request
* - receive profile data
* - receive mail
* - receive comment retraction
* - receive like retraction
* - relay comment
* - relay like
* - relay comment retraction from diaspora
* - relay comment retraction from friendica
* - relay like retraction from diaspora
* - relay like retraction from friendica
* - send share
*
* Should work:
* - receive account deletion
* - send unshare
*
* Unchecked:
* The new protocol is described here: http://diaspora.github.io/diaspora_federation/index.html
* Currently this implementation here interprets the old and the new protocol and sends the old one.
* This will change in the future.
*/
require_once("include/items.php");
@ -135,6 +104,59 @@ class diaspora {
return($signature);
}
/**
* @brief verify the envelope and return the verified data
*
* @param string $envelope The magic envelope
*
* @return string verified data
*/
private function verify_magic_envelope($envelope) {
$basedom = parse_xml_string($envelope, false);
if (!is_object($basedom)) {
logger("Envelope is no XML file");
return false;
}
$children = $basedom->children('http://salmon-protocol.org/ns/magic-env');
if (sizeof($children) == 0) {
logger("XML has no children");
return false;
}
$handle = "";
$data = base64url_decode($children->data);
$type = $children->data->attributes()->type[0];
$encoding = $children->encoding;
$alg = $children->alg;
$sig = base64url_decode($children->sig);
$key_id = $children->sig->attributes()->key_id[0];
if ($key_id != "")
$handle = base64url_decode($key_id);
$b64url_data = base64url_encode($data);
$msg = str_replace(array("\n", "\r", " ", "\t"), array("", "", "", ""), $b64url_data);
$signable_data = $msg.".".base64url_encode($type).".".base64url_encode($encoding).".".base64url_encode($alg);
$key = self::key($handle);
$verify = rsa_verify($signable_data, $sig, $key);
if (!$verify) {
logger('Message did not verify. Discarding.');
return false;
}
return $data;
}
/**
* @brief: Decodes incoming Diaspora message
*
@ -268,7 +290,6 @@ class diaspora {
return array('message' => (string)$inner_decrypted,
'author' => unxmlify($author_link),
'key' => (string)$key);
}
@ -395,8 +416,10 @@ class diaspora {
$data = parse_xml_string($msg["message"], false);
if (!is_object($data))
if (!is_object($data)) {
logger("No valid XML ".$msg["message"], LOGGER_DEBUG);
return false;
}
$first_child = $data->getName();
@ -413,6 +436,8 @@ class diaspora {
$type = $element->getName();
$orig_type = $type;
logger("Got message type ".$type.": ".$msg["message"], LOGGER_DATA);
// All retractions are handled identically from now on.
// In the new version there will only be "retraction".
if (in_array($type, array("signed_retraction", "relayable_retraction")))
@ -457,11 +482,11 @@ class diaspora {
}
}
if ($fieldname == "author_signature")
if (($fieldname == "author_signature") AND ($entry != ""))
$author_signature = base64_decode($entry);
elseif ($fieldname == "parent_author_signature")
elseif (($fieldname == "parent_author_signature") AND ($entry != ""))
$parent_author_signature = base64_decode($entry);
elseif ($fieldname != "target_author_signature") {
elseif (!in_array($fieldname, array("author_signature", "parent_author_signature", "target_author_signature"))) {
if ($signed_data != "") {
$signed_data .= ";";
$signed_data_parent .= ";";
@ -486,19 +511,27 @@ class diaspora {
return true;
// No author_signature? This is a must, so we quit.
if (!isset($author_signature))
if (!isset($author_signature)) {
logger("No author signature for type ".$type." - Message: ".$msg["message"], LOGGER_DEBUG);
return false;
}
if (isset($parent_author_signature)) {
$key = self::key($msg["author"]);
if (!rsa_verify($signed_data, $parent_author_signature, $key, "sha256"))
if (!rsa_verify($signed_data, $parent_author_signature, $key, "sha256")) {
logger("No valid parent author signature for author ".$msg["author"]. " in type ".$type." - signed data: ".$signed_data." - Message: ".$msg["message"]." - Signature ".$parent_author_signature, LOGGER_DEBUG);
return false;
}
}
$key = self::key($fields->author);
return rsa_verify($signed_data, $author_signature, $key, "sha256");
if (!rsa_verify($signed_data, $author_signature, $key, "sha256")) {
logger("No valid author signature for author ".$msg["author"]. " in type ".$type." - signed data: ".$signed_data." - Message: ".$msg["message"]." - Signature ".$author_signature, LOGGER_DEBUG);
return false;
} else
return true;
}
/**
@ -541,6 +574,9 @@ class diaspora {
$d = strtotime($person["updated"]." +00:00");
if ($d < strtotime("now - 14 days"))
$update = true;
if ($person["guid"] == "")
$update = true;
}
if (!$person OR $update) {
@ -574,6 +610,7 @@ class diaspora {
`request` = '%s',
`nick` = '%s',
`addr` = '%s',
`guid` = '%s',
`batch` = '%s',
`notify` = '%s',
`poll` = '%s',
@ -586,7 +623,8 @@ class diaspora {
dbesc($arr["photo"]),
dbesc($arr["request"]),
dbesc($arr["nick"]),
dbesc($arr["addr"]),
dbesc(strtolower($arr["addr"])),
dbesc($arr["guid"]),
dbesc($arr["batch"]),
dbesc($arr["notify"]),
dbesc($arr["poll"]),
@ -598,15 +636,16 @@ class diaspora {
dbesc($arr["network"])
);
} else {
$r = q("INSERT INTO `fcontact` (`url`,`name`,`photo`,`request`,`nick`,`addr`,
$r = q("INSERT INTO `fcontact` (`url`,`name`,`photo`,`request`,`nick`,`addr`, `guid`,
`batch`, `notify`,`poll`,`confirm`,`network`,`alias`,`pubkey`,`updated`)
VALUES ('%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s')",
VALUES ('%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s')",
dbesc($arr["url"]),
dbesc($arr["name"]),
dbesc($arr["photo"]),
dbesc($arr["request"]),
dbesc($arr["nick"]),
dbesc($arr["addr"]),
dbesc($arr["guid"]),
dbesc($arr["batch"]),
dbesc($arr["notify"]),
dbesc($arr["poll"]),
@ -638,7 +677,7 @@ class diaspora {
$r = q("SELECT `addr` FROM `gcontact` WHERE `id` = %d AND `addr` != ''",
intval($gcontact_id));
if ($r)
return $r[0]["addr"];
return strtolower($r[0]["addr"]);
}
$r = q("SELECT `network`, `addr`, `self`, `url`, `nick` FROM `contact` WHERE `id` = %d",
@ -658,7 +697,7 @@ class diaspora {
}
}
return $handle;
return strtolower($handle);
}
/**
@ -841,11 +880,30 @@ class diaspora {
if ($level > 5)
return false;
// This will work for Diaspora and newer Friendica servers
$source_url = $server."/p/".$guid.".xml";
$x = fetch_url($source_url);
if(!$x)
return false;
// This will work for new Diaspora servers and Friendica servers from 3.5
$source_url = $server."/fetch/post/".$guid;
logger("Fetch post from ".$source_url, LOGGER_DEBUG);
$envelope = fetch_url($source_url);
if($envelope) {
logger("Envelope was fetched.", LOGGER_DEBUG);
$x = self::verify_magic_envelope($envelope);
if (!$x)
logger("Envelope could not be verified.", LOGGER_DEBUG);
else
logger("Envelope was verified.", LOGGER_DEBUG);
} else
$x = false;
// This will work for older Diaspora and Friendica servers
if (!$x) {
$source_url = $server."/p/".$guid.".xml";
logger("Fetch post from ".$source_url, LOGGER_DEBUG);
$x = fetch_url($source_url);
if(!$x)
return false;
}
$source_xml = parse_xml_string($x, false);
@ -854,9 +912,11 @@ class diaspora {
if ($source_xml->post->reshare) {
// Reshare of a reshare - old Diaspora version
logger("Message is a reshare", LOGGER_DEBUG);
return self::message($source_xml->post->reshare->root_guid, $server, ++$level);
} elseif ($source_xml->getName() == "reshare") {
// Reshare of a reshare - new Diaspora version
logger("Message is a new reshare", LOGGER_DEBUG);
return self::message($source_xml->root_guid, $server, ++$level);
}
@ -869,8 +929,10 @@ class diaspora {
$author = (string)$source_xml->author;
// If this isn't a "status_message" then quit
if (!$author)
if (!$author) {
logger("Message doesn't seem to be a status message", LOGGER_DEBUG);
return false;
}
$msg = array("message" => $x, "author" => $author);
@ -1016,6 +1078,23 @@ class diaspora {
return true;
}
/**
* @brief Fetch the uri from our database if we already have this item (maybe from ourselves)
*
* @param string $author Author handle
* @param string $guid Message guid
*
* @return string The constructed uri or the one from our database
*/
private function get_uri_from_guid($author, $guid) {
$r = q("SELECT `uri` FROM `item` WHERE `guid` = '%s' LIMIT 1", dbesc($guid));
if ($r)
return $r[0]["uri"];
else
return $author.":".$guid;
}
/**
* @brief Processes an incoming comment
*
@ -1032,6 +1111,11 @@ class diaspora {
$text = unxmlify($data->text);
$author = notags(unxmlify($data->author));
if (isset($data->created_at))
$created_at = datetime_convert("UTC", "UTC", notags(unxmlify($data->created_at)));
else
$created_at = datetime_convert();
$contact = self::allowed_contact_by_handle($importer, $sender, true);
if (!$contact)
return false;
@ -1068,7 +1152,7 @@ class diaspora {
$datarray["owner-avatar"] = ((x($contact,"thumb")) ? $contact["thumb"] : $contact["photo"]);
$datarray["guid"] = $guid;
$datarray["uri"] = $author.":".$guid;
$datarray["uri"] = self::get_uri_from_guid($author, $guid);
$datarray["type"] = "remote-comment";
$datarray["verb"] = ACTIVITY_POST;
@ -1078,6 +1162,8 @@ class diaspora {
$datarray["object-type"] = ACTIVITY_OBJ_COMMENT;
$datarray["object"] = $xml;
$datarray["changed"] = $datarray["created"] = $datarray["edited"] = $created_at;
$datarray["body"] = diaspora2bb($text);
self::fetch_guid($datarray);
@ -1098,7 +1184,7 @@ class diaspora {
);
// notify others
proc_run("php", "include/notifier.php", "comment-import", $message_id);
proc_run(PRIORITY_HIGH, "include/notifier.php", "comment-import", $message_id);
}
return $message_id;
@ -1188,7 +1274,7 @@ class diaspora {
$r = q("SELECT `id` FROM `mail` WHERE `uri` = '%s' LIMIT 1",
dbesc($message_uri)
);
if($r) {
if(dbm::is_result($r)) {
logger("duplicate message already delivered.", LOGGER_DEBUG);
return false;
}
@ -1274,7 +1360,7 @@ class diaspora {
intval($importer["uid"]),
dbesc($guid),
dbesc($author),
dbesc(datetime_convert("UTC", "UTC", $created_at)),
dbesc($created_at),
dbesc(datetime_convert()),
dbesc($subject),
dbesc($participants)
@ -1405,7 +1491,7 @@ class diaspora {
$datarray["owner-avatar"] = ((x($contact,"thumb")) ? $contact["thumb"] : $contact["photo"]);
$datarray["guid"] = $guid;
$datarray["uri"] = $author.":".$guid;
$datarray["uri"] = self::get_uri_from_guid($author, $guid);
$datarray["type"] = "activity";
$datarray["verb"] = $verb;
@ -1433,7 +1519,7 @@ class diaspora {
);
// notify others
proc_run("php", "include/notifier.php", "comment-import", $message_id);
proc_run(PRIORITY_HIGH, "include/notifier.php", "comment-import", $message_id);
}
return $message_id;
@ -1566,7 +1652,7 @@ class diaspora {
* @return bool Success
*/
private function receive_profile($importer, $data) {
$author = notags(unxmlify($data->author));
$author = strtolower(notags(unxmlify($data->author)));
$contact = self::contact_by_handle($importer["uid"], $author);
if (!$contact)
@ -1713,7 +1799,7 @@ class diaspora {
$i = item_store($arr);
if($i)
proc_run("php", "include/notifier.php", "activity", $i);
proc_run(PRIORITY_HIGH, "include/notifier.php", "activity", $i);
}
}
}
@ -1771,10 +1857,26 @@ class diaspora {
// That makes us friends.
if ($contact) {
if ($following AND $sharing) {
logger("Author ".$author." (Contact ".$contact["id"].") wants to have a bidirectional conection.", LOGGER_DEBUG);
self::receive_request_make_friend($importer, $contact);
// refetch the contact array
$contact = self::contact_by_handle($importer["uid"],$author);
// If we are now friends, we are sending a share message.
// Normally we needn't to do so, but the first message could have been vanished.
if (in_array($contact["rel"], array(CONTACT_IS_FRIEND, CONTACT_IS_FOLLOWER))) {
$u = q("SELECT * FROM `user` WHERE `uid` = %d LIMIT 1", intval($importer["uid"]));
if($u) {
logger("Sending share message to author ".$author." - Contact: ".$contact["id"]." - User: ".$importer["uid"], LOGGER_DEBUG);
$ret = self::send_share($u[0], $contact);
}
}
return true;
} else /// @todo Handle all possible variations of adding and retracting of permissions
} else { /// @todo Handle all possible variations of adding and retracting of permissions
logger("Author ".$author." (Contact ".$contact["id"].") wants to change the relationship: Following: ".$following." - sharing: ".$sharing. "(By now unsupported)", LOGGER_DEBUG);
return false;
}
}
if (!$following AND $sharing AND in_array($importer["page-flags"], array(PAGE_SOAPBOX, PAGE_NORMAL))) {
@ -1783,6 +1885,12 @@ class diaspora {
} elseif (!$following AND !$sharing) {
logger("Author ".$author." doesn't want anything - and we don't know the author. Request is ignored.", LOGGER_DEBUG);
return false;
} elseif (!$following AND $sharing) {
logger("Author ".$author." wants to share with us.", LOGGER_DEBUG);
} elseif ($following AND $sharing) {
logger("Author ".$author." wants to have a bidirectional conection.", LOGGER_DEBUG);
} elseif ($following AND !$sharing) {
logger("Author ".$author." wants to listen to us.", LOGGER_DEBUG);
}
$ret = self::person_by_handle($author);
@ -1822,13 +1930,19 @@ class diaspora {
return;
}
logger("Author ".$author." was added as contact number ".$contact_record["id"].".", LOGGER_DEBUG);
$def_gid = get_default_group($importer['uid'], $ret["network"]);
if(intval($def_gid))
group_add_member($importer["uid"], "", $contact_record["id"], $def_gid);
update_contact_avatar($ret["photo"], $importer['uid'], $contact_record["id"], true);
if($importer["page-flags"] == PAGE_NORMAL) {
logger("Sending intra message for author ".$author.".", LOGGER_DEBUG);
$hash = random_string().(string)time(); // Generate a confirm_key
$ret = q("INSERT INTO `intro` (`uid`, `contact-id`, `blocked`, `knowyou`, `note`, `hash`, `datetime`)
@ -1845,6 +1959,8 @@ class diaspora {
// automatic friend approval
logger("Does an automatic friend approval for author ".$author.".", LOGGER_DEBUG);
update_contact_avatar($contact_record["photo"],$importer["uid"],$contact_record["id"]);
// technically they are sharing with us (CONTACT_IS_SHARING),
@ -1873,8 +1989,13 @@ class diaspora {
);
$u = q("SELECT * FROM `user` WHERE `uid` = %d LIMIT 1", intval($importer["uid"]));
if($u)
if($u) {
logger("Sending share message (Relation: ".$new_relation.") to author ".$author." - Contact: ".$contact_record["id"]." - User: ".$importer["uid"], LOGGER_DEBUG);
$ret = self::send_share($u[0], $contact_record);
// Send the profile data, maybe it weren't transmitted before
self::send_profile($importer["uid"], array($contact_record));
}
}
return true;
@ -1918,35 +2039,28 @@ class diaspora {
if (!$r) {
$server = "https://".substr($orig_author, strpos($orig_author, "@") + 1);
logger("1st try: reshared message ".$guid." will be fetched from original server: ".$server);
logger("1st try: reshared message ".$guid." will be fetched via SSL from the server ".$server);
$item_id = self::store_by_guid($guid, $server);
if (!$item_id) {
$server = "http://".substr($orig_author, strpos($orig_author, "@") + 1);
logger("2nd try: reshared message ".$guid." will be fetched from original server: ".$server);
logger("2nd try: reshared message ".$guid." will be fetched without SLL from the server ".$server);
$item_id = self::store_by_guid($guid, $server);
}
// Deactivated by now since there is a risk that someone could manipulate postings through this method
/* if (!$item_id) {
$server = "https://".substr($author, strpos($author, "@") + 1);
logger("3rd try: reshared message ".$guid." will be fetched from sharer's server: ".$server);
$item_id = self::store_by_guid($guid, $server);
}
if (!$item_id) {
$server = "http://".substr($author, strpos($author, "@") + 1);
logger("4th try: reshared message ".$guid." will be fetched from sharer's server: ".$server);
$item_id = self::store_by_guid($guid, $server);
}
*/
if ($item_id) {
$r = q("SELECT `body`, `tag`, `app`, `created`, `object-type`, `uri`, `guid`,
`author-name`, `author-link`, `author-avatar`
FROM `item` WHERE `id` = %d AND `visible` AND NOT `deleted` AND `body` != '' LIMIT 1",
intval($item_id));
if ($r)
if ($r) {
// If it is a reshared post from another network then reformat to avoid display problems with two share elements
if (self::is_reshare($r[0]["body"], false))
$r[0]["body"] = diaspora2bb(bb2diaspora($r[0]["body"]));
return $r[0];
}
}
}
@ -1968,7 +2082,7 @@ class diaspora {
$guid = notags(unxmlify($data->guid));
$author = notags(unxmlify($data->author));
$public = notags(unxmlify($data->public));
$created_at = notags(unxmlify($data->created_at));
$created_at = datetime_convert("UTC", "UTC", notags(unxmlify($data->created_at)));
$contact = self::allowed_contact_by_handle($importer, $author, false);
if (!$contact)
@ -1999,7 +2113,7 @@ class diaspora {
$datarray["owner-avatar"] = $datarray["author-avatar"];
$datarray["guid"] = $guid;
$datarray["uri"] = $datarray["parent-uri"] = $author.":".$guid;
$datarray["uri"] = $datarray["parent-uri"] = self::get_uri_from_guid($author, $guid);
$datarray["verb"] = ACTIVITY_POST;
$datarray["gravity"] = GRAVITY_PARENT;
@ -2015,7 +2129,7 @@ class diaspora {
$datarray["plink"] = self::plink($author, $guid);
$datarray["private"] = (($public == "false") ? 1 : 0);
$datarray["changed"] = $datarray["created"] = $datarray["edited"] = datetime_convert("UTC", "UTC", $created_at);
$datarray["changed"] = $datarray["created"] = $datarray["edited"] = $created_at;
$datarray["object-type"] = $original_item["object-type"];
@ -2055,12 +2169,6 @@ class diaspora {
if (!$r)
return false;
// Only delete it if the author really fits
if (!link_compare($r[0]["author-link"], $person["url"])) {
logger("Item author ".$r[0]["author-link"]." doesn't fit to expected contact ".$person["url"], LOGGER_DEBUG);
return false;
}
// Check if the sender is the thread owner
$p = q("SELECT `id`, `author-link`, `origin` FROM `item` WHERE `id` = %d",
intval($r[0]["parent"]));
@ -2084,7 +2192,7 @@ class diaspora {
// Now check if the retraction needs to be relayed by us
if($p[0]["origin"]) {
// notify others
proc_run("php", "include/notifier.php", "drop", $r[0]["id"]);
proc_run(PRIORITY_HIGH, "include/notifier.php", "drop", $r[0]["id"]);
}
return true;
@ -2142,12 +2250,11 @@ class diaspora {
* @return int The message id of the newly created item
*/
private function receive_status_message($importer, $data, $xml) {
$raw_message = unxmlify($data->raw_message);
$guid = notags(unxmlify($data->guid));
$author = notags(unxmlify($data->author));
$public = notags(unxmlify($data->public));
$created_at = notags(unxmlify($data->created_at));
$created_at = datetime_convert("UTC", "UTC", notags(unxmlify($data->created_at)));
$provider_display_name = notags(unxmlify($data->provider_display_name));
/// @todo enable support for polls
@ -2201,7 +2308,7 @@ class diaspora {
$datarray["owner-avatar"] = $datarray["author-avatar"];
$datarray["guid"] = $guid;
$datarray["uri"] = $datarray["parent-uri"] = $author.":".$guid;
$datarray["uri"] = $datarray["parent-uri"] = self::get_uri_from_guid($author, $guid);
$datarray["verb"] = ACTIVITY_POST;
$datarray["gravity"] = GRAVITY_PARENT;
@ -2215,7 +2322,7 @@ class diaspora {
$datarray["plink"] = self::plink($author, $guid);
$datarray["private"] = (($public == "false") ? 1 : 0);
$datarray["changed"] = $datarray["created"] = $datarray["edited"] = datetime_convert("UTC", "UTC", $created_at);
$datarray["changed"] = $datarray["created"] = $datarray["edited"] = $created_at;
if (isset($address["address"]))
$datarray["location"] = $address["address"];
@ -2257,6 +2364,40 @@ class diaspora {
return $nick."@".substr(App::get_baseurl(), strpos(App::get_baseurl(),"://") + 3);
}
/**
* @brief Creates the envelope for the "fetch" endpoint
*
* @param string $msg The message that is to be transmitted
* @param array $user The record of the sender
*
* @return string The envelope
*/
public static function build_magic_envelope($msg, $user) {
$b64url_data = base64url_encode($msg);
$data = str_replace(array("\n", "\r", " ", "\t"), array("", "", "", ""), $b64url_data);
$key_id = base64url_encode(diaspora::my_handle($user));
$type = "application/xml";
$encoding = "base64url";
$alg = "RSA-SHA256";
$signable_data = $data.".".base64url_encode($type).".".base64url_encode($encoding).".".base64url_encode($alg);
$signature = rsa_sign($signable_data, $user["prvkey"]);
$sig = base64url_encode($signature);
$xmldata = array("me:env" => array("me:data" => $data,
"@attributes" => array("type" => $type),
"me:encoding" => $encoding,
"me:alg" => $alg,
"me:sig" => $sig,
"@attributes2" => array("key_id" => $key_id)));
$namespaces = array("me" => "http://salmon-protocol.org/ns/magic-env");
return xml::from_array($xmldata, $xml, false, $namespaces);
}
/**
* @brief Creates the envelope for a public message
*
@ -2288,11 +2429,11 @@ class diaspora {
$sig = base64url_encode($signature);
$xmldata = array("diaspora" => array("header" => array("author_id" => $handle),
"me:env" => array("me:encoding" => "base64url",
"me:alg" => "RSA-SHA256",
"me:data" => $data,
"@attributes" => array("type" => "application/xml"),
"me:sig" => $sig)));
"me:env" => array("me:encoding" => $encoding,
"me:alg" => $alg,
"me:data" => $data,
"@attributes" => array("type" => $type),
"me:sig" => $sig)));
$namespaces = array("" => "https://joindiaspora.com/protocol",
"me" => "http://salmon-protocol.org/ns/magic-env");
@ -2378,10 +2519,10 @@ class diaspora {
$cipher_json = base64_encode($encrypted_header_json_object);
$xmldata = array("diaspora" => array("encrypted_header" => $cipher_json,
"me:env" => array("me:encoding" => "base64url",
"me:alg" => "RSA-SHA256",
"me:env" => array("me:encoding" => $encoding,
"me:alg" => $alg,
"me:data" => $data,
"@attributes" => array("type" => "application/xml"),
"@attributes" => array("type" => $type),
"me:sig" => $sig)));
$namespaces = array("" => "https://joindiaspora.com/protocol",
@ -2499,6 +2640,20 @@ class diaspora {
}
/**
* @brief Build the post xml
*
* @param string $type The message type
* @param array $message The message data
*
* @return string The post XML
*/
public static function build_post_xml($type, $message) {
$data = array("XML" => array("post" => array($type => $message)));
return xml::from_array($data, $xml);
}
/**
* @brief Builds and transmit messages
*
@ -2514,13 +2669,15 @@ class diaspora {
*/
private function build_and_transmit($owner, $contact, $type, $message, $public_batch = false, $guid = "", $spool = false) {
$data = array("XML" => array("post" => array($type => $message)));
$msg = xml::from_array($data, $xml);
$msg = self::build_post_xml($type, $message);
logger('message: '.$msg, LOGGER_DATA);
logger('send guid '.$guid, LOGGER_DEBUG);
// Fallback if the private key wasn't transmitted in the expected field
if ($owner['uprvkey'] == "")
$owner['uprvkey'] = $owner['prvkey'];
$slap = self::build_message($msg, $owner, $contact, $owner['uprvkey'], $contact['pubkey'], $public_batch);
if ($spool) {
@ -2547,6 +2704,8 @@ class diaspora {
$message = array("sender_handle" => self::my_handle($owner),
"recipient_handle" => $contact["addr"]);
logger("Send share ".print_r($message, true), LOGGER_DEBUG);
return self::build_and_transmit($owner, $contact, "request", $message);
}
@ -2564,6 +2723,8 @@ class diaspora {
"diaspora_handle" => self::my_handle($owner),
"type" => "Person");
logger("Send unshare ".print_r($message, true), LOGGER_DEBUG);
return self::build_and_transmit($owner, $contact, "retraction", $message);
}
@ -2580,7 +2741,7 @@ class diaspora {
// Skip if it isn't a pure repeated messages
// Does it start with a share?
if (strpos($body, "[share") > 0)
if ((strpos($body, "[share") > 0) AND $complete)
return(false);
// Does it end with a share?
@ -2648,16 +2809,16 @@ class diaspora {
}
/**
* @brief Sends a post
* @brief Create a post (status message or reshare)
*
* @param array $item The item that will be exported
* @param array $owner the array of the item owner
* @param array $contact Target of the communication
* @param bool $public_batch Is it a public post?
*
* @return int The result of the transmission
* @return array
* 'type' -> Message type ("status_message" or "reshare")
* 'message' -> Array of XML elements of the status
*/
public static function send_status($item, $owner, $contact, $public_batch = false) {
public static function build_status($item, $owner) {
$myaddr = self::my_handle($owner);
@ -2720,8 +2881,24 @@ class diaspora {
$type = "status_message";
}
return array("type" => $type, "message" => $message);
}
return self::build_and_transmit($owner, $contact, $type, $message, $public_batch, $item["guid"]);
/**
* @brief Sends a post
*
* @param array $item The item that will be exported
* @param array $owner the array of the item owner
* @param array $contact Target of the communication
* @param bool $public_batch Is it a public post?
*
* @return int The result of the transmission
*/
public static function send_status($item, $owner, $contact, $public_batch = false) {
$status = diaspora::build_status($item, $owner);
return self::build_and_transmit($owner, $contact, $status["type"], $status["message"], $public_batch, $item["guid"]);
}
/**
@ -2736,7 +2913,7 @@ class diaspora {
$p = q("SELECT `guid`, `uri`, `parent-uri` FROM `item` WHERE `uri` = '%s' LIMIT 1",
dbesc($item["thr-parent"]));
if(!$p)
if(!dbm::is_result($p))
return false;
$parent = $p[0];
@ -2767,7 +2944,7 @@ class diaspora {
intval($item["parent"])
);
if (!$p)
if (!dbm::is_result($p))
return false;
$parent = $p[0];
@ -2981,7 +3158,7 @@ class diaspora {
intval($item["uid"])
);
if (!$r) {
if (!dbm::is_result($r)) {
logger("conversation not found.");
return;
}
@ -3034,17 +3211,18 @@ class diaspora {
*
* @param int $uid The user id
*/
public static function send_profile($uid) {
public static function send_profile($uid, $recips = false) {
if (!$uid)
return;
$recips = q("SELECT `id`,`name`,`network`,`pubkey`,`notify` FROM `contact` WHERE `network` = '%s'
AND `uid` = %d AND `rel` != %d",
dbesc(NETWORK_DIASPORA),
intval($uid),
intval(CONTACT_IS_SHARING)
);
if (!$recips)
$recips = q("SELECT `id`,`name`,`network`,`pubkey`,`notify` FROM `contact` WHERE `network` = '%s'
AND `uid` = %d AND `rel` != %d",
dbesc(NETWORK_DIASPORA),
intval($uid),
intval(CONTACT_IS_SHARING)
);
if (!$recips)
return;
@ -3108,8 +3286,10 @@ class diaspora {
"searchable" => $searchable,
"tag_string" => $tags);
foreach($recips as $recip)
foreach($recips as $recip) {
logger("Send updated profile data for user ".$uid." to contact ".$recip["id"], LOGGER_DEBUG);
self::build_and_transmit($profile, $recip, "profile", $message, false, "", true);
}
}
/**

View file

@ -4,38 +4,43 @@ require_once('include/email.php');
require_once('include/bbcode.php');
require_once('include/html2bbcode.php');
/**
* @brief Creates a notification entry and possibly sends a mail
*
* @param array $params Array with the elements:
uid, item, parent, type, otype, verb, event,
link, subject, body, to_name, to_email, source_name,
source_link, activity, preamble, notify_flags,
language, show_in_notification_page
*/
function notification($params) {
#logger('notification()', LOGGER_DEBUG);
$a = get_app();
// from here on everything is in the recipients language
push_lang($params['language']);
$banner = t('Friendica Notification');
$product = FRIENDICA_PLATFORM;
$siteurl = $a->get_baseurl(true);
$thanks = t('Thank You,');
$sitename = $a->config['sitename'];
if (!x($a->config['admin_name'])) {
$site_admin = sprintf( t('%s Administrator'), $sitename);
} else {
$site_admin = sprintf( t('%1$s, %2$s Administrator'), $a->config['admin_name'], $sitename);
}
if (!x($a->config['admin_name']))
$site_admin = sprintf(t('%s Administrator'), $sitename);
else
$site_admin = sprintf(t('%1$s, %2$s Administrator'), $a->config['admin_name'], $sitename);
$nickname = "";
$sender_name = $sitename;
$hostname = $a->get_hostname();
if(strpos($hostname,':'))
$hostname = substr($hostname,0,strpos($hostname,':'));
if (strpos($hostname, ':'))
$hostname = substr($hostname, 0, strpos($hostname, ':'));
$sender_email = $a->config['sender_email'];
if (empty($sender_email)) {
$sender_email = t('noreply') . '@' . $hostname;
}
if (empty($sender_email))
$sender_email = t('noreply').'@'.$hostname;
$user = q("SELECT `nickname` FROM `user` WHERE `uid` = %d", intval($params['uid']));
if ($user)
@ -44,7 +49,7 @@ function notification($params) {
// with $params['show_in_notification_page'] == false, the notification isn't inserted into
// the database, and an email is sent if applicable.
// default, if not specified: true
$show_in_notification_page = ((x($params,'show_in_notification_page')) ? $params['show_in_notification_page']:True);
$show_in_notification_page = ((x($params, 'show_in_notification_page')) ? $params['show_in_notification_page']:True);
$additional_mail_header = "";
$additional_mail_header .= "Precedence: list\n";
@ -55,14 +60,11 @@ function notification($params) {
$additional_mail_header .= "List-ID: <notification.".$hostname.">\n";
$additional_mail_header .= "List-Archive: <".$a->get_baseurl()."/notifications/system>\n";
if(array_key_exists('item',$params)) {
if (array_key_exists('item', $params)) {
$title = $params['item']['title'];
$body = $params['item']['body'];
}
else {
} else
$title = $body = '';
}
// e.g. "your post", "David's photo", etc.
$possess_desc = t('%s <!item_type!>');
@ -77,23 +79,19 @@ function notification($params) {
else
$parent_id = 0;
if($params['type'] == NOTIFY_MAIL) {
if ($params['type'] == NOTIFY_MAIL) {
$subject = sprintf(t('[Friendica:Notify] New mail received at %s'), $sitename);
$subject = sprintf( t('[Friendica:Notify] New mail received at %s'),$sitename);
$preamble = sprintf(t('%1$s sent you a new private message at %2$s.'), $params['source_name'], $sitename);
$epreamble = sprintf(t('%1$s sent you %2$s.'), '[url='.$params['source_link'].']'.$params['source_name'].'[/url]', '[url=$itemlink]'.t('a private message').'[/url]');
$preamble = sprintf( t('%1$s sent you a new private message at %2$s.'),$params['source_name'],$sitename);
$epreamble = sprintf( t('%1$s sent you %2$s.'),'[url=' . $params['source_link'] . ']' . $params['source_name'] . '[/url]', '[url=$itemlink]' . t('a private message') . '[/url]');
$sitelink = t('Please visit %s to view and/or reply to your private messages.');
$tsitelink = sprintf( $sitelink, $siteurl . '/message/' . $params['item']['id'] );
$hsitelink = sprintf( $sitelink, '<a href="' . $siteurl . '/message/' . $params['item']['id'] . '">' . $sitename . '</a>');
$itemlink = $siteurl . '/message/' . $params['item']['id'];
$tsitelink = sprintf($sitelink, $siteurl.'/message/'.$params['item']['id']);
$hsitelink = sprintf($sitelink, '<a href="'.$siteurl.'/message/'.$params['item']['id'].'">'.$sitename.'</a>');
$itemlink = $siteurl.'/message/'.$params['item']['id'];
}
if($params['type'] == NOTIFY_COMMENT) {
// logger("notification: params = " . print_r($params, true), LOGGER_DEBUG);
//$parent_id = $params['parent'];
if ($params['type'] == NOTIFY_COMMENT) {
$p = q("SELECT `ignored` FROM `thread` WHERE `iid` = %d AND `uid` = %d LIMIT 1",
intval($parent_id),
intval($params['uid'])
@ -107,51 +105,49 @@ function notification($params) {
// If so don't create a second notification
$p = null;
$p = q("select id from notify where (type = %d or type = %d or type = %d) and link = '%s' and uid = %d limit 1",
$p = q("SELECT `id` FROM `notify` WHERE (`type` = %d OR `type` = %d OR `type` = %d) AND `link` = '%s' AND `uid` = %d LIMIT 1",
intval(NOTIFY_TAGSELF),
intval(NOTIFY_COMMENT),
intval(NOTIFY_SHARE),
dbesc($params['link']),
intval($params['uid'])
);
if($p and count($p)) {
if ($p and count($p)) {
pop_lang();
return;
}
// if it's a post figure out who's post it is.
$p = null;
if($params['otype'] === 'item' && $parent_id) {
$p = q("select * from item where id = %d and uid = %d limit 1",
if ($params['otype'] === 'item' && $parent_id) {
$p = q("SELECT * FROM `item` WHERE `id` = %d AND `uid` = %d LIMIT 1",
intval($parent_id),
intval($params['uid'])
);
}
$item_post_type = item_post_type($p[0]);
//$possess_desc = str_replace('<!item_type!>',$possess_desc);
// "a post"
$dest_str = sprintf(t('%1$s commented on [url=%2$s]a %3$s[/url]'),
'[url=' . $params['source_link'] . ']' . $params['source_name'] . '[/url]',
'[url='.$params['source_link'].']'.$params['source_name'].'[/url]',
$itemlink,
$item_post_type);
// "George Bull's post"
if($p)
if ($p)
$dest_str = sprintf(t('%1$s commented on [url=%2$s]%3$s\'s %4$s[/url]'),
'[url=' . $params['source_link'] . ']' . $params['source_name'] . '[/url]',
'[url='.$params['source_link'].']'.$params['source_name'].'[/url]',
$itemlink,
$p[0]['author-name'],
$item_post_type);
// "your post"
if($p[0]['owner-name'] == $p[0]['author-name'] && $p[0]['wall'])
if ($p[0]['owner-name'] == $p[0]['author-name'] && $p[0]['wall'])
$dest_str = sprintf(t('%1$s commented on [url=%2$s]your %3$s[/url]'),
'[url=' . $params['source_link'] . ']' . $params['source_name'] . '[/url]',
'[url='.$params['source_link'].']'.$params['source_name'].'[/url]',
$itemlink,
$item_post_type);
@ -160,190 +156,200 @@ function notification($params) {
// Before this we have the name of the replier on the subject rendering
// differents subjects for messages on the same thread.
$subject = sprintf( t('[Friendica:Notify] Comment to conversation #%1$d by %2$s'), $parent_id, $params['source_name']);
$preamble = sprintf( t('%s commented on an item/conversation you have been following.'), $params['source_name']);
$subject = sprintf(t('[Friendica:Notify] Comment to conversation #%1$d by %2$s'), $parent_id, $params['source_name']);
$preamble = sprintf(t('%s commented on an item/conversation you have been following.'), $params['source_name']);
$epreamble = $dest_str;
$sitelink = t('Please visit %s to view and/or reply to the conversation.');
$tsitelink = sprintf( $sitelink, $siteurl );
$hsitelink = sprintf( $sitelink, '<a href="' . $siteurl . '">' . $sitename . '</a>');
$tsitelink = sprintf($sitelink, $siteurl);
$hsitelink = sprintf($sitelink, '<a href="'.$siteurl.'">'.$sitename.'</a>');
$itemlink = $params['link'];
}
if($params['type'] == NOTIFY_WALL) {
$subject = sprintf( t('[Friendica:Notify] %s posted to your profile wall') , $params['source_name']);
if ($params['type'] == NOTIFY_WALL) {
$subject = sprintf(t('[Friendica:Notify] %s posted to your profile wall'), $params['source_name']);
$preamble = sprintf( t('%1$s posted to your profile wall at %2$s') , $params['source_name'], $sitename);
$epreamble = sprintf( t('%1$s posted to [url=%2$s]your wall[/url]') ,
'[url=' . $params['source_link'] . ']' . $params['source_name'] . '[/url]',
$params['link']);
$preamble = sprintf(t('%1$s posted to your profile wall at %2$s'), $params['source_name'], $sitename);
$epreamble = sprintf(t('%1$s posted to [url=%2$s]your wall[/url]'),
'[url='.$params['source_link'].']'.$params['source_name'].'[/url]',
$params['link']);
$sitelink = t('Please visit %s to view and/or reply to the conversation.');
$tsitelink = sprintf( $sitelink, $siteurl );
$hsitelink = sprintf( $sitelink, '<a href="' . $siteurl . '">' . $sitename . '</a>');
$tsitelink = sprintf($sitelink, $siteurl);
$hsitelink = sprintf($sitelink, '<a href="'.$siteurl.'">'.$sitename.'</a>');
$itemlink = $params['link'];
}
if($params['type'] == NOTIFY_TAGSELF) {
$subject = sprintf( t('[Friendica:Notify] %s tagged you') , $params['source_name']);
$preamble = sprintf( t('%1$s tagged you at %2$s') , $params['source_name'], $sitename);
$epreamble = sprintf( t('%1$s [url=%2$s]tagged you[/url].') ,
'[url=' . $params['source_link'] . ']' . $params['source_name'] . '[/url]',
$params['link']);
if ($params['type'] == NOTIFY_TAGSELF) {
$subject = sprintf(t('[Friendica:Notify] %s tagged you'), $params['source_name']);
$preamble = sprintf(t('%1$s tagged you at %2$s'), $params['source_name'], $sitename);
$epreamble = sprintf(t('%1$s [url=%2$s]tagged you[/url].'),
'[url='.$params['source_link'].']'.$params['source_name'].'[/url]',
$params['link']);
$sitelink = t('Please visit %s to view and/or reply to the conversation.');
$tsitelink = sprintf( $sitelink, $siteurl );
$hsitelink = sprintf( $sitelink, '<a href="' . $siteurl . '">' . $sitename . '</a>');
$tsitelink = sprintf($sitelink, $siteurl);
$hsitelink = sprintf($sitelink, '<a href="'.$siteurl.'">'.$sitename.'</a>');
$itemlink = $params['link'];
}
if($params['type'] == NOTIFY_SHARE) {
$subject = sprintf( t('[Friendica:Notify] %s shared a new post') , $params['source_name']);
$preamble = sprintf( t('%1$s shared a new post at %2$s') , $params['source_name'], $sitename);
$epreamble = sprintf( t('%1$s [url=%2$s]shared a post[/url].') ,
'[url=' . $params['source_link'] . ']' . $params['source_name'] . '[/url]',
$params['link']);
if ($params['type'] == NOTIFY_SHARE) {
$subject = sprintf(t('[Friendica:Notify] %s shared a new post'), $params['source_name']);
$preamble = sprintf(t('%1$s shared a new post at %2$s'), $params['source_name'], $sitename);
$epreamble = sprintf(t('%1$s [url=%2$s]shared a post[/url].'),
'[url='.$params['source_link'].']'.$params['source_name'].'[/url]',
$params['link']);
$sitelink = t('Please visit %s to view and/or reply to the conversation.');
$tsitelink = sprintf( $sitelink, $siteurl );
$hsitelink = sprintf( $sitelink, '<a href="' . $siteurl . '">' . $sitename . '</a>');
$tsitelink = sprintf($sitelink, $siteurl);
$hsitelink = sprintf($sitelink, '<a href="'.$siteurl.'">'.$sitename.'</a>');
$itemlink = $params['link'];
}
if($params['type'] == NOTIFY_POKE) {
if ($params['type'] == NOTIFY_POKE) {
$subject = sprintf(t('[Friendica:Notify] %1$s poked you'), $params['source_name']);
$subject = sprintf( t('[Friendica:Notify] %1$s poked you') , $params['source_name']);
$preamble = sprintf( t('%1$s poked you at %2$s') , $params['source_name'], $sitename);
$epreamble = sprintf( t('%1$s [url=%2$s]poked you[/url].') ,
'[url=' . $params['source_link'] . ']' . $params['source_name'] . '[/url]',
$params['link']);
$preamble = sprintf(t('%1$s poked you at %2$s'), $params['source_name'], $sitename);
$epreamble = sprintf(t('%1$s [url=%2$s]poked you[/url].'),
'[url='.$params['source_link'].']'.$params['source_name'].'[/url]',
$params['link']);
$subject = str_replace('poked', t($params['activity']), $subject);
$preamble = str_replace('poked', t($params['activity']), $preamble);
$epreamble = str_replace('poked', t($params['activity']), $epreamble);
$sitelink = t('Please visit %s to view and/or reply to the conversation.');
$tsitelink = sprintf( $sitelink, $siteurl );
$hsitelink = sprintf( $sitelink, '<a href="' . $siteurl . '">' . $sitename . '</a>');
$tsitelink = sprintf($sitelink, $siteurl);
$hsitelink = sprintf($sitelink, '<a href="'.$siteurl.'">'.$sitename.'</a>');
$itemlink = $params['link'];
}
if($params['type'] == NOTIFY_TAGSHARE) {
$subject = sprintf( t('[Friendica:Notify] %s tagged your post') , $params['source_name']);
$preamble = sprintf( t('%1$s tagged your post at %2$s') , $params['source_name'], $sitename);
$epreamble = sprintf( t('%1$s tagged [url=%2$s]your post[/url]') ,
'[url=' . $params['source_link'] . ']' . $params['source_name'] . '[/url]',
$itemlink);
if ($params['type'] == NOTIFY_TAGSHARE) {
$subject = sprintf(t('[Friendica:Notify] %s tagged your post'), $params['source_name']);
$preamble = sprintf(t('%1$s tagged your post at %2$s'), $params['source_name'], $sitename);
$epreamble = sprintf(t('%1$s tagged [url=%2$s]your post[/url]'),
'[url='.$params['source_link'].']'.$params['source_name'].'[/url]',
$itemlink);
$sitelink = t('Please visit %s to view and/or reply to the conversation.');
$tsitelink = sprintf( $sitelink, $siteurl );
$hsitelink = sprintf( $sitelink, '<a href="' . $siteurl . '">' . $sitename . '</a>');
$tsitelink = sprintf($sitelink, $siteurl);
$hsitelink = sprintf($sitelink, '<a href="'.$siteurl.'">'.$sitename.'</a>');
$itemlink = $params['link'];
}
if($params['type'] == NOTIFY_INTRO) {
$subject = sprintf( t('[Friendica:Notify] Introduction received'));
$preamble = sprintf( t('You\'ve received an introduction from \'%1$s\' at %2$s'), $params['source_name'], $sitename);
$epreamble = sprintf( t('You\'ve received [url=%1$s]an introduction[/url] from %2$s.'),
$itemlink,
'[url=' . $params['source_link'] . ']' . $params['source_name'] . '[/url]');
$body = sprintf( t('You may visit their profile at %s'),$params['source_link']);
if ($params['type'] == NOTIFY_INTRO) {
$subject = sprintf(t('[Friendica:Notify] Introduction received'));
$preamble = sprintf(t('You\'ve received an introduction from \'%1$s\' at %2$s'), $params['source_name'], $sitename);
$epreamble = sprintf(t('You\'ve received [url=%1$s]an introduction[/url] from %2$s.'),
$itemlink,
'[url='.$params['source_link'].']'.$params['source_name'].'[/url]');
$body = sprintf(t('You may visit their profile at %s'), $params['source_link']);
$sitelink = t('Please visit %s to approve or reject the introduction.');
$tsitelink = sprintf( $sitelink, $siteurl );
$hsitelink = sprintf( $sitelink, '<a href="' . $siteurl . '">' . $sitename . '</a>');
$tsitelink = sprintf($sitelink, $siteurl);
$hsitelink = sprintf($sitelink, '<a href="'.$siteurl.'">'.$sitename.'</a>');
$itemlink = $params['link'];
switch ($params['verb']) {
case ACTIVITY_FRIEND:
// someone started to share with user (mostly OStatus)
$subject = sprintf( t('[Friendica:Notify] A new person is sharing with you'));
$preamble = sprintf( t('%1$s is sharing with you at %2$s'), $params['source_name'], $sitename);
$epreamble = sprintf( t('%1$s is sharing with you at %2$s'),
'[url=' . $params['source_link'] . ']' . $params['source_name'] . '[/url]',
$sitename);
$subject = sprintf(t('[Friendica:Notify] A new person is sharing with you'));
$preamble = sprintf(t('%1$s is sharing with you at %2$s'), $params['source_name'], $sitename);
$epreamble = sprintf(t('%1$s is sharing with you at %2$s'),
'[url='.$params['source_link'].']'.$params['source_name'].'[/url]',
$sitename);
break;
case ACTIVITY_FOLLOW:
// someone started to follow the user (mostly OStatus)
$subject = sprintf( t('[Friendica:Notify] You have a new follower'));
$preamble = sprintf( t('You have a new follower at %2$s : %1$s'), $params['source_name'], $sitename);
$epreamble = sprintf( t('You have a new follower at %2$s : %1$s'),
'[url=' . $params['source_link'] . ']' . $params['source_name'] . '[/url]',
$sitename);
$subject = sprintf(t('[Friendica:Notify] You have a new follower'));
$preamble = sprintf(t('You have a new follower at %2$s : %1$s'), $params['source_name'], $sitename);
$epreamble = sprintf(t('You have a new follower at %2$s : %1$s'),
'[url='.$params['source_link'].']'.$params['source_name'].'[/url]',
$sitename);
break;
default:
// ACTIVITY_REQ_FRIEND is default activity for notifications
break;
}
}
if($params['type'] == NOTIFY_SUGGEST) {
$subject = sprintf( t('[Friendica:Notify] Friend suggestion received'));
$preamble = sprintf( t('You\'ve received a friend suggestion from \'%1$s\' at %2$s'), $params['source_name'], $sitename);
$epreamble = sprintf( t('You\'ve received [url=%1$s]a friend suggestion[/url] for %2$s from %3$s.'),
$itemlink,
'[url=' . $params['item']['url'] . ']' . $params['item']['name'] . '[/url]',
'[url=' . $params['source_link'] . ']' . $params['source_name'] . '[/url]');
if ($params['type'] == NOTIFY_SUGGEST) {
$subject = sprintf(t('[Friendica:Notify] Friend suggestion received'));
$body = t('Name:') . ' ' . $params['item']['name'] . "\n";
$body .= t('Photo:') . ' ' . $params['item']['photo'] . "\n";
$body .= sprintf( t('You may visit their profile at %s'),$params['item']['url']);
$preamble = sprintf(t('You\'ve received a friend suggestion from \'%1$s\' at %2$s'), $params['source_name'], $sitename);
$epreamble = sprintf(t('You\'ve received [url=%1$s]a friend suggestion[/url] for %2$s from %3$s.'),
$itemlink,
'[url='.$params['item']['url'].']'.$params['item']['name'].'[/url]',
'[url='.$params['source_link'].']'.$params['source_name'].'[/url]');
$body = t('Name:').' '.$params['item']['name']."\n";
$body .= t('Photo:').' '.$params['item']['photo']."\n";
$body .= sprintf(t('You may visit their profile at %s'), $params['item']['url']);
$sitelink = t('Please visit %s to approve or reject the suggestion.');
$tsitelink = sprintf( $sitelink, $siteurl );
$hsitelink = sprintf( $sitelink, '<a href="' . $siteurl . '">' . $sitename . '</a>');
$tsitelink = sprintf($sitelink, $siteurl);
$hsitelink = sprintf($sitelink, '<a href="'.$siteurl.'">'.$sitename.'</a>');
$itemlink = $params['link'];
}
if($params['type'] == NOTIFY_CONFIRM) {
if ($params['verb'] == ACTIVITY_FRIEND ){ // mutual connection
$subject = sprintf( t('[Friendica:Notify] Connection accepted'));
$preamble = sprintf( t('\'%1$s\' has accepted your connection request at %2$s'), $params['source_name'], $sitename);
$epreamble = sprintf( t('%2$s has accepted your [url=%1$s]connection request[/url].'),
$itemlink,
'[url=' . $params['source_link'] . ']' . $params['source_name'] . '[/url]');
$body = t('You are now mutual friends and may exchange status updates, photos, and email
without restriction.');
if ($params['type'] == NOTIFY_CONFIRM) {
if ($params['verb'] == ACTIVITY_FRIEND) { // mutual connection
$subject = sprintf(t('[Friendica:Notify] Connection accepted'));
$sitelink = t('Please visit %s if you wish to make any changes to this relationship.');
$tsitelink = sprintf( $sitelink, $siteurl );
$hsitelink = sprintf( $sitelink, '<a href="' . $siteurl . '">' . $sitename . '</a>');
$preamble = sprintf(t('\'%1$s\' has accepted your connection request at %2$s'), $params['source_name'], $sitename);
$epreamble = sprintf(t('%2$s has accepted your [url=%1$s]connection request[/url].'),
$itemlink,
'[url='.$params['source_link'].']'.$params['source_name'].'[/url]');
$body = t('You are now mutual friends and may exchange status updates, photos, and email without restriction.');
$sitelink = t('Please visit %s if you wish to make any changes to this relationship.');
$tsitelink = sprintf($sitelink, $siteurl);
$hsitelink = sprintf($sitelink, '<a href="'.$siteurl.'">'.$sitename.'</a>');
$itemlink = $params['link'];
} else { // ACTIVITY_FOLLOW
$subject = sprintf( t('[Friendica:Notify] Connection accepted'));
$preamble = sprintf( t('\'%1$s\' has accepted your connection request at %2$s'), $params['source_name'], $sitename);
$epreamble = sprintf( t('%2$s has accepted your [url=%1$s]connection request[/url].'),
$itemlink,
'[url=' . $params['source_link'] . ']' . $params['source_name'] . '[/url]');
$subject = sprintf(t('[Friendica:Notify] Connection accepted'));
$preamble = sprintf(t('\'%1$s\' has accepted your connection request at %2$s'), $params['source_name'], $sitename);
$epreamble = sprintf(t('%2$s has accepted your [url=%1$s]connection request[/url].'),
$itemlink,
'[url='.$params['source_link'].']'.$params['source_name'].'[/url]');
$body = sprintf(t('\'%1$s\' has chosen to accept you a "fan", which restricts some forms of communication - such as private messaging and some profile interactions. If this is a celebrity or community page, these settings were applied automatically.'), $params['source_name']);
$body .= "\n\n";
$body .= sprintf(t('\'%1$s\' may choose to extend this into a two-way or more permissive relationship in the future. '), $params['source_name']);
$body .= sprintf(t('\'%1$s\' may choose to extend this into a two-way or more permissive relationship in the future.'), $params['source_name']);
$sitelink = t('Please visit %s if you wish to make any changes to this relationship.');
$tsitelink = sprintf( $sitelink, $siteurl );
$hsitelink = sprintf( $sitelink, '<a href="' . $siteurl . '">' . $sitename . '</a>');
$tsitelink = sprintf($sitelink, $siteurl);
$hsitelink = sprintf($sitelink, '<a href="'.$siteurl.'">'.$sitename.'</a>');
$itemlink = $params['link'];
}
}
if($params['type'] == NOTIFY_SYSTEM) {
if ($params['type'] == NOTIFY_SYSTEM) {
switch($params['event']) {
case "SYSTEM_REGISTER_REQUEST":
$subject = sprintf( t('[Friendica System:Notify] registration request'));
$preamble = sprintf( t('You\'ve received a registration request from \'%1$s\' at %2$s'), $params['source_name'], $sitename);
$epreamble = sprintf( t('You\'ve received a [url=%1$s]registration request[/url] from %2$s.'),
$itemlink,
'[url=' . $params['source_link'] . ']' . $params['source_name'] . '[/url]');
$body = sprintf( t('Full Name: %1$s\nSite Location: %2$s\nLogin Name: %3$s (%4$s)'),
$subject = sprintf(t('[Friendica System:Notify] registration request'));
$preamble = sprintf(t('You\'ve received a registration request from \'%1$s\' at %2$s'), $params['source_name'], $sitename);
$epreamble = sprintf(t('You\'ve received a [url=%1$s]registration request[/url] from %2$s.'),
$itemlink,
'[url='.$params['source_link'].']'.$params['source_name'].'[/url]');
$body = sprintf(t('Full Name: %1$s\nSite Location: %2$s\nLogin Name: %3$s (%4$s)'),
$params['source_name'], $siteurl, $params['source_mail'], $params['source_nick']);
$sitelink = t('Please visit %s to approve or reject the request.');
$tsitelink = sprintf( $sitelink, $params['link'] );
$hsitelink = sprintf( $sitelink, '<a href="' . $params['link'] . '">' . $sitename . '</a><br><br>');
$tsitelink = sprintf($sitelink, $params['link']);
$hsitelink = sprintf($sitelink, '<a href="'.$params['link'].'">'.$sitename.'</a><br><br>');
$itemlink = $params['link'];
break;
case "SYSTEM_DB_UPDATE_FAIL":
@ -351,20 +357,23 @@ function notification($params) {
}
}
if ($params['type'] == "SYSTEM_EMAIL"){
if ($params['type'] == "SYSTEM_EMAIL") {
// not part of the notifications.
// it just send a mail to the user.
// It will be used by the system to send emails to users (like
// password reset, invitations and so) using one look (but without
// add a notification to the user, with could be inexistent)
$subject = $params['subject'];
$preamble = $params['preamble'];
$body = $params['body'];
$sitelink = "";
$tsitelink = "";
$hsitelink = "";
$itemlink = "";
$show_in_notification_page = false;
$subject = $params['subject'];
$preamble = $params['preamble'];
$body = $params['body'];
$sitelink = "";
$tsitelink = "";
$hsitelink = "";
$itemlink = "";
$show_in_notification_page = false;
}
$subject .= " (".$nickname."@".$hostname.")";
@ -381,19 +390,20 @@ function notification($params) {
'itemlink' => $itemlink
);
call_hooks('enotify',$h);
call_hooks('enotify', $h);
$subject = $h['subject'];
$preamble = $h['preamble'];
$epreamble = $h['epreamble'];
$body = $h['body'];
$sitelink = $h['sitelink'];
$tsitelink = $h['tsitelink'];
$hsitelink = $h['hsitelink'];
$itemlink = $h['itemlink'];
if ($show_in_notification_page) {
logger("adding notification entry", LOGGER_DEBUG);
do {
@ -401,11 +411,10 @@ function notification($params) {
$hash = random_string();
$r = q("SELECT `id` FROM `notify` WHERE `hash` = '%s' LIMIT 1",
dbesc($hash));
if(dba::is_result($r))
if(dbm::is_result($r))
$dups = true;
} while($dups == true);
$datarray = array();
$datarray['hash'] = $hash;
$datarray['name'] = $params['source_name'];
@ -423,15 +432,15 @@ function notification($params) {
call_hooks('enotify_store', $datarray);
if($datarray['abort']) {
if ($datarray['abort']) {
pop_lang();
return False;
}
// create notification entry in DB
$r = q("insert into notify (hash,name,url,photo,date,uid,link,iid,parent,type,verb,otype)
values('%s','%s','%s','%s','%s',%d,'%s',%d,%d,%d,'%s','%s')",
$r = q("INSERT INTO `notify` (`hash`, `name`, `url`, `photo`, `date`, `uid`, `link`, `iid`, `parent`, `type`, `verb`, `otype`)
values('%s', '%s', '%s', '%s', '%s', %d, '%s', %d, %d, %d, '%s', '%s')",
dbesc($datarray['hash']),
dbesc($datarray['name']),
dbesc($datarray['url']),
@ -446,11 +455,11 @@ function notification($params) {
dbesc($datarray['otype'])
);
$r = q("select id from notify where hash = '%s' and uid = %d limit 1",
$r = q("SELECT `id` FROM `notify` WHERE `hash` = '%s' AND `uid` = %d LIMIT 1",
dbesc($hash),
intval($params['uid'])
);
if($r)
if ($r)
$notify_id = $r[0]['id'];
else {
pop_lang();
@ -461,40 +470,39 @@ function notification($params) {
// After we've stored everything, look again to see if there are any duplicates and if so remove them
$p = null;
$p = q("select id from notify where ( type = %d or type = %d ) and link = '%s' and uid = %d order by id",
$p = q("SELECT `id` FROM `notify` WHERE (`type` = %d OR `type` = %d) AND `link` = '%s' AND `uid` = %d ORDER BY `id`",
intval(NOTIFY_TAGSELF),
intval(NOTIFY_COMMENT),
dbesc($params['link']),
intval($params['uid'])
);
if($p && (count($p) > 1)) {
if ($p && (count($p) > 1)) {
for ($d = 1; $d < count($p); $d ++) {
q("delete from notify where id = %d",
q("DELETE FROM `notify` WHERE `id` = %d",
intval($p[$d]['id'])
);
}
// only continue on if we stored the first one
if($notify_id != $p[0]['id']) {
if ($notify_id != $p[0]['id']) {
pop_lang();
return False;
}
}
$itemlink = $a->get_baseurl() . '/notify/view/' . $notify_id;
$msg = replace_macros($epreamble,array('$itemlink' => $itemlink));
$r = q("update notify set msg = '%s' where id = %d and uid = %d",
$itemlink = $a->get_baseurl().'/notify/view/'.$notify_id;
$msg = replace_macros($epreamble, array('$itemlink' => $itemlink));
$r = q("UPDATE `notify` SET `msg` = '%s' WHERE `id` = %d AND `uid` = %d",
dbesc($msg),
intval($notify_id),
intval($params['uid'])
);
}
// send email notification if notification preferences permit
if((intval($params['notify_flags']) & intval($params['type']))
if ((intval($params['notify_flags']) & intval($params['type']))
|| $params['type'] == NOTIFY_SYSTEM
|| $params['type'] == "SYSTEM_EMAIL") {
@ -505,39 +513,37 @@ function notification($params) {
// Is this the first email notification for this parent item and user?
$r = q("select `id` from `notify-threads` where `master-parent-item` = %d and `receiver-uid` = %d limit 1",
$r = q("SELECT `id` FROM `notify-threads` WHERE `master-parent-item` = %d AND `receiver-uid` = %d LIMIT 1",
intval($params['parent']),
intval($params['uid']) );
intval($params['uid']));
// If so, create the record of it and use a message-id smtp header.
if(!$r) {
if (!$r) {
logger("notify_id:".intval($notify_id).", parent: ".intval($params['parent'])."uid: ".intval($params['uid']), LOGGER_DEBUG);
$r = q("insert into `notify-threads` (`notify-id`, `master-parent-item`, `receiver-uid`, `parent-item`)
values(%d,%d,%d,%d)",
$r = q("INSERT INTO `notify-threads` (`notify-id`, `master-parent-item`, `receiver-uid`, `parent-item`)
values(%d, %d, %d, %d)",
intval($notify_id),
intval($params['parent']),
intval($params['uid']),
0 );
0);
$additional_mail_header .= "Message-ID: <${id_for_parent}>\n";
$log_msg = "include/enotify: No previous notification found for this parent:\n" .
" parent: ${params['parent']}\n" . " uid : ${params['uid']}\n";
$log_msg = "include/enotify: No previous notification found for this parent:\n".
" parent: ${params['parent']}\n"." uid : ${params['uid']}\n";
logger($log_msg, LOGGER_DEBUG);
} else {
// If not, just "follow" the thread.
$additional_mail_header .= "References: <${id_for_parent}>\nIn-Reply-To: <${id_for_parent}>\n";
logger("There's already a notification for this parent:\n" . print_r($r, true), LOGGER_DEBUG);
logger("There's already a notification for this parent:\n".print_r($r, true), LOGGER_DEBUG);
}
}
// textversion keeps linebreaks
$textversion = strip_tags(str_replace("<br>","\n",html_entity_decode(bbcode(stripslashes(str_replace(array("\\r\\n", "\\r", "\\n"), "\n",
$body))),ENT_QUOTES,'UTF-8')));
$htmlversion = html_entity_decode(bbcode(stripslashes(str_replace(array("\\r\\n", "\\r","\\n\\n" ,"\\n"),
"<br />\n",$body))),ENT_QUOTES,'UTF-8');
$textversion = strip_tags(str_replace("<br>", "\n", html_entity_decode(bbcode(stripslashes(str_replace(array("\\r\\n", "\\r", "\\n"), "\n",
$body))),ENT_QUOTES, 'UTF-8')));
$htmlversion = html_entity_decode(bbcode(stripslashes(str_replace(array("\\r\\n", "\\r", "\\n\\n", "\\n"),
"<br />\n", $body))), ENT_QUOTES, 'UTF-8');
$datarray = array();
$datarray['banner'] = $banner;
@ -554,7 +560,7 @@ function notification($params) {
$datarray['username'] = $params['to_name'];
$datarray['hsitelink'] = $hsitelink;
$datarray['tsitelink'] = $tsitelink;
$datarray['hitemlink'] = '<a href="' . $itemlink . '">' . $itemlink . '</a>';
$datarray['hitemlink'] = '<a href="'.$itemlink.'">'.$itemlink.'</a>';
$datarray['titemlink'] = $itemlink;
$datarray['thanks'] = $thanks;
$datarray['site_admin'] = $site_admin;
@ -568,14 +574,14 @@ function notification($params) {
// check whether sending post content in email notifications is allowed
// always true for "SYSTEM_EMAIL"
$content_allowed = ((!get_config('system','enotify_no_content')) || ($params['type'] == "SYSTEM_EMAIL"));
$content_allowed = ((!get_config('system', 'enotify_no_content')) || ($params['type'] == "SYSTEM_EMAIL"));
// load the template for private message notifications
$tpl = get_markup_template('email_notify_html.tpl');
$email_html_body = replace_macros($tpl,array(
$email_html_body = replace_macros($tpl, array(
'$banner' => $datarray['banner'],
'$product' => $datarray['product'],
'$preamble' => str_replace("\n","<br>\n",$datarray['preamble']),
'$preamble' => str_replace("\n", "<br>\n", $datarray['preamble']),
'$sitename' => $datarray['sitename'],
'$siteurl' => $datarray['siteurl'],
'$source_name' => $datarray['source_name'],
@ -586,14 +592,14 @@ function notification($params) {
'$hitemlink' => $datarray['hitemlink'],
'$thanks' => $datarray['thanks'],
'$site_admin' => $datarray['site_admin'],
'$title' => $datarray['title'],
'$title' => $datarray['title'],
'$htmlversion' => $datarray['htmlversion'],
'$content_allowed' => $content_allowed,
));
// load the template for private message notifications
$tpl = get_markup_template('email_notify_text.tpl');
$email_text_body = replace_macros($tpl,array(
$email_text_body = replace_macros($tpl, array(
'$banner' => $datarray['banner'],
'$product' => $datarray['product'],
'$preamble' => $datarray['preamble'],
@ -607,13 +613,11 @@ function notification($params) {
'$titemlink' => $datarray['titemlink'],
'$thanks' => $datarray['thanks'],
'$site_admin' => $datarray['site_admin'],
'$title' => $datarray['title'],
'$title' => $datarray['title'],
'$textversion' => $datarray['textversion'],
'$content_allowed' => $content_allowed,
));
// logger('text: ' . $email_text_body);
// use the Emailer class to send the message
return Emailer::send(array(
@ -630,7 +634,6 @@ function notification($params) {
}
return False;
}
/**
@ -647,7 +650,7 @@ function check_item_notification($itemid, $uid, $defaulttype = "") {
$profiles = $notification_data["profiles"];
$user = q("SELECT `notify-flags`, `language`, `username`, `email` FROM `user` WHERE `uid` = %d", intval($uid));
$user = q("SELECT `notify-flags`, `language`, `username`, `email`, `nickname` FROM `user` WHERE `uid` = %d", intval($uid));
if (!$user)
return false;
@ -655,13 +658,30 @@ function check_item_notification($itemid, $uid, $defaulttype = "") {
if (!$owner)
return false;
// This is our regular URL format
$profiles[] = $owner[0]["url"];
// Notifications from Diaspora are often with an URL in the Diaspora format
$profiles[] = App::get_baseurl()."/u/".$user[0]["nickname"];
$profiles2 = array();
foreach ($profiles AS $profile) {
$profiles2[] = normalise_link($profile);
$profiles2[] = str_replace("http://", "https://", normalise_link($profile));
// Check for invalid profile urls. 13 should be the shortest possible profile length:
// http://a.bc/d
// Additionally check for invalid urls that would return the normalised value "http:"
if ((strlen($profile) >= 13) AND (normalise_link($profile) != "http:")) {
if (!in_array($profile, $profiles2))
$profiles2[] = $profile;
$profile = normalise_link($profile);
if (!in_array($profile, $profiles2))
$profiles2[] = $profile;
$profile = str_replace("http://", "https://", $profile);
if (!in_array($profile, $profiles2))
$profiles2[] = $profile;
}
}
$profiles = $profiles2;
@ -703,26 +723,26 @@ function check_item_notification($itemid, $uid, $defaulttype = "") {
$params["source_photo"] = $item[0]["author-avatar"];
if ($item[0]["parent-uri"] === $item[0]["uri"]) {
// Send a notification for every new post?
$r = q("SELECT `notify_new_posts` FROM `contact` WHERE `id` = %d AND `uid` = %d AND `notify_new_posts` LIMIT 1",
intval($item[0]['contact-id']),
intval($uid)
);
$send_notification = count($r);
// Send a notification for every new post?
$r = q("SELECT `notify_new_posts` FROM `contact` WHERE `id` = %d AND `uid` = %d AND `notify_new_posts` LIMIT 1",
intval($item[0]['contact-id']),
intval($uid)
);
$send_notification = dbm::is_result($r);
if (!$send_notification) {
$tags = q("SELECT `url` FROM `term` WHERE `otype` = %d AND `oid` = %d AND `type` = %d AND `uid` = %d",
intval(TERM_OBJ_POST), intval($itemid), intval(TERM_MENTION), intval($uid));
if (!$send_notification) {
$tags = q("SELECT `url` FROM `term` WHERE `otype` = %d AND `oid` = %d AND `type` = %d AND `uid` = %d",
intval(TERM_OBJ_POST), intval($itemid), intval(TERM_MENTION), intval($uid));
if (count($tags)) {
foreach ($tags AS $tag) {
$r = q("SELECT `id` FROM `contact` WHERE `nurl` = '%s' AND `uid` = %d AND `notify_new_posts`",
normalise_link($tag["url"]), intval($uid));
if (dba::is_result($r))
$send_notification = true;
}
}
}
if (dbm::is_result($tags)) {
foreach ($tags AS $tag) {
$r = q("SELECT `id` FROM `contact` WHERE `nurl` = '%s' AND `uid` = %d AND `notify_new_posts`",
normalise_link($tag["url"]), intval($uid));
if (dbm::is_result($r))
$send_notification = true;
}
}
}
if ($send_notification) {
$params["type"] = NOTIFY_SHARE;

View file

@ -1,12 +1,15 @@
<?php
/**
* @file include/event.php
* @brief functions specific to event handling
*/
require_once('include/bbcode.php');
require_once('include/map.php');
require_once('include/datetime.php');
function format_event_html($ev, $simple = false) {
if(! ((is_array($ev)) && count($ev)))
return '';
@ -276,7 +279,7 @@ function event_store($arr) {
intval($arr['id']),
intval($arr['uid'])
);
return((dba::is_result($r)) ? $r[0]['id'] : 0);
return((dbm::is_result($r)) ? $r[0]['id'] : 0);
}
// The event changed. Update it.
@ -290,11 +293,7 @@ function event_store($arr) {
`location` = '%s',
`type` = '%s',
`adjust` = %d,
`nofinish` = %d,
`allow_cid` = '%s',
`allow_gid` = '%s',
`deny_cid` = '%s',
`deny_gid` = '%s'
`nofinish` = %d
WHERE `id` = %d AND `uid` = %d",
dbesc($arr['edited']),
@ -306,10 +305,6 @@ function event_store($arr) {
dbesc($arr['type']),
intval($arr['adjust']),
intval($arr['nofinish']),
dbesc($arr['allow_cid']),
dbesc($arr['allow_gid']),
dbesc($arr['deny_cid']),
dbesc($arr['deny_gid']),
intval($arr['id']),
intval($arr['uid'])
);
@ -317,28 +312,22 @@ function event_store($arr) {
intval($arr['id']),
intval($arr['uid'])
);
if(dba::is_result($r)) {
if(dbm::is_result($r)) {
$object = '<object><type>' . xmlify(ACTIVITY_OBJ_EVENT) . '</type><title></title><id>' . xmlify($arr['uri']) . '</id>';
$object .= '<content>' . xmlify(format_event_bbcode($arr)) . '</content>';
$object .= '</object>' . "\n";
q("UPDATE `item` SET `body` = '%s', `object` = '%s', `allow_cid` = '%s', `allow_gid` = '%s', `deny_cid` = '%s', `deny_gid` = '%s', `edited` = '%s', `private` = %d WHERE `id` = %d AND `uid` = %d",
q("UPDATE `item` SET `body` = '%s', `object` = '%s', `edited` = '%s' WHERE `id` = %d AND `uid` = %d",
dbesc(format_event_bbcode($arr)),
dbesc($object),
dbesc($arr['allow_cid']),
dbesc($arr['allow_gid']),
dbesc($arr['deny_cid']),
dbesc($arr['deny_gid']),
dbesc($arr['edited']),
intval($arr['private']),
intval($r[0]['id']),
intval($arr['uid'])
);
$item_id = $r[0]['id'];
}
else
} else
$item_id = 0;
call_hooks("event_updated", $arr['id']);
@ -376,7 +365,7 @@ function event_store($arr) {
dbesc($arr['uri']),
intval($arr['uid'])
);
if(dba::is_result($r))
if(dbm::is_result($r))
$event = $r[0];
$item_arr = array();
@ -418,7 +407,7 @@ function event_store($arr) {
$r = q("SELECT * FROM `user` WHERE `uid` = %d LIMIT 1",
intval($arr['uid'])
);
//if(dba::is_result($r))
//if(dbm::is_result($r))
// $plink = $a->get_baseurl() . '/display/' . $r[0]['nickname'] . '/' . $item_id;
@ -441,3 +430,420 @@ function event_store($arr) {
return $item_id;
}
}
function get_event_strings() {
// First day of the week (0 = Sunday)
$firstDay = get_pconfig(local_user(),'system','first_day_of_week');
if ($firstDay === false) $firstDay=0;
$i18n = array(
"firstDay" => $firstDay,
"Sun" => t("Sun"),
"Mon" => t("Mon"),
"Tue" => t("Tue"),
"Wed" => t("Wed"),
"Thu" => t("Thu"),
"Fri" => t("Fri"),
"Sat" => t("Sat"),
"Sunday" => t("Sunday"),
"Monday" => t("Monday"),
"Tuesday" => t("Tuesday"),
"Wednesday" => t("Wednesday"),
"Thursday" => t("Thursday"),
"Friday" => t("Friday"),
"Saturday" => t("Saturday"),
"Jan" => t("Jan"),
"Feb" => t("Feb"),
"Mar" => t("Mar"),
"Apr" => t("Apr"),
"May" => t("May"),
"Jun" => t("Jun"),
"Jul" => t("Jul"),
"Aug" => t("Aug"),
"Sep" => t("Sept"),
"Oct" => t("Oct"),
"Nov" => t("Nov"),
"Dec" => t("Dec"),
"January" => t("January"),
"February" => t("February"),
"March" => t("March"),
"April" => t("April"),
"May" => t("May"),
"June" => t("June"),
"July" => t("July"),
"August" => t("August"),
"September" => t("September"),
"October" => t("October"),
"November" => t("November"),
"December" => t("December"),
"today" => t("today"),
"month" => t("month"),
"week" => t("week"),
"day" => t("day"),
);
return $i18n;
}
/**
* @brief Get an event by its event ID
*
* @param type $owner_uid The User ID of the owner of the event
* @param type $event_params An assoziative array with
* int 'event_id' => The ID of the event in the event table
* @param type $sql_extra
* @return array Query result
*/
function event_by_id($owner_uid = 0, $event_params, $sql_extra = '') {
// ownly allow events if there is a valid owner_id
if($owner_uid == 0)
return;
// query for the event by event id
$r = q("SELECT `event`.*, `item`.`id` AS `itemid`,`item`.`plink`,
`item`.`author-name`, `item`.`author-avatar`, `item`.`author-link` FROM `event`
LEFT JOIN `item` ON `item`.`event-id` = `event`.`id` AND `item`.`uid` = `event`.`uid`
WHERE `event`.`uid` = %d AND `event`.`id` = %d $sql_extra",
intval($owner_uid),
intval($event_params["event_id"])
);
if(count($r))
return $r;
}
/**
* @brief Get all events in a specific timeframe
*
* @param int $owner_uid The User ID of the owner of the events
* @param array $event_params An assoziative array with
* int 'ignored' =>
* string 'start' => Start time of the timeframe
* string 'finish' => Finish time of the timeframe
* string 'adjust_start' =>
* string 'adjust_start' =>
*
* @param string $sql_extra Additional sql conditions (e.g. permission request)
* @return array Query results
*/
function events_by_date($owner_uid = 0, $event_params, $sql_extra = '') {
// ownly allow events if there is a valid owner_id
if($owner_uid == 0)
return;
// query for the event by date
$r = q("SELECT `event`.*, `item`.`id` AS `itemid`,`item`.`plink`,
`item`.`author-name`, `item`.`author-avatar`, `item`.`author-link` FROM `event`
LEFT JOIN `item` ON `item`.`event-id` = `event`.`id` AND `item`.`uid` = `event`.`uid`
WHERE `event`.`uid` = %d AND event.ignore = %d
AND ((`adjust` = 0 AND (`finish` >= '%s' OR (nofinish AND start >= '%s')) AND `start` <= '%s')
OR (`adjust` = 1 AND (`finish` >= '%s' OR (nofinish AND start >= '%s')) AND `start` <= '%s'))
$sql_extra ",
intval($owner_uid),
intval($event_params["ignored"]),
dbesc($event_params["start"]),
dbesc($event_params["start"]),
dbesc($event_params["finish"]),
dbesc($event_params["adjust_start"]),
dbesc($event_params["adjust_start"]),
dbesc($event_params["adjust_finish"])
);
if(count($r))
return $r;
}
/**
* @brief Convert an array query results in an arry which could be used by the events template
*
* @param array $arr Event query array
* @return array Event array for the template
*/
function process_events ($arr) {
$events=array();
$last_date = '';
$fmt = t('l, F j');
if (count($arr)) {
foreach($arr as $rr) {
$j = (($rr['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$rr['start'], 'j') : datetime_convert('UTC','UTC',$rr['start'],'j'));
$d = (($rr['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$rr['start'], $fmt) : datetime_convert('UTC','UTC',$rr['start'],$fmt));
$d = day_translate($d);
$start = (($rr['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$rr['start'], 'c') : datetime_convert('UTC','UTC',$rr['start'],'c'));
if ($rr['nofinish']){
$end = null;
} else {
$end = (($rr['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$rr['finish'], 'c') : datetime_convert('UTC','UTC',$rr['finish'],'c'));
}
$is_first = ($d !== $last_date);
$last_date = $d;
$edit = ((! $rr['cid']) ? array(App::get_baseurl().'/events/event/'.$rr['id'],t('Edit event'),'','') : null);
$title = strip_tags(html_entity_decode(bbcode($rr['summary']),ENT_QUOTES,'UTF-8'));
if(! $title) {
list($title, $_trash) = explode("<br",bbcode($rr['desc']),2);
$title = strip_tags(html_entity_decode($title,ENT_QUOTES,'UTF-8'));
}
$html = format_event_html($rr);
$rr['desc'] = bbcode($rr['desc']);
$rr['location'] = bbcode($rr['location']);
$events[] = array(
'id'=>$rr['id'],
'start'=> $start,
'end' => $end,
'allDay' => false,
'title' => $title,
'j' => $j,
'd' => $d,
'is_first'=>$is_first,
'item'=>$rr,
'html'=>$html,
'plink' => array($rr['plink'],t('link to source'),'',''),
);
}
}
return $events;
}
/**
* @brief Format event to export format (ical/csv)
*
* @param array $events Query result for events
* @param string $format The output format (ical/csv)
* @param string $timezone The timezone of the user (not implemented yet)
*
* @return string Content according to selected export format
*/
function event_format_export ($events, $format = 'ical', $timezone) {
if(! ((is_array($events)) && count($events)))
return;
switch ($format) {
// format the exported data as a CSV file
case "csv":
header("Content-type: text/csv");
$o = '"Subject", "Start Date", "Start Time", "Description", "End Date", "End Time", "Location"' . PHP_EOL;
foreach ($events as $event) {
/// @todo the time / date entries don't include any information about the
// timezone the event is scheduled in :-/
$tmp1 = strtotime($event['start']);
$tmp2 = strtotime($event['finish']);
$time_format = "%H:%M:%S";
$date_format = "%Y-%m-%d";
$o .= '"'.$event['summary'].'", "'.strftime($date_format, $tmp1) .
'", "'.strftime($time_format, $tmp1).'", "'.$event['desc'] .
'", "'.strftime($date_format, $tmp2) .
'", "'.strftime($time_format, $tmp2) .
'", "'.$event['location'].'"' . PHP_EOL;
}
break;
// format the exported data as a ics file
case "ical":
header("Content-type: text/ics");
$o = 'BEGIN:VCALENDAR'. PHP_EOL
. 'VERSION:2.0' . PHP_EOL
. 'PRODID:-//friendica calendar export//0.1//EN' . PHP_EOL;
/// @todo include timezone informations in cases were the time is not in UTC
// see http://tools.ietf.org/html/rfc2445#section-4.8.3
// . 'BEGIN:VTIMEZONE' . PHP_EOL
// . 'TZID:' . $timezone . PHP_EOL
// . 'END:VTIMEZONE' . PHP_EOL;
// TODO instead of PHP_EOL CRLF should be used for long entries
// but test your solution against http://icalvalid.cloudapp.net/
// also long lines SHOULD be split at 75 characters length
foreach ($events as $event) {
if ($event['adjust'] == 1) {
$UTC = 'Z';
} else {
$UTC = '';
}
$o .= 'BEGIN:VEVENT' . PHP_EOL;
if ($event[start]) {
$tmp = strtotime($event['start']);
$dtformat = "%Y%m%dT%H%M%S".$UTC;
$o .= 'DTSTART:'.strftime($dtformat, $tmp).PHP_EOL;
}
if (!$event['nofinish']) {
$tmp = strtotime($event['finish']);
$dtformat = "%Y%m%dT%H%M%S".$UTC;
$o .= 'DTEND:'.strftime($dtformat, $tmp).PHP_EOL;
}
if ($event['summary'])
$tmp = $event['summary'];
$tmp = str_replace(PHP_EOL, PHP_EOL.' ',$tmp);
$tmp = addcslashes($tmp, ',;');
$o .= 'SUMMARY:' . $tmp . PHP_EOL;
if ($event['desc'])
$tmp = $event['desc'];
$tmp = str_replace(PHP_EOL, PHP_EOL.' ',$tmp);
$tmp = addcslashes($tmp, ',;');
$o .= 'DESCRIPTION:' . $tmp . PHP_EOL;
if ($event['location']) {
$tmp = $event['location'];
$tmp = str_replace(PHP_EOL, PHP_EOL.' ',$tmp);
$tmp = addcslashes($tmp, ',;');
$o .= 'LOCATION:' . $tmp . PHP_EOL;
}
$o .= 'END:VEVENT' . PHP_EOL;
$o .= PHP_EOL;
}
$o .= 'END:VCALENDAR' . PHP_EOL;
break;
}
return $o;
}
/**
* @brief Get all events for a user ID
*
* The query for events is done permission sensitive
* If the user is the owner of the calendar he/she
* will get all of his/her available events.
* If the user is only a visitor only the public events will
* be available
*
* @param int $uid The user ID
* @param int $sql_extra Additional sql conditions for permission
*
* @return array Query results
*/
function events_by_uid($uid = 0, $sql_extra = '') {
if($uid == 0)
return;
// The permission condition if no condition was transmitted
if($sql_extra == '')
$sql_extra = " AND `allow_cid` = '' AND `allow_gid` = '' ";
// does the user who requests happen to be the owner of the events
// requested? then show all of your events, otherwise only those that
// don't have limitations set in allow_cid and allow_gid
if (local_user() == $uid) {
$r = q("SELECT `start`, `finish`, `adjust`, `summary`, `desc`, `location`, `nofinish`
FROM `event` WHERE `uid`= %d AND `cid` = 0 ",
intval($uid)
);
} else {
$r = q("SELECT `start`, `finish`, `adjust`, `summary`, `desc`, `location`, `nofinish`
FROM `event` WHERE `uid`= %d AND `cid` = 0 $sql_extra ",
intval($uid)
);
}
if(count($r))
return $r;
}
/**
*
* @param int $uid The user ID
* @param string $format Output format (ical/csv)
* @return array With the results
* bool 'success' => True if the processing was successful
* string 'format' => The output format
* string 'extension' => The file extension of the output format
* string 'content' => The formatted output content
*
* @todo Respect authenticated users with events_by_uid()
*/
function event_export($uid, $format = 'ical') {
$process = false;
// we are allowed to show events
// get the timezone the user is in
$r = q("SELECT `timezone` FROM `user` WHERE `uid` = %d LIMIT 1", intval($uid));
if (count($r))
$timezone = $r[0]['timezone'];
// get all events which are owned by a uid (respects permissions);
$events = events_by_uid($uid);
// we have the events that are available for the requestor
// now format the output according to the requested format
if(count($events))
$res = event_format_export($events, $format, $timezone);
// If there are results the precess was successfull
if(x($res))
$process = true;
// get the file extension for the format
switch ($format) {
case "ical":
$file_ext = "ics";
break;
case "csv":
$file_ext = "csv";
break;
default:
$file_ext = "";
}
$arr = array(
'success' => $process,
'format' => $format,
'extension' => $file_ext,
'content' => $res,
);
return $arr;
}
/**
* @brief Get the events widget
*
* @return string Formated html of the evens widget
*/
function widget_events() {
$a = get_app();
$owner_uid = $a->data['user']['uid'];
// $a->data is only available if the profile page is visited. If the visited page is not part
// of the profile page it should be the personal /events page. So we can use $a->user
$user = ($a->data['user']['nickname'] ? $a->data['user']['nickname'] : $a->user['nickname']);
// The permission testing is a little bit tricky because we have to respect many cases
// It's not the private events page (we don't get the $owner_uid for /events)
if(! local_user() && ! $owner_uid)
return;
// Cal logged in user (test permission at foreign profile page)
// If the $owner uid is available we know it is part of one of the profile pages (like /cal)
// So we have to test if if it's the own profile page of the logged in user
// or a foreign one. For foreign profile pages we need to check if the feature
// for exporting the cal is enabled (otherwise the widget would appear for logged in users
// on foreigen profile pages even if the widget is disabled)
if(intval($owner_uid) && local_user() !== $owner_uid && ! feature_enabled($owner_uid, "export_calendar"))
return;
// If it's a kind of profile page (intval($owner_uid)) return if the user not logged in and
// export feature isn't enabled
if(intval($owner_uid) && ! local_user() && ! feature_enabled($owner_uid, "export_calendar"))
return;
return replace_macros(get_markup_template("events_aside.tpl"), array(
'$etitle' => t("Export"),
'$export_ical' => t("Export calendar as ical"),
'$export_csv' => t("Export calendar as csv"),
'$user' => $user
));
}

View file

@ -39,7 +39,7 @@ function expire_run(&$argv, &$argc){
logger('expire: start');
$r = q("SELECT `uid`,`username`,`expire` FROM `user` WHERE `expire` != 0");
if(dba::is_result($r)) {
if(dbm::is_result($r)) {
foreach($r as $rr) {
logger('Expire: ' . $rr['username'] . ' interval: ' . $rr['expire'], LOGGER_DEBUG);
item_expire($rr['uid'],$rr['expire']);

View file

@ -10,7 +10,7 @@ function fcontact_store($url,$name,$photo) {
dbesc($nurl)
);
if(dba::is_result($r))
if(dbm::is_result($r))
return $r[0]['id'];
$r = q("INSERT INTO `fcontact` ( `url`, `name`, `photo` ) VALUES ( '%s', '%s', '%s' ) ",
@ -23,7 +23,7 @@ function fcontact_store($url,$name,$photo) {
$r = q("SELECT `id` FROM `fcontact` WHERE `url` = '%s' LIMIT 1",
dbesc($nurl)
);
if(dba::is_result($r))
if(dbm::is_result($r))
return $r[0]['id'];
}

View file

@ -64,6 +64,7 @@ function get_features($filtered = true) {
//array('expire', t('Content Expiration'), t('Remove old posts/comments after a period of time')),
array('multi_profiles', t('Multiple Profiles'), t('Ability to create multiple profiles'), false, get_config('feature_lock','multi_profiles')),
array('photo_location', t('Photo Location'), t('Photo metadata is normally stripped. This extracts the location (if present) prior to stripping metadata and links it to a map.'), false, get_config('feature_lock','photo_location')),
array('export_calendar', t('Export Public Calendar'), t('Ability for visitors to download the public calendar'), false, get_config('feature_lock','export_calendar')),
),
// Post composition

View file

@ -17,10 +17,15 @@ function feed_import($xml,$importer,&$contact, &$hub, $simulate = false) {
$a = get_app();
logger("Import Atom/RSS feed", LOGGER_DEBUG);
if (!$simulate)
logger("Import Atom/RSS feed '".$contact["name"]."' (Contact ".$contact["id"].") for user ".$importer["uid"], LOGGER_DEBUG);
else
logger("Test Atom/RSS feed", LOGGER_DEBUG);
if ($xml == "")
if ($xml == "") {
logger('XML is empty.', LOGGER_DEBUG);
return;
}
$doc = new DOMDocument();
@$doc->loadXML($xml);
@ -84,9 +89,22 @@ function feed_import($xml,$importer,&$contact, &$hub, $simulate = false) {
if ($value != "")
$author["author-name"] = $value;
$value = $xpath->evaluate('atom:author/poco:preferredUsername/text()')->item(0)->nodeValue;
if ($value != "")
$author["author-nick"] = $value;
if ($simulate) {
$author["author-id"] = $xpath->evaluate('/atom:feed/atom:author/atom:uri/text()')->item(0)->nodeValue;
$value = $xpath->evaluate('atom:author/poco:preferredUsername/text()')->item(0)->nodeValue;
if ($value != "")
$author["author-nick"] = $value;
$value = $xpath->evaluate('atom:author/poco:address/poco:formatted/text()', $context)->item(0)->nodeValue;
if ($value != "")
$author["author-location"] = $value;
$value = $xpath->evaluate('atom:author/poco:note/text()')->item(0)->nodeValue;
if ($value != "")
$author["author-about"] = $value;
}
$author["edited"] = $author["created"] = $xpath->query('/atom:feed/atom:updated/text()')->item(0)->nodeValue;
@ -150,8 +168,10 @@ function feed_import($xml,$importer,&$contact, &$hub, $simulate = false) {
$header["last-child"] = 0;
}
if (!is_object($entries))
if (!is_object($entries)) {
logger("There are no entries in this feed.", LOGGER_DEBUG);
return;
}
$items = array();

View file

@ -178,7 +178,7 @@ function new_contact($uid,$url,$interactive = false) {
intval($uid), dbesc(normalise_link($url)), dbesc($ret['network'])
);
if(dba::is_result($r)) {
if(dbm::is_result($r)) {
// update contact
if($r[0]['rel'] == CONTACT_IS_FOLLOWER || ($network === NETWORK_DIASPORA && $r[0]['rel'] == CONTACT_IS_SHARING)) {
q("UPDATE `contact` SET `rel` = %d , `subhub` = %d, `readonly` = 0 WHERE `id` = %d AND `uid` = %d",
@ -196,7 +196,7 @@ function new_contact($uid,$url,$interactive = false) {
$r = q("select count(*) as total from contact where uid = %d and pending = 0 and self = 0",
intval($uid)
);
if(dba::is_result($r))
if(dbm::is_result($r))
$total_contacts = $r[0]['total'];
if(! service_class_allows($uid,'total_contacts',$total_contacts)) {
@ -208,7 +208,7 @@ function new_contact($uid,$url,$interactive = false) {
intval($uid),
dbesc($network)
);
if(dba::is_result($r))
if(dbm::is_result($r))
$total_network = $r[0]['total'];
if(! service_class_allows($uid,'total_contacts_' . $network,$total_network)) {
@ -270,7 +270,7 @@ function new_contact($uid,$url,$interactive = false) {
// pull feed and consume it, which should subscribe to the hub.
proc_run('php',"include/onepoll.php","$contact_id", "force");
proc_run(PRIORITY_MEDIUM, "include/onepoll.php", $contact_id, "force");
// create a follow slap
@ -295,7 +295,7 @@ function new_contact($uid,$url,$interactive = false) {
intval($uid)
);
if(dba::is_result($r)) {
if(dbm::is_result($r)) {
if(($contact['network'] == NETWORK_OSTATUS) && (strlen($contact['notify']))) {
require_once('include/salmon.php');
slapper($r[0],$contact['notify'],$slap);

View file

@ -65,7 +65,7 @@ function gprobe_run(&$argv, &$argc){
dbesc(normalise_link($url))
);
}
if(dba::is_result($r)) {
if(dbm::is_result($r)) {
// Check for accessibility and do a poco discovery
if (poco_last_updated($r[0]['url'], true) AND ($r[0]["network"] == NETWORK_DFRN))
poco_load(0,0,$r[0]['id'], str_replace('/profile/','/poco/',$r[0]['url']));

View file

@ -44,7 +44,7 @@ function group_rmv($uid,$name) {
intval($uid),
dbesc($name)
);
if(dba::is_result($r))
if(dbm::is_result($r))
$group_id = $r[0]['id'];
if(! $group_id)
return false;
@ -106,7 +106,7 @@ function group_byname($uid,$name) {
intval($uid),
dbesc($name)
);
if(dba::is_result($r))
if(dbm::is_result($r))
return $r[0]['id'];
return false;
}
@ -139,7 +139,7 @@ function group_add_member($uid,$name,$member,$gid = 0) {
intval($gid),
intval($member)
);
if(dba::is_result($r))
if(dbm::is_result($r))
return true; // You might question this, but
// we indicate success because the group member was in fact created
// -- It was just created at another time
@ -164,7 +164,7 @@ function group_get_members($gid) {
intval($gid),
intval(local_user())
);
if(dba::is_result($r))
if(dbm::is_result($r))
$ret = $r;
}
return $ret;
@ -181,7 +181,7 @@ function group_public_members($gid) {
intval(local_user()),
dbesc(NETWORK_OSTATUS)
);
if(dba::is_result($r))
if(dbm::is_result($r))
$ret = count($r);
}
return $ret;
@ -197,7 +197,7 @@ function mini_group_select($uid,$gid = 0, $label = "") {
intval($uid)
);
$grps[] = array('name' => '', 'id' => '0', 'selected' => '');
if(dba::is_result($r)) {
if(dbm::is_result($r)) {
foreach($r as $rr) {
$grps[] = array('name' => $rr['name'], 'id' => $rr['id'], 'selected' => (($gid == $rr['id']) ? 'true' : ''));
}
@ -255,7 +255,7 @@ function group_side($every="contacts",$each="group",$editmode = "standard", $gro
$member_of = groups_containing(local_user(),$cid);
}
if(dba::is_result($r)) {
if(dbm::is_result($r)) {
foreach($r as $rr) {
$selected = (($group_id == $rr['id']) ? ' group-selected' : '');
@ -316,7 +316,7 @@ function expand_groups($a,$check_dead = false, $use_gcontact = false) {
$ret = array();
if(dba::is_result($r))
if(dbm::is_result($r))
foreach($r as $rr)
$ret[] = $rr['contact-id'];
if($check_dead AND !$use_gcontact) {
@ -345,7 +345,7 @@ function groups_containing($uid,$c) {
);
$ret = array();
if(dba::is_result($r)) {
if(dbm::is_result($r)) {
foreach($r as $rr)
$ret[] = $rr['gid'];
}
@ -366,7 +366,7 @@ function groups_containing($uid,$c) {
function groups_count_unseen() {
$r = q("SELECT `group`.`id`, `group`.`name`,
(SELECT COUNT(*) FROM `item`
(SELECT COUNT(*) FROM `item` FORCE INDEX (`uid_unseen_contactid`)
WHERE `uid` = %d AND `unseen` AND
`contact-id` IN (SELECT `contact-id` FROM `group_member`
WHERE `group_member`.`gid` = `group`.`id` AND `group_member`.`uid` = %d)) AS `count`

View file

@ -71,8 +71,8 @@ function profile_load(&$a, $nickname, $profile = 0, $profiledata = array()) {
$a->page['title'] = $a->profile['name'] . " @ " . $a->config['sitename'];
// if (!$profiledata)
// $_SESSION['theme'] = $a->profile['theme'];
if (!$profiledata && !get_pconfig(local_user(),'system','always_my_theme'))
$_SESSION['theme'] = $a->profile['theme'];
$_SESSION['mobile-theme'] = $a->profile['mobile-theme'];
@ -138,7 +138,7 @@ function get_profiledata_by_nick($nickname, $uid = 0, $profile = 0) {
$r = q("SELECT `profile-id` FROM `contact` WHERE `id` = %d LIMIT 1",
intval($visitor['cid'])
);
if(dba::is_result($r))
if(dbm::is_result($r))
$profile = $r[0]['profile-id'];
break;
}
@ -230,7 +230,7 @@ function profile_sidebar($profile, $block = 0) {
$r = q("SELECT * FROM `contact` WHERE NOT `pending` AND `uid` = %d AND `nurl` = '%s'",
local_user(), $profile_url);
if (dba::is_result($r))
if (dbm::is_result($r))
$connect = false;
}
@ -246,10 +246,30 @@ function profile_sidebar($profile, $block = 0) {
else
$subscribe_feed = false;
if(get_my_url() && $profile['unkmail'] && ($profile['uid'] != local_user()))
if (remote_user() OR (get_my_url() && $profile['unkmail'] && ($profile['uid'] != local_user()))) {
$wallmessage = t('Message');
else
$wallmessage_link = "wallmessage/".$profile["nickname"];
if (remote_user()) {
$r = q("SELECT `url` FROM `contact` WHERE `uid` = %d AND `id` = '%s' AND `rel` = %d",
intval($profile['uid']),
intval(remote_user()),
intval(CONTACT_IS_FRIEND));
} else {
$r = q("SELECT `url` FROM `contact` WHERE `uid` = %d AND `nurl` = '%s' AND `rel` = %d",
intval($profile['uid']),
dbesc(normalise_link(get_my_url())),
intval(CONTACT_IS_FRIEND));
}
if ($r) {
$remote_url = $r[0]["url"];
$message_path = preg_replace("=(.*)/profile/(.*)=ism", "$1/message/new/", $remote_url);
$wallmessage_link = $message_path.base64_encode($profile["addr"]);
}
} else {
$wallmessage = false;
$wallmessage_link = false;
}
// show edit profile to yourself
if ($profile['uid'] == local_user() && feature_enabled(local_user(),'multi_profiles')) {
@ -263,7 +283,7 @@ function profile_sidebar($profile, $block = 0) {
'entries' => array(),
);
if(dba::is_result($r)) {
if(dbm::is_result($r)) {
foreach($r as $rr) {
$profile['menu']['entries'][] = array(
@ -325,18 +345,21 @@ function profile_sidebar($profile, $block = 0) {
? trim(substr($profile['name'],0,strpos($profile['name'],' '))) : $profile['name']);
$lastname = (($firstname === $profile['name']) ? '' : trim(substr($profile['name'],strlen($firstname))));
$diaspora = array(
'guid' => $profile['guid'],
'podloc' => $a->get_baseurl(),
'searchable' => (($profile['publish'] && $profile['net-publish']) ? 'true' : 'false' ),
'nickname' => $profile['nickname'],
'fullname' => $profile['name'],
'firstname' => $firstname,
'lastname' => $lastname,
'photo300' => $a->get_baseurl() . '/photo/custom/300/' . $profile['uid'] . '.jpg',
'photo100' => $a->get_baseurl() . '/photo/custom/100/' . $profile['uid'] . '.jpg',
'photo50' => $a->get_baseurl() . '/photo/custom/50/' . $profile['uid'] . '.jpg',
);
if ($profile['guid'] != "")
$diaspora = array(
'guid' => $profile['guid'],
'podloc' => $a->get_baseurl(),
'searchable' => (($profile['publish'] && $profile['net-publish']) ? 'true' : 'false' ),
'nickname' => $profile['nickname'],
'fullname' => $profile['name'],
'firstname' => $firstname,
'lastname' => $lastname,
'photo300' => $a->get_baseurl() . '/photo/custom/300/' . $profile['uid'] . '.jpg',
'photo100' => $a->get_baseurl() . '/photo/custom/100/' . $profile['uid'] . '.jpg',
'photo50' => $a->get_baseurl() . '/photo/custom/50/' . $profile['uid'] . '.jpg',
);
else
$diaspora = false;
if (!$block){
$contact_block = contact_block();
@ -344,7 +367,7 @@ function profile_sidebar($profile, $block = 0) {
if(is_array($a->profile) AND !$a->profile['hide-friends']) {
$r = q("SELECT `gcontact`.`updated` FROM `contact` INNER JOIN `gcontact` WHERE `gcontact`.`nurl` = `contact`.`nurl` AND `self` AND `uid` = %d LIMIT 1",
intval($a->profile['uid']));
if(dba::is_result($r))
if(dbm::is_result($r))
$updated = date("c", strtotime($r[0]['updated']));
$r = q("SELECT COUNT(*) AS `total` FROM `contact` WHERE `uid` = %d AND `self` = 0 AND `blocked` = 0 AND `pending` = 0 AND `hidden` = 0 AND `archive` = 0
@ -354,7 +377,7 @@ function profile_sidebar($profile, $block = 0) {
dbesc(NETWORK_DIASPORA),
dbesc(NETWORK_OSTATUS)
);
if(dba::is_result($r))
if(dbm::is_result($r))
$contacts = intval($r[0]['total']);
}
}
@ -386,6 +409,7 @@ function profile_sidebar($profile, $block = 0) {
'$remoteconnect' => $remoteconnect,
'$subscribe_feed' => $subscribe_feed,
'$wallmessage' => $wallmessage,
'$wallmessage_link' => $wallmessage_link,
'$account_type' => $account_type,
'$location' => $location,
'$gender' => $gender,
@ -400,7 +424,6 @@ function profile_sidebar($profile, $block = 0) {
'$contact_block' => $contact_block,
));
$arr = array('profile' => &$profile, 'entry' => &$o);
call_hooks('profile_sidebar', $arr);
@ -664,6 +687,8 @@ function advanced_profile(&$a) {
return replace_macros($tpl, array(
'$title' => t('Profile'),
'$basic' => t('Basic'),
'$advanced' => t('Advanced'),
'$profile' => $profile
));
}
@ -717,8 +742,8 @@ function profile_tabs($a, $is_owner=False, $nickname=Null){
),
);
if ($is_owner){
if ($a->theme_events_in_profile)
// the calendar link for the full featured events calendar
if ($is_owner && $a->theme_events_in_profile) {
$tabs[] = array(
'label' => t('Events'),
'url' => $a->get_baseurl() . '/events',
@ -727,6 +752,20 @@ function profile_tabs($a, $is_owner=False, $nickname=Null){
'id' => 'events-tab',
'accesskey' => 'e',
);
// if the user is not the owner of the calendar we only show a calendar
// with the public events of the calendar owner
} elseif (! $is_owner) {
$tabs[] = array(
'label' => t('Events'),
'url' => $a->get_baseurl() . '/cal/' . $nickname,
'sel' =>((!isset($tab)&&$a->argv[0]=='cal')?'active':''),
'title' => t('Events and Calendar'),
'id' => 'events-tab',
'accesskey' => 'e',
);
}
if ($is_owner){
$tabs[] = array(
'label' => t('Personal Notes'),
'url' => $a->get_baseurl() . '/notes',
@ -779,7 +818,7 @@ function zrl_init(&$a) {
}
}
proc_run('php','include/gprobe.php',bin2hex($tmp_str));
proc_run(PRIORITY_LOW, 'include/gprobe.php',bin2hex($tmp_str));
$arr = array('zrl' => $tmp_str, 'url' => $a->cmd);
call_hooks('zrl_init',$arr);
}

View file

@ -413,7 +413,7 @@ function item_store($arr,$force_parent = false, $notify = false, $dontcache = fa
/* check for create date and expire time */
$uid = intval($arr['uid']);
$r = q("SELECT expire FROM user WHERE uid = %d", intval($uid));
if(dba::is_result($r)) {
if(dbm::is_result($r)) {
$expire_interval = $r[0]['expire'];
if ($expire_interval>0) {
$expire_date = new DateTime( '- '.$expire_interval.' days', new DateTimeZone('UTC'));
@ -507,6 +507,13 @@ function item_store($arr,$force_parent = false, $notify = false, $dontcache = fa
$arr['inform'] = ((x($arr,'inform')) ? trim($arr['inform']) : '');
$arr['file'] = ((x($arr,'file')) ? trim($arr['file']) : '');
// Items cannot be stored before they happen ...
if ($arr['created'] > datetime_convert())
$arr['created'] = datetime_convert();
// We haven't invented time travel by now.
if ($arr['edited'] > datetime_convert())
$arr['edited'] = datetime_convert();
if (($arr['author-link'] == "") AND ($arr['owner-link'] == ""))
logger("Both author-link and owner-link are empty. Called by: ".App::callstack(), LOGGER_DEBUG);
@ -535,7 +542,7 @@ function item_store($arr,$force_parent = false, $notify = false, $dontcache = fa
intval($arr['uid'])
);
if(dba::is_result($r))
if(dbm::is_result($r))
$arr['network'] = $r[0]["network"];
// Fallback to friendica (why is it empty in some cases?)
@ -577,13 +584,19 @@ function item_store($arr,$force_parent = false, $notify = false, $dontcache = fa
"photo" => $arr['author-avatar'], "name" => $arr['author-name']));
}
if ($arr["author-id"] == 0)
$arr["author-id"] = get_contact($arr["author-link"], 0);
if ($arr["owner-id"] == 0)
$arr["owner-id"] = get_contact($arr["owner-link"], 0);
if ($arr['guid'] != "") {
// Checking if there is already an item with the same guid
logger('checking for an item for user '.$arr['uid'].' on network '.$arr['network'].' with the guid '.$arr['guid'], LOGGER_DEBUG);
$r = q("SELECT `guid` FROM `item` WHERE `guid` = '%s' AND `network` = '%s' AND `uid` = '%d' LIMIT 1",
dbesc($arr['guid']), dbesc($arr['network']), intval($arr['uid']));
if(dba::is_result($r)) {
if(dbm::is_result($r)) {
logger('found item with guid '.$arr['guid'].' for user '.$arr['uid'].' on network '.$arr['network'], LOGGER_DEBUG);
return 0;
}
@ -612,7 +625,7 @@ function item_store($arr,$force_parent = false, $notify = false, $dontcache = fa
intval($arr['uid'])
);
if(dba::is_result($r)) {
if(dbm::is_result($r)) {
// is the new message multi-level threaded?
// even though we don't support it now, preserve the info
@ -768,7 +781,7 @@ function item_store($arr,$force_parent = false, $notify = false, $dontcache = fa
intval($r[0]["id"])
);
return 0;
} elseif(dba::is_result($r)) {
} elseif(dbm::is_result($r)) {
$current_post = $r[0]['id'];
logger('item_store: created item ' . $current_post);
@ -904,7 +917,7 @@ function item_store($arr,$force_parent = false, $notify = false, $dontcache = fa
check_item_notification($current_post, $uid);
if ($notify)
proc_run('php', "include/notifier.php", $notify_type, $current_post);
proc_run(PRIORITY_HIGH, "include/notifier.php", $notify_type, $current_post);
return $current_post;
}
@ -979,7 +992,7 @@ function item_body_set_hashtags(&$item) {
function get_item_guid($id) {
$r = q("SELECT `guid` FROM `item` WHERE `id` = %d LIMIT 1", intval($id));
if (dba::is_result($r))
if (dbm::is_result($r))
return($r[0]["guid"]);
else
return("");
@ -998,7 +1011,7 @@ function get_item_id($guid, $uid = 0) {
$r = q("SELECT `item`.`id`, `user`.`nickname` FROM `item` INNER JOIN `user` ON `user`.`uid` = `item`.`uid`
WHERE `item`.`visible` = 1 AND `item`.`deleted` = 0 and `item`.`moderated` = 0
AND `item`.`guid` = '%s' AND `item`.`uid` = %d", dbesc($guid), intval($uid));
if (dba::is_result($r)) {
if (dbm::is_result($r)) {
$id = $r[0]["id"];
$nick = $r[0]["nickname"];
}
@ -1012,7 +1025,7 @@ function get_item_id($guid, $uid = 0) {
AND `item`.`deny_cid` = '' AND `item`.`deny_gid` = ''
AND `item`.`private` = 0 AND `item`.`wall` = 1
AND `item`.`guid` = '%s'", dbesc($guid));
if (dba::is_result($r)) {
if (dbm::is_result($r)) {
$id = $r[0]["id"];
$nick = $r[0]["nickname"];
}
@ -1143,7 +1156,7 @@ function tag_deliver($uid,$item_id) {
);
update_thread($item_id);
proc_run('php','include/notifier.php','tgroup',$item_id);
proc_run(PRIORITY_HIGH,'include/notifier.php', 'tgroup', $item_id);
}
@ -1313,7 +1326,7 @@ function item_is_remote_self($contact, &$datarray) {
if ($contact['remote_self'] == 2) {
$r = q("SELECT `id`,`url`,`name`,`thumb` FROM `contact` WHERE `uid` = %d AND `self`",
intval($contact['uid']));
if (dba::is_result($r)) {
if (dbm::is_result($r)) {
$datarray['contact-id'] = $r[0]["id"];
$datarray['owner-name'] = $r[0]["name"];
@ -1390,17 +1403,9 @@ function new_follower($importer,$contact,$datarray,$item,$sharing = false) {
intval($importer['uid']),
dbesc($url)
);
if(dba::is_result($r)) {
$contact_record = $r[0];
$photos = import_profile_photo($photo,$importer["uid"],$contact_record["id"]);
q("UPDATE `contact` SET `photo` = '%s', `thumb` = '%s', `micro` = '%s' WHERE `id` = %d",
dbesc($photos[0]),
dbesc($photos[1]),
dbesc($photos[2]),
intval($contact_record["id"])
);
if(dbm::is_result($r)) {
$contact_record = $r[0];
update_contact_avatar($photo, $importer["uid"], $contact_record["id"], true);
}
@ -1408,7 +1413,8 @@ function new_follower($importer,$contact,$datarray,$item,$sharing = false) {
intval($importer['uid'])
);
$a = get_app();
if(count($r) AND !in_array($r[0]['page-flags'], array(PAGE_SOAPBOX, PAGE_FREELOVE))) {
if(dbm::is_result($r) AND !in_array($r[0]['page-flags'], array(PAGE_SOAPBOX, PAGE_FREELOVE))) {
// create notification
$hash = random_string();
@ -1707,7 +1713,7 @@ function item_expire($uid, $days, $network = "", $force = false) {
} else
$range = "AND `created` < UTC_TIMESTAMP() - INTERVAL %d DAY ";
$r = q("SELECT * FROM `item`
$r = q("SELECT `file`, `resource-id`, `starred`, `type`, `id` FROM `item`
WHERE `uid` = %d $range
AND `id` = `parent`
$sql_extra
@ -1758,7 +1764,7 @@ function item_expire($uid, $days, $network = "", $force = false) {
drop_item($item['id'],false);
}
proc_run('php',"include/notifier.php","expire","$uid");
proc_run(PRIORITY_HIGH,"include/notifier.php", "expire", $uid);
}
@ -1780,7 +1786,7 @@ function drop_items($items) {
// multiple threads may have been deleted, send an expire notification
if($uid)
proc_run('php',"include/notifier.php","expire","$uid");
proc_run(PRIORITY_HIGH,"include/notifier.php", "expire", $uid);
}
@ -1982,7 +1988,7 @@ function drop_item($id,$interactive = true) {
dbesc($item['parent-uri']),
intval($item['uid'])
);
if(dba::is_result($r)) {
if(dbm::is_result($r)) {
q("UPDATE `item` SET `last-child` = 1 WHERE `id` = %d",
intval($r[0]['id'])
);
@ -1993,7 +1999,7 @@ function drop_item($id,$interactive = true) {
// send the notification upstream/downstream as the case may be
proc_run('php',"include/notifier.php","drop","$drop_id");
proc_run(PRIORITY_HIGH,"include/notifier.php", "drop", $drop_id);
if(! $interactive)
return $owner;
@ -2019,7 +2025,7 @@ function first_post_date($uid,$wall = false) {
intval($uid),
intval($wall ? 1 : 0)
);
if(dba::is_result($r)) {
if(dbm::is_result($r)) {
// logger('first_post_date: ' . $r[0]['id'] . ' ' . $r[0]['created'], LOGGER_DATA);
return substr(datetime_convert('',date_default_timezone_get(),$r[0]['created']),0,10);
}

View file

@ -90,7 +90,7 @@ function do_like($item_id, $verb) {
WHERE `contact`.`self` = 1 AND `contact`.`uid` = %d LIMIT 1",
intval($owner_uid)
);
if(dba::is_result($r))
if(dbm::is_result($r))
$owner = $r[0];
if(! $owner) {
@ -112,7 +112,7 @@ function do_like($item_id, $verb) {
intval($_SESSION['visitor_id']),
intval($owner_uid)
);
if(dba::is_result($r))
if(dbm::is_result($r))
$contact = $r[0];
}
if(! $contact) {
@ -135,7 +135,7 @@ function do_like($item_id, $verb) {
dbesc($item_id), dbesc($item_id), dbesc($item['uri'])
);
if(dba::is_result($r)) {
if(dbm::is_result($r)) {
$like_item = $r[0];
// Already voted, undo it
@ -153,7 +153,7 @@ function do_like($item_id, $verb) {
);
$like_item_id = $like_item['id'];
proc_run('php',"include/notifier.php","like","$like_item_id");
proc_run(PRIORITY_HIGH, "include/notifier.php", "like", $like_item_id);
return true;
}
@ -161,7 +161,7 @@ function do_like($item_id, $verb) {
$uri = item_new_uri($a->get_hostname(),$owner_uid);
$post_type = (($item['resource-id']) ? t('photo') : t('status'));
if($item['obj_type'] === ACTIVITY_OBJ_EVENT)
if($item['object-type'] === ACTIVITY_OBJ_EVENT)
$post_type = t('event');
$objtype = (($item['resource-id']) ? ACTIVITY_OBJ_PHOTO : ACTIVITY_OBJ_NOTE );
$link = xmlify('<link rel="alternate" type="text/html" href="' . $a->get_baseurl() . '/display/' . $owner['nickname'] . '/' . $item['id'] . '" />' . "\n") ;
@ -245,7 +245,7 @@ EOT;
call_hooks('post_local_end', $arr);
proc_run('php',"include/notifier.php","like","$post_id");
proc_run(PRIORITY_HIGH, "include/notifier.php", "like", $post_id);
return true;
}

View file

@ -16,7 +16,7 @@ function lock_function($fn_name, $block = true, $wait_sec = 2, $timeout = 30) {
dbesc($fn_name)
);
if((dba::is_result($r)) AND (!$r[0]['locked'] OR (strtotime($r[0]['created']) < time() - 3600))) {
if((dbm::is_result($r)) AND (!$r[0]['locked'] OR (strtotime($r[0]['created']) < time() - 3600))) {
q("UPDATE `locks` SET `locked` = 1, `created` = '%s' WHERE `name` = '%s'",
dbesc(datetime_convert()),
dbesc($fn_name)

View file

@ -41,7 +41,7 @@ function send_message($recipient=0, $body='', $subject='', $replyto=''){
dbesc($replyto),
dbesc($replyto)
);
if(dba::is_result($r))
if(dbm::is_result($r))
$convid = $r[0]['convid'];
}
@ -74,7 +74,7 @@ function send_message($recipient=0, $body='', $subject='', $replyto=''){
dbesc($conv_guid),
intval(local_user())
);
if(dba::is_result($r))
if(dbm::is_result($r))
$convid = $r[0]['id'];
}
@ -113,7 +113,7 @@ function send_message($recipient=0, $body='', $subject='', $replyto=''){
dbesc($uri),
intval(local_user())
);
if(dba::is_result($r))
if(dbm::is_result($r))
$post_id = $r[0]['id'];
/**
@ -150,7 +150,7 @@ function send_message($recipient=0, $body='', $subject='', $replyto=''){
}
if($post_id) {
proc_run('php',"include/notifier.php","mail","$post_id");
proc_run(PRIORITY_HIGH, "include/notifier.php", "mail", $post_id);
return intval($post_id);
} else {
return -3;
@ -210,7 +210,7 @@ function send_wallmessage($recipient='', $body='', $subject='', $replyto=''){
dbesc($conv_guid),
intval($recipient['uid'])
);
if(dba::is_result($r))
if(dbm::is_result($r))
$convid = $r[0]['id'];
if(! $convid) {

View file

@ -170,7 +170,7 @@ function nav_info(&$a) {
if(in_array($_SESSION['page_flags'], array(PAGE_NORMAL, PAGE_SOAPBOX, PAGE_FREELOVE))) {
$nav['notifications'] = array('notifications', t('Notifications'), "", t('Notifications'));
$nav['notifications']['all']=array('notifications/system', t('See all notifications'), "", "");
$nav['notifications']['mark'] = array('', t('Mark all system notifications seen'), '','');
$nav['notifications']['mark'] = array('', t('Mark as seen'), '',t('Mark all system notifications seen'));
}
}

View file

@ -5,7 +5,7 @@
*/
require_once("include/xml.php");
require_once('include/Probe.php');
/**
* @brief Curl wrapper
@ -338,7 +338,6 @@ function xml_status($st, $message = '') {
killme();
}
/**
* @brief Send HTTP status header and exit.
*
@ -348,6 +347,14 @@ function xml_status($st, $message = '') {
* 'description' => optional message
*/
/**
* @brief Send HTTP status header and exit.
*
* @param integer $val HTTP status result value
* @param array $description optional message
* 'title' => header title
* 'description' => optional message
*/
function http_status_exit($val, $description = array()) {
$err = '';
if($val >= 400) {
@ -371,325 +378,6 @@ function http_status_exit($val, $description = array()) {
}
// Given an email style address, perform webfinger lookup and
// return the resulting DFRN profile URL, or if no DFRN profile URL
// is located, returns an OStatus subscription template (prefixed
// with the string 'stat:' to identify it as on OStatus template).
// If this isn't an email style address just return $webbie.
// Return an empty string if email-style addresses but webfinger fails,
// or if the resultant personal XRD doesn't contain a supported
// subscription/friend-request attribute.
// amended 7/9/2011 to return an hcard which could save potentially loading
// a lengthy content page to scrape dfrn attributes
function webfinger_dfrn($webbie,&$hcard) {
if(! strstr($webbie,'@')) {
return $webbie;
}
$profile_link = '';
$links = webfinger($webbie);
logger('webfinger_dfrn: ' . $webbie . ':' . print_r($links,true), LOGGER_DATA);
if(count($links)) {
foreach($links as $link) {
if(empty($profile_link) && $link['@attributes']['rel'] === NAMESPACE_DFRN) {
$profile_link = $link['@attributes']['href'];
} elseif(empty($profile_link) && $link['@attributes']['rel'] === NAMESPACE_OSTATUSSUB) {
$profile_link = 'stat:' . $link['@attributes']['template'];
} elseif(empty($hcard) && $link['@attributes']['rel'] === 'http://microformats.org/profile/hcard') {
$hcard = $link['@attributes']['href'];
}
}
}
return $profile_link;
}
/**
* @brief Perform webfinger lookup on an email style address
*
* @param string $webbi An email style address
* @param boolean $debug
*
* @return array of link attributes from the personal XRD file
* empty array on error/failure
*/
function webfinger($webbie, $debug = false) {
$host = '';
if(strstr($webbie,'@')) {
$host = substr($webbie,strpos($webbie,'@') + 1);
}
if(strlen($host)) {
$tpl = fetch_lrdd_template($host);
logger('webfinger: lrdd template: ' . $tpl);
if(strlen($tpl)) {
$pxrd = str_replace('{uri}', urlencode('acct:' . $webbie), $tpl);
logger('webfinger: pxrd: ' . $pxrd);
$links = fetch_xrd_links($pxrd);
if(! count($links)) {
// try with double slashes
$pxrd = str_replace('{uri}', urlencode('acct://' . $webbie), $tpl);
logger('webfinger: pxrd: ' . $pxrd);
$links = fetch_xrd_links($pxrd);
}
return $links;
}
}
return array();
}
function lrdd($uri, $debug = false) {
$a = get_app();
// default priority is host priority, host-meta first
$priority = 'host';
// All we have is an email address. Resource-priority is irrelevant
// because our URI isn't directly resolvable.
if(strstr($uri,'@')) {
return(webfinger($uri));
}
// get the host meta file
$host = @parse_url($uri);
if($host) {
$url = ((x($host,'scheme')) ? $host['scheme'] : 'http') . '://';
$url .= $host['host'] . '/.well-known/host-meta' ;
}
else
return array();
logger('lrdd: constructed url: ' . $url);
$xml = fetch_url($url);
$headers = $a->get_curl_headers();
if (! $xml)
return array();
logger('lrdd: host_meta: ' . $xml, LOGGER_DATA);
if(! stristr($xml,'<xrd'))
return array();
$h = parse_xml_string($xml);
if(! $h)
return array();
$arr = xml::element_to_array($h);
if(isset($arr['xrd']['property'])) {
$property = $arr['crd']['property'];
if(! isset($property[0]))
$properties = array($property);
else
$properties = $property;
foreach($properties as $prop)
if((string) $prop['@attributes'] === 'http://lrdd.net/priority/resource')
$priority = 'resource';
}
// save the links in case we need them
$links = array();
if(isset($arr['xrd']['link'])) {
$link = $arr['xrd']['link'];
if(! isset($link[0]))
$links = array($link);
else
$links = $link;
}
// do we have a template or href?
if(count($links)) {
foreach($links as $link) {
if($link['@attributes']['rel'] && attribute_contains($link['@attributes']['rel'],'lrdd')) {
if(x($link['@attributes'],'template'))
$tpl = $link['@attributes']['template'];
elseif(x($link['@attributes'],'href'))
$href = $link['@attributes']['href'];
}
}
}
if((! isset($tpl)) || (! strpos($tpl,'{uri}')))
$tpl = '';
if($priority === 'host') {
if(strlen($tpl))
$pxrd = str_replace('{uri}', urlencode($uri), $tpl);
elseif(isset($href))
$pxrd = $href;
if(isset($pxrd)) {
logger('lrdd: (host priority) pxrd: ' . $pxrd);
$links = fetch_xrd_links($pxrd);
return $links;
}
$lines = explode("\n",$headers);
if(count($lines)) {
foreach($lines as $line) {
if((stristr($line,'link:')) && preg_match('/<([^>].*)>.*rel\=[\'\"]lrdd[\'\"]/',$line,$matches)) {
return(fetch_xrd_links($matches[1]));
break;
}
}
}
}
// priority 'resource'
$html = fetch_url($uri);
$headers = $a->get_curl_headers();
logger('lrdd: headers=' . $headers, LOGGER_DEBUG);
// don't try and parse raw xml as html
if(! strstr($html,'<?xml')) {
require_once('library/HTML5/Parser.php');
try {
$dom = HTML5_Parser::parse($html);
} catch (DOMException $e) {
logger('lrdd: parse error: ' . $e);
}
if(isset($dom) && $dom) {
$items = $dom->getElementsByTagName('link');
foreach($items as $item) {
$x = $item->getAttribute('rel');
if($x == "lrdd") {
$pagelink = $item->getAttribute('href');
break;
}
}
}
}
if(isset($pagelink))
return(fetch_xrd_links($pagelink));
// next look in HTTP headers
$lines = explode("\n",$headers);
if(count($lines)) {
foreach($lines as $line) {
/// @TODO Alter the following regex to support multiple relations (space separated)
if((stristr($line,'link:')) && preg_match('/<([^>].*)>.*rel\=[\'\"]lrdd[\'\"]/',$line,$matches)) {
$pagelink = $matches[1];
break;
}
// don't try and run feeds through the html5 parser
if(stristr($line,'content-type:') && ((stristr($line,'application/atom+xml')) || (stristr($line,'application/rss+xml'))))
return array();
if(stristr($html,'<rss') || stristr($html,'<feed'))
return array();
}
}
if(isset($pagelink))
return(fetch_xrd_links($pagelink));
// If we haven't found any links, return the host xrd links (which we have already fetched)
if(isset($links))
return $links;
return array();
}
// Given a host name, locate the LRDD template from that
// host. Returns the LRDD template or an empty string on
// error/failure.
function fetch_lrdd_template($host) {
$tpl = '';
$url1 = 'https://' . $host . '/.well-known/host-meta' ;
$url2 = 'http://' . $host . '/.well-known/host-meta' ;
$links = fetch_xrd_links($url1);
logger('fetch_lrdd_template from: ' . $url1);
logger('template (https): ' . print_r($links,true));
if(! count($links)) {
logger('fetch_lrdd_template from: ' . $url2);
$links = fetch_xrd_links($url2);
logger('template (http): ' . print_r($links,true));
}
if(count($links)) {
foreach($links as $link)
if($link['@attributes']['rel'] && $link['@attributes']['rel'] === 'lrdd' && (!$link['@attributes']['type'] || $link['@attributes']['type'] === 'application/xrd+xml'))
$tpl = $link['@attributes']['template'];
}
if(! strpos($tpl,'{uri}'))
$tpl = '';
return $tpl;
}
/**
* @brief Given a URL, retrieve the page as an XRD document.
*
* @param string $url An url
* @return array of links
* return empty array on error/failure
*/
function fetch_xrd_links($url) {
$xrd_timeout = intval(get_config('system','xrd_timeout'));
$redirects = 0;
$xml = fetch_url($url,false,$redirects,(($xrd_timeout) ? $xrd_timeout : 20), "application/xrd+xml");
logger('fetch_xrd_links: ' . $xml, LOGGER_DATA);
if ((! $xml) || (! stristr($xml,'<xrd')))
return array();
// fix diaspora's bad xml
$xml = str_replace(array('href=&quot;','&quot;/>'),array('href="','"/>'),$xml);
$h = parse_xml_string($xml);
if(! $h)
return array();
$arr = xml::element_to_array($h);
$links = array();
if(isset($arr['xrd']['link'])) {
$link = $arr['xrd']['link'];
if(! isset($link[0]))
$links = array($link);
else
$links = $link;
}
if(isset($arr['xrd']['alias'])) {
$alias = $arr['xrd']['alias'];
if(! isset($alias[0]))
$aliases = array($alias);
else
$aliases = $alias;
if(is_array($aliases) && count($aliases)) {
foreach($aliases as $alias) {
$links[]['@attributes'] = array('rel' => 'alias' , 'href' => $alias);
}
}
}
logger('fetch_xrd_links: ' . print_r($links,true), LOGGER_DATA);
return $links;
}
/**
* @brief Check URL to se if ts's real
*
@ -1137,7 +825,7 @@ function short_link($url) {
* This function encodes an array to json format
* and adds an application/json HTTP header to the output.
* After finishing the process is getting killed.
*
*
* @param array $x The input content
*/
function json_return_and_die($x) {
@ -1145,3 +833,57 @@ function json_return_and_die($x) {
echo json_encode($x);
killme();
}
/**
* @brief Find the matching part between two url
*
* @param string $url1
* @param string $url2
* @return string The matching part
*/
function matching_url($url1, $url2) {
if (($url1 == "") OR ($url2 == ""))
return "";
$url1 = normalise_link($url1);
$url2 = normalise_link($url2);
$parts1 = parse_url($url1);
$parts2 = parse_url($url2);
if (!isset($parts1["host"]) OR !isset($parts2["host"]))
return "";
if ($parts1["scheme"] != $parts2["scheme"])
return "";
if ($parts1["host"] != $parts2["host"])
return "";
if ($parts1["port"] != $parts2["port"])
return "";
$match = $parts1["scheme"]."://".$parts1["host"];
if ($parts1["port"])
$match .= ":".$parts1["port"];
$pathparts1 = explode("/", $parts1["path"]);
$pathparts2 = explode("/", $parts2["path"]);
$i = 0;
$path = "";
do {
$path1 = $pathparts1[$i];
$path2 = $pathparts2[$i];
if ($path1 == $path2)
$path .= $path1."/";
} while (($path1 == $path2) AND ($i++ <= count($pathparts1)));
$match .= $path;
return normalise_link($match);
}

View file

@ -16,7 +16,7 @@ require_once('include/salmon.php');
/*
* The notifier is typically called with:
*
* proc_run('php', "include/notifier.php", COMMAND, ITEM_ID);
* proc_run(PRIORITY_HIGH, "include/notifier.php", COMMAND, ITEM_ID);
*
* where COMMAND is one of the following:
*
@ -132,18 +132,25 @@ function notifier_run(&$argv, &$argc){
$recipients[] = $suggest[0]['cid'];
$item = $suggest[0];
} elseif($cmd === 'removeme') {
$r = q("SELECT * FROM `user` WHERE `uid` = %d LIMIT 1", intval($item_id));
if (! $r)
$r = q("SELECT `contact`.*, `user`.`pubkey` AS `upubkey`, `user`.`prvkey` AS `uprvkey`,
`user`.`timezone`, `user`.`nickname`, `user`.`sprvkey`, `user`.`spubkey`,
`user`.`page-flags`, `user`.`prvnets`, `user`.`guid`
FROM `contact` INNER JOIN `user` ON `user`.`uid` = `contact`.`uid`
WHERE `contact`.`uid` = %d AND `contact`.`self` LIMIT 1",
intval($item_id));
if (!$r)
return;
$user = $r[0];
$r = q("SELECT * FROM `contact` WHERE `uid` = %d AND `self` = 1 LIMIT 1", intval($item_id));
if (! $r)
$r = q("SELECT * FROM `contact` WHERE `uid` = %d AND `self` LIMIT 1", intval($item_id));
if (!$r)
return;
$self = $r[0];
$r = q("SELECT * FROM `contact` WHERE `self` = 0 AND `uid` = %d", intval($item_id));
if(! $r)
$r = q("SELECT * FROM `contact` WHERE NOT `self` AND `uid` = %d", intval($item_id));
if(!$r)
return;
require_once('include/Contact.php');
@ -314,7 +321,7 @@ function notifier_run(&$argv, &$argc){
intval($uid),
dbesc(NETWORK_DFRN)
);
if(dba::is_result($r))
if(dbm::is_result($r))
foreach($r as $rr)
$recipients_followup[] = $rr['id'];
}
@ -348,7 +355,7 @@ function notifier_run(&$argv, &$argc){
// a delivery fork. private groups (forum_mode == 2) do not uplink
if((intval($parent['forum_mode']) == 1) && (! $top_level) && ($cmd !== 'uplink')) {
proc_run('php','include/notifier.php','uplink',$item_id);
proc_run(PRIORITY_HIGH,'include/notifier.php','uplink',$item_id);
}
$conversants = array();
@ -388,7 +395,34 @@ function notifier_run(&$argv, &$argc){
// We have not only to look at the parent, since it could be a Friendica thread.
if (($thr_parent AND ($thr_parent[0]['network'] == NETWORK_OSTATUS)) OR ($parent['network'] == NETWORK_OSTATUS)) {
logger('Some parent is OStatus for '.$target_item["guid"], LOGGER_DEBUG);
logger('Some parent is OStatus for '.$target_item["guid"]." - Author: ".$thr_parent[0]['author-link']." - Owner: ".$thr_parent[0]['owner-link'], LOGGER_DEBUG);
// Send a salmon to the parent author
$r = q("SELECT `notify` FROM `contact` WHERE `nurl`='%s' AND `uid` IN (0, %d) AND `notify` != ''",
dbesc(normalise_link($thr_parent[0]['author-link'])),
intval($uid));
if ($r)
$probed_contact = $r[0];
else
$probed_contact = probe_url($thr_parent[0]['author-link']);
if ($probed_contact["notify"] != "") {
logger('Notify parent author '.$probed_contact["url"].': '.$probed_contact["notify"]);
$url_recipients[$probed_contact["notify"]] = $probed_contact["notify"];
}
// Send a salmon to the parent owner
$r = q("SELECT `notify` FROM `contact` WHERE `nurl`='%s' AND `uid` IN (0, %d) AND `notify` != ''",
dbesc(normalise_link($thr_parent[0]['owner-link'])),
intval($uid));
if ($r)
$probed_contact = $r[0];
else
$probed_contact = probe_url($thr_parent[0]['owner-link']);
if ($probed_contact["notify"] != "") {
logger('Notify parent owner '.$probed_contact["url"].': '.$probed_contact["notify"]);
$url_recipients[$probed_contact["notify"]] = $probed_contact["notify"];
}
// Send a salmon to the parent author
$probed_contact = probe_url($thr_parent[0]['author-link']);
@ -425,7 +459,7 @@ function notifier_run(&$argv, &$argc){
$r = q("SELECT * FROM `contact` WHERE `id` IN ($conversant_str) AND NOT `blocked` AND NOT `pending` AND NOT `archive`".$sql_extra);
if(dba::is_result($r))
if(dbm::is_result($r))
$contacts = $r;
} else
@ -443,7 +477,7 @@ function notifier_run(&$argv, &$argc){
intval($uid),
dbesc(NETWORK_MAIL)
);
if(dba::is_result($r)) {
if(dbm::is_result($r)) {
foreach($r as $rr)
$recipients[] = $rr['id'];
}
@ -471,7 +505,7 @@ function notifier_run(&$argv, &$argc){
// delivery loop
if(dba::is_result($r)) {
if(dbm::is_result($r)) {
foreach($r as $contact) {
if(!$contact['self']) {
@ -518,7 +552,7 @@ function notifier_run(&$argv, &$argc){
$this_batch[] = $contact['id'];
if(count($this_batch) >= $deliveries_per_process) {
proc_run('php','include/delivery.php',$cmd,$item_id,$this_batch);
proc_run(PRIORITY_HIGH,'include/delivery.php',$cmd,$item_id,$this_batch);
$this_batch = array();
if($interval)
@time_sleep_until(microtime(true) + (float) $interval);
@ -528,7 +562,7 @@ function notifier_run(&$argv, &$argc){
// be sure to pick up any stragglers
if(count($this_batch))
proc_run('php','include/delivery.php',$cmd,$item_id,$this_batch);
proc_run(PRIORITY_HIGH,'include/delivery.php',$cmd,$item_id,$this_batch);
}
// send salmon slaps to mentioned remote tags (@foo@example.com) in OStatus posts
@ -549,7 +583,7 @@ function notifier_run(&$argv, &$argc){
if($public_message) {
if (!$followup AND $top_level)
if (!$followup)
$r0 = diaspora::relay_list();
else
$r0 = array();
@ -572,7 +606,7 @@ function notifier_run(&$argv, &$argc){
$r = array_merge($r2,$r1,$r0);
if(dba::is_result($r)) {
if(dbm::is_result($r)) {
logger('pubdeliver '.$target_item["guid"].': '.print_r($r,true), LOGGER_DEBUG);
// throw everything into the queue in case we get killed
@ -599,7 +633,7 @@ function notifier_run(&$argv, &$argc){
if((! $mail) && (! $fsuggest) && (! $followup)) {
logger('notifier: delivery agent: '.$rr['name'].' '.$rr['id'].' '.$rr['network'].' '.$target_item["guid"]);
proc_run('php','include/delivery.php',$cmd,$item_id,$rr['id']);
proc_run(PRIORITY_HIGH,'include/delivery.php',$cmd,$item_id,$rr['id']);
if($interval)
@time_sleep_until(microtime(true) + (float) $interval);
}
@ -622,8 +656,8 @@ function notifier_run(&$argv, &$argc){
if ($h === '[internal]') {
// Set push flag for PuSH subscribers to this topic,
// they will be notified in queue.php
q("UPDATE `push_subscriber` SET `push` = 1 " .
"WHERE `nickname` = '%s'", dbesc($owner['nickname']));
q("UPDATE `push_subscriber` SET `push` = 1 ".
"WHERE `nickname` = '%s' AND `push` = 0", dbesc($owner['nickname']));
logger('Activating internal PuSH for item '.$item_id, LOGGER_DEBUG);
@ -639,7 +673,7 @@ function notifier_run(&$argv, &$argc){
}
// Handling the pubsubhubbub requests
proc_run('php','include/pubsubpublish.php');
proc_run(PRIORITY_HIGH,'include/pubsubpublish.php');
}
logger('notifier: calling hooks', LOGGER_DEBUG);

View file

@ -23,7 +23,7 @@ class FKOAuthDataStore extends OAuthDataStore {
$r = q("SELECT client_id, pw, redirect_uri FROM clients WHERE client_id='%s'",
dbesc($consumer_key)
);
if (dba::is_result($r))
if (dbm::is_result($r))
return new OAuthConsumer($r[0]['client_id'],$r[0]['pw'],$r[0]['redirect_uri']);
return null;
}
@ -35,7 +35,7 @@ class FKOAuthDataStore extends OAuthDataStore {
dbesc($token_type),
dbesc($token)
);
if (dba::is_result($r)){
if (dbm::is_result($r)){
$ot=new OAuthToken($r[0]['id'],$r[0]['secret']);
$ot->scope=$r[0]['scope'];
$ot->expires = $r[0]['expires'];
@ -52,7 +52,7 @@ class FKOAuthDataStore extends OAuthDataStore {
dbesc($nonce),
intval($timestamp)
);
if (dba::is_result($r))
if (dbm::is_result($r))
return new OAuthToken($r[0]['id'],$r[0]['secret']);
return null;
}
@ -136,7 +136,7 @@ class FKOAuth1 extends OAuthServer {
$r = q("SELECT * FROM `user` WHERE uid=%d AND `blocked` = 0 AND `account_expired` = 0 AND `account_removed` = 0 AND `verified` = 1 LIMIT 1",
intval($uid)
);
if(dba::is_result($r)){
if(dbm::is_result($r)){
$record = $r[0];
} else {
logger('FKOAuth1::loginUser failure: ' . print_r($_SERVER,true), LOGGER_DEBUG);
@ -162,7 +162,7 @@ class FKOAuth1 extends OAuthServer {
$r = q("SELECT * FROM `contact` WHERE `uid` = %s AND `self` = 1 LIMIT 1",
intval($_SESSION['uid']));
if(dba::is_result($r)) {
if(dbm::is_result($r)) {
$a->contact = $r[0];
$a->cid = $r[0]['id'];
$_SESSION['cid'] = $a->cid;
@ -219,7 +219,7 @@ class FKOAuth2 extends OAuth2 {
$r = q("SELECT client_id, expires, scope FROM tokens WHERE id = '%s'",
dbesc($oauth_token));
if (dba::is_result($r))
if (dbm::is_result($r))
return $r[0];
return null;
}
@ -247,7 +247,7 @@ class FKOAuth2 extends OAuth2 {
$r = q("SELECT id, client_id, redirect_uri, expires, scope FROM auth_codes WHERE id = '%s'",
dbesc($code));
if (dba::is_result($r))
if (dbm::is_result($r))
return $r[0];
return null;
}

View file

@ -75,10 +75,13 @@ function oembed_fetch_url($embedurl, $no_rich_type = false){
else { //save in cache
$j = json_decode($txt);
if ($j->type != "error")
q("INSERT INTO `oembed` (`url`, `content`, `created`) VALUES ('%s', '%s', '%s')",
dbesc(normalise_link($embedurl)), dbesc($txt), dbesc(datetime_convert()));
q("INSERT INTO `oembed` (`url`, `content`, `created`) VALUES ('%s', '%s', '%s')
ON DUPLICATE KEY UPDATE `content` = '%s', `created` = '%s'",
dbesc(normalise_link($embedurl)),
dbesc($txt), dbesc(datetime_convert()),
dbesc($txt), dbesc(datetime_convert()));
Cache::set($a->videowidth . $embedurl,$txt, CACHE_DAY);
Cache::set($a->videowidth.$embedurl,$txt, CACHE_DAY);
}
}

View file

@ -24,7 +24,6 @@ function onepoll_run(&$argv, &$argc){
unset($db_host, $db_user, $db_pass, $db_data);
};
require_once('include/session.php');
require_once('include/datetime.php');
require_once('include/items.php');
@ -94,7 +93,7 @@ function onepoll_run(&$argv, &$argc){
where `cid` = %d and updated > UTC_TIMESTAMP() - INTERVAL 1 DAY",
intval($contact['id'])
);
if (dba::is_result($r))
if (dbm::is_result($r))
if (!$r[0]['total'])
poco_load($contact['id'],$importer_uid,0,$contact['poco']);
}
@ -394,7 +393,7 @@ function onepoll_run(&$argv, &$argc){
dbesc($datarray['uri'])
);
if(dba::is_result($r)) {
if(dbm::is_result($r)) {
logger("Mail: Seen before ".$msg_uid." for ".$mailconf[0]['user']." UID: ".$importer_uid." URI: ".$datarray['uri'],LOGGER_DEBUG);
// Only delete when mails aren't automatically moved or deleted
@ -447,7 +446,7 @@ function onepoll_run(&$argv, &$argc){
$r = q("SELECT `uri` , `parent-uri` FROM `item` WHERE `uri` IN ( $qstr ) AND `uid` = %d LIMIT 1",
intval($importer_uid)
);
if(dba::is_result($r))
if(dbm::is_result($r))
$datarray['parent-uri'] = $r[0]['parent-uri']; // Set the parent as the top-level item
// $datarray['parent-uri'] = $r[0]['uri'];
}
@ -479,7 +478,7 @@ function onepoll_run(&$argv, &$argc){
$r = q("SELECT `uri` , `parent-uri` FROM `item` WHERE `title` = \"%s\" AND `uid` = %d ORDER BY `created` DESC LIMIT 1",
dbesc(protect_sprintf($datarray['title'])),
intval($importer_uid));
if(dba::is_result($r))
if(dbm::is_result($r))
$datarray['parent-uri'] = $r[0]['parent-uri'];
}

View file

@ -161,6 +161,7 @@ class ostatus {
}
$contact["generation"] = 2;
$contact["hide"] = false; // OStatus contacts are never hidden
$contact["photo"] = $author["author-avatar"];
update_gcontact($contact);
}
@ -492,6 +493,7 @@ class ostatus {
$orig_body = $xpath->query('atom:content/text()', $activityobjects)->item(0)->nodeValue;
$orig_created = $xpath->query('atom:published/text()', $activityobjects)->item(0)->nodeValue;
$orig_edited = $xpath->query('atom:updated/text()', $activityobjects)->item(0)->nodeValue;
$orig_contact = $contact;
$orig_author = self::fetchauthor($xpath, $activityobjects, $importer, $orig_contact, false);
@ -501,6 +503,7 @@ class ostatus {
$item["author-avatar"] = $orig_author["author-avatar"];
$item["body"] = add_page_info_to_body(html2bbcode($orig_body));
$item["created"] = $orig_created;
$item["edited"] = $orig_edited;
$item["uri"] = $orig_uri;
$item["plink"] = $orig_link;
@ -691,6 +694,7 @@ class ostatus {
}
}
$contact["hide"] = false; // OStatus contacts are never hidden
update_gcontact($contact);
}
@ -1967,7 +1971,7 @@ class ostatus {
OR (`item`.`network` = '%s' AND ((`thread`.`network` IN ('%s', '%s')) OR (`thritem`.`network` IN ('%s', '%s')))) AND `thread`.`mention`)
AND ((`item`.`owner-link` IN ('%s', '%s') AND (`item`.`parent` = `item`.`id`))
OR (`item`.`author-link` IN ('%s', '%s')))
ORDER BY `item`.`received` DESC
ORDER BY `item`.`id` DESC
LIMIT 0, 300",
intval($owner["uid"]), dbesc($check_date), dbesc(NETWORK_DFRN),
//dbesc(NETWORK_OSTATUS), dbesc(NETWORK_OSTATUS),

View file

@ -82,7 +82,7 @@ function get_attachment_data($body) {
$data = array();
if (!preg_match("/(.*)\[attachment(.*)\](.*?)\[\/attachment\](.*)/ism", $body, $match))
if (!preg_match("/(.*)\[attachment(.*?)\](.*?)\[\/attachment\](.*)/ism", $body, $match))
return get_old_attachment_data($body);
$attributes = $match[2];
@ -117,7 +117,7 @@ function get_attachment_data($body) {
$url = $matches[1];
if ($url != "")
$data["url"] = $url;
$data["url"] = html_entity_decode($url, ENT_QUOTES, 'UTF-8');
$title = "";
preg_match("/title='(.*?)'/ism", $attributes, $matches);
@ -128,12 +128,12 @@ function get_attachment_data($body) {
if ($matches[1] != "")
$title = $matches[1];
//$title = htmlentities($title, ENT_QUOTES, 'UTF-8', false);
$title = bbcode(html_entity_decode($title, ENT_QUOTES, 'UTF-8'), false, false, true);
$title = str_replace(array("[", "]"), array("&#91;", "&#93;"), $title);
if ($title != "")
if ($title != "") {
$title = bbcode(html_entity_decode($title, ENT_QUOTES, 'UTF-8'), false, false, true);
$title = html_entity_decode($title, ENT_QUOTES, 'UTF-8');
$title = str_replace(array("[", "]"), array("&#91;", "&#93;"), $title);
$data["title"] = $title;
}
$image = "";
preg_match("/image='(.*?)'/ism", $attributes, $matches);
@ -145,7 +145,7 @@ function get_attachment_data($body) {
$image = $matches[1];
if ($image != "")
$data["image"] = $image;
$data["image"] = html_entity_decode($image, ENT_QUOTES, 'UTF-8');
$preview = "";
preg_match("/preview='(.*?)'/ism", $attributes, $matches);
@ -157,7 +157,7 @@ function get_attachment_data($body) {
$preview = $matches[1];
if ($preview != "")
$data["preview"] = $preview;
$data["preview"] = html_entity_decode($preview, ENT_QUOTES, 'UTF-8');
$data["description"] = trim($match[3]);
@ -189,6 +189,13 @@ function get_attached_data($body) {
if (count($pictures) == 1) {
// Checking, if the link goes to a picture
$data = parseurl_getsiteinfo_cached($pictures[0][1], true);
// Workaround:
// Sometimes photo posts to the own album are not detected at the start.
// So we seem to cannot use the cache for these cases. That's strange.
if (($data["type"] != "photo") AND strstr($pictures[0][1], "/photos/"))
$data = parseurl_getsiteinfo($pictures[0][1], true);
if ($data["type"] == "photo") {
$post["type"] = "photo";
if (isset($data["images"][0])) {
@ -343,7 +350,7 @@ function plaintext($a, $b, $limit = 0, $includedlinks = false, $htmlmode = 2, $t
}
}
$html = bbcode($post["text"], false, false, $htmlmode);
$html = bbcode($post["text"].$post["after"], false, false, $htmlmode);
$msg = html2plain($html, 0, true);
$msg = trim(html_entity_decode($msg,ENT_QUOTES,'UTF-8'));

View file

@ -79,7 +79,7 @@ function reload_plugins() {
if(strlen($plugins)) {
$r = q("SELECT * FROM `addon` WHERE `installed` = 1");
if(dba::is_result($r))
if(dbm::is_result($r))
$installed = $r;
else
$installed = array();
@ -150,7 +150,7 @@ function register_hook($hook,$file,$function,$priority=0) {
dbesc($file),
dbesc($function)
);
if(dba::is_result($r))
if(dbm::is_result($r))
return true;
$r = q("INSERT INTO `hook` (`hook`, `file`, `function`, `priority`) VALUES ( '%s', '%s', '%s', '%s' ) ",
@ -187,7 +187,7 @@ function load_hooks() {
$a = get_app();
$a->hooks = array();
$r = q("SELECT * FROM `hook` WHERE 1 ORDER BY `priority` DESC, `file`");
if(dba::is_result($r)) {
if(dbm::is_result($r)) {
foreach($r as $rr) {
if(! array_key_exists($rr['hook'],$a->hooks))
$a->hooks[$rr['hook']] = array();
@ -205,37 +205,41 @@ function load_hooks() {
* @param string $name of the hook to call
* @param string|array &$data to transmit to the callback handler
*/
if(! function_exists('call_hooks')) {
function call_hooks($name, &$data = null) {
$stamp1 = microtime(true);
$a = get_app();
#logger($name, LOGGER_ALL);
if (is_array($a->hooks) && array_key_exists($name, $a->hooks))
foreach ($a->hooks[$name] as $hook)
call_single_hook($a, $name, $hook, $data);
}
if((is_array($a->hooks)) && (array_key_exists($name,$a->hooks))) {
foreach($a->hooks[$name] as $hook) {
// Don't run a theme's hook if the user isn't using the theme
if(strpos($hook[0], 'view/theme/') !== false && strpos($hook[0], 'view/theme/'.current_theme()) === false)
continue;
/**
* @brief Calls a single hook.
*
* @param string $name of the hook to call
* @param array $hook Hook data
* @param string|array &$data to transmit to the callback handler
*/
function call_single_hook($a, $name, $hook, &$data = null) {
// Don't run a theme's hook if the user isn't using the theme
if (strpos($hook[0], 'view/theme/') !== false && strpos($hook[0], 'view/theme/'.current_theme()) === false)
return;
@include_once($hook[0]);
if(function_exists($hook[1])) {
$func = $hook[1];
//logger($name." => ".$hook[0].":".$func."()", LOGGER_DEBUG);
$func($a,$data);
}
else {
// remove orphan hooks
q("DELETE FROM `hook` WHERE `hook` = '%s' AND `file` = '%s' AND `function` = '%s'",
dbesc($name),
dbesc($hook[0]),
dbesc($hook[1])
);
}
}
@include_once($hook[0]);
if (function_exists($hook[1])) {
$func = $hook[1];
$func($a, $data);
} else {
// remove orphan hooks
q("DELETE FROM `hook` WHERE `hook` = '%s' AND `file` = '%s' AND `function` = '%s'",
dbesc($name),
dbesc($hook[0]),
dbesc($hook[1])
);
}
}}
}
//check if an app_menu hook exist for plugin $name.
//Return true if the plugin is an app
@ -534,3 +538,41 @@ function upgrade_bool_message($bbcode = false) {
$x = upgrade_link($bbcode);
return t('This action is not available under your subscription plan.') . (($x) ? ' ' . $x : '') ;
}
/**
* @brief Get the full path to relevant theme files by filename
*
* This function search in the theme directory (and if not present in global theme directory)
* if there is a directory with the file extension and for a file with the given
* filename.
*
* @param string $file Filename
* @param string $root Full root path
* @return string Path to the file or empty string if the file isn't found
*/
function theme_include($file, $root = '') {
// Make sure $root ends with a slash / if it's not blank
if($root !== '' && $root[strlen($root)-1] !== '/')
$root = $root . '/';
$theme_info = $a->theme_info;
if(is_array($theme_info) AND array_key_exists('extends',$theme_info))
$parent = $theme_info['extends'];
else
$parent = 'NOPATH';
$theme = current_theme();
$thname = $theme;
$ext = substr($file,strrpos($file,'.')+1);
$paths = array(
"{$root}view/theme/$thname/$ext/$file",
"{$root}view/theme/$parent/$ext/$file",
"{$root}view/$ext/$file",
);
foreach($paths as $p) {
// strpos() is faster than strstr when checking if one string is in another (http://php.net/manual/en/function.strstr.php)
if(strpos($p,'NOPATH') !== false)
continue;
if(file_exists($p))
return $p;
}
return '';
}

View file

@ -10,6 +10,9 @@ if (!file_exists("boot.php") AND (sizeof($_SERVER["argv"]) != 0)) {
chdir($directory);
}
use \Friendica\Core\Config;
use \Friendica\Core\PConfig;
require_once("boot.php");
function poller_run(&$argv, &$argc){
@ -26,6 +29,13 @@ function poller_run(&$argv, &$argc){
unset($db_host, $db_user, $db_pass, $db_data);
};
$a->start_process();
$mypid = getmypid();
if ($a->max_processes_reached())
return;
if (poller_max_connections_reached())
return;
@ -33,17 +43,17 @@ function poller_run(&$argv, &$argc){
return;
// Checking the number of workers
if (poller_too_much_workers(1)) {
if (poller_too_much_workers()) {
poller_kill_stale_workers();
return;
}
if(($argc <= 1) OR ($argv[1] != "no_cron")) {
// Run the cron job that calls all other jobs
proc_run("php","include/cron.php");
proc_run(PRIORITY_MEDIUM, "include/cron.php");
// Run the cronhooks job separately from cron for being able to use a different timing
proc_run("php","include/cronhooks.php");
proc_run(PRIORITY_MEDIUM, "include/cronhooks.php");
// Cleaning dead processes
poller_kill_stale_workers();
@ -52,32 +62,42 @@ function poller_run(&$argv, &$argc){
sleep(4);
// Checking number of workers
if (poller_too_much_workers(2))
if (poller_too_much_workers())
return;
$cooldown = Config::get("system", "worker_cooldown", 0);
$starttime = time();
while ($r = q("SELECT * FROM `workerqueue` WHERE `executed` = '0000-00-00 00:00:00' ORDER BY `created` LIMIT 1")) {
while ($r = q("SELECT * FROM `workerqueue` WHERE `executed` = '0000-00-00 00:00:00' ORDER BY `priority`, `created` LIMIT 1")) {
// Constantly check the number of parallel database processes
if ($a->max_processes_reached())
return;
// Constantly check the number of available database connections to let the frontend be accessible at any time
if (poller_max_connections_reached())
return;
// Count active workers and compare them with a maximum value that depends on the load
if (poller_too_much_workers(3))
if (poller_too_much_workers())
return;
q("UPDATE `workerqueue` SET `executed` = '%s', `pid` = %d WHERE `id` = %d AND `executed` = '0000-00-00 00:00:00'",
dbesc(datetime_convert()),
intval(getmypid()),
intval($mypid),
intval($r[0]["id"]));
// Assure that there are no tasks executed twice
$id = q("SELECT `id` FROM `workerqueue` WHERE `id` = %d AND `pid` = %d",
intval($r[0]["id"]),
intval(getmypid()));
$id = q("SELECT `pid`, `executed` FROM `workerqueue` WHERE `id` = %d", intval($r[0]["id"]));
if (!$id) {
logger("Queue item ".$r[0]["id"]." was executed multiple times - skip this execution", LOGGER_DEBUG);
logger("Queue item ".$r[0]["id"]." vanished - skip this execution", LOGGER_DEBUG);
continue;
} elseif ((strtotime($id[0]["executed"]) <= 0) OR ($id[0]["pid"] == 0)) {
logger("Entry for queue item ".$r[0]["id"]." wasn't stored - we better stop here", LOGGER_DEBUG);
return;
} elseif ($id[0]["pid"] != $mypid) {
logger("Queue item ".$r[0]["id"]." is to be executed by process ".$id[0]["pid"]." and not by me (".$mypid.") - skip this execution", LOGGER_DEBUG);
continue;
}
@ -96,13 +116,18 @@ function poller_run(&$argv, &$argc){
require_once($include);
$funcname=str_replace(".php", "", basename($argv[0]))."_run";
$funcname = str_replace(".php", "", basename($argv[0]))."_run";
if (function_exists($funcname)) {
logger("Process ".getmypid()." - ID ".$r[0]["id"].": ".$funcname." ".$r[0]["parameter"]);
logger("Process ".$mypid." - Prio ".$r[0]["priority"]." - ID ".$r[0]["id"].": ".$funcname." ".$r[0]["parameter"]);
$funcname($argv, $argc);
logger("Process ".getmypid()." - ID ".$r[0]["id"].": ".$funcname." - done");
if ($cooldown > 0) {
logger("Process ".$mypid." - Prio ".$r[0]["priority"]." - ID ".$r[0]["id"].": ".$funcname." - in cooldown for ".$cooldown." seconds");
sleep($cooldown);
}
logger("Process ".$mypid." - Prio ".$r[0]["priority"]." - ID ".$r[0]["id"].": ".$funcname." - done");
q("DELETE FROM `workerqueue` WHERE `id` = %d", intval($r[0]["id"]));
} else
@ -200,9 +225,9 @@ function poller_max_connections_reached() {
*
*/
function poller_kill_stale_workers() {
$r = q("SELECT `pid`, `executed` FROM `workerqueue` WHERE `executed` != '0000-00-00 00:00:00'");
$r = q("SELECT `pid`, `executed`, `priority`, `parameter` FROM `workerqueue` WHERE `executed` != '0000-00-00 00:00:00'");
if (!dba::is_result($r)) {
if (!dbm::is_result($r)) {
// No processing here needed
return;
}
@ -213,27 +238,47 @@ function poller_kill_stale_workers() {
intval($pid["pid"]));
else {
// Kill long running processes
// Check if the priority is in a valid range
if (!in_array($pid["priority"], array(PRIORITY_CRITICAL, PRIORITY_HIGH, PRIORITY_MEDIUM, PRIORITY_LOW, PRIORITY_NEGLIGIBLE)))
$pid["priority"] = PRIORITY_MEDIUM;
// Define the maximum durations
$max_duration_defaults = array(PRIORITY_CRITICAL => 360, PRIORITY_HIGH => 10, PRIORITY_MEDIUM => 60, PRIORITY_LOW => 180, PRIORITY_NEGLIGIBLE => 360);
$max_duration = $max_duration_defaults[$pid["priority"]];
$argv = json_decode($pid["parameter"]);
$argv[0] = basename($argv[0]);
// How long is the process already running?
$duration = (time() - strtotime($pid["executed"])) / 60;
if ($duration > 180) {
logger("Worker process ".$pid["pid"]." took more than 3 hours. It will be killed now.");
if ($duration > $max_duration) {
logger("Worker process ".$pid["pid"]." (".implode(" ", $argv).") took more than ".$max_duration." minutes. It will be killed now.");
posix_kill($pid["pid"], SIGTERM);
// Question: If a process is stale: Should we remove it or should we reschedule it?
// By now we rescheduling it. It's maybe not the wisest decision?
q("UPDATE `workerqueue` SET `executed` = '0000-00-00 00:00:00', `pid` = 0 WHERE `pid` = %d",
// We killed the stale process.
// To avoid a blocking situation we reschedule the process at the beginning of the queue.
// Additionally we are lowering the priority.
q("UPDATE `workerqueue` SET `executed` = '0000-00-00 00:00:00', `created` = '%s',
`priority` = %d, `pid` = 0 WHERE `pid` = %d",
dbesc(datetime_convert()),
intval(PRIORITY_NEGLIGIBLE),
intval($pid["pid"]));
} else
logger("Worker process ".$pid["pid"]." now runs for ".round($duration)." minutes. That's okay.", LOGGER_DEBUG);
logger("Worker process ".$pid["pid"]." (".implode(" ", $argv).") now runs for ".round($duration)." of ".$max_duration." allowed minutes. That's okay.", LOGGER_DEBUG);
}
}
function poller_too_much_workers($stage) {
function poller_too_much_workers() {
$queues = get_config("system", "worker_queues");
if ($queues == 0)
$queues = 4;
$maxqueues = $queues;
$active = poller_active_workers();
// Decrease the number of workers at higher load
@ -250,21 +295,48 @@ function poller_too_much_workers($stage) {
$slope = $maxworkers / pow($maxsysload, $exponent);
$queues = ceil($slope * pow(max(0, $maxsysload - $load), $exponent));
logger("Current load stage ".$stage.": ".$load." - maximum: ".$maxsysload." - current queues: ".$active." - maximum: ".$queues, LOGGER_DEBUG);
$s = q("SELECT COUNT(*) AS `total` FROM `workerqueue` WHERE `executed` = '0000-00-00 00:00:00'");
$entries = $s[0]["total"];
if (Config::get("system", "worker_fastlane", false) AND ($queues > 0) AND ($entries > 0) AND ($active >= $queues)) {
$s = q("SELECT `priority` FROM `workerqueue` WHERE `executed` = '0000-00-00 00:00:00' ORDER BY `priority` LIMIT 1");
$top_priority = $s[0]["priority"];
$s = q("SELECT `id` FROM `workerqueue` WHERE `priority` <= %d AND `executed` != '0000-00-00 00:00:00' LIMIT 1",
intval($top_priority));
$high_running = dbm::is_result($s);
if (!$high_running AND ($top_priority > PRIORITY_UNDEFINED) AND ($top_priority < PRIORITY_NEGLIGIBLE)) {
logger("There are jobs with priority ".$top_priority." waiting but none is executed. Open a fastlane.", LOGGER_DEBUG);
$queues = $active + 1;
}
}
logger("Current load: ".$load." - maximum: ".$maxsysload." - current queues: ".$active."/".$entries." - maximum: ".$queues."/".$maxqueues, LOGGER_DEBUG);
// Are there fewer workers running as possible? Then fork a new one.
if (!get_config("system", "worker_dont_fork") AND ($queues > ($active + 1)) AND ($entries > 1)) {
logger("Active workers: ".$active."/".$queues." Fork a new worker.", LOGGER_DEBUG);
$args = array("php", "include/poller.php", "no_cron");
$a = get_app();
$a->proc_run($args);
}
}
return($active >= $queues);
}
function poller_active_workers() {
$workers = q("SELECT COUNT(*) AS `workers` FROM `workerqueue` WHERE `executed` != '0000-00-00 00:00:00'");
$workers = q("SELECT COUNT(*) AS `processes` FROM `process` WHERE `command` = 'poller.php'");
return($workers[0]["workers"]);
return($workers[0]["processes"]);
}
if (array_search(__file__,get_included_files())===0){
poller_run($_SERVER["argv"],$_SERVER["argc"]);
killme();
poller_run($_SERVER["argv"],$_SERVER["argc"]);
get_app()->end_process();
killme();
}
?>

View file

@ -13,6 +13,9 @@ function post_update() {
if (!post_update_1194())
return;
if (!post_update_1198())
return;
}
/**
@ -138,4 +141,78 @@ function post_update_1194() {
logger("Done", LOGGER_DEBUG);
}
/**
* @brief set the author-id and owner-id in all item entries
*
* This job has to be started multiple times until all entries are set.
* It isn't started in the update function since it would consume too much time and can be done in the background.
*
* @return bool "true" when the job is done
*/
function post_update_1198() {
// Was the script completed?
if (get_config("system", "post_update_version") >= 1198)
return true;
logger("Start", LOGGER_DEBUG);
// Check if the first step is done (Setting "author-id" and "owner-id" in the item table)
$r = q("SELECT `author-link`, `owner-link`, `uid` FROM `item` WHERE `author-id` = 0 AND `owner-id` = 0 LIMIT 100");
if (!$r) {
// Are there unfinished entries in the thread table?
$r = q("SELECT COUNT(*) AS `total` FROM `thread`
INNER JOIN `item` ON `item`.`id` =`thread`.`iid`
WHERE `thread`.`author-id` = 0 AND `thread`.`owner-id` = 0 AND
(`thread`.`uid` IN (SELECT `uid` from `user`) OR `thread`.`uid` = 0)");
if ($r AND ($r[0]["total"] == 0)) {
set_config("system", "post_update_version", 1198);
logger("Done", LOGGER_DEBUG);
return true;
}
// Update the thread table from the item table
q("UPDATE `thread` INNER JOIN `item` ON `item`.`id`=`thread`.`iid`
SET `thread`.`author-id` = `item`.`author-id`,
`thread`.`owner-id` = `item`.`owner-id`
WHERE `thread`.`author-id` = 0 AND `thread`.`owner-id` = 0 AND
(`thread`.`uid` IN (SELECT `uid` from `user`) OR `thread`.`uid` = 0)");
logger("Updated threads", LOGGER_DEBUG);
return false;
}
logger("Query done", LOGGER_DEBUG);
$item_arr = array();
foreach ($r AS $item) {
$index = $item["author-link"]."-".$item["owner-link"]."-".$item["uid"];
$item_arr[$index] = array("author-link" => $item["author-link"],
"owner-link" => $item["owner-link"],
"uid" => $item["uid"]);
}
// Set the "gcontact-id" in the item table and add a new gcontact entry if needed
foreach($item_arr AS $item) {
$author_id = get_contact($item["author-link"], 0);
$owner_id = get_contact($item["owner-link"], 0);
if ($author_id == 0)
$author_id = -1;
if ($owner_id == 0)
$owner_id = -1;
q("UPDATE `item` SET `author-id` = %d, `owner-id` = %d
WHERE `uid` = %d AND `author-link` = '%s' AND `owner-link` = '%s'
AND `author-id` = 0 AND `owner-id` = 0",
intval($author_id), intval($owner_id), intval($item["uid"]),
dbesc($item["author-link"]), dbesc($item["owner-link"]));
}
logger("Updated items", LOGGER_DEBUG);
return false;
}
?>

View file

@ -2,60 +2,57 @@
require_once("boot.php");
require_once("include/ostatus.php");
function handle_pubsubhubbub() {
use \Friendica\Core\Config;
use \Friendica\Core\PConfig;
function handle_pubsubhubbub($id) {
global $a, $db;
logger('start');
$r = q("SELECT * FROM `push_subscriber` WHERE `id` = %d", intval($id));
if (!$r)
return;
else
$rr = $r[0];
// We'll push to each subscriber that has push > 0,
// i.e. there has been an update (set in notifier.php).
logger("Generate feed of user ".$rr['nickname']." to ".$rr['callback_url']." - last updated ".$rr['last_update'], LOGGER_DEBUG);
$r = q("SELECT * FROM `push_subscriber` WHERE `push` > 0");
$params = ostatus::feed($a, $rr['nickname'], $rr['last_update']);
$hmac_sig = hash_hmac("sha1", $params, $rr['secret']);
foreach($r as $rr) {
$headers = array("Content-type: application/atom+xml",
sprintf("Link: <%s>;rel=hub,<%s>;rel=self",
$a->get_baseurl().'/pubsubhubbub',
$rr['topic']),
"X-Hub-Signature: sha1=".$hmac_sig);
logger("Generate feed for user ".$rr['nickname']." - last updated ".$rr['last_update'], LOGGER_DEBUG);
logger('POST '.print_r($headers, true)."\n".$params, LOGGER_DEBUG);
$params = ostatus::feed($a, $rr['nickname'], $rr['last_update']);
$hmac_sig = hash_hmac("sha1", $params, $rr['secret']);
post_url($rr['callback_url'], $params, $headers);
$ret = $a->get_curl_code();
$headers = array("Content-type: application/atom+xml",
sprintf("Link: <%s>;rel=hub,<%s>;rel=self",
$a->get_baseurl().'/pubsubhubbub',
$rr['topic']),
"X-Hub-Signature: sha1=".$hmac_sig);
if ($ret >= 200 && $ret <= 299) {
logger('successfully pushed to '.$rr['callback_url']);
logger('POST '.print_r($headers, true)."\n".$params, LOGGER_DEBUG);
// set last_update to "now", and reset push=0
$date_now = datetime_convert('UTC','UTC','now','Y-m-d H:i:s');
q("UPDATE `push_subscriber` SET `push` = 0, last_update = '%s' WHERE id = %d",
dbesc($date_now),
intval($rr['id']));
post_url($rr['callback_url'], $params, $headers);
$ret = $a->get_curl_code();
} else {
logger('error when pushing to '.$rr['callback_url'].' HTTP: '.$ret);
if ($ret >= 200 && $ret <= 299) {
logger('successfully pushed to '.$rr['callback_url']);
// we use the push variable also as a counter, if we failed we
// increment this until some upper limit where we give up
$new_push = intval($rr['push']) + 1;
// set last_update to "now", and reset push=0
$date_now = datetime_convert('UTC','UTC','now','Y-m-d H:i:s');
q("UPDATE `push_subscriber` SET `push` = 0, last_update = '%s' WHERE id = %d",
dbesc($date_now),
intval($rr['id']));
if ($new_push > 30) // OK, let's give up
$new_push = 0;
} else {
logger('error when pushing to '.$rr['callback_url'].' HTTP: '.$ret);
// we use the push variable also as a counter, if we failed we
// increment this until some upper limit where we give up
$new_push = intval($rr['push']) + 1;
if ($new_push > 30) // OK, let's give up
$new_push = 0;
q("UPDATE `push_subscriber` SET `push` = %d WHERE id = %d",
$new_push,
intval($rr['id']));
}
q("UPDATE `push_subscriber` SET `push` = %d WHERE id = %d",
$new_push,
intval($rr['id']));
}
logger('done');
}
@ -89,10 +86,28 @@ function pubsubpublish_run(&$argv, &$argc){
if($argc > 1)
$pubsubpublish_id = intval($argv[1]);
else
$pubsubpublish_id = 0;
else {
// We'll push to each subscriber that has push > 0,
// i.e. there has been an update (set in notifier.php).
$r = q("SELECT `id`, `callback_url` FROM `push_subscriber` WHERE `push` > 0");
handle_pubsubhubbub();
// Use the delivery interval that is also used for the notifier
$interval = Config::get("system", "delivery_interval", 2);
// If we are using the worker we don't need a delivery interval
if (get_config("system", "worker"))
$interval = false;
foreach($r as $rr) {
logger("Publish feed to ".$rr["callback_url"], LOGGER_DEBUG);
proc_run(PRIORITY_HIGH, 'include/pubsubpublish.php', $rr["id"]);
if($interval)
@time_sleep_until(microtime(true) + (float) $interval);
}
}
handle_pubsubhubbub($pubsubpublish_id);
return;

View file

@ -17,7 +17,6 @@ function queue_run(&$argv, &$argc){
unset($db_host, $db_user, $db_pass, $db_data);
};
require_once("include/session.php");
require_once("include/datetime.php");
require_once('include/items.php');
@ -45,55 +44,57 @@ function queue_run(&$argv, &$argc){
$deadservers = array();
$serverlist = array();
logger('queue: start');
if (!$queue_id) {
// Handling the pubsubhubbub requests
proc_run('php','include/pubsubpublish.php');
logger('queue: start');
$interval = ((get_config('system','delivery_interval') === false) ? 2 : intval(get_config('system','delivery_interval')));
// Handling the pubsubhubbub requests
proc_run(PRIORITY_HIGH,'include/pubsubpublish.php');
// If we are using the worker we don't need a delivery interval
if (get_config("system", "worker"))
$interval = false;
$interval = ((get_config('system','delivery_interval') === false) ? 2 : intval(get_config('system','delivery_interval')));
$r = q("select * from deliverq where 1");
if($r) {
foreach($r as $rr) {
logger('queue: deliverq');
proc_run('php','include/delivery.php',$rr['cmd'],$rr['item'],$rr['contact']);
if($interval)
// If we are using the worker we don't need a delivery interval
if (get_config("system", "worker"))
$interval = false;
$r = q("select * from deliverq where 1");
if($r) {
foreach($r as $rr) {
logger('queue: deliverq');
proc_run(PRIORITY_HIGH,'include/delivery.php',$rr['cmd'],$rr['item'],$rr['contact']);
if($interval)
@time_sleep_until(microtime(true) + (float) $interval);
}
}
}
$r = q("SELECT `queue`.*, `contact`.`name`, `contact`.`uid` FROM `queue`
INNER JOIN `contact` ON `queue`.`cid` = `contact`.`id`
WHERE `queue`.`created` < UTC_TIMESTAMP() - INTERVAL 3 DAY");
if($r) {
foreach($r as $rr) {
logger('Removing expired queue item for ' . $rr['name'] . ', uid=' . $rr['uid']);
logger('Expired queue data :' . $rr['content'], LOGGER_DATA);
$r = q("SELECT `queue`.*, `contact`.`name`, `contact`.`uid` FROM `queue`
INNER JOIN `contact` ON `queue`.`cid` = `contact`.`id`
WHERE `queue`.`created` < UTC_TIMESTAMP() - INTERVAL 3 DAY");
if($r) {
foreach($r as $rr) {
logger('Removing expired queue item for ' . $rr['name'] . ', uid=' . $rr['uid']);
logger('Expired queue data :' . $rr['content'], LOGGER_DATA);
}
q("DELETE FROM `queue` WHERE `created` < UTC_TIMESTAMP() - INTERVAL 3 DAY");
}
q("DELETE FROM `queue` WHERE `created` < UTC_TIMESTAMP() - INTERVAL 3 DAY");
}
if($queue_id) {
$r = q("SELECT `id` FROM `queue` WHERE `id` = %d LIMIT 1",
intval($queue_id)
);
}
else {
// For the first 12 hours we'll try to deliver every 15 minutes
// After that, we'll only attempt delivery once per hour.
$r = q("SELECT `id` FROM `queue` WHERE ((`created` > UTC_TIMESTAMP() - INTERVAL 12 HOUR && `last` < UTC_TIMESTAMP() - INTERVAL 15 MINUTE) OR (`last` < UTC_TIMESTAMP() - INTERVAL 1 HOUR)) ORDER BY `cid`, `created`");
} else {
logger('queue: start for id '.$queue_id);
$r = q("SELECT `id` FROM `queue` WHERE `id` = %d LIMIT 1",
intval($queue_id)
);
}
if(! $r){
if (!$r){
return;
}
if(! $queue_id)
if (!$queue_id)
call_hooks('queue_predeliver', $a, $r);
@ -107,16 +108,17 @@ function queue_run(&$argv, &$argc){
// queue_predeliver hooks may have changed the queue db details,
// so check again if this entry still needs processing
if($queue_id) {
if($queue_id)
$qi = q("SELECT * FROM `queue` WHERE `id` = %d LIMIT 1",
intval($queue_id)
);
}
else {
intval($queue_id));
elseif (get_config("system", "worker")) {
logger('Call queue for id '.$q_item['id']);
proc_run(PRIORITY_LOW, "include/queue.php", $q_item['id']);
continue;
} else
$qi = q("SELECT * FROM `queue` WHERE `id` = %d AND `last` < UTC_TIMESTAMP() - INTERVAL 15 MINUTE ",
intval($q_item['id'])
);
}
intval($q_item['id']));
if(! count($qi))
continue;

View file

@ -21,14 +21,14 @@ function was_recently_delayed($cid) {
and last > UTC_TIMESTAMP() - interval 15 minute limit 1",
intval($cid)
);
if(dba::is_result($r))
if(dbm::is_result($r))
return true;
$r = q("select `term-date` from contact where id = %d and `term-date` != '' and `term-date` != '0000-00-00 00:00:00' limit 1",
intval($cid)
);
return (dba::is_result($r));
return (dbm::is_result($r));
}

View file

@ -1,15 +1,14 @@
<?php
require_once('include/crypto.php');
require_once('include/Probe.php');
function get_salmon_key($uri,$keyhash) {
$ret = array();
logger('Fetching salmon key for '.$uri);
$arr = lrdd($uri);
$arr = Probe::lrdd($uri);
if(is_array($arr)) {
foreach($arr as $a) {

View file

@ -42,7 +42,7 @@ function authenticate_success($user_record, $login_initial = false, $interactive
$r = q("select * from user where uid = %d limit 1",
intval($_SESSION['submanage'])
);
if(dba::is_result($r))
if(dbm::is_result($r))
$master_record = $r[0];
}
@ -70,7 +70,7 @@ function authenticate_success($user_record, $login_initial = false, $interactive
$r = q("SELECT * FROM `contact` WHERE `uid` = %d AND `self` = 1 LIMIT 1",
intval($_SESSION['uid']));
if(dba::is_result($r)) {
if(dbm::is_result($r)) {
$a->contact = $r[0];
$a->cid = $r[0]['id'];
$_SESSION['cid'] = $a->cid;
@ -158,7 +158,7 @@ function can_write_wall(&$a,$owner) {
intval(PAGE_COMMUNITY)
);
if(dba::is_result($r)) {
if(dbm::is_result($r)) {
$verified = 2;
return true;
}
@ -212,7 +212,7 @@ function permissions_sql($owner_id,$remote_verified = false,$groups = null) {
intval($remote_user),
intval($owner_id)
);
if(dba::is_result($r)) {
if(dbm::is_result($r)) {
$remote_verified = true;
$groups = init_groups_visitor($remote_user);
}
@ -294,7 +294,7 @@ function item_permissions_sql($owner_id,$remote_verified = false,$groups = null)
intval($remote_user),
intval($owner_id)
);
if(dba::is_result($r)) {
if(dbm::is_result($r)) {
$remote_verified = true;
$groups = init_groups_visitor($remote_user);
}
@ -405,7 +405,7 @@ function init_groups_visitor($contact_id) {
WHERE `contact-id` = %d ",
intval($contact_id)
);
if(dba::is_result($r)) {
if(dbm::is_result($r)) {
foreach($r as $rr)
$groups[] = $rr['gid'];
}

View file

@ -17,7 +17,7 @@ function ref_session_read ($id) {
if(x($id))
$r = q("SELECT `data` FROM `session` WHERE `sid`= '%s'", dbesc($id));
if(dba::is_result($r)) {
if(dbm::is_result($r)) {
$session_exists = true;
return $r[0]['data'];
} else {

View file

@ -9,6 +9,7 @@
require_once('include/datetime.php');
require_once("include/Scrape.php");
require_once("include/network.php");
require_once("include/html2bbcode.php");
require_once("include/Contact.php");
require_once("include/Photo.php");
@ -39,7 +40,7 @@ function poco_load($cid,$uid = 0,$zcid = 0,$url = null) {
$r = q("select `poco`, `uid` from `contact` where `id` = %d limit 1",
intval($cid)
);
if(dba::is_result($r)) {
if(dbm::is_result($r)) {
$url = $r[0]['poco'];
$uid = $r[0]['uid'];
}
@ -205,14 +206,14 @@ function poco_check($profile_url, $name, $network, $profile_photo, $about, $loca
$r = q("SELECT `network` FROM `contact` WHERE `nurl` = '%s' AND `network` != '' AND `network` != '%s' LIMIT 1",
dbesc(normalise_link($profile_url)), dbesc(NETWORK_STATUSNET)
);
if(dba::is_result($r))
if(dbm::is_result($r))
$network = $r[0]["network"];
if (($network == "") OR ($network == NETWORK_OSTATUS)) {
$r = q("SELECT `network`, `url` FROM `contact` WHERE `alias` IN ('%s', '%s') AND `network` != '' AND `network` != '%s' LIMIT 1",
dbesc($profile_url), dbesc(normalise_link($profile_url)), dbesc(NETWORK_STATUSNET)
);
if(dba::is_result($r)) {
if(dbm::is_result($r)) {
$network = $r[0]["network"];
//$profile_url = $r[0]["url"];
}
@ -453,8 +454,11 @@ function poco_last_updated($profile, $force = false) {
"network" => $server[0]["network"],
"generation" => $gcontacts[0]["generation"]);
$contact["name"] = $noscrape["fn"];
$contact["community"] = $noscrape["comm"];
if (isset($noscrape["fn"]))
$contact["name"] = $noscrape["fn"];
if (isset($noscrape["comm"]))
$contact["community"] = $noscrape["comm"];
if (isset($noscrape["tags"])) {
$keywords = implode(" ", $noscrape["tags"]);
@ -466,7 +470,8 @@ function poco_last_updated($profile, $force = false) {
if ($location)
$contact["location"] = $location;
$contact["notify"] = $noscrape["dfrn-notify"];
if (isset($noscrape["dfrn-notify"]))
$contact["notify"] = $noscrape["dfrn-notify"];
// Remove all fields that are not present in the gcontact table
unset($noscrape["fn"]);
@ -948,7 +953,7 @@ function count_common_friends($uid,$cid) {
);
// logger("count_common_friends: $uid $cid {$r[0]['total']}");
if(dba::is_result($r))
if(dbm::is_result($r))
return $r[0]['total'];
return 0;
@ -994,7 +999,7 @@ function count_common_friends_zcid($uid,$zcid) {
intval($uid)
);
if(dba::is_result($r))
if(dbm::is_result($r))
return $r[0]['total'];
return 0;
@ -1033,7 +1038,7 @@ function count_all_friends($uid,$cid) {
intval($uid)
);
if(dba::is_result($r))
if(dbm::is_result($r))
return $r[0]['total'];
return 0;
@ -1162,7 +1167,7 @@ function update_suggestions() {
dbesc(NETWORK_DFRN), dbesc(NETWORK_DIASPORA)
);
if(dba::is_result($r)) {
if(dbm::is_result($r)) {
foreach($r as $rr) {
$base = substr($rr['poco'],0,strrpos($rr['poco'],'/'));
if(! in_array($base,$done))
@ -1391,23 +1396,23 @@ function poco_discover_server($data, $default_generation = 0) {
* @return string Contact url with the wanted parts
*/
function clean_contact_url($url) {
$parts = parse_url($url);
$parts = parse_url($url);
if (!isset($parts["scheme"]) OR !isset($parts["host"]))
return $url;
if (!isset($parts["scheme"]) OR !isset($parts["host"]))
return $url;
$new_url = $parts["scheme"]."://".$parts["host"];
$new_url = $parts["scheme"]."://".$parts["host"];
if (isset($parts["port"]))
$new_url .= ":".$parts["port"];
if (isset($parts["port"]))
$new_url .= ":".$parts["port"];
if (isset($parts["path"]))
$new_url .= $parts["path"];
if (isset($parts["path"]))
$new_url .= $parts["path"];
if ($new_url != $url)
logger("Cleaned contact url ".$url." to ".$new_url." - Called by: ".App::callstack(), LOGGER_DEBUG);
return $new_url;
return $new_url;
}
/**
@ -1417,7 +1422,7 @@ function clean_contact_url($url) {
*/
function fix_alternate_contact_address(&$contact) {
if (($contact["network"] == NETWORK_OSTATUS) AND poco_alternate_ostatus_url($contact["url"])) {
$data = probe_url($contact["url"]);
$data = probe_url($contact["url"]);
if ($contact["network"] == NETWORK_OSTATUS) {
logger("Fix primary url from ".$contact["url"]." to ".$data["url"]." - Called by: ".App::callstack(), LOGGER_DEBUG);
$contact["url"] = $data["url"];
@ -1447,6 +1452,10 @@ function get_gcontact_id($contact) {
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
fix_alternate_contact_address($contact);
@ -1469,8 +1478,8 @@ function get_gcontact_id($contact) {
$doprobing = (((time() - $last_contact) > (90 * 86400)) AND ((time() - $last_failure) > (90 * 86400)));
}
} else {
q("INSERT INTO `gcontact` (`name`, `nick`, `addr` , `network`, `url`, `nurl`, `photo`, `created`, `updated`, `location`, `about`, `generation`)
VALUES ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d)",
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"]),
@ -1482,6 +1491,7 @@ function get_gcontact_id($contact) {
dbesc(datetime_convert()),
dbesc($contact["location"]),
dbesc($contact["about"]),
intval($contact["hide"]),
intval($contact["generation"])
);
@ -1497,7 +1507,7 @@ function get_gcontact_id($contact) {
if ($doprobing) {
logger("Last Contact: ". $last_contact_str." - Last Failure: ".$last_failure_str." - Checking: ".$contact["url"], LOGGER_DEBUG);
proc_run('php', 'include/gprobe.php', bin2hex($contact["url"]));
proc_run(PRIORITY_LOW, 'include/gprobe.php', bin2hex($contact["url"]));
}
if ((count($r) > 1) AND ($gcontact_id > 0) AND ($contact["url"] != ""))
@ -1535,6 +1545,7 @@ function update_gcontact($contact) {
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.
@ -1549,6 +1560,11 @@ function update_gcontact($contact) {
if (!isset($contact[$field]) OR ($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;
@ -1657,6 +1673,44 @@ function update_gcontact_from_probe($url) {
update_gcontact($data);
}
/**
* @brief Update the gcontact entry for a given user id
*
* @param int $uid User ID
*/
function update_gcontact_for_user($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 = formatted_location(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://"), "", App::get_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"] OR !$r[0]["net-publish"]),
"nick" => $r[0]["nickname"], "addr" => $addr,
"connect" => $addr, "server_url" => App::get_baseurl(),
"generation" => 1, "network" => NETWORK_DFRN);
update_gcontact($gcontact);
}
/**
* @brief Fetches users of given GNU Social server
*

View file

@ -491,7 +491,7 @@ function item_new_uri($hostname,$uid, $guid = "") {
$r = q("SELECT `id` FROM `item` WHERE `uri` = '%s' LIMIT 1",
dbesc($uri));
if(dba::is_result($r))
if(dbm::is_result($r))
$dups = true;
} while($dups == true);
return $uri;
@ -515,7 +515,7 @@ function photo_new_resource() {
$r = q("SELECT `id` FROM `photo` WHERE `resource-id` = '%s' LIMIT 1",
dbesc($resource)
);
if(dba::is_result($r))
if(dbm::is_result($r))
$found = true;
} while($found == true);
return $resource;
@ -717,10 +717,15 @@ function logger($msg,$level = 0) {
if((! $debugging) || (! $logfile) || ($level > $loglevel))
return;
$process_id = session_id();
if ($process_id == "")
$process_id = get_app()->process_id;
$callers = debug_backtrace();
$logline = sprintf("%s@%s\t[%s]:%s:%s:%s\t%s\n",
datetime_convert(),
session_id(),
$process_id,
$LOGGER_LEVELS[$level],
basename($callers[0]['file']),
$callers[0]['line'],
@ -859,7 +864,7 @@ function contact_block() {
dbesc(NETWORK_OSTATUS),
dbesc(NETWORK_DIASPORA)
);
if(dba::is_result($r)) {
if(dbm::is_result($r)) {
$total = intval($r[0]['total']);
}
if(! $total) {
@ -867,7 +872,8 @@ function contact_block() {
$micropro = Null;
} else {
$r = q("SELECT `id`, `uid`, `addr`, `url`, `name`, `micro`, `network` FROM `contact`
// Splitting the query in two parts makes it much faster
$r = q("SELECT `id` FROM `contact`
WHERE `uid` = %d AND NOT `self` AND NOT `blocked` AND NOT `pending`
AND NOT `hidden` AND NOT `archive`
AND `network` IN ('%s', '%s', '%s') ORDER BY RAND() LIMIT %d",
@ -877,11 +883,20 @@ function contact_block() {
dbesc(NETWORK_DIASPORA),
intval($shown)
);
if(dba::is_result($r)) {
$contacts = sprintf( tt('%d Contact','%d Contacts', $total),$total);
$micropro = Array();
foreach($r as $rr) {
$micropro[] = micropro($rr,true,'mpfriend');
if(dbm::is_result($r)) {
$contacts = "";
foreach ($r AS $contact)
$contacts[] = $contact["id"];
$r = q("SELECT `id`, `uid`, `addr`, `url`, `name`, `thumb`, `network` FROM `contact` WHERE `id` IN (%s)",
dbesc(implode(",", $contacts)));
if(dbm::is_result($r)) {
$contacts = sprintf( tt('%d Contact','%d Contacts', $total),$total);
$micropro = Array();
foreach($r as $rr) {
$micropro[] = micropro($rr,true,'mpfriend');
}
}
}
}
@ -901,20 +916,28 @@ function contact_block() {
}}
if(! function_exists('micropro')) {
/**
* @brief Format contacts as picture links or as texxt links
*
* @param array $contact
* @param boolean $redirect
* @param string $class
* @param boolean $textmode
* @return string #FIXME: remove html
* @param array $contact Array with contacts which contains an array with
* int 'id' => The ID of the contact
* int 'uid' => The user ID of the user who owns this data
* string 'name' => The name of the contact
* string 'url' => The url to the profile page of the contact
* string 'addr' => The webbie of the contact (e.g.) username@friendica.com
* string 'network' => The network to which the contact belongs to
* string 'thumb' => The contact picture
* string 'click' => js code which is performed when clicking on the contact
* @param boolean $redirect If true try to use the redir url if it's possible
* @param string $class CSS class for the
* @param boolean $textmode If true display the contacts as text links
* if false display the contacts as picture links
* @return string Formatted html
*/
function micropro($contact, $redirect = false, $class = '', $textmode = false) {
if($class)
$class = ' ' . $class;
// Use the contact URL if no address is available
if ($contact["addr"] == "")
$contact["addr"] = $contact["url"];
@ -933,26 +956,23 @@ function micropro($contact, $redirect = false, $class = '', $textmode = false) {
else
$url = zrl($url);
}
$click = ((x($contact,'click')) ? ' onclick="' . $contact['click'] . '" ' : '');
if($click)
// If there is some js available we don't need the url
if(x($contact,'click'))
$url = '';
if($textmode) {
return '<div class="contact-block-textdiv' . $class . '"><a class="contact-block-link' . $class . $sparkle
. (($click) ? ' fakelink' : '') . '" '
. (($redir) ? ' target="redir" ' : '')
. (($url) ? ' href="' . $url . '"' : '') . $click
. '" title="' . $contact['name'] . ' [' . $contact['addr'] . ']" alt="' . $contact['name']
. '" >'. $contact['name'] . '</a></div>' . "\r\n";
}
else {
return '<div class="contact-block-div' . $class . '"><a class="contact-block-link' . $class . $sparkle
. (($click) ? ' fakelink' : '') . '" '
. (($redir) ? ' target="redir" ' : '')
. (($url) ? ' href="' . $url . '"' : '') . $click . ' ><img class="contact-block-img' . $class . $sparkle . '" src="'
. proxy_url($contact['micro'], false, PROXY_SIZE_THUMB) . '" title="' . $contact['name'] . ' [' . $contact['addr'] . ']" alt="' . $contact['name']
. '" /></a></div>' . "\r\n";
}
}}
return replace_macros(get_markup_template(($textmode)?'micropro_txt.tpl':'micropro_img.tpl'),array(
'$click' => (($contact['click']) ? $contact['click'] : ''),
'$class' => $class,
'$url' => $url,
'$photo' => proxy_url($contact['thumb'], false, PROXY_SIZE_THUMB),
'$name' => $contact['name'],
'title' => $contact['name'] . ' [' . $contact['addr'] . ']',
'$parkle' => $sparkle,
'$redir' => $redir,
));
}
@ -975,6 +995,7 @@ function search($s,$id='search-box',$url='search',$save = false, $aside = true)
'$search_label' => t('Search'),
'$save_label' => t('Save'),
'$savedsearch' => feature_enabled(local_user(),'savedsearch'),
'$search_hint' => t('@name, !forum, #tags, content'),
);
if (!$aside) {
@ -1080,159 +1101,6 @@ function get_mood_verbs() {
return $arr;
}
if(! function_exists('smilies')) {
/**
* Replaces text emoticons with graphical images
*
* It is expected that this function will be called using HTML text.
* We will escape text between HTML pre and code blocks from being
* processed.
*
* At a higher level, the bbcode [nosmile] tag can be used to prevent this
* function from being executed by the prepare_text() routine when preparing
* bbcode source for HTML display
*
* @param string $s
* @param boolean $sample
* @return string
* @hook smilie ('texts' => smilies texts array, 'icons' => smilies html array, 'string' => $s)
*/
function smilies($s, $sample = false) {
$a = get_app();
if(intval(get_config('system','no_smilies'))
|| (local_user() && intval(get_pconfig(local_user(),'system','no_smilies'))))
return $s;
$s = preg_replace_callback('/<pre>(.*?)<\/pre>/ism','smile_encode',$s);
$s = preg_replace_callback('/<code>(.*?)<\/code>/ism','smile_encode',$s);
$texts = array(
'&lt;3',
'&lt;/3',
'&lt;\\3',
':-)',
';-)',
':-(',
':-P',
':-p',
':-"',
':-&quot;',
':-x',
':-X',
':-D',
'8-|',
'8-O',
':-O',
'\\o/',
'o.O',
'O.o',
'o_O',
'O_o',
":'(",
":-!",
":-/",
":-[",
"8-)",
':beer',
':homebrew',
':coffee',
':facepalm',
':like',
':dislike',
'~friendica',
'red#',
'red#matrix'
);
$icons = array(
'<img class="smiley" src="' . z_root() . '/images/smiley-heart.gif" alt="&lt;3" title="&lt;3" />',
'<img class="smiley" src="' . z_root() . '/images/smiley-brokenheart.gif" alt="&lt;/3" title="&lt;/3" />',
'<img class="smiley" src="' . z_root() . '/images/smiley-brokenheart.gif" alt="&lt;\\3" title="&lt;\\3" />',
'<img class="smiley" src="' . z_root() . '/images/smiley-smile.gif" alt=":-)" title=":-)" />',
'<img class="smiley" src="' . z_root() . '/images/smiley-wink.gif" alt=";-)" title=";-)" />',
'<img class="smiley" src="' . z_root() . '/images/smiley-frown.gif" alt=":-(" title=":-(" />',
'<img class="smiley" src="' . z_root() . '/images/smiley-tongue-out.gif" alt=":-P" title=":-P" />',
'<img class="smiley" src="' . z_root() . '/images/smiley-tongue-out.gif" alt=":-p" title=":-P" />',
'<img class="smiley" src="' . z_root() . '/images/smiley-kiss.gif" alt=":-\" title=":-\" />',
'<img class="smiley" src="' . z_root() . '/images/smiley-kiss.gif" alt=":-\" title=":-\" />',
'<img class="smiley" src="' . z_root() . '/images/smiley-kiss.gif" alt=":-x" title=":-x" />',
'<img class="smiley" src="' . z_root() . '/images/smiley-kiss.gif" alt=":-X" title=":-X" />',
'<img class="smiley" src="' . z_root() . '/images/smiley-laughing.gif" alt=":-D" title=":-D" />',
'<img class="smiley" src="' . z_root() . '/images/smiley-surprised.gif" alt="8-|" title="8-|" />',
'<img class="smiley" src="' . z_root() . '/images/smiley-surprised.gif" alt="8-O" title="8-O" />',
'<img class="smiley" src="' . z_root() . '/images/smiley-surprised.gif" alt=":-O" title="8-O" />',
'<img class="smiley" src="' . z_root() . '/images/smiley-thumbsup.gif" alt="\\o/" title="\\o/" />',
'<img class="smiley" src="' . z_root() . '/images/smiley-Oo.gif" alt="o.O" title="o.O" />',
'<img class="smiley" src="' . z_root() . '/images/smiley-Oo.gif" alt="O.o" title="O.o" />',
'<img class="smiley" src="' . z_root() . '/images/smiley-Oo.gif" alt="o_O" title="o_O" />',
'<img class="smiley" src="' . z_root() . '/images/smiley-Oo.gif" alt="O_o" title="O_o" />',
'<img class="smiley" src="' . z_root() . '/images/smiley-cry.gif" alt=":\'(" title=":\'("/>',
'<img class="smiley" src="' . z_root() . '/images/smiley-foot-in-mouth.gif" alt=":-!" title=":-!" />',
'<img class="smiley" src="' . z_root() . '/images/smiley-undecided.gif" alt=":-/" title=":-/" />',
'<img class="smiley" src="' . z_root() . '/images/smiley-embarassed.gif" alt=":-[" title=":-[" />',
'<img class="smiley" src="' . z_root() . '/images/smiley-cool.gif" alt="8-)" title="8-)" />',
'<img class="smiley" src="' . z_root() . '/images/beer_mug.gif" alt=":beer" title=":beer" />',
'<img class="smiley" src="' . z_root() . '/images/beer_mug.gif" alt=":homebrew" title=":homebrew" />',
'<img class="smiley" src="' . z_root() . '/images/coffee.gif" alt=":coffee" title=":coffee" />',
'<img class="smiley" src="' . z_root() . '/images/smiley-facepalm.gif" alt=":facepalm" title=":facepalm" />',
'<img class="smiley" src="' . z_root() . '/images/like.gif" alt=":like" title=":like" />',
'<img class="smiley" src="' . z_root() . '/images/dislike.gif" alt=":dislike" title=":dislike" />',
'<a href="http://friendica.com">~friendica <img class="smiley" src="' . z_root() . '/images/friendica-16.png" alt="~friendica" title="~friendica" /></a>',
'<a href="http://redmatrix.me/">red<img class="smiley" src="' . z_root() . '/images/rm-16.png" alt="red#" title="red#" />matrix</a>',
'<a href="http://redmatrix.me/">red<img class="smiley" src="' . z_root() . '/images/rm-16.png" alt="red#matrix" title="red#matrix" />matrix</a>'
);
$params = array('texts' => $texts, 'icons' => $icons, 'string' => $s);
call_hooks('smilie', $params);
if($sample) {
$s = '<div class="smiley-sample">';
for($x = 0; $x < count($params['texts']); $x ++) {
$s .= '<dl><dt>' . $params['texts'][$x] . '</dt><dd>' . $params['icons'][$x] . '</dd></dl>';
}
}
else {
$params['string'] = preg_replace_callback('/&lt;(3+)/','preg_heart',$params['string']);
$s = str_replace($params['texts'],$params['icons'],$params['string']);
}
$s = preg_replace_callback('/<pre>(.*?)<\/pre>/ism','smile_decode',$s);
$s = preg_replace_callback('/<code>(.*?)<\/code>/ism','smile_decode',$s);
return $s;
}}
function smile_encode($m) {
return(str_replace($m[1],base64url_encode($m[1]),$m[0]));
}
function smile_decode($m) {
return(str_replace($m[1],base64url_decode($m[1]),$m[0]));
}
/**
* expand <3333 to the correct number of hearts
*
* @param string $x
* @return string
*/
function preg_heart($x) {
$a = get_app();
if(strlen($x[1]) == 1)
return $x[0];
$t = '';
for($cnt = 0; $cnt < strlen($x[1]); $cnt ++)
$t .= '<img class="smiley" src="' . z_root() . '/images/smiley-heart.gif" alt="&lt;3" />';
$r = str_replace($x[0],$t,$x[0]);
return $r;
}
if(! function_exists('day_translate')) {
/**
* Translate days and months names
@ -2050,7 +1918,7 @@ function file_tag_update_pconfig($uid,$file_old,$file_new,$type = 'file') {
// intval($uid)
//);
if(dba::is_result($r)) {
if(dbm::is_result($r)) {
unset($deleted_tags[$key]);
}
else {
@ -2080,7 +1948,7 @@ function file_tag_save_file($uid,$item,$file) {
intval($item),
intval($uid)
);
if(dba::is_result($r)) {
if(dbm::is_result($r)) {
if(! stristr($r[0]['file'],'[' . file_tag_encode($file) . ']'))
q("UPDATE `item` SET `file` = '%s' WHERE `id` = %d AND `uid` = %d",
dbesc($r[0]['file'] . '[' . file_tag_encode($file) . ']'),
@ -2239,3 +2107,54 @@ function format_network_name($network, $url = 0) {
}
}
/**
* @brief Syntax based code highlighting for popular languages.
* @param string $s Code block
* @param string $lang Programming language
* @return string Formated html
*/
function text_highlight($s,$lang) {
if($lang === 'js')
$lang = 'javascript';
if(! strpos('Text_Highlighter',get_include_path())) {
set_include_path(get_include_path() . PATH_SEPARATOR . 'library/Text_Highlighter');
}
require_once('library/Text_Highlighter/Text/Highlighter.php');
require_once('library/Text_Highlighter/Text/Highlighter/Renderer/Html.php');
$options = array(
'numbers' => HL_NUMBERS_LI,
'tabsize' => 4,
);
$tag_added = false;
$s = trim(html_entity_decode($s,ENT_COMPAT));
$s = str_replace(" ","\t",$s);
// The highlighter library insists on an opening php tag for php code blocks. If
// it isn't present, nothing is highlighted. So we're going to see if it's present.
// If not, we'll add it, and then quietly remove it after we get the processed output back.
if($lang === 'php') {
if(strpos('<?php',$s) !== 0) {
$s = '<?php' . "\n" . $s;
$tag_added = true;
}
}
$renderer = new Text_Highlighter_Renderer_HTML($options);
$hl = Text_Highlighter::factory($lang);
$hl->setRenderer($renderer);
$o = $hl->highlight($s);
$o = str_replace([" ","\n"],["&nbsp;&nbsp;&nbsp;&nbsp;",''],$o);
if($tag_added) {
$b = substr($o,0,strpos($o,'<li>'));
$e = substr($o,strpos($o,'</li>'));
$o = $b . $e;
}
return('<code>' . $o . '</code>');
}

View file

@ -1,7 +1,9 @@
<?php
function add_thread($itemid, $onlyshadow = false) {
$items = q("SELECT `uid`, `created`, `edited`, `commented`, `received`, `changed`, `wall`, `private`, `pubmail`, `moderated`, `visible`, `spam`, `starred`, `bookmark`, `contact-id`, `gcontact-id`,
`deleted`, `origin`, `forum_mode`, `mention`, `network` FROM `item` WHERE `id` = %d AND (`parent` = %d OR `parent` = 0) LIMIT 1", intval($itemid), intval($itemid));
$items = q("SELECT `uid`, `created`, `edited`, `commented`, `received`, `changed`, `wall`, `private`, `pubmail`,
`moderated`, `visible`, `spam`, `starred`, `bookmark`, `contact-id`, `gcontact-id`,
`deleted`, `origin`, `forum_mode`, `mention`, `network`, `author-id`, `owner-id`
FROM `item` WHERE `id` = %d AND (`parent` = %d OR `parent` = 0) LIMIT 1", intval($itemid), intval($itemid));
if (!$items)
return;
@ -83,12 +85,12 @@ function add_shadow_entry($item) {
// Is there a shadow parent?
$r = q("SELECT `id` FROM `item` WHERE `uri` = '%s' AND `uid` = 0 LIMIT 1", dbesc($item['parent-uri']));
if (!count($r))
if (!dbm::is_result($r))
return;
// Is there already a shadow entry?
$r = q("SELECT `id` FROM `item` WHERE `uri` = '%s' AND `uid` = 0 LIMIT 1", dbesc($item['uri']));
if (dba::is_result($r))
if (dbm::is_result($r))
return;
// Preparing public shadow (removing user specific data)
@ -106,7 +108,7 @@ function add_shadow_entry($item) {
function update_thread_uri($itemuri, $uid) {
$messages = q("SELECT `id` FROM `item` WHERE uri ='%s' AND uid=%d", dbesc($itemuri), intval($uid));
if(count($messages))
if(dbm::is_result($messages))
foreach ($messages as $message)
update_thread($message["id"]);
}
@ -115,7 +117,7 @@ function update_thread($itemid, $setmention = false) {
$items = q("SELECT `uid`, `guid`, `title`, `body`, `created`, `edited`, `commented`, `received`, `changed`, `wall`, `private`, `pubmail`, `moderated`, `visible`, `spam`, `starred`, `bookmark`, `contact-id`, `gcontact-id`,
`deleted`, `origin`, `forum_mode`, `network`, `rendered-html`, `rendered-hash` FROM `item` WHERE `id` = %d AND (`parent` = %d OR `parent` = 0) LIMIT 1", intval($itemid), intval($itemid));
if (!$items)
if (!dbm::is_result($items))
return;
$item = $items[0];
@ -174,7 +176,7 @@ function delete_thread($itemid, $itemuri = "") {
intval($item["uid"])
);
if (!count($r)) {
$r = q("DELETE FROM `item` WHERE `uri` = '%s' AND `uid` = 0)",
$r = q("DELETE FROM `item` WHERE `uri` = '%s' AND `uid` = 0",
dbesc($itemuri)
);
logger("delete_thread: Deleted shadow for item ".$itemuri." - ".print_r($result, true), LOGGER_DEBUG);

View file

@ -287,7 +287,7 @@ function import_account(&$a, $file) {
}
// send relocate messages
proc_run('php', 'include/notifier.php', 'relocate', $newuid);
proc_run(PRIORITY_HIGH, 'include/notifier.php', 'relocate', $newuid);
info(t("Done. You can now login with your username and password"));
goaway($a->get_baseurl() . "/login");

View file

@ -130,7 +130,7 @@ function create_user($arr) {
$r = q("SELECT * FROM `user` WHERE `email` = '%s' LIMIT 1",
dbesc($email)
);
if(dba::is_result($r))
if(dbm::is_result($r))
$result['message'] .= t('Cannot use that email.') . EOL;
}
@ -143,7 +143,7 @@ function create_user($arr) {
WHERE `nickname` = '%s' LIMIT 1",
dbesc($nickname)
);
if(dba::is_result($r))
if(dbm::is_result($r))
$result['message'] .= t('Nickname is already registered. Please choose another.') . EOL;
// Check deleted accounts that had this nickname. Doesn't matter to us,
@ -153,7 +153,7 @@ function create_user($arr) {
WHERE `username` = '%s' LIMIT 1",
dbesc($nickname)
);
if(dba::is_result($r))
if(dbm::is_result($r))
$result['message'] .= t('Nickname was once registered here and may not be re-used. Please choose another.') . EOL;
if(strlen($result['message'])) {

View file

@ -27,8 +27,11 @@ class xml {
foreach ($namespaces AS $nskey => $nsvalue)
$key .= " xmlns".($nskey == "" ? "":":").$nskey.'="'.$nsvalue.'"';
$root = new SimpleXMLElement("<".$key."/>");
self::from_array($value, $root, $remove_header, $namespaces, false);
if (is_array($value)) {
$root = new SimpleXMLElement("<".$key."/>");
self::from_array($value, $root, $remove_header, $namespaces, false);
} else
$root = new SimpleXMLElement("<".$key.">".xmlify($value)."</".$key.">");
$dom = dom_import_simplexml($root)->ownerDocument;
$dom->formatOutput = true;
@ -44,7 +47,33 @@ class xml {
}
foreach($array as $key => $value) {
if ($key == "@attributes") {
if (!isset($element) AND isset($xml))
$element = $xml;
if (is_integer($key)) {
if (isset($element)) {
if (is_scalar($value)) {
$element[0] = $value;
} else {
/// @todo: handle nested array values
}
}
continue;
}
$element_parts = explode(":", $key);
if ((count($element_parts) > 1) AND isset($namespaces[$element_parts[0]]))
$namespace = $namespaces[$element_parts[0]];
elseif (isset($namespaces[""])) {
$namespace = $namespaces[""];
} else
$namespace = NULL;
// Remove undefined namespaces from the key
if ((count($element_parts) > 1) AND is_null($namespace))
$key = $element_parts[1];
if (substr($key, 0, 11) == "@attributes") {
if (!isset($element) OR !is_array($value))
continue;
@ -55,18 +84,12 @@ class xml {
else
$namespace = NULL;
$element->addAttribute ($attr_key, $attr_value, $namespace);
$element->addAttribute($attr_key, $attr_value, $namespace);
}
continue;
}
$element_parts = explode(":", $key);
if ((count($element_parts) > 1) AND isset($namespaces[$element_parts[0]]))
$namespace = $namespaces[$element_parts[0]];
else
$namespace = NULL;
if (!is_array($value))
$element = $xml->addChild($key, xmlify($value), $namespace);
elseif (is_array($value)) {
@ -131,11 +154,11 @@ class xml {
/**
* @brief Convert an XML document to a normalised, case-corrected array
* used by webfinger
*
*
* @param object $xml_element The XML document
* @param integer $recursion_depth recursion counter for internal use - default 0
* @param integer $recursion_depth recursion counter for internal use - default 0
* internal use, recursion counter
*
*
* @return array | sring The array from the xml element or the string
*/
public static function element_to_array($xml_element, &$recursion_depth=0) {
@ -181,23 +204,23 @@ class xml {
/**
* @brief Convert the given XML text to an array in the XML structure.
*
*
* xml::to_array() will convert the given XML text to an array in the XML structure.
* Link: http://www.bin-co.com/php/scripts/xml2array/
* Portions significantly re-written by mike@macgirvin.com for Friendica
* (namespaces, lowercase tags, get_attribute default changed, more...)
*
*
* Examples: $array = xml::to_array(file_get_contents('feed.xml'));
* $array = xml::to_array(file_get_contents('feed.xml', true, 1, 'attribute'));
*
*
* @param object $contents The XML text
* @param boolean $namespaces True or false include namespace information
* in the returned array as array elements.
* @param integer $get_attributes 1 or 0. If this is 1 the function will get the attributes as well as the tag values -
* @param integer $get_attributes 1 or 0. If this is 1 the function will get the attributes as well as the tag values -
* this results in a different array structure in the return value.
* @param string $priority Can be 'tag' or 'attribute'. This will change the way the resulting
* array sturcture. For 'tag', the tags are given more importance.
*
*
* @return array The parsed XML in an array form. Use print_r() to see the resulting array structure.
*/
public static function to_array($contents, $namespaces = true, $get_attributes=1, $priority = 'attribute') {