aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/ItemObject.php1
-rw-r--r--include/RedDAV/RedBrowser.php2
-rw-r--r--include/account.php4
-rw-r--r--include/api.php98
-rw-r--r--include/api_auth.php84
-rw-r--r--include/attach.php6
-rw-r--r--include/bb2diaspora.php12
-rw-r--r--include/comanche.php16
-rw-r--r--include/conversation.php3
-rw-r--r--include/datetime.php2
-rw-r--r--include/deliver.php112
-rw-r--r--include/dir_fns.php2
-rw-r--r--include/directory.php26
-rw-r--r--include/event.php34
-rw-r--r--include/externals.php21
-rw-r--r--include/follow.php25
-rw-r--r--include/identity.php6
-rwxr-xr-xinclude/items.php22
-rw-r--r--include/js_strings.php1
-rw-r--r--include/message.php12
-rw-r--r--include/network.php187
-rw-r--r--include/notifier.php237
-rw-r--r--include/oauth.php161
-rw-r--r--include/photos.php49
-rwxr-xr-xinclude/plugin.php30
-rw-r--r--include/queue.php57
-rw-r--r--include/queue_fn.php139
-rw-r--r--include/ratenotif.php20
-rw-r--r--include/security.php18
-rw-r--r--include/taxonomy.php4
-rw-r--r--include/text.php62
-rw-r--r--include/widgets.php20
-rw-r--r--include/zot.php531
33 files changed, 1327 insertions, 677 deletions
diff --git a/include/ItemObject.php b/include/ItemObject.php
index 512e12838..8be99d91e 100644
--- a/include/ItemObject.php
+++ b/include/ItemObject.php
@@ -346,6 +346,7 @@ class Item extends BaseObject {
'owner_photo' => $this->get_owner_photo(),
'owner_name' => $this->get_owner_name(),
'photo' => $body['photo'],
+ 'event' => $body['event'],
'has_tags' => $has_tags,
// Item toolbar buttons
diff --git a/include/RedDAV/RedBrowser.php b/include/RedDAV/RedBrowser.php
index efea5d92f..1aa5f435e 100644
--- a/include/RedDAV/RedBrowser.php
+++ b/include/RedDAV/RedBrowser.php
@@ -188,7 +188,7 @@ class RedBrowser extends DAV\Browser\Plugin {
$parentHash = '';
$owner = $this->auth->owner_id;
- $splitPath = split('/', $fullPath);
+ $splitPath = explode('/', $fullPath);
if (count($splitPath) > 3) {
for ($i = 3; $i < count($splitPath); $i++) {
$attachName = urldecode($splitPath[$i]);
diff --git a/include/account.php b/include/account.php
index b3a520fd4..e448bdcc6 100644
--- a/include/account.php
+++ b/include/account.php
@@ -67,7 +67,7 @@ function check_account_invite($invite_code) {
$result['message'] .= t('An invitation is required.') . EOL;
}
$r = q("select * from register where `hash` = '%s' limit 1", dbesc($invite_code));
- if(! results($r)) {
+ if(! $r) {
$result['message'] .= t('Invitation could not be verified.') . EOL;
}
}
@@ -718,4 +718,4 @@ function upgrade_message($bbcode = false) {
function upgrade_bool_message($bbcode = false) {
$x = upgrade_link($bbcode);
return t('This action is not available under your subscription plan.') . (($x) ? ' ' . $x : '') ;
-} \ No newline at end of file
+}
diff --git a/include/api.php b/include/api.php
index f279b2aa3..5053977c5 100644
--- a/include/api.php
+++ b/include/api.php
@@ -1,10 +1,10 @@
<?php /** @file */
-require_once("bbcode.php");
-require_once("datetime.php");
-require_once("conversation.php");
-require_once("oauth.php");
-require_once("html2plain.php");
+require_once("include/bbcode.php");
+require_once("include/datetime.php");
+require_once("include/conversation.php");
+require_once("include/oauth.php");
+require_once("include/html2plain.php");
require_once('include/security.php');
require_once('include/photos.php');
require_once('include/items.php');
@@ -112,8 +112,11 @@ require_once('include/api_auth.php');
break;
case "json":
header ("Content-Type: application/json");
- foreach($r as $rr)
+ foreach($r as $rr) {
+ if(! $rr)
+ $rr = array();
$json = json_encode($rr);
+ }
if ($_GET['callback'])
$json = $_GET['callback']."(".$json.")";
return $json;
@@ -248,6 +251,7 @@ require_once('include/api_auth.php');
if (count($uinfo)==0) {
return False;
}
+ $following = false;
if(intval($uinfo[0]['abook_self'])) {
$usr = q("select * from channel where channel_id = %d limit 1",
@@ -263,18 +267,22 @@ require_once('include/api_auth.php');
$r = q("SELECT COUNT(`id`) as `count` FROM `item`
WHERE `uid` = %d
AND item_wall = 1 $item_normal
- AND `allow_cid`='' AND `allow_gid`='' AND `deny_cid`='' AND `deny_gid`=''",
+ AND `allow_cid`='' AND `allow_gid`='' AND `deny_cid`='' AND `deny_gid`=''
+ AND item_private = 0 ",
intval($usr[0]['channel_id'])
);
$countitms = $r[0]['count'];
+ $following = true;
}
else {
$r = q("SELECT COUNT(`id`) as `count` FROM `item`
WHERE author_xchan = '%s'
- AND `allow_cid`='' AND `allow_gid`='' AND `deny_cid`='' AND `deny_gid`=''",
+ AND `allow_cid`='' AND `allow_gid`='' AND `deny_cid`='' AND `deny_gid`=''
+ AND item_private = 0 ",
intval($uinfo[0]['xchan_hash'])
);
$countitms = $r[0]['count'];
+ $following = (($uinfo[0]['abook_myperms'] & PERMS_R_STREAM) ? true : false );
}
@@ -310,7 +318,6 @@ require_once('include/api_auth.php');
'location' => ($usr) ? $usr[0]['channel_location'] : '',
'profile_image_url' => $uinfo[0]['xchan_photo_l'],
'url' => $uinfo[0]['xchan_url'],
-//FIXME
'contact_url' => $a->get_baseurl() . "/connections/".$uinfo[0]['abook_id'],
'protected' => false,
'friends_count' => intval($countfriends),
@@ -334,7 +341,7 @@ require_once('include/api_auth.php');
'profile_background_tile' => false,
'profile_use_background_image' => false,
'notifications' => false,
- 'following' => '', // #XXX: fix me
+ 'following' => $following,
'verified' => true // #XXX: fix me
);
@@ -382,7 +389,6 @@ require_once('include/api_auth.php');
function api_item_get_user(&$a, $item) {
- global $usercache;
// The author is our direct contact, in a conversation with us.
@@ -396,11 +402,11 @@ require_once('include/api_auth.php');
$name = $item['author']['xchan_name'];
// Generating a random ID
- if (is_null($usercache[$nick]) or !array_key_exists($nick, $usercache))
- $usercache[$nick] = mt_rand(2000000, 2100000);
+ if (! $nick)
+ $nick = mt_rand(2000000, 2100000);
$ret = array(
- 'id' => $usercache[$nick],
+ 'id' => $nick,
'name' => $name,
'screen_name' => $nick,
'location' => '', //$uinfo[0]['default-location'],
@@ -415,7 +421,7 @@ require_once('include/api_auth.php');
'utc_offset' => 0, // #XXX: fix me
'time_zone' => '', //$uinfo[0]['timezone'],
'statuses_count' => 0,
- 'following' => 1,
+ 'following' => false,
'statusnet_blocking' => false,
'notifications' => false,
'uid' => 0,
@@ -853,13 +859,38 @@ require_once('include/api_auth.php');
$_REQUEST['type'] = 'wall';
if(x($_FILES,'media')) {
- $_FILES['userfile'] = $_FILES['media'];
- // upload the image if we have one
- $_REQUEST['silent']='1'; //tell wall_upload function to return img info instead of echo
- require_once('mod/wall_attach.php');
- $media = wall_attach_post($a);
- if(strlen($media)>0)
- $_REQUEST['body'] .= "\n\n".$media;
+ if(is_array($_FILES['media']['name'])) {
+ $num_uploads = count($_FILES['media']['name']);
+ for($x = 0; $x < $num_uploads; $x ++) {
+ $_FILES['userfile'] = array();
+ $_FILES['userfile']['name'] = $_FILES['media']['name'][$x];
+ $_FILES['userfile']['type'] = $_FILES['media']['type'][$x];
+ $_FILES['userfile']['tmp_name'] = $_FILES['media']['tmp_name'][$x];
+ $_FILES['userfile']['error'] = $_FILES['media']['error'][$x];
+ $_FILES['userfile']['size'] = $_FILES['media']['size'][$x];
+
+ // upload each image if we have any
+ $_REQUEST['silent']='1'; //tell wall_upload function to return img info instead of echo
+ require_once('mod/wall_attach.php');
+ $a->data['api_info'] = $user_info;
+ $media = wall_attach_post($a);
+
+ if(strlen($media)>0)
+ $_REQUEST['body'] .= "\n\n" . $media;
+ }
+ }
+ else {
+ // AndStatus doesn't present media as an array
+ $_FILES['userfile'] = $_FILES['media'];
+ // upload each image if we have any
+ $_REQUEST['silent']='1'; //tell wall_upload function to return img info instead of echo
+ require_once('mod/wall_attach.php');
+ $a->data['api_info'] = $user_info;
+ $media = wall_attach_post($a);
+
+ if(strlen($media)>0)
+ $_REQUEST['body'] .= "\n\n" . $media;
+ }
}
}
@@ -871,6 +902,7 @@ require_once('include/api_auth.php');
// this should output the last post (the one we just posted).
return api_status_show($a,$type);
}
+ api_register_func('api/statuses/update_with_media','api_statuses_update', true);
api_register_func('api/statuses/update','api_statuses_update', true);
@@ -1079,6 +1111,8 @@ require_once('include/api_auth.php');
'contributors' => ''
);
$status_info['user'] = $user_info;
+ if(array_key_exists('status',$status_info['user']))
+ unset($status_info['user']['status']);
}
return api_apply_template("status", $type, array('$status' => $status_info));
@@ -1320,6 +1354,8 @@ require_once('include/api_auth.php');
// params
$id = intval(argv(3));
+ if(! $id)
+ $id = $_REQUEST['id'];
logger('API: api_statuses_show: '.$id);
@@ -1336,10 +1372,12 @@ require_once('include/api_auth.php');
$r = q("select * from item where true $item_normal $sql_extra",
intval($id)
);
+
xchan_query($r,true);
$ret = api_format_items($r,$user_info);
+
if ($conversation) {
$data = array('$statuses' => $ret);
return api_apply_template("timeline", $type, $data);
@@ -2299,28 +2337,28 @@ require_once('include/api_auth.php');
api_register_func('api/direct_messages','api_direct_messages_inbox',true);
-
function api_oauth_request_token(&$a, $type){
try{
- $oauth = new FKOAuth1();
- $req = OAuthRequest::from_request();
-logger('Req: ' . var_export($req,true));
+ $oauth = new ZotOAuth1();
+ $req = OAuth1Request::from_request();
+ logger('Req: ' . var_export($req,true),LOGGER_DATA);
$r = $oauth->fetch_request_token($req);
}catch(Exception $e){
logger('oauth_exception: ' . print_r($e->getMessage(),true));
- echo "error=". OAuthUtil::urlencode_rfc3986($e->getMessage());
+ echo "error=". OAuth1Util::urlencode_rfc3986($e->getMessage());
killme();
}
echo $r;
killme();
}
+
function api_oauth_access_token(&$a, $type){
try{
- $oauth = new FKOAuth1();
- $req = OAuthRequest::from_request();
+ $oauth = new ZotOAuth1();
+ $req = OAuth1Request::from_request();
$r = $oauth->fetch_access_token($req);
}catch(Exception $e){
- echo "error=". OAuthUtil::urlencode_rfc3986($e->getMessage()); killme();
+ echo "error=". OAuth1Util::urlencode_rfc3986($e->getMessage()); killme();
}
echo $r;
killme();
diff --git a/include/api_auth.php b/include/api_auth.php
index ee9db3f55..26a9df8d4 100644
--- a/include/api_auth.php
+++ b/include/api_auth.php
@@ -1,17 +1,19 @@
<?php /** @file */
-require_once("oauth.php");
-
-
/**
- * Simple HTTP Login
+ * API Login via basic-auth or OAuth
*/
function api_login(&$a){
+
+ $record = null;
+
+ require_once('include/oauth.php');
+
// login with oauth
try {
- $oauth = new FKOAuth1();
- $req = OAuthRequest::from_request();
+ $oauth = new ZotOAuth1();
+ $req = OAuth1Request::from_request();
list($consumer,$token) = $oauth->verify_request($req);
@@ -23,16 +25,14 @@ function api_login(&$a){
call_hooks('logged_in', $a->user);
return;
}
- echo __file__.__line__.__function__."<pre>";
-// var_dump($consumer, $token);
- die();
+ killme();
}
catch(Exception $e) {
- logger(__file__.__line__.__function__."\n".$e);
+ logger($e->getMessage());
}
-
- // workaround for HTTP-auth in CGI mode
+ // workarounds for HTTP-auth in CGI mode
+
if(x($_SERVER,'REDIRECT_REMOTE_USER')) {
$userpass = base64_decode(substr($_SERVER["REDIRECT_REMOTE_USER"],6)) ;
if(strlen($userpass)) {
@@ -51,45 +51,49 @@ function api_login(&$a){
}
}
+ require_once('include/auth.php');
+ require_once('include/security.php');
- if (!isset($_SERVER['PHP_AUTH_USER'])) {
- logger('API_login: ' . print_r($_SERVER,true), LOGGER_DEBUG);
- header('WWW-Authenticate: Basic realm="Red"');
- header('HTTP/1.0 401 Unauthorized');
- die('This api requires login');
- }
-
// process normal login request
- require_once('include/auth.php');
- $channel_login = 0;
- $record = account_verify_password($_SERVER['PHP_AUTH_USER'],$_SERVER['PHP_AUTH_PW']);
- if(! $record) {
- $r = q("select * from channel where channel_address = '%s' limit 1",
+
+ if(isset($_SERVER['PHP_AUTH_USER'])) {
+ $channel_login = 0;
+ $record = account_verify_password($_SERVER['PHP_AUTH_USER'],$_SERVER['PHP_AUTH_PW']);
+ if(! $record) {
+ $r = q("select * from channel left join account on account.account_id = channel.channel_account_id
+ where channel.channel_address = '%s' limit 1",
dbesc($_SERVER['PHP_AUTH_USER'])
);
if ($r) {
- $x = q("select * from account where account_id = %d limit 1",
- intval($r[0]['channel_account_id'])
- );
- if ($x) {
- $record = account_verify_password($x[0]['account_email'],$_SERVER['PHP_AUTH_PW']);
+ $record = account_verify_password($r[0]['account_email'],$_SERVER['PHP_AUTH_PW']);
if($record)
$channel_login = $r[0]['channel_id'];
}
}
- if(! $record) {
- logger('API_login failure: ' . print_r($_SERVER,true), LOGGER_DEBUG);
- header('WWW-Authenticate: Basic realm="Red"');
- header('HTTP/1.0 401 Unauthorized');
- die('This api requires login');
- }
}
- require_once('include/security.php');
- authenticate_success($record);
+ if($record) {
+ authenticate_success($record);
- if($channel_login)
- change_channel($channel_login);
+ if($channel_login)
+ change_channel($channel_login);
+
+ $_SESSION['allow_api'] = true;
+ return true;
+ }
+ else {
+ $_SERVER['PHP_AUTH_PW'] = '*****';
+ logger('API_login failure: ' . print_r($_SERVER,true), LOGGER_DEBUG);
+ log_failed_login('API login failure');
+ retry_basic_auth();
+ }
- $_SESSION['allow_api'] = true;
}
+
+
+function retry_basic_auth() {
+ header('WWW-Authenticate: Basic realm="Hubzilla"');
+ header('HTTP/1.0 401 Unauthorized');
+ echo('This api requires login');
+ killme();
+} \ No newline at end of file
diff --git a/include/attach.php b/include/attach.php
index 36b971712..8595d5d86 100644
--- a/include/attach.php
+++ b/include/attach.php
@@ -430,7 +430,7 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) {
$observer = $x[0];
}
- logger('arr: ' . print_r($arr,true));
+ logger('arr: ' . print_r($arr,true), LOGGER_DATA);
if(! perm_is_allowed($channel_id,$observer_hash, 'write_storage')) {
$ret['message'] = t('Permission denied.');
@@ -503,6 +503,10 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) {
}
}
+ // AndStatus sends jpegs with a non-standard mimetype
+ if($type === 'image/jpg')
+ $type = 'image/jpeg';
+
$existing_size = 0;
if($options === 'replace') {
diff --git a/include/bb2diaspora.php b/include/bb2diaspora.php
index 1be7caa19..81b95b30b 100644
--- a/include/bb2diaspora.php
+++ b/include/bb2diaspora.php
@@ -305,15 +305,6 @@ function bb2diaspora_itembody($item, $force_update = false) {
$matches = array();
- //if we have a photo item just prepend the photo bbcode to item['body']
- $is_photo = (($item['obj_type'] == ACTIVITY_OBJ_PHOTO) ? true : false);
- if($is_photo) {
- $object = json_decode($item['object'],true);
- if($object['bbcode']) {
- $item['body'] = (($item['body']) ? $object['bbcode'] . "\r\n" . $item['body'] : $object['bbcode']);
- }
- }
-
if(($item['diaspora_meta']) && (! $force_update)) {
$diaspora_meta = json_decode($item['diaspora_meta'],true);
if($diaspora_meta) {
@@ -333,6 +324,8 @@ function bb2diaspora_itembody($item, $force_update = false) {
}
}
+ create_export_photo_body($item);
+
$newitem = $item;
if(array_key_exists('item_obscured',$item) && intval($item['item_obscured'])) {
@@ -346,6 +339,7 @@ function bb2diaspora_itembody($item, $force_update = false) {
}
}
+
bb2diaspora_itemwallwall($newitem);
$title = $newitem['title'];
diff --git a/include/comanche.php b/include/comanche.php
index 9585a6578..1537226ca 100644
--- a/include/comanche.php
+++ b/include/comanche.php
@@ -282,15 +282,21 @@ function comanche_widget($name, $text) {
}
}
- if(file_exists('widget/' . trim($name) . '.php'))
- require_once('widget/' . trim($name) . '.php');
+ $func = 'widget_' . trim($name);
+
+ if(! function_exists($func)) {
+ if(file_exists('widget/' . trim($name) . '.php'))
+ require_once('widget/' . trim($name) . '.php');
+ elseif(folder_exists('widget/'. trim($name))
+ && (file_exists('widget/' . trim($name) . '/' . trim($name) . '.php')))
+ require_once('widget/' . trim($name) . '/' . trim($name) . '.php');
+ }
else {
- $theme_widget = 'widget_' . trim($name) . '.php';
- if(theme_include($theme_widget))
+ $theme_widget = $func . '.php';
+ if((! function_exists($func)) && theme_include($theme_widget))
require_once(theme_include($theme_widget));
}
- $func = 'widget_' . trim($name);
if (function_exists($func))
return $func($vars);
}
diff --git a/include/conversation.php b/include/conversation.php
index 2c447acbc..747bb5d0a 100644
--- a/include/conversation.php
+++ b/include/conversation.php
@@ -697,6 +697,7 @@ function conversation(&$a, $items, $mode, $update, $page_mode = 'traditional', $
'thumb' => $profile_avatar,
'title' => $item['title'],
'body' => $body['html'],
+ 'event' => $body['event'],
'photo' => $body['photo'],
'tags' => $body['tags'],
'categories' => $body['categories'],
@@ -1226,7 +1227,7 @@ function status_editor($a, $x, $popup = false) {
'$wait' => t('Please wait'),
'$permset' => t('Permission settings'),
'$shortpermset' => t('permissions'),
- '$ptyp' => (($notes_cid) ? 'note' : 'wall'),
+ '$ptyp' => '',
'$content' => ((x($x,'body')) ? htmlspecialchars($x['body'], ENT_COMPAT,'UTF-8') : ''),
'$attachment' => ((x($x, 'attachment')) ? $x['attachment'] : ''),
'$post_id' => '',
diff --git a/include/datetime.php b/include/datetime.php
index f7df70a36..1d10e7ad7 100644
--- a/include/datetime.php
+++ b/include/datetime.php
@@ -235,7 +235,7 @@ function datetimesel($format, $min, $max, $default, $label, $id = 'datetimepicke
$o .= replace_macros($tpl,array(
'$field' => array($id, $label, $input_text, (($required) ? t('Required') : ''), (($required) ? '*' : ''), 'placeholder="' . $readable_format . '"'),
));
- $o .= "<script>\$(function () {var picker = \$('#id_$id').datetimepicker({step:5,format:'$dateformat' $minjs $maxjs $pickers $defaultdatejs,dayOfWeekStart:$first_day}); $extra_js})</script>";
+ $o .= "<script>\$(function () {var picker = \$('#id_$id').datetimepicker({step:15,format:'$dateformat' $minjs $maxjs $pickers $defaultdatejs,dayOfWeekStart:$first_day}); $extra_js})</script>";
return $o;
}
diff --git a/include/deliver.php b/include/deliver.php
index de93e316e..7ff0fa125 100644
--- a/include/deliver.php
+++ b/include/deliver.php
@@ -2,6 +2,7 @@
require_once('include/cli_startup.php');
require_once('include/zot.php');
+require_once('include/queue_fn.php');
function deliver_run($argv, $argc) {
@@ -15,7 +16,6 @@ function deliver_run($argv, $argc) {
logger('deliver: invoked: ' . print_r($argv,true), LOGGER_DATA);
-
for($x = 1; $x < $argc; $x ++) {
$dresult = null;
@@ -24,87 +24,6 @@ function deliver_run($argv, $argc) {
);
if($r) {
- /**
- * Check to see if we have any recent communications with this hub (in the last month).
- * If not, reduce the outq_priority.
- */
-
- $base = '';
-
- $h = parse_url($r[0]['outq_posturl']);
- if($h) {
- $base = $h['scheme'] . '://' . $h['host'] . (($h['port']) ? ':' . $h['port'] : '');
- if($base !== z_root()) {
- $y = q("select site_update, site_dead from site where site_url = '%s' ",
- dbesc($base)
- );
- if($y) {
- if(intval($y[0]['site_dead'])) {
- q("delete from outq where outq_posturl = '%s'",
- dbesc($r[0]['outq_posturl'])
- );
- logger('dead site ignored ' . $base);
- continue;
- }
- if($y[0]['site_update'] < datetime_convert('UTC','UTC','now - 1 month')) {
- q("update outq set outq_priority = %d where outq_hash = '%s'",
- intval($r[0]['outq_priority'] + 10),
- dbesc($r[0]['outq_hash'])
- );
- logger('immediate delivery deferred for site ' . $base);
- continue;
- }
- }
- else {
-
- // zot sites should all have a site record, unless they've been dead for as long as
- // your site has existed. Since we don't know for sure what these sites are,
- // call them unknown
-
- q("insert into site (site_url, site_update, site_dead, site_type) values ('%s','%s',0,%d) ",
- dbesc($base),
- dbesc(datetime_convert()),
- intval(($r[0]['outq_driver'] === 'post') ? SITE_TYPE_NOTZOT : SITE_TYPE_UNKNOWN)
- );
- }
- }
- }
-
- // "post" queue driver - used for diaspora and friendica-over-diaspora communications.
-
- if($r[0]['outq_driver'] === 'post') {
-
-
- $result = z_post_url($r[0]['outq_posturl'],$r[0]['outq_msg']);
- if($result['success'] && $result['return_code'] < 300) {
- logger('deliver: queue post success to ' . $r[0]['outq_posturl'], LOGGER_DEBUG);
- if($base) {
- q("update site set site_update = '%s', site_dead = 0 where site_url = '%s' ",
- dbesc(datetime_convert()),
- dbesc($base)
- );
- }
- q("update dreport set dreport_result = '%s', dreport_time = '%s' where dreport_queue = '%s' limit 1",
- dbesc('accepted for delivery'),
- dbesc(datetime_convert()),
- dbesc($argv[$x])
- );
-
- $y = q("delete from outq where outq_hash = '%s'",
- dbesc($argv[$x])
- );
-
- }
- else {
- logger('deliver: queue post returned ' . $result['return_code'] . ' from ' . $r[0]['outq_posturl'],LOGGER_DEBUG);
- $y = q("update outq set outq_updated = '%s' where outq_hash = '%s'",
- dbesc(datetime_convert()),
- dbesc($argv[$x])
- );
- }
- continue;
- }
-
$notify = json_decode($r[0]['outq_notify'],true);
// Messages without an outq_msg will need to go via the web, even if it's a
@@ -127,9 +46,9 @@ function deliver_run($argv, $argc) {
$msg = array('body' => json_encode(array('success' => true, 'pickup' => array(array('notify' => $notify,'message' => $m)))));
$dresult = zot_import($msg,z_root());
}
- $r = q("delete from outq where outq_hash = '%s'",
- dbesc($argv[$x])
- );
+
+ remove_queue_item($r[0]['outq_hash']);
+
if($dresult && is_array($dresult)) {
foreach($dresult as $xx) {
if(is_array($xx) && array_key_exists('message_id',$xx)) {
@@ -147,27 +66,16 @@ function deliver_run($argv, $argc) {
}
}
- q("delete from dreport where dreport_queue = '%s' limit 1",
- dbesc($argv[$x])
- );
- }
- }
- else {
- logger('deliver: dest: ' . $r[0]['outq_posturl'], LOGGER_DEBUG);
- $result = zot_zot($r[0]['outq_posturl'],$r[0]['outq_notify']);
- if($result['success']) {
- logger('deliver: remote zot delivery succeeded to ' . $r[0]['outq_posturl']);
- zot_process_response($r[0]['outq_posturl'],$result, $r[0]);
- }
- else {
- logger('deliver: remote zot delivery failed to ' . $r[0]['outq_posturl']);
- logger('deliver: remote zot delivery fail data: ' . print_r($result,true), LOGGER_DATA);
- $y = q("update outq set outq_updated = '%s' where outq_hash = '%s'",
- dbesc(datetime_convert()),
+ q("delete from dreport where dreport_queue = '%s'",
dbesc($argv[$x])
);
}
}
+
+ // otherwise it's a remote delivery - call queue_deliver();
+
+ queue_deliver($r[0],true);
+
}
}
}
diff --git a/include/dir_fns.php b/include/dir_fns.php
index b9f221bd1..fd2a5835d 100644
--- a/include/dir_fns.php
+++ b/include/dir_fns.php
@@ -22,7 +22,7 @@ function find_upstream_directory($dirmode) {
$r = q("select * from site where site_url = '%s' limit 1",
dbesc($preferred)
);
- if(($r) && ($r[0]['site_flags'] & DIRECTORY_MODE_STADALONE)) {
+ if(($r) && ($r[0]['site_flags'] & DIRECTORY_MODE_STANDALONE)) {
$preferred = '';
}
}
diff --git a/include/directory.php b/include/directory.php
index 9ab1d805b..8792a15e1 100644
--- a/include/directory.php
+++ b/include/directory.php
@@ -8,6 +8,7 @@ require_once('boot.php');
require_once('include/zot.php');
require_once('include/cli_startup.php');
require_once('include/dir_fns.php');
+require_once('include/queue_fn.php');
/**
* @brief
@@ -83,20 +84,17 @@ function directory_run($argv, $argc){
*/
$hash = random_string();
- q("insert into outq ( outq_hash, outq_account, outq_channel, outq_driver, outq_posturl, outq_async, outq_created, outq_updated, outq_notify, outq_msg )
- values ( '%s', %d, %d, '%s', '%s', %d, '%s', '%s', '%s', '%s' )",
- dbesc($hash),
- intval($channel['channel_account_id']),
- intval($channel['channel_id']),
- dbesc('zot'),
- dbesc($url),
- intval(1),
- dbesc(datetime_convert()),
- dbesc(datetime_convert()),
- dbesc($packet),
- dbesc('')
- );
- } else {
+
+ queue_insert(array(
+ 'hash' => $hash,
+ 'account_id' => $channel['channel_account_id'],
+ 'channel_id' => $channel['channel_id'],
+ 'posturl' => $url,
+ 'notify' => $packet,
+ ));
+
+ }
+ else {
q("update channel set channel_dirdate = '%s' where channel_id = %d",
dbesc(datetime_convert()),
intval($channel['channel_id'])
diff --git a/include/event.php b/include/event.php
index e303ad232..539bfe484 100644
--- a/include/event.php
+++ b/include/event.php
@@ -21,35 +21,37 @@ function format_event_html($ev) {
$bd_format = t('l F d, Y \@ g:i A') ; // Friday January 18, 2011 @ 8:01 AM
- $o = '<div class="vevent">' . "\r\n";
+ //todo: move this to template
- $o .= '<p class="summary event-summary">' . bbcode($ev['summary']) . '</p>' . "\r\n";
+ $o = '<div class="vevent">' . "\r\n";
- $o .= '<p class="description event-description">' . bbcode($ev['description']) . '</p>' . "\r\n";
+ $o .= '<div class="event-title"><h3><i class="icon-calendar"></i>&nbsp;' . bbcode($ev['summary']) . '</h3></div>' . "\r\n";
- $o .= '<p class="event-start">' . t('Starts:') . ' <abbr class="dtstart" title="'
+ $o .= '<div class="event-start"><span class="event-label">' . t('Starts:') . '</span>&nbsp;<span class="dtstart" title="'
. datetime_convert('UTC', 'UTC', $ev['start'], (($ev['adjust']) ? ATOM_TIME : 'Y-m-d\TH:i:s' ))
. '" >'
. (($ev['adjust']) ? day_translate(datetime_convert('UTC', date_default_timezone_get(),
$ev['start'] , $bd_format ))
: day_translate(datetime_convert('UTC', 'UTC',
$ev['start'] , $bd_format)))
- . '</abbr></p>' . "\r\n";
+ . '</span></div>' . "\r\n";
if(! $ev['nofinish'])
- $o .= '<p class="event-end" >' . t('Finishes:') . ' <abbr class="dtend" title="'
+ $o .= '<div class="event-end" ><span class="event-label">' . t('Finishes:') . '</span>&nbsp;<span class="dtend" title="'
. datetime_convert('UTC','UTC',$ev['finish'], (($ev['adjust']) ? ATOM_TIME : 'Y-m-d\TH:i:s' ))
. '" >'
. (($ev['adjust']) ? day_translate(datetime_convert('UTC', date_default_timezone_get(),
$ev['finish'] , $bd_format ))
: day_translate(datetime_convert('UTC', 'UTC',
$ev['finish'] , $bd_format )))
- . '</abbr></p>' . "\r\n";
+ . '</span></div>' . "\r\n";
+
+ $o .= '<div class="event-description">' . bbcode($ev['description']) . '</div>' . "\r\n";
if(strlen($ev['location']))
- $o .= '<p class="event-location"> ' . t('Location:') . ' <span class="location">'
+ $o .= '<div class="event-location"><span class="event-label"> ' . t('Location:') . '</span>&nbsp;<span class="location">'
. bbcode($ev['location'])
- . '</span></p>' . "\r\n";
+ . '</span></div>' . "\r\n";
$o .= '</div>' . "\r\n";
@@ -785,6 +787,12 @@ function event_store_item($arr, $event) {
'type' => ACTIVITY_OBJ_EVENT,
'id' => z_root() . '/event/' . $r[0]['resource_id'],
'title' => $arr['summary'],
+ 'start' => $arr['start'],
+ 'finish' => $arr['finish'],
+ 'nofinish' => $arr['nofinish'],
+ 'description' => $arr['description'],
+ 'location' => $arr['location'],
+ 'adjust' => $arr['adjust'],
'content' => format_event_bbcode($arr),
'author' => array(
'name' => $r[0]['xchan_name'],
@@ -887,7 +895,7 @@ function event_store_item($arr, $event) {
$item_arr['verb'] = ACTIVITY_POST;
$item_arr['item_wall'] = $item_wall;
$item_arr['item_origin'] = $item_origin;
- $item_arr['item_thread_top'] = $item_thread_top;;
+ $item_arr['item_thread_top'] = $item_thread_top;
$attach = array(array(
'href' => z_root() . '/events/ical/' . urlencode($event['event_hash']),
@@ -924,6 +932,12 @@ function event_store_item($arr, $event) {
'type' => ACTIVITY_OBJ_EVENT,
'id' => z_root() . '/event/' . $event['event_hash'],
'title' => $arr['summary'],
+ 'start' => $arr['start'],
+ 'finish' => $arr['finish'],
+ 'nofinish' => $arr['nofinish'],
+ 'description' => $arr['description'],
+ 'location' => $arr['location'],
+ 'adjust' => $arr['adjust'],
'content' => format_event_bbcode($arr),
'author' => array(
'name' => $x[0]['xchan_name'],
diff --git a/include/externals.php b/include/externals.php
index 18c034bb2..3a3a32420 100644
--- a/include/externals.php
+++ b/include/externals.php
@@ -28,7 +28,10 @@ function externals_run($argv, $argc){
}
else {
$randfunc = db_getfunc('RAND');
- $r = q("select site_url, site_pull from site where site_url != '%s' and site_flags != %d and site_type = %d order by $randfunc limit 1",
+
+ // fixme this query does not deal with directory realms.
+
+ $r = q("select site_url, site_pull from site where site_url != '%s' and site_flags != %d and site_type = %d and site_dead = 0 order by $randfunc limit 1",
dbesc(z_root()),
intval(DIRECTORY_MODE_STANDALONE),
intval(SITE_TYPE_ZOT)
@@ -37,19 +40,11 @@ function externals_run($argv, $argc){
$url = $r[0]['site_url'];
}
- // Note: blacklisted sites must be stored in the config as an array.
- // No simple way to turn this into a personal config because we have no identity here.
- // For that we probably need a variant of superblock.
-
$blacklisted = false;
- $bl1 = get_config('system','blacklisted_sites');
- if(is_array($bl1) && $bl1) {
- foreach($bl1 as $bl) {
- if($bl && strpos($url,$bl) !== false) {
- $blacklisted = true;
- break;
- }
- }
+
+ if(! check_siteallowed($url)) {
+ logger('blacklisted site: ' . $url);
+ $blacklisted = true;
}
$attempts ++;
diff --git a/include/follow.php b/include/follow.php
index 40ad2c299..97be82da7 100644
--- a/include/follow.php
+++ b/include/follow.php
@@ -161,6 +161,7 @@ function new_contact($uid,$url,$channel,$interactive = false, $confirm = false)
}
}
if($r) {
+ $xchan = $r[0];
$xchan_hash = $r[0]['xchan_hash'];
$their_perms = 0;
}
@@ -172,7 +173,7 @@ function new_contact($uid,$url,$channel,$interactive = false, $confirm = false)
return $result;
}
- $x = array('channel_id' => $uid, 'follow_address' => $url, 'xchan' => $r[0], 'allowed' => 1);
+ $x = array('channel_id' => $uid, 'follow_address' => $url, 'xchan' => $r[0], 'allowed' => 1, 'singleton' => 0);
call_hooks('follow_allow',$x);
@@ -180,7 +181,7 @@ function new_contact($uid,$url,$channel,$interactive = false, $confirm = false)
$result['message'] = t('Protocol disabled.');
return $result;
}
-
+ $singleton = intval($x['singleton']);
if((local_channel()) && $uid == local_channel()) {
$aid = get_account_id();
@@ -221,13 +222,22 @@ function new_contact($uid,$url,$channel,$interactive = false, $confirm = false)
return $result;
}
- $r = q("select abook_xchan from abook where abook_xchan = '%s' and abook_channel = %d limit 1",
+ $r = q("select abook_xchan, abook_instance from abook where abook_xchan = '%s' and abook_channel = %d limit 1",
dbesc($xchan_hash),
intval($uid)
);
if($r) {
- $x = q("update abook set abook_their_perms = %d where abook_id = %d",
+ $abook_instance = $r[0]['abook_instance'];
+
+ if(($singleton) && strpos($abook_instance,z_root()) === false) {
+ if($abook_instance)
+ $abook_instance .= ',';
+ $abook_instance .= z_root();
+ }
+
+ $x = q("update abook set abook_their_perms = %d, abook_instance = '%s' where abook_id = %d",
intval($their_perms),
+ dbesc($abook_instance),
intval($r[0]['abook_id'])
);
}
@@ -237,8 +247,8 @@ function new_contact($uid,$url,$channel,$interactive = false, $confirm = false)
if($closeness === false)
$closeness = 80;
- $r = q("insert into abook ( abook_account, abook_channel, abook_closeness, abook_xchan, abook_feed, abook_their_perms, abook_my_perms, abook_created, abook_updated )
- values( %d, %d, %d, '%s', %d, %d, %d, '%s', '%s' ) ",
+ $r = q("insert into abook ( abook_account, abook_channel, abook_closeness, abook_xchan, abook_feed, abook_their_perms, abook_my_perms, abook_created, abook_updated, abook_instance )
+ values( %d, %d, %d, '%s', %d, %d, %d, '%s', '%s', '%s' ) ",
intval($aid),
intval($uid),
intval($closeness),
@@ -247,7 +257,8 @@ function new_contact($uid,$url,$channel,$interactive = false, $confirm = false)
intval(($is_http) ? $their_perms|PERMS_R_STREAM|PERMS_A_REPUBLISH : $their_perms),
intval($my_perms),
dbesc(datetime_convert()),
- dbesc(datetime_convert())
+ dbesc(datetime_convert()),
+ dbesc(($singleton) ? z_root() : '')
);
}
diff --git a/include/identity.php b/include/identity.php
index 95ade3b28..98ba26bd8 100644
--- a/include/identity.php
+++ b/include/identity.php
@@ -896,12 +896,6 @@ function profile_load(&$a, $nickname, $profile = '') {
$_SESSION['theme'] = $p[0]['channel_theme'];
-// $a->set_template_engine(); // reset the template engine to the default in case the user's theme doesn't specify one
-
-// $theme_info_file = "view/theme/".current_theme()."/php/theme.php";
-// if (file_exists($theme_info_file)){
-// require_once($theme_info_file);
-// }
}
/**
diff --git a/include/items.php b/include/items.php
index 7d349c631..44f9633a9 100755
--- a/include/items.php
+++ b/include/items.php
@@ -550,6 +550,7 @@ function get_public_feed($channel, $params) {
$params['direction'] = ((x($params,'direction')) ? $params['direction'] : 'desc');
$params['pages'] = ((x($params,'pages')) ? intval($params['pages']) : 0);
$params['top'] = ((x($params,'top')) ? intval($params['top']) : 0);
+ $params['cat'] = ((x($params,'cat')) ? $params['cat'] : '');
switch($params['type']) {
case 'json':
@@ -593,7 +594,8 @@ function get_feed_for($channel, $observer_hash, $params) {
'direction' => $params['direction'], // FIXME
'pages' => $params['pages'],
'order' => 'post',
- 'top' => $params['top']
+ 'top' => $params['top'],
+ 'cat' => $params['cat']
), $channel, $observer_hash, CLIENT_MODE_NORMAL, get_app()->module);
@@ -2347,7 +2349,7 @@ function item_store($arr, $allow_exec = false) {
return $ret;
}
- if($arr['obj_type'] == ACTIVITY_OBJ_NOTE)
+ if(($arr['obj_type'] == ACTIVITY_OBJ_NOTE) && (! $arr['object']))
$arr['obj_type'] = ACTIVITY_OBJ_COMMENT;
// is the new message multi-level threaded?
@@ -2868,6 +2870,7 @@ function send_status_notifications($post_id,$item) {
if($x) {
foreach($x as $xx) {
if($xx['author_xchan'] === $r[0]['channel_hash']) {
+
$notify = true;
// check for an unfollow thread activity - we should probably decode the obj and check the id
@@ -3332,7 +3335,6 @@ function start_delivery_chain($channel, $item, $item_id, $parent) {
if((! $private) && $new_public_policy)
$private = 1;
-
$item_wall = 1;
$item_origin = 1;
$item_uplink = 0;
@@ -3383,8 +3385,13 @@ function start_delivery_chain($channel, $item, $item_id, $parent) {
if($r)
proc_run('php','include/notifier.php','tgroup',$item_id);
- else
+ else {
logger('start_delivery_chain: failed to update item');
+ // reset the source xchan to prevent loops
+ $r = q("update item set source_xchan = '' where id = %d",
+ intval($item_id)
+ );
+ }
}
/**
@@ -3472,7 +3479,7 @@ function post_is_importable($item,$abook) {
unobscure($item);
$text = prepare_text($item['body'],$item['mimetype']);
- $text = html2plain($text);
+ $text = html2plain(($item['title']) ? $item['title'] . ' ' . $text : $text);
$lang = null;
@@ -3947,6 +3954,8 @@ function atom_entry($item,$type,$author,$owner,$comment = false,$cid = 0) {
return '<at:deleted-entry ref="' . xmlify($item['mid']) . '" when="' . xmlify(datetime_convert('UTC','UTC',$item['edited'] . '+00:00',ATOM_TIME)) . '" />' . "\r\n";
+ create_export_photo_body($item);
+
if($item['allow_cid'] || $item['allow_gid'] || $item['deny_cid'] || $item['deny_gid'])
$body = fix_private_photos($item['body'],$owner['uid'],$item,$cid);
else
@@ -4817,6 +4826,9 @@ function items_fetch($arr,$channel = null,$observer_hash = null,$client_mode = C
if($arr['since_id'])
$sql_extra .= " and item.id > " . $since_id . " ";
+ if($arr['cat'])
+ $sql_extra .= protect_sprintf(term_query('item', $arr['cat'], TERM_CATEGORY));
+
if($arr['gid'] && $uid) {
$r = q("SELECT * FROM `groups` WHERE id = %d AND uid = %d LIMIT 1",
intval($arr['group']),
diff --git a/include/js_strings.php b/include/js_strings.php
index a21461a52..b1817f373 100644
--- a/include/js_strings.php
+++ b/include/js_strings.php
@@ -22,6 +22,7 @@ function js_strings() {
'$submit' => t('Submit'),
'$linkurl' => t('Please enter a link URL'),
'$leavethispage' => t('Unsaved changes. Are you sure you wish to leave this page?'),
+ '$location' => t('Location'),
'$t01' => ((t('timeago.prefixAgo') != 'timeago.prefixAgo') ? t('timeago.prefixAgo') : ''),
'$t02' => ((t('timeago.prefixFromNow') != 'timeago.prefixFromNow') ? t('timeago.prefixFromNow') : ''),
diff --git a/include/message.php b/include/message.php
index 820d814b6..940fcc275 100644
--- a/include/message.php
+++ b/include/message.php
@@ -13,6 +13,7 @@ function send_message($uid = 0, $recipient='', $body='', $subject='', $replyto='
$ret = array('success' => false);
$a = get_app();
+ $observer_hash = get_observer_hash();
if(! $recipient) {
$ret['message'] = t('No recipient provided.');
@@ -148,8 +149,8 @@ function send_message($uid = 0, $recipient='', $body='', $subject='', $replyto='
$match = null;
$images = null;
- if(preg_match_all("/\[zmg\](.*?)\[\/zmg\]/",((strpos($body,'[/crypt]')) ? $_POST['media_str'] : $body),$match))
- $images = $match[1];
+ if(preg_match_all("/\[zmg\=([0-9]*)x([0-9]*)\](.*?)\[\/zmg\]/",((strpos($body,'[/crypt]')) ? $_POST['media_str'] : $body),$match))
+ $images = $match[3];
$match = false;
@@ -173,7 +174,7 @@ function send_message($uid = 0, $recipient='', $body='', $subject='', $replyto='
'revision' => $r['data']['revision']
);
}
- $body = str_replace($match[1],'',$body);
+ $body = trim(str_replace($match[1],'',$body));
}
}
@@ -230,7 +231,7 @@ function send_message($uid = 0, $recipient='', $body='', $subject='', $replyto='
dbesc($image_uri),
intval($channel['channel_id']),
dbesc('<' . $channel['channel_hash'] . '>')
- );
+ );
$r = q("UPDATE attach SET allow_cid = '%s' WHERE hash = '%s' AND is_photo = 1 and uid = %d and allow_cid = '%s'",
dbesc('<' . $recipient . '>'),
dbesc($image_uri),
@@ -239,7 +240,7 @@ function send_message($uid = 0, $recipient='', $body='', $subject='', $replyto='
);
}
}
-
+
if($attaches) {
foreach($attaches as $attach) {
$hash = substr($attach,0,strpos($attach,','));
@@ -505,3 +506,4 @@ function private_messages_fetch_conversation($channel_id, $messageitem_id, $upda
return $messages;
}
+
diff --git a/include/network.php b/include/network.php
index 026f5ee0a..68452c3d1 100644
--- a/include/network.php
+++ b/include/network.php
@@ -1709,3 +1709,190 @@ function do_delivery($deliveries) {
}
+
+
+function get_site_info() {
+
+ global $db;
+ global $a;
+
+ $register_policy = Array('REGISTER_CLOSED', 'REGISTER_APPROVE', 'REGISTER_OPEN');
+ $directory_mode = Array('DIRECTORY_MODE_NORMAL', 'DIRECTORY_MODE_SECONDARY','DIRECTORY_MODE_PRIMARY', 256 => 'DIRECTORY_MODE_STANDALONE');
+
+ $sql_extra = '';
+
+ $r = q("select * from channel left join account on account_id = channel_account_id where ( account_roles & 4096 )>0 and account_default_channel = channel_id");
+
+
+ if($r) {
+ $admin = array();
+ foreach($r as $rr) {
+ if($rr['channel_pageflags'] & PAGE_HUBADMIN)
+ $admin[] = array( 'name' => $rr['channel_name'], 'address' => $rr['channel_address'] . '@' . get_app()->get_hostname(), 'channel' => z_root() . '/channel/' . $rr['channel_address']);
+ }
+ if(! $admin) {
+ foreach($r as $rr) {
+ $admin[] = array( 'name' => $rr['channel_name'], 'address' => $rr['channel_address'] . '@' . get_app()->get_hostname(), 'channel' => z_root() . '/channel/' . $rr['channel_address']);
+ }
+ }
+ }
+ else {
+ $admin = false;
+ }
+
+ $def_service_class = get_config('system','default_service_class');
+ if($def_service_class)
+ $service_class = get_config('service_class',$def_service_class);
+ else
+ $service_class = false;
+
+ $visible_plugins = array();
+ if(is_array($a->plugins) && count($a->plugins)) {
+ $r = q("select * from addon where hidden = 0");
+ if(count($r))
+ foreach($r as $rr)
+ $visible_plugins[] = $rr['name'];
+ }
+ sort($visible_plugins);
+
+ if(@is_dir('.git') && function_exists('shell_exec'))
+ $commit = trim(@shell_exec('git log -1 --format="%h"'));
+ if(! isset($commit) || strlen($commit) > 16)
+ $commit = '';
+
+ $site_info = get_config('system','info');
+ $site_name = get_config('system','sitename');
+ if(! get_config('system','hidden_version_siteinfo')) {
+ $version = RED_VERSION;
+ $tag = get_std_version();
+
+ if(@is_dir('.git') && function_exists('shell_exec')) {
+ $commit = trim( @shell_exec('git log -1 --format="%h"'));
+// if(! get_config('system','hidden_tag_siteinfo'))
+// $tag = trim( @shell_exec('git describe --tags --abbrev=0'));
+// else
+// $tag = '';
+ }
+ if(! isset($commit) || strlen($commit) > 16)
+ $commit = '';
+ }
+ else {
+ $version = $commit = '';
+ }
+
+ //Statistics
+ $channels_total_stat = intval(get_config('system','channels_total_stat'));
+ $channels_active_halfyear_stat = intval(get_config('system','channels_active_halfyear_stat'));
+ $channels_active_monthly_stat = intval(get_config('system','channels_active_monthly_stat'));
+ $local_posts_stat = intval(get_config('system','local_posts_stat'));
+ $hide_in_statistics = intval(get_config('system','hide_in_statistics'));
+ $site_expire = intval(get_config('system', 'default_expire_days'));
+
+
+ $data = Array(
+ 'version' => $version,
+ 'version_tag' => $tag,
+ 'commit' => $commit,
+ 'url' => z_root(),
+ 'plugins' => $visible_plugins,
+ 'register_policy' => $register_policy[get_config('system','register_policy')],
+ 'directory_mode' => $directory_mode[get_config('system','directory_mode')],
+ 'language' => get_config('system','language'),
+ 'rss_connections' => get_config('system','feed_contacts'),
+ 'expiration' => $site_expire,
+ 'default_service_restrictions' => $service_class,
+ 'admin' => $admin,
+ 'site_name' => (($site_name) ? $site_name : ''),
+ 'platform' => PLATFORM_NAME,
+ 'dbdriver' => $db->getdriver(),
+ 'lastpoll' => get_config('system','lastpoll'),
+ 'info' => (($site_info) ? $site_info : ''),
+ 'channels_total' => $channels_total_stat,
+ 'channels_active_halfyear' => $channels_active_halfyear_stat,
+ 'channels_active_monthly' => $channels_active_monthly_stat,
+ 'local_posts' => $local_posts_stat,
+ 'hide_in_statistics' => $hide_in_statistics
+ );
+ return $data;
+}
+
+
+
+function check_siteallowed($url) {
+
+ $retvalue = true;
+
+
+ $arr = array('url' => $url);
+ call_hooks('check_siteallowed',$arr);
+
+ if(array_key_exists('allowed',$arr))
+ return $arr['allowed'];
+
+ $bl1 = get_config('system','whitelisted_sites');
+ if(is_array($bl1) && $bl1) {
+ foreach($bl1 as $bl) {
+ if($bl1 === '*')
+ $retvalue = true;
+ if($bl && strpos($url,$bl) !== false)
+ return true;
+ }
+ }
+ $bl1 = get_config('system','blacklisted_sites');
+ if(is_array($bl1) && $bl1) {
+ foreach($bl1 as $bl) {
+ if($bl1 === '*')
+ $retvalue = false;
+ if($bl && strpos($url,$bl) !== false) {
+ return false;
+ }
+ }
+ }
+ return $retvalue;
+}
+
+function check_channelallowed($hash) {
+
+ $retvalue = true;
+
+ $arr = array('hash' => $hash);
+ call_hooks('check_channelallowed',$arr);
+
+ if(array_key_exists('allowed',$arr))
+ return $arr['allowed'];
+
+ $bl1 = get_config('system','whitelisted_channels');
+ if(is_array($bl1) && $bl1) {
+ foreach($bl1 as $bl) {
+ if($bl1 === '*')
+ $retvalue = true;
+ if($bl && strpos($hash,$bl) !== false)
+ return true;
+ }
+ }
+ $bl1 = get_config('system','blacklisted_channels');
+ if(is_array($bl1) && $bl1) {
+ foreach($bl1 as $bl) {
+ if($bl1 === '*')
+ $retvalue = false;
+ if($bl && strpos($hash,$bl) !== false) {
+ return false;
+ }
+ }
+ }
+ return $retvalue;
+}
+
+function deliverable_singleton($xchan) {
+ $r = q("select abook_instance from abook where abook_xchan = '%s' limit 1",
+ dbesc($xchan['xchan_hash'])
+ );
+ if($r) {
+ if(! $r[0]['abook_instance'])
+ return true;
+ if(strpos($r[0]['abook_instance'],z_root()) !== false)
+ return true;
+ }
+ return false;
+}
+
diff --git a/include/notifier.php b/include/notifier.php
index b7830285a..50981df9d 100644
--- a/include/notifier.php
+++ b/include/notifier.php
@@ -44,7 +44,6 @@ require_once('include/html2plain.php');
* expire (in items.php)
* like (in like.php, poke.php)
* mail (in message.php)
- * suggest (in fsuggest.php)
* tag (in photos.php, poke.php, tagger.php)
* tgroup (in items.php)
* wall-new (in photos.php, item.php)
@@ -52,11 +51,14 @@ require_once('include/html2plain.php');
* and ITEM_ID is the id of the item in the database that needs to be sent to others.
*
* ZOT
+ * permission_create abook_id
* permission_update abook_id
* refresh_all channel_id
* purge_all channel_id
* expire channel_id
* relay item_id (item was relayed to owner, we will deliver it as owner)
+ * single_activity item_id (deliver to a singleton network from the appropriate clone)
+ * single_mail mail_id (deliver to a singleton network from the appropriate clone)
* location channel_id
* request channel_id xchan_hash message_id
* rating xlink_id
@@ -66,6 +68,12 @@ require_once('include/html2plain.php');
require_once('include/cli_startup.php');
require_once('include/zot.php');
require_once('include/queue_fn.php');
+require_once('include/session.php');
+require_once('include/datetime.php');
+require_once('include/items.php');
+require_once('include/bbcode.php');
+require_once('include/identity.php');
+require_once('include/Contact.php');
function notifier_run($argv, $argc){
@@ -73,15 +81,10 @@ function notifier_run($argv, $argc){
$a = get_app();
- require_once("session.php");
- require_once("datetime.php");
- require_once('include/items.php');
- require_once('include/bbcode.php');
if($argc < 3)
return;
-
logger('notifier: invoked: ' . print_r($argv,true), LOGGER_DEBUG);
$cmd = $argv[1];
@@ -93,7 +96,6 @@ function notifier_run($argv, $argc){
if(! $item_id)
return;
- require_once('include/identity.php');
$sys = get_sys_channel();
$deliveries = array();
@@ -108,87 +110,8 @@ function notifier_run($argv, $argc){
}
- if($cmd == 'permission_update' || $cmd == 'permission_create') {
- // Get the recipient
- $r = q("select abook.*, hubloc.* from abook
- left join hubloc on hubloc_hash = abook_xchan
- where abook_id = %d and abook_self = 0
- and not (hubloc_flags & %d) > 0 and not (hubloc_status & %d) > 0 limit 1",
- intval($item_id),
- intval(HUBLOC_FLAGS_DELETED),
- intval(HUBLOC_OFFLINE)
- );
-
- if($r) {
- // Get the sender
- $s = q("select * from channel left join xchan on channel_hash = xchan_hash where channel_id = %d limit 1",
- intval($r[0]['abook_channel'])
- );
- if($s) {
- $perm_update = array('sender' => $s[0], 'recipient' => $r[0], 'success' => false, 'deliveries' => '');
-
- if($cmd == 'permission_create')
- call_hooks('permissions_create',$perm_update);
- else
- call_hooks('permissions_update',$perm_update);
-
- if($perm_update['success'] && $perm_update['deliveries'])
- $deliveries[] = $perm_update['deliveries'];
-
- if(! $perm_update['success']) {
- // send a refresh message to each hub they have registered here
- $h = q("select * from hubloc where hubloc_hash = '%s'
- and not (hubloc_flags & %d) > 0 and not (hubloc_status & %d) > 0",
- dbesc($r[0]['hubloc_hash']),
- intval(HUBLOC_FLAGS_DELETED),
- intval(HUBLOC_OFFLINE)
- );
- if($h) {
- foreach($h as $hh) {
- if(in_array($hh['hubloc_url'],$dead_hubs)) {
- logger('skipping dead hub: ' . $hh['hubloc_url'], LOGGER_DEBUG);
- continue;
- }
-
- $data = zot_build_packet($s[0],'refresh',array(array(
- 'guid' => $hh['hubloc_guid'],
- 'guid_sig' => $hh['hubloc_guid_sig'],
- 'url' => $hh['hubloc_url'])
- ));
- if($data) {
- $hash = random_string();
- q("insert into outq ( outq_hash, outq_account, outq_channel, outq_driver, outq_posturl, outq_async, outq_created, outq_updated, outq_notify, outq_msg )
- values ( '%s', %d, %d, '%s', '%s', %d, '%s', '%s', '%s', '%s' )",
- dbesc($hash),
- intval($s[0]['channel_account_id']),
- intval($s[0]['channel_id']),
- dbesc('zot'),
- dbesc($hh['hubloc_callback']),
- intval(1),
- dbesc(datetime_convert()),
- dbesc(datetime_convert()),
- dbesc($data),
- dbesc('')
- );
- $deliveries[] = $hash;
- }
- }
-
- }
- }
-
- if($deliveries)
- do_delivery($deliveries);
- }
- }
- return;
- }
-
-
- $expire = false;
$request = false;
$mail = false;
- $fsuggest = false;
$top_level = false;
$location = false;
$recipients = array();
@@ -237,51 +160,42 @@ function notifier_run($argv, $argc){
$packet_type = 'request';
$normal_mode = false;
}
- elseif($cmd === 'expire') {
-
- // FIXME
- // This will require a special zot packet containing a list of item message_id's to be expired.
- // This packet will be public, since we cannot selectively deliver here.
- // We need the handling on this end to create the array, and the handling on the remote end
- // to verify permissions (for each item) and process it. Until this is complete, the expire feature will be disabled.
-
- return;
-
- $normal_mode = false;
- $expire = true;
- $items = q("SELECT * FROM item WHERE uid = %d AND item_wall = 1
- AND item_deleted = 1 AND `changed` > %s - INTERVAL %s",
- intval($item_id),
- db_utcnow(), db_quoteinterval('10 MINUTE')
+ elseif($cmd == 'permission_update' || $cmd == 'permission_create') {
+ // Get the (single) recipient
+ $r = q("select * from abook left join xchan on abook_xchan = xchan_hash where abook_id = %d and abook_self = 0",
+ intval($item_id)
);
- $uid = $item_id;
- $item_id = 0;
- if(! $items)
- return;
+ if($r) {
+ $uid = $r[0]['abook_channel'];
+ // Get the sender
+ $channel = channelx_by_n($uid);
+ if($channel) {
+ $perm_update = array('sender' => $channel, 'recipient' => $r[0], 'success' => false, 'deliveries' => '');
- }
- elseif($cmd === 'suggest') {
- $normal_mode = false;
- $fsuggest = true;
+ if($cmd == 'permission_create')
+ call_hooks('permissions_create',$perm_update);
+ else
+ call_hooks('permissions_update',$perm_update);
- $suggest = q("SELECT * FROM `fsuggest` WHERE `id` = %d LIMIT 1",
- intval($item_id)
- );
- if(! count($suggest))
- return;
- $uid = $suggest[0]['uid'];
- $recipients[] = $suggest[0]['cid'];
- $item = $suggest[0];
+ if($perm_update['success']) {
+ if($perm_update['deliveries']) {
+ $deliveries[] = $perm_update['deliveries'];
+ do_delivery($deliveries);
+ }
+ return;
+ }
+ else {
+ $recipients[] = $r[0]['abook_xchan'];
+ $private = false;
+ $packet_type = 'refresh';
+ }
+ }
+ }
}
elseif($cmd === 'refresh_all') {
logger('notifier: refresh_all: ' . $item_id);
- $s = q("select * from channel where channel_id = %d limit 1",
- intval($item_id)
- );
- if($s)
- $channel = $s[0];
$uid = $item_id;
- $recipients = array();
+ $channel = channelx_by_n($item_id);
$r = q("select abook_xchan from abook where abook_channel = %d",
intval($item_id)
);
@@ -464,9 +378,12 @@ function notifier_run($argv, $argc){
// if our parent is a tag_delivery recipient, uplink to the original author causing
// a delivery fork.
- if(intval($parent_item['item_uplink']) && (! $top_level_post) && ($cmd !== 'uplink')) {
- logger('notifier: uplinking this item');
- proc_run('php','include/notifier.php','uplink',$item_id);
+ if(($parent_item) && intval($parent_item['item_uplink']) && (! $top_level_post) && ($cmd !== 'uplink')) {
+ // don't uplink a relayed post to the relay owner
+ if($parent_item['source_xchan'] !== $parent_item['owner_xchan']) {
+ logger('notifier: uplinking this item');
+ proc_run('php','include/notifier.php','uplink',$item_id);
+ }
}
$private = false;
@@ -605,10 +522,8 @@ function notifier_run($argv, $argc){
'relay_to_owner' => $relay_to_owner,
'uplink' => $uplink,
'cmd' => $cmd,
- 'expire' => $expire,
'mail' => $mail,
'location' => $location,
- 'fsuggest' => $fsuggest,
'request' => $request,
'normal_mode' => $normal_mode,
'packet_type' => $packet_type,
@@ -628,52 +543,38 @@ function notifier_run($argv, $argc){
// default: zot protocol
-
$hash = random_string();
+ $packet = null;
+
if($packet_type === 'refresh' || $packet_type === 'purge') {
- $n = zot_build_packet($channel,$packet_type);
- q("insert into outq ( outq_hash, outq_account, outq_channel, outq_driver, outq_posturl, outq_async, outq_created, outq_updated, outq_notify, outq_msg ) values ( '%s', %d, %d, '%s', '%s', %d, '%s', '%s', '%s', '%s' )",
- dbesc($hash),
- intval($channel['channel_account_id']),
- intval($channel['channel_id']),
- dbesc('zot'),
- dbesc($hub['hubloc_callback']),
- intval(1),
- dbesc(datetime_convert()),
- dbesc(datetime_convert()),
- dbesc($n),
- dbesc('')
- );
+ $packet = zot_build_packet($channel,$packet_type);
}
elseif($packet_type === 'request') {
- $n = zot_build_packet($channel,'request',$env_recips,$hub['hubloc_sitekey'],$hash,array('message_id' => $request_message_id));
- q("insert into outq ( outq_hash, outq_account, outq_channel, outq_driver, outq_posturl, outq_async, outq_created, outq_updated, outq_notify, outq_msg ) values ( '%s', %d, %d, '%s', '%s', %d, '%s', '%s', '%s', '%s' )",
- dbesc($hash),
- intval($channel['channel_account_id']),
- intval($channel['channel_id']),
- dbesc('zot'),
- dbesc($hub['hubloc_callback']),
- intval(1),
- dbesc(datetime_convert()),
- dbesc(datetime_convert()),
- dbesc($n),
- dbesc('')
+ $packet = zot_build_packet($channel,$packet_type,$env_recips,$hub['hubloc_sitekey'],$hash,
+ array('message_id' => $request_message_id)
);
}
+
+ if($packet) {
+ queue_insert(array(
+ 'hash' => $hash,
+ 'account_id' => $channel['channel_account_id'],
+ 'channel_id' => $channel['channel_id'],
+ 'posturl' => $hub['hubloc_callback'],
+ 'notify' => $packet
+ ));
+ }
else {
- $n = zot_build_packet($channel,'notify',$env_recips,(($private) ? $hub['hubloc_sitekey'] : null),$hash);
- q("insert into outq ( outq_hash, outq_account, outq_channel, outq_driver, outq_posturl, outq_async, outq_created, outq_updated, outq_notify, outq_msg ) values ( '%s', %d, %d, '%s', '%s', %d, '%s', '%s', '%s', '%s' )",
- dbesc($hash),
- intval($target_item['aid']),
- intval($target_item['uid']),
- dbesc('zot'),
- dbesc($hub['hubloc_callback']),
- intval(1),
- dbesc(datetime_convert()),
- dbesc(datetime_convert()),
- dbesc($n),
- dbesc(json_encode($encoded_item))
- );
+ $packet = zot_build_packet($channel,'notify',$env_recips,(($private) ? $hub['hubloc_sitekey'] : null),$hash);
+ queue_insert(array(
+ 'hash' => $hash,
+ 'account_id' => $target_item['aid'],
+ 'channel_id' => $target_item['uid'],
+ 'posturl' => $hub['hubloc_callback'],
+ 'notify' => $packet,
+ 'msg' => json_encode($encoded_item)
+ ));
+
// only create delivery reports for normal undeleted items
if(is_array($target_item) && array_key_exists('postopts',$target_item) && (! $target_item['item_deleted'])) {
q("insert into dreport ( dreport_mid, dreport_site, dreport_recip, dreport_result, dreport_time, dreport_xchan, dreport_queue ) values ( '%s','%s','%s','%s','%s','%s','%s' ) ",
diff --git a/include/oauth.php b/include/oauth.php
index 80336f906..f3d144158 100644
--- a/include/oauth.php
+++ b/include/oauth.php
@@ -1,4 +1,5 @@
<?php /** @file */
+
/**
* OAuth server
* Based on oauth2-php <http://code.google.com/p/oauth2-php/>
@@ -9,16 +10,17 @@ define('REQUEST_TOKEN_DURATION', 300);
define('ACCESS_TOKEN_DURATION', 31536000);
require_once("library/OAuth1.php");
-require_once("library/oauth2-php/lib/OAuth2.inc");
-class FKOAuthDataStore extends OAuthDataStore {
- function gen_token(){
+//require_once("library/oauth2-php/lib/OAuth2.inc");
+
+class ZotOAuth1DataStore extends OAuth1DataStore {
+
+ function gen_token(){
return md5(base64_encode(pack('N6', mt_rand(), mt_rand(), mt_rand(), mt_rand(), mt_rand(), uniqid())));
- }
+ }
- function lookup_consumer($consumer_key) {
- logger(__function__.":".$consumer_key);
-// echo "<pre>"; var_dump($consumer_key); killme();
+ function lookup_consumer($consumer_key) {
+ logger('consumer_key: ' . $consumer_key, LOGGER_DEBUG);
$r = q("SELECT client_id, pw, redirect_uri FROM clients WHERE client_id = '%s'",
dbesc($consumer_key)
@@ -26,13 +28,14 @@ class FKOAuthDataStore extends OAuthDataStore {
if($r) {
get_app()->set_oauth_key($consumer_key);
- return new OAuthConsumer($r[0]['client_id'],$r[0]['pw'],$r[0]['redirect_uri']);
+ return new OAuth1Consumer($r[0]['client_id'],$r[0]['pw'],$r[0]['redirect_uri']);
}
return null;
- }
+ }
- function lookup_token($consumer, $token_type, $token) {
- logger(__function__.":".$consumer.", ". $token_type.", ".$token);
+ function lookup_token($consumer, $token_type, $token) {
+
+ logger(__function__.":".$consumer.", ". $token_type.", ".$token, LOGGER_DEBUG);
$r = q("SELECT id, secret, scope, expires, uid FROM tokens WHERE client_id = '%s' AND scope = '%s' AND id = '%s'",
dbesc($consumer->key),
@@ -41,17 +44,16 @@ class FKOAuthDataStore extends OAuthDataStore {
);
if (count($r)){
- $ot=new OAuthToken($r[0]['id'],$r[0]['secret']);
+ $ot=new OAuth1Token($r[0]['id'],$r[0]['secret']);
$ot->scope=$r[0]['scope'];
$ot->expires = $r[0]['expires'];
$ot->uid = $r[0]['uid'];
return $ot;
}
return null;
- }
+ }
- function lookup_nonce($consumer, $token, $nonce, $timestamp) {
-// echo __file__.":".__line__."<pre>"; var_dump($consumer,$key); killme();
+ function lookup_nonce($consumer, $token, $nonce, $timestamp) {
$r = q("SELECT id, secret FROM tokens WHERE client_id = '%s' AND id = '%s' AND expires = %d",
dbesc($consumer->key),
@@ -60,12 +62,14 @@ class FKOAuthDataStore extends OAuthDataStore {
);
if (count($r))
- return new OAuthToken($r[0]['id'],$r[0]['secret']);
+ return new OAuth1Token($r[0]['id'],$r[0]['secret']);
return null;
- }
+ }
+
+ function new_request_token($consumer, $callback = null) {
+
+ logger(__function__.":".$consumer.", ". $callback, LOGGER_DEBUG);
- function new_request_token($consumer, $callback = null) {
- logger(__function__.":".$consumer.", ". $callback);
$key = $this->gen_token();
$sec = $this->gen_token();
@@ -82,29 +86,31 @@ class FKOAuthDataStore extends OAuthDataStore {
'request',
time()+intval(REQUEST_TOKEN_DURATION));
- if (!$r) return null;
- return new OAuthToken($key,$sec);
- }
+ if(! $r)
+ return null;
+ return new OAuth1Token($key,$sec);
+ }
- function new_access_token($token, $consumer, $verifier = null) {
- logger(__function__.":".$token.", ". $consumer.", ". $verifier);
-
- // return a new access token attached to this consumer
- // for the user associated with this token if the request token
- // is authorized
- // should also invalidate the request token
-
- $ret=Null;
+ function new_access_token($token, $consumer, $verifier = null) {
+
+ logger(__function__.":".$token.", ". $consumer.", ". $verifier, LOGGER_DEBUG);
- // get user for this verifier
- $uverifier = get_config("oauth", $verifier);
- logger(__function__.":".$verifier.",".$uverifier);
- if (is_null($verifier) || ($uverifier!==false)){
+ // return a new access token attached to this consumer
+ // for the user associated with this token if the request token
+ // is authorized
+ // should also invalidate the request token
+
+ $ret=Null;
+
+ // get user for this verifier
+ $uverifier = get_config("oauth", $verifier);
+ logger(__function__.":".$verifier.",".$uverifier, LOGGER_DEBUG);
+ if (is_null($verifier) || ($uverifier!==false)) {
- $key = $this->gen_token();
- $sec = $this->gen_token();
+ $key = $this->gen_token();
+ $sec = $this->gen_token();
- $r = q("INSERT INTO tokens (id, secret, client_id, scope, expires, uid) VALUES ('%s','%s','%s','%s', %d, %d)",
+ $r = q("INSERT INTO tokens (id, secret, client_id, scope, expires, uid) VALUES ('%s','%s','%s','%s', %d, %d)",
dbesc($key),
dbesc($sec),
dbesc($consumer->key),
@@ -112,81 +118,70 @@ class FKOAuthDataStore extends OAuthDataStore {
time()+intval(ACCESS_TOKEN_DURATION),
intval($uverifier));
- if ($r)
- $ret = new OAuthToken($key,$sec);
- }
+ if ($r)
+ $ret = new OAuth1Token($key,$sec);
+ }
- q("DELETE FROM tokens WHERE id='%s'", $token->key);
+ q("DELETE FROM tokens WHERE id='%s'", $token->key);
- if (!is_null($ret) && $uverifier!==false){
- del_config("oauth", $verifier);
- /* $apps = get_pconfig($uverifier, "oauth", "apps");
- if ($apps===false) $apps=array();
- $apps[] = $consumer->key;
- set_pconfig($uverifier, "oauth", "apps", $apps);*/
+ if (!is_null($ret) && $uverifier!==false) {
+ del_config("oauth", $verifier);
+
+ // $apps = get_pconfig($uverifier, "oauth", "apps");
+ // if ($apps===false) $apps=array();
+ // $apps[] = $consumer->key;
+ // set_pconfig($uverifier, "oauth", "apps", $apps);
+ }
+ return $ret;
}
-
- return $ret;
-
- }
}
-class FKOAuth1 extends OAuthServer {
+class ZotOAuth1 extends OAuth1Server {
function __construct() {
- parent::__construct(new FKOAuthDataStore());
- $this->add_signature_method(new OAuthSignatureMethod_PLAINTEXT());
- $this->add_signature_method(new OAuthSignatureMethod_HMAC_SHA1());
+ parent::__construct(new ZotOAuth1DataStore());
+ $this->add_signature_method(new OAuth1SignatureMethod_PLAINTEXT());
+ $this->add_signature_method(new OAuth1SignatureMethod_HMAC_SHA1());
}
function loginUser($uid){
- logger("RedOAuth1::loginUser $uid");
- $a = get_app();
+
+ logger("ZotOAuth1::loginUser $uid");
+
$r = q("SELECT * FROM channel WHERE channel_id = %d LIMIT 1",
intval($uid)
);
if(count($r)){
$record = $r[0];
} else {
- logger('FKOAuth1::loginUser failure: ' . print_r($_SERVER,true), LOGGER_DEBUG);
- header('HTTP/1.0 401 Unauthorized');
- die('This api requires login');
+ logger('ZotOAuth1::loginUser failure: ' . print_r($_SERVER,true), LOGGER_DEBUG);
+ header('HTTP/1.0 401 Unauthorized');
+ echo('This api requires login');
+ killme();
}
$_SESSION['uid'] = $record['channel_id'];
- $_SESSION['theme'] = $record['channel_theme'];
- $_SESSION['account_id'] = $record['channel_account_id'];
- $_SESSION['mobile_theme'] = get_pconfig($record['channel_id'], 'system', 'mobile_theme');
- $_SESSION['authenticated'] = 1;
- $_SESSION['my_url'] = $a->get_baseurl() . '/channel/' . $record['channel_address'];
$_SESSION['addr'] = $_SERVER['REMOTE_ADDR'];
- $_SESSION['allow_api'] = true;
+
$x = q("select * from account where account_id = %d limit 1",
intval($record['channel_account_id'])
);
- if($x)
- $a->account = $x[0];
-
- change_channel($record['channel_id']);
-
- $a->channel = $record;
-
- if(strlen($a->channel['channel_timezone'])) {
- date_default_timezone_set($a->channel['channel_timezone']);
+ if($x) {
+ require_once('include/security.php');
+ authenticate_success($x[0],true,false,true,true);
+ $_SESSION['allow_api'] = true;
}
-
-// q("UPDATE `user` SET `login_date` = '%s' WHERE `uid` = %d LIMIT 1",
-// dbesc(datetime_convert()),
-// intval($_SESSION['uid'])
-// );
-//
-// call_hooks('logged_in', $a->user);
}
}
+
/*
+ *
+
+ not yet used
+
class FKOAuth2 extends OAuth2 {
private function db_secret($client_secret){
diff --git a/include/photos.php b/include/photos.php
index c7360a956..93511d2c0 100644
--- a/include/photos.php
+++ b/include/photos.php
@@ -292,17 +292,35 @@ function photo_upload($channel, $observer, $args) {
$tag = (($r2) ? '[zmg=' . $width . 'x' . $height . ']' : '[zmg]');
}
- $body = '[zrl=' . z_root() . '/photos/' . $channel['channel_address'] . '/image/' . $photo_hash . ']'
+ $author_link = '[zrl=' . z_root() . '/channel/' . $channel['channel_address'] . ']' . $channel['channel_name'] . '[/zrl]';
+
+ $photo_link = '[zrl=' . z_root() . '/photos/' . $channel['channel_address'] . '/image/' . $photo_hash . ']' . t('a new photo') . '[/zrl]';
+
+ $album_link = '[zrl=' . z_root() . '/photos/album/' . bin2hex($album) . ']' . $album . '[/zrl]';
+
+ $activity_format = sprintf(t('%1$s posted %2$s to %3$s','photo_upload'), $author_link, $photo_link, $album_link);
+
+ $summary = $activity_format . "\n\n" . (($args['body']) ? $args['body'] . "\n\n" : '');
+
+ $obj_body = '[zrl=' . z_root() . '/photos/' . $channel['channel_address'] . '/image/' . $photo_hash . ']'
. $tag . z_root() . "/photo/{$photo_hash}-{$scale}." . $ph->getExt() . '[/zmg]'
. '[/zrl]';
// Create item object
$object = array(
- 'type' => ACTIVITY_OBJ_PHOTO,
- 'title' => $title,
- 'id' => rawurlencode(z_root() . '/photos/' . $channel['channel_address'] . '/image/' . $photo_hash),
- 'link' => $link,
- 'bbcode' => $body
+ 'type' => ACTIVITY_OBJ_PHOTO,
+ 'title' => $title,
+ 'created' => $p['created'],
+ 'edited' => $p['edited'],
+ 'id' => rawurlencode(z_root() . '/photos/' . $channel['channel_address'] . '/image/' . $photo_hash),
+ 'link' => $link,
+ 'body' => $obj_body
+ );
+
+ $target = array(
+ 'type' => ACTIVITY_OBJ_ALBUM,
+ 'title' => (($album) ? $album : '/'),
+ 'id' => rawurlencode(z_root() . '/photos/' . $channel['channel_address'] . '/album/' . bin2hex($album))
);
// Create item container
@@ -314,9 +332,12 @@ function photo_upload($channel, $observer, $args) {
if($item['mid'] === $item['parent_mid']) {
- $item['body'] = (($object) ? $args['body'] : $body . "\r\n" . $args['body']);
- $item['obj_type'] = (($object) ? ACTIVITY_OBJ_PHOTO : '');
- $item['object'] = (($object) ? json_encode($object) : '');
+ $item['body'] = $args['body'];
+ $item['obj_type'] = ACTIVITY_OBJ_PHOTO;
+ $item['object'] = json_encode($object);
+
+ $item['tgt_type'] = ACTIVITY_OBJ_ALBUM;
+ $item['target'] = json_encode($target);
if($item['author_xchan'] === $channel['channel_hash']) {
$item['sig'] = base64url_encode(rsa_sign($item['body'],$channel['channel_prvkey']));
@@ -370,14 +391,16 @@ function photo_upload($channel, $observer, $args) {
$arr['deny_cid'] = $ac['deny_cid'];
$arr['deny_gid'] = $ac['deny_gid'];
$arr['verb'] = ACTIVITY_POST;
- $arr['obj_type'] = (($object) ? ACTIVITY_OBJ_PHOTO : '');
- $arr['object'] = (($object) ? json_encode($object) : '');
+ $arr['obj_type'] = ACTIVITY_OBJ_PHOTO;
+ $arr['object'] = json_encode($object);
+ $arr['tgt_type'] = ACTIVITY_OBJ_ALBUM;
+ $arr['target'] = json_encode($target);
$arr['item_wall'] = 1;
$arr['item_origin'] = 1;
$arr['item_thread_top'] = 1;
$arr['item_private'] = intval($acl->is_private());
$arr['plink'] = z_root() . '/channel/' . $channel['channel_address'] . '/?f=&mid=' . $arr['mid'];
- $arr['body'] = (($object) ? $args['body'] : $body . "\r\n" . $args['body']);
+ $arr['body'] = $summary;
// this one is tricky because the item and the photo have the same permissions, those of the photo.
@@ -402,7 +425,7 @@ function photo_upload($channel, $observer, $args) {
$ret['success'] = true;
$ret['item'] = $arr;
- $ret['body'] = $body;
+ $ret['body'] = $obj_body;
$ret['resource_id'] = $photo_hash;
$ret['photoitem_id'] = $item_id;
diff --git a/include/plugin.php b/include/plugin.php
index 8749f3fbf..4a35a0170 100755
--- a/include/plugin.php
+++ b/include/plugin.php
@@ -495,6 +495,15 @@ function format_css_if_exists($source) {
return '<link rel="stylesheet" href="' . script_path() . '/' . $path . '" type="text/css" media="' . $source[1] . '">' . "\r\n";
}
+/*
+ * This basically calculates the baseurl. We have other functions to do that, but
+ * there was an issue with script paths and mixed-content whose details are arcane
+ * and perhaps lost in the message archives. The short answer is that we're ignoring
+ * the URL which we are "supposed" to use, and generating script paths relative to
+ * the URL which we are currently using; in order to ensure they are found and aren't
+ * blocked due to mixed content issues.
+ */
+
function script_path() {
if(x($_SERVER,'HTTPS') && $_SERVER['HTTPS'])
$scheme = 'https';
@@ -616,3 +625,24 @@ function get_markup_template($s, $root = '') {
$template = $t->get_markup_template($s, $root);
return $template;
}
+
+// return the standardised version. Since we can't easily compare
+// before the STD_VERSION definition was applied, we have to treat
+// all prior release versions the same. You can dig through them
+// with other means (such as RED_VERSION) if necessary.
+
+function get_std_version() {
+ if(defined('STD_VERSION'))
+ return STD_VERSION;
+ return '0.0.0';
+}
+
+
+function folder_exists($folder)
+{
+ // Get canonicalized absolute pathname
+ $path = realpath($folder);
+
+ // If it exist, check if it's a directory
+ return (($path !== false) && is_dir($path)) ? $path : false;
+} \ No newline at end of file
diff --git a/include/queue.php b/include/queue.php
index 71ac50c83..8a3b2aa58 100644
--- a/include/queue.php
+++ b/include/queue.php
@@ -18,11 +18,8 @@ function queue_run($argv, $argc){
else
$queue_id = 0;
- $deadguys = array();
-
logger('queue: start');
-
// delete all queue items more than 3 days old
// but first mark these sites dead if we haven't heard from them in a month
@@ -88,59 +85,7 @@ function queue_run($argv, $argc){
return;
foreach($r as $rr) {
-
- $dresult = null;
-
- if(in_array($rr['outq_posturl'],$deadguys))
- continue;
-
- $base = '';
- $h = parse_url($rr['outq_posturl']);
- if($h)
- $base = $h['scheme'] . '://' . $h['host'] . (($h['port']) ? ':' . $h['port'] : '');
-
- if($rr['outq_driver'] === 'post') {
- $result = z_post_url($rr['outq_posturl'],$rr['outq_msg']);
- if($result['success'] && $result['return_code'] < 300) {
- logger('queue: queue post success to ' . $rr['outq_posturl'], LOGGER_DEBUG);
- if($base) {
- q("update site set site_update = '%s', site_dead = 0 where site_url = '%s' ",
- dbesc(datetime_convert()),
- dbesc($base)
- );
- }
- q("update dreport set dreport_result = '%s', dreport_time = '%s' where dreport_queue = '%s' limit 1",
- dbesc('accepted for delivery'),
- dbesc(datetime_convert()),
- dbesc($rr['outq_hash'])
- );
- $y = q("delete from outq where outq_hash = '%s'",
- dbesc($rr['outq_hash'])
- );
- }
- else {
- logger('queue: queue post returned ' . $result['return_code'] . ' from ' . $rr['outq_posturl'],LOGGER_DEBUG);
- $y = q("update outq set outq_updated = '%s', outq_priority = outq_priority + 10 where outq_hash = '%s'",
- dbesc(datetime_convert()),
- dbesc($rr['outq_hash'])
- );
- $deadguys[] = $rr['outq_posturl'];
- }
- continue;
- }
- $result = zot_zot($rr['outq_posturl'],$rr['outq_notify']);
- if($result['success']) {
- logger('queue: deliver zot success to ' . $rr['outq_posturl'], LOGGER_DEBUG);
- zot_process_response($rr['outq_posturl'],$result, $rr);
- }
- else {
- $deadguys[] = $rr['outq_posturl'];
- logger('queue: deliver zot returned ' . $result['return_code'] . ' from ' . $rr['outq_posturl'],LOGGER_DEBUG);
- $y = q("update outq set outq_updated = '%s', outq_priority = outq_priority + 10 where outq_hash = '%s'",
- dbesc(datetime_convert()),
- dbesc($rr['outq_hash'])
- );
- }
+ queue_deliver($rr);
}
}
diff --git a/include/queue_fn.php b/include/queue_fn.php
index 22580bc48..1e53d7488 100644
--- a/include/queue_fn.php
+++ b/include/queue_fn.php
@@ -1,18 +1,145 @@
<?php /** @file */
-function update_queue_time($id) {
- logger('queue: requeue item ' . $id);
- q("UPDATE outq SET outq_updated = '%s' WHERE outq_hash = '%s'",
+function update_queue_item($id, $add_priority = 0) {
+ logger('queue: requeue item ' . $id,LOGGER_DEBUG);
+ q("UPDATE outq SET outq_updated = '%s', outq_priority = outq_priority + %d WHERE outq_hash = '%s'",
dbesc(datetime_convert()),
+ intval($add_priority),
dbesc($id)
);
}
-function remove_queue_item($id) {
- logger('queue: remove queue item ' . $id);
- q("DELETE FROM outq WHERE hash = '%s'",
+function remove_queue_item($id,$channel_id = 0) {
+ logger('queue: remove queue item ' . $id,LOGGER_DEBUG);
+ $sql_extra = (($channel_id) ? " and outq_channel = " . intval($channel_id) . " " : '');
+
+ q("DELETE FROM outq WHERE outq_hash = '%s' $sql_extra",
dbesc($id)
);
}
+function remove_queue_by_posturl($posturl) {
+ logger('queue: remove queue posturl ' . $posturl,LOGGER_DEBUG);
+
+ q("DELETE FROM outq WHERE outq_posturl = '%s' ",
+ dbesc($posturl)
+ );
+}
+
+
+
+function queue_set_delivered($id,$channel = 0) {
+ logger('queue: set delivered ' . $id,LOGGER_DEBUG);
+ $sql_extra = (($channel_id) ? " and outq_channel = " . intval($channel_id) . " " : '');
+
+ q("update outq set outq_delivered = 1, outq_updated = '%s' where outq_hash = '%s' $sql_extra ",
+ dbesc(datetime_convert()),
+ dbesc($id)
+ );
+}
+
+
+
+function queue_insert($arr) {
+
+ $x = q("insert into outq ( outq_hash, outq_account, outq_channel, outq_driver, outq_posturl, outq_async, outq_priority,
+ outq_created, outq_updated, outq_notify, outq_msg )
+ values ( '%s', %d, %d, '%s', '%s', %d, %d, '%s', '%s', '%s', '%s' )",
+ dbesc($arr['hash']),
+ intval($arr['account_id']),
+ intval($arr['channel_id']),
+ dbesc(($arr['driver']) ? $arr['driver'] : 'zot'),
+ dbesc($arr['posturl']),
+ intval(1),
+ intval(($arr['priority']) ? $arr['priority'] : 0),
+ dbesc(datetime_convert()),
+ dbesc(datetime_convert()),
+ dbesc($arr['notify']),
+ dbesc(($arr['msg']) ? $arr['msg'] : '')
+ );
+ return $x;
+
+}
+
+
+
+function queue_deliver($outq, $immediate = false) {
+
+ $base = null;
+ $h = parse_url($outq['outq_posturl']);
+ if($h)
+ $base = $h['scheme'] . '://' . $h['host'] . (($h['port']) ? ':' . $h['port'] : '');
+
+ if(($base) && ($base !== z_root()) && ($immediate)) {
+ $y = q("select site_update, site_dead from site where site_url = '%s' ",
+ dbesc($base)
+ );
+ if($y) {
+ if(intval($y[0]['site_dead'])) {
+ remove_queue_by_posturl($outq['outq_posturl']);
+ logger('dead site ignored ' . $base);
+ return;
+ }
+ if($y[0]['site_update'] < datetime_convert('UTC','UTC','now - 1 month')) {
+ update_queue_item($outq['outq_hash'],10);
+ logger('immediate delivery deferred for site ' . $base);
+ return;
+ }
+ }
+ else {
+ // zot sites should all have a site record, unless they've been dead for as long as
+ // your site has existed. Since we don't know for sure what these sites are,
+ // call them unknown
+
+ q("insert into site (site_url, site_update, site_dead, site_type) values ('%s','%s',0,%d) ",
+ dbesc($base),
+ dbesc(datetime_convert()),
+ intval(($outq['outq_driver'] === 'post') ? SITE_TYPE_NOTZOT : SITE_TYPE_UNKNOWN)
+ );
+ }
+ }
+
+ // "post" queue driver - used for diaspora and friendica-over-diaspora communications.
+
+ if($outq['outq_driver'] === 'post') {
+ $result = z_post_url($outq['outq_posturl'],$outq['outq_msg']);
+ if($result['success'] && $result['return_code'] < 300) {
+ logger('deliver: queue post success to ' . $outq['outq_posturl'], LOGGER_DEBUG);
+ if($base) {
+ q("update site set site_update = '%s', site_dead = 0 where site_url = '%s' ",
+ dbesc(datetime_convert()),
+ dbesc($base)
+ );
+ }
+ q("update dreport set dreport_result = '%s', dreport_time = '%s' where dreport_queue = '%s' limit 1",
+ dbesc('accepted for delivery'),
+ dbesc(datetime_convert()),
+ dbesc($outq['outq_hash'])
+ );
+ remove_queue_item($outq['outq_hash']);
+ }
+ else {
+ logger('deliver: queue post returned ' . $result['return_code']
+ . ' from ' . $outq['outq_posturl'],LOGGER_DEBUG);
+ update_queue_item($argv[$x]);
+ }
+ return;
+ }
+
+ // normal zot delivery
+
+ logger('deliver: dest: ' . $outq['outq_posturl'], LOGGER_DEBUG);
+ $result = zot_zot($outq['outq_posturl'],$outq['outq_notify']);
+ if($result['success']) {
+ logger('deliver: remote zot delivery succeeded to ' . $outq['outq_posturl']);
+ zot_process_response($outq['outq_posturl'],$result, $outq);
+ }
+ else {
+ logger('deliver: remote zot delivery failed to ' . $outq['outq_posturl']);
+ logger('deliver: remote zot delivery fail data: ' . print_r($result,true), LOGGER_DATA);
+ update_queue_item($outq['outq_hash'],10);
+ }
+ return;
+}
+
diff --git a/include/ratenotif.php b/include/ratenotif.php
index 63fd7c2ee..e94f30247 100644
--- a/include/ratenotif.php
+++ b/include/ratenotif.php
@@ -82,18 +82,14 @@ function ratenotif_run($argv, $argc){
$hash = random_string();
$n = zot_build_packet($channel,'notify',null,null,$hash);
- q("insert into outq ( outq_hash, outq_account, outq_channel, outq_driver, outq_posturl, outq_async, outq_created, outq_updated, outq_notify, outq_msg ) values ( '%s', %d, %d, '%s', '%s', %d, '%s', '%s', '%s', '%s' )",
- dbesc($hash),
- intval($channel['channel_account_id']),
- intval($channel['channel_id']),
- dbesc('zot'),
- dbesc($h . '/post'),
- intval(1),
- dbesc(datetime_convert()),
- dbesc(datetime_convert()),
- dbesc($n),
- dbesc(json_encode($encoded_item))
- );
+ queue_insert(array(
+ 'hash' => $hash,
+ 'account_id' => $channel['channel_account_id'],
+ 'channel_id' => $channel['channel_id'],
+ 'posturl' => $h . '/post',
+ 'notify' => $n,
+ 'msg' => json_encode($encoded_item)
+ ));
$deliver[] = $hash;
diff --git a/include/security.php b/include/security.php
index 9a25d9e0e..d4ebe0024 100644
--- a/include/security.php
+++ b/include/security.php
@@ -93,6 +93,7 @@ function change_channel($change_channel) {
$ret = false;
if($change_channel) {
+
$r = q("select channel.*, xchan.* from channel left join xchan on channel.channel_hash = xchan.xchan_hash where channel_id = %d and channel_account_id = %d and channel_removed = 0 limit 1",
intval($change_channel),
intval(get_account_id())
@@ -136,14 +137,14 @@ function change_channel($change_channel) {
}
/**
- * @brief Creates an addiontal SQL where statement to check permissions.
+ * @brief Creates an additional SQL where statement to check permissions.
*
* @param int $owner_id
- * @param bool $remote_verified default false, not used at all
- * @param string $groups this param is not used at all
+ * @param bool $remote_observer - if unset use current observer
*
* @return string additional SQL where statement
*/
+
function permissions_sql($owner_id, $remote_observer = null) {
$local_channel = local_channel();
@@ -208,8 +209,7 @@ function permissions_sql($owner_id, $remote_observer = null) {
* @brief Creates an addiontal SQL where statement to check permissions for an item.
*
* @param int $owner_id
- * @param bool $remote_verified default false, not used at all
- * @param string $groups this param is not used at all
+ * @param bool $remote_observer, use current observer if unset
*
* @return string additional SQL where statement
*/
@@ -400,11 +400,9 @@ function check_form_security_token_ForbiddenOnErr($typename = '', $formname = 'f
}
-// Returns an array of group id's this contact is a member of.
-// This array will only contain group id's related to the uid of this
-// DFRN contact. They are *not* neccessarily unique across the entire site.
+// Returns an array of group hash id's on this entire site (across all channels) that this connection is a member of.
+// var $contact_id = xchan_hash of connection
-if(! function_exists('init_groups_visitor')) {
function init_groups_visitor($contact_id) {
$groups = array();
$r = q("SELECT hash FROM `groups` left join group_member on groups.id = group_member.gid WHERE xchan = '%s' ",
@@ -415,7 +413,7 @@ function init_groups_visitor($contact_id) {
$groups[] = $rr['hash'];
}
return $groups;
-}}
+}
diff --git a/include/taxonomy.php b/include/taxonomy.php
index b396d53f1..0bf89a7c1 100644
--- a/include/taxonomy.php
+++ b/include/taxonomy.php
@@ -117,6 +117,8 @@ function tagadelic($uid, $count = 0, $authors = '', $owner = '', $flags = 0, $re
if(! perm_is_allowed($uid,get_observer_hash(),'view_stream'))
return array();
+
+ $item_normal = item_normal();
$sql_options = item_permissions_sql($uid);
$count = intval($count);
@@ -142,7 +144,7 @@ function tagadelic($uid, $count = 0, $authors = '', $owner = '', $flags = 0, $re
$r = q("select term, count(term) as total from term left join item on term.oid = item.id
where term.uid = %d and term.type = %d
and otype = %d and item_type = %d and item_private = 0
- $sql_options
+ $sql_options $item_normal
group by term order by total desc %s",
intval($uid),
intval($type),
diff --git a/include/text.php b/include/text.php
index eb9171b40..dd52b16b6 100644
--- a/include/text.php
+++ b/include/text.php
@@ -5,6 +5,7 @@
require_once("include/template_processor.php");
require_once("include/smarty.php");
+require_once("include/bbcode.php");
// random string, there are 86 characters max in text mode, 128 for hex
// output is urlsafe
@@ -1380,25 +1381,49 @@ function generate_named_map($location) {
return (($arr['html']) ? $arr['html'] : $location);
}
+function format_event($jobject) {
+ $event = array();
+ $object = json_decode($jobject,true);
+
+ //ensure compatibility with older items - this check can be removed at a later point
+ if(array_key_exists('description', $object)) {
+
+ $bd_format = t('l F d, Y \@ g:i A'); // Friday January 18, 2011 @ 8:01 AM
+
+ $event['header'] = replace_macros(get_markup_template('event_item_header.tpl'),array(
+ '$title' => bbcode($object['title']),
+ '$dtstart_label' => t('Starts:'),
+ '$dtstart_title' => datetime_convert('UTC', 'UTC', $object['start'], (($object['adjust']) ? ATOM_TIME : 'Y-m-d\TH:i:s' )),
+ '$dtstart_dt' => (($object['adjust']) ? day_translate(datetime_convert('UTC', date_default_timezone_get(), $object['start'] , $bd_format )) : day_translate(datetime_convert('UTC', 'UTC', $object['start'] , $bd_format))),
+ '$finish' => (($object['nofinish']) ? false : true),
+ '$dtend_label' => t('Finishes:'),
+ '$dtend_title' => datetime_convert('UTC','UTC',$object['finish'], (($object['adjust']) ? ATOM_TIME : 'Y-m-d\TH:i:s' )),
+ '$dtend_dt' => (($object['adjust']) ? day_translate(datetime_convert('UTC', date_default_timezone_get(), $object['finish'] , $bd_format )) : day_translate(datetime_convert('UTC', 'UTC', $object['finish'] , $bd_format )))
+ ));
+
+ $event['content'] = replace_macros(get_markup_template('event_item_content.tpl'),array(
+ '$description' => bbcode($object['description']),
+ '$location_label' => t('Location:'),
+ '$location' => bbcode($object['location'])
+ ));
+
+ }
+
+ return $event;
+}
function prepare_body(&$item,$attach = false) {
require_once('include/identity.php');
-// if($item['html']) {
-// $s = bb_observer($item['html']);
-// }
-// else {
- call_hooks('prepare_body_init', $item);
-// unobscure($item);
- $s = prepare_text($item['body'],$item['mimetype'], false);
-// }
+ call_hooks('prepare_body_init', $item);
$photo = '';
- $is_photo = (($item['obj_type'] === ACTIVITY_OBJ_PHOTO) ? true : false);
+ $is_photo = ((($item['verb'] === ACTIVITY_POST) && ($item['obj_type'] === ACTIVITY_OBJ_PHOTO)) ? true : false);
if($is_photo) {
+
$object = json_decode($item['object'],true);
// if original photo width is <= 640px prepend it to item body
@@ -1413,9 +1438,14 @@ function prepare_body(&$item,$attach = false) {
}
}
+ $s = prepare_text($item['body'],$item['mimetype'], false);
+
+ $event = (($item['obj_type'] === ACTIVITY_OBJ_EVENT) ? format_event($item['object']) : false);
+
$prep_arr = array(
'item' => $item,
- 'html' => $s,
+ 'html' => $event ? $event['content'] : $s,
+ 'event' => $event['header'],
'photo' => $photo
);
@@ -1423,6 +1453,7 @@ function prepare_body(&$item,$attach = false) {
$s = $prep_arr['html'];
$photo = $prep_arr['photo'];
+ $event = $prep_arr['event'];
// q("update item set html = '%s' where id = %d",
// dbesc($s),
@@ -1489,6 +1520,7 @@ function prepare_body(&$item,$attach = false) {
'item' => $item,
'photo' => $photo,
'html' => $s,
+ 'event' => $event,
'categories' => $categories,
'folders' => $filer,
'tags' => $tags,
@@ -1566,6 +1598,16 @@ function prepare_text($text, $content_type = 'text/bbcode', $cache = false) {
}
+function create_export_photo_body(&$item) {
+ if(($item['verb'] === ACTIVITY_POST) && ($item['obj_type'] === ACTIVITY_OBJ_PHOTO)) {
+ $j = json_decode($item['object'],true);
+ if($j) {
+ $item['body'] .= "\n\n" . (($j['body']) ? $j['body'] : $j['bbcode']);
+ $item['sig'] = '';
+ }
+ }
+}
+
/**
* zidify_callback() and zidify_links() work together to turn any HTML a tags with class="zrl" into zid links
* These will typically be generated by a bbcode '[zrl]' tag. This is done inside prepare_text() rather than bbcode()
diff --git a/include/widgets.php b/include/widgets.php
index a3f7444ec..4b14d6c94 100644
--- a/include/widgets.php
+++ b/include/widgets.php
@@ -666,7 +666,7 @@ function widget_eventsmenu($arr) {
if (! local_channel())
return;
- return replace_macros(get_markup_template('events_side.tpl'), array(
+ return replace_macros(get_markup_template('events_menu_side.tpl'), array(
'$title' => t('Events Menu'),
'$day' => t('Day View'),
'$week' => t('Week View'),
@@ -677,6 +677,18 @@ function widget_eventsmenu($arr) {
));
}
+function widget_eventstools($arr) {
+ if (! local_channel())
+ return;
+
+ return replace_macros(get_markup_template('events_tools_side.tpl'), array(
+ '$title' => t('Events Tools'),
+ '$export' => t('Export Calendar'),
+ '$import' => t('Import Calendar'),
+ '$submit' => t('Submit')
+ ));
+}
+
function widget_design_tools($arr) {
$a = get_app();
@@ -1136,7 +1148,7 @@ function widget_forums($arr) {
foreach($r1 as $rr) {
if($unseen && (! intval($rr['unseen'])))
continue;
- $o .= '<li><span class="pull-right">' . ((intval($rr['unseen'])) ? intval($rr['unseen']) : '') . '</span><a href="network?f=&pf=1&cid=' . $rr['abook_id'] . '" ><img src="' . $rr['xchan_photo_s'] . '" style="width: 16px; height: 16px;" /> ' . $rr['xchan_name'] . '</a></li>';
+ $o .= '<li><a href="network?f=&pf=1&cid=' . $rr['abook_id'] . '" ><span class="badge pull-right">' . ((intval($rr['unseen'])) ? intval($rr['unseen']) : '') . '</span><img src="' . $rr['xchan_photo_s'] . '" style="width: 16px; height: 16px;" /> ' . $rr['xchan_name'] . '</a></li>';
}
$o .= '</ul></div>';
}
@@ -1147,6 +1159,8 @@ function widget_forums($arr) {
function widget_tasklist($arr) {
+ if (! local_channel())
+ return;
require_once('include/event.php');
$o .= '<script>var tasksShowAll = 0; $(document).ready(function() { tasksFetch(); $("#tasklist-new-form").submit(function(event) { event.preventDefault(); $.post( "tasks/new", $("#tasklist-new-form").serialize(), function(data) { tasksFetch(); $("#tasklist-new-summary").val(""); } ); return false; } )});</script>';
@@ -1285,7 +1299,6 @@ function widget_album($args) {
//edit album name
$album_edit = null;
-
$photos = array();
if($r) {
$twist = 'rotright';
@@ -1324,6 +1337,7 @@ function widget_album($args) {
$o .= replace_macros($tpl, array(
'$photos' => $photos,
'$album' => (($title) ? $title : $album),
+ '$album_id' => rand(),
'$album_edit' => array(t('Edit Album'), $album_edit),
'$can_post' => false,
'$upload' => array(t('Upload'), z_root() . '/photos/' . get_app()->profile['channel_address'] . '/upload/' . bin2hex($album)),
diff --git a/include/zot.php b/include/zot.php
index 2366c1d2d..922637bc1 100644
--- a/include/zot.php
+++ b/include/zot.php
@@ -12,6 +12,7 @@ require_once('include/crypto.php');
require_once('include/items.php');
require_once('include/hubloc.php');
require_once('include/DReport.php');
+require_once('include/queue_fn.php');
/**
@@ -554,18 +555,8 @@ function zot_gethub($arr,$multiple = false) {
if($arr['guid'] && $arr['guid_sig'] && $arr['url'] && $arr['url_sig']) {
- $blacklisted = false;
- $bl1 = get_config('system','blacklisted_sites');
- if(is_array($bl1) && $bl1) {
- foreach($bl1 as $bl) {
- if($bl && strpos($arr['url'],$bl) !== false) {
- $blacklisted = true;
- break;
- }
- }
- }
- if($blacklisted) {
- logger('zot_gethub: blacklisted site: ' . $arr['url']);
+ if(! check_siteallowed($arr['url'])) {
+ logger('blacklisted site: ' . $arr['url']);
return null;
}
@@ -1007,7 +998,9 @@ function zot_process_response($hub, $arr, $outq) {
}
}
- q("delete from dreport where dreport_queue = '%s' limit 1",
+ // we have a more descriptive delivery report, so discard the per hub 'queued' report.
+
+ q("delete from dreport where dreport_queue = '%s' ",
dbesc($outq['outq_hash'])
);
@@ -1021,18 +1014,8 @@ function zot_process_response($hub, $arr, $outq) {
// synchronous message types are handled immediately
// async messages remain in the queue until processed.
- if (intval($outq['outq_async'])) {
- q("update outq set outq_delivered = 1, outq_updated = '%s' where outq_hash = '%s' and outq_channel = %d",
- dbesc(datetime_convert()),
- dbesc($outq['outq_hash']),
- intval($outq['outq_channel'])
- );
- } else {
- q("delete from outq where outq_hash = '%s' and outq_channel = %d",
- dbesc($outq['outq_hash']),
- intval($outq['outq_channel'])
- );
- }
+ if(intval($outq['outq_async']))
+ queue_set_delivered($outq['outq_hash'],$outq['outq_channel']);
logger('zot_process_response: ' . print_r($x,true), LOGGER_DEBUG);
}
@@ -1246,6 +1229,10 @@ function zot_import($arr, $sender_url) {
$no_dups = array();
if($deliveries) {
foreach($deliveries as $d) {
+ if(! is_array($d)) {
+ logger('Delivery hash array is not an array: ' . print_r($d,true));
+ continue;
+ }
if(! in_array($d['hash'],$no_dups))
$no_dups[] = $d['hash'];
}
@@ -1617,6 +1604,14 @@ function process_delivery($sender, $arr, $deliveries, $relay, $public = false, $
$channel = $r[0];
$DR->addto_recipient($channel['channel_name'] . ' <' . $channel['channel_address'] . '@' . get_app()->get_hostname() . '>');
+ /* blacklisted channels get a permission denied, no special message to tip them off */
+
+ if(! check_channelallowed($sender['hash'])) {
+ $DR->update('permission denied');
+ $result[] = $DR->get();
+ continue;
+ }
+
/**
* @FIXME: Somehow we need to block normal message delivery from our clones, as the delivered
* message doesn't have ACL information in it as the cloned copy does. That copy
@@ -2088,6 +2083,14 @@ function process_mail_delivery($sender, $arr, $deliveries) {
$channel = $r[0];
$DR->addto_recipient($channel['channel_name'] . ' <' . $channel['channel_address'] . '@' . get_app()->get_hostname() . '>');
+ /* blacklisted channels get a permission denied, no special message to tip them off */
+
+ if(! check_channelallowed($sender['hash'])) {
+ $DR->update('permission denied');
+ $result[] = $DR->get();
+ continue;
+ }
+
if(! perm_is_allowed($channel['channel_id'],$sender['hash'],'post_mail')) {
logger("permission denied for mail delivery {$channel['channel_id']}");
$DR->update('permission denied');
@@ -2964,24 +2967,19 @@ function build_sync_packet($uid = 0, $packet = null, $groups_changed = false) {
$interval = ((get_config('system','delivery_interval') !== false)
? intval(get_config('system','delivery_interval')) : 2 );
-
logger('build_sync_packet: packet: ' . print_r($info,true), LOGGER_DATA);
foreach($synchubs as $hub) {
$hash = random_string();
$n = zot_build_packet($channel,'notify',$env_recips,$hub['hubloc_sitekey'],$hash);
- q("insert into outq ( outq_hash, outq_account, outq_channel, outq_driver, outq_posturl, outq_async, outq_created, outq_updated, outq_notify, outq_msg ) values ( '%s', %d, %d, '%s', '%s', %d, '%s', '%s', '%s', '%s' )",
- dbesc($hash),
- intval($channel['channel_account']),
- intval($channel['channel_id']),
- dbesc('zot'),
- dbesc($hub['hubloc_callback']),
- intval(1),
- dbesc(datetime_convert()),
- dbesc(datetime_convert()),
- dbesc($n),
- dbesc(json_encode($info))
- );
+ queue_insert(array(
+ 'hash' => $hash,
+ 'account_id' => $channel['channel_account_id'],
+ 'channel_id' => $channel['channel_id'],
+ 'posturl' => $hub['hubloc_callback'],
+ 'notify' => $n,
+ 'msg' => json_encode($info)
+ ));
proc_run('php', 'include/deliver.php', $hash);
if($interval)
@@ -3484,13 +3482,13 @@ function import_author_zot($x) {
* @param array $data
* @return array
*/
-function zot_process_message_request($data) {
+function zot_reply_message_request($data) {
$ret = array('success' => false);
if (! $data['message_id']) {
$ret['message'] = 'no message_id';
logger('no message_id');
- return $ret;
+ json_return_and_die($ret);
}
$sender = $data['sender'];
@@ -3508,7 +3506,7 @@ function zot_process_message_request($data) {
if (! $c) {
logger('recipient channel not found.');
$ret['message'] .= 'recipient not found.' . EOL;
- return $ret;
+ json_return_and_die($ret);
}
/*
@@ -3520,13 +3518,13 @@ function zot_process_message_request($data) {
if ($messages) {
$env_recips = null;
- $r = q("select * from hubloc where hubloc_hash = '%s' and not hubloc_error and not hubloc_deleted
+ $r = q("select * from hubloc where hubloc_hash = '%s' and hubloc_error = 0 and hubloc_deleted = 0
group by hubloc_sitekey",
dbesc($sender_hash)
);
if (! $r) {
logger('no hubs');
- return $ret;
+ json_return_and_die($ret);
}
$hubs = $r;
@@ -3544,20 +3542,15 @@ function zot_process_message_request($data) {
*/
$n = zot_build_packet($c[0],'notify',$env_recips,(($private) ? $hub['hubloc_sitekey'] : null),$hash,array('message_id' => $data['message_id']));
- q("insert into outq ( outq_hash, outq_account, outq_channel, outq_driver, outq_posturl, outq_async,
- outq_created, outq_updated, outq_notify, outq_msg )
- values ( '%s', %d, %d, '%s', '%s', %d, '%s', '%s', '%s', '%s' )",
- dbesc($hash),
- intval($c[0]['channel_account_id']),
- intval($c[0]['channel_id']),
- dbesc('zot'),
- dbesc($hub['hubloc_callback']),
- intval(1),
- dbesc(datetime_convert()),
- dbesc(datetime_convert()),
- dbesc($n),
- dbesc($data_packet)
- );
+
+ queue_insert(array(
+ 'hash' => $hash,
+ 'account_id' => $c[0]['channel_account_id'],
+ 'channel_id' => $c[0]['channel_id'],
+ 'posturl' => $hub['hubloc_callback'],
+ 'notify' => $n,
+ 'msg' => $data_packet
+ ));
/*
* invoke delivery to send out the notify packet
@@ -3567,8 +3560,7 @@ function zot_process_message_request($data) {
}
}
$ret['success'] = true;
-
- return $ret;
+ json_return_and_die($ret);
}
@@ -3789,6 +3781,7 @@ function zotinfo($arr) {
$ret['site'] = array();
$ret['site']['url'] = z_root();
$ret['site']['url_sig'] = base64url_encode(rsa_sign(z_root(),$e['channel_prvkey']));
+ $ret['site']['zot_auth'] = z_root() . '/magic';
$dirmode = get_config('system','directory_mode');
if(($dirmode === false) || ($dirmode == DIRECTORY_MODE_NORMAL))
@@ -3951,9 +3944,6 @@ function delivery_report_is_storable($dr) {
return false;
-
-
-
// is the recipient one of our connections, or do we want to store every report?
$r = explode(' ', $dr['recipient']);
@@ -3982,3 +3972,420 @@ function delivery_report_is_storable($dr) {
}
+
+function update_hub_connected($hub,$sitekey = '') {
+
+ if($sitekey) {
+
+ /*
+ * This hub has now been proven to be valid.
+ * Any hub with the same URL and a different sitekey cannot be valid.
+ * Get rid of them (mark them deleted). There's a good chance they were re-installs.
+ */
+
+ q("update hubloc set hubloc_deleted = 1, hubloc_error = 1 where hubloc_url = '%s' and hubloc_sitekey != '%s' ",
+ dbesc($hub['hubloc_url']),
+ dbesc($sitekey)
+ );
+
+ }
+ else {
+ $sitekey = $hub['sitekey'];
+ }
+
+ // $sender['sitekey'] is a new addition to the protcol to distinguish
+ // hublocs coming from re-installed sites. Older sites will not provide
+ // this field and we have to still mark them valid, since we can't tell
+ // if this hubloc has the same sitekey as the packet we received.
+
+
+ // Update our DB to show when we last communicated successfully with this hub
+ // This will allow us to prune dead hubs from using up resources
+
+ $r = q("update hubloc set hubloc_connected = '%s' where hubloc_id = %d and hubloc_sitekey = '%s' ",
+ dbesc(datetime_convert()),
+ intval($hub['hubloc_id']),
+ dbesc($sitekey)
+ );
+
+ // a dead hub came back to life - reset any tombstones we might have
+
+ if(intval($hub['hubloc_error'])) {
+ q("update hubloc set hubloc_error = 0 where hubloc_id = %d and hubloc_sitekey = '%s' ",
+ intval($hub['hubloc_id']),
+ dbesc($sitekey)
+ );
+ if(intval($r[0]['hubloc_orphancheck'])) {
+ q("update hubloc set hubloc_orhpancheck = 0 where hubloc_id = %d and hubloc_sitekey = '%s' ",
+ intval($hub['hubloc_id']),
+ dbesc($sitekey)
+ );
+ }
+ q("update xchan set xchan_orphan = 0 where xchan_orphan = 1 and xchan_hash = '%s'",
+ dbesc($hub['hubloc_hash'])
+ );
+ }
+
+ return $hub['hubloc_url'];
+}
+
+
+function zot_reply_ping() {
+
+ $ret = array('success'=> false);
+
+ // Useful to get a health check on a remote site.
+ // This will let us know if any important communication details
+ // that we may have stored are no longer valid, regardless of xchan details.
+ logger('POST: got ping send pong now back: ' . z_root() , LOGGER_DEBUG );
+
+ $ret['success'] = true;
+ $ret['site'] = array();
+ $ret['site']['url'] = z_root();
+ $ret['site']['url_sig'] = base64url_encode(rsa_sign(z_root(),get_config('system','prvkey')));
+ $ret['site']['sitekey'] = get_config('system','pubkey');
+ json_return_and_die($ret);
+}
+
+function zot_reply_pickup($data) {
+
+ $ret = array('success'=> false);
+
+ /*
+ * The 'pickup' message arrives with a tracking ID which is associated with a particular outq_hash
+ * First verify that that the returned signatures verify, then check that we have an outbound queue item
+ * with the correct hash.
+ * If everything verifies, find any/all outbound messages in the queue for this hubloc and send them back
+ */
+
+ if((! $data['secret']) || (! $data['secret_sig'])) {
+ $ret['message'] = 'no verification signature';
+ logger('mod_zot: pickup: ' . $ret['message'], LOGGER_DEBUG);
+ json_return_and_die($ret);
+ }
+
+ $r = q("select distinct hubloc_sitekey from hubloc where hubloc_url = '%s' and hubloc_callback = '%s' and hubloc_sitekey != '' group by hubloc_sitekey ",
+ dbesc($data['url']),
+ dbesc($data['callback'])
+ );
+ if(! $r) {
+ $ret['message'] = 'site not found';
+ logger('mod_zot: pickup: ' . $ret['message']);
+ json_return_and_die($ret);
+ }
+
+ foreach ($r as $hubsite) {
+
+ // verify the url_sig
+ // If the server was re-installed at some point, there could be multiple hubs with the same url and callback.
+ // Only one will have a valid key.
+
+ $forgery = true;
+ $secret_fail = true;
+
+ $sitekey = $hubsite['hubloc_sitekey'];
+
+ logger('mod_zot: Checking sitekey: ' . $sitekey, LOGGER_DATA);
+
+ if(rsa_verify($data['callback'],base64url_decode($data['callback_sig']),$sitekey)) {
+ $forgery = false;
+ }
+ if(rsa_verify($data['secret'],base64url_decode($data['secret_sig']),$sitekey)) {
+ $secret_fail = false;
+ }
+ if((! $forgery) && (! $secret_fail))
+ break;
+ }
+
+ if($forgery) {
+ $ret['message'] = 'possible site forgery';
+ logger('mod_zot: pickup: ' . $ret['message']);
+ json_return_and_die($ret);
+ }
+
+ if($secret_fail) {
+ $ret['message'] = 'secret validation failed';
+ logger('mod_zot: pickup: ' . $ret['message']);
+ json_return_and_die($ret);
+ }
+
+ /*
+ * If we made it to here, the signatures verify, but we still don't know if the tracking ID is valid.
+ * It wouldn't be an error if the tracking ID isn't found, because we may have sent this particular
+ * queue item with another pickup (after the tracking ID for the other pickup was verified).
+ */
+
+ $r = q("select outq_posturl from outq where outq_hash = '%s' and outq_posturl = '%s' limit 1",
+ dbesc($data['secret']),
+ dbesc($data['callback'])
+ );
+ if(! $r) {
+ $ret['message'] = 'nothing to pick up';
+ logger('mod_zot: pickup: ' . $ret['message']);
+ json_return_and_die($ret);
+ }
+
+ /*
+ * Everything is good if we made it here, so find all messages that are going to this location
+ * and send them all.
+ */
+
+ $r = q("select * from outq where outq_posturl = '%s'",
+ dbesc($data['callback'])
+ );
+ if($r) {
+ logger('mod_zot: successful pickup message received from ' . $data['callback'] . ' ' . count($r) . ' message(s) picked up', LOGGER_DEBUG);
+
+ $ret['success'] = true;
+ $ret['pickup'] = array();
+ foreach($r as $rr) {
+ if($rr['outq_msg']) {
+ $x = json_decode($rr['outq_msg'],true);
+
+ if(! $x)
+ continue;
+
+ if(is_array($x) && array_key_exists('message_list',$x)) {
+ foreach($x['message_list'] as $xx) {
+ $ret['pickup'][] = array('notify' => json_decode($rr['outq_notify'],true),'message' => $xx);
+ }
+ }
+ else
+ $ret['pickup'][] = array('notify' => json_decode($rr['outq_notify'],true),'message' => $x);
+
+ remove_queue_item($rr['outq_hash']);
+ }
+ }
+ }
+
+ $encrypted = crypto_encapsulate(json_encode($ret),$sitekey);
+ json_return_and_die($encrypted);
+
+ /* pickup: end */
+}
+
+
+
+function zot_reply_auth_check($data,$encrypted_packet) {
+
+ $ret = array('success' => false);
+
+ /*
+ * Requestor visits /magic/?dest=somewhere on their own site with a browser
+ * magic redirects them to $destsite/post [with auth args....]
+ * $destsite sends an auth_check packet to originator site
+ * The auth_check packet is handled here by the originator's site
+ * - the browser session is still waiting
+ * inside $destsite/post for everything to verify
+ * If everything checks out we'll return a token to $destsite
+ * and then $destsite will verify the token, authenticate the browser
+ * session and then redirect to the original destination.
+ * If authentication fails, the redirection to the original destination
+ * will still take place but without authentication.
+ */
+ logger('mod_zot: auth_check', LOGGER_DEBUG);
+
+ if (! $encrypted_packet) {
+ logger('mod_zot: auth_check packet was not encrypted.');
+ $ret['message'] .= 'no packet encryption' . EOL;
+ json_return_and_die($ret);
+ }
+
+ $arr = $data['sender'];
+ $sender_hash = make_xchan_hash($arr['guid'],$arr['guid_sig']);
+
+ // garbage collect any old unused notifications
+
+ // This was and should be 10 minutes but my hosting provider has time lag between the DB and
+ // the web server. We should probably convert this to webserver time rather than DB time so
+ // that the different clocks won't affect it and allow us to keep the time short.
+
+ q("delete from verify where type = 'auth' and created < %s - INTERVAL %s",
+ db_utcnow(), db_quoteinterval('30 MINUTE')
+ );
+
+ $y = q("select xchan_pubkey from xchan where xchan_hash = '%s' limit 1",
+ dbesc($sender_hash)
+ );
+
+ // We created a unique hash in mod/magic.php when we invoked remote auth, and stored it in
+ // the verify table. It is now coming back to us as 'secret' and is signed by a channel at the other end.
+ // First verify their signature. We will have obtained a zot-info packet from them as part of the sender
+ // verification.
+
+ if ((! $y) || (! rsa_verify($data['secret'], base64url_decode($data['secret_sig']),$y[0]['xchan_pubkey']))) {
+ logger('mod_zot: auth_check: sender not found or secret_sig invalid.');
+ $ret['message'] .= 'sender not found or sig invalid ' . print_r($y,true) . EOL;
+ json_return_and_die($ret);
+ }
+
+ // There should be exactly one recipient, the original auth requestor
+
+ $ret['message'] .= 'recipients ' . print_r($recipients,true) . EOL;
+
+ if ($data['recipients']) {
+
+ $arr = $data['recipients'][0];
+ $recip_hash = make_xchan_hash($arr['guid'], $arr['guid_sig']);
+ $c = q("select channel_id, channel_account_id, channel_prvkey from channel where channel_hash = '%s' limit 1",
+ dbesc($recip_hash)
+ );
+ if (! $c) {
+ logger('mod_zot: auth_check: recipient channel not found.');
+ $ret['message'] .= 'recipient not found.' . EOL;
+ json_return_and_die($ret);
+ }
+
+ $confirm = base64url_encode(rsa_sign($data['secret'] . $recip_hash,$c[0]['channel_prvkey']));
+
+ // This additionally checks for forged sites since we already stored the expected result in meta
+ // and we've already verified that this is them via zot_gethub() and that their key signed our token
+
+ $z = q("select id from verify where channel = %d and type = 'auth' and token = '%s' and meta = '%s' limit 1",
+ intval($c[0]['channel_id']),
+ dbesc($data['secret']),
+ dbesc($data['sender']['url'])
+ );
+ if (! $z) {
+ logger('mod_zot: auth_check: verification key not found.');
+ $ret['message'] .= 'verification key not found' . EOL;
+ json_return_and_die($ret);
+ }
+ $r = q("delete from verify where id = %d",
+ intval($z[0]['id'])
+ );
+
+ $u = q("select account_service_class from account where account_id = %d limit 1",
+ intval($c[0]['channel_account_id'])
+ );
+
+ logger('mod_zot: auth_check: success', LOGGER_DEBUG);
+ $ret['success'] = true;
+ $ret['confirm'] = $confirm;
+ if ($u && $u[0]['account_service_class'])
+ $ret['service_class'] = $u[0]['account_service_class'];
+
+ // Set "do not track" flag if this site or this channel's profile is restricted
+ // in some way
+
+ if (intval(get_config('system','block_public')))
+ $ret['DNT'] = true;
+ if (! perm_is_allowed($c[0]['channel_id'],'','view_profile'))
+ $ret['DNT'] = true;
+ if (get_pconfig($c[0]['channel_id'],'system','do_not_track'))
+ $ret['DNT'] = true;
+ if (get_pconfig($c[0]['channel_id'],'system','hide_online_status'))
+ $ret['DNT'] = true;
+
+ json_return_and_die($ret);
+ }
+ json_return_and_die($ret);
+}
+
+
+function zot_reply_purge($sender,$recipients) {
+
+ $ret = array('success' => false);
+
+ if ($recipients) {
+ // basically this means "unfriend"
+ foreach ($recipients as $recip) {
+ $r = q("select channel.*,xchan.* from channel
+ left join xchan on channel_hash = xchan_hash
+ where channel_guid = '%s' and channel_guid_sig = '%s' limit 1",
+ dbesc($recip['guid']),
+ dbesc($recip['guid_sig'])
+ );
+ if ($r) {
+ $r = q("select abook_id from abook where uid = %d and abook_xchan = '%s' limit 1",
+ intval($r[0]['channel_id']),
+ dbesc(make_xchan_hash($sender['guid'],$sender['guid_sig']))
+ );
+ if ($r) {
+ contact_remove($r[0]['channel_id'],$r[0]['abook_id']);
+ }
+ }
+ }
+ $ret['success'] = true;
+ }
+ else {
+ // Unfriend everybody - basically this means the channel has committed suicide
+ $arr = $sender;
+ $sender_hash = make_xchan_hash($arr['guid'],$arr['guid_sig']);
+
+ require_once('include/Contact.php');
+ remove_all_xchan_resources($sender_hash);
+
+ $ret['success'] = true;
+ }
+
+ json_return_and_die($ret);
+}
+
+
+function zot_reply_refresh($sender,$recipients) {
+
+ $ret = array('success' => false);
+
+ // remote channel info (such as permissions or photo or something)
+ // has been updated. Grab a fresh copy and sync it.
+ // The difference between refresh and force_refresh is that
+ // force_refresh unconditionally creates a directory update record,
+ // even if no changes were detected upon processing.
+
+ if($recipients) {
+
+ // This would be a permissions update, typically for one connection
+
+ foreach ($recipients as $recip) {
+ $r = q("select channel.*,xchan.* from channel
+ left join xchan on channel_hash = xchan_hash
+ where channel_guid = '%s' and channel_guid_sig = '%s' limit 1",
+ dbesc($recip['guid']),
+ dbesc($recip['guid_sig'])
+ );
+
+ $x = zot_refresh(array(
+ 'xchan_guid' => $sender['guid'],
+ 'xchan_guid_sig' => $sender['guid_sig'],
+ 'hubloc_url' => $sender['url']
+ ), $r[0], (($msgtype === 'force_refresh') ? true : false));
+ }
+ }
+ else {
+ // system wide refresh
+
+ $x = zot_refresh(array(
+ 'xchan_guid' => $sender['guid'],
+ 'xchan_guid_sig' => $sender['guid_sig'],
+ 'hubloc_url' => $sender['url']
+ ), null, (($msgtype === 'force_refresh') ? true : false));
+ }
+
+ $ret['success'] = true;
+ json_return_and_die($ret);
+
+}
+
+
+function zot_reply_notify($data) {
+
+ $ret = array('success' => false);
+
+ logger('notify received from ' . $data['sender']['url']);
+
+ $async = get_config('system','queued_fetch');
+
+ if($async) {
+ // add to receive queue
+ // qreceive_add($data);
+ }
+ else {
+ $x = zot_fetch($data);
+ $ret['delivery_report'] = $x;
+ }
+
+ $ret['success'] = true;
+ json_return_and_die($ret);
+
+} \ No newline at end of file