aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/Contact.php60
-rw-r--r--include/Scrape.php2
-rw-r--r--include/acl_selectors.php4
-rw-r--r--include/api.php13
-rw-r--r--include/bbcode.php3
-rw-r--r--include/cache.php42
-rw-r--r--include/contact_widgets.php57
-rw-r--r--include/conversation.php17
-rw-r--r--include/dba.php28
-rw-r--r--include/delivery.php740
-rw-r--r--include/diaspora.php40
-rw-r--r--include/enotify.php4
-rw-r--r--include/expire.php6
-rw-r--r--include/gprobe.php65
-rw-r--r--include/group.php31
-rw-r--r--include/html2plain.php2
-rw-r--r--include/items.php141
-rw-r--r--include/network.php170
-rw-r--r--include/notifier.php26
-rw-r--r--include/onepoll.php523
-rw-r--r--include/pgettext.php6
-rw-r--r--include/plugin.php23
-rw-r--r--include/poller.php452
-rw-r--r--include/profile_selectors.php18
-rw-r--r--include/queue_fn.php11
-rwxr-xr-xinclude/security.php2
-rw-r--r--include/socgraph.php91
-rw-r--r--include/text.php24
28 files changed, 1664 insertions, 937 deletions
diff --git a/include/Contact.php b/include/Contact.php
index 9ba1e8ae5..675d1c81e 100644
--- a/include/Contact.php
+++ b/include/Contact.php
@@ -51,6 +51,21 @@ function user_remove($uid) {
function contact_remove($id) {
+
+ $r = q("select uid from contact where id = %d limit 1",
+ intval($id)
+ );
+ if((! count($r)) || (! intval($r[0]['uid'])))
+ return;
+
+ $archive = get_pconfig($r[0]['uid'], 'system','archive_removed_contacts');
+ if($archive) {
+ q("update contact set `archive` = 1, `network` = 'none', `writable` = 0 where id = %d limit 1",
+ intval($id)
+ );
+ return;
+ }
+
q("DELETE FROM `contact` WHERE `id` = %d LIMIT 1",
intval($id)
);
@@ -73,6 +88,49 @@ function contact_remove($id) {
}
+// sends an unfriend message. Does not remove the contact
+
+function terminate_friendship($user,$self,$contact) {
+
+
+ $a = get_app();
+
+ require_once('include/datetime.php');
+
+ if($contact['network'] === NETWORK_OSTATUS) {
+
+ $slap = replace_macros(get_markup_template('follow_slap.tpl'), array(
+ '$name' => $user['username'],
+ '$profile_page' => $a->get_baseurl() . '/profile/' . $user['nickname'],
+ '$photo' => $self['photo'],
+ '$thumb' => $self['thumb'],
+ '$published' => datetime_convert('UTC','UTC', 'now', ATOM_TIME),
+ '$item_id' => 'urn:X-dfrn:' . $a->get_hostname() . ':unfollow:' . random_string(),
+ '$title' => '',
+ '$type' => 'text',
+ '$content' => t('stopped following'),
+ '$nick' => $user['nickname'],
+ '$verb' => 'http://ostatus.org/schema/1.0/unfollow', // ACTIVITY_UNFOLLOW,
+ '$ostat_follow' => '' // '<as:verb>http://ostatus.org/schema/1.0/unfollow</as:verb>' . "\r\n"
+ ));
+
+ if((x($contact,'notify')) && (strlen($contact['notify']))) {
+ require_once('include/salmon.php');
+ slapper($user,$contact['notify'],$slap);
+ }
+ }
+ elseif($contact['network'] === NETWORK_DIASPORA) {
+ require_once('include/diaspora.php');
+ diaspora_unshare($user,$contact);
+ }
+ elseif($contact['network'] === NETWORK_DFRN) {
+ require_once('include/items.php');
+ dfrn_deliver($user,$contact,'placeholder', 1);
+ }
+
+}
+
+
// Contact has refused to recognise us as a friend. We will start a countdown.
// If they still don't recognise us in 32 days, the relationship is over,
// and we won't waste any more time trying to communicate with them.
@@ -151,7 +209,7 @@ function contact_photo_menu($contact) {
);
- $args = array('contact' => $contact, 'menu' => $menu);
+ $args = array('contact' => $contact, 'menu' => &$menu);
call_hooks('contact_photo_menu', $args);
diff --git a/include/Scrape.php b/include/Scrape.php
index b20d7d604..227252600 100644
--- a/include/Scrape.php
+++ b/include/Scrape.php
@@ -282,7 +282,7 @@ function scrape_feed($url) {
}
}
if(! $basename)
- $basename = substr($url,0,strrpos($url,'/')) . '/';
+ $basename = implode('/', array_slice(explode('/',$url),0,3)) . '/';
$items = $dom->getElementsByTagName('link');
diff --git a/include/acl_selectors.php b/include/acl_selectors.php
index a5f5aff53..461ad0c36 100644
--- a/include/acl_selectors.php
+++ b/include/acl_selectors.php
@@ -122,7 +122,7 @@ function contact_selector($selname, $selclass, $preselected = false, $options) {
$o .= "<select name=\"{$selname}[]\" id=\"$selclass\" class=\"$selclass\" multiple=\"multiple\" size=\"" . $x['size'] . "$\" $tabindex >\r\n";
$r = q("SELECT `id`, `name`, `url`, `network` FROM `contact`
- WHERE `uid` = %d AND `self` = 0 AND `blocked` = 0 AND `pending` = 0 AND `notify` != ''
+ WHERE `uid` = %d AND `self` = 0 AND `blocked` = 0 AND `pending` = 0 AND `archive` = 0 AND `notify` != ''
$sql_extra
ORDER BY `name` ASC ",
intval(local_user())
@@ -188,7 +188,7 @@ function contact_select($selname, $selclass, $preselected = false, $size = 4, $p
$o .= "<select name=\"{$selname}[]\" id=\"$selclass\" class=\"$selclass\" multiple=\"multiple\" size=\"$size\" $tabindex >\r\n";
$r = q("SELECT `id`, `name`, `url`, `network` FROM `contact`
- WHERE `uid` = %d AND `self` = 0 AND `blocked` = 0 AND `pending` = 0 AND `notify` != ''
+ WHERE `uid` = %d AND `self` = 0 AND `blocked` = 0 AND `pending` = 0 AND `archive` = 0 AND `notify` != ''
$sql_extra
ORDER BY `name` ASC ",
intval(local_user())
diff --git a/include/api.php b/include/api.php
index 11494ba27..f58a91a72 100644
--- a/include/api.php
+++ b/include/api.php
@@ -380,7 +380,7 @@
$nick = $name;
// Generating a random ID
- if (!array_key_exists($nick, $usercache))
+ if (is_null($usercache[$nick]) or !array_key_exists($nick, $usercache))
$usercache[$nick] = mt_rand(2000000, 2100000);
$ret = array(
@@ -567,8 +567,17 @@
$_REQUEST['profile_uid'] = local_user();
if(requestdata('parent'))
$_REQUEST['type'] = 'net-comment';
- else
+ else {
$_REQUEST['type'] = 'wall';
+ if(x($_FILES,'media')) {
+ // upload the image if we have one
+ $_REQUEST['hush']='yeah'; //tell wall_upload function to return img info instead of echo
+ require_once('mod/wall_upload.php');
+ $media = wall_upload_post($a);
+ if(strlen($media)>0)
+ $_REQUEST['body'] .= "\n\n".$media;
+ }
+ }
// set this so that the item_post() function is quiet and doesn't redirect or emit json
diff --git a/include/bbcode.php b/include/bbcode.php
index 3697f1fc5..85d310b75 100644
--- a/include/bbcode.php
+++ b/include/bbcode.php
@@ -298,6 +298,9 @@ function bbcode($Text,$preserve_nl = false) {
$Text = preg_replace_callback("/\[nobb\](.*?)\[\/nobb\]/ism", 'bb_unspacefy_and_trim',$Text);
$Text = preg_replace_callback("/\[pre\](.*?)\[\/pre\]/ism", 'bb_unspacefy_and_trim',$Text);
+
+ $Text = preg_replace('/\[\&amp\;([#a-z0-9]+)\;\]/','&$1;',$Text);
+
// fix any escaped ampersands that may have been converted into links
$Text = preg_replace("/\<(.*?)(src|href)=(.*?)\&amp\;(.*?)\>/ism",'<$1$2=$3&$4>',$Text);
if(strlen($saved_image))
diff --git a/include/cache.php b/include/cache.php
index 3c8a3f713..360c4acbd 100644
--- a/include/cache.php
+++ b/include/cache.php
@@ -14,22 +14,40 @@
}
public static function set($key,$value) {
- $r = q("SELECT * FROM `cache` WHERE `k`='%s' limit 1",
- dbesc($key)
- );
- if(count($r)) {
- q("UPDATE `cache` SET `v` = '%s', `updated = '%s' WHERE `k` = '%s' limit 1",
- dbesc($value),
- dbesc(datetime_convert()),
- dbesc($key));
- }
- else {
- q("INSERT INTO `cache` (`k`,`v`,`updated`) VALUES ('%s','%s','%s')",
+
+ q("REPLACE INTO `cache` (`k`,`v`,`updated`) VALUES ('%s','%s','%s')",
dbesc($key),
dbesc($value),
dbesc(datetime_convert()));
- }
}
+
+
+/*
+ *
+ * Leaving this legacy code temporaily to see how REPLACE fares
+ * as opposed to non-atomic checks when faced with fast moving key duplication.
+ * As a MySQL extension it isn't portable, but we're not yet very portable.
+ */
+
+/*
+ * $r = q("SELECT * FROM `cache` WHERE `k`='%s' limit 1",
+ * dbesc($key)
+ * );
+ * if(count($r)) {
+ * q("UPDATE `cache` SET `v` = '%s', `updated = '%s' WHERE `k` = '%s' limit 1",
+ * dbesc($value),
+ * dbesc(datetime_convert()),
+ * dbesc($key));
+ * }
+ * else {
+ * q("INSERT INTO `cache` (`k`,`v`,`updated`) VALUES ('%s','%s','%s')",
+ * dbesc($key),
+ * dbesc($value),
+ * dbesc(datetime_convert()));
+ * }
+ * }
+ */
+
public static function clear(){
q("DELETE FROM `cache` WHERE `updated` < '%s'",
diff --git a/include/contact_widgets.php b/include/contact_widgets.php
index 96b02f293..ce1cdbad5 100644
--- a/include/contact_widgets.php
+++ b/include/contact_widgets.php
@@ -133,3 +133,60 @@ function categories_widget($baseurl,$selected = '') {
));
}
+function common_friends_visitor_widget($profile_uid) {
+
+ $a = get_app();
+
+ if(local_user() == $profile_uid)
+ return;
+
+ $cid = $zcid = 0;
+
+ if(can_write_wall($a,$profile_uid))
+ $cid = remote_user();
+ else {
+ if(get_my_url()) {
+ $r = q("select id from contact where nurl = '%s' and uid = %d limit 1",
+ dbesc(normalise_link(get_my_url())),
+ intval($profile_uid)
+ );
+ if(count($r))
+ $cid = $r[0]['id'];
+ else {
+ $r = q("select id from gcontact where nurl = '%s' limit 1",
+ dbesc(normalise_link(get_my_url()))
+ );
+ if(count($r))
+ $zcid = $r[0]['id'];
+ }
+ }
+ }
+
+ if($cid == 0 && $zcid == 0)
+ return;
+
+ require_once('include/socgraph.php');
+
+ if($cid)
+ $t = count_common_friends($profile_uid,$cid);
+ else
+ $t = count_common_friends_zcid($profile_uid,$zcid);
+ if(! $t)
+ return;
+
+ if($cid)
+ $r = common_friends($profile_uid,$cid,0,5,true);
+ else
+ $r = common_friends_zcid($profile_uid,$zcid,0,5,true);
+
+ return replace_macros(get_markup_template('remote_friends_common.tpl'), array(
+ '$desc' => sprintf( tt("%d contact in common", "%d contacts in common", $t), $t),
+ '$base' => $a->get_baseurl(),
+ '$uid' => $profile_uid,
+ '$cid' => (($cid) ? $cid : '0'),
+ '$linkmore' => (($t > 5) ? 'true' : ''),
+ '$more' => t('show more'),
+ '$items' => $r
+ ));
+
+}; \ No newline at end of file
diff --git a/include/conversation.php b/include/conversation.php
index 1b869b91e..6bf673b97 100644
--- a/include/conversation.php
+++ b/include/conversation.php
@@ -278,6 +278,9 @@ function conversation(&$a, $items, $mode, $update, $preview = false) {
else
$nickname = $a->user['nickname'];
+ // prevent private email from leaking.
+ if($item['network'] === NETWORK_MAIL && local_user() != $item['uid'])
+ continue;
$profile_name = ((strlen($item['author-name'])) ? $item['author-name'] : $item['name']);
if($item['author-link'] && (! $item['author-name']))
@@ -447,8 +450,8 @@ function conversation(&$a, $items, $mode, $update, $preview = false) {
else {
// prevent private email reply to public conversation from leaking.
- if($item['private'] && ! $threads[$threadsid]['private'])
- continue;
+ if($item['network'] === NETWORK_MAIL && local_user() != $item['uid'])
+ continue;
$comments_seen ++;
$comment_lastcollapsed = false;
@@ -553,6 +556,14 @@ function conversation(&$a, $items, $mode, $update, $preview = false) {
'$myphoto' => $a->contact['thumb'],
'$comment' => t('Comment'),
'$submit' => t('Submit'),
+ '$edbold' => t('Bold'),
+ '$editalic' => t('Italic'),
+ '$eduline' => t('Underline'),
+ '$edquote' => t('Quote'),
+ '$edcode' => t('Code'),
+ '$edimg' => t('Image'),
+ '$edurl' => t('Link'),
+ '$edvideo' => t('Video'),
'$preview' => t('Preview'),
'$ww' => (($mode === 'network') ? $commentww : '')
));
@@ -951,7 +962,7 @@ function status_editor($a,$x, $notes_cid = 0, $popup=false) {
$tpl = replace_macros($tpl,array('$jotplugins' => $jotplugins));
$o .= replace_macros($tpl,array(
- '$return_path' => $a->cmd,
+ '$return_path' => $a->query_string,
'$action' => $a->get_baseurl(true) . '/item',
'$share' => (x($x,'button') ? $x['button'] : t('Share')),
'$upload' => t('Upload photo'),
diff --git a/include/dba.php b/include/dba.php
index 44a663eac..c9f880241 100644
--- a/include/dba.php
+++ b/include/dba.php
@@ -75,22 +75,28 @@ class dba {
if((! $this->db) || (! $this->connected))
return false;
+ $this->error = '';
+
if($this->mysqli)
$result = @$this->db->query($sql);
else
$result = @mysql_query($sql,$this->db);
+ if($this->mysqli) {
+ if($this->db->errno)
+ $this->error = $this->db->error;
+ }
+ elseif(mysql_errno($this->db))
+ $this->error = mysql_error($this->db);
+
+ if(strlen($this->error)) {
+ logger('dba: ' . $this->error);
+ }
+
if($this->debug) {
$mesg = '';
- if($this->mysqli) {
- if($this->db->errno)
- logger('dba: ' . $this->db->error);
- }
- elseif(mysql_errno($this->db))
- logger('dba: ' . mysql_error($this->db));
-
if($result === false)
$mesg = 'false';
elseif($result === true)
@@ -102,7 +108,9 @@ class dba {
$mesg = mysql_num_rows($result) . ' results' . EOL;
}
- $str = 'SQL = ' . printable($sql) . EOL . 'SQL returned ' . $mesg . EOL;
+ $str = 'SQL = ' . printable($sql) . EOL . 'SQL returned ' . $mesg
+ . (($this->error) ? ' error: ' . $this->error : '')
+ . EOL;
logger('dba: ' . $str );
}
@@ -114,9 +122,9 @@ class dba {
*/
if($result === false) {
- logger('dba: ' . printable($sql) . ' returned false.');
+ logger('dba: ' . printable($sql) . ' returned false.' . "\n" . $this->error);
if(file_exists('dbfail.out'))
- file_put_contents('dbfail.out', datetime_convert() . "\n" . printable($sql) . ' returned false' . "\n", FILE_APPEND);
+ file_put_contents('dbfail.out', datetime_convert() . "\n" . printable($sql) . ' returned false' . "\n" . $this->error . "\n", FILE_APPEND);
}
if(($result === true) || ($result === false))
diff --git a/include/delivery.php b/include/delivery.php
index 794b8f27a..1cee2d697 100644
--- a/include/delivery.php
+++ b/include/delivery.php
@@ -38,153 +38,167 @@ function delivery_run($argv, $argc){
$cmd = $argv[1];
$item_id = intval($argv[2]);
- $contact_id = intval($argv[3]);
- // Some other process may have delivered this item already.
+ for($x = 3; $x < $argc; $x ++) {
- $r = q("select * from deliverq where cmd = '%s' and item = %d and contact = %d limit 1",
- dbesc($cmd),
- dbesc($item_id),
- dbesc($contact_id)
- );
- if(! count($r)) {
- return;
- }
+ $contact_id = intval($argv[x]);
- // It's ours to deliver. Remove it from the queue.
+ // Some other process may have delivered this item already.
- q("delete from deliverq where cmd = '%s' and item = %d and contact = %d limit 1",
- dbesc($cmd),
- dbesc($item_id),
- dbesc($contact_id)
- );
+ $r = q("select * from deliverq where cmd = '%s' and item = %d and contact = %d limit 1",
+ dbesc($cmd),
+ dbesc($item_id),
+ dbesc($contact_id)
+ );
+ if(! count($r)) {
+ continue;
+ }
+
+ $maxsysload = intval(get_config('system','maxloadavg'));
+ if($maxsysload < 1)
+ $maxsysload = 50;
+ if(function_exists('sys_getloadavg')) {
+ $load = sys_getloadavg();
+ if(intval($load[0]) > $maxsysload) {
+ logger('system: load ' . $load . ' too high. Delivery deferred to next queue run.');
+ return;
+ }
+ }
- if((! $item_id) || (! $contact_id))
- return;
+ // It's ours to deliver. Remove it from the queue.
- $expire = false;
- $top_level = false;
- $recipients = array();
- $url_recipients = array();
+ q("delete from deliverq where cmd = '%s' and item = %d and contact = %d limit 1",
+ dbesc($cmd),
+ dbesc($item_id),
+ dbesc($contact_id)
+ );
- $normal_mode = true;
+ if((! $item_id) || (! $contact_id))
+ continue;
- $recipients[] = $contact_id;
+ $expire = false;
+ $top_level = false;
+ $recipients = array();
+ $url_recipients = array();
- if($cmd === 'expire') {
- $normal_mode = false;
- $expire = true;
- $items = q("SELECT * FROM `item` WHERE `uid` = %d AND `wall` = 1
- AND `deleted` = 1 AND `changed` > UTC_TIMESTAMP() - INTERVAL 30 MINUTE",
- intval($item_id)
- );
- $uid = $item_id;
- $item_id = 0;
- if(! count($items))
- return;
- }
- else {
+ $normal_mode = true;
- // find ancestors
- $r = q("SELECT * FROM `item` WHERE `id` = %d and visible = 1 and moderated = 0 LIMIT 1",
- intval($item_id)
- );
+ $recipients[] = $contact_id;
- if((! count($r)) || (! intval($r[0]['parent']))) {
- return;
+ if($cmd === 'expire') {
+ $normal_mode = false;
+ $expire = true;
+ $items = q("SELECT * FROM `item` WHERE `uid` = %d AND `wall` = 1
+ AND `deleted` = 1 AND `changed` > UTC_TIMESTAMP() - INTERVAL 30 MINUTE",
+ intval($item_id)
+ );
+ $uid = $item_id;
+ $item_id = 0;
+ if(! count($items))
+ continue;
}
+ else {
- $target_item = $r[0];
- $parent_id = intval($r[0]['parent']);
- $uid = $r[0]['uid'];
- $updated = $r[0]['edited'];
+ // find ancestors
+ $r = q("SELECT * FROM `item` WHERE `id` = %d and visible = 1 and moderated = 0 LIMIT 1",
+ intval($item_id)
+ );
- if(! $parent_id)
- return;
+ if((! count($r)) || (! intval($r[0]['parent']))) {
+ continue;
+ }
+ $target_item = $r[0];
+ $parent_id = intval($r[0]['parent']);
+ $uid = $r[0]['uid'];
+ $updated = $r[0]['edited'];
- $items = q("SELECT `item`.*, `sign`.`signed_text`,`sign`.`signature`,`sign`.`signer`
- FROM `item` LEFT JOIN `sign` ON `sign`.`iid` = `item`.`id` WHERE `parent` = %d and visible = 1 and moderated = 0 ORDER BY `id` ASC",
- intval($parent_id)
- );
+ if(! $parent_id)
+ continue;
- if(! count($items)) {
- return;
- }
- $icontacts = null;
- $contacts_arr = array();
- foreach($items as $item)
- if(! in_array($item['contact-id'],$contacts_arr))
- $contacts_arr[] = intval($item['contact-id']);
- if(count($contacts_arr)) {
- $str_contacts = implode(',',$contacts_arr);
- $icontacts = q("SELECT * FROM `contact`
- WHERE `id` IN ( $str_contacts ) "
+ $items = q("SELECT `item`.*, `sign`.`signed_text`,`sign`.`signature`,`sign`.`signer`
+ FROM `item` LEFT JOIN `sign` ON `sign`.`iid` = `item`.`id` WHERE `parent` = %d and visible = 1 and moderated = 0 ORDER BY `id` ASC",
+ intval($parent_id)
);
- }
- if( ! ($icontacts && count($icontacts)))
- return;
- // avoid race condition with deleting entries
+ if(! count($items)) {
+ continue;
+ }
- if($items[0]['deleted']) {
+ $icontacts = null;
+ $contacts_arr = array();
foreach($items as $item)
- $item['deleted'] = 1;
- }
+ if(! in_array($item['contact-id'],$contacts_arr))
+ $contacts_arr[] = intval($item['contact-id']);
+ if(count($contacts_arr)) {
+ $str_contacts = implode(',',$contacts_arr);
+ $icontacts = q("SELECT * FROM `contact`
+ WHERE `id` IN ( $str_contacts ) "
+ );
+ }
+ if( ! ($icontacts && count($icontacts)))
+ continue;
+
+ // avoid race condition with deleting entries
+
+ if($items[0]['deleted']) {
+ foreach($items as $item)
+ $item['deleted'] = 1;
+ }
- if((count($items) == 1) && ($items[0]['uri'] === $items[0]['parent-uri'])) {
- logger('delivery: top level post');
- $top_level = true;
+ if((count($items) == 1) && ($items[0]['uri'] === $items[0]['parent-uri'])) {
+ logger('delivery: top level post');
+ $top_level = true;
+ }
}
- }
- $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`
- FROM `contact` LEFT JOIN `user` ON `user`.`uid` = `contact`.`uid`
- WHERE `contact`.`uid` = %d AND `contact`.`self` = 1 LIMIT 1",
- intval($uid)
- );
+ $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`
+ FROM `contact` LEFT JOIN `user` ON `user`.`uid` = `contact`.`uid`
+ WHERE `contact`.`uid` = %d AND `contact`.`self` = 1 LIMIT 1",
+ intval($uid)
+ );
+
+ if(! count($r))
+ continue;
- if(! count($r))
- return;
+ $owner = $r[0];
- $owner = $r[0];
+ $walltowall = ((($top_level) && ($owner['id'] != $items[0]['contact-id'])) ? true : false);
- $walltowall = ((($top_level) && ($owner['id'] != $items[0]['contact-id'])) ? true : false);
+ $public_message = true;
- $public_message = true;
+ // fill this in with a single salmon slap if applicable
- // fill this in with a single salmon slap if applicable
+ $slap = '';
- $slap = '';
+ require_once('include/group.php');
- require_once('include/group.php');
+ $parent = $items[0];
- $parent = $items[0];
+ // This is IMPORTANT!!!!
- // This is IMPORTANT!!!!
+ // We will only send a "notify owner to relay" or followup message if the referenced post
+ // originated on our system by virtue of having our hostname somewhere
+ // in the URI, AND it was a comment (not top_level) AND the parent originated elsewhere.
+ // if $parent['wall'] == 1 we will already have the parent message in our array
+ // and we will relay the whole lot.
+
+ // expire sends an entire group of expire messages and cannot be forwarded.
+ // However the conversation owner will be a part of the conversation and will
+ // be notified during this run.
+ // Other DFRN conversation members will be alerted during polled updates.
- // We will only send a "notify owner to relay" or followup message if the referenced post
- // originated on our system by virtue of having our hostname somewhere
- // in the URI, AND it was a comment (not top_level) AND the parent originated elsewhere.
- // if $parent['wall'] == 1 we will already have the parent message in our array
- // and we will relay the whole lot.
-
- // expire sends an entire group of expire messages and cannot be forwarded.
- // However the conversation owner will be a part of the conversation and will
- // be notified during this run.
- // Other DFRN conversation members will be alerted during polled updates.
-
- // Diaspora members currently are not notified of expirations, and other networks have
- // either limited or no ability to process deletions. We should at least fix Diaspora
- // by stringing togther an array of retractions and sending them onward.
+ // Diaspora members currently are not notified of expirations, and other networks have
+ // either limited or no ability to process deletions. We should at least fix Diaspora
+ // by stringing togther an array of retractions and sending them onward.
- $localhost = $a->get_hostname();
- if(strpos($localhost,':'))
- $localhost = substr($localhost,0,strpos($localhost,':'));
+ $localhost = $a->get_hostname();
+ if(strpos($localhost,':'))
+ $localhost = substr($localhost,0,strpos($localhost,':'));
/**
*
@@ -194,330 +208,338 @@ function delivery_run($argv, $argc){
*
*/
- if((! $top_level) && ($parent['wall'] == 0) && (! $expire) && (stristr($target_item['uri'],$localhost))) {
- logger('relay denied for delivery agent.');
+ if((! $top_level) && ($parent['wall'] == 0) && (! $expire) && (stristr($target_item['uri'],$localhost))) {
+ logger('relay denied for delivery agent.');
- /* no relay allowed for direct contact delivery */
- return;
- }
+ /* no relay allowed for direct contact delivery */
+ continue;
+ }
- if((strlen($parent['allow_cid']))
- || (strlen($parent['allow_gid']))
- || (strlen($parent['deny_cid']))
- || (strlen($parent['deny_gid']))) {
- $public_message = false; // private recipients, not public
- }
+ if((strlen($parent['allow_cid']))
+ || (strlen($parent['allow_gid']))
+ || (strlen($parent['deny_cid']))
+ || (strlen($parent['deny_gid']))) {
+ $public_message = false; // private recipients, not public
+ }
- $r = q("SELECT * FROM `contact` WHERE `id` = %d AND `blocked` = 0 AND `pending` = 0",
- intval($contact_id)
- );
+ $r = q("SELECT * FROM `contact` WHERE `id` = %d AND `blocked` = 0 AND `pending` = 0",
+ intval($contact_id)
+ );
- if(count($r))
- $contact = $r[0];
+ if(count($r))
+ $contact = $r[0];
- $hubxml = feed_hublinks();
+ $hubxml = feed_hublinks();
- logger('notifier: slaps: ' . print_r($slaps,true), LOGGER_DATA);
+ logger('notifier: slaps: ' . print_r($slaps,true), LOGGER_DATA);
- require_once('include/salmon.php');
+ require_once('include/salmon.php');
- if($contact['self'])
- return;
+ if($contact['self'])
+ continue;
- $deliver_status = 0;
+ $deliver_status = 0;
- switch($contact['network']) {
+ switch($contact['network']) {
- case NETWORK_DFRN :
- logger('notifier: dfrndelivery: ' . $contact['name']);
+ case NETWORK_DFRN :
+ logger('notifier: dfrndelivery: ' . $contact['name']);
- $feed_template = get_markup_template('atom_feed.tpl');
- $mail_template = get_markup_template('atom_mail.tpl');
+ $feed_template = get_markup_template('atom_feed.tpl');
+ $mail_template = get_markup_template('atom_mail.tpl');
- $atom = '';
+ $atom = '';
- $birthday = feed_birthday($owner['uid'],$owner['timezone']);
+ $birthday = feed_birthday($owner['uid'],$owner['timezone']);
- if(strlen($birthday))
- $birthday = '<dfrn:birthday>' . xmlify($birthday) . '</dfrn:birthday>';
+ if(strlen($birthday))
+ $birthday = '<dfrn:birthday>' . xmlify($birthday) . '</dfrn:birthday>';
- $atom .= replace_macros($feed_template, array(
- '$version' => xmlify(FRIENDICA_VERSION),
- '$feed_id' => xmlify($a->get_baseurl() . '/profile/' . $owner['nickname'] ),
- '$feed_title' => xmlify($owner['name']),
- '$feed_updated' => xmlify(datetime_convert('UTC', 'UTC', $updated . '+00:00' , ATOM_TIME)) ,
- '$hub' => $hubxml,
- '$salmon' => '', // private feed, we don't use salmon here
- '$name' => xmlify($owner['name']),
- '$profile_page' => xmlify($owner['url']),
- '$photo' => xmlify($owner['photo']),
- '$thumb' => xmlify($owner['thumb']),
- '$picdate' => xmlify(datetime_convert('UTC','UTC',$owner['avatar-date'] . '+00:00' , ATOM_TIME)) ,
- '$uridate' => xmlify(datetime_convert('UTC','UTC',$owner['uri-date'] . '+00:00' , ATOM_TIME)) ,
- '$namdate' => xmlify(datetime_convert('UTC','UTC',$owner['name-date'] . '+00:00' , ATOM_TIME)) ,
- '$birthday' => $birthday,
- '$community' => (($owner['page-flags'] == PAGE_COMMUNITY) ? '<dfrn:community>1</dfrn:community>' : '')
- ));
+ $atom .= replace_macros($feed_template, array(
+ '$version' => xmlify(FRIENDICA_VERSION),
+ '$feed_id' => xmlify($a->get_baseurl() . '/profile/' . $owner['nickname'] ),
+ '$feed_title' => xmlify($owner['name']),
+ '$feed_updated' => xmlify(datetime_convert('UTC', 'UTC', $updated . '+00:00' , ATOM_TIME)) ,
+ '$hub' => $hubxml,
+ '$salmon' => '', // private feed, we don't use salmon here
+ '$name' => xmlify($owner['name']),
+ '$profile_page' => xmlify($owner['url']),
+ '$photo' => xmlify($owner['photo']),
+ '$thumb' => xmlify($owner['thumb']),
+ '$picdate' => xmlify(datetime_convert('UTC','UTC',$owner['avatar-date'] . '+00:00' , ATOM_TIME)) ,
+ '$uridate' => xmlify(datetime_convert('UTC','UTC',$owner['uri-date'] . '+00:00' , ATOM_TIME)) ,
+ '$namdate' => xmlify(datetime_convert('UTC','UTC',$owner['name-date'] . '+00:00' , ATOM_TIME)) ,
+ '$birthday' => $birthday,
+ '$community' => (($owner['page-flags'] == PAGE_COMMUNITY) ? '<dfrn:community>1</dfrn:community>' : '')
+ ));
- foreach($items as $item) {
- if(! $item['parent'])
- continue;
+ foreach($items as $item) {
+ if(! $item['parent'])
+ continue;
- // private emails may be in included in public conversations. Filter them.
- if(($public_message) && $item['private'])
- continue;
+ // private emails may be in included in public conversations. Filter them.
+ if(($public_message) && $item['private'])
+ continue;
- $item_contact = get_item_contact($item,$icontacts);
- if(! $item_contact)
- continue;
+ $item_contact = get_item_contact($item,$icontacts);
+ if(! $item_contact)
+ continue;
- if($normal_mode) {
- if($item_id == $item['id'] || $item['id'] == $item['parent'])
+ if($normal_mode) {
+ if($item_id == $item['id'] || $item['id'] == $item['parent'])
+ $atom .= atom_entry($item,'text',null,$owner,true);
+ }
+ else
$atom .= atom_entry($item,'text',null,$owner,true);
- }
- else
- $atom .= atom_entry($item,'text',null,$owner,true);
-
- }
-
- $atom .= '</feed>' . "\r\n";
- logger('notifier: ' . $atom, LOGGER_DATA);
- $basepath = implode('/', array_slice(explode('/',$contact['url']),0,3));
-
- // perform local delivery if we are on the same site
+ }
- if(link_compare($basepath,$a->get_baseurl())) {
+ $atom .= '</feed>' . "\r\n";
+
+ logger('notifier: ' . $atom, LOGGER_DATA);
+ $basepath = implode('/', array_slice(explode('/',$contact['url']),0,3));
+
+ // perform local delivery if we are on the same site
+
+ if(link_compare($basepath,$a->get_baseurl())) {
+
+ $nickname = basename($contact['url']);
+ if($contact['issued-id'])
+ $sql_extra = sprintf(" AND `dfrn-id` = '%s' ", dbesc($contact['issued-id']));
+ else
+ $sql_extra = sprintf(" AND `issued-id` = '%s' ", dbesc($contact['dfrn-id']));
+
+ $x = q("SELECT `contact`.*, `contact`.`uid` AS `importer_uid`,
+ `contact`.`pubkey` AS `cpubkey`,
+ `contact`.`prvkey` AS `cprvkey`,
+ `contact`.`thumb` AS `thumb`,
+ `contact`.`url` as `url`,
+ `contact`.`name` as `senderName`,
+ `user`.*
+ FROM `contact`
+ LEFT JOIN `user` ON `contact`.`uid` = `user`.`uid`
+ WHERE `contact`.`blocked` = 0 AND `contact`.`pending` = 0
+ AND `contact`.`network` = '%s' AND `user`.`nickname` = '%s'
+ $sql_extra
+ AND `user`.`account_expired` = 0 LIMIT 1",
+ dbesc(NETWORK_DFRN),
+ dbesc($nickname)
+ );
- $nickname = basename($contact['url']);
- if($contact['issued-id'])
- $sql_extra = sprintf(" AND `dfrn-id` = '%s' ", dbesc($contact['issued-id']));
- else
- $sql_extra = sprintf(" AND `issued-id` = '%s' ", dbesc($contact['dfrn-id']));
-
- $x = q("SELECT `contact`.*, `contact`.`uid` AS `importer_uid`,
- `contact`.`pubkey` AS `cpubkey`,
- `contact`.`prvkey` AS `cprvkey`,
- `contact`.`thumb` AS `thumb`,
- `contact`.`url` as `url`,
- `contact`.`name` as `senderName`,
- `user`.*
- FROM `contact`
- LEFT JOIN `user` ON `contact`.`uid` = `user`.`uid`
- WHERE `contact`.`blocked` = 0 AND `contact`.`pending` = 0
- AND `contact`.`network` = '%s' AND `user`.`nickname` = '%s'
- $sql_extra
- AND `user`.`account_expired` = 0 LIMIT 1",
- dbesc(NETWORK_DFRN),
- dbesc($nickname)
- );
+ if(count($x)) {
+ if($owner['page-flags'] == PAGE_COMMUNITY && ! $x[0]['writable']) {
+ q("update contact set writable = 1 where id = %d limit 1",
+ intval($x[0]['id'])
+ );
+ $x[0]['writable'] = 1;
+ }
- if(count($x)) {
- if($owner['page-flags'] == PAGE_COMMUNITY && ! $x[0]['writable']) {
- q("update contact set writable = 1 where id = %d limit 1",
- intval($x[0]['id'])
- );
- $x[0]['writable'] = 1;
- }
+ $ssl_policy = get_config('system','ssl_policy');
+ fix_contact_ssl_policy($x[0],$ssl_policy);
- $ssl_policy = get_config('system','ssl_policy');
- fix_contact_ssl_policy($x[0],$ssl_policy);
+ // If we are setup as a soapbox we aren't accepting input from this person
- // If we are setup as a soapbox we aren't accepting input from this person
+ if($x[0]['page-flags'] == PAGE_SOAPBOX)
+ break;
- if($x[0]['page-flags'] == PAGE_SOAPBOX)
+ require_once('library/simplepie/simplepie.inc');
+ logger('mod-delivery: local delivery');
+ local_delivery($x[0],$atom);
break;
-
- require_once('library/simplepie/simplepie.inc');
- logger('mod-delivery: local delivery');
- local_delivery($x[0],$atom);
- break;
+ }
}
- }
-
- $deliver_status = dfrn_deliver($owner,$contact,$atom);
- logger('notifier: dfrn_delivery returns ' . $deliver_status);
-
- if($deliver_status == (-1)) {
- logger('notifier: delivery failed: queuing message');
- add_to_queue($contact['id'],NETWORK_DFRN,$atom);
- }
- break;
+ if(! was_recently_delayed($contact['id']))
+ $deliver_status = dfrn_deliver($owner,$contact,$atom);
+ else
+ $deliver_status = (-1);
- case NETWORK_OSTATUS :
+ logger('notifier: dfrn_delivery returns ' . $deliver_status);
- // Do not send to otatus if we are not configured to send to public networks
- if($owner['prvnets'])
- break;
- if(get_config('system','ostatus_disabled') || get_config('system','dfrn_only'))
+ if($deliver_status == (-1)) {
+ logger('notifier: delivery failed: queuing message');
+ add_to_queue($contact['id'],NETWORK_DFRN,$atom);
+ }
break;
- // only send salmon if public - e.g. if it's ok to notify
- // a public hub, it's ok to send a salmon
+ case NETWORK_OSTATUS :
- if(($public_message) && (! $expire)) {
- $slaps = array();
+ // Do not send to otatus if we are not configured to send to public networks
+ if($owner['prvnets'])
+ break;
+ if(get_config('system','ostatus_disabled') || get_config('system','dfrn_only'))
+ break;
- foreach($items as $item) {
- if(! $item['parent'])
- continue;
+ // only send salmon if public - e.g. if it's ok to notify
+ // a public hub, it's ok to send a salmon
- // private emails may be in included in public conversations. Filter them.
- if(($public_message) && $item['private'])
- continue;
+ if(($public_message) && (! $expire)) {
+ $slaps = array();
- $item_contact = get_item_contact($item,$icontacts);
- if(! $item_contact)
- continue;
+ foreach($items as $item) {
+ if(! $item['parent'])
+ continue;
- if(($top_level) && ($public_message) && ($item['author-link'] === $item['owner-link']) && (! $expire))
- $slaps[] = atom_entry($item,'html',null,$owner,true);
- }
+ // private emails may be in included in public conversations. Filter them.
+ if(($public_message) && $item['private'])
+ continue;
+
+ $item_contact = get_item_contact($item,$icontacts);
+ if(! $item_contact)
+ continue;
- logger('notifier: slapdelivery: ' . $contact['name']);
- foreach($slaps as $slappy) {
- if($contact['notify']) {
- $deliver_status = slapper($owner,$contact['notify'],$slappy);
- if($deliver_status == (-1)) {
- // queue message for redelivery
- add_to_queue($contact['id'],NETWORK_OSTATUS,$slappy);
+ if(($top_level) && ($public_message) && ($item['author-link'] === $item['owner-link']) && (! $expire))
+ $slaps[] = atom_entry($item,'html',null,$owner,true);
+ }
+
+ logger('notifier: slapdelivery: ' . $contact['name']);
+ foreach($slaps as $slappy) {
+ if($contact['notify']) {
+ if(! was_recently_delayed($contact['id']))
+ $deliver_status = slapper($owner,$contact['notify'],$slappy);
+ else
+ $deliver_status = (-1);
+
+ if($deliver_status == (-1)) {
+ // queue message for redelivery
+ add_to_queue($contact['id'],NETWORK_OSTATUS,$slappy);
+ }
}
}
}
- }
-
- break;
-
- case NETWORK_MAIL :
- case NETWORK_MAIL2:
- if(get_config('system','dfrn_only'))
break;
- // WARNING: does not currently convert to RFC2047 header encodings, etc.
- $addr = $contact['addr'];
- if(! strlen($addr))
- break;
-
- if($cmd === 'wall-new' || $cmd === 'comment-new') {
+ case NETWORK_MAIL :
+ case NETWORK_MAIL2:
- $it = null;
- if($cmd === 'wall-new')
- $it = $items[0];
- else {
- $r = q("SELECT * FROM `item` WHERE `id` = %d AND `uid` = %d LIMIT 1",
- intval($argv[2]),
- intval($uid)
- );
- if(count($r))
- $it = $r[0];
- }
- if(! $it)
+ if(get_config('system','dfrn_only'))
break;
-
+ // WARNING: does not currently convert to RFC2047 header encodings, etc.
- $local_user = q("SELECT * FROM `user` WHERE `uid` = %d LIMIT 1",
- intval($uid)
- );
- if(! count($local_user))
+ $addr = $contact['addr'];
+ if(! strlen($addr))
break;
+
+ if($cmd === 'wall-new' || $cmd === 'comment-new') {
+
+ $it = null;
+ if($cmd === 'wall-new')
+ $it = $items[0];
+ else {
+ $r = q("SELECT * FROM `item` WHERE `id` = %d AND `uid` = %d LIMIT 1",
+ intval($argv[2]),
+ intval($uid)
+ );
+ if(count($r))
+ $it = $r[0];
+ }
+ if(! $it)
+ break;
- $reply_to = '';
- $r1 = q("SELECT * FROM `mailacct` WHERE `uid` = %d LIMIT 1",
- intval($uid)
- );
- if($r1 && $r1[0]['reply_to'])
- $reply_to = $r1[0]['reply_to'];
- $subject = (($it['title']) ? email_header_encode($it['title'],'UTF-8') : t("\x28no subject\x29")) ;
+ $local_user = q("SELECT * FROM `user` WHERE `uid` = %d LIMIT 1",
+ intval($uid)
+ );
+ if(! count($local_user))
+ break;
+
+ $reply_to = '';
+ $r1 = q("SELECT * FROM `mailacct` WHERE `uid` = %d LIMIT 1",
+ intval($uid)
+ );
+ if($r1 && $r1[0]['reply_to'])
+ $reply_to = $r1[0]['reply_to'];
- // only expose our real email address to true friends
+ $subject = (($it['title']) ? email_header_encode($it['title'],'UTF-8') : t("\x28no subject\x29")) ;
- if(($contact['rel'] == CONTACT_IS_FRIEND) && (! $contact['blocked']))
- $headers = 'From: ' . email_header_encode($local_user[0]['username'],'UTF-8') . ' <' . $local_user[0]['email'] . '>' . "\n";
- else
- $headers = 'From: ' . email_header_encode($local_user[0]['username'],'UTF-8') . ' <' . t('noreply') . '@' . $a->get_hostname() . '>' . "\n";
+ // only expose our real email address to true friends
- if($reply_to)
- $headers .= 'Reply-to: ' . $reply_to . "\n";
+ if(($contact['rel'] == CONTACT_IS_FRIEND) && (! $contact['blocked']))
+ $headers = 'From: ' . email_header_encode($local_user[0]['username'],'UTF-8') . ' <' . $local_user[0]['email'] . '>' . "\n";
+ else
+ $headers = 'From: ' . email_header_encode($local_user[0]['username'],'UTF-8') . ' <' . t('noreply') . '@' . $a->get_hostname() . '>' . "\n";
- // for testing purposes: Collect exported mails
- // $file = tempnam("/tmp/friendica/", "mail-out-");
- // file_put_contents($file, json_encode($it));
+ if($reply_to)
+ $headers .= 'Reply-to: ' . $reply_to . "\n";
- $headers .= 'Message-Id: <' . iri2msgid($it['uri']). '>' . "\n";
+ // for testing purposes: Collect exported mails
+ // $file = tempnam("/tmp/friendica/", "mail-out-");
+ // file_put_contents($file, json_encode($it));
+
+ $headers .= 'Message-Id: <' . iri2msgid($it['uri']). '>' . "\n";
- //logger("Mail: uri: ".$it['uri']." parent-uri ".$it['parent-uri'], LOGGER_DEBUG);
- //logger("Mail: Data: ".print_r($it, true), LOGGER_DEBUG);
- //logger("Mail: Data: ".print_r($it, true), LOGGER_DATA);
+ //logger("Mail: uri: ".$it['uri']." parent-uri ".$it['parent-uri'], LOGGER_DEBUG);
+ //logger("Mail: Data: ".print_r($it, true), LOGGER_DEBUG);
+ //logger("Mail: Data: ".print_r($it, true), LOGGER_DATA);
- if($it['uri'] !== $it['parent-uri']) {
- $headers .= 'References: <' . iri2msgid($it['parent-uri']) . '>' . "\n";
- if(!strlen($it['title'])) {
- $r = q("SELECT `title` FROM `item` WHERE `parent-uri` = '%s' LIMIT 1",
- dbesc($it['parent-uri']));
+ if($it['uri'] !== $it['parent-uri']) {
+ $headers .= 'References: <' . iri2msgid($it['parent-uri']) . '>' . "\n";
+ if(!strlen($it['title'])) {
+ $r = q("SELECT `title` FROM `item` WHERE `parent-uri` = '%s' LIMIT 1",
+ dbesc($it['parent-uri']));
- if(count($r) AND ($r[0]['title'] != ''))
- $subject = $r[0]['title'];
+ if(count($r) AND ($r[0]['title'] != ''))
+ $subject = $r[0]['title'];
+ }
+ if(strncasecmp($subject,'RE:',3))
+ $subject = 'Re: '.$subject;
}
- if(strncasecmp($subject,'RE:',3))
- $subject = 'Re: '.$subject;
+ email_send($addr, $subject, $headers, $it);
}
- email_send($addr, $subject, $headers, $it);
- }
- break;
+ break;
- case NETWORK_DIASPORA :
- if($public_message)
- $loc = 'public batch ' . $contact['batch'];
- else
- $loc = $contact['name'];
+ case NETWORK_DIASPORA :
+ if($public_message)
+ $loc = 'public batch ' . $contact['batch'];
+ else
+ $loc = $contact['name'];
- logger('delivery: diaspora batch deliver: ' . $loc);
+ logger('delivery: diaspora batch deliver: ' . $loc);
- if(get_config('system','dfrn_only') || (! get_config('system','diaspora_enabled')) || (! $normal_mode))
- break;
+ if(get_config('system','dfrn_only') || (! get_config('system','diaspora_enabled')) || (! $normal_mode))
+ break;
- if((! $contact['pubkey']) && (! $public_message))
- break;
+ if((! $contact['pubkey']) && (! $public_message))
+ break;
- if($target_item['verb'] === ACTIVITY_DISLIKE) {
- // unsupported
- break;
- }
- elseif(($target_item['deleted']) && ($target_item['verb'] !== ACTIVITY_LIKE)) {
- logger('delivery: diaspora retract: ' . $loc);
- // diaspora delete,
- diaspora_send_retraction($target_item,$owner,$contact,$public_message);
- break;
- }
- elseif($target_item['parent'] != $target_item['id']) {
+ if($target_item['verb'] === ACTIVITY_DISLIKE) {
+ // unsupported
+ break;
+ }
+ elseif(($target_item['deleted']) && ($target_item['verb'] !== ACTIVITY_LIKE)) {
+ logger('delivery: diaspora retract: ' . $loc);
+ // diaspora delete,
+ diaspora_send_retraction($target_item,$owner,$contact,$public_message);
+ break;
+ }
+ elseif($target_item['parent'] != $target_item['id']) {
- logger('delivery: diaspora relay: ' . $loc);
+ logger('delivery: diaspora relay: ' . $loc);
- // we are the relay - send comments, likes and unlikes to our conversants
- diaspora_send_relay($target_item,$owner,$contact,$public_message);
- break;
- }
- elseif(($top_level) && (! $walltowall)) {
- // currently no workable solution for sending walltowall
- logger('delivery: diaspora status: ' . $loc);
- diaspora_send_status($target_item,$owner,$contact,$public_message);
- break;
- }
+ // we are the relay - send comments, likes and unlikes to our conversants
+ diaspora_send_relay($target_item,$owner,$contact,$public_message);
+ break;
+ }
+ elseif(($top_level) && (! $walltowall)) {
+ // currently no workable solution for sending walltowall
+ logger('delivery: diaspora status: ' . $loc);
+ diaspora_send_status($target_item,$owner,$contact,$public_message);
+ break;
+ }
- logger('delivery: diaspora unknown mode: ' . $contact['name']);
+ logger('delivery: diaspora unknown mode: ' . $contact['name']);
- break;
+ break;
- case NETWORK_FEED :
- case NETWORK_FACEBOOK :
- if(get_config('system','dfrn_only'))
+ case NETWORK_FEED :
+ case NETWORK_FACEBOOK :
+ if(get_config('system','dfrn_only'))
+ break;
+ default:
break;
- default:
- break;
+ }
}
return;
diff --git a/include/diaspora.php b/include/diaspora.php
index 06df9c24a..3f2cdf8e4 100644
--- a/include/diaspora.php
+++ b/include/diaspora.php
@@ -569,6 +569,14 @@ function diaspora_request($importer,$xml) {
return;
}
+ $g = q("select def_gid from user where uid = %d limit 1",
+ intval($importer['uid'])
+ );
+ if($g && intval($g[0]['def_gid'])) {
+ require_once('include/group.php');
+ group_add_member($importer['uid'],'',$contact_record['id'],$g[0]['def_gid']);
+ }
+
if($importer['page-flags'] == PAGE_NORMAL) {
$hash = random_string() . (string) time(); // Generate a confirm_key
@@ -706,10 +714,10 @@ function diaspora_post($importer,$xml) {
continue;
$basetag = str_replace('_',' ',substr($tag,1));
- $body = str_replace($tag,'#[url=' . $a->get_baseurl() . '/search?search=' . rawurlencode($basetag) . ']' . $basetag . '[/url]',$body);
+ $body = str_replace($tag,'#[url=' . $a->get_baseurl() . '/search?tag=' . rawurlencode($basetag) . ']' . $basetag . '[/url]',$body);
if(strlen($str_tags))
$str_tags .= ',';
- $str_tags .= '#[url=' . $a->get_baseurl() . '/search?search=' . rawurlencode($basetag) . ']' . $basetag . '[/url]';
+ $str_tags .= '#[url=' . $a->get_baseurl() . '/search?tag=' . rawurlencode($basetag) . ']' . $basetag . '[/url]';
continue;
}
}
@@ -872,10 +880,10 @@ function diaspora_reshare($importer,$xml) {
$basetag = str_replace('_',' ',substr($tag,1));
- $body = str_replace($tag,'#[url=' . $a->get_baseurl() . '/search?search=' . rawurlencode($basetag) . ']' . $basetag . '[/url]',$body);
+ $body = str_replace($tag,'#[url=' . $a->get_baseurl() . '/search?tag=' . rawurlencode($basetag) . ']' . $basetag . '[/url]',$body);
if(strlen($str_tags))
$str_tags .= ',';
- $str_tags .= '#[url=' . $a->get_baseurl() . '/search?search=' . rawurlencode($basetag) . ']' . $basetag . '[/url]';
+ $str_tags .= '#[url=' . $a->get_baseurl() . '/search?tag=' . rawurlencode($basetag) . ']' . $basetag . '[/url]';
continue;
}
}
@@ -1113,10 +1121,10 @@ function diaspora_comment($importer,$xml,$msg) {
$basetag = str_replace('_',' ',substr($tag,1));
- $body = str_replace($tag,'#[url=' . $a->get_baseurl() . '/search?search=' . rawurlencode($basetag) . ']' . $basetag . '[/url]',$body);
+ $body = str_replace($tag,'#[url=' . $a->get_baseurl() . '/search?tag=' . rawurlencode($basetag) . ']' . $basetag . '[/url]',$body);
if(strlen($str_tags))
$str_tags .= ',';
- $str_tags .= '#[url=' . $a->get_baseurl() . '/search?search=' . rawurlencode($basetag) . ']' . $basetag . '[/url]';
+ $str_tags .= '#[url=' . $a->get_baseurl() . '/search?tag=' . rawurlencode($basetag) . ']' . $basetag . '[/url]';
continue;
}
}
@@ -1172,7 +1180,7 @@ function diaspora_comment($importer,$xml,$msg) {
proc_run('php','include/notifier.php','comment',$message_id);
}
- $myconv = q("SELECT `author-link`, `author-avatar`, `parent` FROM `item` WHERE `parent-uri` = '%s' AND `uid` = %d AND `parent` != 0 ",
+ $myconv = q("SELECT `author-link`, `author-avatar`, `parent` FROM `item` WHERE `parent-uri` = '%s' AND `uid` = %d AND `parent` != 0 AND `deleted` = 0 ",
dbesc($parent_item['uri']),
intval($importer['uid'])
);
@@ -2298,14 +2306,20 @@ function diaspora_transmit($owner,$contact,$slap,$public_batch) {
logger('diaspora_transmit: ' . $logid . ' ' . $dest_url);
- if(! intval(get_config('system','diaspora_test')))
- post_url($dest_url . '/', $slap);
+ if(was_recently_delayed($contact['id'])) {
+ $return_code = 0;
+ }
else {
- logger('diaspora_transmit: test_mode');
- return 200;
+ if(! intval(get_config('system','diaspora_test'))) {
+ post_url($dest_url . '/', $slap);
+ $return_code = $a->get_curl_code();
+ }
+ else {
+ logger('diaspora_transmit: test_mode');
+ return 200;
+ }
}
-
- $return_code = $a->get_curl_code();
+
logger('diaspora_transmit: ' . $logid . ' returns: ' . $return_code);
if((! $return_code) || (($return_code == 503) && (stristr($a->get_curl_headers(),'retry-after')))) {
diff --git a/include/enotify.php b/include/enotify.php
index 8385bdec5..ca134ac86 100644
--- a/include/enotify.php
+++ b/include/enotify.php
@@ -402,8 +402,8 @@ class enotify {
*/
static public function send($params) {
- $fromName = email_header_encode($params['fromName'],'UTF-8');
- $messageSubject = email_header_encode($params['messageSubject'],'UTF-8');
+ $fromName = email_header_encode(html_entity_decode($params['fromName'],ENT_QUOTES,'UTF-8'),'UTF-8');
+ $messageSubject = email_header_encode(html_entity_decode($params['messageSubject'],ENT_QUOTES,'UTF-8'),'UTF-8');
// generate a mime boundary
$mimeBoundary =rand(0,9)."-"
diff --git a/include/expire.php b/include/expire.php
index 5fa0ec758..755cd2494 100644
--- a/include/expire.php
+++ b/include/expire.php
@@ -32,7 +32,11 @@ function expire_run($argv, $argc){
// physically remove anything that has been deleted for more than two months
$r = q("delete from item where deleted = 1 and changed < UTC_TIMESTAMP() - INTERVAL 60 DAY");
- q("optimize table item");
+
+ // make this optional as it could have a performance impact on large sites
+
+ if(intval(get_config('system','optimize_items')))
+ q("optimize table item");
logger('expire: start');
diff --git a/include/gprobe.php b/include/gprobe.php
new file mode 100644
index 000000000..5ca42729a
--- /dev/null
+++ b/include/gprobe.php
@@ -0,0 +1,65 @@
+<?php
+
+require_once("boot.php");
+require_once('include/Scrape.php');
+require_once('include/socgraph.php');
+
+function gprobe_run($argv, $argc){
+ global $a, $db;
+
+ if(is_null($a)) {
+ $a = new App;
+ }
+
+ if(is_null($db)) {
+ @include(".htconfig.php");
+ require_once("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');
+
+ load_config('config');
+ load_config('system');
+
+ $a->set_baseurl(get_config('system','url'));
+
+ load_hooks();
+
+ if($argc != 2)
+ return;
+
+ $url = hex2bin($argv[1]);
+
+ $r = q("select * from gcontact where nurl = '%s' limit 1",
+ dbesc(normalise_link($url))
+ );
+
+ if(! count($r)) {
+
+ $arr = probe_url($url);
+ if(count($arr) && x($arr,'network') && $arr['network'] === NETWORK_DFRN) {
+ q("insert into `gcontact` (`name`,`url`,`nurl`,`photo`)
+ values ( '%s', '%s', '%s', '%s') ",
+ dbesc($arr['name']),
+ dbesc($arr['url']),
+ dbesc(normalise_link($arr['url'])),
+ dbesc($arr['photo'])
+ );
+ }
+ $r = q("select * from gcontact where nurl = '%s' limit 1",
+ dbesc(normalise_link($url))
+ );
+ }
+ if(count($r))
+ poco_load(0,0,$r[0]['id'], str_replace('/profile/','/poco/',$r[0]['url']));
+
+ return;
+}
+
+if (array_search(__file__,get_included_files())===0){
+ gprobe_run($argv,$argc);
+ killme();
+}
diff --git a/include/group.php b/include/group.php
index edb547de6..854ac06a9 100644
--- a/include/group.php
+++ b/include/group.php
@@ -97,8 +97,9 @@ function group_rmv_member($uid,$name,$member) {
}
-function group_add_member($uid,$name,$member) {
- $gid = group_byname($uid,$name);
+function group_add_member($uid,$name,$member,$gid = 0) {
+ if(! $gid)
+ $gid = group_byname($uid,$name);
if((! $gid) || (! $uid) || (! $member))
return false;
@@ -154,6 +155,32 @@ function group_public_members($gid) {
}
+function mini_group_select($uid,$gid = 0) {
+
+ $grps = array();
+ $o = '';
+
+ $r = q("SELECT * FROM `group` WHERE `deleted` = 0 AND `uid` = %d ORDER BY `name` ASC",
+ intval($uid)
+ );
+ $grps[] = array('name' => '', 'id' => '0', 'selected' => '');
+ if(count($r)) {
+ foreach($r as $rr) {
+ $grps[] = array('name' => $rr['name'], 'id' => $rr['id'], 'selected' => (($gid == $rr['id']) ? 'true' : ''));
+ }
+
+ }
+ logger('groups: ' . print_r($grps,true));
+
+ $o = replace_macros(get_markup_template('group_selection.tpl'), array(
+ '$label' => t('Default privacy group for new contacts'),
+ '$groups' => $grps
+ ));
+ return $o;
+}
+
+
+
function group_side($every="contacts",$each="group",$edit = false, $group_id = 0, $cid = 0) {
diff --git a/include/html2plain.php b/include/html2plain.php
index 21261327d..839dd70a7 100644
--- a/include/html2plain.php
+++ b/include/html2plain.php
@@ -83,7 +83,7 @@ function collecturls($message) {
$urls = array();
foreach ($result as $treffer) {
// A list of some links that should be ignored
- $list = array("/user/", "/tag/", "/group/", "/profile/", "/search?search=", "mailto:", "/u/", "/node/",
+ $list = array("/user/", "/tag/", "/group/", "/profile/", "/search?search=", "/search?tag=", "mailto:", "/u/", "/node/",
"//facebook.com/profile.php?id=", "//plus.google.com/");
foreach ($list as $listitem)
if (strpos($treffer[1], $listitem) !== false)
diff --git a/include/items.php b/include/items.php
index 0a8bc12c0..91c9056fe 100644
--- a/include/items.php
+++ b/include/items.php
@@ -119,7 +119,7 @@ function get_feed_for(&$a, $dfrn_id, $owner_nick, $last_update, $direction = 0)
$check_date = datetime_convert('UTC','UTC',$last_update,'Y-m-d H:i:s');
$r = q("SELECT `item`.*, `item`.`id` AS `item_id`,
- `contact`.`name`, `contact`.`photo`, `contact`.`url`,
+ `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`,
@@ -952,13 +952,15 @@ function tag_deliver($uid,$item_id) {
$mention = false;
- $u = q("select uid, nickname, language, username, email, `page-flags`, `notify-flags` from user where uid = %d limit 1",
+ $u = q("select * from user where uid = %d limit 1",
intval($uid)
);
if(! count($u))
return;
$community_page = (($u[0]['page-flags'] == PAGE_COMMUNITY) ? true : false);
+ $prvgroup = (($u[0]['page-flags'] == PAGE_PRVGROUP) ? true : false);
+
$i = q("select * from item where id = %d and uid = %d limit 1",
intval($item_id),
@@ -1008,9 +1010,10 @@ function tag_deliver($uid,$item_id) {
'otype' => 'item'
));
- if(! $community_page)
+ if((! $community_page) && (! prvgroup))
return;
+
// tgroup delivery - setup a second delivery chain
// prevent delivery looping - only proceed
// if the message originated elsewhere and is a top-level post
@@ -1027,10 +1030,23 @@ function tag_deliver($uid,$item_id) {
if(! count($c))
return;
- q("update item set wall = 1, origin = 1, forum_mode = 1, `owner-name` = '%s', `owner-link` = '%s', `owner-avatar` = '%s' where id = %d limit 1",
+ // also reset all the privacy bits to the forum default permissions
+
+ $private = ($u[0]['allow_cid'] || $u[0]['allow_gid'] || $u[0]['deny_cid'] || $u[0]['deny_gid']) ? 1 : 0;
+
+ $forum_mode = (($prvgroup) ? 2 : 1);
+
+ q("update item set wall = 1, origin = 1, forum_mode = %d, `owner-name` = '%s', `owner-link` = '%s', `owner-avatar` = '%s',
+ `private` = %d, `allow_cid` = '%s', `allow_gid` = '%s', `deny_cid` = '%s', `deny_gid` = '%s' where id = %d limit 1",
+ intval($forum_mode),
dbesc($c[0]['name']),
dbesc($c[0]['url']),
dbesc($c[0]['thumb']),
+ intval($private),
+ dbesc($u[0]['allow_cid']),
+ dbesc($u[0]['allow_gid']),
+ dbesc($u[0]['deny_cid']),
+ dbesc($u[0]['deny_gid']),
intval($item_id)
);
@@ -2184,7 +2200,7 @@ function local_delivery($importer,$data) {
if($is_reply) {
$community = false;
- if($importer['page-flags'] == PAGE_COMMUNITY) {
+ if($importer['page-flags'] == PAGE_COMMUNITY || $importer['page-flags'] == PAGE_PRVGROUP ) {
$sql_extra = '';
$community = true;
logger('local_delivery: possible community reply');
@@ -2211,8 +2227,8 @@ function local_delivery($importer,$data) {
if($r && count($r))
$is_a_remote_comment = true;
- // Does this have the characteristics of a community comment?
- // If it's a reply to a wall post on a community page it's a
+ // Does this have the characteristics of a community or private group comment?
+ // If it's a reply to a wall post on a community/prvgroup page it's a
// valid community comment. Also forum_mode makes it valid for sure.
// If neither, it's not.
@@ -2227,10 +2243,10 @@ function local_delivery($importer,$data) {
logger('local_delivery: received remote comment');
$is_like = false;
// remote reply to our post. Import and then notify everybody else.
- $datarray = get_atom_elements($feed,$item);
+ $datarray = get_atom_elements($feed,$item);
- $r = q("SELECT `id`, `uid`, `last-child`, `edited`, `body` FROM `item` WHERE `uri` = '%s' AND `uid` = %d LIMIT 1",
+ $r = q("SELECT `id`, `uid`, `last-child`, `edited`, `body` FROM `item` WHERE `uri` = '%s' AND `uid` = %d LIMIT 1",
dbesc($item_id),
intval($importer['importer_uid'])
);
@@ -2266,14 +2282,22 @@ function local_delivery($importer,$data) {
// return 0;
// }
+ // our user with $importer['importer_uid'] is the owner
+
+ $own = q("select name,url,thumb from contact where uid = %d and self = 1 limit 1",
+ intval($importer['importer_uid'])
+ );
+
+
$datarray['type'] = 'remote-comment';
$datarray['wall'] = 1;
$datarray['parent-uri'] = $parent_uri;
$datarray['uid'] = $importer['importer_uid'];
- $datarray['owner-name'] = $r[0]['name'];
- $datarray['owner-link'] = $r[0]['url'];
- $datarray['owner-avatar'] = $r[0]['thumb'];
+ $datarray['owner-name'] = $own[0]['name'];
+ $datarray['owner-link'] = $own[0]['url'];
+ $datarray['owner-avatar'] = $own[0]['thumb'];
$datarray['contact-id'] = $importer['id'];
+
if(($datarray['verb'] === ACTIVITY_LIKE) || ($datarray['verb'] === ACTIVITY_DISLIKE)) {
$is_like = true;
$datarray['type'] = 'activity';
@@ -2290,26 +2314,34 @@ function local_delivery($importer,$data) {
}
if(($datarray['verb'] === ACTIVITY_TAG) && ($datarray['object-type'] === ACTIVITY_OBJ_TAGTERM)) {
-
-
+
$xo = parse_xml_string($datarray['object'],false);
$xt = parse_xml_string($datarray['target'],false);
- if(($xt->type == ACTIVITY_OBJ_NOTE) && ($xt->id == $r[0]['uri'])) {
+ if(($xt->type == ACTIVITY_OBJ_NOTE) && ($xt->id)) {
+
+ // fetch the parent item
+
+ $tagp = q("select * from item where uri = '%s' and uid = %d limit 1",
+ dbesc($xt->id),
+ intval($importer['importer_uid'])
+ );
+ if(! count($tagp))
+ continue;
// extract tag, if not duplicate, and this user allows tags, add to parent item
if($xo->id && $xo->content) {
$newtag = '#[url=' . $xo->id . ']'. $xo->content . '[/url]';
-
- if(! (stristr($r[0]['tag'],$newtag))) {
+ if(! (stristr($tagp[0]['tag'],$newtag))) {
$i = q("SELECT `blocktags` FROM `user` where `uid` = %d LIMIT 1",
intval($importer['importer_uid'])
);
- if(count($i) && ! ($i[0]['blocktags'])) {
- q("UPDATE item SET tag = '%s' WHERE id = %d LIMIT 1",
- dbesc($r[0]['tag'] . (strlen($r[0]['tag']) ? ',' : '') . $newtag),
- intval($r[0]['id'])
+ if(count($i) && ! intval($i[0]['blocktags'])) {
+ q("UPDATE item SET tag = '%s', `edited` = '%s' WHERE id = %d LIMIT 1",
+ dbesc($tagp[0]['tag'] . (strlen($tagp[0]['tag']) ? ',' : '') . $newtag),
+ intval($tagp[0]['id']),
+ dbesc(datetime_convert())
);
}
}
@@ -2479,7 +2511,7 @@ function local_delivery($importer,$data) {
if(!x($datarray['type']) || $datarray['type'] != 'activity') {
- $myconv = q("SELECT `author-link`, `author-avatar`, `parent` FROM `item` WHERE `parent-uri` = '%s' AND `uid` = %d AND `parent` != 0 ",
+ $myconv = q("SELECT `author-link`, `author-avatar`, `parent` FROM `item` WHERE `parent-uri` = '%s' AND `uid` = %d AND `parent` != 0 AND `deleted` = 0",
dbesc($parent_uri),
intval($importer['importer_uid'])
);
@@ -2685,6 +2717,12 @@ function new_follower($importer,$contact,$datarray,$item,$sharing = false) {
);
$a = get_app();
if(count($r)) {
+
+ if(intval($r[0]['def_gid'])) {
+ require_once('include/group.php');
+ group_add_member($r[0]['uid'],'',$contact_record['id'],$r[0]['def_gid']);
+ }
+
if(($r[0]['notify-flags'] & NOTIFY_INTRO) && ($r[0]['page-flags'] == PAGE_NORMAL)) {
$email_tpl = get_intltext_template('follow_notify_eml.tpl');
$email = replace_macros($email_tpl, array(
@@ -3013,32 +3051,7 @@ function item_expire($uid,$days) {
if($expire_items==0 && $item['type']!='note')
continue;
-
- $r = q("UPDATE `item` SET `deleted` = 1, `edited` = '%s', `changed` = '%s' WHERE `id` = %d LIMIT 1",
- dbesc(datetime_convert()),
- dbesc(datetime_convert()),
- intval($item['id'])
- );
-
- $r = q("DELETE FROM item_id where iid in (select id from item where parent = %d) and uid = %d",
- intval($item['id']),
- intval($uid)
- );
-
- $r = q("DELETE FROM sign where iid in (select id from item where parent = %d) and uid = %d",
- intval($item['id']),
- intval($uid)
- );
-
- // kill the kids
-
- $r = q("UPDATE `item` SET `deleted` = 1, `edited` = '%s', `changed` = '%s' WHERE `parent-uri` = '%s' AND `uid` = %d ",
- dbesc(datetime_convert()),
- dbesc(datetime_convert()),
- dbesc($item['parent-uri']),
- intval($item['uid'])
- );
-
+ drop_item($item['id'],false);
}
proc_run('php',"include/notifier.php","expire","$uid");
@@ -3100,6 +3113,25 @@ function drop_item($id,$interactive = true) {
intval($item['id'])
);
+ // clean up categories and tags so they don't end up as orphans
+
+ $matches = false;
+ $cnt = preg_match_all('/<(.*?)>/',$item['file'],$matches,PREG_SET_ORDER);
+ if($cnt) {
+ foreach($matches as $mtch) {
+ file_tag_unsave_file($item['uid'],$item['id'],$mtch[1],true);
+ }
+ }
+
+ $matches = false;
+
+ $cnt = preg_match_all('/\[(.*?)\]/',$item['file'],$matches,PREG_SET_ORDER);
+ if($cnt) {
+ foreach($matches as $mtch) {
+ file_tag_unsave_file($item['uid'],$item['id'],$mtch[1],false);
+ }
+ }
+
// If item is a link to a photo resource, nuke all the associated photos
// (visitors will not have photo resources)
// This only applies to photos uploaded from the photos page. Photos inserted into a post do not
@@ -3123,6 +3155,17 @@ function drop_item($id,$interactive = true) {
// ignore the result
}
+ // clean up item_id and sign meta-data tables
+
+ $r = q("DELETE FROM item_id where iid in (select id from item where parent = %d and uid = %d)",
+ intval($item['id']),
+ intval($item['uid'])
+ );
+
+ $r = q("DELETE FROM sign where iid in (select id from item where parent = %d and uid = %d)",
+ intval($item['id']),
+ intval($item['uid'])
+ );
// If it's the parent of a comment thread, kill all the kids
@@ -3155,7 +3198,7 @@ function drop_item($id,$interactive = true) {
}
}
$drop_id = intval($item['id']);
-
+
// send the notification upstream/downstream as the case may be
if(! $interactive)
diff --git a/include/network.php b/include/network.php
index 4bec4a172..eeb2460d1 100644
--- a/include/network.php
+++ b/include/network.php
@@ -583,7 +583,7 @@ function fetch_xrd_links($url) {
// Take a URL from the wild, prepend http:// if necessary
-// and check DNS to see if it's real
+// and check DNS to see if it's real (or check if is a valid IP address)
// return true if it's OK, false if something is wrong with it
if(! function_exists('validate_url')) {
@@ -596,7 +596,7 @@ function validate_url(&$url) {
$url = 'http://' . $url;
$h = @parse_url($url);
- if(($h) && (dns_get_record($h['host'], DNS_A + DNS_CNAME + DNS_PTR))) {
+ if(($h) && (dns_get_record($h['host'], DNS_A + DNS_CNAME + DNS_PTR) || filter_var($h['host'], FILTER_VALIDATE_IP) )) {
return true;
}
return false;
@@ -611,7 +611,7 @@ function validate_email($addr) {
return false;
$h = substr($addr,strpos($addr,'@') + 1);
- if(($h) && (dns_get_record($h, DNS_A + DNS_CNAME + DNS_PTR + DNS_MX))) {
+ if(($h) && (dns_get_record($h, DNS_A + DNS_CNAME + DNS_PTR + DNS_MX) || filter_var($h['host'], FILTER_VALIDATE_IP) )) {
return true;
}
return false;
@@ -876,3 +876,167 @@ function fix_contact_ssl_policy(&$contact,$new_policy) {
}
}
+
+
+/**
+ * xml2array() 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...)
+ * Arguments : $contents - The XML text
+ * $namespaces - true or false include namespace information in the returned array as array elements.
+ * $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.
+ * $priority - Can be 'tag' or 'attribute'. This will change the way the resulting array sturcture. For 'tag', the tags are given more importance.
+ * Return: The parsed XML in an array form. Use print_r() to see the resulting array structure.
+ * Examples: $array = xml2array(file_get_contents('feed.xml'));
+ * $array = xml2array(file_get_contents('feed.xml', true, 1, 'attribute'));
+ */
+
+function xml2array($contents, $namespaces = true, $get_attributes=1, $priority = 'attribute') {
+ if(!$contents) return array();
+
+ if(!function_exists('xml_parser_create')) {
+ logger('xml2array: parser function missing');
+ return array();
+ }
+
+
+ libxml_use_internal_errors(true);
+ libxml_clear_errors();
+
+ if($namespaces)
+ $parser = @xml_parser_create_ns("UTF-8",':');
+ else
+ $parser = @xml_parser_create();
+
+ if(! $parser) {
+ logger('xml2array: xml_parser_create: no resource');
+ return array();
+ }
+
+ xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, "UTF-8");
+ // http://minutillo.com/steve/weblog/2004/6/17/php-xml-and-character-encodings-a-tale-of-sadness-rage-and-data-loss
+ xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
+ xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);
+ @xml_parse_into_struct($parser, trim($contents), $xml_values);
+ @xml_parser_free($parser);
+
+ if(! $xml_values) {
+ logger('xml2array: libxml: parse error: ' . $contents, LOGGER_DATA);
+ foreach(libxml_get_errors() as $err)
+ logger('libxml: parse: ' . $err->code . " at " . $err->line . ":" . $err->column . " : " . $err->message, LOGGER_DATA);
+ libxml_clear_errors();
+ return;
+ }
+
+ //Initializations
+ $xml_array = array();
+ $parents = array();
+ $opened_tags = array();
+ $arr = array();
+
+ $current = &$xml_array; // Reference
+
+ // Go through the tags.
+ $repeated_tag_index = array(); // Multiple tags with same name will be turned into an array
+ foreach($xml_values as $data) {
+ unset($attributes,$value); // Remove existing values, or there will be trouble
+
+ // This command will extract these variables into the foreach scope
+ // tag(string), type(string), level(int), attributes(array).
+ extract($data); // We could use the array by itself, but this cooler.
+
+ $result = array();
+ $attributes_data = array();
+
+ if(isset($value)) {
+ if($priority == 'tag') $result = $value;
+ else $result['value'] = $value; // Put the value in a assoc array if we are in the 'Attribute' mode
+ }
+
+ //Set the attributes too.
+ if(isset($attributes) and $get_attributes) {
+ foreach($attributes as $attr => $val) {
+ if($priority == 'tag') $attributes_data[$attr] = $val;
+ else $result['@attributes'][$attr] = $val; // Set all the attributes in a array called 'attr'
+ }
+ }
+
+ // See tag status and do the needed.
+ if($namespaces && strpos($tag,':')) {
+ $namespc = substr($tag,0,strrpos($tag,':'));
+ $tag = strtolower(substr($tag,strlen($namespc)+1));
+ $result['@namespace'] = $namespc;
+ }
+ $tag = strtolower($tag);
+
+ if($type == "open") { // The starting of the tag '<tag>'
+ $parent[$level-1] = &$current;
+ if(!is_array($current) or (!in_array($tag, array_keys($current)))) { // Insert New tag
+ $current[$tag] = $result;
+ if($attributes_data) $current[$tag. '_attr'] = $attributes_data;
+ $repeated_tag_index[$tag.'_'.$level] = 1;
+
+ $current = &$current[$tag];
+
+ } else { // There was another element with the same tag name
+
+ if(isset($current[$tag][0])) { // If there is a 0th element it is already an array
+ $current[$tag][$repeated_tag_index[$tag.'_'.$level]] = $result;
+ $repeated_tag_index[$tag.'_'.$level]++;
+ } else { // This section will make the value an array if multiple tags with the same name appear together
+ $current[$tag] = array($current[$tag],$result); // This will combine the existing item and the new item together to make an array
+ $repeated_tag_index[$tag.'_'.$level] = 2;
+
+ if(isset($current[$tag.'_attr'])) { // The attribute of the last(0th) tag must be moved as well
+ $current[$tag]['0_attr'] = $current[$tag.'_attr'];
+ unset($current[$tag.'_attr']);
+ }
+
+ }
+ $last_item_index = $repeated_tag_index[$tag.'_'.$level]-1;
+ $current = &$current[$tag][$last_item_index];
+ }
+
+ } elseif($type == "complete") { // Tags that ends in 1 line '<tag />'
+ //See if the key is already taken.
+ if(!isset($current[$tag])) { //New Key
+ $current[$tag] = $result;
+ $repeated_tag_index[$tag.'_'.$level] = 1;
+ if($priority == 'tag' and $attributes_data) $current[$tag. '_attr'] = $attributes_data;
+
+ } else { // If taken, put all things inside a list(array)
+ if(isset($current[$tag][0]) and is_array($current[$tag])) { // If it is already an array...
+
+ // ...push the new element into that array.
+ $current[$tag][$repeated_tag_index[$tag.'_'.$level]] = $result;
+
+ if($priority == 'tag' and $get_attributes and $attributes_data) {
+ $current[$tag][$repeated_tag_index[$tag.'_'.$level] . '_attr'] = $attributes_data;
+ }
+ $repeated_tag_index[$tag.'_'.$level]++;
+
+ } else { // If it is not an array...
+ $current[$tag] = array($current[$tag],$result); //...Make it an array using using the existing value and the new value
+ $repeated_tag_index[$tag.'_'.$level] = 1;
+ if($priority == 'tag' and $get_attributes) {
+ if(isset($current[$tag.'_attr'])) { // The attribute of the last(0th) tag must be moved as well
+
+ $current[$tag]['0_attr'] = $current[$tag.'_attr'];
+ unset($current[$tag.'_attr']);
+ }
+
+ if($attributes_data) {
+ $current[$tag][$repeated_tag_index[$tag.'_'.$level] . '_attr'] = $attributes_data;
+ }
+ }
+ $repeated_tag_index[$tag.'_'.$level]++; // 0 and 1 indexes are already taken
+ }
+ }
+
+ } elseif($type == 'close') { // End of tag '</tag>'
+ $current = &$parent[$level-1];
+ }
+ }
+
+ return($xml_array);
+}
diff --git a/include/notifier.php b/include/notifier.php
index ca7c7b92e..8b904dbcd 100644
--- a/include/notifier.php
+++ b/include/notifier.php
@@ -47,7 +47,7 @@ function notifier_run($argv, $argc){
$a->set_baseurl(get_config('system','url'));
- logger('notifier: invoked: ' . print_r($argv,true));
+ logger('notifier: invoked: ' . print_r($argv,true), LOGGER_DEBUG);
$cmd = $argv[1];
@@ -220,7 +220,7 @@ function notifier_run($argv, $argc){
}
- if(($cmd === 'uplink') && (intval($parent['forum_mode'])) && (! $top_level)) {
+ if(($cmd === 'uplink') && (intval($parent['forum_mode']) == 1) && (! $top_level)) {
$relay_to_owner = true;
}
@@ -265,10 +265,10 @@ function notifier_run($argv, $argc){
$deny_people = expand_acl($parent['deny_cid']);
$deny_groups = expand_groups(expand_acl($parent['deny_gid']));
- // if our parent is a forum, uplink to the origional author causing
- // a delivery fork
+ // if our parent is a public forum (forum_mode == 1), uplink to the origional author causing
+ // a delivery fork. private groups (forum_mode == 2) do not uplink
- if(intval($parent['forum_mode']) && (! $top_level) && ($cmd !== 'uplink')) {
+ if((intval($parent['forum_mode']) == 1) && (! $top_level) && ($cmd !== 'uplink')) {
proc_run('php','include/notifier','uplink',$item_id);
}
@@ -304,7 +304,7 @@ function notifier_run($argv, $argc){
$conversant_str = dbesc(implode(', ',$conversants));
}
- $r = q("SELECT * FROM `contact` WHERE `id` IN ( $conversant_str ) AND `blocked` = 0 AND `pending` = 0");
+ $r = q("SELECT * FROM `contact` WHERE `id` IN ( $conversant_str ) AND `blocked` = 0 AND `pending` = 0 AND `archive` = 0");
if(count($r))
$contacts = $r;
@@ -478,6 +478,12 @@ function notifier_run($argv, $argc){
}
}
+ $deliveries_per_process = intval(get_config('system','delivery_batch_count'));
+ if($deliveries_per_process <= 0)
+ $deliveries_per_process = 1;
+
+ $this_batch = array();
+
foreach($r as $contact) {
if($contact['self'])
continue;
@@ -486,6 +492,7 @@ function notifier_run($argv, $argc){
// we will deliver single recipient types of message and email receipients here.
if((! $mail) && (! $fsuggest) && (! $followup)) {
+ // deliveries per process not yet implemented, 1 delivery per process.
proc_run('php','include/delivery.php',$cmd,$item_id,$contact['id']);
if($interval)
@time_sleep_until(microtime(true) + (float) $interval);
@@ -520,7 +527,8 @@ function notifier_run($argv, $argc){
`user`.*
FROM `contact`
LEFT JOIN `user` ON `contact`.`uid` = `user`.`uid`
- WHERE `contact`.`blocked` = 0 AND `contact`.`pending` = 0
+ WHERE `contact`.`blocked` = 0 AND `contact`.`archive` = 0
+ AND `contact`.`pending` = 0
AND `contact`.`network` = '%s' AND `user`.`nickname` = '%s'
$sql_extra
AND `user`.`account_expired` = 0 LIMIT 1",
@@ -769,7 +777,7 @@ function notifier_run($argv, $argc){
);
$r2 = q("SELECT `id`, `name`,`network` FROM `contact`
- WHERE `network` in ( '%s', '%s') AND `uid` = %d AND `blocked` = 0 AND `pending` = 0
+ WHERE `network` in ( '%s', '%s') AND `uid` = %d AND `blocked` = 0 AND `pending` = 0 AND `archive` = 0
AND `rel` != %d order by rand() ",
dbesc(NETWORK_DFRN),
dbesc(NETWORK_MAIL2),
@@ -832,6 +840,8 @@ function notifier_run($argv, $argc){
}
+ logger('notifier: calling hooks', LOGGER_DEBUG);
+
if($normal_mode)
call_hooks('notifier_normal',$target_item);
diff --git a/include/onepoll.php b/include/onepoll.php
new file mode 100644
index 000000000..a64922aa3
--- /dev/null
+++ b/include/onepoll.php
@@ -0,0 +1,523 @@
+<?php
+
+require_once("boot.php");
+
+function onepoll_run($argv, $argc){
+ global $a, $db;
+
+ if(is_null($a)) {
+ $a = new App;
+ }
+
+ if(is_null($db)) {
+ @include(".htconfig.php");
+ require_once("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('library/simplepie/simplepie.inc');
+ require_once('include/items.php');
+ require_once('include/Contact.php');
+ require_once('include/email.php');
+ require_once('include/socgraph.php');
+ require_once('include/pidfile.php');
+ require_once('include/queue_fn.php');
+
+ load_config('config');
+ load_config('system');
+
+ $a->set_baseurl(get_config('system','url'));
+
+ load_hooks();
+
+ logger('onepoll: start');
+
+ $abandon_days = intval(get_config('system','account_abandon_days'));
+ if($abandon_days < 1)
+ $abandon_days = 0;
+
+
+ $manual_id = 0;
+ $generation = 0;
+ $hub_update = false;
+ $force = false;
+ $restart = false;
+
+ if(($argc > 1) && (intval($argv[1])))
+ $contact_id = intval($argv[1]);
+
+ if(! $contact_id) {
+ logger('onepoll: no contact');
+ return;
+ }
+
+ if(was_recently_delayed($contact_id))
+ return;
+
+ $d = datetime_convert();
+
+ // Only poll from those with suitable relationships,
+ // 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_sql = (($abandon_days)
+ ? sprintf(" AND `user`.`login_date` > UTC_TIMESTAMP() - INTERVAL %d DAY ", intval($abandon_days))
+ : ''
+ );
+
+ $contacts = q("SELECT `contact`.* FROM `contact`
+ WHERE ( `rel` = %d OR `rel` = %d ) AND `poll` != ''
+ AND NOT `network` IN ( '%s', '%s' )
+ AND `contact`.`id` = %d
+ AND `self` = 0 AND `contact`.`blocked` = 0 AND `contact`.`readonly` = 0
+ AND `contact`.`archive` = 0 LIMIT 1",
+ intval(CONTACT_IS_SHARING),
+ intval(CONTACT_IS_FRIEND),
+ dbesc(NETWORK_DIASPORA),
+ dbesc(NETWORK_FACEBOOK),
+ intval($contact_id)
+ );
+
+ if(! count($contacts)) {
+ return;
+ }
+
+ $contact = $contacts[0];
+
+
+ $xml = false;
+
+ $t = $contact['last-update'];
+
+ if($contact['subhub']) {
+ $interval = get_config('system','pushpoll_frequency');
+ $contact['priority'] = (($interval !== false) ? intval($interval) : 3);
+ $hub_update = false;
+
+ if(datetime_convert('UTC','UTC', 'now') > datetime_convert('UTC','UTC', $t . " + 1 day"))
+ $hub_update = true;
+ }
+ else
+ $hub_update = false;
+
+
+ $importer_uid = $contact['uid'];
+
+ $r = q("SELECT `contact`.*, `user`.`page-flags` FROM `contact` LEFT JOIN `user` on `contact`.`uid` = `user`.`uid` WHERE `user`.`uid` = %d AND `contact`.`self` = 1 LIMIT 1",
+ intval($importer_uid)
+ );
+ if(! count($r))
+ return;
+
+ $importer = $r[0];
+
+ logger("onepoll: poll: ({$contact['id']}) IMPORTER: {$importer['name']}, CONTACT: {$contact['name']}");
+
+ $last_update = (($contact['last-update'] === '0000-00-00 00:00:00')
+ ? datetime_convert('UTC','UTC','now - 7 days', ATOM_TIME)
+ : datetime_convert('UTC','UTC',$contact['last-update'], ATOM_TIME)
+ );
+
+ if($contact['network'] === NETWORK_DFRN) {
+
+ $idtosend = $orig_id = (($contact['dfrn-id']) ? $contact['dfrn-id'] : $contact['issued-id']);
+ if(intval($contact['duplex']) && $contact['dfrn-id'])
+ $idtosend = '0:' . $orig_id;
+ if(intval($contact['duplex']) && $contact['issued-id'])
+ $idtosend = '1:' . $orig_id;
+
+ // they have permission to write to us. We already filtered this in the contact query.
+ $perm = 'rw';
+
+ $url = $contact['poll'] . '?dfrn_id=' . $idtosend
+ . '&dfrn_version=' . DFRN_PROTOCOL_VERSION
+ . '&type=data&last_update=' . $last_update
+ . '&perm=' . $perm ;
+
+ $handshake_xml = fetch_url($url);
+
+ logger('onepoll: handshake with url ' . $url . ' returns xml: ' . $handshake_xml, LOGGER_DATA);
+
+
+ if(! $handshake_xml) {
+ logger("poller: $url appears to be dead - marking for death ");
+ // dead connection - might be a transient event, or this might
+ // mean the software was uninstalled or the domain expired.
+ // Will keep trying for one month.
+ mark_for_death($contact);
+
+ // set the last-update so we don't keep polling
+ $r = q("UPDATE `contact` SET `last-update` = '%s' WHERE `id` = %d LIMIT 1",
+ dbesc(datetime_convert()),
+ intval($contact['id'])
+ );
+
+ return;
+ }
+
+ if(! strstr($handshake_xml,'<?xml')) {
+ logger('poller: response from ' . $url . ' did not contain XML.');
+ $r = q("UPDATE `contact` SET `last-update` = '%s' WHERE `id` = %d LIMIT 1",
+ dbesc(datetime_convert()),
+ intval($contact['id'])
+ );
+ return;
+ }
+
+
+ $res = parse_xml_string($handshake_xml);
+
+ if(intval($res->status) == 1) {
+ logger("poller: $url replied status 1 - marking for death ");
+
+ // we may not be friends anymore. Will keep trying for one month.
+ // set the last-update so we don't keep polling
+
+
+ $r = q("UPDATE `contact` SET `last-update` = '%s' WHERE `id` = %d LIMIT 1",
+ dbesc(datetime_convert()),
+ intval($contact['id'])
+ );
+ mark_for_death($contact);
+ }
+ else {
+ if($contact['term-date'] != '0000-00-00 00:00:00') {
+ logger("poller: $url back from the dead - removing mark for death");
+ unmark_for_death($contact);
+ }
+ }
+
+ if((intval($res->status) != 0) || (! strlen($res->challenge)) || (! strlen($res->dfrn_id)))
+ return;
+
+ if(((float) $res->dfrn_version > 2.21) && ($contact['poco'] == '')) {
+ q("update contact set poco = '%s' where id = %d limit 1",
+ dbesc(str_replace('/profile/','/poco/', $contact['url'])),
+ intval($contact['id'])
+ );
+ }
+
+ $postvars = array();
+
+ $sent_dfrn_id = hex2bin((string) $res->dfrn_id);
+ $challenge = hex2bin((string) $res->challenge);
+
+ $final_dfrn_id = '';
+
+ if(($contact['duplex']) && strlen($contact['prvkey'])) {
+ openssl_private_decrypt($sent_dfrn_id,$final_dfrn_id,$contact['prvkey']);
+ openssl_private_decrypt($challenge,$postvars['challenge'],$contact['prvkey']);
+ }
+ else {
+ openssl_public_decrypt($sent_dfrn_id,$final_dfrn_id,$contact['pubkey']);
+ openssl_public_decrypt($challenge,$postvars['challenge'],$contact['pubkey']);
+ }
+
+ $final_dfrn_id = substr($final_dfrn_id, 0, strpos($final_dfrn_id, '.'));
+
+ if(strpos($final_dfrn_id,':') == 1)
+ $final_dfrn_id = substr($final_dfrn_id,2);
+
+ if($final_dfrn_id != $orig_id) {
+ logger('poller: ID did not decode: ' . $contact['id'] . ' orig: ' . $orig_id . ' final: ' . $final_dfrn_id);
+ // did not decode properly - cannot trust this site
+ return;
+ }
+
+ $postvars['dfrn_id'] = $idtosend;
+ $postvars['dfrn_version'] = DFRN_PROTOCOL_VERSION;
+ $postvars['perm'] = 'rw';
+
+ $xml = post_url($contact['poll'],$postvars);
+
+ }
+ elseif(($contact['network'] === NETWORK_OSTATUS)
+ || ($contact['network'] === NETWORK_DIASPORA)
+ || ($contact['network'] === NETWORK_FEED) ) {
+
+ // Upgrading DB fields from an older Friendica version
+ // Will only do this once per notify-enabled OStatus contact
+ // or if relationship changes
+
+ $stat_writeable = ((($contact['notify']) && ($contact['rel'] == CONTACT_IS_FOLLOWER || $contact['rel'] == CONTACT_IS_FRIEND)) ? 1 : 0);
+
+ if($stat_writeable != $contact['writable']) {
+ q("UPDATE `contact` SET `writable` = %d WHERE `id` = %d LIMIT 1",
+ intval($stat_writeable),
+ intval($contact['id'])
+ );
+ }
+
+ // Are we allowed to import from this person?
+
+ if($contact['rel'] == CONTACT_IS_FOLLOWER || $contact['blocked'] || $contact['readonly'])
+ return;
+
+ $xml = fetch_url($contact['poll']);
+ }
+ elseif($contact['network'] === NETWORK_MAIL || $contact['network'] === NETWORK_MAIL2) {
+
+ logger("onepoll: mail: Fetching", LOGGER_DEBUG);
+
+ $mail_disabled = ((function_exists('imap_open') && (! get_config('system','imap_disabled'))) ? 0 : 1);
+ if($mail_disabled)
+ return;
+
+ logger("onepoll: Mail: Enabled", LOGGER_DEBUG);
+
+ $mbox = null;
+ $x = q("SELECT `prvkey` FROM `user` WHERE `uid` = %d LIMIT 1",
+ intval($importer_uid)
+ );
+ $mailconf = q("SELECT * FROM `mailacct` WHERE `server` != '' AND `uid` = %d LIMIT 1",
+ intval($importer_uid)
+ );
+ if(count($x) && count($mailconf)) {
+ $mailbox = construct_mailbox_name($mailconf[0]);
+ $password = '';
+ openssl_private_decrypt(hex2bin($mailconf[0]['pass']),$password,$x[0]['prvkey']);
+ $mbox = email_connect($mailbox,$mailconf[0]['user'],$password);
+ unset($password);
+ logger("Mail: Connect");
+ if($mbox) {
+ q("UPDATE `mailacct` SET `last_check` = '%s' WHERE `id` = %d AND `uid` = %d LIMIT 1",
+ dbesc(datetime_convert()),
+ intval($mailconf[0]['id']),
+ intval($importer_uid)
+ );
+ }
+ }
+ if($mbox) {
+
+ $msgs = email_poll($mbox,$contact['addr']);
+
+ if(count($msgs)) {
+ logger("Mail: Parsing ".count($msgs)." mails.", LOGGER_DEBUG);
+
+ foreach($msgs as $msg_uid) {
+ logger("Mail: Parsing mail ".$msg_uid, LOGGER_DATA);
+
+ $datarray = array();
+ $meta = email_msg_meta($mbox,$msg_uid);
+ $headers = email_msg_headers($mbox,$msg_uid);
+
+ // look for a 'references' header and try and match with a parent item we have locally.
+
+ $raw_refs = ((x($headers,'references')) ? str_replace("\t",'',$headers['references']) : '');
+ $datarray['uri'] = msgid2iri(trim($meta->message_id,'<>'));
+
+ if($raw_refs) {
+ $refs_arr = explode(' ', $raw_refs);
+ if(count($refs_arr)) {
+ for($x = 0; $x < count($refs_arr); $x ++)
+ $refs_arr[$x] = "'" . msgid2iri(str_replace(array('<','>',' '),array('','',''),dbesc($refs_arr[$x]))) . "'";
+ }
+ $qstr = implode(',',$refs_arr);
+ $r = q("SELECT `uri` , `parent-uri` FROM `item` WHERE `uri` IN ( $qstr ) AND `uid` = %d LIMIT 1",
+ intval($importer_uid)
+ );
+ if(count($r))
+ $datarray['parent-uri'] = $r[0]['uri'];
+ }
+
+
+ if(! x($datarray,'parent-uri'))
+ $datarray['parent-uri'] = $datarray['uri'];
+
+ // Have we seen it before?
+ $r = q("SELECT * FROM `item` WHERE `uid` = %d AND `uri` = '%s' LIMIT 1",
+ intval($importer_uid),
+ dbesc($datarray['uri'])
+ );
+
+ if(count($r)) {
+// logger("Mail: Seen before ".$msg_uid);
+ if($meta->deleted && ! $r[0]['deleted']) {
+ q("UPDATE `item` SET `deleted` = 1, `changed` = '%s' WHERE `id` = %d LIMIT 1",
+ dbesc(datetime_convert()),
+ intval($r[0]['id'])
+ );
+ }
+ switch ($mailconf[0]['action']) {
+ case 0:
+ break;
+ case 1:
+ logger("Mail: Deleting ".$msg_uid);
+ imap_delete($mbox, $msg_uid, FT_UID);
+ break;
+ case 2:
+ logger("Mail: Mark as seen ".$msg_uid);
+ imap_setflag_full($mbox, $msg_uid, "\\Seen", ST_UID);
+ break;
+ case 3:
+ logger("Mail: Moving ".$msg_uid." to ".$mailconf[0]['movetofolder']);
+ imap_setflag_full($mbox, $msg_uid, "\\Seen", ST_UID);
+ if ($mailconf[0]['movetofolder'] != "")
+ imap_mail_move($mbox, $msg_uid, $mailconf[0]['movetofolder'], FT_UID);
+ break;
+ }
+ continue;
+ }
+
+ // Decoding the header
+ $subject = imap_mime_header_decode($meta->subject);
+ $datarray['title'] = "";
+ foreach($subject as $subpart)
+ if ($subpart->charset != "default")
+ $datarray['title'] .= iconv($subpart->charset, 'UTF-8//IGNORE', $subpart->text);
+ else
+ $datarray['title'] .= $subpart->text;
+
+ $datarray['title'] = notags(trim($datarray['title']));
+
+ //$datarray['title'] = notags(trim($meta->subject));
+ $datarray['created'] = datetime_convert('UTC','UTC',$meta->date);
+
+ // Is it reply?
+ $reply = ((substr(strtolower($datarray['title']), 0, 3) == "re:") or
+ (substr(strtolower($datarray['title']), 0, 3) == "re-") or
+ (raw_refs != ""));
+
+ $r = email_get_msg($mbox,$msg_uid, $reply);
+ if(! $r) {
+ logger("Mail: can't fetch msg ".$msg_uid);
+ continue;
+ }
+ $datarray['body'] = escape_tags($r['body']);
+
+ logger("Mail: Importing ".$msg_uid);
+
+ // some mailing lists have the original author as 'from' - add this sender info to msg body.
+ // todo: adding a gravatar for the original author would be cool
+
+ if(! stristr($meta->from,$contact['addr'])) {
+ $from = imap_mime_header_decode($meta->from);
+ $fromdecoded = "";
+ foreach($from as $frompart)
+ if ($frompart->charset != "default")
+ $fromdecoded .= iconv($frompart->charset, 'UTF-8//IGNORE', $frompart->text);
+ else
+ $fromdecoded .= $frompart->text;
+
+ $datarray['body'] = "[b]".t('From: ') . escape_tags($fromdecoded) . "[/b]\n\n" . $datarray['body'];
+ }
+
+ $datarray['uid'] = $importer_uid;
+ $datarray['contact-id'] = $contact['id'];
+ if($datarray['parent-uri'] === $datarray['uri'])
+ $datarray['private'] = 1;
+ if(($contact['network'] === NETWORK_MAIL) && (! get_pconfig($importer_uid,'system','allow_public_email_replies'))) {
+ $datarray['private'] = 1;
+ $datarray['allow_cid'] = '<' . $contact['id'] . '>';
+ }
+ $datarray['author-name'] = $contact['name'];
+ $datarray['author-link'] = 'mailbox';
+ $datarray['author-avatar'] = $contact['photo'];
+
+ $stored_item = item_store($datarray);
+ q("UPDATE `item` SET `last-child` = 0 WHERE `parent-uri` = '%s' AND `uid` = %d",
+ dbesc($datarray['parent-uri']),
+ intval($importer_uid)
+ );
+ q("UPDATE `item` SET `last-child` = 1 WHERE `id` = %d LIMIT 1",
+ intval($stored_item)
+ );
+ switch ($mailconf[0]['action']) {
+ case 0:
+ break;
+ case 1:
+ logger("Mail: Deleting ".$msg_uid);
+ imap_delete($mbox, $msg_uid, FT_UID);
+ break;
+ case 2:
+ logger("Mail: Mark as seen ".$msg_uid);
+ imap_setflag_full($mbox, $msg_uid, "\\Seen", ST_UID);
+ break;
+ case 3:
+ logger("Mail: Moving ".$msg_uid." to ".$mailconf[0]['movetofolder']);
+ imap_setflag_full($mbox, $msg_uid, "\\Seen", ST_UID);
+ if ($mailconf[0]['movetofolder'] != "")
+ imap_mail_move($mbox, $msg_uid, $mailconf[0]['movetofolder'], FT_UID);
+ break;
+ }
+ }
+ }
+ imap_close($mbox);
+ }
+ }
+ elseif($contact['network'] === NETWORK_FACEBOOK) {
+ // This is picked up by the Facebook plugin on a cron hook.
+ // Ignored here.
+ }
+
+ if($xml) {
+ logger('poller: received xml : ' . $xml, LOGGER_DATA);
+ if((! strstr($xml,'<?xml')) && (! strstr($xml,'<rss'))) {
+ logger('poller: post_handshake: response from ' . $url . ' did not contain XML.');
+ $r = q("UPDATE `contact` SET `last-update` = '%s' WHERE `id` = %d LIMIT 1",
+ dbesc(datetime_convert()),
+ intval($contact['id'])
+ );
+ return;
+ }
+
+
+ consume_feed($xml,$importer,$contact,$hub,1,1);
+
+
+ // do it twice. Ensures that children of parents which may be later in the stream aren't tossed
+
+ consume_feed($xml,$importer,$contact,$hub,1,2);
+
+ $hubmode = 'subscribe';
+ if($contact['network'] === NETWORK_DFRN || $contact['blocked'] || $contact['readonly'])
+ $hubmode = 'unsubscribe';
+
+ if((strlen($hub)) && ($hub_update) && ($contact['rel'] != CONTACT_IS_FOLLOWER)) {
+ logger('poller: hub ' . $hubmode . ' : ' . $hub . ' contact name : ' . $contact['name'] . ' local user : ' . $importer['name']);
+ $hubs = explode(',', $hub);
+ if(count($hubs)) {
+ foreach($hubs as $h) {
+ $h = trim($h);
+ if(! strlen($h))
+ continue;
+ subscribe_to_hub($h,$importer,$contact,$hubmode);
+ }
+ }
+ }
+ }
+
+ $updated = datetime_convert();
+
+ $r = q("UPDATE `contact` SET `last-update` = '%s', `success_update` = '%s' WHERE `id` = %d LIMIT 1",
+ dbesc($updated),
+ dbesc($updated),
+ intval($contact['id'])
+ );
+
+
+ // load current friends if possible.
+
+ if($contact['poco']) {
+ $r = q("SELECT count(*) as total from glink
+ where `cid` = %d and updated > UTC_TIMESTAMP() - INTERVAL 1 DAY",
+ intval($contact['id'])
+ );
+ }
+ if(count($r)) {
+ if(! $r[0]['total']) {
+ poco_load($contact['id'],$importer_uid,0,$contact['poco']);
+ }
+ }
+
+ return;
+}
+
+if (array_search(__file__,get_included_files())===0){
+ onepoll_run($argv,$argc);
+ killme();
+}
diff --git a/include/pgettext.php b/include/pgettext.php
index a079a4687..5a0eab0b0 100644
--- a/include/pgettext.php
+++ b/include/pgettext.php
@@ -15,10 +15,10 @@
*/
-if(! function_exists('get_language')) {
-function get_language() {
+if(! function_exists('get_browser_language')) {
+function get_browser_language() {
- if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
+ if (x($_SERVER,'HTTP_ACCEPT_LANGUAGE')) {
// break up string into pieces (languages and q factors)
preg_match_all('/([a-z]{1,8}(-[a-z]{1,8})?)\s*(;\s*q\s*=\s*(1|0\.[0-9]+))?/i',
$_SERVER['HTTP_ACCEPT_LANGUAGE'], $lang_parse);
diff --git a/include/plugin.php b/include/plugin.php
index 8196e8756..ae8eee78a 100644
--- a/include/plugin.php
+++ b/include/plugin.php
@@ -5,7 +5,7 @@
if (! function_exists('uninstall_plugin')){
function uninstall_plugin($plugin){
logger("Addons: uninstalling " . $plugin);
- q("DELETE FROM `addon` WHERE `name` = '%s' LIMIT 1",
+ q("DELETE FROM `addon` WHERE `name` = '%s' ",
dbesc($plugin)
);
@@ -37,6 +37,16 @@ function install_plugin($plugin) {
intval($t),
$plugin_admin
);
+
+ // we can add the following with the previous SQL
+ // once most site tables have been updated.
+ // This way the system won't fall over dead during the update.
+
+ if(file_exists('addon/' . $plugin . '/.hidden')) {
+ q("update addon set hidden = 1 where name = '%s' limit 1",
+ dbesc($plugin)
+ );
+ }
return true;
}
else {
@@ -60,8 +70,10 @@ function reload_plugins() {
$installed = array();
$parr = explode(',',$plugins);
+
if(count($parr)) {
foreach($parr as $pl) {
+
$pl = trim($pl);
$fname = 'addon/' . $pl . '/' . $pl . '.php';
@@ -91,6 +103,7 @@ function reload_plugins() {
}
}
}
+
}}
@@ -153,6 +166,14 @@ function call_hooks($name, &$data = null) {
$func = $hook[HOOK_FUNCTION];
$func($a,$data);
}
+ else {
+ // remove orphan hooks
+ q("delete from hook where hook = '%s' and file = '$s' and function = '%s' limit 1",
+ dbesc($hook[HOOK_HOOK]),
+ dbesc($hook[HOOK_FILE]),
+ dbesc($hook[HOOK_FUNCTION])
+ );
+ }
}
}
}
diff --git a/include/poller.php b/include/poller.php
index 499483d00..6b12445d1 100644
--- a/include/poller.php
+++ b/include/poller.php
@@ -30,6 +30,17 @@ function poller_run($argv, $argc){
load_config('config');
load_config('system');
+ $maxsysload = intval(get_config('system','maxloadavg'));
+ if($maxsysload < 1)
+ $maxsysload = 50;
+ if(function_exists('sys_getloadavg')) {
+ $load = sys_getloadavg();
+ if(intval($load[0]) > $maxsysload) {
+ logger('system: load ' . $load . ' too high. Poller deferred to next scheduled run.');
+ return;
+ }
+ }
+
$lockpath = get_config('system','lockpath');
if ($lockpath != '') {
$pidfile = new pidfile($lockpath, 'poller.lck');
@@ -39,6 +50,8 @@ function poller_run($argv, $argc){
}
}
+
+
$a->set_baseurl(get_config('system','url'));
load_hooks();
@@ -113,6 +126,10 @@ function poller_run($argv, $argc){
$force = true;
}
+ $interval = intval(get_config('system','poll_interval'));
+ if(! $interval)
+ $interval = ((get_config('system','delivery_interval') === false) ? 3 : intval(get_config('system','delivery_interval')));
+
$sql_extra = (($manual_id) ? " AND `id` = $manual_id " : "");
reload_plugins();
@@ -136,6 +153,7 @@ function poller_run($argv, $argc){
AND NOT `network` IN ( '%s', '%s' )
$sql_extra
AND `self` = 0 AND `contact`.`blocked` = 0 AND `contact`.`readonly` = 0
+ AND `contact`.`archive` = 0
AND `user`.`account_expired` = 0 $abandon_sql ORDER BY RAND()",
intval(CONTACT_IS_SHARING),
intval(CONTACT_IS_FRIEND),
@@ -224,440 +242,12 @@ function poller_run($argv, $argc){
continue;
}
- // Check to see if we are running out of memory - if so spawn a new process and kill this one
-
- $avail_memory = return_bytes(ini_get('memory_limit'));
- $memused = memory_get_peak_usage(true);
- if(intval($avail_memory)) {
- if(($memused / $avail_memory) > 0.95) {
- if($generation + 1 > 10) {
- logger('poller: maximum number of spawns exceeded. Terminating.');
- killme();
- }
- logger('poller: memory exceeded. ' . $memused . ' bytes used. Spawning new poll.');
- proc_run('php', 'include/poller.php', 'restart', (string) $generation + 1);
- killme();
- }
- }
-
- $importer_uid = $contact['uid'];
-
- $r = q("SELECT `contact`.*, `user`.`page-flags` FROM `contact` LEFT JOIN `user` on `contact`.`uid` = `user`.`uid` WHERE `user`.`uid` = %d AND `contact`.`self` = 1 LIMIT 1",
- intval($importer_uid)
- );
- if(! count($r))
- continue;
-
- $importer = $r[0];
-
- logger("poller: poll: ({$contact['id']}) IMPORTER: {$importer['name']}, CONTACT: {$contact['name']}");
-
- $last_update = (($contact['last-update'] === '0000-00-00 00:00:00')
- ? datetime_convert('UTC','UTC','now - 30 days', ATOM_TIME)
- : datetime_convert('UTC','UTC',$contact['last-update'], ATOM_TIME)
- );
-
- if($contact['network'] === NETWORK_DFRN) {
-
- $idtosend = $orig_id = (($contact['dfrn-id']) ? $contact['dfrn-id'] : $contact['issued-id']);
-
- if(intval($contact['duplex']) && $contact['dfrn-id'])
- $idtosend = '0:' . $orig_id;
- if(intval($contact['duplex']) && $contact['issued-id'])
- $idtosend = '1:' . $orig_id;
-
- // they have permission to write to us. We already filtered this in the contact query.
- $perm = 'rw';
-
- $url = $contact['poll'] . '?dfrn_id=' . $idtosend
- . '&dfrn_version=' . DFRN_PROTOCOL_VERSION
- . '&type=data&last_update=' . $last_update
- . '&perm=' . $perm ;
-
- $handshake_xml = fetch_url($url);
-
- logger('poller: handshake with url ' . $url . ' returns xml: ' . $handshake_xml, LOGGER_DATA);
-
-
- if(! $handshake_xml) {
- logger("poller: $url appears to be dead - marking for death ");
- // dead connection - might be a transient event, or this might
- // mean the software was uninstalled or the domain expired.
- // Will keep trying for one month.
- mark_for_death($contact);
-
- // set the last-update so we don't keep polling
-
- $r = q("UPDATE `contact` SET `last-update` = '%s' WHERE `id` = %d LIMIT 1",
- dbesc(datetime_convert()),
- intval($contact['id'])
- );
-
- continue;
- }
-
- if(! strstr($handshake_xml,'<?xml')) {
- logger('poller: response from ' . $url . ' did not contain XML.');
- $r = q("UPDATE `contact` SET `last-update` = '%s' WHERE `id` = %d LIMIT 1",
- dbesc(datetime_convert()),
- intval($contact['id'])
- );
- continue;
- }
-
-
- $res = parse_xml_string($handshake_xml);
-
- if(intval($res->status) == 1) {
- logger("poller: $url replied status 1 - marking for death ");
-
- // we may not be friends anymore. Will keep trying for one month.
- // set the last-update so we don't keep polling
-
- $r = q("UPDATE `contact` SET `last-update` = '%s' WHERE `id` = %d LIMIT 1",
- dbesc(datetime_convert()),
- intval($contact['id'])
- );
-
- mark_for_death($contact);
- }
- else {
- if($contact['term-date'] != '0000-00-00 00:00:00') {
- logger("poller: $url back from the dead - removing mark for death");
- unmark_for_death($contact);
- }
- }
-
- if((intval($res->status) != 0) || (! strlen($res->challenge)) || (! strlen($res->dfrn_id)))
- continue;
-
- if(((float) $res->dfrn_version > 2.21) && ($contact['poco'] == '')) {
- q("update contact set poco = '%s' where id = %d limit 1",
- dbesc(str_replace('/profile/','/poco/', $contact['url'])),
- intval($contact['id'])
- );
- }
-
- $postvars = array();
-
- $sent_dfrn_id = hex2bin((string) $res->dfrn_id);
- $challenge = hex2bin((string) $res->challenge);
-
- $final_dfrn_id = '';
-
- if(($contact['duplex']) && strlen($contact['prvkey'])) {
- openssl_private_decrypt($sent_dfrn_id,$final_dfrn_id,$contact['prvkey']);
- openssl_private_decrypt($challenge,$postvars['challenge'],$contact['prvkey']);
- }
- else {
- openssl_public_decrypt($sent_dfrn_id,$final_dfrn_id,$contact['pubkey']);
- openssl_public_decrypt($challenge,$postvars['challenge'],$contact['pubkey']);
- }
-
- $final_dfrn_id = substr($final_dfrn_id, 0, strpos($final_dfrn_id, '.'));
-
- if(strpos($final_dfrn_id,':') == 1)
- $final_dfrn_id = substr($final_dfrn_id,2);
-
- if($final_dfrn_id != $orig_id) {
- logger('poller: ID did not decode: ' . $contact['id'] . ' orig: ' . $orig_id . ' final: ' . $final_dfrn_id);
- // did not decode properly - cannot trust this site
- continue;
- }
-
- $postvars['dfrn_id'] = $idtosend;
- $postvars['dfrn_version'] = DFRN_PROTOCOL_VERSION;
- $postvars['perm'] = 'rw';
-
- $xml = post_url($contact['poll'],$postvars);
- }
- elseif(($contact['network'] === NETWORK_OSTATUS)
- || ($contact['network'] === NETWORK_DIASPORA)
- || ($contact['network'] === NETWORK_FEED) ) {
-
- // Upgrading DB fields from an older Friendica version
- // Will only do this once per notify-enabled OStatus contact
- // or if relationship changes
-
- $stat_writeable = ((($contact['notify']) && ($contact['rel'] == CONTACT_IS_FOLLOWER || $contact['rel'] == CONTACT_IS_FRIEND)) ? 1 : 0);
-
- if($stat_writeable != $contact['writable']) {
- q("UPDATE `contact` SET `writable` = %d WHERE `id` = %d LIMIT 1",
- intval($stat_writeable),
- intval($contact['id'])
- );
- }
-
- // Are we allowed to import from this person?
-
- if($contact['rel'] == CONTACT_IS_FOLLOWER || $contact['blocked'] || $contact['readonly'])
- continue;
-
- $xml = fetch_url($contact['poll']);
- }
- elseif($contact['network'] === NETWORK_MAIL || $contact['network'] === NETWORK_MAIL2) {
-
- logger("Mail: Fetching");
-
- $mail_disabled = ((function_exists('imap_open') && (! get_config('system','imap_disabled'))) ? 0 : 1);
- if($mail_disabled)
- continue;
-
- logger("Mail: Enabled");
-
- $mbox = null;
- $x = q("SELECT `prvkey` FROM `user` WHERE `uid` = %d LIMIT 1",
- intval($importer_uid)
- );
- $mailconf = q("SELECT * FROM `mailacct` WHERE `server` != '' AND `uid` = %d LIMIT 1",
- intval($importer_uid)
- );
- if(count($x) && count($mailconf)) {
- $mailbox = construct_mailbox_name($mailconf[0]);
- $password = '';
- openssl_private_decrypt(hex2bin($mailconf[0]['pass']),$password,$x[0]['prvkey']);
- $mbox = email_connect($mailbox,$mailconf[0]['user'],$password);
- unset($password);
- logger("Mail: Connect");
- if($mbox) {
- q("UPDATE `mailacct` SET `last_check` = '%s' WHERE `id` = %d AND `uid` = %d LIMIT 1",
- dbesc(datetime_convert()),
- intval($mailconf[0]['id']),
- intval($importer_uid)
- );
- }
- }
- if($mbox) {
- logger("Mail: mbox");
-
- $msgs = email_poll($mbox,$contact['addr']);
-
- if(count($msgs)) {
- logger("Mail: Parsing ".count($msgs)." mails.");
-
- foreach($msgs as $msg_uid) {
- logger("Mail: Parsing mail ".$msg_uid);
-
- $datarray = array();
- $meta = email_msg_meta($mbox,$msg_uid);
- $headers = email_msg_headers($mbox,$msg_uid);
-
- // look for a 'references' header and try and match with a parent item we have locally.
-
- $raw_refs = ((x($headers,'references')) ? str_replace("\t",'',$headers['references']) : '');
- $datarray['uri'] = msgid2iri(trim($meta->message_id,'<>'));
-
- if($raw_refs) {
- $refs_arr = explode(' ', $raw_refs);
- if(count($refs_arr)) {
- for($x = 0; $x < count($refs_arr); $x ++)
- $refs_arr[$x] = "'" . msgid2iri(str_replace(array('<','>',' '),array('','',''),dbesc($refs_arr[$x]))) . "'";
- }
- $qstr = implode(',',$refs_arr);
- $r = q("SELECT `uri` , `parent-uri` FROM `item` WHERE `uri` IN ( $qstr ) AND `uid` = %d LIMIT 1",
- intval($importer_uid)
- );
- if(count($r))
- $datarray['parent-uri'] = $r[0]['uri'];
- }
-
-
- if(! x($datarray,'parent-uri'))
- $datarray['parent-uri'] = $datarray['uri'];
-
- // Have we seen it before?
- $r = q("SELECT * FROM `item` WHERE `uid` = %d AND `uri` = '%s' LIMIT 1",
- intval($importer_uid),
- dbesc($datarray['uri'])
- );
-
- if(count($r)) {
- logger("Mail: Seen before ".$msg_uid);
- if($meta->deleted && ! $r[0]['deleted']) {
- q("UPDATE `item` SET `deleted` = 1, `changed` = '%s' WHERE `id` = %d LIMIT 1",
- dbesc(datetime_convert()),
- intval($r[0]['id'])
- );
- }
- switch ($mailconf[0]['action']) {
- case 0:
- break;
- case 1:
- logger("Mail: Deleting ".$msg_uid);
- imap_delete($mbox, $msg_uid, FT_UID);
- break;
- case 2:
- logger("Mail: Mark as seen ".$msg_uid);
- imap_setflag_full($mbox, $msg_uid, "\\Seen", ST_UID);
- break;
- case 3:
- logger("Mail: Moving ".$msg_uid." to ".$mailconf[0]['movetofolder']);
- imap_setflag_full($mbox, $msg_uid, "\\Seen", ST_UID);
- if ($mailconf[0]['movetofolder'] != "")
- imap_mail_move($mbox, $msg_uid, $mailconf[0]['movetofolder'], FT_UID);
- break;
- }
- continue;
- }
-
- // Decoding the header
- $subject = imap_mime_header_decode($meta->subject);
- $datarray['title'] = "";
- foreach($subject as $subpart)
- if ($subpart->charset != "default")
- $datarray['title'] .= iconv($subpart->charset, 'UTF-8//IGNORE', $subpart->text);
- else
- $datarray['title'] .= $subpart->text;
-
- $datarray['title'] = notags(trim($datarray['title']));
-
- //$datarray['title'] = notags(trim($meta->subject));
- $datarray['created'] = datetime_convert('UTC','UTC',$meta->date);
-
- // Is it reply?
- $reply = ((substr(strtolower($datarray['title']), 0, 3) == "re:") or
- (substr(strtolower($datarray['title']), 0, 3) == "re-") or
- (raw_refs != ""));
-
- $r = email_get_msg($mbox,$msg_uid, $reply);
- if(! $r) {
- logger("Mail: can't fetch msg ".$msg_uid);
- continue;
- }
- $datarray['body'] = escape_tags($r['body']);
-
- logger("Mail: Importing ".$msg_uid);
-
- // some mailing lists have the original author as 'from' - add this sender info to msg body.
- // todo: adding a gravatar for the original author would be cool
-
- if(! stristr($meta->from,$contact['addr'])) {
- $from = imap_mime_header_decode($meta->from);
- $fromdecoded = "";
- foreach($from as $frompart)
- if ($frompart->charset != "default")
- $fromdecoded .= iconv($frompart->charset, 'UTF-8//IGNORE', $frompart->text);
- else
- $fromdecoded .= $frompart->text;
-
- $datarray['body'] = "[b]".t('From: ') . escape_tags($fromdecoded) . "[/b]\n\n" . $datarray['body'];
- }
-
- $datarray['uid'] = $importer_uid;
- $datarray['contact-id'] = $contact['id'];
- if($datarray['parent-uri'] === $datarray['uri'])
- $datarray['private'] = 1;
- if(($contact['network'] === NETWORK_MAIL) && (! get_pconfig($importer_uid,'system','allow_public_email_replies'))) {
- $datarray['private'] = 1;
- $datarray['allow_cid'] = '<' . $contact['id'] . '>';
- }
- $datarray['author-name'] = $contact['name'];
- $datarray['author-link'] = 'mailbox';
- $datarray['author-avatar'] = $contact['photo'];
-
- $stored_item = item_store($datarray);
- q("UPDATE `item` SET `last-child` = 0 WHERE `parent-uri` = '%s' AND `uid` = %d",
- dbesc($datarray['parent-uri']),
- intval($importer_uid)
- );
- q("UPDATE `item` SET `last-child` = 1 WHERE `id` = %d LIMIT 1",
- intval($stored_item)
- );
- switch ($mailconf[0]['action']) {
- case 0:
- break;
- case 1:
- logger("Mail: Deleting ".$msg_uid);
- imap_delete($mbox, $msg_uid, FT_UID);
- break;
- case 2:
- logger("Mail: Mark as seen ".$msg_uid);
- imap_setflag_full($mbox, $msg_uid, "\\Seen", ST_UID);
- break;
- case 3:
- logger("Mail: Moving ".$msg_uid." to ".$mailconf[0]['movetofolder']);
- imap_setflag_full($mbox, $msg_uid, "\\Seen", ST_UID);
- if ($mailconf[0]['movetofolder'] != "")
- imap_mail_move($mbox, $msg_uid, $mailconf[0]['movetofolder'], FT_UID);
- break;
- }
- }
- }
-
- imap_close($mbox);
- }
- }
- elseif($contact['network'] === NETWORK_FACEBOOK) {
- // This is picked up by the Facebook plugin on a cron hook.
- // Ignored here.
- }
-
- if($xml) {
- logger('poller: received xml : ' . $xml, LOGGER_DATA);
-
- if(! strstr($xml,'<?xml')) {
- logger('poller: post_handshake: response from ' . $url . ' did not contain XML.');
- $r = q("UPDATE `contact` SET `last-update` = '%s' WHERE `id` = %d LIMIT 1",
- dbesc(datetime_convert()),
- intval($contact['id'])
- );
- continue;
- }
-
-
- consume_feed($xml,$importer,$contact,$hub,1,1);
-
- // do it twice. Ensures that children of parents which may be later in the stream aren't tossed
-
- consume_feed($xml,$importer,$contact,$hub,1,2);
-
- $hubmode = 'subscribe';
- if($contact['network'] === NETWORK_DFRN || $contact['blocked'] || $contact['readonly'])
- $hubmode = 'unsubscribe';
-
- if((strlen($hub)) && ($hub_update) && ($contact['rel'] != CONTACT_IS_FOLLOWER)) {
- logger('poller: hub ' . $hubmode . ' : ' . $hub . ' contact name : ' . $contact['name'] . ' local user : ' . $importer['name']);
- $hubs = explode(',', $hub);
- if(count($hubs)) {
- foreach($hubs as $h) {
- $h = trim($h);
- if(! strlen($h))
- continue;
- subscribe_to_hub($h,$importer,$contact,$hubmode);
- }
- }
- }
- }
-
-
- $updated = datetime_convert();
-
- $r = q("UPDATE `contact` SET `last-update` = '%s', `success_update` = '%s' WHERE `id` = %d LIMIT 1",
- dbesc($updated),
- dbesc($updated),
- intval($contact['id'])
- );
-
-
- // load current friends if possible.
-
- if($contact['poco']) {
- $r = q("SELECT count(*) as total from glink
- where `cid` = %d and updated > UTC_TIMESTAMP() - INTERVAL 1 DAY",
- intval($contact['id'])
- );
- }
- if(count($r)) {
- if(! $r[0]['total']) {
- poco_load($contact['id'],$importer_uid,$contact['poco']);
- }
- }
-
- // loop - next contact
+ proc_run('php','include/onepoll.php',$contact['id']);
+ if($interval)
+ @time_sleep_until(microtime(true) + (float) $interval);
}
}
-
return;
}
diff --git a/include/profile_selectors.php b/include/profile_selectors.php
index a2cef959d..4700bb96f 100644
--- a/include/profile_selectors.php
+++ b/include/profile_selectors.php
@@ -7,8 +7,10 @@ function gender_selector($current="",$suffix="") {
$o .= "<select name=\"gender$suffix\" id=\"gender-select$suffix\" size=\"1\" >";
foreach($select as $selection) {
- $selected = (($selection == $current) ? ' selected="selected" ' : '');
- $o .= "<option value=\"$selection\" $selected >$selection</option>";
+ if($selection !== 'NOTRANSLATION') {
+ $selected = (($selection == $current) ? ' selected="selected" ' : '');
+ $o .= "<option value=\"$selection\" $selected >$selection</option>";
+ }
}
$o .= '</select>';
return $o;
@@ -20,8 +22,10 @@ function sexpref_selector($current="",$suffix="") {
$o .= "<select name=\"sexual$suffix\" id=\"sexual-select$suffix\" size=\"1\" >";
foreach($select as $selection) {
- $selected = (($selection == $current) ? ' selected="selected" ' : '');
- $o .= "<option value=\"$selection\" $selected >$selection</option>";
+ if($selection !== 'NOTRANSLATION') {
+ $selected = (($selection == $current) ? ' selected="selected" ' : '');
+ $o .= "<option value=\"$selection\" $selected >$selection</option>";
+ }
}
$o .= '</select>';
return $o;
@@ -34,8 +38,10 @@ function marital_selector($current="",$suffix="") {
$o .= "<select name=\"marital\" id=\"marital-select\" size=\"1\" >";
foreach($select as $selection) {
- $selected = (($selection == $current) ? ' selected="selected" ' : '');
- $o .= "<option value=\"$selection\" $selected >$selection</option>";
+ if($selection !== 'NOTRANSLATION') {
+ $selected = (($selection == $current) ? ' selected="selected" ' : '');
+ $o .= "<option value=\"$selection\" $selected >$selection</option>";
+ }
}
$o .= '</select>';
return $o;
diff --git a/include/queue_fn.php b/include/queue_fn.php
index 3c1087f4e..2aca338f5 100644
--- a/include/queue_fn.php
+++ b/include/queue_fn.php
@@ -15,6 +15,17 @@ function remove_queue_item($id) {
);
}
+function was_recently_delayed($cid) {
+
+ $r = q("SELECT `id` FROM `queue` WHERE `cid` = %d
+ and last > UTC_TIMESTAMP() - interval 15 minute limit 1",
+ intval($cid)
+ );
+ if(count($r))
+ return true;
+ return false;
+}
+
function add_to_queue($cid,$network,$msg,$batch = false) {
diff --git a/include/security.php b/include/security.php
index a92400b5c..af201d2af 100755
--- a/include/security.php
+++ b/include/security.php
@@ -76,7 +76,7 @@ function authenticate_success($user_record, $login_initial = false, $interactive
header('X-Account-Management-Status: active; name="' . $a->user['username'] . '"; id="' . $a->user['nickname'] .'"');
if($login_initial) {
- $l = get_language();
+ $l = get_browser_language();
q("UPDATE `user` SET `login_date` = '%s', `language` = '%s' WHERE `uid` = %d LIMIT 1",
dbesc(datetime_convert()),
diff --git a/include/socgraph.php b/include/socgraph.php
index 3f5194049..592779089 100644
--- a/include/socgraph.php
+++ b/include/socgraph.php
@@ -20,7 +20,7 @@ require_once('include/datetime.php');
-function poco_load($cid,$uid = 0,$url = null) {
+function poco_load($cid,$uid = 0,$zcid = 0,$url = null) {
$a = get_app();
if($cid) {
@@ -53,7 +53,6 @@ function poco_load($cid,$uid = 0,$url = null) {
if(($a->get_curl_code() > 299) || (! $s))
return;
-
$j = json_decode($s);
logger('poco_load: json: ' . print_r($j,true),LOGGER_DATA);
@@ -81,7 +80,6 @@ function poco_load($cid,$uid = 0,$url = null) {
$connect_url = str_replace('acct:' , '', $url->value);
continue;
}
-
}
foreach($entry->photos as $photo) {
if($photo->type == 'profile') {
@@ -101,11 +99,12 @@ function poco_load($cid,$uid = 0,$url = null) {
$gcid = $x[0]['id'];
if($x[0]['name'] != $name || $x[0]['photo'] != $profile_photo) {
- q("update gcontact set `name` = '%s', `photo` = '%s', `connect` = '%s'
+ q("update gcontact set `name` = '%s', `photo` = '%s', `connect` = '%s', `url` = '%s'
where `nurl` = '%s' limit 1",
dbesc($name),
dbesc($profile_photo),
dbesc($connect_url),
+ dbesc($profile_url),
dbesc(normalise_link($profile_url))
);
}
@@ -128,34 +127,38 @@ function poco_load($cid,$uid = 0,$url = null) {
if(! $gcid)
return;
- $r = q("select * from glink where `cid` = %d and `uid` = %d and `gcid` = %d limit 1",
+ $r = q("select * from glink where `cid` = %d and `uid` = %d and `gcid` = %d and `zcid` = %d limit 1",
intval($cid),
intval($uid),
- intval($gcid)
+ intval($gcid),
+ intval($zcid)
);
if(! count($r)) {
- q("insert into glink ( `cid`,`uid`,`gcid`,`updated`) values (%d,%d,%d,'%s') ",
+ q("insert into glink ( `cid`,`uid`,`gcid`,`zcid`, `updated`) values (%d,%d,%d,%d, '%s') ",
intval($cid),
intval($uid),
intval($gcid),
+ intval($zcid),
dbesc(datetime_convert())
);
}
else {
- q("update glink set updated = '%s' where `cid` = %d and `uid` = %d and `gcid` = %d limit 1",
+ q("update glink set updated = '%s' where `cid` = %d and `uid` = %d and `gcid` = %d and zcid = %d limit 1",
dbesc(datetime_convert()),
intval($cid),
intval($uid),
- intval($gcid)
+ intval($gcid),
+ intval($zcid)
);
}
}
logger("poco_load: loaded $total entries",LOGGER_DEBUG);
- q("delete from glink where `cid` = %d and `uid` = %d and `updated` < UTC_TIMESTAMP - INTERVAL 2 DAY",
+ q("delete from glink where `cid` = %d and `uid` = %d and `zcid` = %d and `updated` < UTC_TIMESTAMP - INTERVAL 2 DAY",
intval($cid),
- intval($uid)
+ intval($uid),
+ intval($zcid)
);
}
@@ -166,13 +169,14 @@ function count_common_friends($uid,$cid) {
$r = q("SELECT count(*) as `total`
FROM `glink` left join `gcontact` on `glink`.`gcid` = `gcontact`.`id`
where `glink`.`cid` = %d and `glink`.`uid` = %d
- and `gcontact`.`nurl` in (select nurl from contact where uid = %d and self = 0 and id != %d ) ",
+ and `gcontact`.`nurl` in (select nurl from contact where uid = %d and self = 0 and blocked = 0 and hidden = 0 and id != %d ) ",
intval($cid),
intval($uid),
intval($uid),
intval($cid)
);
+// logger("count_common_friends: $uid $cid {$r[0]['total']}");
if(count($r))
return $r[0]['total'];
return 0;
@@ -180,23 +184,70 @@ function count_common_friends($uid,$cid) {
}
-function common_friends($uid,$cid) {
+function common_friends($uid,$cid,$start = 0,$limit=9999,$shuffle = false) {
+
+ if($shuffle)
+ $sql_extra = " order by rand() ";
+ else
+ $sql_extra = " order by `gcontact`.`name` asc ";
$r = q("SELECT `gcontact`.*
FROM `glink` left join `gcontact` on `glink`.`gcid` = `gcontact`.`id`
where `glink`.`cid` = %d and `glink`.`uid` = %d
- and `gcontact`.`nurl` in (select nurl from contact where uid = %d and self = 0 and id != %d )
- order by `gcontact`.`name` asc ",
+ and `gcontact`.`nurl` in (select nurl from contact where uid = %d and self = 0 and blocked = 0 and hidden = 0 and id != %d )
+ $sql_extra limit %d, %d",
intval($cid),
intval($uid),
intval($uid),
- intval($cid)
+ intval($cid),
+ intval($start),
+ intval($limit)
+ );
+
+ return $r;
+
+}
+
+
+function count_common_friends_zcid($uid,$zcid) {
+
+ $r = q("SELECT count(*) as `total`
+ FROM `glink` left join `gcontact` on `glink`.`gcid` = `gcontact`.`id`
+ where `glink`.`zcid` = %d
+ and `gcontact`.`nurl` in (select nurl from contact where uid = %d and self = 0 and blocked = 0 and hidden = 0 ) ",
+ intval($zcid),
+ intval($uid)
+ );
+
+ if(count($r))
+ return $r[0]['total'];
+ return 0;
+
+}
+
+function common_friends_zcid($uid,$zcid,$start = 0, $limit = 9999,$shuffle) {
+
+ if($shuffle)
+ $sql_extra = " order by rand() ";
+ else
+ $sql_extra = " order by `gcontact`.`name` asc ";
+
+ $r = q("SELECT `gcontact`.*
+ FROM `glink` left join `gcontact` on `glink`.`gcid` = `gcontact`.`id`
+ where `glink`.`zcid` = %d
+ and `gcontact`.`nurl` in (select nurl from contact where uid = %d and self = 0 and blocked = 0 and hidden = 0 )
+ $sql_extra limit %d, %d",
+ intval($zcid),
+ intval($uid),
+ intval($start),
+ intval($limit)
);
return $r;
}
+
function count_all_friends($uid,$cid) {
$r = q("SELECT count(*) as `total`
@@ -254,7 +305,7 @@ function suggestion_query($uid, $start = 0, $limit = 80) {
$r2 = q("SELECT gcontact.* from gcontact
left join glink on glink.gcid = gcontact.id
- where glink.uid = 0 and glink.cid = 0 and not gcontact.nurl in ( select nurl from contact where uid = %d )
+ where glink.uid = 0 and glink.cid = 0 and glink.zcid = 0 and not gcontact.nurl in ( select nurl from contact where uid = %d )
and not gcontact.name in ( select name from contact where uid = %d )
and not gcontact.id in ( select gcid from gcign where uid = %d )
order by rand() limit %d, %d ",
@@ -276,7 +327,7 @@ function update_suggestions() {
$done = array();
- poco_load(0,0,$a->get_baseurl() . '/poco');
+ poco_load(0,0,0,$a->get_baseurl() . '/poco');
$done[] = $a->get_baseurl() . '/poco';
@@ -288,7 +339,7 @@ function update_suggestions() {
foreach($j->entries as $entry) {
$url = $entry->url . '/poco';
if(! in_array($url,$done))
- poco_load(0,0,$entry->url . '/poco');
+ poco_load(0,0,0,$entry->url . '/poco');
}
}
}
@@ -302,7 +353,7 @@ function update_suggestions() {
foreach($r as $rr) {
$base = substr($rr['poco'],0,strrpos($rr['poco'],'/'));
if(! in_array($base,$done))
- poco_load(0,0,$base);
+ poco_load(0,0,0,$base);
}
}
}
diff --git a/include/text.php b/include/text.php
index 8c8db66a9..e3c683338 100644
--- a/include/text.php
+++ b/include/text.php
@@ -558,7 +558,7 @@ function contact_block() {
if((! is_array($a->profile)) || ($a->profile['hide-friends']))
return $o;
- $r = q("SELECT COUNT(*) AS `total` FROM `contact` WHERE `uid` = %d AND `self` = 0 AND `blocked` = 0 and `pending` = 0 AND `hidden` = 0",
+ $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",
intval($a->profile['uid'])
);
if(count($r)) {
@@ -569,7 +569,7 @@ function contact_block() {
$micropro = Null;
} else {
- $r = q("SELECT * FROM `contact` WHERE `uid` = %d AND `self` = 0 AND `blocked` = 0 and `pending` = 0 AND `hidden` = 0 ORDER BY RAND() LIMIT %d",
+ $r = q("SELECT * FROM `contact` WHERE `uid` = %d AND `self` = 0 AND `blocked` = 0 and `pending` = 0 AND `hidden` = 0 AND `archive` = 0 ORDER BY RAND() LIMIT %d",
intval($a->profile['uid']),
intval($shown)
);
@@ -930,7 +930,8 @@ function prepare_body($item,$attach = false) {
foreach($matches as $mtch) {
if(strlen($x))
$x .= ',';
- $x .= xmlify(file_tag_decode($mtch[1]));
+ $x .= xmlify(file_tag_decode($mtch[1]))
+ . ((local_user() == $item['uid']) ? ' <a href="' . $a->get_baseurl() . '/filerm/' . $item['id'] . '?f=&cat=' . xmlify(file_tag_decode($mtch[1])) . '" title="' . t('remove') . '" >' . t('[remove]') . '</a>' : '');
}
if(strlen($x))
$s .= '<div class="categorytags"><span>' . t('Categories:') . ' </span>' . $x . '</div>';
@@ -1466,12 +1467,16 @@ function file_tag_save_file($uid,$item,$file) {
return true;
}
-function file_tag_unsave_file($uid,$item,$file) {
+function file_tag_unsave_file($uid,$item,$file,$cat = false) {
$result = false;
if(! intval($uid))
return false;
- $pattern = '[' . file_tag_encode($file) . ']' ;
+ if($cat == true)
+ $pattern = '<' . file_tag_encode($file) . '>' ;
+ else
+ $pattern = '[' . file_tag_encode($file) . ']' ;
+
$r = q("select file from item where id = %d and uid = %d limit 1",
intval($item),
@@ -1486,13 +1491,14 @@ function file_tag_unsave_file($uid,$item,$file) {
intval($uid)
);
- $r = q("select file from item where uid = %d " . file_tag_file_query('item',$file),
+ $r = q("select file from item where uid = %d and deleted = 0 " . file_tag_file_query('item',$file,(($cat) ? 'category' : 'file')),
intval($uid)
);
if(! count($r)) {
$saved = get_pconfig($uid,'system','filetags');
set_pconfig($uid,'system','filetags',str_replace($pattern,'',$saved));
+
}
return true;
}
@@ -1518,3 +1524,9 @@ function fix_mce_lf($s) {
$s = str_replace("\n\n","\n",$s);
return $s;
}
+
+
+function protect_sprintf($s) {
+ return(str_replace('%','%%',$s));
+}
+