aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/AccessList.php148
-rw-r--r--include/Contact.php141
-rw-r--r--include/ConversationObject.php4
-rw-r--r--include/Import/Importer.php4
-rw-r--r--include/Import/import_diaspora.php5
-rw-r--r--include/Import/refimport.php11
-rw-r--r--include/ItemObject.php38
-rw-r--r--include/RedDAV/RedBrowser.php55
-rw-r--r--include/RedDAV/RedDirectory.php110
-rw-r--r--include/RedDAV/RedFile.php67
-rw-r--r--include/account.php2
-rw-r--r--include/acl_selectors.php3
-rw-r--r--include/activities.php5
-rw-r--r--include/api.php279
-rw-r--r--include/apps.php53
-rw-r--r--include/attach.php666
-rw-r--r--include/bb2diaspora.php22
-rw-r--r--include/bbcode.php171
-rw-r--r--include/chat.php2
-rw-r--r--include/checksites.php62
-rw-r--r--include/comanche.php2
-rw-r--r--include/contact_widgets.php7
-rw-r--r--include/conversation.php79
-rw-r--r--include/deliver.php54
-rw-r--r--include/deliver_hooks.php29
-rwxr-xr-xinclude/diaspora.php3036
-rw-r--r--include/dir_fns.php33
-rw-r--r--include/enotify.php37
-rw-r--r--include/event.php381
-rw-r--r--include/expire.php10
-rw-r--r--include/externals.php25
-rw-r--r--include/features.php5
-rw-r--r--include/follow.php58
-rw-r--r--include/gprobe.php3
-rw-r--r--include/group.php11
-rw-r--r--include/hubloc.php53
-rw-r--r--include/identity.php140
-rw-r--r--include/import.php871
-rwxr-xr-xinclude/importdoc.php41
-rwxr-xr-xinclude/items.php843
-rw-r--r--include/js_strings.php45
-rw-r--r--include/language.php16
-rw-r--r--include/menu.php37
-rw-r--r--include/message.php191
-rw-r--r--include/nav.php30
-rw-r--r--include/network.php91
-rw-r--r--include/notifier.php235
-rw-r--r--include/notify.php5
-rwxr-xr-xinclude/oembed.php32
-rw-r--r--include/onedirsync.php2
-rw-r--r--include/onepoll.php6
-rw-r--r--include/permissions.php94
-rw-r--r--include/photo/photo_driver.php150
-rw-r--r--include/photos.php378
-rwxr-xr-xinclude/plugin.php17
-rw-r--r--include/poller.php50
-rw-r--r--include/queue.php41
-rw-r--r--include/reddav.php52
-rw-r--r--include/security.php66
-rw-r--r--include/session.php3
-rw-r--r--include/socgraph.php44
-rw-r--r--include/statistics_fns.php9
-rw-r--r--include/taxonomy.php37
-rw-r--r--include/text.php327
-rw-r--r--include/widgets.php275
-rw-r--r--include/zot.php992
66 files changed, 5543 insertions, 5248 deletions
diff --git a/include/AccessList.php b/include/AccessList.php
new file mode 100644
index 000000000..43f1de111
--- /dev/null
+++ b/include/AccessList.php
@@ -0,0 +1,148 @@
+<?php
+
+
+class AccessList {
+
+ private $allow_cid;
+ private $allow_gid;
+ private $deny_cid;
+ private $deny_gid;
+
+ /* indicates if we are using the default constructor values or values that have been set explicitly. */
+
+ private $explicit;
+
+ function __construct($channel) {
+
+ if($channel) {
+ $this->allow_cid = $channel['channel_allow_cid'];
+ $this->allow_gid = $channel['channel_allow_gid'];
+ $this->deny_cid = $channel['channel_deny_cid'];
+ $this->deny_gid = $channel['channel_deny_gid'];
+ }
+ else {
+ $this->allow_cid = '';
+ $this->allow_gid = '';
+ $this->deny_cid = '';
+ $this->deny_gid = '';
+ }
+
+ $this->explicit = false;
+ }
+
+ function get_explicit() {
+ return $this->explicit;
+ }
+
+ /**
+ * Set AccessList from strings such as those in already
+ * existing stored data items
+ */
+
+ function set($arr,$explicit = true) {
+ $this->allow_cid = $arr['allow_cid'];
+ $this->allow_gid = $arr['allow_gid'];
+ $this->deny_cid = $arr['deny_cid'];
+ $this->deny_gid = $arr['deny_gid'];
+
+ $this->explicit = $explicit;
+ }
+
+ /**
+ * return an array consisting of the current
+ * access list components where the elements
+ * are directly storable.
+ */
+
+ function get() {
+ return array(
+ 'allow_cid' => $this->allow_cid,
+ 'allow_gid' => $this->allow_gid,
+ 'deny_cid' => $this->deny_cid,
+ 'deny_gid' => $this->deny_gid,
+ );
+ }
+
+ /**
+ * Set AccessList from arrays, such as those provided by
+ * acl_selector(). For convenience, a string (or non-array) input is
+ * assumed to be a comma-separated list and auto-converted into an array.
+ */
+
+ function set_from_array($arr,$explicit = true) {
+ $this->allow_cid = perms2str((is_array($arr['contact_allow']))
+ ? $arr['contact_allow'] : explode(',',$arr['contact_allow']));
+ $this->allow_gid = perms2str((is_array($arr['group_allow']))
+ ? $arr['group_allow'] : explode(',',$arr['group_allow']));
+ $this->deny_cid = perms2str((is_array($arr['contact_deny']))
+ ? $arr['contact_deny'] : explode(',',$arr['contact_deny']));
+ $this->deny_gid = perms2str((is_array($arr['group_deny']))
+ ? $arr['group_deny'] : explode(',',$arr['group_deny']));
+
+ $this->explicit = $explicit;
+ }
+
+ function is_private() {
+ return (($this->allow_cid || $this->allow_gid || $this->deny_cid || $this->deny_gid) ? true : false);
+ }
+
+}
+
+/**
+ * @brief Used to wrap ACL elements in angle brackets for storage.
+ *
+ * @param[in,out] array &$item
+ */
+function sanitise_acl(&$item) {
+ if (strlen($item))
+ $item = '<' . notags(trim($item)) . '>';
+ else
+ unset($item);
+}
+
+/**
+ * @brief Convert an ACL array to a storable string.
+ *
+ * @param array $p
+ * @return array
+ */
+function perms2str($p) {
+ $ret = '';
+
+ if (is_array($p))
+ $tmp = $p;
+ else
+ $tmp = explode(',', $p);
+
+ if (is_array($tmp)) {
+ array_walk($tmp, 'sanitise_acl');
+ $ret = implode('', $tmp);
+ }
+
+ return $ret;
+}
+
+
+/**
+ * @brief Turn user/group ACLs stored as angle bracketed text into arrays.
+ *
+ * turn string array of angle-bracketed elements into string array
+ * e.g. "<123xyz><246qyo><sxo33e>" => array(123xyz,246qyo,sxo33e);
+ *
+ * @param string $s
+ * @return array
+ */
+function expand_acl($s) {
+ $ret = array();
+
+ if(strlen($s)) {
+ $t = str_replace('<','',$s);
+ $a = explode('>',$t);
+ foreach($a as $aa) {
+ if($aa)
+ $ret[] = $aa;
+ }
+ }
+
+ return $ret;
+}
diff --git a/include/Contact.php b/include/Contact.php
index a27a8eca9..3bd5f9936 100644
--- a/include/Contact.php
+++ b/include/Contact.php
@@ -22,9 +22,8 @@ function rconnect_url($channel_id,$xchan) {
if(($r) && ($r[0]['xchan_follow']))
return $r[0]['xchan_follow'];
- $r = q("select hubloc_url from hubloc where hubloc_hash = '%s' and ( hubloc_flags & %d )>0 limit 1",
- dbesc($xchan),
- intval(HUBLOC_FLAGS_PRIMARY)
+ $r = q("select hubloc_url from hubloc where hubloc_hash = '%s' and hubloc_primary = 1 limit 1",
+ dbesc($xchan)
);
if($r)
@@ -35,42 +34,37 @@ function rconnect_url($channel_id,$xchan) {
function abook_connections($channel_id, $sql_conditions = '') {
$r = q("select * from abook left join xchan on abook_xchan = xchan_hash where abook_channel = %d
- and not ( abook_flags & %d )>0 $sql_conditions",
- intval($channel_id),
- intval(ABOOK_FLAG_SELF)
+ and abook_self = 0 $sql_conditions",
+ intval($channel_id)
);
return(($r) ? $r : array());
}
function abook_self($channel_id) {
$r = q("select * from abook left join xchan on abook_xchan = xchan_hash where abook_channel = %d
- and ( abook_flags & %d )>0 limit 1",
- intval($channel_id),
- intval(ABOOK_FLAG_SELF)
+ and abook_self = 1 limit 1",
+ intval($channel_id)
);
return(($r) ? $r[0] : array());
}
function channelx_by_nick($nick) {
- $r = q("SELECT * FROM channel left join xchan on channel_hash = xchan_hash WHERE channel_address = '%s' and not ( channel_pageflags & %d )>0 LIMIT 1",
- dbesc($nick),
- intval(PAGE_REMOVED)
+ $r = q("SELECT * FROM channel left join xchan on channel_hash = xchan_hash WHERE channel_address = '%s' and channel_removed = 0 LIMIT 1",
+ dbesc($nick)
);
return(($r) ? $r[0] : false);
}
function channelx_by_hash($hash) {
- $r = q("SELECT * FROM channel left join xchan on channel_hash = xchan_hash WHERE channel_hash = '%s' and not ( channel_pageflags & %d )>0 LIMIT 1",
- dbesc($hash),
- intval(PAGE_REMOVED)
+ $r = q("SELECT * FROM channel left join xchan on channel_hash = xchan_hash WHERE channel_hash = '%s' and channel_removed = 0 LIMIT 1",
+ dbesc($hash)
);
return(($r) ? $r[0] : false);
}
function channelx_by_n($id) {
- $r = q("SELECT * FROM channel left join xchan on channel_hash = xchan_hash WHERE channel_id = %d and not ( channel_pageflags & %d )>0 LIMIT 1",
- dbesc($id),
- intval(PAGE_REMOVED)
+ $r = q("SELECT * FROM channel left join xchan on channel_hash = xchan_hash WHERE channel_id = %d and channel_removed = 0 LIMIT 1",
+ dbesc($id)
);
return(($r) ? $r[0] : false);
}
@@ -129,9 +123,40 @@ function vcard_from_xchan($xchan, $observer = null, $mode = '') {
function abook_toggle_flag($abook,$flag) {
- $r = q("UPDATE abook set abook_flags = (abook_flags %s %d) where abook_id = %d and abook_channel = %d",
- db_getfunc('^'),
- intval($flag),
+ $field = '';
+
+ switch($flag) {
+ case ABOOK_FLAG_BLOCKED:
+ $field = 'abook_blocked';
+ break;
+ case ABOOK_FLAG_IGNORED:
+ $field = 'abook_ignored';
+ break;
+ case ABOOK_FLAG_HIDDEN:
+ $field = 'abook_hidden';
+ break;
+ case ABOOK_FLAG_ARCHIVED:
+ $field = 'abook_archived';
+ break;
+ case ABOOK_FLAG_PENDING:
+ $field = 'abook_pending';
+ break;
+ case ABOOK_FLAG_UNCONNECTED:
+ $field = 'abook_unconnected';
+ break;
+ case ABOOK_FLAG_SELF:
+ $field = 'abook_self';
+ break;
+ case ABOOK_FLAG_FEED:
+ $field = 'abook_feed';
+ break;
+ default:
+ break;
+ }
+ if(! $field)
+ return;
+
+ $r = q("UPDATE abook set $field = (1 - $field) where abook_id = %d and abook_channel = %d",
intval($abook['abook_id']),
intval($abook['abook_channel'])
);
@@ -139,7 +164,7 @@ function abook_toggle_flag($abook,$flag) {
// if unsetting the archive bit, update the timestamps so we'll try to connect for an additional 30 days.
- if(($flag === ABOOK_FLAG_ARCHIVED) && ($abook['abook_flags'] & ABOOK_FLAG_ARCHIVED)) {
+ if(($flag === ABOOK_FLAG_ARCHIVED) && (intval($abook['abook_archived']))) {
$r = q("update abook set abook_connected = '%s', abook_updated = '%s'
where abook_id = %d and abook_channel = %d",
dbesc(datetime_convert()),
@@ -258,25 +283,23 @@ function channel_remove($channel_id, $local = true, $unset_session=true) {
if(! $local) {
- $r = q("update channel set channel_deleted = '%s', channel_pageflags = (channel_pageflags | %d), channel_r_stream = 0, channel_r_profile = 0,
+ $r = q("update channel set channel_deleted = '%s', channel_removed = 1, channel_r_stream = 0, channel_r_profile = 0,
channel_r_photos = 0, channel_r_abook = 0, channel_w_stream = 0, channel_w_wall = 0, channel_w_tagwall = 0,
channel_w_comment = 0, channel_w_mail = 0, channel_w_photos = 0, channel_w_chat = 0, channel_a_delegate = 0,
channel_r_storage = 0, channel_w_storage = 0, channel_r_pages = 0, channel_w_pages = 0, channel_a_republish = 0
where channel_id = %d",
dbesc(datetime_convert()),
- intval(PAGE_REMOVED),
intval($channel_id)
);
-
- $r = q("update hubloc set hubloc_flags = (hubloc_flags | %d) where hubloc_hash = '%s'",
- intval(HUBLOC_FLAGS_DELETED),
+ logger('deleting hublocs',LOGGER_DEBUG);
+
+ $r = q("update hubloc set hubloc_deleted = 1 where hubloc_hash = '%s'",
dbesc($channel['channel_hash'])
);
- $r = q("update xchan set xchan_flags = (xchan_flags | %d) where xchan_hash = '%s'",
- intval(XCHAN_FLAGS_DELETED),
+ $r = q("update xchan set xchan_deleted = 1 where xchan_hash = '%s'",
dbesc($channel['channel_hash'])
);
@@ -297,20 +320,20 @@ function channel_remove($channel_id, $local = true, $unset_session=true) {
q("DELETE FROM `pconfig` WHERE `uid` = %d", intval($channel_id));
q("DELETE FROM `spam` WHERE `uid` = %d", intval($channel_id));
+ // @FIXME At this stage we need to remove the file resources located under /store/$nickname
- q("delete from abook where abook_xchan = '%s' and (abook_flags & %d)>0",
- dbesc($channel['channel_hash']),
- dbesc(ABOOK_FLAG_SELF)
+
+ q("delete from abook where abook_xchan = '%s' and abook_self = 1 ",
+ dbesc($channel['channel_hash'])
);
- $r = q("update channel set channel_deleted = '%s', channel_pageflags = (channel_pageflags | %d) where channel_id = %d",
+ $r = q("update channel set channel_deleted = '%s', channel_removed = 1 where channel_id = %d",
dbesc(datetime_convert()),
- intval(PAGE_REMOVED),
intval($channel_id)
);
// if this was the default channel, set another one as default
if($a->account['account_default_channel'] == $channel_id) {
- $r = q("select channel_id from channel where channel_account_id = %d and not ( channel_pageflags & %d)>0 limit 1",
+ $r = q("select channel_id from channel where channel_account_id = %d and channel_removed = 0 limit 1",
intval($a->account['account_id']),
intval(PAGE_REMOVED));
if ($r) {
@@ -327,8 +350,9 @@ function channel_remove($channel_id, $local = true, $unset_session=true) {
}
- $r = q("update hubloc set hubloc_flags = (hubloc_flags | %d) where hubloc_hash = '%s' and hubloc_url = '%s' ",
- intval(HUBLOC_FLAGS_DELETED),
+ logger('deleting hublocs',LOGGER_DEBUG);
+
+ $r = q("update hubloc set hubloc_deleted = 1 where hubloc_hash = '%s' and hubloc_url = '%s' ",
dbesc($channel['channel_hash']),
dbesc(z_root())
);
@@ -337,16 +361,14 @@ function channel_remove($channel_id, $local = true, $unset_session=true) {
$hublocs = 0;
- $r = q("select hubloc_id from hubloc where hubloc_hash = '%s' and not (hubloc_flags & %d)>0",
- dbesc($channel['channel_hash']),
- intval(HUBLOC_FLAGS_DELETED)
+ $r = q("select hubloc_id from hubloc where hubloc_hash = '%s' and hubloc_deleted = 0",
+ dbesc($channel['channel_hash'])
);
if($r)
$hublocs = count($r);
if(! $hublocs) {
- $r = q("update xchan set xchan_flags = (xchan_flags | %d) where xchan_hash = '%s' ",
- intval(XCHAN_FLAGS_DELETED),
+ $r = q("update xchan set xchan_deleted = 1 where xchan_hash = '%s' ",
dbesc($channel['channel_hash'])
);
}
@@ -389,10 +411,8 @@ function mark_orphan_hubsxchans() {
if($dirmode == DIRECTORY_MODE_NORMAL)
return;
- $r = q("update hubloc set hubloc_status = (hubloc_status | %d) where (hubloc_status & %d) = 0
+ $r = q("update hubloc set hubloc_error = 1 where hubloc_error = 0
and hubloc_network = 'zot' and hubloc_connected < %s - interval %s",
- intval(HUBLOC_OFFLINE),
- intval(HUBLOC_OFFLINE),
db_utcnow(), db_quoteinterval('36 day')
);
@@ -409,27 +429,21 @@ function mark_orphan_hubsxchans() {
// }
- $r = q("select hubloc_id, hubloc_hash from hubloc where (hubloc_status & %d)>0 and not (hubloc_flags & %d)>0",
- intval(HUBLOC_OFFLINE),
- intval(HUBLOC_FLAGS_ORPHANCHECK)
- );
+ $r = q("select hubloc_id, hubloc_hash from hubloc where hubloc_error = 0 and hubloc_orphancheck = 0");
if($r) {
foreach($r as $rr) {
// see if any other hublocs are still alive for this channel
- $x = q("select * from hubloc where hubloc_hash = '%s' and not (hubloc_status & %d)>0",
- dbesc($rr['hubloc_hash']),
- intval(HUBLOC_OFFLINE)
+ $x = q("select * from hubloc where hubloc_hash = '%s' and hubloc_error = 0",
+ dbesc($rr['hubloc_hash'])
);
if($x) {
// yes - if the xchan was marked as an orphan, undo it
- $y = q("update xchan set xchan_flags = (xchan_flags & ~%d) where (xchan_flags & %d)>0 and xchan_hash = '%s'",
- intval(XCHAN_FLAGS_ORPHAN),
- intval(XCHAN_FLAGS_ORPHAN),
+ $y = q("update xchan set xchan_orphan = 0 where xchan_orphan = 1 and xchan_hash = '%s'",
dbesc($rr['hubloc_hash'])
);
@@ -438,16 +452,14 @@ function mark_orphan_hubsxchans() {
// nope - mark the xchan as an orphan
- $y = q("update xchan set xchan_flags = (xchan_flags | %d) where xchan_hash = '%s'",
- intval(XCHAN_FLAGS_ORPHAN),
+ $y = q("update xchan set xchan_orphan = 1 where xchan_hash = '%s'",
dbesc($rr['hubloc_hash'])
);
}
// mark that we've checked this entry so we don't need to do it again
- $y = q("update hubloc set hubloc_flags = (hubloc_flags | %d) where hubloc_id = %d",
- intval(HUBLOC_FLAGS_ORPHANCHECK),
+ $y = q("update hubloc set hubloc_orphancheck = 1 where hubloc_id = %d",
dbesc($rr['hubloc_id'])
);
}
@@ -516,13 +528,11 @@ function remove_all_xchan_resources($xchan, $channel_id = 0) {
// directory servers need to keep the record around for sync purposes - mark it deleted
- $r = q("update hubloc set hubloc_flags = (hubloc_flags | %d) where hubloc_hash = '%s'",
- intval(HUBLOC_FLAGS_DELETED),
+ $r = q("update hubloc set hubloc_deleted = 1 where hubloc_hash = '%s'",
dbesc($xchan)
);
- $r = q("update xchan set xchan_flags = (xchan_flags | %d) where xchan_hash = '%s'",
- intval(XCHAN_FLAGS_DELETED),
+ $r = q("update xchan set xchan_deleted = 1 where xchan_hash = '%s'",
dbesc($xchan)
);
}
@@ -539,8 +549,7 @@ function contact_remove($channel_id, $abook_id) {
$archive = get_pconfig($channel_id, 'system','archive_removed_contacts');
if($archive) {
- q("update abook set abook_flags = ( abook_flags | %d ) where abook_id = %d and abook_channel = %d",
- intval(ABOOK_FLAG_ARCHIVED),
+ q("update abook set abook_archived = 1 where abook_id = %d and abook_channel = %d",
intval($abook_id),
intval($channel_id)
);
@@ -557,7 +566,7 @@ function contact_remove($channel_id, $abook_id) {
$abook = $r[0];
- if($abook['abook_flags'] & ABOOK_FLAG_SELF)
+ if(intval($abook['abook_self']))
return false;
diff --git a/include/ConversationObject.php b/include/ConversationObject.php
index af0bb8d2c..7e0d67c10 100644
--- a/include/ConversationObject.php
+++ b/include/ConversationObject.php
@@ -166,11 +166,11 @@ class Conversation extends BaseObject {
if(($item->get_data_value('author_xchan') === $ob_hash) || ($item->get_data_value('owner_xchan') === $ob_hash))
$item->set_commentable(true);
- if($item->get_data_value('item_flags') & ITEM_NOCOMMENT) {
+ if(intval($item->get_data_value('item_nocomment'))) {
$item->set_commentable(false);
}
elseif(($this->observer) && (! $item->is_commentable())) {
- if((array_key_exists('owner',$item->data)) && ($item->data['owner']['abook_flags'] & ABOOK_FLAG_SELF))
+ if((array_key_exists('owner',$item->data)) && intval($item->data['owner']['abook_self']))
$item->set_commentable(perm_is_allowed($this->profile_owner,$this->observer['xchan_hash'],'post_comments'));
else
$item->set_commentable(can_comment_on_post($this->observer['xchan_hash'],$item->data));
diff --git a/include/Import/Importer.php b/include/Import/Importer.php
index 5e684cd8e..cddfac7b5 100644
--- a/include/Import/Importer.php
+++ b/include/Import/Importer.php
@@ -1,11 +1,11 @@
<?php /** @file */
-namespace RedMatrix\Import;
+namespace Hubzilla\Import;
/**
* @brief Class Import
*
- * @package RedMatrix\Import
+ * @package Hubzilla\Import
*/
class Import {
diff --git a/include/Import/import_diaspora.php b/include/Import/import_diaspora.php
index fca9fa4f2..a0f473b50 100644
--- a/include/Import/import_diaspora.php
+++ b/include/Import/import_diaspora.php
@@ -57,6 +57,10 @@ function import_diaspora($data) {
$channel_id = $c['channel']['channel_id'];
+ // Hubzilla only: Turn on the Diaspora protocol so that follow requests will be sent.
+
+ set_pconfig($channel_id,'system','diaspora_allowed','1');
+
// todo - add auto follow settings, (and strip exif in hubzilla)
$location = escape_tags($data['user']['profile']['location']);
@@ -70,7 +74,6 @@ function import_diaspora($data) {
);
if($data['user']['profile']['nsfw']) {
- // fixme for hubzilla which doesn't use pageflags any more
q("update channel set channel_pageflags = (channel_pageflags | %d) where channel_id = %d",
intval(PAGE_ADULT),
intval($channel_id)
diff --git a/include/Import/refimport.php b/include/Import/refimport.php
index b9b6bf639..3ef8870ac 100644
--- a/include/Import/refimport.php
+++ b/include/Import/refimport.php
@@ -88,7 +88,11 @@ function refimport_content(&$a) {
$arr['author_xchan'] = $channel['channel_hash'];
$arr['owner_xchan'] = $channel['channel_hash'];
$arr['app'] = REFLECT_BLOGNAME;
- $arr['item_flags'] = ITEM_ORIGIN|ITEM_WALL|ITEM_THREAD_TOP;
+
+ $arr['item_origin'] = 1;
+ $arr['item_wall'] = 1;
+ $arr['item_thread_top'] = 1;
+
$arr['verb'] = ACTIVITY_POST;
// this is an assumption
@@ -205,7 +209,7 @@ function reflect_find_user($users,$name) {
function reflect_comment_store($channel,$post,$comment,$user) {
- // if the commenter was the channel owner, use their redmatrix xchan
+ // if the commenter was the channel owner, use their hubzilla xchan
if($comment['author'] === REFLECT_EXPORTUSERNAME && $comment['registered'])
$hash = $channel['xchan_hash'];
@@ -256,7 +260,8 @@ function reflect_comment_store($channel,$post,$comment,$user) {
$arr['edited'] = $comment['created'];
$arr['author_xchan'] = $hash;
$arr['owner_xchan'] = $channel['channel_hash'];
- $arr['item_flags'] = ITEM_ORIGIN|ITEM_WALL;
+ $arr['item_origin'] = 1;
+ $arr['item_wall'] = 1;
$arr['verb'] = ACTIVITY_POST;
$arr['comment_policy'] = 'contacts';
diff --git a/include/ItemObject.php b/include/ItemObject.php
index dea2f75bf..34500efb9 100644
--- a/include/ItemObject.php
+++ b/include/ItemObject.php
@@ -152,7 +152,7 @@ class Item extends BaseObject {
}
}
- $consensus = (($item['item_flags'] & ITEM_CONSENSUS) ? true : false);
+ $consensus = (intval($item['item_consensus']) ? true : false);
if($consensus) {
$response_verbs[] = 'agree';
$response_verbs[] = 'disagree';
@@ -212,9 +212,9 @@ class Item extends BaseObject {
'do' => t("Add Star"),
'undo' => t("Remove Star"),
'toggle' => t("Toggle Star Status"),
- 'classdo' => (($item['item_flags'] & ITEM_STARRED) ? "hidden" : ""),
- 'classundo' => (($item['item_flags'] & ITEM_STARRED) ? "" : "hidden"),
- 'isstarred' => (($item['item_flags'] & ITEM_STARRED) ? "starred icon-star" : "unstarred icon-star-empty"),
+ 'classdo' => (intval($item['item_starred']) ? "hidden" : ""),
+ 'classundo' => (intval($item['item_starred']) ? "" : "hidden"),
+ 'isstarred' => (intval($item['item_starred']) ? "starred icon-star" : "unstarred icon-star-empty"),
'starred' => t('starred'),
);
@@ -224,9 +224,9 @@ class Item extends BaseObject {
}
- $verified = (($item['item_flags'] & ITEM_VERIFIED) ? t('Message signature validated') : '');
- $forged = ((($item['sig']) && (! ($item['item_flags'] & ITEM_VERIFIED))) ? t('Message signature incorrect') : '');
- $unverified = '' ; // (($this->is_wall_to_wall() && (! ($item['item_flags'] & ITEM_VERIFIED))) ? t('Message cannot be verified') : '');
+ $verified = (intval($item['item_verified']) ? t('Message signature validated') : '');
+ $forged = ((($item['sig']) && (! intval($item['item_verified']))) ? t('Message signature incorrect') : '');
+ $unverified = '' ; // (($this->is_wall_to_wall() && (! intval($item['item_verified']))) ? t('Message cannot be verified') : '');
@@ -279,14 +279,21 @@ class Item extends BaseObject {
$children = $this->get_children();
+ $has_tags = (($body['tags'] || $body['categories'] || $body['mentions'] || $body['attachments'] || $body['folders']) ? true : false);
+
$tmp_item = array(
'template' => $this->get_template(),
'mode' => $mode,
'type' => implode("",array_slice(explode("/",$item['verb']),-1)),
- 'tags' => array(),
- 'body' => $body,
- 'text' => strip_tags($body),
+ 'body' => $body['html'],
+ 'tags' => $body['tags'],
+ 'categories' => $body['categories'],
+ 'mentions' => $body['mentions'],
+ 'attachments' => $body['attachments'],
+ 'folders' => $body['folders'],
+ 'text' => strip_tags($body['html']),
'id' => $this->get_id(),
+ 'mid' => $item['mid'],
'isevent' => $isevent,
'attend' => $attend,
'consensus' => $consensus,
@@ -302,6 +309,7 @@ class Item extends BaseObject {
'vwall' => t('via Wall-To-Wall:'),
'profile_url' => $profile_link,
'item_photo_menu' => item_photo_menu($item),
+ 'dreport' => t('Delivery Report'),
'name' => $profile_name,
'thumb' => $profile_avatar,
'osparkle' => $osparkle,
@@ -324,6 +332,8 @@ class Item extends BaseObject {
'owner_url' => $this->get_owner_url(),
'owner_photo' => $this->get_owner_photo(),
'owner_name' => $this->get_owner_name(),
+ 'photo' => $body['photo'],
+ 'has_tags' => $has_tags,
// Item toolbar buttons
'like' => $like,
@@ -374,12 +384,16 @@ class Item extends BaseObject {
$result['children'] = array();
$nb_children = count($children);
+ $visible_comments = get_config('system','expanded_comments');
+ if($visible_comments === false)
+ $visible_comments = 3;
+
if(($this->get_display_mode() === 'normal') && ($nb_children > 0)) {
foreach($children as $child) {
$result['children'][] = $child->get_template_data($conv_responses, $thread_level + 1);
}
// Collapse
- if(($nb_children > 2) || ($thread_level > 1)) {
+ if(($nb_children > $visible_comments) || ($thread_level > 1)) {
$result['children'][0]['comment_firstcollapsed'] = true;
$result['children'][0]['num_comments'] = $comment_count_txt;
$result['children'][0]['hide_text'] = t('[+] show all');
@@ -387,7 +401,7 @@ class Item extends BaseObject {
$result['children'][$nb_children - 1]['comment_lastcollapsed'] = true;
}
else {
- $result['children'][$nb_children - 3]['comment_lastcollapsed'] = true;
+ $result['children'][$nb_children - ($visible_comments + 1)]['comment_lastcollapsed'] = true;
}
}
}
diff --git a/include/RedDAV/RedBrowser.php b/include/RedDAV/RedBrowser.php
index d74bba220..efea5d92f 100644
--- a/include/RedDAV/RedBrowser.php
+++ b/include/RedDAV/RedBrowser.php
@@ -217,31 +217,6 @@ class RedBrowser extends DAV\Browser\Plugin {
$f[] = $ft;
}
- // Storage and quota for the account (all channels of the owner of this directory)!
- $limit = service_class_fetch($owner, 'attach_upload_limit');
- $r = q("SELECT SUM(filesize) AS total FROM attach WHERE aid = %d",
- intval($this->auth->channel_account_id)
- );
- $used = $r[0]['total'];
- if ($used) {
- $quotaDesc = t('%1$s used');
- $quotaDesc = sprintf($quotaDesc,
- userReadableSize($used));
- }
- if ($limit && $used) {
- $quotaDesc = t('%1$s used of %2$s (%3$s&#37;)');
- $quotaDesc = sprintf($quotaDesc,
- userReadableSize($used),
- userReadableSize($limit),
- round($used / $limit, 1));
- }
-
- // prepare quota for template
- $quota = array();
- $quota['used'] = $used;
- $quota['limit'] = $limit;
- $quota['desc'] = $quotaDesc;
-
$output = '';
if ($this->enablePost) {
$this->server->broadcastEvent('onHTMLActionsPanel', array($parent, &$output));
@@ -249,7 +224,6 @@ class RedBrowser extends DAV\Browser\Plugin {
$html .= replace_macros(get_markup_template('cloud.tpl'), array(
'$header' => t('Files') . ": " . $this->escapeHTML($path) . "/",
- '$quota' => $quota,
'$total' => t('Total'),
'$actionspanel' => $output,
'$shared' => t('Shared'),
@@ -298,11 +272,38 @@ class RedBrowser extends DAV\Browser\Plugin {
if (get_class($node) === 'Sabre\\DAV\\SimpleCollection')
return;
+ // Storage and quota for the account (all channels of the owner of this directory)!
+ $limit = service_class_fetch($owner, 'attach_upload_limit');
+ $r = q("SELECT SUM(filesize) AS total FROM attach WHERE aid = %d",
+ intval($this->auth->channel_account_id)
+ );
+ $used = $r[0]['total'];
+ if ($used) {
+ $quotaDesc = t('You are using %1$s of your available file storage.');
+ $quotaDesc = sprintf($quotaDesc,
+ userReadableSize($used));
+ }
+ if ($limit && $used) {
+ $quotaDesc = t('You are using %1$s of %2$s available file storage. (%3$s&#37;)');
+ $quotaDesc = sprintf($quotaDesc,
+ userReadableSize($used),
+ userReadableSize($limit),
+ round($used / $limit, 1) * 100);
+ }
+
+ // prepare quota for template
+ $quota = array();
+ $quota['used'] = $used;
+ $quota['limit'] = $limit;
+ $quota['desc'] = $quotaDesc;
+ $quota['warning'] = ((($limit) && ((round($used / $limit, 1) * 100) >= 90)) ? t('WARNING:') : ''); // 10485760 bytes = 100MB
+
$output .= replace_macros(get_markup_template('cloud_actionspanel.tpl'), array(
'$folder_header' => t('Create new folder'),
'$folder_submit' => t('Create'),
'$upload_header' => t('Upload file'),
- '$upload_submit' => t('Upload')
+ '$upload_submit' => t('Upload'),
+ '$quota' => $quota
));
}
diff --git a/include/RedDAV/RedDirectory.php b/include/RedDAV/RedDirectory.php
index 922be378d..507fde46f 100644
--- a/include/RedDAV/RedDirectory.php
+++ b/include/RedDAV/RedDirectory.php
@@ -50,7 +50,7 @@ class RedDirectory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
*/
public function __construct($ext_path, &$auth_plugin) {
// $ext_path = urldecode($ext_path);
- //logger('directory ' . $ext_path, LOGGER_DATA);
+ logger('directory ' . $ext_path, LOGGER_DATA);
$this->ext_path = $ext_path;
// remove "/cloud" from the beginning of the path
$modulename = get_app()->module;
@@ -80,7 +80,7 @@ class RedDirectory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
* @return array \Sabre\DAV\INode[]
*/
public function getChildren() {
- //logger('children for ' . $this->ext_path, LOGGER_DATA);
+ logger('children for ' . $this->ext_path, LOGGER_DATA);
$this->log();
if (get_config('system', 'block_public') && (! $this->auth->channel_id) && (! $this->auth->observer)) {
@@ -200,9 +200,8 @@ class RedDirectory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
$mimetype = z_mime_content_type($name);
- $c = q("SELECT * FROM channel WHERE channel_id = %d AND NOT (channel_pageflags & %d)>0 LIMIT 1",
- intval($this->auth->owner_id),
- intval(PAGE_REMOVED)
+ $c = q("SELECT * FROM channel WHERE channel_id = %d AND channel_removed = 0 LIMIT 1",
+ intval($this->auth->owner_id)
);
if (! $c) {
@@ -213,28 +212,55 @@ class RedDirectory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
$filesize = 0;
$hash = random_string();
- $r = q("INSERT INTO attach ( aid, uid, hash, creator, filename, folder, flags, filetype, filesize, revision, data, created, edited, allow_cid, allow_gid, deny_cid, deny_gid )
- VALUES ( %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s' ) ",
+ $f = 'store/' . $this->auth->owner_nick . '/' . (($this->os_path) ? $this->os_path . '/' : '') . $hash;
+
+ $direct = null;
+
+ if($this->folder_hash) {
+ $r = q("select * from attach where hash = '%s' and is_dir = 1 and uid = %d limit 1",
+ dbesc($this->folder_hash),
+ intval($c[0]['channel_id'])
+ );
+ if($r)
+ $direct = $r[0];
+ }
+
+ if(($direct) && (($direct['allow_cid']) || ($direct['allow_gid']) || ($direct['deny_cid']) || ($direct['deny_gid']))) {
+ $allow_cid = $direct['allow_cid'];
+ $allow_gid = $direct['allow_gid'];
+ $deny_cid = $direct['deny_cid'];
+ $deny_gid = $direct['deny_gid'];
+ }
+ else {
+ $allow_cid = $c[0]['channel_allow_cid'];
+ $allow_gid = $c[0]['channel_allow_gid'];
+ $deny_cid = $c[0]['channel_deny_cid'];
+ $deny_gid = $c[0]['channel_deny_gid'];
+ }
+
+ $r = q("INSERT INTO attach ( aid, uid, hash, creator, filename, folder, os_storage, filetype, filesize, revision, is_photo, data, created, edited, allow_cid, allow_gid, deny_cid, deny_gid )
+ VALUES ( %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s' ) ",
intval($c[0]['channel_account_id']),
intval($c[0]['channel_id']),
dbesc($hash),
dbesc($this->auth->observer),
dbesc($name),
dbesc($this->folder_hash),
- dbesc(ATTACH_FLAG_OS),
+ intval(1),
dbesc($mimetype),
intval($filesize),
intval(0),
+ intval($is_photo),
dbesc($this->os_path . '/' . $hash),
dbesc(datetime_convert()),
dbesc(datetime_convert()),
- dbesc($c[0]['channel_allow_cid']),
- dbesc($c[0]['channel_allow_gid']),
- dbesc($c[0]['channel_deny_cid']),
- dbesc($c[0]['channel_deny_gid'])
+ dbesc($allow_cid),
+ dbesc($allow_gid),
+ dbesc($deny_cid),
+ dbesc($deny_gid)
);
- $f = 'store/' . $this->auth->owner_nick . '/' . (($this->os_path) ? $this->os_path . '/' : '') . $hash;
+
// returns the number of bytes that were written to the file, or FALSE on failure
$size = file_put_contents($f, $data);
@@ -248,9 +274,20 @@ class RedDirectory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
// returns now
$edited = datetime_convert();
+
+
+ $is_photo = 0;
+ $x = @getimagesize($f);
+ logger('getimagesize: ' . print_r($x,true), LOGGER_DATA);
+ if(($x) && ($x[2] === IMAGETYPE_GIF || $x[2] === IMAGETYPE_JPEG || $x[2] === IMAGETYPE_PNG)) {
+ $is_photo = 1;
+ }
+
+
// updates entry with filesize and timestamp
- $d = q("UPDATE attach SET filesize = '%s', edited = '%s' WHERE hash = '%s' AND uid = %d",
+ $d = q("UPDATE attach SET filesize = '%s', is_photo = %d, edited = '%s' WHERE hash = '%s' AND uid = %d",
dbesc($size),
+ intval($is_photo),
dbesc($edited),
dbesc($hash),
intval($c[0]['channel_id'])
@@ -281,6 +318,23 @@ class RedDirectory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
return;
}
}
+
+ if($is_photo) {
+ $album = '';
+ if($this->folder_hash) {
+ $f1 = q("select filename from attach WHERE hash = '%s' AND uid = %d",
+ dbesc($this->folder_hash),
+ intval($c[0]['channel_id'])
+ );
+ if($f1)
+ $album = $f1[0]['filename'];
+ }
+
+ require_once('include/photos.php');
+ $args = array( 'resource_id' => $hash, 'album' => $album, 'os_path' => $f, 'filename' => $name, 'getimagesize' => $x, 'directory' => $direct);
+ $p = photo_upload($c[0],get_app()->get_observer(),$args);
+ }
+
}
/**
@@ -296,9 +350,8 @@ class RedDirectory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
throw new DAV\Exception\Forbidden('Permission denied.');
}
- $r = q("SELECT * FROM channel WHERE channel_id = %d AND NOT (channel_pageflags & %d)>0 LIMIT 1",
- intval($this->auth->owner_id),
- intval(PAGE_REMOVED)
+ $r = q("SELECT * FROM channel WHERE channel_id = %d AND channel_removed = 0 LIMIT 1",
+ intval($this->auth->owner_id)
);
if ($r) {
@@ -340,15 +393,14 @@ class RedDirectory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
* @return void
*/
function getDir() {
- //logger($this->ext_path, LOGGER_DEBUG);
+
+ logger('GetDir: ' . $this->ext_path, LOGGER_DEBUG);
$this->auth->log();
$modulename = get_app()->module;
$file = $this->ext_path;
$x = strpos($file, '/' . $modulename);
- if ($x === false)
- return;
if ($x === 0) {
$file = substr($file, strlen($modulename) + 1);
}
@@ -367,9 +419,8 @@ class RedDirectory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
$channel_name = $path_arr[0];
- $r = q("SELECT channel_id FROM channel WHERE channel_address = '%s' AND NOT ( channel_pageflags & %d )>0 LIMIT 1",
- dbesc($channel_name),
- intval(PAGE_REMOVED)
+ $r = q("SELECT channel_id FROM channel WHERE channel_address = '%s' AND channel_removed = 0 LIMIT 1",
+ dbesc($channel_name)
);
if (! $r) {
@@ -385,14 +436,12 @@ class RedDirectory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
$os_path = '';
for ($x = 1; $x < count($path_arr); $x++) {
- $r = q("select id, hash, filename, flags from attach where folder = '%s' and filename = '%s' and uid = %d and (flags & %d)>0",
+ $r = q("select id, hash, filename, flags, is_dir from attach where folder = '%s' and filename = '%s' and uid = %d and is_dir != 0",
dbesc($folder),
dbesc($path_arr[$x]),
- intval($channel_id),
- intval(ATTACH_FLAG_DIR)
+ intval($channel_id)
);
-
- if ($r && ( $r[0]['flags'] & ATTACH_FLAG_DIR)) {
+ if ($r && intval($r[0]['is_dir'])) {
$folder = $r[0]['hash'];
if (strlen($os_path))
$os_path .= '/';
@@ -445,9 +494,8 @@ class RedDirectory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
$free = disk_free_space('store');
if ($this->auth->owner_id) {
- $c = q("select * from channel where channel_id = %d and not (channel_pageflags & %d)>0 limit 1",
- intval($this->auth->owner_id),
- intval(PAGE_REMOVED)
+ $c = q("select * from channel where channel_id = %d and channel_removed = 0 limit 1",
+ intval($this->auth->owner_id)
);
$ulimit = service_class_fetch($c[0]['channel_id'], 'attach_upload_limit');
diff --git a/include/RedDAV/RedFile.php b/include/RedDAV/RedFile.php
index b7aa5473a..ec6871a69 100644
--- a/include/RedDAV/RedFile.php
+++ b/include/RedDAV/RedFile.php
@@ -49,7 +49,7 @@ class RedFile extends DAV\Node implements DAV\IFile {
$this->data = $data;
$this->auth = $auth;
- //logger(print_r($this->data, true), LOGGER_DATA);
+ logger(print_r($this->data, true), LOGGER_DATA);
}
/**
@@ -97,24 +97,49 @@ class RedFile extends DAV\Node implements DAV\IFile {
$size = 0;
// @todo only 3 values are needed
- $c = q("SELECT * FROM channel WHERE channel_id = %d AND (channel_pageflags & %d) = 0 LIMIT 1",
- intval($this->auth->owner_id),
- intval(PAGE_REMOVED)
+ $c = q("SELECT * FROM channel WHERE channel_id = %d AND channel_removed = 0 LIMIT 1",
+ intval($this->auth->owner_id)
);
- $r = q("SELECT flags, folder, data FROM attach WHERE hash = '%s' AND uid = %d LIMIT 1",
+ $is_photo = false;
+ $album = '';
+
+ $r = q("SELECT flags, folder, os_storage, filename, is_photo FROM attach WHERE hash = '%s' AND uid = %d LIMIT 1",
dbesc($this->data['hash']),
intval($c[0]['channel_id'])
);
if ($r) {
- if ($r[0]['flags'] & ATTACH_FLAG_OS) {
- $fname = dbunescbin($r[0]['data']);
- $f = 'store/' . $this->auth->owner_nick . '/' . (($fname) ? $fname : '');
- // @todo check return value and set $size directly
- @file_put_contents($f, $data);
- $size = @filesize($f);
- logger('filename: ' . $f . ' size: ' . $size, LOGGER_DEBUG);
- } else {
+ if (intval($r[0]['os_storage'])) {
+ $d = q("select folder, data from attach where hash = '%s' and uid = %d limit 1",
+ dbesc($this->data['hash']),
+ intval($c[0]['channel_id'])
+ );
+ if($d) {
+ if($d[0]['folder']) {
+ $f1 = q("select * from attach where is_dir = 1 and hash = '%s' and uid = %d limit 1",
+ dbesc($d[0]['folder']),
+ intval($c[0]['channel_id'])
+ );
+ if($f1) {
+ $album = $f1[0]['filename'];
+ $direct = $f1[0];
+ }
+ }
+ $fname = dbunescbin($d[0]['data']);
+ $f = 'store/' . $this->auth->owner_nick . '/' . (($fname) ? $fname : '');
+ // @todo check return value and set $size directly
+ @file_put_contents($f, $data);
+ $size = @filesize($f);
+ logger('filename: ' . $f . ' size: ' . $size, LOGGER_DEBUG);
+ }
+ $gis = @getimagesize($f);
+ logger('getimagesize: ' . print_r($gis,true), LOGGER_DATA);
+ if(($gis) && ($gis[2] === IMAGETYPE_GIF || $gis[2] === IMAGETYPE_JPEG || $gis[2] === IMAGETYPE_PNG)) {
+ $is_photo = 1;
+ }
+ }
+ else {
+ // this shouldn't happen any more
$r = q("UPDATE attach SET data = '%s' WHERE hash = '%s' AND uid = %d",
dbescbin(stream_get_contents($data)),
dbesc($this->data['hash']),
@@ -133,13 +158,20 @@ class RedFile extends DAV\Node implements DAV\IFile {
// returns now()
$edited = datetime_convert();
- $d = q("UPDATE attach SET filesize = '%s', edited = '%s' WHERE hash = '%s' AND uid = %d",
+ $d = q("UPDATE attach SET filesize = '%s', is_photo = %d, edited = '%s' WHERE hash = '%s' AND uid = %d",
dbesc($size),
+ intval($is_photo),
dbesc($edited),
dbesc($this->data['hash']),
intval($c[0]['channel_id'])
);
+ if($is_photo) {
+ require_once('include/photos.php');
+ $args = array( 'resource_id' => $this->data['hash'], 'album' => $album, 'os_path' => $f, 'filename' => $r[0]['filename'], 'getimagesize' => $gis, 'directory' => $direct );
+ $p = photo_upload($c[0],get_app()->get_observer(),$args);
+ }
+
// update the folder's lastmodified timestamp
$e = q("UPDATE attach SET edited = '%s' WHERE hash = '%s' AND uid = %d",
dbesc($edited),
@@ -178,8 +210,9 @@ class RedFile extends DAV\Node implements DAV\IFile {
*/
public function get() {
logger('get file ' . basename($this->name), LOGGER_DEBUG);
+ logger('os_path: ' . $this->os_path, LOGGER_DATA);
- $r = q("SELECT data, flags, filename, filetype FROM attach WHERE hash = '%s' AND uid = %d LIMIT 1",
+ $r = q("SELECT data, flags, os_storage, filename, filetype FROM attach WHERE hash = '%s' AND uid = %d LIMIT 1",
dbesc($this->data['hash']),
intval($this->data['uid'])
);
@@ -192,7 +225,7 @@ class RedFile extends DAV\Node implements DAV\IFile {
header('Content-type: text/plain');
}
- if ($r[0]['flags'] & ATTACH_FLAG_OS ) {
+ if (intval($r[0]['os_storage'])) {
$f = 'store/' . $this->auth->owner_nick . '/' . (($this->os_path) ? $this->os_path . '/' : '') . dbunescbin($r[0]['data']);
return fopen($f, 'rb');
}
@@ -271,7 +304,7 @@ class RedFile extends DAV\Node implements DAV\IFile {
}
if ($this->auth->owner_id !== $this->auth->channel_id) {
- if (($this->auth->observer !== $this->data['creator']) || ($this->data['flags'] & ATTACH_FLAG_DIR)) {
+ if (($this->auth->observer !== $this->data['creator']) || intval($this->data['is_dir'])) {
throw new DAV\Exception\Forbidden('Permission denied.');
}
}
diff --git a/include/account.php b/include/account.php
index 5926e05c1..b3a520fd4 100644
--- a/include/account.php
+++ b/include/account.php
@@ -217,6 +217,8 @@ function create_account($arr) {
$result['email'] = $email;
$result['password'] = $password;
+ call_hooks('register_account',$result);
+
return $result;
}
diff --git a/include/acl_selectors.php b/include/acl_selectors.php
index ae740b281..cb2266473 100644
--- a/include/acl_selectors.php
+++ b/include/acl_selectors.php
@@ -171,10 +171,9 @@ function contact_select($selname, $selclass, $preselected = false, $size = 4, $p
$o .= "<select name=\"{$selname}[]\" id=\"$selclass\" class=\"$selclass\" multiple=\"multiple\" size=\"$size\" $tabindex >\r\n";
$r = q("SELECT abook_id, xchan_name, xchan_url, xchan_photo_s from abook left join xchan on abook_xchan = xchan_hash
- where abook_flags = 0 or not ( abook_flags & %d )>0 and abook_channel = %d
+ where abook_self = 0 and abook_channel = %d
$sql_extra
ORDER BY xchan_name ASC ",
- intval(ABOOK_FLAG_SELF),
intval(local_channel())
);
diff --git a/include/activities.php b/include/activities.php
index ca8863e51..df43f1f6f 100644
--- a/include/activities.php
+++ b/include/activities.php
@@ -21,7 +21,10 @@ function profile_activity($changed, $value) {
$arr['uid'] = local_channel();
$arr['aid'] = $self['channel_account_id'];
$arr['owner_xchan'] = $arr['author_xchan'] = $self['xchan_hash'];
- $arr['item_flags'] = ITEM_WALL|ITEM_ORIGIN|ITEM_THREAD_TOP;
+
+ $arr['item_wall'] = 1;
+ $arr['item_origin'] = 1;
+ $arr['item_thread_top'] = 1;
$arr['verb'] = ACTIVITY_UPDATE;
$arr['obj_type'] = ACTIVITY_OBJ_PROFILE;
diff --git a/include/api.php b/include/api.php
index 258d197a5..711b946ed 100644
--- a/include/api.php
+++ b/include/api.php
@@ -75,8 +75,9 @@ require_once('include/attach.php');
try {
$oauth = new FKOAuth1();
$req = OAuthRequest::from_request();
+
list($consumer,$token) = $oauth->verify_request($req);
-// list($consumer,$token) = $oauth->verify_request(OAuthRequest::from_request());
+
if (!is_null($token)){
$oauth->loginUser($token->uid);
@@ -319,7 +320,7 @@ require_once('include/attach.php');
return False;
} else {
$user = local_channel();
- $extra_query = " AND abook_channel = %d AND (abook_flags & " . ABOOK_FLAG_SELF . " )>0 ";
+ $extra_query = " AND abook_channel = %d AND abook_self = 1 ";
}
}
@@ -337,7 +338,7 @@ require_once('include/attach.php');
return False;
}
- if($uinfo[0]['abook_flags'] & ABOOK_FLAG_SELF) {
+ if(intval($uinfo[0]['abook_self'])) {
$usr = q("select * from channel where channel_id = %d limit 1",
intval(api_user())
);
@@ -345,13 +346,14 @@ require_once('include/attach.php');
intval(api_user())
);
+ $item_normal = item_normal();
+
// count public wall messages
$r = q("SELECT COUNT(`id`) as `count` FROM `item`
WHERE `uid` = %d
- AND ( item_flags & %d )>0 and item_restrict = 0
+ AND item_wall = 1 $item_normal
AND `allow_cid`='' AND `allow_gid`='' AND `deny_cid`='' AND `deny_gid`=''",
- intval($usr[0]['channel_id']),
- intval(ITEM_WALL)
+ intval($usr[0]['channel_id'])
);
$countitms = $r[0]['count'];
}
@@ -368,21 +370,20 @@ require_once('include/attach.php');
// count friends
if($usr) {
$r = q("SELECT COUNT(abook_id) as `count` FROM abook
- WHERE abook_channel = %d AND abook_flags = 0 ",
+ WHERE abook_channel = %d AND abook_self = 0 ",
intval($usr[0]['channel_id'])
);
$countfriends = $r[0]['count'];
$countfollowers = $r[0]['count'];
}
- $r = q("SELECT count(`id`) as `count` FROM item where ( item_flags & %d )>0 and uid = %d and item_restrict = 0",
- intval($uinfo[0]['channel_id']),
- intval(ITEM_STARRED)
+ $r = q("SELECT count(`id`) as `count` FROM item where item_starred = 1 and uid = %d " . item_normal(),
+ intval($uinfo[0]['channel_id'])
);
$starred = $r[0]['count'];
- if(! ($uinfo[0]['abook_flags'] & ABOOK_FLAG_SELF)) {
+ if(! intval($uinfo[0]['abook_self'])) {
$countfriends = 0;
$countfollowers = 0;
$starred = 0;
@@ -390,7 +391,7 @@ require_once('include/attach.php');
$ret = Array(
'id' => intval($uinfo[0]['abook_id']),
- 'self' => (($uinfo[0]['abook_flags'] & ABOOK_FLAG_SELF) ? 1 : 0),
+ 'self' => (intval($uinfo[0]['abook_self']) ? 1 : 0),
'uid' => intval($uinfo[0]['abook_channel']),
'guid' => $uinfo[0]['xchan_hash'],
'name' => (($uinfo[0]['xchan_name']) ? $uinfo[0]['xchan_name'] : substr($uinfo[0]['xchan_addr'],0,strpos($uinfo[0]['xchan_addr'],'@'))),
@@ -627,6 +628,71 @@ require_once('include/attach.php');
api_register_func('api/red/files','api_attach_list', true);
+
+
+
+ function api_file_meta(&$a,$type) {
+ if (api_user()===false) return false;
+ if(! $_REQUEST['file_id']) return false;
+ $r = q("select * from attach where uid = %d and hash = '%s' limit 1",
+ intval(api_user()),
+ dbesc($_REQUEST['file_id'])
+ );
+ if($r) {
+ unset($r[0]['data']);
+ $ret = array('attach' => $r[0]);
+ json_return_and_die($ret);
+ }
+ killme();
+ }
+
+ api_register_func('api/red/filemeta', 'api_file_meta', true);
+
+
+ function api_file_data(&$a,$type) {
+ if (api_user()===false) return false;
+ if(! $_REQUEST['file_id']) return false;
+ $start = (($_REQUEST['start']) ? intval($_REQUEST['start']) : 0);
+ $length = (($_REQUEST['length']) ? intval($_REQUEST['length']) : 0);
+
+ $r = q("select * from attach where uid = %d and hash = '%s' limit 1",
+ intval(api_user()),
+ dbesc($_REQUEST['file_id'])
+ );
+ if($r) {
+ $ptr = $r[0];
+ if($length === 0)
+ $length = intval($ptr['filesize']);
+
+ if($ptr['is_dir'])
+ $ptr['data'] = '';
+ elseif(! intval($r[0]['os_storage'])) {
+ $ptr['start'] = $start;
+ $x = substr(dbunescbin($ptr['data'],$start,$length));
+ $ptr['length'] = strlen($x);
+ $ptr['data'] = base64_encode($x);
+ }
+ else {
+ $fp = fopen(dbunescbin($ptr['data'],'r'));
+ if($fp) {
+ $seek = fseek($fp,$start,SEEK_SET);
+ $x = fread($fp,$length);
+ $ptr['start'] = $start;
+ $ptr['length'] = strlen($x);
+ $ptr['data'] = base64_encode($x);
+ }
+ }
+
+ $ret = array('attach' => $ptr);
+ json_return_and_die($ret);
+ }
+ killme();
+ }
+
+ api_register_func('api/red/filedata', 'api_file_data', true);
+
+
+
function api_file_detail(&$a,$type) {
if (api_user()===false) return false;
if(! $_REQUEST['file_id']) return false;
@@ -635,11 +701,9 @@ require_once('include/attach.php');
dbesc($_REQUEST['file_id'])
);
if($r) {
- if($r[0]['flags'] & ATTACH_FLAG_DIR) {
- $r[0]['is_dir'] = '1';
+ if($r[0]['is_dir'])
$r[0]['data'] = '';
- }
- elseif($r[0]['flags'] & ATTACH_FLAG_OS)
+ elseif(intval($r[0]['os_storage']))
$r[0]['data'] = base64_encode(file_get_contents(dbunescbin($r[0]['data'])));
else
$r[0]['data'] = base64_encode(dbunescbin($r[0]['data']));
@@ -828,6 +892,7 @@ require_once('include/attach.php');
require_once('include/html2bbcode.php');
$txt = requestdata('htmlstatus');
+
if((strpos($txt,'<') !== false) || (strpos($txt,'>') !== false)) {
$txt = html2bb_video($txt);
@@ -839,9 +904,10 @@ require_once('include/attach.php');
$purifier = new HTMLPurifier($config);
$txt = $purifier->purify($txt);
- $_REQUEST['body'] = html2bbcode($txt);
}
+ $_REQUEST['body'] = html2bbcode($txt);
+
}
else
$_REQUEST['body'] = requestdata('status');
@@ -929,11 +995,62 @@ require_once('include/attach.php');
api_register_func('api/red/item/new','red_item_new', true);
+ function red_item(&$a, $type) {
+
+ if (api_user() === false) {
+ logger('api_red_item_new: no user');
+ return false;
+ }
+
+ if($_REQUEST['mid']) {
+ $arr = array('mid' => $_REQUEST['mid']);
+ }
+ elseif($_REQUEST['item_id']) {
+ $arr = array('item_id' => $_REQUEST['item_id']);
+ }
+ else
+ json_return_and_die(array());
+
+ $arr['start'] = 0;
+ $arr['records'] = 999999;
+ $arr['item_type'] = '*';
+
+ $i = items_fetch($arr,$a->get_channel(),get_observer_hash());
+
+ if(! $i)
+ json_return_and_die(array());
+
+ $ret = array();
+ $tmp = array();
+ $str = '';
+ foreach($i as $ii) {
+ $tmp[] = encode_item($ii,true);
+ if($str)
+ $str .= ',';
+ $str .= $ii['id'];
+ }
+ $ret['item'] = $tmp;
+ if($str) {
+ $r = q("select item_id.*, item.mid from item_id left join item on item_id.iid = item.id where item.id in ( $str ) ");
+
+ if($r)
+ $ret['item_id'] = $r;
+ }
+
+ json_return_and_die($ret);
+ }
+
+ api_register_func('api/red/item/full','red_item', true);
+
+
+
function api_get_status($xchan_hash) {
require_once('include/security.php');
+ $item_normal = item_normal();
+
$lastwall = q("SELECT * from item where
- item_private = 0 and item_restrict = 0
+ item_private = 0 $item_normal
and author_xchan = '%s'
and allow_cid = '' and allow_gid = '' and deny_cid = '' and deny_gid = ''
and verb = '%s'
@@ -995,9 +1112,10 @@ require_once('include/attach.php');
// get last public message
require_once('include/security.php');
+ $item_normal = item_normal();
$lastwall = q("SELECT * from item where
- item_private = 0 and item_restrict = 0
+ item_private = 0 $item_normal
and author_xchan = '%s'
and allow_cid = '' and allow_gid = '' and deny_cid = '' and deny_gid = ''
and verb = '%s'
@@ -1068,9 +1186,10 @@ require_once('include/attach.php');
$user_info = api_get_user($a);
require_once('include/security.php');
+ $item_normal = item_normal();
$lastwall = q("SELECT * from item where 1
- and item_private != 0 and item_restrict = 0
+ and item_private != 0 $item_normal
and author_xchan = '%s'
and allow_cid = '' and allow_gid = '' and deny_cid = '' and deny_gid = ''
and verb = '%s'
@@ -1171,7 +1290,9 @@ require_once('include/attach.php');
$sql_extra .= " and item_private = 0 ";
}
- $r = q("SELECT * from item WHERE uid = %d and item_restrict = 0
+ $item_normal = item_normal();
+
+ $r = q("SELECT * from item WHERE uid = %d $item_normal
$sql_extra
AND id > %d
ORDER BY received DESC LIMIT %d ,%d ",
@@ -1190,7 +1311,7 @@ require_once('include/attach.php');
// at the network timeline just mark everything seen.
if (api_user() == $user_info['uid']) {
- $r = q("UPDATE `item` SET item_unseen = 0 where item_unseen = 1 and uid = %d",
+ $r = q("UPDATE item SET item_unseen = 0 WHERE item_unseen = 1 and uid = %d",
intval($user_info['uid'])
);
}
@@ -1237,11 +1358,12 @@ require_once('include/attach.php');
if ($max_id > 0)
$sql_extra = 'AND `item`.`id` <= '.intval($max_id);
require_once('include/security.php');
+ $item_normal = item_normal();
- $r = q("select * from item where item_restrict = 0
- and allow_cid = '' and allow_gid = ''
+ $r = q("select * from item where allow_cid = '' and allow_gid = ''
and deny_cid = '' and deny_gid = ''
- and item_private = 0
+ and item_private = 0
+ $item_normal
and uid = " . $sys['channel_id'] . "
$sql_extra
AND id > %d group by mid
@@ -1297,7 +1419,8 @@ require_once('include/attach.php');
else
$sql_extra .= " AND `item`.`id` = %d";
- $r = q("select * from item where item_restrict = 0 $sql_extra",
+ $item_normal = item_normal();
+ $r = q("select * from item where true $item_normal $sql_extra",
intval($id)
);
xchan_query($r,true);
@@ -1337,7 +1460,9 @@ require_once('include/attach.php');
$observer = get_app()->get_observer();
- $r = q("SELECT * from item where item_restrict = 0 and id = %d limit 1",
+ $item_normal = item_normal();
+
+ $r = q("SELECT * from item where and id = %d $item_normal limit 1",
intval($id)
);
@@ -1430,7 +1555,7 @@ require_once('include/attach.php');
*
*/
-// FIXME
+
function api_statuses_mentions(&$a, $type){
if (api_user()===false) return false;
@@ -1455,39 +1580,25 @@ require_once('include/attach.php');
$myurl = str_replace(array('www.','.'),array('','\\.'),$myurl);
$diasp_url = str_replace('/channel/','/u/',$myurl);
- if (get_config('system','use_fulltext_engine'))
- $sql_extra .= sprintf(" AND `item`.`parent` IN (SELECT distinct(`parent`) from item where (MATCH(`author-link`) AGAINST ('".'"%s"'."' in boolean mode) or MATCH(`tag`) AGAINST ('".'"%s"'."' in boolean mode) or MATCH(tag) AGAINST ('".'"%s"'."' in boolean mode))) ",
- dbesc(protect_sprintf($myurl)),
- dbesc(protect_sprintf($myurl)),
- dbesc(protect_sprintf($diasp_url))
- );
- else
- $sql_extra .= sprintf(" AND `item`.`parent` IN (SELECT distinct(`parent`) from item where ( `author-link` like '%s' or `tag` like '%s' or tag like '%s' )) ",
- dbesc(protect_sprintf('%' . $myurl)),
- dbesc(protect_sprintf('%' . $myurl . ']%')),
- dbesc(protect_sprintf('%' . $diasp_url . ']%'))
- );
-
+ $sql_extra .= " AND item_mentionsme = 1 ";
if ($max_id > 0)
- $sql_extra .= ' AND `item`.`id` <= '.intval($max_id);
+ $sql_extra .= " AND item.id <= " . intval($max_id) . " ";
- $r = q("SELECT `item`.*, `item`.`id` AS `item_id`,
- `contact`.`name`, `contact`.`photo`, `contact`.`url`, `contact`.`rel`,
- `contact`.`network`, `contact`.`thumb`, `contact`.`dfrn_id`, `contact`.`self`,
- `contact`.`id` AS `cid`, `contact`.`uid` AS `contact-uid`
- FROM `item`, `contact`
- WHERE `item`.`uid` = %d
- AND `item`.`visible` = 1 and `item`.`moderated` = 0 AND `item`.`deleted` = 0
- AND `contact`.`id` = `item`.`contact-id`
- AND `contact`.`blocked` = 0 AND `contact`.`pending` = 0
- $sql_extra
- AND `item`.`id`>%d
- ORDER BY `item`.`received` DESC LIMIT %d ,%d ",
- intval($user_info['uid']),
+ require_once('include/security.php');
+ $item_normal = item_normal();
+
+ $r = q("select * from item where uid = " . intval(api_user()) . "
+ $item_normal $sql_extra
+ AND id > %d group by mid
+ order by received desc LIMIT %d OFFSET %d ",
intval($since_id),
- intval($start), intval($count)
+ intval($count),
+ intval($start)
);
+ xchan_query($r,true);
+
+
$ret = api_format_items($r,$user_info);
@@ -1610,39 +1721,36 @@ require_once('include/attach.php');
$itemid = intval($_REQUEST['id']);
}
- $item = q("SELECT * FROM item WHERE id = %d AND uid = %d",
- intval($itemid),
- intval(api_user())
+ $item = q("SELECT * FROM item WHERE id = %d AND uid = %d",
+ intval($itemid),
+ intval(api_user())
);
if (! $item)
return false;
- switch($action){
- case "create":
-
- $flags = $item[0]['item_flags'] | ITEM_STARRED;
-
- break;
- case "destroy":
-
- $flags = $item[0]['item_flags'] | (~ ITEM_STARRED);
- break;
- default:
- return false;
- }
-
- $r = q("UPDATE item SET item_flags = %d where id = %d and uid = %d",
- intval($flags),
+ switch($action){
+ case "create":
+ $flags = $item[0]['item_starred'] = 1;
+ break;
+ case "destroy":
+ $flags = $item[0]['item_starred'] = 0;
+ break;
+ default:
+ return false;
+ }
+
+ $r = q("UPDATE item SET item_starred = %d where id = %d and uid = %d",
+ intval($flags),
intval($itemid),
intval(api_user())
);
if(! $r)
return false;
- $item = q("SELECT * FROM item WHERE id = %d AND uid = %d",
- intval($itemid),
- intval(api_user())
+ $item = q("SELECT * FROM item WHERE id = %d AND uid = %d",
+ intval($itemid),
+ intval(api_user())
);
xchan_query($item,true);
@@ -1700,12 +1808,13 @@ require_once('include/attach.php');
$sql_extra .= " and item_private = 0 ";
}
- $r = q("SELECT * from item WHERE uid = %d and item_restrict = 0
- and ( item_flags & %d ) > 0 $sql_extra
+ $item_normal = item_normal();
+
+ $r = q("SELECT * from item WHERE uid = %d $item_normal
+ and item_starred = 1 $sql_extra
AND id > %d
ORDER BY received DESC LIMIT %d ,%d ",
intval($user_info['uid']),
- intval(ITEM_STARRED),
intval($since_id),
intval($start),
intval($count)
@@ -1897,7 +2006,7 @@ require_once('include/attach.php');
'in_reply_to_user_id' => $in_reply_to_user_id,
'in_reply_to_screen_name' => $in_reply_to_screen_name,
'geo' => '',
- 'favorited' => (($item['item_flags'] & ITEM_STARRED) ? true : false),
+ 'favorited' => (intval($item['item_starred']) ? true : false),
'user' => $status_user ,
'statusnet_html' => trim(prepare_text($item['body'],$item['mimetype'])),
@@ -1992,7 +2101,7 @@ require_once('include/attach.php');
if($qtype == 'followers')
$sql_extra = sprintf(" AND ( abook_my_perms & %d )>0 and not ( abook_their_perms & %d )>0 ", intval(PERMS_W_STREAM), intval(PERMS_W_STREAM));
- $r = q("SELECT abook_id FROM abook where abook_flags = 0 and abook_channel = %d $sql_extra",
+ $r = q("SELECT abook_id FROM abook where abook_self = 0 and abook_channel = %d $sql_extra",
intval(api_user())
);
@@ -2045,7 +2154,7 @@ require_once('include/attach.php');
'broughtbyurl' => '', 'timezone' => 'UTC', 'closed' => $closed, 'inviteonly' => 'false',
'private' => $private, 'textlimit' => $textlimit, 'sslserver' => $sslserver, 'ssl' => $ssl,
'shorturllength' => '30',
- 'redmatrix' => array(
+ 'hubzilla' => array(
'PLATFORM_NAME' => PLATFORM_NAME,
'RED_VERSION' => RED_VERSION,
'ZOT_REVISION' => ZOT_REVISION,
@@ -2108,7 +2217,7 @@ require_once('include/attach.php');
if($qtype == 'followers')
$sql_extra = sprintf(" AND ( abook_my_perms & %d )>0 and not ( abook_their_perms & %d )>0 ", intval(PERMS_W_STREAM), intval(PERMS_W_STREAM));
- $r = q("SELECT abook_id FROM abook where abook_flags = 0 and abook_channel = %d $sql_extra",
+ $r = q("SELECT abook_id FROM abook where abook_self = 0 and abook_channel = %d $sql_extra",
intval(api_user())
);
diff --git a/include/apps.php b/include/apps.php
index 504641102..0a62dc5a8 100644
--- a/include/apps.php
+++ b/include/apps.php
@@ -130,7 +130,7 @@ function translate_system_apps(&$arr) {
'Address Book' => t('Address Book'),
'Login' => t('Login'),
'Channel Manager' => t('Channel Manager'),
- 'Matrix' => t('Matrix'),
+ 'Grid' => t('Grid'),
'Settings' => t('Settings'),
'Files' => t('Files'),
'Webpages' => t('Webpages'),
@@ -176,14 +176,19 @@ function app_render($papp,$mode = 'view') {
$installed = false;
- if(! $papp['photo'])
- $papp['photo'] = z_root() . '/' . get_default_profile_photo(80);
-
if(! $papp)
return;
+ if(! $papp['photo'])
+ $papp['photo'] = z_root() . '/' . get_default_profile_photo(80);
+
+
+
$papp['papp'] = papp_encode($papp);
+ if(! strstr($papp['url'],'://'))
+ $papp['url'] = z_root() . ((strpos($papp['url'],'/') === 0) ? '' : '/') . $papp['url'];
+
foreach($papp as $k => $v) {
if(strpos($v,'http') === 0 && $k != 'papp')
$papp[$k] = zid($v);
@@ -264,18 +269,37 @@ function app_install($uid,$app) {
else
$x = app_store($app);
- if($x['success'])
- return $x['app_id'];
+ if($x['success']) {
+ $r = q("select * from app where app_id = '%s' and app_channel = %d limit 1",
+ dbesc($x['app_id']),
+ intval($uid)
+ );
+ if($r)
+ build_sync_packet($uid,array('app' => $r[0]));
+ return $x['app_id'];
+ }
return false;
}
function app_destroy($uid,$app) {
+
+
if($uid && $app['guid']) {
+
+ $x = q("select * from app where app_id = '%s' and app_channel = %d limit 1",
+ dbesc($app['guid']),
+ intval($uid)
+ );
+ $x[0]['app_deleted'] = 1;
+
+
$r = q("delete from app where app_id = '%s' and app_channel = %d",
dbesc($app['guid']),
intval($uid)
);
+
+ build_sync_packet($uid,array('app' => $x));
}
}
@@ -325,7 +349,7 @@ function app_store($arr) {
return $ret;
if($arr['photo'] && ! strstr($arr['photo'],z_root())) {
- $x = import_profile_photo($arr['photo'],get_observer_hash(),true);
+ $x = import_xchan_photo($arr['photo'],get_observer_hash(),true);
$arr['photo'] = $x[1];
}
@@ -342,7 +366,9 @@ function app_store($arr) {
$darray['app_page'] = ((x($arr,'page')) ? escape_tags($arr['page']) : '');
$darray['app_requires'] = ((x($arr,'requires')) ? escape_tags($arr['requires']) : '');
- $r = q("insert into app ( app_id, app_sig, app_author, app_name, app_desc, app_url, app_photo, app_version, app_channel, app_addr, app_price, app_page, app_requires ) values ( '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, '%s', '%s', '%s', '%s' )",
+ $created = datetime_convert();
+
+ $r = q("insert into app ( app_id, app_sig, app_author, app_name, app_desc, app_url, app_photo, app_version, app_channel, app_addr, app_price, app_page, app_requires, app_created, app_edited ) values ( '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, '%s', '%s', '%s', '%s', '%s', '%s' )",
dbesc($darray['app_id']),
dbesc($darray['app_sig']),
dbesc($darray['app_author']),
@@ -355,7 +381,9 @@ function app_store($arr) {
dbesc($darray['app_addr']),
dbesc($darray['app_price']),
dbesc($darray['app_page']),
- dbesc($darray['app_requires'])
+ dbesc($darray['app_requires']),
+ dbesc($created),
+ dbesc($created)
);
if($r) {
$ret['success'] = true;
@@ -378,7 +406,7 @@ function app_update($arr) {
return $ret;
if($arr['photo'] && ! strstr($arr['photo'],z_root())) {
- $x = import_profile_photo($arr['photo'],get_observer_hash(),true);
+ $x = import_xchan_photo($arr['photo'],get_observer_hash(),true);
$arr['photo'] = $x[1];
}
@@ -393,7 +421,9 @@ function app_update($arr) {
$darray['app_page'] = ((x($arr,'page')) ? escape_tags($arr['page']) : '');
$darray['app_requires'] = ((x($arr,'requires')) ? escape_tags($arr['requires']) : '');
- $r = q("update app set app_sig = '%s', app_author = '%s', app_name = '%s', app_desc = '%s', app_url = '%s', app_photo = '%s', app_version = '%s', app_addr = '%s', app_price = '%s', app_page = '%s', app_requires = '%s' where app_id = '%s' and app_channel = %d",
+ $edited = datetime_convert();
+
+ $r = q("update app set app_sig = '%s', app_author = '%s', app_name = '%s', app_desc = '%s', app_url = '%s', app_photo = '%s', app_version = '%s', app_addr = '%s', app_price = '%s', app_page = '%s', app_requires = '%s', app_edited = '%s' where app_id = '%s' and app_channel = %d",
dbesc($darray['app_sig']),
dbesc($darray['app_author']),
dbesc($darray['app_name']),
@@ -405,6 +435,7 @@ function app_update($arr) {
dbesc($darray['app_price']),
dbesc($darray['app_page']),
dbesc($darray['app_requires']),
+ dbesc($edited),
dbesc($darray['app_id']),
intval($darray['app_channel'])
);
diff --git a/include/attach.php b/include/attach.php
index c16944601..8a568d8e1 100644
--- a/include/attach.php
+++ b/include/attach.php
@@ -64,7 +64,10 @@ function z_mime_content_type($filename) {
'wav' => 'audio/wav',
'qt' => 'video/quicktime',
'mov' => 'video/quicktime',
- 'ogg' => 'application/ogg',
+ 'ogg' => 'audio/ogg',
+ 'ogv' => 'video/ogg',
+ 'ogx' => 'application/ogg',
+ 'flac' => 'audio/flac',
'opus' => 'audio/ogg',
'webm' => 'video/webm',
// 'webm' => 'audio/webm',
@@ -105,9 +108,9 @@ function z_mime_content_type($filename) {
'oth' => 'application/vnd.oasis.opendocument.text-web'
);
- $dot = strpos($filename, '.');
- if ($dot !== false) {
- $ext = strtolower(substr($filename, $dot + 1));
+ $last_dot = strrpos($filename, '.');
+ if ($last_dot !== false) {
+ $ext = strtolower(substr($filename, $last_dot + 1));
if (array_key_exists($ext, $mime_types)) {
return $mime_types[$ext];
}
@@ -150,10 +153,11 @@ function attach_count_files($channel_id, $observer, $hash = '', $filename = '',
if($filetype)
$sql_extra .= protect_sprintf(" and filetype like '@" . dbesc($filetype) . "@' ");
- $r = q("select id from attach where uid = %d $sql_extra",
+ $r = q("select id, uid, folder from attach where uid = %d $sql_extra",
intval($channel_id)
);
+
$ret['success'] = ((is_array($r)) ? true : false);
$ret['results'] = ((is_array($r)) ? count($r) : false);
@@ -202,7 +206,7 @@ function attach_list_files($channel_id, $observer, $hash = '', $filename = '', $
// Retrieve all columns except 'data'
- $r = q("select id, aid, uid, hash, filename, filetype, filesize, revision, folder, flags, created, edited, allow_cid, allow_gid, deny_cid, deny_gid from attach where uid = %d $sql_extra ORDER BY $orderby $limit",
+ $r = q("select id, aid, uid, hash, filename, filetype, filesize, revision, folder, os_storage, is_dir, is_photo, flags, created, edited, allow_cid, allow_gid, deny_cid, deny_gid from attach where uid = %d $sql_extra ORDER BY $orderby $limit",
intval($channel_id)
);
@@ -262,12 +266,40 @@ function attach_by_hash($hash, $rev = 0) {
return $ret;
}
+ if($r[0]['folder']) {
+ $x = attach_can_view_folder($r[0]['uid'],get_observer_hash(),$r[0]['folder']);
+ if(! $x) {
+ $ret['message'] = t('Permission denied.');
+ return $ret;
+ }
+ }
+
$ret['success'] = true;
$ret['data'] = $r[0];
return $ret;
}
+function attach_can_view_folder($uid,$ob_hash,$folder_hash) {
+
+ $sql_extra = permissions_sql($uid,$ob_hash);
+ $hash = $folder_hash;
+ $result = false;
+
+ do {
+ $r = q("select folder from attach where hash = '%s' and uid = %d $sql_extra",
+ dbesc($hash),
+ intval($uid)
+ );
+ if(! $r)
+ return false;
+ $hash = $r[0]['folder'];
+ }
+ while($hash);
+ return true;
+}
+
+
/**
* @brief Find an attachment by hash and revision.
*
@@ -310,7 +342,7 @@ function attach_by_hash_nodata($hash, $rev = 0) {
// Now we'll see if we can access the attachment
- $r = q("select id, aid, uid, hash, creator, filename, filetype, filesize, revision, folder, flags, created, edited, allow_cid, allow_gid, deny_cid, deny_gid from attach where uid = %d and hash = '%s' $sql_extra limit 1",
+ $r = q("select id, aid, uid, hash, creator, filename, filetype, filesize, revision, folder, os_storage, is_photo, is_dir, flags, created, edited, allow_cid, allow_gid, deny_cid, deny_gid from attach where uid = %d and hash = '%s' $sql_extra limit 1",
intval($r[0]['uid']),
dbesc($hash)
);
@@ -320,6 +352,15 @@ function attach_by_hash_nodata($hash, $rev = 0) {
return $ret;
}
+ if($r[0]['folder']) {
+ $x = attach_can_view_folder($r[0]['uid'],get_observer_hash(),$r[0]['folder']);
+ if(! $x) {
+ $ret['message'] = t('Permission denied.');
+ return $ret;
+ }
+ }
+
+
$ret['success'] = true;
$ret['data'] = $r[0];
@@ -340,17 +381,68 @@ function attach_by_hash_nodata($hash, $rev = 0) {
* @param string $options (optional) one of update, replace, revision
* @param array $arr (optional) associative array
*/
+
+/**
+ * A lot going on in this function, and some of it is old cruft and some is new cruft
+ * and the entire thing probably needs to be refactored. It started out just storing
+ * files, before we had DAV. It was made extensible to do extra stuff like edit an
+ * existing file or optionally store a separate revision using $options to choose between different
+ * storage models. Along the way we moved from
+ * DB data storage to file system storage.
+ * Then DAV came along and used different upload methods depending on whether the
+ * file was stored as a DAV directory object or updated as a file object. One of these
+ * is essentially an update and the other is basically an upload, but doesn't use the traditional PHP
+ * upload workflow.
+ * Then came hubzilla and we tried to merge photo functionality with the file storage. Most of
+ * that integration occurs within this function.
+ * This required overlap with the old photo_upload stuff and photo albums were
+ * completely different concepts from directories which needed to be reconciled somehow.
+ * The old revision stuff is kind of orphaned currently. There's new revision stuff for photos
+ * which attaches (2) etc. onto the name, but doesn't integrate with the attach table revisioning.
+ * That's where it sits currently. I repeat it needs to be refactored, and this note is here
+ * for future explorers and those who may be doing that work to understand where it came
+ * from and got to be the monstrosity of tangled unrelated code that it currently is.
+ */
+
function attach_store($channel, $observer_hash, $options = '', $arr = null) {
+ require_once('include/photos.php');
+
+ call_hooks('photo_upload_begin',$arr);
+
$ret = array('success' => false);
$channel_id = $channel['channel_id'];
$sql_options = '';
+ $source = (($arr) ? $arr['source'] : '');
+ $album = (($arr) ? $arr['album'] : '');
+ $newalbum = (($arr) ? $arr['newalbum'] : '');
+ $hash = (($arr && $arr['hash']) ? $arr['hash'] : null);
+ $upload_path = (($arr && $arr['directory']) ? $arr['directory'] : '');
+ $visible = (($arr && $arr['visible']) ? $arr['visible'] : '');
+
+ $observer = array();
+
+ if($observer_hash) {
+ $x = q("select * from xchan where xchan_hash = '%s' limit 1",
+ dbesc($observer_hash)
+ );
+ if($x)
+ $observer = $x[0];
+ }
+
+ logger('arr: ' . print_r($arr,true));
- if(! perm_is_allowed($channel_id,get_observer_hash(), 'write_storage')) {
+ if(! perm_is_allowed($channel_id,$observer_hash, 'write_storage')) {
$ret['message'] = t('Permission denied.');
return $ret;
}
+ $str_group_allow = perms2str($arr['group_allow']);
+ $str_contact_allow = perms2str($arr['contact_allow']);
+ $str_group_deny = perms2str($arr['group_deny']);
+ $str_contact_deny = perms2str($arr['contact_deny']);
+
+
// The 'update' option sets db values without uploading a new attachment
// 'replace' replaces the existing uploaded data
// 'revision' creates a new revision with new upload data
@@ -358,23 +450,64 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) {
// revise or update must provide $arr['hash'] of the thing to revise/update
- if($options !== 'update') {
- if(! x($_FILES,'userfile')) {
- $ret['message'] = t('No source file.');
- return $ret;
+ // By default remove $src when finished
+
+ $remove_when_processed = true;
+
+ if($options === 'import') {
+ $src = $arr['src'];
+ $filename = $arr['filename'];
+ $filesize = @filesize($src);
+
+ $hash = $arr['resource_id'];
+
+ if(array_key_exists('hash',$arr))
+ $hash = $arr['hash'];
+ if(array_key_exists('type',$arr))
+ $type = $arr['type'];
+
+ if($arr['preserve_original'])
+ $remove_when_processed = false;
+
+ // if importing a directory, just do it now and go home - we're done.
+
+ if(array_key_exists('is_dir',$arr) && intval($arr['is_dir'])) {
+ $x = attach_mkdir($channel,$observer_hash,$arr);
+ if($x['message'])
+ logger('import_directory: ' . $x['message']);
+ return;
}
+ }
+ elseif($options !== 'update') {
+ $f = array('src' => '', 'filename' => '', 'filesize' => 0, 'type' => '');
+
+ call_hooks('photo_upload_file',$f);
+ call_hooks('attach_upload_file',$f);
- $src = $_FILES['userfile']['tmp_name'];
- $filename = basename($_FILES['userfile']['name']);
- $filesize = intval($_FILES['userfile']['size']);
+ if (x($f,'src') && x($f,'filesize')) {
+ $src = $f['src'];
+ $filename = $f['filename'];
+ $filesize = $f['filesize'];
+ $type = $f['type'];
+
+ } else {
+
+ if(! x($_FILES,'userfile')) {
+ $ret['message'] = t('No source file.');
+ return $ret;
+ }
+
+ $src = $_FILES['userfile']['tmp_name'];
+ $filename = basename($_FILES['userfile']['name']);
+ $filesize = intval($_FILES['userfile']['size']);
+ }
}
$existing_size = 0;
if($options === 'replace') {
- /** @BUG $replace is undefined here */
$x = q("select id, hash, filesize from attach where id = %d and uid = %d limit 1",
- intval($replace),
+ intval($arr['id']),
intval($channel_id)
);
if(! $x) {
@@ -391,7 +524,7 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) {
if($options === 'update' && $arr && array_key_exists('revision',$arr))
$sql_options = " and revision = " . intval($arr['revision']) . " ";
- $x = q("select id, aid, uid, filename, filetype, filesize, hash, revision, folder, flags, created, edited, allow_cid, allow_gid, deny_cid, deny_gid from attach where hash = '%s' and uid = %d $sql_options limit 1",
+ $x = q("select id, aid, uid, filename, filetype, filesize, hash, revision, folder, os_storage, is_photo, flags, created, edited, allow_cid, allow_gid, deny_cid, deny_gid from attach where hash = '%s' and uid = %d $sql_options limit 1",
dbesc($arr['hash']),
intval($channel_id)
);
@@ -402,13 +535,139 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) {
$hash = $x[0]['hash'];
}
+
+
+ $def_extension = '';
+ $is_photo = 0;
+ $gis = @getimagesize($src);
+ logger('getimagesize: ' . print_r($gis,true), LOGGER_DATA);
+ if(($gis) && ($gis[2] === IMAGETYPE_GIF || $gis[2] === IMAGETYPE_JPEG || $gis[2] === IMAGETYPE_PNG)) {
+ $is_photo = 1;
+ if($gis[2] === IMAGETYPE_GIF)
+ $def_extension = '.gif';
+ if($gis[2] === IMAGETYPE_JPEG)
+ $def_extension = '.jpg';
+ if($gis[2] === IMAGETYPE_PNG)
+ $def_extension = '.png';
+
+ }
+
+ $pathname = '';
+
+ if($is_photo) {
+ if($newalbum) {
+ $pathname = filepath_macro($newalbum);
+ }
+ elseif(array_key_exists('folder',$arr)) {
+ $x = q("select filename from attach where hash = '%s' and uid = %d limit 1",
+ dbesc($arr['folder']),
+ intval($channel['channel_id'])
+ );
+ if($x)
+ $pathname = $x[0]['filename'];
+ }
+ else {
+ $pathname = filepath_macro($album);
+ }
+ }
+ else {
+ $pathname = filepath_macro($upload_path);
+ }
+
+ $darr = array('pathname' => $pathname);
+
+ // if we need to create a directory, use the channel default permissions.
+
+ $darr['allow_cid'] = $channel['allow_cid'];
+ $darr['allow_gid'] = $channel['allow_gid'];
+ $darr['deny_cid'] = $channel['deny_cid'];
+ $darr['deny_gid'] = $channel['deny_gid'];
+
+
+ $direct = null;
+
+ if($pathname) {
+ $x = attach_mkdirp($channel, $observer_hash, $darr);
+ $folder_hash = (($x['success']) ? $x['data']['hash'] : '');
+ $direct = (($x['success']) ? $x['data'] : null);
+ if((! $str_contact_allow) && (! $str_group_allow) && (! $str_contact_deny) && (! $str_group_deny)) {
+ $str_contact_allow = $x['data']['allow_cid'];
+ $str_group_allow = $x['data']['allow_gid'];
+ $str_contact_deny = $x['data']['deny_cid'];
+ $str_group_deny = $x['data']['deny_gid'];
+ }
+ }
+ else {
+ $folder_hash = ((($arr) && array_key_exists('folder',$arr)) ? $arr['folder'] : '');
+ }
+
+ if((! $options) || ($options === 'import')) {
+
+ // A freshly uploaded file. Check for duplicate and resolve with the channel's overwrite settings.
+
+ $r = q("select filename, id, hash, filesize from attach where filename = '%s' and folder = '%s' ",
+ dbesc($filename),
+ dbesc($folder_hash)
+ );
+ if($r) {
+ $overwrite = get_pconfig($channel_id,'system','overwrite_dup_files');
+ if($overwrite) {
+ $options = 'replace';
+ $existing_id = $x[0]['id'];
+ $existing_size = intval($x[0]['filesize']);
+ $hash = $x[0]['hash'];
+ }
+ else {
+ if(strpos($filename,'.') !== false) {
+ $basename = substr($filename,0,strrpos($filename,'.'));
+ $ext = substr($filename,strrpos($filename,'.'));
+ }
+ else {
+ $basename = $filename;
+ $ext = $def_extension;
+ }
+
+ $r = q("select filename from attach where ( filename = '%s' OR filename like '%s' ) and folder = '%s' ",
+ dbesc($basename . $ext),
+ dbesc($basename . '(%)' . $ext),
+ dbesc($folder_hash)
+ );
+
+ if($r) {
+ $x = 1;
+
+ do {
+ $found = false;
+ foreach($r as $rr) {
+ if($rr['filename'] === $basename . '(' . $x . ')' . $ext) {
+ $found = true;
+ break;
+ }
+ }
+ if($found)
+ $x++;
+ }
+ while($found);
+ $filename = $basename . '(' . $x . ')' . $ext;
+ }
+ else
+ $filename = $basename . $ext;
+ }
+ }
+ }
+
+ if(! $hash)
+ $hash = random_string();
+
// Check storage limits
if($options !== 'update') {
$maxfilesize = get_config('system','maxfilesize');
if(($maxfilesize) && ($filesize > $maxfilesize)) {
$ret['message'] = sprintf( t('File exceeds size limit of %d'), $maxfilesize);
- @unlink($src);
+ if($remove_when_processed)
+ @unlink($src);
+ call_hooks('photo_upload_end',$ret);
return $ret;
}
@@ -420,41 +679,70 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) {
);
if(($r) && (($r[0]['total'] + $filesize) > ($limit - $existing_size))) {
$ret['message'] = upgrade_message(true) . sprintf(t("You have reached your limit of %1$.0f Mbytes attachment storage."), $limit / 1024000);
- @unlink($src);
+ if($remove_when_processed)
+ @unlink($src);
+
+ call_hooks('photo_upload_end',$ret);
return $ret;
}
}
- $mimetype = z_mime_content_type($filename);
+ $mimetype = ((isset($type) && $type) ? $type : z_mime_content_type($filename));
}
- if(! isset($hash))
- $hash = random_string();
+ $os_basepath = 'store/' . $channel['channel_address'] . '/' ;
+ $os_relpath = '';
- $created = datetime_convert();
+ if($folder_hash) {
+ $curr = find_folder_hash_by_attach_hash($channel_id,$folder_hash,true);
+ if($curr)
+ $os_relpath .= $curr . '/';
+ $os_relpath .= $folder_hash . '/';
+ }
+
+ $os_relpath .= $hash;
+
+ if($src)
+ @file_put_contents($os_basepath . $os_relpath,@file_get_contents($src));
+
+ if(array_key_exists('created', $arr))
+ $created = $arr['created'];
+ else
+ $created = datetime_convert();
+
+ if(array_key_exists('edited', $arr))
+ $edited = $arr['edited'];
+ else
+ $edited = $created;
if($options === 'replace') {
- $r = q("update attach set filename = '%s', filetype = '%s', filesize = %d, data = '%s', edited = '%s' where id = %d and uid = %d",
+ $r = q("update attach set filename = '%s', filetype = '%s', folder = '%s', filesize = %d, os_storage = %d, is_photo = %d, data = '%s', edited = '%s' where id = %d and uid = %d",
dbesc($filename),
dbesc($mimetype),
+ dbesc($folder_hash),
intval($filesize),
- dbescbin(@file_get_contents($src)),
+ intval(1),
+ intval($is_photo),
+ dbesc($os_basepath . $os_relpath),
dbesc($created),
intval($existing_id),
intval($channel_id)
);
}
elseif($options === 'revise') {
- $r = q("insert into attach ( aid, uid, hash, creator, filename, filetype, filesize, revision, data, created, edited, allow_cid, allow_gid, deny_cid, deny_gid )
- VALUES ( %d, %d, '%s', '%s', '%s', '%s', %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s' ) ",
+ $r = q("insert into attach ( aid, uid, hash, creator, filename, filetype, folder, filesize, revision, os_storage, is_photo, data, created, edited, allow_cid, allow_gid, deny_cid, deny_gid )
+ VALUES ( %d, %d, '%s', '%s', '%s', '%s', '%s', %d, %d, %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s' ) ",
intval($x[0]['aid']),
intval($channel_id),
dbesc($x[0]['hash']),
- dbesc(get_observer_hash()),
+ dbesc($observer_hash),
dbesc($filename),
dbesc($mimetype),
+ dbesc($folder_hash),
intval($filesize),
intval($x[0]['revision'] + 1),
- dbescbin(@file_get_contents($src)),
+ intval(1),
+ intval($is_photo),
+ dbesc($os_basepath . $os_relpath),
dbesc($created),
dbesc($created),
dbesc($x[0]['allow_cid']),
@@ -464,11 +752,14 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) {
);
}
elseif($options === 'update') {
- $r = q("update attach set filename = '%s', filetype = '%s', edited = '%s',
+ $r = q("update attach set filename = '%s', filetype = '%s', folder = '%s', edited = '%s', os_storage = %d, is_photo = %d,
allow_cid = '%s', allow_gid = '%s', deny_cid = '%s', deny_gid = '%s' where id = %d and uid = %d",
dbesc((array_key_exists('filename',$arr)) ? $arr['filename'] : $x[0]['filename']),
dbesc((array_key_exists('filetype',$arr)) ? $arr['filetype'] : $x[0]['filetype']),
+ dbesc(($folder_hash) ? $folder_hash : $x[0]['folder']),
dbesc($created),
+ dbesc((array_key_exists('os_storage',$arr)) ? $arr['os_storage'] : $x[0]['os_storage']),
+ dbesc((array_key_exists('is_photo',$arr)) ? $arr['is_photo'] : $x[0]['is_photo']),
dbesc((array_key_exists('allow_cid',$arr)) ? $arr['allow_cid'] : $x[0]['allow_cid']),
dbesc((array_key_exists('allow_gid',$arr)) ? $arr['allow_gid'] : $x[0]['allow_gid']),
dbesc((array_key_exists('deny_cid',$arr)) ? $arr['deny_cid'] : $x[0]['deny_cid']),
@@ -478,49 +769,96 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) {
);
}
else {
- $r = q("INSERT INTO attach ( aid, uid, hash, creator, filename, filetype, filesize, revision, data, created, edited, allow_cid, allow_gid,deny_cid, deny_gid )
- VALUES ( %d, %d, '%s', '%s', '%s', '%s', %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s' ) ",
+
+ $r = q("INSERT INTO attach ( aid, uid, hash, creator, filename, filetype, folder, filesize, revision, os_storage, is_photo, data, created, edited, allow_cid, allow_gid,deny_cid, deny_gid )
+ VALUES ( %d, %d, '%s', '%s', '%s', '%s', '%s', %d, %d, %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s' ) ",
intval($channel['channel_account_id']),
intval($channel_id),
dbesc($hash),
dbesc(get_observer_hash()),
dbesc($filename),
dbesc($mimetype),
+ dbesc($folder_hash),
intval($filesize),
intval(0),
- dbescbin(@file_get_contents($src)),
+ intval(1),
+ intval($is_photo),
+ dbesc($os_basepath . $os_relpath),
dbesc($created),
dbesc($created),
- dbesc(($arr && array_key_exists('allow_cid',$arr)) ? $arr['allow_cid'] : '<' . $channel['channel_hash'] . '>'),
- dbesc(($arr && array_key_exists('allow_gid',$arr)) ? $arr['allow_gid'] : ''),
- dbesc(($arr && array_key_exists('deny_cid',$arr)) ? $arr['deny_cid'] : ''),
- dbesc(($arr && array_key_exists('deny_gid',$arr)) ? $arr['deny_gid'] : '')
+ dbesc(($arr && array_key_exists('allow_cid',$arr)) ? $arr['allow_cid'] : $str_contact_allow),
+ dbesc(($arr && array_key_exists('allow_gid',$arr)) ? $arr['allow_gid'] : $str_group_allow),
+ dbesc(($arr && array_key_exists('deny_cid',$arr)) ? $arr['deny_cid'] : $str_contact_deny),
+ dbesc(($arr && array_key_exists('deny_gid',$arr)) ? $arr['deny_gid'] : $str_group_deny)
);
}
- if($options !== 'update')
+ if($is_photo) {
+
+ $args = array( 'source' => $source, 'visible' => $visible, 'resource_id' => $hash, 'album' => basename($pathname), 'os_path' => $os_basepath . $os_relpath, 'filename' => $filename, 'getimagesize' => $gis, 'directory' => $direct);
+ if($arr['contact_allow'])
+ $args['contact_allow'] = $arr['contact_allow'];
+ if($arr['group_allow'])
+ $args['group_allow'] = $arr['group_allow'];
+ if($arr['contact_deny'])
+ $args['contact_deny'] = $arr['contact_deny'];
+ if($arr['group_deny'])
+ $args['group_deny'] = $arr['group_deny'];
+ if(array_key_exists('allow_cid',$arr))
+ $args['allow_cid'] = $arr['allow_cid'];
+ if(array_key_exists('allow_gid',$arr))
+ $args['allow_gid'] = $arr['allow_gid'];
+ if(array_key_exists('deny_cid',$arr))
+ $args['deny_cid'] = $arr['deny_cid'];
+ if(array_key_exists('deny_gid',$arr))
+ $args['deny_gid'] = $arr['deny_gid'];
+
+ $args['created'] = $created;
+ $args['edited'] = $edited;
+ if($arr['item'])
+ $args['item'] = $arr['item'];
+
+ if($arr['body'])
+ $args['body'] = $arr['body'];
+
+ if($arr['description'])
+ $args['description'] = $arr['description'];
+
+ $p = photo_upload($channel,$observer,$args);
+ if($p['success']) {
+ $ret['body'] = $p['body'];
+ }
+ }
+
+ if(($options !== 'update') && ($remove_when_processed))
@unlink($src);
if(! $r) {
$ret['message'] = t('File upload failed. Possible system limit or action terminated.');
+ call_hooks('photo_upload_end',$ret);
return $ret;
}
// Caution: This re-uses $sql_options set further above
- $r = q("select id, aid, uid, hash, creator, filename, filetype, filesize, revision, folder, flags, created, edited, allow_cid, allow_gid, deny_cid, deny_gid from attach where uid = %d and hash = '%s' $sql_options limit 1",
+ $r = q("select id, aid, uid, hash, creator, filename, filetype, filesize, revision, folder, os_storage, is_photo, flags, created, edited, allow_cid, allow_gid, deny_cid, deny_gid from attach where uid = %d and hash = '%s' $sql_options limit 1",
intval($channel_id),
dbesc($hash)
);
if(! $r) {
$ret['message'] = t('Stored file could not be verified. Upload failed.');
+ call_hooks('photo_upload_end',$ret);
return $ret;
}
+
$ret['success'] = true;
$ret['data'] = $r[0];
-
+ if(! $is_photo) {
+ // This would've been called already with a success result in photos_upload() if it was a photo.
+ call_hooks('photo_upload_end',$ret);
+ }
return $ret;
}
@@ -552,10 +890,9 @@ function z_readdir($channel_id, $observer_hash, $pathname, $parent_hash = '') {
if(count($paths) > 1) {
$curpath = array_shift($paths);
- $r = q("select hash, id from attach where uid = %d and filename = '%s' and (flags & %d )>0 " . permissions_sql($channel_id) . " limit 1",
+ $r = q("select hash, id, is_dir from attach where uid = %d and filename = '%s' and is_dir != 0 " . permissions_sql($channel_id) . " limit 1",
intval($channel_id),
- dbesc($curpath),
- intval(ATTACH_FLAG_DIR)
+ dbesc($curpath)
);
if(! $r) {
$ret['message'] = t('Path not available.');
@@ -568,11 +905,10 @@ function z_readdir($channel_id, $observer_hash, $pathname, $parent_hash = '') {
else
$paths = array($pathname);
- $r = q("select id, aid, uid, hash, creator, filename, filetype, filesize, revision, folder, flags, created, edited, allow_cid, allow_gid, deny_cid, deny_gid from attach where id = %d and folder = '%s' and filename = '%s' and (flags & %d )>0 " . permissions_sql($channel_id),
+ $r = q("select id, aid, uid, hash, creator, filename, filetype, filesize, revision, folder, is_photo, is_dir, os_storage, flags, created, edited, allow_cid, allow_gid, deny_cid, deny_gid from attach where id = %d and folder = '%s' and filename = '%s' and is_dir != 0 " . permissions_sql($channel_id),
intval($channel_id),
dbesc($parent_hash),
- dbesc($paths[0]),
- intval(ATTACH_FLAG_DIR)
+ dbesc($paths[0])
);
if(! $r) {
$ret['message'] = t('Path not available.');
@@ -594,7 +930,7 @@ function z_readdir($channel_id, $observer_hash, $pathname, $parent_hash = '') {
* * \e string \b filename
* * \e string \b folder hash of parent directory, empty string for root directory
* - Optional:
- * * \e string \b hash precumputed hash for this node
+ * * \e string \b hash precomputed hash for this node
* * \e tring \b allow_cid
* * \e string \b allow_gid
* * \e string \b deny_cid
@@ -605,6 +941,7 @@ function attach_mkdir($channel, $observer_hash, $arr = null) {
$ret = array('success' => false);
$channel_id = $channel['channel_id'];
+
$sql_options = '';
$basepath = 'store/' . $channel['channel_address'];
@@ -629,13 +966,23 @@ function attach_mkdir($channel, $observer_hash, $arr = null) {
// Check for duplicate name.
// Check both the filename and the hash as we will be making use of both.
- $r = q("select hash from attach where ( filename = '%s' or hash = '%s' ) and folder = '%s' and uid = %d limit 1",
+ $r = q("select id, hash, is_dir, flags from attach where ( filename = '%s' or hash = '%s' ) and folder = '%s' and uid = %d limit 1",
dbesc($arr['filename']),
dbesc($arr['hash']),
dbesc($arr['folder']),
intval($channel['channel_id'])
);
if($r) {
+ if(array_key_exists('force',$arr) && intval($arr['force'])
+ && (intval($r[0]['is_dir']))) {
+ $ret['success'] = true;
+ $r = q("select * from attach where id = %d limit 1",
+ intval($r[0]['id'])
+ );
+ if($r)
+ $ret['data'] = $r[0];
+ return $ret;
+ }
$ret['message'] = t('duplicate filename or path');
return $ret;
}
@@ -651,13 +998,11 @@ function attach_mkdir($channel, $observer_hash, $arr = null) {
$sql_options = permissions_sql($channel['channel_id']);
do {
- $r = q("select filename, hash, flags, folder from attach where uid = %d and hash = '%s' and ( flags & %d )>0
+ $r = q("select filename, hash, flags, is_dir, folder from attach where uid = %d and hash = '%s' and is_dir != 0
$sql_options limit 1",
intval($channel['channel_id']),
- dbesc($lfile),
- intval(ATTACH_FLAG_DIR)
+ dbesc($lfile)
);
-
if(! $r) {
logger('attach_mkdir: hash ' . $lfile . ' not found in ' . $lpath);
$ret['message'] = t('Path not found.');
@@ -666,7 +1011,7 @@ function attach_mkdir($channel, $observer_hash, $arr = null) {
if($lfile)
$lpath = $r[0]['hash'] . '/' . $lpath;
$lfile = $r[0]['folder'];
- } while ( ($r[0]['folder']) && ($r[0]['flags'] & ATTACH_FLAG_DIR)) ;
+ } while ( ($r[0]['folder']) && intval($r[0]['is_dir'])) ;
$path = $basepath . '/' . $lpath;
}
else
@@ -676,8 +1021,8 @@ function attach_mkdir($channel, $observer_hash, $arr = null) {
$created = datetime_convert();
- $r = q("INSERT INTO attach ( aid, uid, hash, creator, filename, filetype, filesize, revision, folder, flags, data, created, edited, allow_cid, allow_gid, deny_cid, deny_gid )
- VALUES ( %d, %d, '%s', '%s', '%s', '%s', %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s' ) ",
+ $r = q("INSERT INTO attach ( aid, uid, hash, creator, filename, filetype, filesize, revision, folder, os_storage, is_dir, data, created, edited, allow_cid, allow_gid, deny_cid, deny_gid )
+ VALUES ( %d, %d, '%s', '%s', '%s', '%s', %d, %d, '%s', %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s' ) ",
intval($channel['channel_account_id']),
intval($channel_id),
dbesc($arr['hash']),
@@ -687,7 +1032,8 @@ function attach_mkdir($channel, $observer_hash, $arr = null) {
intval(0),
intval(0),
dbesc($arr['folder']),
- intval(ATTACH_FLAG_DIR|ATTACH_FLAG_OS),
+ intval(1),
+ intval(1),
dbesc($path),
dbesc($created),
dbesc($created),
@@ -700,7 +1046,6 @@ function attach_mkdir($channel, $observer_hash, $arr = null) {
if($r) {
if(os_mkdir($path, STORAGE_DEFAULT_PERMISSIONS, true)) {
$ret['success'] = true;
- $ret['data'] = $arr;
// update the parent folder's lastmodified timestamp
$e = q("UPDATE attach SET edited = '%s' WHERE hash = '%s' AND uid = %d",
@@ -708,6 +1053,13 @@ function attach_mkdir($channel, $observer_hash, $arr = null) {
dbesc($arr['folder']),
intval($channel_id)
);
+
+ $z = q("select * from attach where hash = '%s' and uid = %d and is_dir = 1 limit 1",
+ dbesc($arr['hash']),
+ intval($channel_id)
+ );
+ if($z)
+ $ret['data'] = $z[0];
}
else {
logger('attach_mkdir: ' . mkdir . ' ' . $path . ' failed.');
@@ -722,6 +1074,95 @@ function attach_mkdir($channel, $observer_hash, $arr = null) {
}
/**
+ * @brief Create directory (recursive).
+ *
+ * @param array $channel channel array of owner
+ * @param string $observer_hash hash of current observer
+ * @param array $arr parameter array to fulfil request
+ * - Required:
+ * * \e string \b pathname
+ * * \e string \b folder hash of parent directory, empty string for root directory
+ * - Optional:
+ * * \e string \b allow_cid
+ * * \e string \b allow_gid
+ * * \e string \b deny_cid
+ * * \e string \b deny_gid
+ * @return array
+ */
+function attach_mkdirp($channel, $observer_hash, $arr = null) {
+
+ $ret = array('success' => false);
+ $channel_id = $channel['channel_id'];
+
+ $sql_options = '';
+
+ $basepath = 'store/' . $channel['channel_address'];
+
+ logger('attach_mkdirp: basepath: ' . $basepath);
+
+ if(! is_dir($basepath))
+ os_mkdir($basepath,STORAGE_DEFAULT_PERMISSIONS, true);
+
+ if(! perm_is_allowed($channel_id, $observer_hash, 'write_storage')) {
+ $ret['message'] = t('Permission denied.');
+ return $ret;
+ }
+
+ if(! $arr['pathname']) {
+ $ret['message'] = t('Empty pathname');
+ return $ret;
+ }
+
+ $paths = explode('/',$arr['pathname']);
+ if(! $paths) {
+ $ret['message'] = t('Empty path');
+ return $ret;
+ }
+
+ $current_parent = '';
+
+ foreach($paths as $p) {
+ if(! $p)
+ continue;
+ $arx = array(
+ 'filename' => $p,
+ 'folder' => $current_parent,
+ 'force' => 1
+ );
+ if(array_key_exists('allow_cid',$arr))
+ $arx['allow_cid'] = $arr['allow_cid'];
+ if(array_key_exists('deny_cid',$arr))
+ $arx['deny_cid'] = $arr['deny_cid'];
+ if(array_key_exists('allow_gid',$arr))
+ $arx['allow_gid'] = $arr['allow_gid'];
+ if(array_key_exists('deny_gid',$arr))
+ $arx['deny_gid'] = $arr['deny_gid'];
+
+ $x = attach_mkdir($channel, $observer_hash, $arx);
+ if($x['success']) {
+ $current_parent = $x['data']['hash'];
+ }
+ else {
+ $ret['message'] = $x['message'];
+ return $ret;
+ }
+ }
+ if(isset($x)) {
+ $ret['success'] = true;
+ $ret['data'] = $x['data'];
+ }
+
+ return $ret;
+
+}
+
+
+
+
+
+
+
+/**
* @brief Changes permissions of a file.
*
* @param int $channel_id
@@ -734,7 +1175,7 @@ function attach_mkdir($channel, $observer_hash, $arr = null) {
*/
function attach_change_permissions($channel_id, $resource, $allow_cid, $allow_gid, $deny_cid, $deny_gid, $recurse = false) {
- $r = q("select hash, flags from attach where hash = '%s' and uid = %d limit 1",
+ $r = q("select hash, flags, is_dir, is_photo from attach where hash = '%s' and uid = %d limit 1",
dbesc($resource),
intval($channel_id)
);
@@ -742,9 +1183,9 @@ function attach_change_permissions($channel_id, $resource, $allow_cid, $allow_gi
if(! $r)
return;
- if($r[0]['flags'] & ATTACH_FLAG_DIR) {
+ if(intval($r[0]['is_dir'])) {
if($recurse) {
- $r = q("select hash, flags from attach where folder = '%s' and uid = %d",
+ $r = q("select hash, flags, is_dir from attach where folder = '%s' and uid = %d",
dbesc($resource),
intval($channel_id)
);
@@ -764,6 +1205,16 @@ function attach_change_permissions($channel_id, $resource, $allow_cid, $allow_gi
dbesc($resource),
intval($channel_id)
);
+ if($r[0]['is_photo']) {
+ $x = q("update photo set allow_cid = '%s', allow_gid = '%s', deny_cid = '%s', deny_gid = '%s' where resource_id = '%s' and uid = %d",
+ dbesc($allow_cid),
+ dbesc($allow_gid),
+ dbesc($deny_cid),
+ dbesc($deny_gid),
+ dbesc($resource),
+ intval($channel_id)
+ );
+ }
}
/**
@@ -778,15 +1229,16 @@ function attach_change_permissions($channel_id, $resource, $allow_cid, $allow_gi
* The hash to delete
* @return void
*/
-function attach_delete($channel_id, $resource) {
+function attach_delete($channel_id, $resource, $is_photo = 0) {
$c = q("SELECT channel_address FROM channel WHERE channel_id = %d LIMIT 1",
intval($channel_id)
);
$channel_address = (($c) ? $c[0]['channel_address'] : 'notfound');
+ $photo_sql = (($is_photo) ? " and is_photo = 1 " : '');
- $r = q("SELECT hash, flags, folder FROM attach WHERE hash = '%s' AND uid = %d limit 1",
+ $r = q("SELECT hash, flags, is_dir, is_photo, folder FROM attach WHERE hash = '%s' AND uid = %d $photo_sql limit 1",
dbesc($resource),
intval($channel_id)
);
@@ -798,8 +1250,8 @@ function attach_delete($channel_id, $resource) {
$object = get_file_activity_object($channel_id, $resource, $cloudpath);
// If resource is a directory delete everything in the directory recursive
- if($r[0]['flags'] & ATTACH_FLAG_DIR) {
- $x = q("SELECT hash, flags FROM attach WHERE folder = '%s' AND uid = %d",
+ if(intval($r[0]['is_dir'])) {
+ $x = q("SELECT hash, os_storage, is_dir, flags FROM attach WHERE folder = '%s' AND uid = %d",
dbesc($resource),
intval($channel_id)
);
@@ -811,7 +1263,7 @@ function attach_delete($channel_id, $resource) {
}
// delete a file from filesystem
- if($r[0]['flags'] & ATTACH_FLAG_OS) {
+ if(intval($r[0]['os_storage'])) {
$y = q("SELECT data FROM attach WHERE hash = '%s' AND uid = %d LIMIT 1",
dbesc($resource),
intval($channel_id)
@@ -832,6 +1284,20 @@ function attach_delete($channel_id, $resource) {
intval($channel_id)
);
+ if($r[0]['is_photo']) {
+ $x = q("select id, item_hidden from item where resource_id = '%s' and resource_type = 'photo' and uid = %d",
+ dbesc($resource),
+ intval($channel_id)
+ );
+ if($x) {
+ drop_item($x[0]['id'],false,(($x[0]['item_hidden']) ? DROPITEM_NORMAL : DROPITEM_PHASE1),true);
+ }
+ q("DELETE FROM photo WHERE uid = %d AND resource_id = '%s'",
+ intval($channel_id),
+ dbesc($resource)
+ );
+ }
+
// update the parent folder's lastmodified timestamp
$e = q("UPDATE attach SET edited = '%s' WHERE hash = '%s' AND uid = %d",
dbesc(datetime_convert()),
@@ -873,11 +1339,10 @@ function get_cloudpath($arr) {
$lfile = $arr['folder'];
do {
- $r = q("select filename, hash, flags, folder from attach where uid = %d and hash = '%s' and ( flags & %d )>0
+ $r = q("select filename, hash, flags, is_dir, folder from attach where uid = %d and hash = '%s' and is_dir != 0
limit 1",
intval($arr['uid']),
- dbesc($lfile),
- intval(ATTACH_FLAG_DIR)
+ dbesc($lfile)
);
if(! $r)
@@ -887,7 +1352,7 @@ function get_cloudpath($arr) {
$lpath = $r[0]['filename'] . '/' . $lpath;
$lfile = $r[0]['folder'];
- } while ( ($r[0]['folder']) && ($r[0]['flags'] & ATTACH_FLAG_DIR));
+ } while ( ($r[0]['folder']) && intval($r[0]['is_dir']));
$path .= $lpath;
}
@@ -932,14 +1397,19 @@ function get_parent_cloudpath($channel_id, $channel_name, $attachHash) {
* The hash of the attachment
* @return string
*/
-function find_folder_hash_by_attach_hash($channel_id, $attachHash) {
+function find_folder_hash_by_attach_hash($channel_id, $attachHash, $recurse = false) {
+
+logger('attach_hash: ' . $attachHash);
$r = q("SELECT folder FROM attach WHERE uid = %d AND hash = '%s' LIMIT 1",
intval($channel_id),
dbesc($attachHash)
);
$hash = '';
- if ($r) {
- $hash = $r[0]['folder'];
+ if($r && $r[0]['folder']) {
+ if($recurse)
+ $hash = find_folder_hash_by_attach_hash($channel_id,$r[0]['folder'],true) . '/' . $r[0]['folder'];
+ else
+ $hash = $r[0]['folder'];
}
return $hash;
}
@@ -1011,7 +1481,7 @@ function file_activity($channel_id, $object, $allow_cid, $allow_gid, $deny_cid,
//filter out receivers which do not have permission to view filestorage
$arr_allow_cid = check_list_permissions($channel_id, $arr_allow_cid, 'view_storage');
- $is_dir = (($object['flags'] & ATTACH_FLAG_DIR) ? true : false);
+ $is_dir = (intval($object['is_dir']) ? true : false);
//do not send activity for folders for now
if($is_dir)
@@ -1036,9 +1506,13 @@ function file_activity($channel_id, $object, $allow_cid, $allow_gid, $deny_cid,
$mid = item_message_id();
- $objtype = ACTIVITY_OBJ_FILE;
+ $arr = array();
- $item_flags = ITEM_WALL|ITEM_ORIGIN;
+ $arr['item_wall'] = 1;
+ $arr['item_origin'] = 1;
+ $arr['item_unseen'] = 1;
+
+ $objtype = ACTIVITY_OBJ_FILE;
$private = (($arr_allow_cid[0] || $arr_allow_gid[0] || $arr_deny_cid[0] || $arr_deny_gid[0]) ? 1 : 0);
@@ -1077,23 +1551,20 @@ function file_activity($channel_id, $object, $allow_cid, $allow_gid, $deny_cid,
$u_mid = item_message_id();
- $arr = array();
-
$arr['aid'] = get_account_id();
$arr['uid'] = $channel_id;
$arr['mid'] = $u_mid;
$arr['parent_mid'] = $u_mid;
- $arr['item_flags'] = $item_flags;
- $arr['item_unseen'] = 1;
$arr['author_xchan'] = $poster['xchan_hash'];
$arr['owner_xchan'] = $poster['xchan_hash'];
$arr['title'] = '';
- $arr['allow_cid'] = perms2str($u_arr_allow_cid);
- $arr['allow_gid'] = perms2str($u_arr_allow_gid);
- $arr['deny_cid'] = perms2str($u_arr_deny_cid);
- $arr['deny_gid'] = perms2str($u_arr_deny_gid);
- $arr['item_restrict'] = ITEM_HIDDEN;
- $arr['item_private'] = $private;
+ //updates should be visible to everybody -> perms may have changed
+ $arr['allow_cid'] = '';
+ $arr['allow_gid'] = '';
+ $arr['deny_cid'] = '';
+ $arr['deny_gid'] = '';
+ $arr['item_hidden'] = 1;
+ $arr['item_private'] = 0;
$arr['verb'] = ACTIVITY_UPDATE;
$arr['obj_type'] = $objtype;
$arr['object'] = $u_jsonobject;
@@ -1124,7 +1595,8 @@ function file_activity($channel_id, $object, $allow_cid, $allow_gid, $deny_cid,
$arr['uid'] = $channel_id;
$arr['mid'] = $mid;
$arr['parent_mid'] = $mid;
- $arr['item_flags'] = $item_flags;
+ $arr['item_wall'] = 1;
+ $arr['item_origin'] = 1;
$arr['item_unseen'] = 1;
$arr['author_xchan'] = $poster['xchan_hash'];
$arr['owner_xchan'] = $poster['xchan_hash'];
@@ -1133,7 +1605,7 @@ function file_activity($channel_id, $object, $allow_cid, $allow_gid, $deny_cid,
$arr['allow_gid'] = perms2str($arr_allow_gid);
$arr['deny_cid'] = perms2str($arr_deny_cid);
$arr['deny_gid'] = perms2str($arr_deny_gid);
- $arr['item_restrict'] = ITEM_HIDDEN;
+ $arr['item_hidden'] = 1;
$arr['item_private'] = $private;
$arr['verb'] = (($update) ? ACTIVITY_UPDATE : ACTIVITY_POST);
$arr['obj_type'] = $objtype;
@@ -1165,7 +1637,7 @@ function file_activity($channel_id, $object, $allow_cid, $allow_gid, $deny_cid,
*/
function get_file_activity_object($channel_id, $hash, $cloudpath) {
- $x = q("SELECT creator, filename, filetype, filesize, revision, folder, flags, created, edited, allow_cid, allow_gid, deny_cid, deny_gid FROM attach WHERE uid = %d AND hash = '%s' LIMIT 1",
+ $x = q("SELECT creator, filename, filetype, filesize, revision, folder, os_storage, is_photo, is_dir, flags, created, edited, allow_cid, allow_gid, deny_cid, deny_gid FROM attach WHERE uid = %d AND hash = '%s' LIMIT 1",
intval($channel_id),
dbesc($hash)
);
@@ -1193,6 +1665,9 @@ function get_file_activity_object($channel_id, $hash, $cloudpath) {
'revision' => $x[0]['revision'],
'folder' => $x[0]['folder'],
'flags' => $x[0]['flags'],
+ 'os_storage' => $x[0]['os_storage'],
+ 'is_photo' => $x[0]['is_photo'],
+ 'is_dir' => $x[0]['is_dir'],
'created' => $x[0]['created'],
'edited' => $x[0]['edited'],
'allow_cid' => $x[0]['allow_cid'],
@@ -1348,3 +1823,16 @@ function in_group($group_id) {
return $group_members;
}
+
+
+function filepath_macro($s) {
+
+ return str_replace(
+ array( '%Y', '%m', '%d' ),
+ array( datetime_convert('UTC',date_default_timezone_get(),'now', 'Y'),
+ datetime_convert('UTC',date_default_timezone_get(),'now', 'm'),
+ datetime_convert('UTC',date_default_timezone_get(),'now', 'd')
+ ), $s);
+
+}
+
diff --git a/include/bb2diaspora.php b/include/bb2diaspora.php
index 65f8f3ea1..1be7caa19 100644
--- a/include/bb2diaspora.php
+++ b/include/bb2diaspora.php
@@ -162,10 +162,10 @@ function diaspora2bb($s, $use_zrl = false) {
}
//$s = preg_replace("/([^\]\=]|^)(https?\:\/\/)(vimeo|youtu|www\.youtube|soundcloud)([a-zA-Z0-9\:\/\-\?\&\;\.\=\_\~\#\%\$\!\+\,]+)/ism", '$1[url=$2$3$4]$2$3$4[/url]',$s);
- $s = bb_tag_preg_replace("/\[url\=?(.*?)\]https?:\/\/www.youtube.com\/watch\?v\=(.*?)\[\/url\]/ism",'[youtube]$2[/youtube]','url',$s);
- $s = bb_tag_preg_replace("/\[url\=https?:\/\/www.youtube.com\/watch\?v\=(.*?)\].*?\[\/url\]/ism",'[youtube]$1[/youtube]','url',$s);
- $s = bb_tag_preg_replace("/\[url\=?(.*?)\]https?:\/ \/vimeo.com\/([0-9]+)(.*?)\[\/url\]/ism",'[vimeo]$2[/vimeo]','url',$s);
- $s = bb_tag_preg_replace("/\[url\=https?:\/\/vimeo.com\/([0-9]+)\](.*?)\[\/url\]/ism",'[vimeo]$1[/vimeo]','url',$s);
+ $s = bb_tag_preg_replace("/\[url\=?(.*?)\]https?:\/\/www.youtube.com\/watch\?v\=(.*?)\[\/url\]/ism",'[embed]https://www.youtube.com/watch?v=$2[/embed]','url',$s);
+ $s = bb_tag_preg_replace("/\[url\=https?:\/\/www.youtube.com\/watch\?v\=(.*?)\].*?\[\/url\]/ism",'[embed]https://www.youtube.com/watch?v=$1[/embed]','url',$s);
+ $s = bb_tag_preg_replace("/\[url\=?(.*?)\]https?:\/ \/vimeo.com\/([0-9]+)(.*?)\[\/url\]/ism",'[embed]https://vimeo.com/$2[/embed]','url',$s);
+ $s = bb_tag_preg_replace("/\[url\=https?:\/\/vimeo.com\/([0-9]+)\](.*?)\[\/url\]/ism",'[embed]https://vimeo.com/$1[/embed]','url',$s);
// remove duplicate adjacent code tags
$s = preg_replace("/(\[code\])+(.*?)(\[\/code\])+/ism","[code]$2[/code]", $s);
@@ -305,6 +305,15 @@ 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) {
@@ -326,7 +335,7 @@ function bb2diaspora_itembody($item, $force_update = false) {
$newitem = $item;
- if(array_key_exists('item_flags',$item) && ($item['item_flags'] & ITEM_OBSCURED)) {
+ if(array_key_exists('item_obscured',$item) && intval($item['item_obscured'])) {
$key = get_config('system','prvkey');
$b = json_decode($item['body'],true);
// if called from diaspora_process_outbound, this decoding has already been done.
@@ -431,6 +440,9 @@ function bb2diaspora($Text,$preserve_nl = false, $fordiaspora = true) {
// So take off the angle brackets of any such URL
$Text = preg_replace("/<http(.*?)>/is", "http$1", $Text);
+ // Remove empty zrl links
+ $Text = preg_replace("/\[zrl\=\].*?\[\/zrl\]/is", "", $Text);
+
// Remove all unconverted tags
$Text = strip_tags($Text);
diff --git a/include/bbcode.php b/include/bbcode.php
index 6fc481fff..517f22bee 100644
--- a/include/bbcode.php
+++ b/include/bbcode.php
@@ -12,6 +12,7 @@ require_once('include/hubloc.php');
function tryoembed($match) {
$url = ((count($match) == 2) ? $match[1] : $match[2]);
+
$o = oembed_fetch_url($url);
if ($o->type == 'error')
@@ -27,7 +28,7 @@ function tryzrlaudio($match) {
if($zrl)
$link = zid($link);
- return '<audio src="' . str_replace(' ','%20',$link) . '" controls="controls"><a href="' . str_replace(' ','%20',$link) . '">' . $link . '</a></audio>';
+ return '<audio src="' . str_replace(' ','%20',$link) . '" controls="controls" preload="none"><a href="' . str_replace(' ','%20',$link) . '">' . $link . '</a></audio>';
}
function tryzrlvideo($match) {
@@ -36,7 +37,7 @@ function tryzrlvideo($match) {
if($zrl)
$link = zid($link);
- return '<video controls="controls" src="' . str_replace(' ','%20',$link) . '" style="width:100%; max-width:' . get_app()->videowidth . 'px"><a href="' . str_replace(' ','%20',$link) . '">' . $link . '</a></video>';
+ return '<video controls="controls" preload="none" src="' . str_replace(' ','%20',$link) . '" style="width:100%; max-width:' . get_app()->videowidth . 'px"><a href="' . str_replace(' ','%20',$link) . '">' . $link . '</a></video>';
}
// [noparse][i]italic[/i][/noparse] turns into
@@ -205,16 +206,6 @@ function translate_design_element($type) {
return $ret;
}
-/**
- * @brief Returns an QR-code image from a value given in $match[1].
- *
- * @param array $match
- * @return string HTML img with QR-code of $match[1]
- */
-function bb_qr($match) {
- return '<img class="zrl" src="' . z_root() . '/photo/qr?f=&qr=' . urlencode($match[1]) . '" alt="' . t('QR code') . '" title="' . htmlspecialchars($match[1],ENT_QUOTES,'UTF-8') . '" />';
-}
-
function bb_ShareAttributes($match) {
@@ -406,10 +397,49 @@ function bb_sanitize_style($input) {
return '<span style="' . $css_string_san . '">' . $input[2] . '</span>';
}
+function bb_observer($Text) {
+
+ $a = get_app();
+
+ $observer = $a->get_observer();
+
+ if ((strpos($Text,'[/observer]') !== false) || (strpos($Text,'[/rpost]') !== false)) {
+ if ($observer) {
+ $Text = preg_replace("/\[observer\=1\](.*?)\[\/observer\]/ism", '$1', $Text);
+ $Text = preg_replace("/\[observer\=0\].*?\[\/observer\]/ism", '', $Text);
+ $Text = preg_replace_callback("/\[rpost(=(.*?))?\](.*?)\[\/rpost\]/ism", 'rpost_callback', $Text);
+ } else {
+ $Text = preg_replace("/\[observer\=1\].*?\[\/observer\]/ism", '', $Text);
+ $Text = preg_replace("/\[observer\=0\](.*?)\[\/observer\]/ism", '$1', $Text);
+ $Text = preg_replace("/\[rpost(=.*?)?\](.*?)\[\/rpost\]/ism", '', $Text);
+ }
+ }
+
+ $channel = $a->get_channel();
+
+ if (strpos($Text,'[/channel]') !== false) {
+ if ($channel) {
+ $Text = preg_replace("/\[channel\=1\](.*?)\[\/channel\]/ism", '$1', $Text);
+ $Text = preg_replace("/\[channel\=0\].*?\[\/channel\]/ism", '', $Text);
+ } else {
+ $Text = preg_replace("/\[channel\=1\].*?\[\/channel\]/ism", '', $Text);
+ $Text = preg_replace("/\[channel\=0\](.*?)\[\/channel\]/ism", '$1', $Text);
+ }
+ }
+
+ return $Text;
+}
+
+
+
+
+
+
+
// BBcode 2 HTML was written by WAY2WEB.net
- // extended to work with Mistpark/Friendica/Red - Mike Macgirvin
+ // extended to work with Mistpark/Friendica/Redmatrix/Hubzilla - Mike Macgirvin
-function bbcode($Text, $preserve_nl = false, $tryoembed = true) {
+function bbcode($Text, $preserve_nl = false, $tryoembed = true, $cache = false) {
$a = get_app();
@@ -434,8 +464,6 @@ function bbcode($Text, $preserve_nl = false, $tryoembed = true) {
$Text = preg_replace_callback("/\[pre\](.*?)\[\/pre\]/ism", 'bb_spacefy',$Text);
}
-
-
// If we find any event code, turn it into an event.
// After we're finished processing the bbcode we'll
// replace all of the event code with a reformatted version.
@@ -445,7 +473,8 @@ function bbcode($Text, $preserve_nl = false, $tryoembed = true) {
// process [observer] tags before we do anything else because we might
// be stripping away stuff that then doesn't need to be worked on anymore
- if(get_config('system','item_cache'))
+
+ if($cache)
$observer = false;
else
$observer = $a->get_observer();
@@ -462,7 +491,7 @@ function bbcode($Text, $preserve_nl = false, $tryoembed = true) {
}
}
- if(get_config('system','item_cache'))
+ if($cache)
$channel = false;
else
$channel = $a->get_channel();
@@ -541,11 +570,7 @@ function bbcode($Text, $preserve_nl = false, $tryoembed = true) {
$urlchars = '[a-zA-Z0-9\:\/\-\?\&\;\.\=\@\_\~\#\%\$\!\+\,\@]';
if (strpos($Text,'http') !== false) {
- $Text = preg_replace("/([^\]\='".'"'."\/]|^|\#\^)(https?\:\/\/$urlchars+)/ism", '$1<a href="$2" >$2</a>', $Text);
- }
-
- if (strpos($Text,'[/qr]') !== false) {
- $Text = preg_replace_callback("/\[qr\](.*?)\[\/qr\]/ism", 'bb_qr', $Text);
+ $Text = preg_replace("/([^\]\='".'"'."\/]|^|\#\^)(https?\:\/\/$urlchars+)/ism", '$1<a href="$2" target="_newwin" >$2</a>', $Text);
}
if (strpos($Text,'[/share]') !== false) {
@@ -557,21 +582,21 @@ function bbcode($Text, $preserve_nl = false, $tryoembed = true) {
}
}
if (strpos($Text,'[/url]') !== false) {
- $Text = preg_replace("/\#\^\[url\]([$URLSearchString]*)\[\/url\]/ism", '<span class="bookmark-identifier">#^</span><a class="bookmark" href="$1" >$1</a>', $Text);
- $Text = preg_replace("/\#\^\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism", '<span class="bookmark-identifier">#^</span><a class="bookmark" href="$1" >$2</a>', $Text);
- $Text = preg_replace("/\[url\]([$URLSearchString]*)\[\/url\]/ism", '<a href="$1" >$1</a>', $Text);
- $Text = preg_replace("/\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism", '<a href="$1" >$2</a>', $Text);
+ $Text = preg_replace("/\#\^\[url\]([$URLSearchString]*)\[\/url\]/ism", '<span class="bookmark-identifier">#^</span><a class="bookmark" href="$1" target="_newwin" >$1</a>', $Text);
+ $Text = preg_replace("/\#\^\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism", '<span class="bookmark-identifier">#^</span><a class="bookmark" href="$1" target="_newwin" >$2</a>', $Text);
+ $Text = preg_replace("/\[url\]([$URLSearchString]*)\[\/url\]/ism", '<a href="$1" target="_newwin" >$1</a>', $Text);
+ $Text = preg_replace("/\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism", '<a href="$1" target="_newwin" >$2</a>', $Text);
}
if (strpos($Text,'[/zrl]') !== false) {
- $Text = preg_replace("/\#\^\[zrl\]([$URLSearchString]*)\[\/zrl\]/ism", '<span class="bookmark-identifier">#^</span><a class="zrl bookmark" href="$1" >$1</a>', $Text);
- $Text = preg_replace("/\#\^\[zrl\=([$URLSearchString]*)\](.*?)\[\/zrl\]/ism", '<span class="bookmark-identifier">#^</span><a class="zrl bookmark" href="$1" >$2</a>', $Text);
- $Text = preg_replace("/\[zrl\]([$URLSearchString]*)\[\/zrl\]/ism", '<a class="zrl" href="$1" >$1</a>', $Text);
- $Text = preg_replace("/\[zrl\=([$URLSearchString]*)\](.*?)\[\/zrl\]/ism", '<a class="zrl" href="$1" >$2</a>', $Text);
+ $Text = preg_replace("/\#\^\[zrl\]([$URLSearchString]*)\[\/zrl\]/ism", '<span class="bookmark-identifier">#^</span><a class="zrl bookmark" href="$1" target="_newwin" >$1</a>', $Text);
+ $Text = preg_replace("/\#\^\[zrl\=([$URLSearchString]*)\](.*?)\[\/zrl\]/ism", '<span class="bookmark-identifier">#^</span><a class="zrl bookmark" href="$1" target="_newwin" >$2</a>', $Text);
+ $Text = preg_replace("/\[zrl\]([$URLSearchString]*)\[\/zrl\]/ism", '<a class="zrl" href="$1" target="_newwin" >$1</a>', $Text);
+ $Text = preg_replace("/\[zrl\=([$URLSearchString]*)\](.*?)\[\/zrl\]/ism", '<a class="zrl" href="$1" target="_newwin" >$2</a>', $Text);
}
// Perform MAIL Search
if (strpos($Text,'[/mail]') !== false) {
- $Text = preg_replace("/\[mail\]([$MAILSearchString]*)\[\/mail\]/", '<a href="mailto:$1">$1</a>', $Text);
- $Text = preg_replace("/\[mail\=([$MAILSearchString]*)\](.*?)\[\/mail\]/", '<a href="mailto:$1">$2</a>', $Text);
+ $Text = preg_replace("/\[mail\]([$MAILSearchString]*)\[\/mail\]/", '<a href="mailto:$1" target="_newwin" >$1</a>', $Text);
+ $Text = preg_replace("/\[mail\=([$MAILSearchString]*)\](.*?)\[\/mail\]/", '<a href="mailto:$1" target="_newwin" >$2</a>', $Text);
}
// leave open the posibility of [map=something]
@@ -860,17 +885,17 @@ function bbcode($Text, $preserve_nl = false, $tryoembed = true) {
// if video couldn't be embedded, link to it instead.
if (strpos($Text,'[/video]') !== false) {
- $Text = preg_replace("/\[video\](.*?)\[\/video\]/", '<a href="$1">$1</a>', $Text);
+ $Text = preg_replace("/\[video\](.*?)\[\/video\]/", '<a href="$1" target="_newwin" >$1</a>', $Text);
}
if (strpos($Text,'[/audio]') !== false) {
- $Text = preg_replace("/\[audio\](.*?)\[\/audio\]/", '<a href="$1">$1</a>', $Text);
+ $Text = preg_replace("/\[audio\](.*?)\[\/audio\]/", '<a href="$1" target="_newwin" >$1</a>', $Text);
}
if (strpos($Text,'[/zvideo]') !== false) {
- $Text = preg_replace("/\[zvideo\](.*?)\[\/zvideo\]/", '<a class="zid" href="$1">$1</a>', $Text);
+ $Text = preg_replace("/\[zvideo\](.*?)\[\/zvideo\]/", '<a class="zid" href="$1" target="_newwin" >$1</a>', $Text);
}
if (strpos($Text,'[/zaudio]') !== false) {
- $Text = preg_replace("/\[zaudio\](.*?)\[\/zaudio\]/", '<a class="zid" href="$1">$1</a>', $Text);
+ $Text = preg_replace("/\[zaudio\](.*?)\[\/zaudio\]/", '<a class="zid" href="$1" target="_newwin" >$1</a>', $Text);
}
if ($tryoembed){
@@ -879,40 +904,40 @@ function bbcode($Text, $preserve_nl = false, $tryoembed = true) {
}
} else {
if (strpos($Text,'[/iframe]') !== false) {
- $Text = preg_replace("/\[iframe\](.*?)\[\/iframe\]/ism", '<a href="$1">$1</a>', $Text);
+ $Text = preg_replace("/\[iframe\](.*?)\[\/iframe\]/ism", '<a href="$1" target="_newwin" >$1</a>', $Text);
}
}
// Youtube extensions
- if (strpos($Text,'[youtube]') !== false) {
- if ($tryoembed) {
- $Text = preg_replace_callback("/\[youtube\](https?:\/\/www.youtube.com\/watch\?v\=.*?)\[\/youtube\]/ism", 'tryoembed', $Text);
- $Text = preg_replace_callback("/\[youtube\](www.youtube.com\/watch\?v\=.*?)\[\/youtube\]/ism", 'tryoembed', $Text);
- $Text = preg_replace_callback("/\[youtube\](https?:\/\/youtu.be\/.*?)\[\/youtube\]/ism", 'tryoembed', $Text);
- }
- $Text = preg_replace("/\[youtube\]https?:\/\/www.youtube.com\/watch\?v\=(.*?)\[\/youtube\]/ism", '[youtube]$1[/youtube]', $Text);
- $Text = preg_replace("/\[youtube\]https?:\/\/www.youtube.com\/embed\/(.*?)\[\/youtube\]/ism", '[youtube]$1[/youtube]', $Text);
- $Text = preg_replace("/\[youtube\]https?:\/\/youtu.be\/(.*?)\[\/youtube\]/ism", '[youtube]$1[/youtube]', $Text);
-
- if ($tryoembed)
- $Text = preg_replace("/\[youtube\]([A-Za-z0-9\-_=]+)(.*?)\[\/youtube\]/ism", '<iframe width="' . $a->videowidth . '" height="' . $a->videoheight . '" src="http://www.youtube.com/embed/$1" frameborder="0"></iframe>', $Text);
- else
- $Text = preg_replace("/\[youtube\]([A-Za-z0-9\-_=]+)(.*?)\[\/youtube\]/ism", "http://www.youtube.com/watch?v=$1", $Text);
- }
- if (strpos($Text,'[vimeo]') !== false) {
- if ($tryoembed) {
- $Text = preg_replace_callback("/\[vimeo\](https?:\/\/player.vimeo.com\/video\/[0-9]+).*?\[\/vimeo\]/ism", 'tryoembed', $Text);
- $Text = preg_replace_callback("/\[vimeo\](https?:\/\/vimeo.com\/[0-9]+).*?\[\/vimeo\]/ism", 'tryoembed', $Text);
- }
-
- $Text = preg_replace("/\[vimeo\]https?:\/\/player.vimeo.com\/video\/([0-9]+)(.*?)\[\/vimeo\]/ism", '[vimeo]$1[/vimeo]', $Text);
- $Text = preg_replace("/\[vimeo\]https?:\/\/vimeo.com\/([0-9]+)(.*?)\[\/vimeo\]/ism", '[vimeo]$1[/vimeo]', $Text);
-
- if ($tryoembed)
- $Text = preg_replace("/\[vimeo\]([0-9]+)(.*?)\[\/vimeo\]/ism", '<iframe width="' . $a->videowidth . '" height="' . $a->videoheight . '" src="http://player.vimeo.com/video/$1" frameborder="0" ></iframe>', $Text);
- else
- $Text = preg_replace("/\[vimeo\]([0-9]+)(.*?)\[\/vimeo\]/ism", "http://vimeo.com/$1", $Text);
- }
+// if (strpos($Text,'[youtube]') !== false) {
+// if ($tryoembed) {
+// $Text = preg_replace_callback("/\[youtube\](https?:\/\/www.youtube.com\/watch\?v\=.*?)\[\/youtube\]/ism", 'tryoembed', $Text);
+// $Text = preg_replace_callback("/\[youtube\](www.youtube.com\/watch\?v\=.*?)\[\/youtube\]/ism", 'tryoembed', $Text);
+// $Text = preg_replace_callback("/\[youtube\](https?:\/\/youtu.be\/.*?)\[\/youtube\]/ism", 'tryoembed', $Text);
+// }
+// $Text = preg_replace("/\[youtube\]https?:\/\/www.youtube.com\/watch\?v\=(.*?)\[\/youtube\]/ism", '[youtube]$1[/youtube]', $Text);
+// $Text = preg_replace("/\[youtube\]https?:\/\/www.youtube.com\/embed\/(.*?)\[\/youtube\]/ism", '[youtube]$1[/youtube]', $Text);
+// $Text = preg_replace("/\[youtube\]https?:\/\/youtu.be\/(.*?)\[\/youtube\]/ism", '[youtube]$1[/youtube]', $Text);
+
+// if ($tryoembed)
+// $Text = preg_replace("/\[youtube\]([A-Za-z0-9\-_=]+)(.*?)\[\/youtube\]/ism", '<iframe width="' . $a->videowidth . '" height="' . $a->videoheight . '" src="http://www.youtube.com/embed/$1" frameborder="0"></iframe>', $Text);
+// else
+// $Text = preg_replace("/\[youtube\]([A-Za-z0-9\-_=]+)(.*?)\[\/youtube\]/ism", "http://www.youtube.com/watch?v=$1", $Text);
+// }
+// if (strpos($Text,'[vimeo]') !== false) {
+// if ($tryoembed) {
+// $Text = preg_replace_callback("/\[vimeo\](https?:\/\/player.vimeo.com\/video\/[0-9]+).*?\[\/vimeo\]/ism", 'tryoembed', $Text);
+// $Text = preg_replace_callback("/\[vimeo\](https?:\/\/vimeo.com\/[0-9]+).*?\[\/vimeo\]/ism", 'tryoembed', $Text);
+// }
+
+// $Text = preg_replace("/\[vimeo\]https?:\/\/player.vimeo.com\/video\/([0-9]+)(.*?)\[\/vimeo\]/ism", '[vimeo]$1[/vimeo]', $Text);
+// $Text = preg_replace("/\[vimeo\]https?:\/\/vimeo.com\/([0-9]+)(.*?)\[\/vimeo\]/ism", '[vimeo]$1[/vimeo]', $Text);
+
+// if ($tryoembed)
+// $Text = preg_replace("/\[vimeo\]([0-9]+)(.*?)\[\/vimeo\]/ism", '<iframe width="' . $a->videowidth . '" height="' . $a->videoheight . '" src="http://player.vimeo.com/video/$1" frameborder="0" ></iframe>', $Text);
+// else
+// $Text = preg_replace("/\[vimeo\]([0-9]+)(.*?)\[\/vimeo\]/ism", "http://vimeo.com/$1", $Text);
+// }
// oembed tag
$Text = oembed_bbcode2html($Text);
@@ -969,15 +994,3 @@ function bbcode($Text, $preserve_nl = false, $tryoembed = true) {
return $Text;
}
-/**
- * This function exists as a short-term solution to folks linking to private images from their /cloud in
- * their profiles, which brings up a login dialogue in the directory when that entry is viewed.
- * The long term solution is to separate the web file browser from DAV so that you'll never see a
- * login prompt (though the resource may return a permission denied).
- */
-
-
-
-function strip_bbimage($s) {
- return preg_replace("/\[[zi]mg(.*?)\](.*?)\[\/[zi]mg\]/ism", '', $s);
-}
diff --git a/include/chat.php b/include/chat.php
index 05bb02bb9..81c5c5d62 100644
--- a/include/chat.php
+++ b/include/chat.php
@@ -91,6 +91,8 @@ function chatroom_destroy($channel,$arr) {
return $ret;
}
+ build_sync_packet($channel['channel_id'],array('chatroom' => $r));
+
q("delete from chatroom where cr_id = %d",
intval($r[0]['cr_id'])
);
diff --git a/include/checksites.php b/include/checksites.php
new file mode 100644
index 000000000..e9c08c202
--- /dev/null
+++ b/include/checksites.php
@@ -0,0 +1,62 @@
+<?php /** @file */
+
+require_once('boot.php');
+require_once('include/cli_startup.php');
+require_once('include/zot.php');
+require_once('include/hubloc.php');
+
+
+
+function checksites_run($argv, $argc){
+
+
+ cli_startup();
+ $a = get_app();
+
+ logger('checksites: start');
+
+ if(($argc > 1) && ($argv[1]))
+ $site_id = $argv[1];
+
+ if($site_id)
+ $sql_options = " and site_url = '" . dbesc($argv[1]) . "' ";
+
+ $days = intval(get_config('system','sitecheckdays'));
+ if($days < 1)
+ $days = 30;
+
+ $r = q("select * from site where site_dead = 0 and site_update < %s - INTERVAL %s and site_type = %d $sql_options ",
+ db_utcnow(), db_quoteinterval($days . ' DAY'),
+ intval(SITE_TYPE_ZOT)
+ );
+
+ if(! $r)
+ return;
+
+ foreach($r as $rr) {
+ if(! strcasecmp($rr['site_url'],z_root()))
+ continue;
+
+ $x = ping_site($rr['site_url']);
+ if($x['success']) {
+ logger('checksites: ' . $rr['site_url']);
+ q("update site set site_update = '%s' where site_url = '%s' ",
+ dbesc(datetime_convert()),
+ dbesc($rr['site_url'])
+ );
+ }
+ else {
+ logger('marking dead site: ' . $x['message']);
+ q("update site set site_dead = 1 where site_url = '%s' ",
+ dbesc($rr['site_url'])
+ );
+ }
+ }
+
+ return;
+}
+
+if (array_search(__file__,get_included_files())===0){
+ checksites_run($argv,$argc);
+ killme();
+}
diff --git a/include/comanche.php b/include/comanche.php
index 49b910bdb..9585a6578 100644
--- a/include/comanche.php
+++ b/include/comanche.php
@@ -5,7 +5,7 @@ require_once('include/menu.php');
require_once('include/widgets.php');
// When editing a webpage - a dropdown is needed to select a page layout
-// On submit, the pdl_select value (which is the mid of an item with item_restrict = ITEM_PDL) is stored in
+// On submit, the pdl_select value (which is the mid of an item with item_type = ITEM_TYPE_PDL) is stored in
// the webpage's resource_id, with resource_type 'pdl'.
// Then when displaying a webpage, we can see if it has a pdl attached. If not we'll
diff --git a/include/contact_widgets.php b/include/contact_widgets.php
index a02fea523..a60b8b1c3 100644
--- a/include/contact_widgets.php
+++ b/include/contact_widgets.php
@@ -71,14 +71,17 @@ function categories_widget($baseurl,$selected = '') {
if(! feature_enabled($a->profile['profile_uid'],'categories'))
return '';
+ $item_normal = item_normal();
+
$terms = array();
$r = q("select distinct(term.term)
from term join item on term.oid = item.id
where item.uid = %d
and term.uid = item.uid
and term.type = %d
- and item.author_xchan = '%s'
- and item.item_restrict = 0
+ and item.owner_xchan = '%s'
+ and item.item_wall = 1
+ $item_normal
order by term.term asc",
intval($a->profile['profile_uid']),
intval(TERM_CATEGORY),
diff --git a/include/conversation.php b/include/conversation.php
index 8bbb87e2c..a5fe573cd 100644
--- a/include/conversation.php
+++ b/include/conversation.php
@@ -96,7 +96,7 @@ function localize_item(&$item){
if(! $item['object'])
return;
- if($item['item_flags'] & ITEM_THREAD_TOP)
+ if(intval($item['item_thread_top']))
return;
$obj = json_decode_plus($item['object']);
@@ -356,21 +356,12 @@ function localize_item(&$item){
}
}
*/
- // add sparkle links to appropriate permalinks
-
-// $x = stristr($item['plink'],'/display/');
-// if($x) {
-// $sparkle = false;
-// $y = best_link_url($item,$sparkle,true);
- // if($sparkle)
-// $item['plink'] = $y . '?f=&url=' . $item['plink'];
-// }
// if item body was obscured and we changed it, re-obscure it
// FIXME - we need a better filter than just the string 'data'; try and
// match the fact that it's json encoded
- if(($item['item_flags'] & ITEM_OBSCURED)
+ if(intval($item['item_obscured'])
&& strlen($item['body']) && (! strpos($item['body'],'data'))) {
$item['body'] = json_encode(crypto_encapsulate($item['body'],get_config('system','pubkey')));
}
@@ -638,11 +629,6 @@ function conversation(&$a, $items, $mode, $update, $page_mode = 'traditional', $
if($item['author-link'] && (! $item['author-name']))
$profile_name = $item['author-link'];
-
- $tags=array();
- $hashtags = array();
- $mentions = array();
-
$sp = false;
$profile_link = best_link_url($item,$sp);
if($sp)
@@ -682,19 +668,21 @@ function conversation(&$a, $items, $mode, $update, $page_mode = 'traditional', $
$likebuttons = false;
$shareable = false;
- $verified = (($item['item_flags'] & ITEM_VERIFIED) ? t('Message signature validated') : '');
- $forged = ((($item['sig']) && (! ($item['item_flags'] & ITEM_VERIFIED))) ? t('Message signature incorrect') : '');
+ $verified = (intval($item['item_verified']) ? t('Message signature validated') : '');
+ $forged = ((($item['sig']) && (! intval($item['item_verified']))) ? t('Message signature incorrect') : '');
$unverified = '';
- $tags=array();
- $terms = get_terms_oftype($item['term'],array(TERM_HASHTAG,TERM_MENTION,TERM_UNKNOWN));
- if(count($terms))
- foreach($terms as $tag)
- $tags[] = format_term_for_display($tag);
+// $tags=array();
+// $terms = get_terms_oftype($item['term'],array(TERM_HASHTAG,TERM_MENTION,TERM_UNKNOWN));
+// if(count($terms))
+// foreach($terms as $tag)
+// $tags[] = format_term_for_display($tag);
$body = prepare_body($item,true);
+ $has_tags = (($body['tags'] || $body['categories'] || $body['mentions'] || $body['attachments'] || $body['folders']) ? true : false);
+
$tmp_item = array(
'template' => $tpl,
'toplevel' => 'toplevel_item',
@@ -708,10 +696,13 @@ function conversation(&$a, $items, $mode, $update, $page_mode = 'traditional', $
'lock' => $lock,
'thumb' => $profile_avatar,
'title' => $item['title'],
- 'body' => $body,
- 'tags' => $tags,
- 'hashtags' => $hashtags,
- 'mentions' => $mentions,
+ 'body' => $body['html'],
+ 'photo' => $body['photo'],
+ 'tags' => $body['tags'],
+ 'categories' => $body['categories'],
+ 'mentions' => $body['mentions'],
+ 'attachments' => $body['attachments'],
+ 'folders' => $body['folders'],
'verified' => $verified,
'unverified' => $unverified,
'forged' => $forged,
@@ -721,7 +712,7 @@ function conversation(&$a, $items, $mode, $update, $page_mode = 'traditional', $
'has_folders' => ((count($folders)) ? 'true' : ''),
'categories' => $categories,
'folders' => $folders,
- 'text' => strip_tags($body),
+ 'text' => strip_tags($body['html']),
'ago' => relative_date($item['created']),
'app' => $item['app'],
'str_app' => sprintf( t('from %s'), $item['app']),
@@ -747,6 +738,7 @@ function conversation(&$a, $items, $mode, $update, $page_mode = 'traditional', $
'previewing' => $previewing,
'wait' => t('Please wait'),
'thread_level' => 1,
+ 'has_tags' => $has_tags,
);
$arr = array('item' => $item, 'output' => $tmp_item);
@@ -925,6 +917,9 @@ function item_photo_menu($item){
if($item['parent'] == $item['id'] && $channel && ($channel_hash != $item['author_xchan'])) {
$sub_link = 'javascript:dosubthread(' . $item['id'] . '); return false;';
}
+ if($channel) {
+ $unsub_link = 'javascript:dounsubthread(' . $item['id'] . '); return false;';
+ }
}
$profile_link = chanlink_hash($item['author_xchan']);
@@ -939,7 +934,7 @@ function item_photo_menu($item){
if($contact) {
$poke_link = $a->get_baseurl($ssl_state) . '/poke/?f=&c=' . $contact['abook_id'];
- if (!($contact['abook_flags'] & ABOOK_FLAG_SELF))
+ if (! intval($contact['abook_self']))
$contact_url = $a->get_baseurl($ssl_state) . '/connedit/' . $contact['abook_id'];
$posts_link = $a->get_baseurl($ssl_state) . '/network/?cid=' . $contact['abook_id'];
@@ -949,12 +944,13 @@ function item_photo_menu($item){
$menu = Array(
t("View Source") => $vsrc_link,
t("Follow Thread") => $sub_link,
+ t("Stop Following") => $unsub_link,
t("View Status") => $status_link,
t("View Profile") => $profile_link,
t("View Photos") => $photos_link,
- t("Matrix Activity") => $posts_link,
+ t("Activity/Posts") => $posts_link,
t("Connect") => $follow_url,
- t("Edit Contact") => $contact_url,
+ t("Edit Connection") => $contact_url,
t("Send PM") => $pm_url,
t("Poke") => $poke_link
);
@@ -1146,6 +1142,7 @@ function status_editor($a, $x, $popup = false) {
'$newpost' => 'true',
'$baseurl' => $a->get_baseurl(true),
'$editselect' => (($plaintext) ? 'none' : '/(profile-jot-text|prvmail-text)/'),
+ '$pretext' => ((x($x,'pretext')) ? $x['pretext'] : ''),
'$geotag' => $geotag,
'$nickname' => $x['nickname'],
'$ispublic' => t('Visible to <strong>everybody</strong>'),
@@ -1172,6 +1169,10 @@ function status_editor($a, $x, $popup = false) {
if($defexpire)
$defexpire = datetime_convert('UTC',date_default_timezone_get(),$defexpire,'Y-m-d H:i');
+ $defpublish = ((($z = get_pconfig($x['profile_uid'], 'system', 'default_post_publish')) && (! $webpage)) ? $z : '');
+ if($defpublish)
+ $defpublish = datetime_convert('UTC',date_default_timezone_get(),$defpublish,'Y-m-d H:i');
+
$cipher = get_pconfig($x['profile_uid'], 'system', 'default_cipher');
if(! $cipher)
$cipher = 'aes256';
@@ -1188,7 +1189,7 @@ function status_editor($a, $x, $popup = false) {
'$pagetitle' => (x($x,'pagetitle') ? $x['pagetitle'] : ''),
'$id_select' => $id_select,
'$id_seltext' => t('Post as'),
- '$writefiles' => (perm_is_allowed($x['profile_uid'], get_observer_hash(), 'post_photos') || perm_is_allowed($x['profile_uid'], get_observer_hash(), 'write_storage')),
+ '$writefiles' => perm_is_allowed($x['profile_uid'], get_observer_hash(), 'write_storage'),
'$bold' => t('Bold'),
'$italic' => t('Italic'),
'$underline' => t('Underline'),
@@ -1243,6 +1244,9 @@ function status_editor($a, $x, $popup = false) {
'$defexpire' => $defexpire,
'$feature_expire' => ((feature_enabled($x['profile_uid'], 'content_expire') && (! $webpage)) ? true : false),
'$expires' => t('Set expiration date'),
+ '$defpublish' => $defpublish,
+ '$feature_future' => ((feature_enabled($x['profile_uid'], 'delayed_posting') && (! $webpage)) ? true : false),
+ '$future_txt' => t('Set publish date'),
'$feature_encrypt' => ((feature_enabled($x['profile_uid'], 'content_encrypt') && (! $webpage)) ? true : false),
'$encrypt' => t('Encrypt text'),
'$cipher' => $cipher,
@@ -1397,7 +1401,8 @@ function render_location_default($item) {
function prepare_page($item) {
$a = get_app();
- $naked = ((get_pconfig($item['uid'],'system','nakedpage')) ? 1 : 0);
+ $naked = 1;
+// $naked = ((get_pconfig($item['uid'],'system','nakedpage')) ? 1 : 0);
$observer = $a->get_observer();
//240 chars is the longest we can have before we start hitting problems with suhosin sites
$preview = substr(urlencode($item['body']), 0, 240);
@@ -1421,7 +1426,7 @@ function prepare_page($item) {
'$auth_url' => (($naked) ? '' : zid($item['author']['xchan_url'])),
'$date' => (($naked) ? '' : datetime_convert('UTC', date_default_timezone_get(), $item['created'], 'Y-m-d H:i')),
'$title' => smilies(bbcode($item['title'])),
- '$body' => $body,
+ '$body' => $body['html'],
'$preview' => $preview,
'$link' => $link,
));
@@ -1606,7 +1611,7 @@ function profile_tabs($a, $is_owner = false, $nickname = null){
'id' => 'profile-tab',
);
}
- if ($p['view_photos']) {
+ if ($p['view_storage']) {
$tabs[] = array(
'label' => t('Photos'),
'url' => $a->get_baseurl() . '/photos/' . $nickname,
@@ -1614,11 +1619,9 @@ function profile_tabs($a, $is_owner = false, $nickname = null){
'title' => t('Photo Albums'),
'id' => 'photo-tab',
);
- }
- if ($p['view_storage']) {
$tabs[] = array(
'label' => t('Files'),
- 'url' => $a->get_baseurl() . '/cloud/' . $nickname . ((get_observer_hash()) ? '' : '?f=&davguest=1'),
+ 'url' => $a->get_baseurl() . '/cloud/' . $nickname,
'sel' => ((argv(0) == 'cloud' || argv(0) == 'sharedwithme') ? 'active' : ''),
'title' => t('Files and Storage'),
'id' => 'files-tab',
diff --git a/include/deliver.php b/include/deliver.php
index 26739fb06..11c1b249e 100644
--- a/include/deliver.php
+++ b/include/deliver.php
@@ -15,7 +15,10 @@ function deliver_run($argv, $argc) {
logger('deliver: invoked: ' . print_r($argv,true), LOGGER_DATA);
+
for($x = 1; $x < $argc; $x ++) {
+
+ $dresult = null;
$r = q("select * from outq where outq_hash = '%s' limit 1",
dbesc($argv[$x])
);
@@ -26,6 +29,8 @@ function deliver_run($argv, $argc) {
* 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'] : '');
@@ -50,18 +55,45 @@ function deliver_run($argv, $argc) {
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);
@@ -98,11 +130,31 @@ function deliver_run($argv, $argc) {
}
else {
$msg = array('body' => json_encode(array('success' => true, 'pickup' => array(array('notify' => $notify,'message' => $m)))));
- zot_import($msg,z_root());
+ $dresult = zot_import($msg,z_root());
}
$r = q("delete from outq where outq_hash = '%s'",
dbesc($argv[$x])
);
+ if($dresult && is_array($dresult)) {
+ foreach($dresult as $xx) {
+ if(is_array($xx) && array_key_exists('message_id',$xx)) {
+ if(delivery_report_is_storable($xx)) {
+ q("insert into dreport ( dreport_mid, dreport_site, dreport_recip, dreport_result, dreport_time, dreport_xchan ) values ( '%s', '%s','%s','%s','%s','%s' ) ",
+ dbesc($xx['message_id']),
+ dbesc($xx['location']),
+ dbesc($xx['recipient']),
+ dbesc($xx['status']),
+ dbesc(datetime_convert($xx['date'])),
+ dbesc($xx['sender'])
+ );
+ }
+ }
+ }
+ }
+
+ q("delete from dreport where dreport_queue = '%s' limit 1",
+ dbesc($argv[$x])
+ );
}
}
else {
diff --git a/include/deliver_hooks.php b/include/deliver_hooks.php
new file mode 100644
index 000000000..f0d6ba1b1
--- /dev/null
+++ b/include/deliver_hooks.php
@@ -0,0 +1,29 @@
+<?php
+
+
+require_once('include/cli_startup.php');
+require_once('include/zot.php');
+
+
+function deliver_hooks_run($argv, $argc) {
+
+ cli_startup();
+
+ $a = get_app();
+
+ if($argc < 2)
+ return;
+
+
+ $r = q("select * from item where id = '%d'",
+ intval($argv[1])
+ );
+ if($r)
+ call_hooks('notifier_normal',$r[0]);
+
+}
+
+if (array_search(__file__,get_included_files())===0){
+ deliver_hooks_run($argv,$argc);
+ killme();
+}
diff --git a/include/diaspora.php b/include/diaspora.php
deleted file mode 100755
index 61556fd9d..000000000
--- a/include/diaspora.php
+++ /dev/null
@@ -1,3036 +0,0 @@
-<?php
-
-require_once('include/crypto.php');
-require_once('include/items.php');
-require_once('include/bb2diaspora.php');
-require_once('include/contact_selectors.php');
-//require_once('include/queue_fn.php');
-//require_once('include/lock.php');
-
-function diaspora_dispatch_public($msg) {
-
- $enabled = intval(get_config('system','diaspora_enabled'));
- if(! $enabled) {
- logger('mod-diaspora: disabled');
- return;
- }
-
- $sys_disabled = true;
-
- if(! get_config('system','disable_discover_tab')) {
- $sys_disabled = get_config('system','disable_diaspora_discover_tab');
- }
- $sys = (($sys_disabled) ? null : get_sys_channel());
-
- // find everybody following or allowing this author
-
- $r = q("SELECT * from channel where channel_id in ( SELECT abook_channel from abook left join xchan on abook_xchan = xchan_hash WHERE xchan_network like '%%diaspora%%' and xchan_addr = '%s' ) and ( channel_pageflags & %d ) = 0 ",
- dbesc($msg['author']),
- intval(PAGE_REMOVED)
- );
-
- // also need to look for those following public streams
-
- if($r) {
- foreach($r as $rr) {
- logger('diaspora_public: delivering to: ' . $rr['channel_name'] . ' (' . $rr['channel_address'] . ') ');
- diaspora_dispatch($rr,$msg);
- }
- }
- else {
- if(! $sys)
- logger('diaspora_public: no subscribers');
- }
-
- if($sys) {
- $sys['system'] = true;
- logger('diaspora_public: delivering to sys.');
- diaspora_dispatch($sys,$msg);
- }
-}
-
-
-
-function diaspora_dispatch($importer,$msg) {
-
- $ret = 0;
-
- if(! array_key_exists('system',$importer))
- $importer['system'] = false;
-
- $enabled = intval(get_config('system','diaspora_enabled'));
- if(! $enabled) {
- logger('mod-diaspora: disabled');
- return;
- }
-
- $allowed = get_pconfig($importer['channel_id'],'system','diaspora_allowed');
- if($allowed === false)
- $allowed = 1;
-
- if(! intval($allowed)) {
- logger('mod-diaspora: disallowed for channel ' . $importer['channel_name']);
- return;
- }
-
- // php doesn't like dashes in variable names
-
- $msg['message'] = str_replace(
- array('<activity_streams-photo>','</activity_streams-photo>'),
- array('<asphoto>','</asphoto>'),
- $msg['message']);
-
-
- $parsed_xml = parse_xml_string($msg['message'],false);
-
- $xmlbase = $parsed_xml->post;
-
-// logger('diaspora_dispatch: ' . print_r($xmlbase,true), LOGGER_DATA);
-
-
- if($xmlbase->request) {
- $ret = diaspora_request($importer,$xmlbase->request);
- }
- elseif($xmlbase->status_message) {
- $ret = diaspora_post($importer,$xmlbase->status_message,$msg);
- }
- elseif($xmlbase->profile) {
- $ret = diaspora_profile($importer,$xmlbase->profile,$msg);
- }
- elseif($xmlbase->comment) {
- $ret = diaspora_comment($importer,$xmlbase->comment,$msg);
- }
- elseif($xmlbase->like) {
- $ret = diaspora_like($importer,$xmlbase->like,$msg);
- }
- elseif($xmlbase->asphoto) {
- $ret = diaspora_asphoto($importer,$xmlbase->asphoto,$msg);
- }
- elseif($xmlbase->reshare) {
- $ret = diaspora_reshare($importer,$xmlbase->reshare,$msg);
- }
- elseif($xmlbase->retraction) {
- $ret = diaspora_retraction($importer,$xmlbase->retraction,$msg);
- }
- elseif($xmlbase->signed_retraction) {
- $ret = diaspora_signed_retraction($importer,$xmlbase->signed_retraction,$msg);
- }
- elseif($xmlbase->relayable_retraction) {
- $ret = diaspora_signed_retraction($importer,$xmlbase->relayable_retraction,$msg);
- }
- elseif($xmlbase->photo) {
- $ret = diaspora_photo($importer,$xmlbase->photo,$msg);
- }
- elseif($xmlbase->conversation) {
- $ret = diaspora_conversation($importer,$xmlbase->conversation,$msg);
- }
- elseif($xmlbase->message) {
- $ret = diaspora_message($importer,$xmlbase->message,$msg);
- }
- else {
- logger('diaspora_dispatch: unknown message type: ' . print_r($xmlbase,true));
- }
- return $ret;
-}
-
-
-function diaspora_is_blacklisted($s) {
-
- $bl1 = get_config('system','blacklisted_sites');
- if(is_array($bl1) && $bl1) {
- foreach($bl1 as $bl) {
- if($bl && strpos($s,$bl) !== false) {
- logger('diaspora_is_blacklisted: blacklisted ' . $s);
- return true;
- }
- }
- }
- return false;
-}
-
-function diaspora_process_outbound($arr) {
-
-/*
-
- We are passed the following array from the notifier, providing everything we need to make delivery decisions.
-
- diaspora_process_outbound(array(
- 'channel' => $channel,
- 'env_recips' => $env_recips,
- 'recipients' => $recipients,
- 'item' => $item,
- 'target_item' => $target_item,
- 'hub' => $hub,
- 'top_level_post' => $top_level_post,
- 'private' => $private,
- 'followup' => $followup,
- 'relay_to_owner' => $relay_to_owner,
- 'uplink' => $uplink,
- 'cmd' => $cmd,
- 'expire' => $expire,
- 'mail' => $mail,
- 'location' => $location,
- 'fsuggest' => $fsuggest,
- 'normal_mode' => $normal_mode,
- 'packet_type' => $packet_type,
- 'walltowall' => $walltowall,
- ));
-*/
-
-
- $allowed = get_pconfig($arr['channel']['channel_id'],'system','diaspora_allowed');
- if($allowed === false)
- $allowed = 1;
-
- if(! intval($allowed)) {
- logger('mod-diaspora: disallowed for channel ' . $arr['channel']['channel_name']);
- return;
- }
-
-
- if($arr['location'])
- return;
-
-
- $target_item = $arr['target_item'];
-
- if($target_item && array_key_exists('item_flags',$target_item) && ($target_item['item_flags'] & ITEM_OBSCURED)) {
- $key = get_config('system','prvkey');
- if($target_item['title'])
- $target_item['title'] = crypto_unencapsulate(json_decode($target_item['title'],true),$key);
- if($target_item['body'])
- $target_item['body'] = crypto_unencapsulate(json_decode($target_item['body'],true),$key);
- }
-
-
-
- if($arr['env_recips']) {
- $hashes = array();
-
- // re-explode the recipients, but only for this hub/pod
-
- foreach($arr['env_recips'] as $recip)
- $hashes[] = "'" . $recip['hash'] . "'";
-
- $r = q("select * from xchan left join hubloc on xchan_hash = hubloc_hash where hubloc_url = '%s'
- and xchan_hash in (" . implode(',', $hashes) . ") and xchan_network in ('diaspora', 'friendica-over-diaspora') ",
- dbesc($arr['hub']['hubloc_url'])
- );
-
- if(! $r) {
- logger('diaspora_process_outbound: no recipients');
- return;
- }
-
- foreach($r as $contact) {
-
- if($arr['mail']) {
- diaspora_send_mail($arr['item'],$arr['channel'],$contact);
- continue;
- }
-
- if(! $arr['normal_mode'])
- continue;
-
- // special handling for followup to public post
- // all other public posts processed as public batches further below
-
- if((! $arr['private']) && ($arr['followup'])) {
- diaspora_send_followup($target_item,$arr['channel'],$contact, true);
- continue;
- }
-
- if(! $contact['xchan_pubkey'])
- continue;
-
- if(($target_item['item_restrict'] & ITEM_DELETED)
- && (($target_item['mid'] === $target_item['parent_mid']) || $arr['followup'])) {
- // send both top-level retractions and relayable retractions for owner to relay
- diaspora_send_retraction($target_item,$arr['channel'],$contact);
- continue;
- }
- elseif($arr['followup']) {
- // send comments and likes to owner to relay
- diaspora_send_followup($target_item,$arr['channel'],$contact);
- continue;
- }
-
- elseif($target_item['mid'] !== $target_item['parent_mid']) {
- // we are the relay - send comments, likes and relayable_retractions
- // (of comments and likes) to our conversants
- diaspora_send_relay($target_item,$arr['channel'],$contact);
- continue;
- }
- elseif($arr['top_level_post']) {
- diaspora_send_status($target_item,$arr['channel'],$contact);
- continue;
- }
- }
- }
- else {
- // public message
-
- $contact = $arr['hub'];
-
- if(($target_item['deleted'])
- && ($target_item['mid'] === $target_item['parent_mod'])) {
- // top-level retraction
- logger('delivery: diaspora retract: ' . $loc);
- diaspora_send_retraction($target_item,$arr['channel'],$contact,true);
- return;
- }
- elseif($target_item['mid'] !== $target_item['parent_mid']) {
- // we are the relay - send comments, likes and relayable_retractions to our conversants
- logger('delivery: diaspora relay: ' . $loc);
- diaspora_send_relay($target_item,$arr['channel'],$contact,true);
- return;
- }
- elseif($arr['top_level_post']) {
- logger('delivery: diaspora status: ' . $loc);
- diaspora_send_status($target_item,$arr['channel'],$contact,true);
- return;
- }
-
- }
-
-}
-
-
-function diaspora_handle_from_contact($contact_hash) {
-
- logger("diaspora_handle_from_contact: contact id is " . $contact_hash, LOGGER_DEBUG);
-
- $r = q("SELECT xchan_addr from xchan where xchan_hash = '%s' limit 1",
- dbesc($contact_hash)
- );
- if($r) {
- return $r[0]['xchan_addr'];
- }
- return false;
-}
-
-function diaspora_get_contact_by_handle($uid,$handle) {
-
- if(diaspora_is_blacklisted($handle))
- return false;
- require_once('include/identity.php');
-
- $sys = get_sys_channel();
- if(($sys) && ($sys['channel_id'] == $uid)) {
- $r = q("SELECT * FROM xchan where xchan_addr = '%s' limit 1",
- dbesc($handle)
- );
- }
- else {
- $r = q("SELECT * FROM abook left join xchan on xchan_hash = abook_xchan where xchan_addr = '%s' and abook_channel = %d limit 1",
- dbesc($handle),
- intval($uid)
- );
- }
-
- return (($r) ? $r[0] : false);
-}
-
-function find_diaspora_person_by_handle($handle) {
-
- $person = false;
-
- if(diaspora_is_blacklisted($handle))
- return false;
-
- $r = q("select * from xchan where xchan_addr = '%s' limit 1",
- dbesc($handle)
- );
- if($r) {
- $person = $r[0];
- logger('find_diaspora_person_by handle: in cache ' . print_r($r,true), LOGGER_DATA);
- }
-
- if(! $person) {
-
- // try webfinger. Make sure to distinguish between diaspora,
- // redmatrix w/diaspora protocol and friendica w/diaspora protocol.
-
- $result = discover_by_webbie($handle);
- if($result) {
- $r = q("select * from xchan where xchan_addr = '%s' limit 1",
- dbesc($handle)
- );
- if($r) {
- $person = $r[0];
- logger('find_diaspora_person_by handle: discovered ' . print_r($r,true), LOGGER_DATA);
- }
- }
- }
-
- return $person;
-}
-
-
-function get_diaspora_key($handle) {
- logger('Fetching diaspora key for: ' . $handle, LOGGER_DEBUG);
- $r = find_diaspora_person_by_handle($handle);
- return(($r) ? $r['xchan_pubkey'] : '');
-}
-
-
-function diaspora_pubmsg_build($msg,$channel,$contact,$prvkey,$pubkey) {
-
- $a = get_app();
-
- logger('diaspora_pubmsg_build: ' . $msg, LOGGER_DATA);
-
- $handle = $channel['channel_address'] . '@' . get_app()->get_hostname();
-
-
- $b64url_data = base64url_encode($msg,false);
-
- $data = str_replace(array("\n","\r"," ","\t"),array('','','',''),$b64url_data);
-
- $type = 'application/xml';
- $encoding = 'base64url';
- $alg = 'RSA-SHA256';
-
- $signable_data = $data . '.' . base64url_encode($type,false) . '.'
- . base64url_encode($encoding,false) . '.' . base64url_encode($alg,false) ;
-
- $signature = rsa_sign($signable_data,$prvkey);
- $sig = base64url_encode($signature,false);
-
-$magic_env = <<< EOT
-<?xml version='1.0' encoding='UTF-8'?>
-<diaspora xmlns="https://joindiaspora.com/protocol" xmlns:me="http://salmon-protocol.org/ns/magic-env" >
- <header>
- <author_id>$handle</author_id>
- </header>
- <me:env>
- <me:encoding>base64url</me:encoding>
- <me:alg>RSA-SHA256</me:alg>
- <me:data type="application/xml">$data</me:data>
- <me:sig>$sig</me:sig>
- </me:env>
-</diaspora>
-EOT;
-
- logger('diaspora_pubmsg_build: magic_env: ' . $magic_env, LOGGER_DATA);
- return $magic_env;
-
-}
-
-
-
-
-function diaspora_msg_build($msg,$channel,$contact,$prvkey,$pubkey,$public = false) {
- $a = get_app();
-
- if($public)
- return diaspora_pubmsg_build($msg,$channel,$contact,$prvkey,$pubkey);
-
- logger('diaspora_msg_build: ' . $msg, LOGGER_DATA);
-
- // without a public key nothing will work
-
- if(! $pubkey) {
- logger('diaspora_msg_build: pubkey missing: contact id: ' . $contact['abook_id']);
- return '';
- }
-
- $inner_aes_key = random_string(32);
- $b_inner_aes_key = base64_encode($inner_aes_key);
- $inner_iv = random_string(16);
- $b_inner_iv = base64_encode($inner_iv);
-
- $outer_aes_key = random_string(32);
- $b_outer_aes_key = base64_encode($outer_aes_key);
- $outer_iv = random_string(16);
- $b_outer_iv = base64_encode($outer_iv);
-
- $handle = $channel['channel_address'] . '@' . get_app()->get_hostname();
-
- $padded_data = pkcs5_pad($msg,16);
- $inner_encrypted = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $inner_aes_key, $padded_data, MCRYPT_MODE_CBC, $inner_iv);
-
- $b64_data = base64_encode($inner_encrypted);
-
-
- $b64url_data = base64url_encode($b64_data,false);
- $data = str_replace(array("\n","\r"," ","\t"),array('','','',''),$b64url_data);
-
- $type = 'application/xml';
- $encoding = 'base64url';
- $alg = 'RSA-SHA256';
-
- $signable_data = $data . '.' . base64url_encode($type,false) . '.'
- . base64url_encode($encoding,false) . '.' . base64url_encode($alg,false) ;
-
- logger('diaspora_msg_build: signable_data: ' . $signable_data, LOGGER_DATA);
-
- $signature = rsa_sign($signable_data,$prvkey);
- $sig = base64url_encode($signature,false);
-
-$decrypted_header = <<< EOT
-<decrypted_header>
- <iv>$b_inner_iv</iv>
- <aes_key>$b_inner_aes_key</aes_key>
- <author_id>$handle</author_id>
-</decrypted_header>
-EOT;
-
- $decrypted_header = pkcs5_pad($decrypted_header,16);
-
- $ciphertext = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $outer_aes_key, $decrypted_header, MCRYPT_MODE_CBC, $outer_iv);
-
- $outer_json = json_encode(array('iv' => $b_outer_iv,'key' => $b_outer_aes_key));
-
- $encrypted_outer_key_bundle = '';
- openssl_public_encrypt($outer_json,$encrypted_outer_key_bundle,$pubkey);
-
- $b64_encrypted_outer_key_bundle = base64_encode($encrypted_outer_key_bundle);
-
- logger('outer_bundle: ' . $b64_encrypted_outer_key_bundle . ' key: ' . $pubkey, LOGGER_DATA);
-
- $encrypted_header_json_object = json_encode(array('aes_key' => base64_encode($encrypted_outer_key_bundle),
- 'ciphertext' => base64_encode($ciphertext)));
- $cipher_json = base64_encode($encrypted_header_json_object);
-
- $encrypted_header = '<encrypted_header>' . $cipher_json . '</encrypted_header>';
-
-$magic_env = <<< EOT
-<?xml version='1.0' encoding='UTF-8'?>
-<diaspora xmlns="https://joindiaspora.com/protocol" xmlns:me="http://salmon-protocol.org/ns/magic-env" >
- $encrypted_header
- <me:env>
- <me:encoding>base64url</me:encoding>
- <me:alg>RSA-SHA256</me:alg>
- <me:data type="application/xml">$data</me:data>
- <me:sig>$sig</me:sig>
- </me:env>
-</diaspora>
-EOT;
-
- logger('diaspora_msg_build: magic_env: ' . $magic_env, LOGGER_DATA);
- return $magic_env;
-
-}
-
-/**
- *
- * diaspora_decode($importer,$xml)
- * array $importer -> from user table
- * string $xml -> urldecoded Diaspora salmon
- *
- * Returns array
- * 'message' -> decoded Diaspora XML message
- * 'author' -> author diaspora handle
- * 'key' -> author public key (converted to pkcs#8)
- *
- * Author and key are used elsewhere to save a lookup for verifying replies and likes
- */
-
-
-function diaspora_decode($importer,$xml) {
-
- $public = false;
- $basedom = parse_xml_string($xml);
-
- $children = $basedom->children('https://joindiaspora.com/protocol');
-
- if($children->header) {
- $public = true;
- $author_link = str_replace('acct:','',$children->header->author_id);
- }
- else {
-
- $encrypted_header = json_decode(base64_decode($children->encrypted_header));
-
- $encrypted_aes_key_bundle = base64_decode($encrypted_header->aes_key);
- $ciphertext = base64_decode($encrypted_header->ciphertext);
-
- $outer_key_bundle = '';
- openssl_private_decrypt($encrypted_aes_key_bundle,$outer_key_bundle,$importer['channel_prvkey']);
-
- $j_outer_key_bundle = json_decode($outer_key_bundle);
-
- $outer_iv = base64_decode($j_outer_key_bundle->iv);
- $outer_key = base64_decode($j_outer_key_bundle->key);
-
- $decrypted = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $outer_key, $ciphertext, MCRYPT_MODE_CBC, $outer_iv);
-
-
- $decrypted = pkcs5_unpad($decrypted);
-
- /**
- * $decrypted now contains something like
- *
- * <decrypted_header>
- * <iv>8e+G2+ET8l5BPuW0sVTnQw==</iv>
- * <aes_key>UvSMb4puPeB14STkcDWq+4QE302Edu15oaprAQSkLKU=</aes_key>
-
-***** OBSOLETE
-
- * <author>
- * <name>Ryan Hughes</name>
- * <uri>acct:galaxor@diaspora.pirateship.org</uri>
- * </author>
-
-***** CURRENT
-
- * <author_id>galaxor@diaspora.priateship.org</author_id>
-
-***** END DIFFS
-
- * </decrypted_header>
- */
-
- logger('decrypted: ' . $decrypted, LOGGER_DATA);
- $idom = parse_xml_string($decrypted,false);
-
- $inner_iv = base64_decode($idom->iv);
- $inner_aes_key = base64_decode($idom->aes_key);
-
- $author_link = str_replace('acct:','',$idom->author_id);
-
- }
-
- $dom = $basedom->children(NAMESPACE_SALMON_ME);
-
- // figure out where in the DOM tree our data is hiding
-
- if($dom->provenance->data)
- $base = $dom->provenance;
- elseif($dom->env->data)
- $base = $dom->env;
- elseif($dom->data)
- $base = $dom;
-
- if(! $base) {
- logger('mod-diaspora: unable to locate salmon data in xml ');
- http_status_exit(400);
- }
-
-
- // Stash the signature away for now. We have to find their key or it won't be good for anything.
- $signature = base64url_decode($base->sig);
-
- // unpack the data
-
- // strip whitespace so our data element will return to one big base64 blob
- $data = str_replace(array(" ","\t","\r","\n"),array("","","",""),$base->data);
-
-
- // stash away some other stuff for later
-
- $type = $base->data[0]->attributes()->type[0];
- $keyhash = $base->sig[0]->attributes()->keyhash[0];
- $encoding = $base->encoding;
- $alg = $base->alg;
-
- $signed_data = $data . '.' . base64url_encode($type,false) . '.' . base64url_encode($encoding,false) . '.' . base64url_encode($alg,false);
-
-
- // decode the data
- $data = base64url_decode($data);
-
-
- if($public) {
- $inner_decrypted = $data;
- }
- else {
-
- // Decode the encrypted blob
-
- $inner_encrypted = base64_decode($data);
- $inner_decrypted = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $inner_aes_key, $inner_encrypted, MCRYPT_MODE_CBC, $inner_iv);
- $inner_decrypted = pkcs5_unpad($inner_decrypted);
- }
-
- if(! $author_link) {
- logger('mod-diaspora: Could not retrieve author URI.');
- http_status_exit(400);
- }
-
- // Once we have the author URI, go to the web and try to find their public key
- // (first this will look it up locally if it is in the fcontact cache)
- // This will also convert diaspora public key from pkcs#1 to pkcs#8
-
- logger('mod-diaspora: Fetching key for ' . $author_link );
- $key = get_diaspora_key($author_link);
-
- if(! $key) {
- logger('mod-diaspora: Could not retrieve author key.');
- http_status_exit(400);
- }
-
- $verify = rsa_verify($signed_data,$signature,$key);
-
- if(! $verify) {
- logger('mod-diaspora: Message did not verify. Discarding.');
- http_status_exit(400);
- }
-
- logger('mod-diaspora: Message verified.');
-
- return array('message' => $inner_decrypted, 'author' => $author_link, 'key' => $key);
-
-}
-
-
-/* sender is now sharing with recipient */
-
-function diaspora_request($importer,$xml) {
-
- $a = get_app();
-
- $sender_handle = unxmlify($xml->sender_handle);
- $recipient_handle = unxmlify($xml->recipient_handle);
-
- if(! $sender_handle || ! $recipient_handle)
- return;
-
-
- // Do we already have an abook record?
-
- $contact = diaspora_get_contact_by_handle($importer['channel_id'],$sender_handle);
-
- if($contact && $contact['abook_id']) {
-
- // perhaps we were already sharing with this person. Now they're sharing with us.
- // That makes us friends. Maybe.
-
- // Please note some of these permissions such as PERMS_R_PAGES are impossible for Disapora.
- // They cannot authenticate to our system.
-
- $newperms = PERMS_R_STREAM|PERMS_R_PROFILE|PERMS_R_PHOTOS|PERMS_R_ABOOK|PERMS_W_STREAM|PERMS_W_COMMENT|PERMS_W_MAIL|PERMS_W_CHAT|PERMS_R_STORAGE|PERMS_R_PAGES;
-
- $r = q("update abook set abook_their_perms = %d where abook_id = %d and abook_channel = %d",
- intval($newperms),
- intval($contact['abook_id']),
- intval($importer['channel_id'])
- );
-
- return;
- }
-
- $ret = find_diaspora_person_by_handle($sender_handle);
-
- if((! $ret) || (! strstr($ret['xchan_network'],'diaspora'))) {
- logger('diaspora_request: Cannot resolve diaspora handle ' . $sender_handle . ' for ' . $recipient_handle);
- return;
- }
-
-
-//FIXME
-/*
- if(feature_enabled($channel['channel_id'],'premium_channel')) {
- $myaddr = $importer['channel_address'] . '@' . get_app()->get_hostname();
- $cnv = random_string();
- $mid = random_string();
-
- $msg = t('You have started sharing with a $Projectname premium channel.');
- $msg .= t('$Projectname premium channels are not available for sharing with Diaspora members. This sharing request has been blocked.') . "\r";
- $msg .= t('Please do not reply to this message, as this channel is not sharing with you and any reply will not be seen by the recipient.') . "\r";
-
- $created = datetime_convert('UTC','UTC',$item['created'],'Y-m-d H:i:s \U\T\C');
- $signed_text = $mid . ';' . $cnv . ';' . $msg . ';'
- . $created . ';' . $myaddr . ';' . $cnv;
-
- $sig = base64_encode(rsa_sign($signed_text,$importer['channel_prvkey'],'sha256'));
-
- $conv = array(
- 'guid' => xmlify($cnv),
- 'subject' => xmlify(t('Sharing request failed.')),
- 'created_at' => xmlify($created),
- 'diaspora_handle' => xmlify($myaddr),
- 'participant_handles' => xmlify($myaddr . ';' . $sender_handle)
- );
-
- $msg = array(
- 'guid' => xmlify($mid),
- 'parent_guid' => xmlify($cnv),
- 'parent_author_signature' => xmlify($sig),
- 'author_signature' => xmlify($sig),
- 'text' => xmlify($msg),
- 'created_at' => xmlify($created),
- 'diaspora_handle' => xmlify($myaddr),
- 'conversation_guid' => xmlify($cnv)
- );
-
- $conv['messages'] = array($msg);
- $tpl = get_markup_template('diaspora_conversation.tpl');
- $xmsg = replace_macros($tpl, array('$conv' => $conv));
-
- $slap = 'xml=' . urlencode(urlencode(diaspora_msg_build($xmsg,$importer,$ret,$importer['channel_prvkey'],$ret['xchan_pubkey'],false)));
-
- diaspora_transmit($importer,$ret,$slap,false);
- return;
- }
-
-*/
-// End FIXME
-
-
- $role = get_pconfig($channel['channel_id'],'system','permissions_role');
- if($role) {
- $x = get_role_perms($role);
- if($x['perms_auto'])
- $default_perms = $x['perms_accept'];
- }
- if(! $default_perms)
- $default_perms = intval(get_pconfig($importer['channel_id'],'system','autoperms'));
-
- $their_perms = PERMS_R_STREAM|PERMS_R_PROFILE|PERMS_R_PHOTOS|PERMS_R_ABOOK|PERMS_W_STREAM|PERMS_W_COMMENT|PERMS_W_MAIL|PERMS_W_CHAT|PERMS_R_STORAGE|PERMS_R_PAGES;
-
-
- $closeness = get_pconfig($importer['channel_id'],'system','new_abook_closeness');
- if($closeness === false)
- $closeness = 80;
-
-
- $r = q("insert into abook ( abook_account, abook_channel, abook_xchan, abook_my_perms, abook_their_perms, abook_closeness, abook_rating, abook_created, abook_updated, abook_connected, abook_dob, abook_flags) values ( %d, %d, '%s', %d, %d, %d, %d, '%s', '%s', '%s', '%s', %d )",
- intval($importer['channel_account_id']),
- intval($importer['channel_id']),
- dbesc($ret['xchan_hash']),
- intval($default_perms),
- intval($their_perms),
- intval($closeness),
- intval(0),
- dbesc(datetime_convert()),
- dbesc(datetime_convert()),
- dbesc(datetime_convert()),
- dbesc(NULL_DATE),
- intval(($default_perms) ? 0 : ABOOK_FLAG_PENDING)
- );
-
-
- if($r) {
- logger("New Diaspora introduction received for {$importer['channel_name']}");
-
- $new_connection = q("select * from abook left join xchan on abook_xchan = xchan_hash left join hubloc on hubloc_hash = xchan_hash where abook_channel = %d and abook_xchan = '%s' order by abook_created desc limit 1",
- intval($importer['channel_id']),
- dbesc($ret['xchan_hash'])
- );
- if($new_connection) {
- require_once('include/enotify.php');
- notification(array(
- 'type' => NOTIFY_INTRO,
- 'from_xchan' => $ret['xchan_hash'],
- 'to_xchan' => $importer['channel_hash'],
- 'link' => z_root() . '/connedit/' . $new_connection[0]['abook_id'],
- ));
-
-
- if($default_perms) {
- // Send back a sharing notification to them
- diaspora_share($importer,$new_connection[0]);
-
- }
-
- $clone = array();
- foreach($new_connection[0] as $k => $v) {
- if(strpos($k,'abook_') === 0) {
- $clone[$k] = $v;
- }
- }
- unset($clone['abook_id']);
- unset($clone['abook_account']);
- unset($clone['abook_channel']);
-
- build_sync_packet($importer['channel_id'], array('abook' => array($clone)));
-
- }
- }
-
- // find the abook record we just created
-
- $contact_record = diaspora_get_contact_by_handle($importer['channel_id'],$sender_handle);
-
- if(! $contact_record) {
- logger('diaspora_request: unable to locate newly created contact record.');
- return;
- }
-
- /** If there is a default group for this channel, add this member to it */
-
- if($importer['channel_default_group']) {
- require_once('include/group.php');
- $g = group_rec_byhash($importer['channel_id'],$importer['channel_default_group']);
- if($g)
- group_add_member($importer['channel_id'],'',$contact_record['xchan_hash'],$g['id']);
- }
-
- return;
-}
-
-
-
-function diaspora_post($importer,$xml,$msg) {
-
- $a = get_app();
- $guid = notags(unxmlify($xml->guid));
- $diaspora_handle = notags(unxmlify($xml->diaspora_handle));
- $app = notags(xmlify($xml->provider_display_name));
-
-
- if($diaspora_handle != $msg['author']) {
- logger('diaspora_post: Potential forgery. Message handle is not the same as envelope sender.');
- return 202;
- }
-
- $contact = diaspora_get_contact_by_handle($importer['channel_id'],$diaspora_handle);
- if(! $contact)
- return;
-
-
-
- if(! $app) {
- if(strstr($contact['xchan_network'],'friendica'))
- $app = 'Friendica';
- else
- $app = 'Diaspora';
- }
-
-
- $search_guid = ((strlen($guid) == 64) ? $guid . '%' : $guid);
-
- $r = q("SELECT id FROM item WHERE uid = %d AND mid like '%s' LIMIT 1",
- intval($importer['channel_id']),
- dbesc($search_guid)
- );
-
- if($r) {
- // check dates if post editing is implemented
- logger('diaspora_post: message exists: ' . $guid);
- return;
- }
-
- $created = unxmlify($xml->created_at);
- $private = ((unxmlify($xml->public) == 'false') ? 1 : 0);
-
- $body = diaspora2bb($xml->raw_message);
-
- if($xml->photo) {
- $body = '[img]' . $xml->photo->remote_photo_path . $xml->photo->remote_photo_name . '[/img]' . "\n\n" . $body;
- $body = scale_external_images($body);
- }
-
- $maxlen = get_max_import_size();
-
- if($maxlen && mb_strlen($body) > $maxlen) {
- $body = mb_substr($body,0,$maxlen,'UTF-8');
- logger('message length exceeds max_import_size: truncated');
- }
-
-//WTF? FIXME
- // Add OEmbed and other information to the body
-// $body = add_page_info_to_body($body, false, true);
-
- $datarray = array();
-
-
- // Look for tags and linkify them
- $results = linkify_tags(get_app(), $body, $importer['channel_id'], true);
-
- $datarray['term'] = array();
-
- if($results) {
- foreach($results as $result) {
- $success = $result['success'];
- if($success['replaced']) {
- $datarray['term'][] = array(
- 'uid' => $importer['channel_id'],
- 'type' => $success['termtype'],
- 'otype' => TERM_OBJ_POST,
- 'term' => $success['term'],
- 'url' => $success['url']
- );
- }
- }
- }
-
- $cnt = preg_match_all('/@\[url=(.*?)\](.*?)\[\/url\]/ism',$body,$matches,PREG_SET_ORDER);
- if($cnt) {
- foreach($matches as $mtch) {
- $datarray['term'][] = array(
- 'uid' => $importer['channel_id'],
- 'type' => TERM_MENTION,
- 'otype' => TERM_OBJ_POST,
- 'term' => $mtch[2],
- 'url' => $mtch[1]
- );
- }
- }
-
- $cnt = preg_match_all('/@\[zrl=(.*?)\](.*?)\[\/zrl\]/ism',$body,$matches,PREG_SET_ORDER);
- if($cnt) {
- foreach($matches as $mtch) {
- // don't include plustags in the term
- $term = ((substr($mtch[2],-1,1) === '+') ? substr($mtch[2],0,-1) : $mtch[2]);
- $datarray['term'][] = array(
- 'uid' => $importer['channel_id'],
- 'type' => TERM_MENTION,
- 'otype' => TERM_OBJ_POST,
- 'term' => $term,
- 'url' => $mtch[1]
- );
- }
- }
-
-
-
-
- $plink = service_plink($contact,$guid);
-
-
- $datarray['uid'] = $importer['channel_id'];
-
- $datarray['verb'] = ACTIVITY_POST;
- $datarray['mid'] = $datarray['parent_mid'] = $guid;
-
- $datarray['changed'] = $datarray['created'] = $datarray['edited'] = datetime_convert('UTC','UTC',$created);
- $datarray['item_private'] = $private;
-
- $datarray['plink'] = $plink;
-
- $datarray['author_xchan'] = $contact['xchan_hash'];
- $datarray['owner_xchan'] = $contact['xchan_hash'];
-
- $datarray['body'] = $body;
-
- $datarray['app'] = $app;
-
- $datarray['item_flags'] = ITEM_THREAD_TOP;
- $datarray['item_unseen'] = 1;
-
-
- $tgroup = tgroup_check($importer['channel_id'],$datarray);
-
- if((! $importer['system']) && (! perm_is_allowed($importer['channel_id'],$contact['xchan_hash'],'send_stream')) && (! $tgroup)) {
- logger('diaspora_post: Ignoring this author.');
- return 202;
- }
-
- if(! post_is_importable($datarray,$contact)) {
- logger('diaspora_post: filtering this author.');
- return 202;
- }
-
- $result = item_store($datarray);
- return;
-
-}
-
-
-function get_diaspora_reshare_xml($url,$recurse = 0) {
-
- $x = z_fetch_url($url);
- if(! $x['success'])
- $x = z_fetch_url(str_replace('https://','http://',$url));
- if(! $x['success']) {
- logger('get_diaspora_reshare_xml: unable to fetch source url ' . $url);
- return;
- }
- logger('get_diaspora_reshare_xml: source: ' . $x['body'], LOGGER_DEBUG);
-
- $source_xml = parse_xml_string($x['body'],false);
-
- if(! $source_xml) {
- logger('get_diaspora_reshare_xml: unparseable result from ' . $url);
- return '';
- }
-
- if($source_xml->post->status_message) {
- return $source_xml;
- }
-
- // see if it's a reshare of a reshare
-
- if($source_xml->post->reshare)
- $xml = $source_xml->post->reshare;
- else
- return false;
-
- if($xml->root_diaspora_id && $xml->root_guid && $recurse < 15) {
- $orig_author = notags(unxmlify($xml->root_diaspora_id));
- $orig_guid = notags(unxmlify($xml->root_guid));
- $source_url = 'https://' . substr($orig_author,strpos($orig_author,'@')+1) . '/p/' . $orig_guid . '.xml';
- $y = get_diaspora_reshare_xml($source_url,$recurse+1);
- if($y)
- return $y;
- }
- return false;
-}
-
-
-
-function diaspora_reshare($importer,$xml,$msg) {
-
- logger('diaspora_reshare: init: ' . print_r($xml,true), LOGGER_DATA);
-
- $a = get_app();
- $guid = notags(unxmlify($xml->guid));
- $diaspora_handle = notags(unxmlify($xml->diaspora_handle));
-
-
- if($diaspora_handle != $msg['author']) {
- logger('diaspora_post: Potential forgery. Message handle is not the same as envelope sender.');
- return 202;
- }
-
- $contact = diaspora_get_contact_by_handle($importer['channel_id'],$diaspora_handle);
- if(! $contact)
- return;
-
- $search_guid = ((strlen($guid) == 64) ? $guid . '%' : $guid);
- $r = q("SELECT id FROM item WHERE uid = %d AND mid like '%s' LIMIT 1",
- intval($importer['channel_id']),
- dbesc($search_guid)
- );
- if($r) {
- logger('diaspora_reshare: message exists: ' . $guid);
- return;
- }
-
- $orig_author = notags(unxmlify($xml->root_diaspora_id));
- $orig_guid = notags(unxmlify($xml->root_guid));
-
- $source_url = 'https://' . substr($orig_author,strpos($orig_author,'@')+1) . '/p/' . $orig_guid . '.xml';
- $orig_url = 'https://'.substr($orig_author,strpos($orig_author,'@')+1).'/posts/'.$orig_guid;
-
- $source_xml = get_diaspora_reshare_xml($source_url);
-
- if($source_xml->post->status_message) {
- $body = diaspora2bb($source_xml->post->status_message->raw_message);
-
- $orig_author = notags(unxmlify($source_xml->post->status_message->diaspora_handle));
- $orig_guid = notags(unxmlify($source_xml->post->status_message->guid));
-
-
- // Checking for embedded pictures
- if($source_xml->post->status_message->photo->remote_photo_path &&
- $source_xml->post->status_message->photo->remote_photo_name) {
-
- $remote_photo_path = notags(unxmlify($source_xml->post->status_message->photo->remote_photo_path));
- $remote_photo_name = notags(unxmlify($source_xml->post->status_message->photo->remote_photo_name));
-
- $body = '[img]'.$remote_photo_path.$remote_photo_name.'[/img]'."\n".$body;
-
- logger('diaspora_reshare: embedded picture link found: '.$body, LOGGER_DEBUG);
- }
-
- $body = scale_external_images($body);
-
- // Add OEmbed and other information to the body
-// $body = add_page_info_to_body($body, false, true);
- }
- else {
- // Maybe it is a reshare of a photo that will be delivered at a later time (testing)
- logger('diaspora_reshare: no reshare content found: ' . print_r($source_xml,true));
- $body = "";
- //return;
- }
-
- $maxlen = get_max_import_size();
-
- if($maxlen && mb_strlen($body) > $maxlen) {
- $body = mb_substr($body,0,$maxlen,'UTF-8');
- logger('message length exceeds max_import_size: truncated');
- }
-
- $person = find_diaspora_person_by_handle($orig_author);
-
- if($person) {
- $orig_author_name = $person['xchan_name'];
- $orig_author_link = $person['xchan_url'];
- $orig_author_photo = $person['xchan_photo_m'];
- }
-
-
- $created = unxmlify($xml->created_at);
- $private = ((unxmlify($xml->public) == 'false') ? 1 : 0);
-
- $datarray = array();
-
- // Look for tags and linkify them
- $results = linkify_tags(get_app(), $body, $importer['channel_id'], true);
-
- $datarray['term'] = array();
-
- if($results) {
- foreach($results as $result) {
- $success = $result['success'];
- if($success['replaced']) {
- $datarray['term'][] = array(
- 'uid' => $importer['channel_id'],
- 'type' => $success['termtype'],
- 'otype' => TERM_OBJ_POST,
- 'term' => $success['term'],
- 'url' => $success['url']
- );
- }
- }
- }
-
- $cnt = preg_match_all('/@\[url=(.*?)\](.*?)\[\/url\]/ism',$body,$matches,PREG_SET_ORDER);
- if($cnt) {
- foreach($matches as $mtch) {
- $datarray['term'][] = array(
- 'uid' => $importer['channel_id'],
- 'type' => TERM_MENTION,
- 'otype' => TERM_OBJ_POST,
- 'term' => $mtch[2],
- 'url' => $mtch[1]
- );
- }
- }
-
- $cnt = preg_match_all('/@\[zrl=(.*?)\](.*?)\[\/zrl\]/ism',$body,$matches,PREG_SET_ORDER);
- if($cnt) {
- foreach($matches as $mtch) {
- // don't include plustags in the term
- $term = ((substr($mtch[2],-1,1) === '+') ? substr($mtch[2],0,-1) : $mtch[2]);
- $datarray['term'][] = array(
- 'uid' => $importer['channel_id'],
- 'type' => TERM_MENTION,
- 'otype' => TERM_OBJ_POST,
- 'term' => $term,
- 'url' => $mtch[1]
- );
- }
- }
-
-
-
-
-
- $newbody = "[share author='" . urlencode($orig_author_name)
- . "' profile='" . $orig_author_link
- . "' avatar='" . $orig_author_photo
- . "' link='" . $orig_url
- . "' posted='" . datetime_convert('UTC','UTC',unxmlify($source_xml->post->status_message->created_at))
- . "' message_id='" . unxmlify($source_xml->post->status_message->guid)
- . "']" . $body . "[/share]";
-
-
- $plink = service_plink($contact,$guid);
-
- $datarray['uid'] = $importer['channel_id'];
- $datarray['mid'] = $datarray['parent_mid'] = $guid;
- $datarray['changed'] = $datarray['created'] = $datarray['edited'] = datetime_convert('UTC','UTC',$created);
- $datarray['item_private'] = $private;
- $datarray['plink'] = $plink;
- $datarray['owner_xchan'] = $contact['xchan_hash'];
- $datarray['author_xchan'] = $contact['xchan_hash'];
-
- $datarray['body'] = $newbody;
- $datarray['app'] = 'Diaspora';
-
-
-
- $tgroup = tgroup_check($importer['channel_id'],$datarray);
-
- if((! $importer['system']) && (! perm_is_allowed($importer['channel_id'],$contact['xchan_hash'],'send_stream')) && (! $tgroup)) {
- logger('diaspora_post: Ignoring this author.');
- return 202;
- }
-
-
- $result = item_store($datarray);
-
- return;
-
-}
-
-
-function diaspora_asphoto($importer,$xml,$msg) {
- logger('diaspora_asphoto called');
-
- $a = get_app();
- $guid = notags(unxmlify($xml->guid));
- $diaspora_handle = notags(unxmlify($xml->diaspora_handle));
-
- if($diaspora_handle != $msg['author']) {
- logger('diaspora_post: Potential forgery. Message handle is not the same as envelope sender.');
- return 202;
- }
-
- $contact = diaspora_get_contact_by_handle($importer['channel_id'],$diaspora_handle);
- if(! $contact)
- return;
-
- if((! $importer['system']) && (! perm_is_allowed($importer['channel_id'],$contact['xchan_hash'],'send_stream'))) {
- logger('diaspora_asphoto: Ignoring this author.');
- return 202;
- }
-
- $message_id = $diaspora_handle . ':' . $guid;
- $r = q("SELECT `id` FROM `item` WHERE `uid` = %d AND `uri` = '%s' AND `guid` = '%s' LIMIT 1",
- intval($importer['channel_id']),
- dbesc($message_id),
- dbesc($guid)
- );
- if(count($r)) {
- logger('diaspora_asphoto: message exists: ' . $guid);
- return;
- }
-
- // allocate a guid on our system - we aren't fixing any collisions.
- // we're ignoring them
-
- $g = q("select * from guid where guid = '%s' limit 1",
- dbesc($guid)
- );
- if(! count($g)) {
- q("insert into guid ( guid ) values ( '%s' )",
- dbesc($guid)
- );
- }
-
- $created = unxmlify($xml->created_at);
- $private = ((unxmlify($xml->public) == 'false') ? 1 : 0);
-
- if(strlen($xml->objectId) && ($xml->objectId != 0) && ($xml->image_url)) {
- $body = '[url=' . notags(unxmlify($xml->image_url)) . '][img]' . notags(unxmlify($xml->objectId)) . '[/img][/url]' . "\n";
- $body = scale_external_images($body,false);
- }
- elseif($xml->image_url) {
- $body = '[img]' . notags(unxmlify($xml->image_url)) . '[/img]' . "\n";
- $body = scale_external_images($body);
- }
- else {
- logger('diaspora_asphoto: no photo url found.');
- return;
- }
-
- $plink = service_plink($contact,$guid);
-
- $datarray = array();
-
- $datarray['uid'] = $importer['channel_id'];
- $datarray['contact-id'] = $contact['id'];
- $datarray['wall'] = 0;
- $datarray['network'] = NETWORK_DIASPORA;
- $datarray['guid'] = $guid;
- $datarray['uri'] = $datarray['parent-uri'] = $message_id;
- $datarray['changed'] = $datarray['created'] = $datarray['edited'] = datetime_convert('UTC','UTC',$created);
- $datarray['private'] = $private;
- $datarray['parent'] = 0;
- $datarray['plink'] = $plink;
- $datarray['owner-name'] = $contact['name'];
- $datarray['owner-link'] = $contact['url'];
- //$datarray['owner-avatar'] = $contact['thumb'];
- $datarray['owner-avatar'] = ((x($contact,'thumb')) ? $contact['thumb'] : $contact['photo']);
- $datarray['author-name'] = $contact['name'];
- $datarray['author-link'] = $contact['url'];
- $datarray['author-avatar'] = $contact['thumb'];
- $datarray['body'] = $body;
-
- $datarray['app'] = 'Diaspora/Cubbi.es';
-
- $message_id = item_store($datarray);
-
- //if($message_id) {
- // q("update item set plink = '%s' where id = %d",
- // dbesc($a->get_baseurl() . '/display/' . $importer['nickname'] . '/' . $message_id),
- // intval($message_id)
- // );
- //}
-
- return;
-
-}
-
-
-
-
-
-
-function diaspora_comment($importer,$xml,$msg) {
-
- $a = get_app();
- $guid = notags(unxmlify($xml->guid));
- $parent_guid = notags(unxmlify($xml->parent_guid));
- $diaspora_handle = notags(unxmlify($xml->diaspora_handle));
- $target_type = notags(unxmlify($xml->target_type));
- $text = unxmlify($xml->text);
- $author_signature = notags(unxmlify($xml->author_signature));
-
- $parent_author_signature = (($xml->parent_author_signature) ? notags(unxmlify($xml->parent_author_signature)) : '');
-
- $contact = diaspora_get_contact_by_handle($importer['channel_id'],$msg['author']);
- if(! $contact) {
- logger('diaspora_comment: cannot find contact: ' . $msg['author']);
- return;
- }
-
-
-
- $pubcomment = get_pconfig($importer['channel_id'],'system','diaspora_public_comments');
-
- // by default comments on public posts are allowed from anybody on Diaspora. That is their policy.
- // Once this setting is set to something we'll track your preference and it will over-ride the default.
-
- if($pubcomment === false)
- $pubcomment = 1;
-
- // Friendica is currently truncating guids at 64 chars
- $search_guid = $parent_guid;
- if(strlen($parent_guid) == 64)
- $search_guid = $parent_guid . '%';
-
- $r = q("SELECT * FROM item WHERE uid = %d AND mid LIKE '%s' LIMIT 1",
- intval($importer['channel_id']),
- dbesc($search_guid)
- );
- if(! $r) {
- logger('diaspora_comment: parent item not found: parent: ' . $parent_guid . ' item: ' . $guid);
- return;
- }
-
- $parent_item = $r[0];
-
- if(intval($parent_item['item_private']))
- $pubcomment = 0;
-
- $search_guid = $guid;
- if(strlen($guid) == 64)
- $search_guid = $guid . '%';
-
-
- $r = q("SELECT * FROM item WHERE uid = %d AND mid like '%s' LIMIT 1",
- intval($importer['channel_id']),
- dbesc($search_guid)
- );
- if($r) {
- logger('diaspora_comment: our comment just got relayed back to us (or there was a guid collision) : ' . $guid);
- return;
- }
-
-
-
- /* How Diaspora performs comment signature checking:
-
- - If an item has been sent by the comment author to the top-level post owner to relay on
- to the rest of the contacts on the top-level post, the top-level post owner should check
- the author_signature, then create a parent_author_signature before relaying the comment on
- - If an item has been relayed on by the top-level post owner, the contacts who receive it
- check only the parent_author_signature. Basically, they trust that the top-level post
- owner has already verified the authenticity of anything he/she sends out
- - In either case, the signature that get checked is the signature created by the person
- who sent the psuedo-salmon
- */
-
- $signed_data = $guid . ';' . $parent_guid . ';' . $text . ';' . $diaspora_handle;
- $key = $msg['key'];
-
- if($parent_author_signature) {
- // If a parent_author_signature exists, then we've received the comment
- // relayed from the top-level post owner. There's no need to check the
- // author_signature if the parent_author_signature is valid
-
- $parent_author_signature = base64_decode($parent_author_signature);
-
- if(! rsa_verify($signed_data,$parent_author_signature,$key,'sha256')) {
- logger('diaspora_comment: top-level owner verification failed.');
- return;
- }
- }
- else {
- // If there's no parent_author_signature, then we've received the comment
- // from the comment creator. In that case, the person is commenting on
- // our post, so he/she must be a contact of ours and his/her public key
- // should be in $msg['key']
-
- if($importer['system']) {
- // don't relay to the sys channel
- logger('diaspora_comment: relay to sys channel blocked.');
- return;
- }
-
- $author_signature = base64_decode($author_signature);
-
- if(! rsa_verify($signed_data,$author_signature,$key,'sha256')) {
- logger('diaspora_comment: comment author verification failed.');
- return;
- }
- }
-
- // Phew! Everything checks out. Now create an item.
-
- // Find the original comment author information.
- // We need this to make sure we display the comment author
- // information (name and avatar) correctly.
-
- if(strcasecmp($diaspora_handle,$msg['author']) == 0)
- $person = $contact;
- else {
- $person = find_diaspora_person_by_handle($diaspora_handle);
-
- if(! is_array($person)) {
- logger('diaspora_comment: unable to find author details');
- return;
- }
- }
-
-
- $body = diaspora2bb($text);
-
-
- $maxlen = get_max_import_size();
-
- if($maxlen && mb_strlen($body) > $maxlen) {
- $body = mb_substr($body,0,$maxlen,'UTF-8');
- logger('message length exceeds max_import_size: truncated');
- }
-
-
- $datarray = array();
-
- // Look for tags and linkify them
- $results = linkify_tags(get_app(), $body, $importer['channel_id'], true);
-
- $datarray['term'] = array();
-
- if($results) {
- foreach($results as $result) {
- $success = $result['success'];
- if($success['replaced']) {
- $datarray['term'][] = array(
- 'uid' => $importer['channel_id'],
- 'type' => $success['termtype'],
- 'otype' => TERM_OBJ_POST,
- 'term' => $success['term'],
- 'url' => $success['url']
- );
- }
- }
- }
-
- $cnt = preg_match_all('/@\[url=(.*?)\](.*?)\[\/url\]/ism',$body,$matches,PREG_SET_ORDER);
- if($cnt) {
- foreach($matches as $mtch) {
- $datarray['term'][] = array(
- 'uid' => $importer['channel_id'],
- 'type' => TERM_MENTION,
- 'otype' => TERM_OBJ_POST,
- 'term' => $mtch[2],
- 'url' => $mtch[1]
- );
- }
- }
-
- $cnt = preg_match_all('/@\[zrl=(.*?)\](.*?)\[\/zrl\]/ism',$body,$matches,PREG_SET_ORDER);
- if($cnt) {
- foreach($matches as $mtch) {
- // don't include plustags in the term
- $term = ((substr($mtch[2],-1,1) === '+') ? substr($mtch[2],0,-1) : $mtch[2]);
- $datarray['term'][] = array(
- 'uid' => $importer['channel_id'],
- 'type' => TERM_MENTION,
- 'otype' => TERM_OBJ_POST,
- 'term' => $term,
- 'url' => $mtch[1]
- );
- }
- }
-
- $datarray['uid'] = $importer['channel_id'];
- $datarray['verb'] = ACTIVITY_POST;
- $datarray['mid'] = $guid;
- $datarray['parent_mid'] = $parent_item['mid'];
-
- // set the route to that of the parent so downstream hubs won't reject it.
- $datarray['route'] = $parent_item['route'];
-
- // No timestamps for comments? OK, we'll the use current time.
- $datarray['changed'] = $datarray['created'] = $datarray['edited'] = datetime_convert();
- $datarray['item_private'] = $parent_item['item_private'];
-
- $datarray['owner_xchan'] = $parent_item['owner_xchan'];
- $datarray['author_xchan'] = $person['xchan_hash'];
-
- $datarray['body'] = $body;
-
- if(strstr($person['xchan_network'],'friendica'))
- $app = 'Friendica';
- else
- $app = 'Diaspora';
-
- $datarray['app'] = $app;
-
- if(! $parent_author_signature) {
- $key = get_config('system','pubkey');
- $x = array('signer' => $diaspora_handle, 'body' => $text,
- 'signed_text' => $signed_data, 'signature' => base64_encode($author_signature));
- $datarray['diaspora_meta'] = json_encode(crypto_encapsulate(json_encode($x),$key));
- }
-
-
-
- // So basically if something arrives at the sys channel it's by definition public and we allow it.
- // If $pubcomment and the parent was public, we allow it.
- // In all other cases, honour the permissions for this Diaspora connection
-
- $tgroup = tgroup_check($importer['channel_id'],$datarray);
-
- if((! $importer['system']) && (! $pubcomment) && (! perm_is_allowed($importer['channel_id'],$contact['xchan_hash'],'post_comments')) && (! $tgroup)) {
- logger('diaspora_comment: Ignoring this author.');
- return 202;
- }
-
-
-
-
- $result = item_store($datarray);
-
- if($result && $result['success'])
- $message_id = $result['item_id'];
-
- if(($parent_item['item_flags'] & ITEM_ORIGIN) && (! $parent_author_signature)) {
- // if the message isn't already being relayed, notify others
- // the existence of parent_author_signature means the parent_author or owner
- // is already relaying.
-
- proc_run('php','include/notifier.php','comment-import',$message_id);
- }
-
- if($result['item_id']) {
- $r = q("select * from item where id = %d limit 1",
- intval($result['item_id'])
- );
- if($r)
- send_status_notifications($result['item_id'],$r[0]);
- }
-
- return;
-}
-
-
-
-
-function diaspora_conversation($importer,$xml,$msg) {
-
- $a = get_app();
-
- $guid = notags(unxmlify($xml->guid));
- $subject = notags(unxmlify($xml->subject));
- $diaspora_handle = notags(unxmlify($xml->diaspora_handle));
- $participant_handles = notags(unxmlify($xml->participant_handles));
- $created_at = datetime_convert('UTC','UTC',notags(unxmlify($xml->created_at)));
-
- $parent_uri = $diaspora_handle . ':' . $guid;
-
- $messages = $xml->message;
-
- if(! count($messages)) {
- logger('diaspora_conversation: empty conversation');
- return;
- }
-
- $contact = diaspora_get_contact_by_handle($importer['channel_id'],$msg['author']);
- if(! $contact) {
- logger('diaspora_conversation: cannot find contact: ' . $msg['author']);
- return;
- }
-
-
- if(! perm_is_allowed($importer['channel_id'],$contact['xchan_hash'],'post_mail')) {
- logger('diaspora_conversation: Ignoring this author.');
- return 202;
- }
-
- $conversation = null;
-
- $c = q("select * from conv where uid = %d and guid = '%s' limit 1",
- intval($importer['channel_id']),
- dbesc($guid)
- );
- if(count($c))
- $conversation = $c[0];
- else {
- $r = q("insert into conv (uid,guid,creator,created,updated,subject,recips) values(%d, '%s', '%s', '%s', '%s', '%s', '%s') ",
- intval($importer['channel_id']),
- dbesc($guid),
- dbesc($diaspora_handle),
- dbesc(datetime_convert('UTC','UTC',$created_at)),
- dbesc(datetime_convert()),
- dbesc($subject),
- dbesc($participant_handles)
- );
- if($r)
- $c = q("select * from conv where uid = %d and guid = '%s' limit 1",
- intval($importer['channel_id']),
- dbesc($guid)
- );
- if(count($c))
- $conversation = $c[0];
- }
- if(! $conversation) {
- logger('diaspora_conversation: unable to create conversation.');
- return;
- }
-
- foreach($messages as $mesg) {
-
- $reply = 0;
-
- $msg_guid = notags(unxmlify($mesg->guid));
- $msg_parent_guid = notags(unxmlify($mesg->parent_guid));
- $msg_parent_author_signature = notags(unxmlify($mesg->parent_author_signature));
- $msg_author_signature = notags(unxmlify($mesg->author_signature));
- $msg_text = unxmlify($mesg->text);
- $msg_created_at = datetime_convert('UTC','UTC',notags(unxmlify($mesg->created_at)));
- $msg_diaspora_handle = notags(unxmlify($mesg->diaspora_handle));
- $msg_conversation_guid = notags(unxmlify($mesg->conversation_guid));
- if($msg_conversation_guid != $guid) {
- logger('diaspora_conversation: message conversation guid does not belong to the current conversation. ' . $xml);
- continue;
- }
-
- $body = diaspora2bb($msg_text);
-
-
- $maxlen = get_max_import_size();
-
- if($maxlen && mb_strlen($body) > $maxlen) {
- $body = mb_substr($body,0,$maxlen,'UTF-8');
- logger('message length exceeds max_import_size: truncated');
- }
-
-
- $author_signed_data = $msg_guid . ';' . $msg_parent_guid . ';' . $msg_text . ';' . unxmlify($mesg->created_at) . ';' . $msg_diaspora_handle . ';' . $msg_conversation_guid;
-
- $author_signature = base64_decode($msg_author_signature);
-
- if(strcasecmp($msg_diaspora_handle,$msg['author']) == 0) {
- $person = $contact;
- $key = $msg['key'];
- }
- else {
- $person = find_diaspora_person_by_handle($msg_diaspora_handle);
-
- if(is_array($person) && x($person,'xchan_pubkey'))
- $key = $person['xchan_pubkey'];
- else {
- logger('diaspora_conversation: unable to find author details');
- continue;
- }
- }
-
- if(! rsa_verify($author_signed_data,$author_signature,$key,'sha256')) {
- logger('diaspora_conversation: verification failed.');
- continue;
- }
-
- if($msg_parent_author_signature) {
- $owner_signed_data = $msg_guid . ';' . $msg_parent_guid . ';' . $msg_text . ';' . unxmlify($mesg->created_at) . ';' . $msg_diaspora_handle . ';' . $msg_conversation_guid;
-
- $parent_author_signature = base64_decode($msg_parent_author_signature);
-
- $key = $msg['key'];
-
- if(! rsa_verify($owner_signed_data,$parent_author_signature,$key,'sha256')) {
- logger('diaspora_conversation: owner verification failed.');
- continue;
- }
- }
-
- $r = q("select id from mail where mid = '%s' limit 1",
- dbesc($message_id)
- );
- if(count($r)) {
- logger('diaspora_conversation: duplicate message already delivered.', LOGGER_DEBUG);
- continue;
- }
-
- $key = get_config('system','pubkey');
- if($subject)
- $subject = json_encode(crypto_encapsulate($subject,$key));
- if($body)
- $body = json_encode(crypto_encapsulate($body,$key));
-
- q("insert into mail ( `channel_id`, `convid`, `from_xchan`,`to_xchan`,`title`,`body`,`mail_flags`,`mid`,`parent_mid`,`created`) values ( %d, %d, '%s', '%s', '%s', '%s', %d, '%s', '%s', '%s')",
- intval($importer['channel_id']),
- intval($conversation['id']),
- dbesc($person['xchan_hash']),
- dbesc($importer['channel_hash']),
- dbesc($subject),
- dbesc($body),
- intval(MAIL_OBSCURED),
- dbesc($msg_guid),
- dbesc($parent_uri),
- dbesc($msg_created_at)
- );
-
- q("update conv set updated = '%s' where id = %d",
- dbesc(datetime_convert()),
- intval($conversation['id'])
- );
-
- require_once('include/enotify.php');
-/******
-//FIXME
-
- notification(array(
- 'type' => NOTIFY_MAIL,
- 'notify_flags' => $importer['notify-flags'],
- 'language' => $importer['language'],
- 'to_name' => $importer['username'],
- 'to_email' => $importer['email'],
- 'uid' =>$importer['importer_uid'],
- 'item' => array('subject' => $subject, 'body' => $body),
- 'source_name' => $person['name'],
- 'source_link' => $person['url'],
- 'source_photo' => $person['thumb'],
- 'verb' => ACTIVITY_POST,
- 'otype' => 'mail'
- ));
-*******/
-
- }
-
- return;
-}
-
-function diaspora_message($importer,$xml,$msg) {
-
- $a = get_app();
-
- $msg_guid = notags(unxmlify($xml->guid));
- $msg_parent_guid = notags(unxmlify($xml->parent_guid));
- $msg_parent_author_signature = notags(unxmlify($xml->parent_author_signature));
- $msg_author_signature = notags(unxmlify($xml->author_signature));
- $msg_text = unxmlify($xml->text);
- $msg_created_at = datetime_convert('UTC','UTC',notags(unxmlify($xml->created_at)));
- $msg_diaspora_handle = notags(unxmlify($xml->diaspora_handle));
- $msg_conversation_guid = notags(unxmlify($xml->conversation_guid));
-
- $parent_uri = $msg_parent_guid;
-
- $contact = diaspora_get_contact_by_handle($importer['channel_id'],$msg_diaspora_handle);
- if(! $contact) {
- logger('diaspora_message: cannot find contact: ' . $msg_diaspora_handle);
- return;
- }
-
- if(($contact['rel'] == CONTACT_IS_FOLLOWER) || ($contact['blocked']) || ($contact['readonly'])) {
- logger('diaspora_message: Ignoring this author.');
- return 202;
- }
-
- $conversation = null;
-
- $c = q("select * from conv where uid = %d and guid = '%s' limit 1",
- intval($importer['channel_id']),
- dbesc($msg_conversation_guid)
- );
- if($c)
- $conversation = $c[0];
- else {
- logger('diaspora_message: conversation not available.');
- return;
- }
-
- $reply = 0;
-
- $subject = $conversation['subject'];
- $body = diaspora2bb($msg_text);
-
-
- $maxlen = get_max_import_size();
-
- if($maxlen && mb_strlen($body) > $maxlen) {
- $body = mb_substr($body,0,$maxlen,'UTF-8');
- logger('message length exceeds max_import_size: truncated');
- }
-
-
-
- $message_id = $msg_diaspora_handle . ':' . $msg_guid;
-
- $author_signed_data = $msg_guid . ';' . $msg_parent_guid . ';' . $msg_text . ';' . unxmlify($xml->created_at) . ';' . $msg_diaspora_handle . ';' . $msg_conversation_guid;
-
-
- $author_signature = base64_decode($msg_author_signature);
-
- $person = find_diaspora_person_by_handle($msg_diaspora_handle);
- if(is_array($person) && x($person,'xchan_pubkey'))
- $key = $person['xchan_pubkey'];
- else {
- logger('diaspora_message: unable to find author details');
- return;
- }
-
- if(! rsa_verify($author_signed_data,$author_signature,$key,'sha256')) {
- logger('diaspora_message: verification failed.');
- return;
- }
-
- $r = q("select id from mail where mid = '%s' and channel_id = %d limit 1",
- dbesc($message_id),
- intval($importer['channel_id'])
- );
- if($r) {
- logger('diaspora_message: duplicate message already delivered.', LOGGER_DEBUG);
- return;
- }
-
- $key = get_config('system','pubkey');
- if($subject)
- $subject = json_encode(crypto_encapsulate($subject,$key));
- if($body)
- $body = json_encode(crypto_encapsulate($body,$key));
-
- q("insert into mail ( `channel_id`, `convid`, `from_xchan`,`to_xchan`,`title`,`body`,`mail_flags`,`mid`,`parent_mid`,`created`) values ( %d, %d, '%s', '%s', '%s', '%s', '%d','%s','%s','%s')",
- intval($importer['channel_id']),
- intval($conversation['id']),
- dbesc($person['xchan_hash']),
- dbesc($importer['xchan_hash']),
- dbesc($subject),
- dbesc($body),
- intval(MAIL_OBSCURED),
- dbesc($msg_guid),
- dbesc($parent_uri),
- dbesc($msg_created_at)
- );
-
- q("update conv set updated = '%s' where id = %d",
- dbesc(datetime_convert()),
- intval($conversation['id'])
- );
-
- return;
-}
-
-
-function diaspora_photo($importer,$xml,$msg) {
-
- $a = get_app();
-
- logger('diaspora_photo: init',LOGGER_DEBUG);
-
- $remote_photo_path = notags(unxmlify($xml->remote_photo_path));
-
- $remote_photo_name = notags(unxmlify($xml->remote_photo_name));
-
- $status_message_guid = notags(unxmlify($xml->status_message_guid));
-
- $guid = notags(unxmlify($xml->guid));
-
- $diaspora_handle = notags(unxmlify($xml->diaspora_handle));
-
- $public = notags(unxmlify($xml->public));
-
- $created_at = notags(unxmlify($xml_created_at));
-
- logger('diaspora_photo: status_message_guid: ' . $status_message_guid, LOGGER_DEBUG);
-
- $contact = diaspora_get_contact_by_handle($importer['channel_id'],$msg['author']);
- if(! $contact) {
- logger('diaspora_photo: contact record not found: ' . $msg['author'] . ' handle: ' . $diaspora_handle);
- return;
- }
-
- if((! $importer['system']) && (! perm_is_allowed($importer['channel_id'],$contact['xchan_hash'],'send_stream'))) {
- logger('diaspora_photo: Ignoring this author.');
- return 202;
- }
-
- $r = q("SELECT * FROM `item` WHERE `uid` = %d AND `mid` = '%s' LIMIT 1",
- intval($importer['channel_id']),
- dbesc($status_message_guid)
- );
- if(! $r) {
- logger('diaspora_photo: attempt = ' . $attempt . '; status message not found: ' . $status_message_guid . ' for photo: ' . $guid);
- return;
- }
-
-// $parent_item = $r[0];
-
-// $link_text = '[img]' . $remote_photo_path . $remote_photo_name . '[/img]' . "\n";
-
-// $link_text = scale_external_images($link_text, true,
-// array($remote_photo_name, 'scaled_full_' . $remote_photo_name));
-
-// if(strpos($parent_item['body'],$link_text) === false) {
-// $r = q("update item set `body` = '%s', `visible` = 1 where `id` = %d and `uid` = %d",
-// dbesc($link_text . $parent_item['body']),
-// intval($parent_item['id']),
-// intval($parent_item['uid'])
-// );
-// }
-
- return;
-}
-
-
-
-
-function diaspora_like($importer,$xml,$msg) {
-
- $a = get_app();
- $guid = notags(unxmlify($xml->guid));
- $parent_guid = notags(unxmlify($xml->parent_guid));
- $diaspora_handle = notags(unxmlify($xml->diaspora_handle));
- $target_type = notags(unxmlify($xml->target_type));
- $positive = notags(unxmlify($xml->positive));
- $author_signature = notags(unxmlify($xml->author_signature));
-
- $parent_author_signature = (($xml->parent_author_signature) ? notags(unxmlify($xml->parent_author_signature)) : '');
-
- // likes on comments not supported here and likes on photos not supported by Diaspora
-
-// if($target_type !== 'Post')
-// return;
-
- $contact = diaspora_get_contact_by_handle($importer['channel_id'],$msg['author']);
- if(! $contact) {
- logger('diaspora_like: cannot find contact: ' . $msg['author'] . ' for channel ' . $importer['channel_name']);
- return;
- }
-
-
- if((! $importer['system']) && (! perm_is_allowed($importer['channel_id'],$contact['xchan_hash'],'post_comments'))) {
- logger('diaspora_like: Ignoring this author.');
- return 202;
- }
-
- $r = q("SELECT * FROM `item` WHERE `uid` = %d AND `mid` = '%s' LIMIT 1",
- intval($importer['channel_id']),
- dbesc($parent_guid)
- );
- if(! count($r)) {
- logger('diaspora_like: parent item not found: ' . $guid);
- return;
- }
-
- $parent_item = $r[0];
-
- $r = q("SELECT * FROM `item` WHERE `uid` = %d AND `mid` = '%s' LIMIT 1",
- intval($importer['channel_id']),
- dbesc($guid)
- );
- if(count($r)) {
- if($positive === 'true') {
- logger('diaspora_like: duplicate like: ' . $guid);
- return;
- }
- // Note: I don't think "Like" objects with positive = "false" are ever actually used
- // It looks like "RelayableRetractions" are used for "unlike" instead
- if($positive === 'false') {
- logger('diaspora_like: received a like with positive set to "false"...ignoring');
- // perhaps call drop_item()
- // FIXME--actually don't unless it turns out that Diaspora does indeed send out "false" likes
- // send notification via proc_run()
- return;
- }
- }
-
- $i = q("select * from xchan where xchan_hash = '%s' limit 1",
- dbesc($parent_item['author_xchan'])
- );
- if($i)
- $item_author = $i[0];
-
- // Note: I don't think "Like" objects with positive = "false" are ever actually used
- // It looks like "RelayableRetractions" are used for "unlike" instead
- if($positive === 'false') {
- logger('diaspora_like: received a like with positive set to "false"');
- logger('diaspora_like: unlike received with no corresponding like...ignoring');
- return;
- }
-
-
- /* How Diaspora performs "like" signature checking:
-
- - If an item has been sent by the like author to the top-level post owner to relay on
- to the rest of the contacts on the top-level post, the top-level post owner should check
- the author_signature, then create a parent_author_signature before relaying the like on
- - If an item has been relayed on by the top-level post owner, the contacts who receive it
- check only the parent_author_signature. Basically, they trust that the top-level post
- owner has already verified the authenticity of anything he/she sends out
- - In either case, the signature that get checked is the signature created by the person
- who sent the salmon
- */
-
- // 2014-09-10 let's try this: signatures are failing. I'll try and make a signable string from
- // the parameters in the order they were presented in the post. This is how D* creates the signable string.
-
-
- $signed_data = $positive . ';' . $guid . ';' . $target_type . ';' . $parent_guid . ';' . $diaspora_handle;
-
- $key = $msg['key'];
-
- if($parent_author_signature) {
- // If a parent_author_signature exists, then we've received the like
- // relayed from the top-level post owner. There's no need to check the
- // author_signature if the parent_author_signature is valid
-
- $parent_author_signature = base64_decode($parent_author_signature);
-
- if(! rsa_verify($signed_data,$parent_author_signature,$key,'sha256')) {
- if (intval(get_config('system','ignore_diaspora_like_signature')))
- logger('diaspora_like: top-level owner verification failed. Proceeding anyway.');
- else {
- logger('diaspora_like: top-level owner verification failed.');
- return;
- }
- }
- }
- else {
- // If there's no parent_author_signature, then we've received the like
- // from the like creator. In that case, the person is "like"ing
- // our post, so he/she must be a contact of ours and his/her public key
- // should be in $msg['key']
-
- $author_signature = base64_decode($author_signature);
-
- if(! rsa_verify($signed_data,$author_signature,$key,'sha256')) {
- if (intval(get_config('system','ignore_diaspora_like_signature')))
- logger('diaspora_like: like creator verification failed. Proceeding anyway');
- else {
- logger('diaspora_like: like creator verification failed.');
- return;
- }
- }
- }
-
- logger('diaspora_like: signature check complete.',LOGGER_DEBUG);
-
- // Phew! Everything checks out. Now create an item.
-
- // Find the original comment author information.
- // We need this to make sure we display the comment author
- // information (name and avatar) correctly.
- if(strcasecmp($diaspora_handle,$msg['author']) == 0)
- $person = $contact;
- else {
- $person = find_diaspora_person_by_handle($diaspora_handle);
-
- if(! is_array($person)) {
- logger('diaspora_like: unable to find author details');
- return;
- }
- }
-
- $uri = $diaspora_handle . ':' . $guid;
-
- $activity = ACTIVITY_LIKE;
-
- $post_type = (($parent_item['resource_type'] === 'photo') ? t('photo') : t('status'));
-
- $links = array(array('rel' => 'alternate','type' => 'text/html', 'href' => $parent_item['plink']));
- $objtype = (($parent_item['resource_type'] === 'photo') ? ACTIVITY_OBJ_PHOTO : ACTIVITY_OBJ_NOTE );
-
- $body = $parent_item['body'];
-
-
- $object = json_encode(array(
- 'type' => $post_type,
- 'id' => $parent_item['mid'],
- 'parent' => (($parent_item['thr_parent']) ? $parent_item['thr_parent'] : $parent_item['parent_mid']),
- 'link' => $links,
- 'title' => $parent_item['title'],
- 'content' => $parent_item['body'],
- 'created' => $parent_item['created'],
- 'edited' => $parent_item['edited'],
- 'author' => array(
- 'name' => $item_author['xchan_name'],
- 'address' => $item_author['xchan_addr'],
- 'guid' => $item_author['xchan_guid'],
- 'guid_sig' => $item_author['xchan_guid_sig'],
- 'link' => array(
- array('rel' => 'alternate', 'type' => 'text/html', 'href' => $item_author['xchan_url']),
- array('rel' => 'photo', 'type' => $item_author['xchan_photo_mimetype'], 'href' => $item_author['xchan_photo_m'])),
- ),
- ));
-
-
- $bodyverb = t('%1$s likes %2$s\'s %3$s');
-
- $arr = array();
-
- $arr['uid'] = $importer['channel_id'];
- $arr['aid'] = $importer['channel_account_id'];
- $arr['mid'] = $guid;
- $arr['parent_mid'] = $parent_item['mid'];
- $arr['owner_xchan'] = $parent_item['owner_xchan'];
- $arr['author_xchan'] = $person['xchan_hash'];
-
- $ulink = '[url=' . $contact['url'] . ']' . $contact['name'] . '[/url]';
- $alink = '[url=' . $parent_item['author-link'] . ']' . $parent_item['author-name'] . '[/url]';
- $plink = '[url='. z_root() .'/display/'.$guid.']'.$post_type.'[/url]';
- $arr['body'] = sprintf( $bodyverb, $ulink, $alink, $plink );
-
- $arr['app'] = 'Diaspora';
-
- // set the route to that of the parent so downstream hubs won't reject it.
- $arr['route'] = $parent_item['route'];
-
- $arr['item_private'] = $parent_item['item_private'];
- $arr['verb'] = $activity;
- $arr['obj_type'] = $objtype;
- $arr['object'] = $object;
-
- if(! $parent_author_signature) {
- $key = get_config('system','pubkey');
- $x = array('signer' => $diaspora_handle, 'body' => $text,
- 'signed_text' => $signed_data, 'signature' => base64_encode($author_signature));
- $arr['diaspora_meta'] = json_encode(crypto_encapsulate(json_encode($x),$key));
- }
-
- $x = item_store($arr);
-
- if($x)
- $message_id = $x['item_id'];
-
- // if the message isn't already being relayed, notify others
- // the existence of parent_author_signature means the parent_author or owner
- // is already relaying. The parent_item['origin'] indicates the message was created on our system
-
- if(($parent_item['item_flags'] & ITEM_ORIGIN) && (! $parent_author_signature))
- proc_run('php','include/notifier.php','comment-import',$message_id);
-
- return;
-}
-
-function diaspora_retraction($importer,$xml) {
-
-
- $guid = notags(unxmlify($xml->guid));
- $diaspora_handle = notags(unxmlify($xml->diaspora_handle));
- $type = notags(unxmlify($xml->type));
-
- $contact = diaspora_get_contact_by_handle($importer['channel_id'],$diaspora_handle);
- if(! $contact)
- return;
-
- if($type === 'Person') {
- require_once('include/Contact.php');
- contact_remove($importer['channel_id'],$contact['abook_id']);
- }
- elseif($type === 'Post') {
- $r = q("select * from item where mid = '%s' and uid = %d limit 1",
- dbesc('guid'),
- intval($importer['channel_id'])
- );
- if(count($r)) {
- if(link_compare($r[0]['author_xchan'],$contact['xchan_hash'])) {
- drop_item($r[0]['id'],false);
- }
- }
- }
-
- return 202;
- // NOTREACHED
-}
-
-function diaspora_signed_retraction($importer,$xml,$msg) {
-
-
- $guid = notags(unxmlify($xml->target_guid));
- $diaspora_handle = notags(unxmlify($xml->sender_handle));
- $type = notags(unxmlify($xml->target_type));
- $sig = notags(unxmlify($xml->target_author_signature));
-
- $parent_author_signature = (($xml->parent_author_signature) ? notags(unxmlify($xml->parent_author_signature)) : '');
-
- $contact = diaspora_get_contact_by_handle($importer['channel_id'],$diaspora_handle);
- if(! $contact) {
- logger('diaspora_signed_retraction: no contact ' . $diaspora_handle . ' for ' . $importer['channel_id']);
- return;
- }
-
-
- $signed_data = $guid . ';' . $type ;
- $key = $msg['key'];
-
- /* How Diaspora performs relayable_retraction signature checking:
-
- - If an item has been sent by the item author to the top-level post owner to relay on
- to the rest of the contacts on the top-level post, the top-level post owner checks
- the author_signature, then creates a parent_author_signature before relaying the item on
- - If an item has been relayed on by the top-level post owner, the contacts who receive it
- check only the parent_author_signature. Basically, they trust that the top-level post
- owner has already verified the authenticity of anything he/she sends out
- - In either case, the signature that get checked is the signature created by the person
- who sent the salmon
- */
-
- if($parent_author_signature) {
-
- $parent_author_signature = base64_decode($parent_author_signature);
-
- if(! rsa_verify($signed_data,$parent_author_signature,$key,'sha256')) {
- logger('diaspora_signed_retraction: top-level post owner verification failed');
- return;
- }
-
- }
- else {
-
- $sig_decode = base64_decode($sig);
-
- if(! rsa_verify($signed_data,$sig_decode,$key,'sha256')) {
- logger('diaspora_signed_retraction: retraction owner verification failed.' . print_r($msg,true));
- return;
- }
- }
-
- if($type === 'StatusMessage' || $type === 'Comment' || $type === 'Like') {
- $r = q("select * from item where mid = '%s' and uid = %d limit 1",
- dbesc($guid),
- intval($importer['channel_id'])
- );
- if($r) {
- if($r[0]['author_xchan'] == $contact['xchan_hash']) {
-
- drop_item($r[0]['id'],false, DROPITEM_PHASE1);
-
- // Now check if the retraction needs to be relayed by us
- //
- // The first item in the `item` table with the parent id is the parent. However, MySQL doesn't always
- // return the items ordered by `item`.`id`, in which case the wrong item is chosen as the parent.
- // The only item with `parent` and `id` as the parent id is the parent item.
- $p = q("select item_flags from item where parent = %d and id = %d limit 1",
- $r[0]['parent'],
- $r[0]['parent']
- );
- if($p) {
- if(($p[0]['item_flags'] & ITEM_ORIGIN) && (! $parent_author_signature)) {
-// FIXME so we can relay this
-// q("insert into sign (`retract_iid`,`signed_text`,`signature`,`signer`) values (%d,'%s','%s','%s') ",
-// $r[0]['id'],
-// dbesc($signed_data),
-// dbesc($sig),
-// dbesc($diaspora_handle)
-// );
-
- // the existence of parent_author_signature would have meant the parent_author or owner
- // is already relaying.
- logger('diaspora_signed_retraction: relaying relayable_retraction');
-
- proc_run('php','include/notifier.php','drop',$r[0]['id']);
- }
- }
- }
- }
- }
- else
- logger('diaspora_signed_retraction: unknown type: ' . $type);
-
- return 202;
- // NOTREACHED
-}
-
-function diaspora_profile($importer,$xml,$msg) {
-
- $a = get_app();
- $diaspora_handle = notags(unxmlify($xml->diaspora_handle));
-
-
- if($diaspora_handle != $msg['author']) {
- logger('diaspora_post: Potential forgery. Message handle is not the same as envelope sender.');
- return 202;
- }
-
- $contact = diaspora_get_contact_by_handle($importer['channel_id'],$diaspora_handle);
- if(! $contact)
- return;
-
- if($contact['blocked']) {
- logger('diaspora_post: Ignoring this author.');
- return 202;
- }
-
- $name = unxmlify($xml->first_name) . ((strlen($xml->last_name)) ? ' ' . unxmlify($xml->last_name) : '');
- $image_url = unxmlify($xml->image_url);
- $birthday = unxmlify($xml->birthday);
-
-
- $handle_parts = explode("@", $diaspora_handle);
- if($name === '') {
- $name = $handle_parts[0];
- }
-
- if( preg_match("|^https?://|", $image_url) === 0) {
- $image_url = "http://" . $handle_parts[1] . $image_url;
- }
-
- require_once('include/photo/photo_driver.php');
-
- $images = import_profile_photo($image_url,$contact['xchan_hash']);
-
- // Generic birthday. We don't know the timezone. The year is irrelevant.
-
- $birthday = str_replace('1000','1901',$birthday);
-
- $birthday = datetime_convert('UTC','UTC',$birthday,'Y-m-d');
-
- // this is to prevent multiple birthday notifications in a single year
- // if we already have a stored birthday and the 'm-d' part hasn't changed, preserve the entry, which will preserve the notify year
-
- if(substr($birthday,5) === substr($contact['bd'],5))
- $birthday = $contact['bd'];
-
- $r = q("update xchan set xchan_name = '%s', xchan_name_date = '%s', xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s' where xchan_hash = '%s' ",
- dbesc($name),
- dbesc(datetime_convert()),
- dbesc($images[0]),
- dbesc($images[1]),
- dbesc($images[2]),
- dbesc($images[3]),
- dbesc(datetime_convert()),
- intval($contact['xchan_hash'])
- );
-
- return;
-
-}
-
-function diaspora_share($owner,$contact) {
- $a = get_app();
-
- $enabled = intval(get_config('system','diaspora_enabled'));
- if(! $enabled) {
- logger('diaspora_share: disabled');
- return;
- }
-
- $allowed = get_pconfig($owner['channel_id'],'system','diaspora_allowed');
- if($allowed === false)
- $allowed = 1;
-
- if(! intval($allowed)) {
- logger('diaspora_share: disallowed for channel ' . $importer['channel_name']);
- return;
- }
-
-
-
- $myaddr = $owner['channel_address'] . '@' . substr($a->get_baseurl(), strpos($a->get_baseurl(),'://') + 3);
-
- if(! array_key_exists('xchan_hash',$contact)) {
- $c = q("select * from xchan left join hubloc on xchan_hash = hubloc_hash where xchan_hash = '%s' limit 1",
- dbesc($contact['hubloc_hash'])
- );
- if(! $c) {
- logger('diaspora_share: ' . $contact['hubloc_hash'] . ' not found.');
- return;
- }
- $contact = $c[0];
- }
-
- $theiraddr = $contact['xchan_addr'];
-
- $tpl = get_markup_template('diaspora_share.tpl');
- $msg = replace_macros($tpl, array(
- '$sender' => $myaddr,
- '$recipient' => $theiraddr
- ));
-
- $slap = 'xml=' . urlencode(urlencode(diaspora_msg_build($msg,$owner,$contact,$owner['channel_prvkey'],$contact['xchan_pubkey'])));
- return(diaspora_transmit($owner,$contact,$slap, false));
-}
-
-function diaspora_unshare($owner,$contact) {
-
- $a = get_app();
- $myaddr = $owner['channel_address'] . '@' . substr($a->get_baseurl(), strpos($a->get_baseurl(),'://') + 3);
-
- $tpl = get_markup_template('diaspora_retract.tpl');
- $msg = replace_macros($tpl, array(
- '$guid' => $owner['channel_guid'],
- '$type' => 'Person',
- '$handle' => $myaddr
- ));
-
- $slap = 'xml=' . urlencode(urlencode(diaspora_msg_build($msg,$owner,$contact,$owner['channel_prvkey'],$contact['xchan_pubkey'])));
-
- return(diaspora_transmit($owner,$contact,$slap, false));
-}
-
-
-function diaspora_send_status($item,$owner,$contact,$public_batch = false) {
-
- $a = get_app();
- $myaddr = $owner['channel_address'] . '@' . substr($a->get_baseurl(), strpos($a->get_baseurl(),'://') + 3);
-
- if(intval($item['id']) != intval($item['parent'])) {
- logger('attempted to send a comment as a top-level post');
- return;
- }
-
- $images = array();
-
- $title = $item['title'];
- $body = bb2diaspora_itembody($item,true);
-
-/*
- // We're trying to match Diaspora's split message/photo protocol but
- // all the photos are displayed on D* as links and not img's - even
- // though we're sending pretty much precisely what they send us when
- // doing the same operation.
- // Commented out for now, we'll use bb2diaspora to convert photos to markdown
- // which seems to get through intact.
-
- $cnt = preg_match_all('|\[img\](.*?)\[\/img\]|',$body,$matches,PREG_SET_ORDER);
- if($cnt) {
- foreach($matches as $mtch) {
- $detail = array();
- $detail['str'] = $mtch[0];
- $detail['path'] = dirname($mtch[1]) . '/';
- $detail['file'] = basename($mtch[1]);
- $detail['guid'] = $item['guid'];
- $detail['handle'] = $myaddr;
- $images[] = $detail;
- $body = str_replace($detail['str'],$mtch[1],$body);
- }
- }
-*/
-
- if($item['item_flags'] & ITEM_CONSENSUS) {
- $poll = replace_macros(get_markup_template('diaspora_consensus.tpl'), array(
- '$guid_q' => random_string(),
- '$question' => t('Please choose'),
- '$guid_y' => random_string(),
- '$agree' => t('Agree'),
- '$guid_n' => random_string(),
- '$disagree' => t('Disagree'),
- '$guid_a' => random_string(),
- '$abstain' => t('Abstain')
- ));
- }
- else
- $poll = '';
-
- $public = (($item['item_private']) ? 'false' : 'true');
-
- require_once('include/datetime.php');
- $created = datetime_convert('UTC','UTC',$item['created'],'Y-m-d H:i:s \U\T\C');
-
- // Detect a share element and do a reshare
- // see: https://github.com/Raven24/diaspora-federation/blob/master/lib/diaspora-federation/entities/reshare.rb
- if (!$item['item_private'] AND ($ret = diaspora_is_reshare($item["body"]))) {
- $tpl = get_markup_template('diaspora_reshare.tpl');
- $msg = replace_macros($tpl, array(
- '$root_handle' => xmlify($ret['root_handle']),
- '$root_guid' => $ret['root_guid'],
- '$guid' => $item['mid'],
- '$handle' => xmlify($myaddr),
- '$public' => $public,
- '$created' => $created,
- '$provider' => (($item['app']) ? $item['app'] : t('$projectname'))
- ));
- } else {
- $tpl = get_markup_template('diaspora_post.tpl');
- $msg = replace_macros($tpl, array(
- '$body' => xmlify($body),
- '$guid' => $item['mid'],
- '$poll' => $poll,
- '$handle' => xmlify($myaddr),
- '$public' => $public,
- '$created' => $created,
- '$provider' => (($item['app']) ? $item['app'] : t('$projectname'))
- ));
- }
-
- logger('diaspora_send_status: '.$owner['channel_name'].' -> '.$contact['xchan_name'].' base message: ' . $msg, LOGGER_DATA);
-
- $slap = 'xml=' . urlencode(urlencode(diaspora_msg_build($msg,$owner,$contact,$owner['channel_prvkey'],$contact['xchan_pubkey'],$public_batch)));
-
- $return_code = diaspora_transmit($owner,$contact,$slap,$public_batch);
-
-// logger('diaspora_send_status: guid: '.$item['mid'].' result '.$return_code, LOGGER_DEBUG);
-
- if(count($images)) {
- diaspora_send_images($item,$owner,$contact,$images,$public_batch);
- }
-
- return $return_code;
-}
-
-function diaspora_is_reshare($body) {
-
- $body = trim($body);
-
- // Skip if it isn't a pure repeated messages
- // Does it start with a share?
- if(strpos($body, "[share") > 0)
- return(false);
-
- // Does it end with a share?
- if(strlen($body) > (strrpos($body, "[/share]") + 8))
- return(false);
-
- $attributes = preg_replace("/\[share(.*?)\]\s?(.*?)\s?\[\/share\]\s?/ism","$1",$body);
- // Skip if there is no shared message in there
- if ($body == $attributes)
- return(false);
-
- $profile = "";
- preg_match("/profile='(.*?)'/ism", $attributes, $matches);
- if ($matches[1] != "")
- $profile = $matches[1];
-
- preg_match('/profile="(.*?)"/ism', $attributes, $matches);
- if ($matches[1] != "")
- $profile = $matches[1];
-
- $ret= array();
-
- $ret["root_handle"] = preg_replace("=https?://(.*)/u/(.*)=ism", "$2@$1", $profile);
- if (($ret["root_handle"] == $profile) OR ($ret["root_handle"] == ""))
- return(false);
-
- $link = "";
- preg_match("/link='(.*?)'/ism", $attributes, $matches);
- if ($matches[1] != "")
- $link = $matches[1];
-
- preg_match('/link="(.*?)"/ism', $attributes, $matches);
- if ($matches[1] != "")
- $link = $matches[1];
-
- $ret["root_guid"] = preg_replace("=https?://(.*)/posts/(.*)=ism", "$2", $link);
- if (($ret["root_guid"] == $link) OR ($ret["root_guid"] == ""))
- return(false);
-
- return($ret);
-}
-
-function diaspora_send_images($item,$owner,$contact,$images,$public_batch = false) {
- $a = get_app();
- if(! count($images))
- return;
- $mysite = substr($a->get_baseurl(),strpos($a->get_baseurl(),'://') + 3) . '/photo';
-
- $tpl = get_markup_template('diaspora_photo.tpl');
- foreach($images as $image) {
- if(! stristr($image['path'],$mysite))
- continue;
- $resource = str_replace('.jpg','',$image['file']);
- $resource = substr($resource,0,strpos($resource,'-'));
-
- $r = q("select * from photo where `resource_id` = '%s' and `uid` = %d limit 1",
- dbesc($resource),
- intval($owner['uid'])
- );
- if(! $r)
- continue;
- $public = (($r[0]['allow_cid'] || $r[0]['allow_gid'] || $r[0]['deny_cid'] || $r[0]['deny_gid']) ? 'false' : 'true' );
- $msg = replace_macros($tpl,array(
- '$path' => xmlify($image['path']),
- '$filename' => xmlify($image['file']),
- '$msg_guid' => xmlify($image['guid']),
- '$guid' => xmlify($r[0]['resource_id']),
- '$handle' => xmlify($image['handle']),
- '$public' => xmlify($public),
- '$created_at' => xmlify(datetime_convert('UTC','UTC',$r[0]['created'],'Y-m-d H:i:s \U\T\C'))
- ));
-
-
- logger('diaspora_send_photo: base message: ' . $msg, LOGGER_DATA);
- $slap = 'xml=' . urlencode(urlencode(diaspora_msg_build($msg,$owner,$contact,$owner['channel_prvkey'],$contact['xchan_pubkey'],$public_batch)));
-
- diaspora_transmit($owner,$contact,$slap,$public_batch);
- }
-
-}
-
-function diaspora_send_followup($item,$owner,$contact,$public_batch = false) {
-
- $a = get_app();
- $myaddr = $owner['channel_address'] . '@' . get_app()->get_hostname();
- $theiraddr = $contact['xchan_addr'];
-
- // Diaspora doesn't support threaded comments, but some
- // versions of Diaspora (i.e. Diaspora-pistos) support
- // likes on comments
- if(($item['verb'] === ACTIVITY_LIKE || $item['verb'] === ACTIVITY_DISLIKE) && $item['thr_parent']) {
- $p = q("select mid, parent_mid from item where mid = '%s' limit 1",
- dbesc($item['thr_parent'])
- );
- }
- else {
- // The first item in the `item` table with the parent id is the parent. However, MySQL doesn't always
- // return the items ordered by `item`.`id`, in which case the wrong item is chosen as the parent.
- // The only item with `parent` and `id` as the parent id is the parent item.
- $p = q("select * from item where parent = %d and id = %d limit 1",
- intval($item['parent']),
- intval($item['parent'])
- );
- }
- if($p)
- $parent = $p[0];
- else
- return;
-
-
- if(($item['verb'] === ACTIVITY_LIKE) && ($parent['mid'] === $parent['parent_mid'])) {
- $tpl = get_markup_template('diaspora_like.tpl');
- $like = true;
- $target_type = 'Post';
- $positive = 'true';
-
- if(($item_['item_restrict'] & ITEM_DELETED))
- logger('diaspora_send_followup: received deleted "like". Those should go to diaspora_send_retraction');
- }
- else {
- $tpl = get_markup_template('diaspora_comment.tpl');
- $like = false;
- }
-
- if($item['diaspora_meta'] && ! $like) {
- $diaspora_meta = json_decode($item['diaspora_meta'],true);
- if($diaspora_meta) {
- if(array_key_exists('iv',$diaspora_meta)) {
- $key = get_config('system','prvkey');
- $meta = json_decode(crypto_unencapsulate($diaspora_meta,$key),true);
- }
- else
- $meta = $diaspora_meta;
- }
- $signed_text = $meta['signed_text'];
- $authorsig = $meta['signature'];
- $signer = $meta['signer'];
- $text = $meta['body'];
- }
- else {
- $text = bb2diaspora_itembody($item);
-
- // sign it
-
- if($like)
- $signed_text = $item['mid'] . ';' . $target_type . ';' . $parent['mid'] . ';' . $positive . ';' . $myaddr;
- else
- $signed_text = $item['mid'] . ';' . $parent['mid'] . ';' . $text . ';' . $myaddr;
-
- $authorsig = base64_encode(rsa_sign($signed_text,$owner['channel_prvkey'],'sha256'));
-
- }
-
- $msg = replace_macros($tpl,array(
- '$guid' => xmlify($item['mid']),
- '$parent_guid' => xmlify($parent['mid']),
- '$target_type' =>xmlify($target_type),
- '$authorsig' => xmlify($authorsig),
- '$body' => xmlify($text),
- '$positive' => xmlify($positive),
- '$handle' => xmlify($myaddr)
- ));
-
- logger('diaspora_followup: base message: ' . $msg, LOGGER_DATA);
-
- $slap = 'xml=' . urlencode(urlencode(diaspora_msg_build($msg,$owner,$contact,$owner['channel_prvkey'],$contact['xchan_pubkey'],$public_batch)));
-
-
- return(diaspora_transmit($owner,$contact,$slap,$public_batch));
-}
-
-
-function diaspora_send_relay($item,$owner,$contact,$public_batch = false) {
-
-
- $a = get_app();
- $myaddr = $owner['channel_address'] . '@' . get_app()->get_hostname();
-
- $text = bb2diaspora_itembody($item);
-
- $body = $text;
-
- // Diaspora doesn't support threaded comments, but some
- // versions of Diaspora (i.e. Diaspora-pistos) support
- // likes on comments
-
-
- // That version is now dead so detect a "sublike" and
- // just send it as an activity.
-
- $sublike = false;
-
-
- if($item['verb'] === ACTIVITY_LIKE && $item['thr_parent']) {
- $sublike = true;
- }
-
-
- // The first item in the `item` table with the parent id is the parent. However, MySQL doesn't always
- // return the items ordered by `item`.`id`, in which case the wrong item is chosen as the parent.
- // The only item with `parent` and `id` as the parent id is the parent item.
- $p = q("select * from item where parent = %d and id = %d limit 1",
- intval($item['parent']),
- intval($item['parent'])
- );
-
- if($p)
- $parent = $p[0];
- else {
- logger('diaspora_send_relay: no parent');
- return;
- }
-
- $like = false;
- $relay_retract = false;
- $sql_sign_id = 'iid';
-
- if( $item['item_restrict'] & ITEM_DELETED) {
- $relay_retract = true;
-
- $target_type = ( ($item['verb'] === ACTIVITY_LIKE && (! $sublike)) ? 'Like' : 'Comment');
-
- $sql_sign_id = 'retract_iid';
- $tpl = get_markup_template('diaspora_relayable_retraction.tpl');
- }
- elseif(($item['verb'] === ACTIVITY_LIKE) && (! $sublike)) {
- $like = true;
-
- $target_type = ( $parent['mid'] === $parent['parent_mid'] ? 'Post' : 'Comment');
-// $positive = (($item['item_restrict'] & ITEM_DELETED) ? 'false' : 'true');
- $positive = 'true';
-
- $tpl = get_markup_template('diaspora_like_relay.tpl');
- }
- else { // item is a comment
- $tpl = get_markup_template('diaspora_comment_relay.tpl');
- }
-
- $diaspora_meta = (($item['diaspora_meta']) ? json_decode($item['diaspora_meta'],true) : '');
- if($diaspora_meta) {
- if(array_key_exists('iv',$diaspora_meta)) {
- $key = get_config('system','prvkey');
- $meta = json_decode(crypto_unencapsulate($diaspora_meta,$key),true);
- }
- else
- $meta = $diaspora_meta;
- $sender_signed_text = $meta['signed_text'];
- $authorsig = $meta['signature'];
- $handle = $meta['signer'];
- $text = $meta['body'];
- }
- else
- logger('diaspora_send_relay: original author signature not found');
-
- /* Since the author signature is only checked by the parent, not by the relay recipients,
- * I think it may not be necessary for us to do so much work to preserve all the original
- * signatures. The important thing that Diaspora DOES need is the original creator's handle.
- * Let's just generate that and forget about all the original author signature stuff.
- *
- * Note: this might be more of an problem if we want to support likes on comments for older
- * versions of Diaspora (diaspora-pistos), but since there are a number of problems with
- * doing that, let's ignore it for now.
- *
- *
- */
-// bug - nomadic identity may/will affect diaspora_handle_from_contact
- if(! $handle) {
- if($item['author_xchan'] === $owner['channel_hash'])
- $handle = $owner['channel_address'] . '@' . substr($a->get_baseurl(), strpos($a->get_baseurl(),'://') + 3);
- else
- $handle = diaspora_handle_from_contact($item['author_xchan']);
- }
- if(! $handle) {
- logger('diaspora_send_relay: no handle');
- return;
- }
-
- if(! $sender_signed_text) {
- if($relay_retract)
- $sender_signed_text = $item['mid'] . ';' . $target_type;
- elseif($like)
- $sender_signed_text = $positive . ';' . $item['mid'] . ';' . $target_type . ';' . $parent['mid'] . ';' . $handle;
- else
- $sender_signed_text = $item['mid'] . ';' . $parent['mid'] . ';' . $text . ';' . $handle;
- }
-
- // Sign the relayable with the top-level owner's signature
- //
- // We'll use the $sender_signed_text that we just created, instead of the $signed_text
- // stored in the database, because that provides the best chance that Diaspora will
- // be able to reconstruct the signed text the same way we did. This is particularly a
- // concern for the comment, whose signed text includes the text of the comment. The
- // smallest change in the text of the comment, including removing whitespace, will
- // make the signature verification fail. Since we translate from BB code to Diaspora's
- // markup at the top of this function, which is AFTER we placed the original $signed_text
- // in the database, it's hazardous to trust the original $signed_text.
-
- $parentauthorsig = base64_encode(rsa_sign($sender_signed_text,$owner['channel_prvkey'],'sha256'));
-
- if(! $text)
- logger('diaspora_send_relay: no text');
-
- $msg = replace_macros($tpl,array(
- '$guid' => xmlify($item['mid']),
- '$parent_guid' => xmlify($parent['mid']),
- '$target_type' =>xmlify($target_type),
- '$authorsig' => xmlify($authorsig),
- '$parentsig' => xmlify($parentauthorsig),
- '$body' => xmlify($text),
- '$positive' => xmlify($positive),
- '$handle' => xmlify($handle)
- ));
-
- logger('diaspora_send_relay: base message: ' . $msg, LOGGER_DATA);
-
- $slap = 'xml=' . urlencode(urlencode(diaspora_msg_build($msg,$owner,$contact,$owner['channel_prvkey'],$contact['xchan_pubkey'],$public_batch)));
-
- return(diaspora_transmit($owner,$contact,$slap,$public_batch));
-
-}
-
-
-
-function diaspora_send_retraction($item,$owner,$contact,$public_batch = false) {
-
- $a = get_app();
- $myaddr = $owner['channel_address'] . '@' . get_app()->get_hostname();
-
- // Check whether the retraction is for a top-level post or whether it's a relayable
- if( $item['mid'] !== $item['parent_mid'] ) {
-
- $tpl = get_markup_template('diaspora_relay_retraction.tpl');
- $target_type = (($item['verb'] === ACTIVITY_LIKE) ? 'Like' : 'Comment');
- }
- else {
-
- $tpl = get_markup_template('diaspora_signed_retract.tpl');
- $target_type = 'StatusMessage';
- }
-
- $signed_text = $item['mid'] . ';' . $target_type;
-
- $msg = replace_macros($tpl, array(
- '$guid' => xmlify($item['mid']),
- '$type' => xmlify($target_type),
- '$handle' => xmlify($myaddr),
- '$signature' => xmlify(base64_encode(rsa_sign($signed_text,$owner['channel_prvkey'],'sha256')))
- ));
-
- $slap = 'xml=' . urlencode(urlencode(diaspora_msg_build($msg,$owner,$contact,$owner['channel_prvkey'],$contact['xchan_pubkey'],$public_batch)));
-
- return(diaspora_transmit($owner,$contact,$slap,$public_batch));
-}
-
-function diaspora_send_mail($item,$owner,$contact) {
-
- $a = get_app();
- $myaddr = $owner['channel_address'] . '@' . get_app()->get_hostname();
-
- $r = q("select * from conv where id = %d and uid = %d limit 1",
- intval($item['convid']),
- intval($item['channel_id'])
- );
-
- if(! count($r)) {
- logger('diaspora_send_mail: conversation not found.');
- return;
- }
- $cnv = $r[0];
-
- $conv = array(
- 'guid' => xmlify($cnv['guid']),
- 'subject' => xmlify($cnv['subject']),
- 'created_at' => xmlify(datetime_convert('UTC','UTC',$cnv['created'],'Y-m-d H:i:s \U\T\C')),
- 'diaspora_handle' => xmlify($cnv['creator']),
- 'participant_handles' => xmlify($cnv['recips'])
- );
-
- if(array_key_exists('mail_flags',$item) && ($item['mail_flags'] & MAIL_OBSCURED)) {
- $key = get_config('system','prvkey');
-// if($item['title'])
-// $item['title'] = crypto_unencapsulate(json_decode_plus($item['title']),$key);
- if($item['body'])
- $item['body'] = crypto_unencapsulate(json_decode_plus($item['body']),$key);
- }
-
-
- $body = bb2diaspora($item['body']);
- $created = datetime_convert('UTC','UTC',$item['created'],'Y-m-d H:i:s \U\T\C');
-
- $signed_text = $item['mid'] . ';' . $cnv['guid'] . ';' . $body . ';'
- . $created . ';' . $myaddr . ';' . $cnv['guid'];
-
- $sig = base64_encode(rsa_sign($signed_text,$owner['channel_prvkey'],'sha256'));
-
- $msg = array(
- 'guid' => xmlify($item['mid']),
- 'parent_guid' => xmlify($cnv['guid']),
- 'parent_author_signature' => (($item['reply']) ? null : xmlify($sig)),
- 'author_signature' => xmlify($sig),
- 'text' => xmlify($body),
- 'created_at' => xmlify($created),
- 'diaspora_handle' => xmlify($myaddr),
- 'conversation_guid' => xmlify($cnv['guid'])
- );
-
- if($item['reply']) {
- $tpl = get_markup_template('diaspora_message.tpl');
- $xmsg = replace_macros($tpl, array('$msg' => $msg));
- }
- else {
- $conv['messages'] = array($msg);
- $tpl = get_markup_template('diaspora_conversation.tpl');
- $xmsg = replace_macros($tpl, array('$conv' => $conv));
- }
-
- logger('diaspora_conversation: ' . print_r($xmsg,true), LOGGER_DATA);
-
- $slap = 'xml=' . urlencode(urlencode(diaspora_msg_build($xmsg,$owner,$contact,$owner['channel_prvkey'],$contact['xchan_pubkey'],false)));
-
- return(diaspora_transmit($owner,$contact,$slap,false));
-
-
-}
-
-function diaspora_transmit($owner,$contact,$slap,$public_batch,$queue_run=false) {
-
- $enabled = intval(get_config('system','diaspora_enabled'));
- if(! $enabled) {
- return 200;
- }
-
- $allowed = get_pconfig($owner['channel_id'],'system','diaspora_allowed');
- if($allowed === false)
- $allowed = 1;
-
- if(! intval($allowed)) {
- return 200;
- }
-
- if($public_batch)
- $dest_url = $contact['hubloc_callback'] . '/public';
- else
- $dest_url = $contact['hubloc_callback'] . '/users/' . $contact['hubloc_guid'];
-
- logger('diaspora_transmit: URL: ' . $dest_url, LOGGER_DEBUG);
-
- if(intval(get_config('system','diaspora_test')))
- return 200;
-
- $a = get_app();
- $logid = random_string(4);
-
- logger('diaspora_transmit: ' . $logid . ' ' . $dest_url, LOGGER_DEBUG);
-
- $hash = random_string();
-
- $interval = ((get_config('system','delivery_interval') !== false)
- ? intval(get_config('system','delivery_interval')) : 2 );
-
- 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($owner['account_id']),
- intval($owner['channel_id']),
- dbesc('post'),
- dbesc($dest_url),
- intval(1),
- dbesc(datetime_convert()),
- dbesc(datetime_convert()),
- dbesc(''),
- dbesc($slap)
- );
-
- proc_run('php','include/deliver.php',$hash);
- if($interval)
- @time_sleep_until(microtime(true) + (float) $interval);
-
-}
diff --git a/include/dir_fns.php b/include/dir_fns.php
index 83073154a..e5f0e1e2b 100644
--- a/include/dir_fns.php
+++ b/include/dir_fns.php
@@ -151,16 +151,18 @@ function sync_directories($dirmode) {
$realm = get_directory_realm();
if ($realm == DIRECTORY_REALM) {
- $r = q("select * from site where (site_flags & %d) > 0 and site_url != '%s' and ( site_realm = '%s' or site_realm = '') ",
+ $r = q("select * from site where (site_flags & %d) > 0 and site_url != '%s' and site_type = %d and ( site_realm = '%s' or site_realm = '') ",
intval(DIRECTORY_MODE_PRIMARY|DIRECTORY_MODE_SECONDARY),
dbesc(z_root()),
+ intval(SITE_TYPE_ZOT),
dbesc($realm)
);
} else {
- $r = q("select * from site where (site_flags & %d) > 0 and site_url != '%s' and site_realm like '%s' ",
+ $r = q("select * from site where (site_flags & %d) > 0 and site_url != '%s' and site_realm like '%s' and site_type = %d ",
intval(DIRECTORY_MODE_PRIMARY|DIRECTORY_MODE_SECONDARY),
dbesc(z_root()),
- dbesc(protect_sprintf('%' . $realm . '%'))
+ dbesc(protect_sprintf('%' . $realm . '%')),
+ intval(SITE_TYPE_ZOT)
);
}
@@ -176,9 +178,10 @@ function sync_directories($dirmode) {
'site_directory' => DIRECTORY_FALLBACK_MASTER . '/dirsearch',
'site_realm' => DIRECTORY_REALM,
'site_valid' => 1
+
);
$x = q("insert into site ( site_url, site_flags, site_update, site_directory, site_realm, site_valid )
- values ( '%s', %d', '%s', '%s', '%s' ) ",
+ values ( '%s', %d, '%s', '%s', '%s', %d ) ",
dbesc($r[0]['site_url']),
intval($r[0]['site_flags']),
dbesc($r[0]['site_update']),
@@ -187,9 +190,11 @@ function sync_directories($dirmode) {
intval($r[0]['site_valid'])
);
- $r = q("select * from site where (site_flags & %d) > 0 and site_url != '%s'",
- intval(DIRECTORY_MODE_PRIMARY|DIRECTORY_MODE_SECONDARY),
- dbesc(z_root())
+ $r = q("select * from site where site_flags in (%d, %d) and site_url != '%s' and site_type = %d ",
+ intval(DIRECTORY_MODE_PRIMARY),
+ intval(DIRECTORY_MODE_SECONDARY),
+ dbesc(z_root()),
+ intval(SITE_TYPE_ZOT)
);
}
if (! $r)
@@ -389,19 +394,13 @@ function local_dir_update($uid, $force) {
logger('hidden: ' . $hidden);
- $r = q("select xchan_flags from xchan where xchan_hash = '%s' limit 1",
+ $r = q("select xchan_hidden from xchan where xchan_hash = '%s' limit 1",
dbesc($p[0]['channel_hash'])
);
- // Be careful - XCHAN_FLAGS_HIDDEN should evaluate to 1
- if (($r[0]['xchan_flags'] & XCHAN_FLAGS_HIDDEN) != $hidden)
- $new_flags = $r[0]['xchan_flags'] ^ XCHAN_FLAGS_HIDDEN;
- else
- $new_flags = $r[0]['xchan_flags'];
-
- if ($new_flags != $r[0]['xchan_flags']) {
- $r = q("update xchan set xchan_flags = %d where xchan_hash = '%s'",
- intval($new_flags),
+ if(intval($r[0]['xchan_hidden']) != $hidden) {
+ $r = q("update xchan set xchan_hidden = %d where xchan_hash = '%s'",
+ intval($hidden),
dbesc($p[0]['channel_hash'])
);
}
diff --git a/include/enotify.php b/include/enotify.php
index b1aae816b..bbddcdd14 100644
--- a/include/enotify.php
+++ b/include/enotify.php
@@ -36,9 +36,8 @@ function notification($params) {
}
if ($params['to_xchan']) {
$y = q("select channel.*, account.* from channel left join account on channel_account_id = account_id
- where channel_hash = '%s' and not (channel_pageflags & %d)>0 limit 1",
- dbesc($params['to_xchan']),
- intval(PAGE_REMOVED)
+ where channel_hash = '%s' and channel_removed = 0 limit 1",
+ dbesc($params['to_xchan'])
);
}
if ($x & $y) {
@@ -82,8 +81,9 @@ function notification($params) {
localize_item($i);
$title = $i['title'];
$body = $i['body'];
- $private = (($i['item_private']) || ($i['item_flags'] & ITEM_OBSCURED));
- } else {
+ $private = (($i['item_private']) || intval($i['item_obscured']));
+ }
+ else {
$title = $params['item']['title'];
$body = $params['item']['body'];
}
@@ -97,7 +97,7 @@ function notification($params) {
if ($params['type'] == NOTIFY_MAIL) {
logger('notification: mail');
- $subject = sprintf( t('[Red:Notify] New mail received at %s'),$sitename);
+ $subject = sprintf( t('[Hubzilla:Notify] New mail received at %s'),$sitename);
$preamble = sprintf( t('%1$s, %2$s sent you a new private message at %3$s.'),$recip['channel_name'], $sender['xchan_name'],$sitename);
$epreamble = sprintf( t('%1$s sent you %2$s.'),'[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]', '[zrl=$itemlink]' . t('a private message') . '[/zrl]');
@@ -171,7 +171,7 @@ function notification($params) {
$item_post_type);
// "your post"
- if($p[0]['owner']['xchan_name'] == $p[0]['author']['xchan_name'] && ($p[0]['item_flags'] & ITEM_WALL))
+ if($p[0]['owner']['xchan_name'] == $p[0]['author']['xchan_name'] && intval($p[0]['item_wall']))
$dest_str = sprintf(t('%1$s, %2$s commented on [zrl=%3$s]your %4$s[/zrl]'),
$recip['channel_name'],
'[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]',
@@ -183,7 +183,7 @@ function notification($params) {
// Before this we have the name of the replier on the subject rendering
// differents subjects for messages on the same thread.
- $subject = sprintf( t('[Red:Notify] Comment to conversation #%1$d by %2$s'), $parent_id, $sender['xchan_name']);
+ $subject = sprintf( t('[Hubzilla:Notify] Comment to conversation #%1$d by %2$s'), $parent_id, $sender['xchan_name']);
$preamble = sprintf( t('%1$s, %2$s commented on an item/conversation you have been following.'), $recip['channel_name'], $sender['xchan_name']);
$epreamble = $dest_str;
@@ -193,7 +193,7 @@ function notification($params) {
}
if($params['type'] == NOTIFY_WALL) {
- $subject = sprintf( t('[Red:Notify] %s posted to your profile wall') , $sender['xchan_name']);
+ $subject = sprintf( t('[Hubzilla:Notify] %s posted to your profile wall') , $sender['xchan_name']);
$preamble = sprintf( t('%1$s, %2$s posted to your profile wall at %3$s') , $recip['channel_name'], $sender['xchan_name'], $sitename);
@@ -221,7 +221,7 @@ function notification($params) {
return;
}
- $subject = sprintf( t('[Red:Notify] %s tagged you') , $sender['xchan_name']);
+ $subject = sprintf( t('[Hubzilla:Notify] %s tagged you') , $sender['xchan_name']);
$preamble = sprintf( t('%1$s, %2$s tagged you at %3$s') , $recip['channel_name'], $sender['xchan_name'], $sitename);
$epreamble = sprintf( t('%1$s, %2$s [zrl=%3$s]tagged you[/zrl].') ,
$recip['channel_name'],
@@ -235,7 +235,7 @@ function notification($params) {
}
if ($params['type'] == NOTIFY_POKE) {
- $subject = sprintf( t('[Red:Notify] %1$s poked you') , $sender['xchan_name']);
+ $subject = sprintf( t('[Hubzilla:Notify] %1$s poked you') , $sender['xchan_name']);
$preamble = sprintf( t('%1$s, %2$s poked you at %3$s') , $recip['channel_name'], $sender['xchan_name'], $sitename);
$epreamble = sprintf( t('%1$s, %2$s [zrl=%2$s]poked you[/zrl].') ,
$recip['channel_name'],
@@ -253,7 +253,7 @@ function notification($params) {
}
if ($params['type'] == NOTIFY_TAGSHARE) {
- $subject = sprintf( t('[Red:Notify] %s tagged your post') , $sender['xchan_name']);
+ $subject = sprintf( t('[Hubzilla:Notify] %s tagged your post') , $sender['xchan_name']);
$preamble = sprintf( t('%1$s, %2$s tagged your post at %3$s') , $recip['channel_name'],$sender['xchan_name'], $sitename);
$epreamble = sprintf( t('%1$s, %2$s tagged [zrl=%3$s]your post[/zrl]') ,
$recip['channel_name'],
@@ -267,7 +267,7 @@ function notification($params) {
}
if ($params['type'] == NOTIFY_INTRO) {
- $subject = sprintf( t('[Red:Notify] Introduction received'));
+ $subject = sprintf( t('[Hubzilla:Notify] Introduction received'));
$preamble = sprintf( t('%1$s, you\'ve received an new connection request from \'%2$s\' at %3$s'), $recip['channel_name'], $sender['xchan_name'], $sitename);
$epreamble = sprintf( t('%1$s, you\'ve received [zrl=%2$s]a new connection request[/zrl] from %3$s.'),
$recip['channel_name'],
@@ -282,7 +282,7 @@ function notification($params) {
}
if ($params['type'] == NOTIFY_SUGGEST) {
- $subject = sprintf( t('[Red:Notify] Friend suggestion received'));
+ $subject = sprintf( t('[Hubzilla:Notify] Friend suggestion received'));
$preamble = sprintf( t('%1$s, you\'ve received a friend suggestion from \'%2$s\' at %3$s'), $recip['channel_name'], $sender['xchan_name'], $sitename);
$epreamble = sprintf( t('%1$s, you\'ve received [zrl=%2$s]a friend suggestion[/zrl] for %3$s from %4$s.'),
$recip['channel_name'],
@@ -315,9 +315,12 @@ function notification($params) {
'epreamble' => $epreamble,
'body' => $body,
'sitelink' => $sitelink,
+ 'sitename' => $sitename,
'tsitelink' => $tsitelink,
'hsitelink' => $hsitelink,
- 'itemlink' => $itemlink
+ 'itemlink' => $itemlink,
+ 'sender' => $sender,
+ 'recipient' => $recip
);
call_hooks('enotify', $h);
@@ -505,7 +508,7 @@ function notification($params) {
$private_activity = true;
case NOTIFY_MAIL:
$datarray['textversion'] = $datarray['htmlversion'] = $datarray['title'] = '';
- $datarray['subject'] = preg_replace('/' . preg_quote(t('[Red:Notify]')) . '/','$0*',$datarray['subject']);
+ $datarray['subject'] = preg_replace('/' . preg_quote(t('[Hubzilla:Notify]')) . '/','$0*',$datarray['subject']);
break;
default:
break;
@@ -642,4 +645,4 @@ class enotify {
);
logger("notification: enotify::send returns " . $res, LOGGER_DEBUG);
}
-} \ No newline at end of file
+}
diff --git a/include/event.php b/include/event.php
index 3b48837f1..e303ad232 100644
--- a/include/event.php
+++ b/include/event.php
@@ -63,9 +63,9 @@ function ical_wrapper($ev) {
return '';
$o .= "BEGIN:VCALENDAR";
- $o .= "\nVERSION:2.0";
- $o .= "\nMETHOD:PUBLISH";
- $o .= "\nPRODID:-//" . get_config('system','sitename') . "//" . PLATFORM_NAME . "//" . strtoupper(get_app()->language). "\n";
+ $o .= "\r\nVERSION:2.0";
+ $o .= "\r\nMETHOD:PUBLISH";
+ $o .= "\r\nPRODID:-//" . get_config('system','sitename') . "//" . PLATFORM_NAME . "//" . strtoupper(get_app()->language). "\r\n";
if(array_key_exists('start', $ev))
$o .= format_event_ical($ev);
else {
@@ -73,38 +73,84 @@ function ical_wrapper($ev) {
$o .= format_event_ical($e);
}
}
- $o .= "\nEND:VCALENDAR\n";
+ $o .= "\r\nEND:VCALENDAR\r\n";
return $o;
}
function format_event_ical($ev) {
+ if($ev['type'] === 'task')
+ return format_todo_ical($ev);
+
$o = '';
- $o .= "\nBEGIN:VEVENT";
+ $o .= "\r\nBEGIN:VEVENT";
+
+ $o .= "\r\nCREATED:" . datetime_convert('UTC','UTC', $ev['created'],'Ymd\\THis\\Z');
+ $o .= "\r\nLAST-MODIFIED:" . datetime_convert('UTC','UTC', $ev['edited'],'Ymd\\THis\\Z');
+ $o .= "\r\nDTSTAMP:" . datetime_convert('UTC','UTC', $ev['edited'],'Ymd\\THis\\Z');
if($ev['start'])
- $o .= "\nDTSTART:" . datetime_convert('UTC','UTC', $ev['start'],'Ymd\\THis' . (($ev['adjust']) ? '\\Z' : ''));
+ $o .= "\r\nDTSTART:" . datetime_convert('UTC','UTC', $ev['start'],'Ymd\\THis' . (($ev['adjust']) ? '\\Z' : ''));
if($ev['finish'] && ! $ev['nofinish'])
- $o .= "\nDTEND:" . datetime_convert('UTC','UTC', $ev['finish'],'Ymd\\THis' . (($ev['adjust']) ? '\\Z' : ''));
+ $o .= "\r\nDTEND:" . datetime_convert('UTC','UTC', $ev['finish'],'Ymd\\THis' . (($ev['adjust']) ? '\\Z' : ''));
if($ev['summary'])
- $o .= "\nSUMMARY:" . format_ical_text($ev['summary']);
+ $o .= "\r\nSUMMARY:" . format_ical_text($ev['summary']);
if($ev['location'])
- $o .= "\nLOCATION:" . format_ical_text($ev['location']);
+ $o .= "\r\nLOCATION:" . format_ical_text($ev['location']);
if($ev['description'])
- $o .= "\nDESCRIPTION:" . format_ical_text($ev['description']);
- $o .= "\nUID:" . $ev['event_hash'] ;
- $o .= "\nEND:VEVENT\n";
+ $o .= "\r\nDESCRIPTION:" . format_ical_text($ev['description']);
+ if($ev['event_priority'])
+ $o .= "\r\nPRIORITY:" . intval($ev['event_priority']);
+ $o .= "\r\nUID:" . $ev['event_hash'] ;
+ $o .= "\r\nEND:VEVENT\r\n";
+
+ return $o;
+}
+
+
+function format_todo_ical($ev) {
+
+ $o = '';
+
+ $o .= "\r\nBEGIN:VTODO";
+ $o .= "\r\nCREATED:" . datetime_convert('UTC','UTC', $ev['created'],'Ymd\\THis\\Z');
+ $o .= "\r\nLAST-MODIFIED:" . datetime_convert('UTC','UTC', $ev['edited'],'Ymd\\THis\\Z');
+ $o .= "\r\nDTSTAMP:" . datetime_convert('UTC','UTC', $ev['edited'],'Ymd\\THis\\Z');
+ if($ev['start'])
+ $o .= "\r\nDTSTART:" . datetime_convert('UTC','UTC', $ev['start'],'Ymd\\THis' . (($ev['adjust']) ? '\\Z' : ''));
+ if($ev['finish'] && ! $ev['nofinish'])
+ $o .= "\r\nDUE:" . datetime_convert('UTC','UTC', $ev['finish'],'Ymd\\THis' . (($ev['adjust']) ? '\\Z' : ''));
+ if($ev['summary'])
+ $o .= "\r\nSUMMARY:" . format_ical_text($ev['summary']);
+ if($ev['event_status']) {
+ $o .= "\r\nSTATUS:" . $ev['event_status'];
+ if($ev['event_status'] === 'COMPLETED')
+ $o .= "\r\nCOMPLETED:" . datetime_convert('UTC','UTC', $ev['event_status_date'],'Ymd\\THis\\Z');
+ }
+ if(intval($ev['event_percent']))
+ $o .= "\r\nPERCENT-COMPLETE:" . $ev['event_percent'];
+ if(intval($ev['event_sequence']))
+ $o .= "\r\nSEQUENCE:" . $ev['event_sequence'];
+ if($ev['location'])
+ $o .= "\r\nLOCATION:" . format_ical_text($ev['location']);
+ if($ev['description'])
+ $o .= "\r\nDESCRIPTION:" . format_ical_text($ev['description']);
+ $o .= "\r\nUID:" . $ev['event_hash'] ;
+ if($ev['event_priority'])
+ $o .= "\r\nPRIORITY:" . intval($ev['event_priority']);
+ $o .= "\r\nEND:VTODO\r\n";
return $o;
}
+
function format_ical_text($s) {
require_once('include/bbcode.php');
require_once('include/html2plain.php');
- return(wordwrap(str_replace(',','\\,',html2plain(bbcode($s))),72,"\n ",true));
+ return(wordwrap(str_replace(array(',',';','\\'),array('\\,','\\;','\\\\'),html2plain(bbcode($s))),72,"\r\n ",true));
}
@@ -218,11 +264,17 @@ function ev_compare($a, $b) {
function event_store_event($arr) {
- $arr['created'] = (($arr['created']) ? $arr['created'] : datetime_convert());
- $arr['edited'] = (($arr['edited']) ? $arr['edited'] : datetime_convert());
- $arr['type'] = (($arr['type']) ? $arr['type'] : 'event' );
- $arr['event_xchan'] = (($arr['event_xchan']) ? $arr['event_xchan'] : '');
+ $arr['created'] = (($arr['created']) ? $arr['created'] : datetime_convert());
+ $arr['edited'] = (($arr['edited']) ? $arr['edited'] : datetime_convert());
+ $arr['type'] = (($arr['type']) ? $arr['type'] : 'event' );
+ $arr['event_xchan'] = (($arr['event_xchan']) ? $arr['event_xchan'] : '');
+ $arr['event_priority'] = (($arr['event_priority']) ? $arr['event_priority'] : 0);
+
+ if(array_key_exists('event_status_date',$arr))
+ $arr['event_status_date'] = datetime_convert('UTC','UTC', $arr['event_status_date']);
+ else
+ $arr['event_status_date'] = NULL_DATE;
// Existing event being modified
@@ -265,6 +317,12 @@ function event_store_event($arr) {
`type` = '%s',
`adjust` = %d,
`nofinish` = %d,
+ `event_status` = '%s',
+ `event_status_date` = '%s',
+ `event_percent` = %d,
+ `event_repeat` = '%s',
+ `event_sequence` = %d,
+ `event_priority` = %d,
`allow_cid` = '%s',
`allow_gid` = '%s',
`deny_cid` = '%s',
@@ -280,6 +338,12 @@ function event_store_event($arr) {
dbesc($arr['type']),
intval($arr['adjust']),
intval($arr['nofinish']),
+ dbesc($arr['event_status']),
+ dbesc($arr['event_status_date']),
+ intval($arr['event_percent']),
+ dbesc($arr['event_repeat']),
+ intval($arr['event_sequence']),
+ intval($arr['event_priority']),
dbesc($arr['allow_cid']),
dbesc($arr['allow_gid']),
dbesc($arr['deny_cid']),
@@ -298,8 +362,8 @@ function event_store_event($arr) {
$hash = random_string() . '@' . get_app()->get_hostname();
$r = q("INSERT INTO event ( uid,aid,event_xchan,event_hash,created,edited,start,finish,summary,description,location,type,
- adjust,nofinish,allow_cid,allow_gid,deny_cid,deny_gid)
- VALUES ( %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, '%s', '%s', '%s', '%s' ) ",
+ adjust,nofinish, event_status, event_status_date, event_percent, event_repeat, event_sequence, event_priority, allow_cid,allow_gid,deny_cid,deny_gid)
+ VALUES ( %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, '%s', '%s', %d, '%s', %d, %d, '%s', '%s', '%s', '%s' ) ",
intval($arr['uid']),
intval($arr['account']),
dbesc($arr['event_xchan']),
@@ -314,6 +378,12 @@ function event_store_event($arr) {
dbesc($arr['type']),
intval($arr['adjust']),
intval($arr['nofinish']),
+ dbesc($arr['event_status']),
+ dbesc($arr['event_status_date']),
+ intval($arr['event_percent']),
+ dbesc($arr['event_repeat']),
+ intval($arr['event_sequence']),
+ intval($arr['event_priority']),
dbesc($arr['allow_cid']),
dbesc($arr['allow_gid']),
dbesc($arr['deny_cid']),
@@ -413,9 +483,15 @@ require_once('vendor/autoload.php');
$ical = VObject\Reader::read($s);
if($ical) {
- foreach($ical->VEVENT as $event) {
- event_import_ical($event,$uid);
-
+ if($ical->VEVENT) {
+ foreach($ical->VEVENT as $event) {
+ event_import_ical($event,$uid);
+ }
+ }
+ if($ical->VTODO) {
+ foreach($ical->VTODO as $event) {
+ event_import_ical_task($event,$uid);
+ }
}
}
@@ -450,6 +526,105 @@ function event_import_ical($ical, $uid) {
// logger('dtstart: ' . var_export($dtstart,true));
+
+ switch($dtstart->timezone_type) {
+ case VObject\Property\DateTime::UTC :
+ $ev['adjust'] = 0;
+ break;
+ case VObject\Property\DateTime::LOCALTZ :
+ default:
+ $ev['adjust'] = 1;
+ break;
+ }
+
+ $ev['start'] = datetime_convert((($ev['adjust']) ? 'UTC' : date_default_timezone_get()),'UTC',
+ $dtstart->format(\DateTime::W3C));
+
+
+ if(isset($ical->DTEND)) {
+ $dtend = $ical->DTEND->getDateTime();
+ $ev['finish'] = datetime_convert((($ev['adjust']) ? 'UTC' : date_default_timezone_get()),'UTC',
+ $dtend->format(\DateTime::W3C));
+ }
+ else
+ $ev['nofinish'] = 1;
+
+
+ if($ev['start'] === $ev['finish'])
+ $ev['nofinish'] = 1;
+
+ if(isset($ical->CREATED)) {
+ $created = $ical->CREATED->getDateTime();
+ $ev['created'] = datetime_convert('UTC','UTC',$created->format(\DateTime::W3C));
+ }
+
+ if(isset($ical->{'LAST-MODIFIED'})) {
+ $edited = $ical->{'LAST-MODIFIED'}->getDateTime();
+ $ev['edited'] = datetime_convert('UTC','UTC',$edited->format(\DateTime::W3C));
+ }
+
+ if(isset($ical->LOCATION))
+ $ev['location'] = (string) $ical->LOCATION;
+ if(isset($ical->DESCRIPTION))
+ $ev['description'] = (string) $ical->DESCRIPTION;
+ if(isset($ical->SUMMARY))
+ $ev['summary'] = (string) $ical->SUMMARY;
+ if(isset($ical->PRIORITY))
+ $ev['event_priority'] = intval((string) $ical->PRIORITY);
+
+ if(isset($ical->UID)) {
+ $evuid = (string) $ical->UID;
+ $r = q("SELECT * FROM event WHERE event_hash = '%s' AND uid = %d LIMIT 1",
+ dbesc($evuid),
+ intval($uid)
+ );
+ if($r)
+ $ev['event_hash'] = $evuid;
+ else
+ $ev['external_id'] = $evuid;
+ }
+
+ if($ev['summary'] && $ev['start']) {
+ $ev['event_xchan'] = $channel['channel_hash'];
+ $ev['uid'] = $channel['channel_id'];
+ $ev['account'] = $channel['channel_account_id'];
+ $ev['private'] = 1;
+ $ev['allow_cid'] = '<' . $channel['channel_hash'] . '>';
+
+ logger('storing event: ' . print_r($ev,true), LOGGER_ALL);
+ $event = event_store_event($ev);
+ if($event) {
+ $item_id = event_store_item($ev,$event);
+ return true;
+ }
+ }
+
+ return false;
+
+}
+
+function event_import_ical_task($ical, $uid) {
+
+ $c = q("select * from channel where channel_id = %d limit 1",
+ intval($uid)
+ );
+
+ if(! $c)
+ return false;
+
+ $channel = $c[0];
+ $ev = array();
+
+
+ if(! isset($ical->DTSTART)) {
+ logger('no event start');
+ return false;
+ }
+
+ $dtstart = $ical->DTSTART->getDateTime();
+
+// logger('dtstart: ' . var_export($dtstart,true));
+
if(($dtstart->timezone_type == 2) || (($dtstart->timezone_type == 3) && ($dtstart->timezone === 'UTC'))) {
$ev['adjust'] = 1;
}
@@ -461,8 +636,8 @@ function event_import_ical($ical, $uid) {
$dtstart->format(\DateTime::W3C));
- if(isset($ical->DTEND)) {
- $dtend = $ical->DTEND->getDateTime();
+ if(isset($ical->DUE)) {
+ $dtend = $ical->DUE->getDateTime();
$ev['finish'] = datetime_convert((($ev['adjust']) ? 'UTC' : date_default_timezone_get()),'UTC',
$dtend->format(\DateTime::W3C));
}
@@ -478,6 +653,11 @@ function event_import_ical($ical, $uid) {
$ev['created'] = datetime_convert('UTC','UTC',$created->format(\DateTime::W3C));
}
+ if(isset($ical->{'DTSTAMP'})) {
+ $edited = $ical->{'DTSTAMP'}->getDateTime();
+ $ev['edited'] = datetime_convert('UTC','UTC',$edited->format(\DateTime::W3C));
+ }
+
if(isset($ical->{'LAST-MODIFIED'})) {
$edited = $ical->{'LAST-MODIFIED'}->getDateTime();
$ev['edited'] = datetime_convert('UTC','UTC',$edited->format(\DateTime::W3C));
@@ -489,6 +669,10 @@ function event_import_ical($ical, $uid) {
$ev['description'] = (string) $ical->DESCRIPTION;
if(isset($ical->SUMMARY))
$ev['summary'] = (string) $ical->SUMMARY;
+ if(isset($ical->PRIORITY))
+ $ev['event_priority'] = intval((string) $ical->PRIORITY);
+
+ $stored_event = null;
if(isset($ical->UID)) {
$evuid = (string) $ical->UID;
@@ -496,12 +680,38 @@ function event_import_ical($ical, $uid) {
dbesc($evuid),
intval($uid)
);
- if($r)
+ if($r) {
$ev['event_hash'] = $evuid;
- else
+ $stored_event = $r[0];
+ }
+ else {
$ev['external_id'] = $evuid;
+ }
}
-
+
+ if(isset($ical->SEQUENCE)) {
+ $ev['event_sequence'] = (string) $ical->SEQUENCE;
+ // see if our stored event is more current than the one we're importing
+ if((intval($ev['event_sequence']) <= intval($stored_event['event_sequence']))
+ && ($ev['edited'] <= $stored_event['edited']))
+ return false;
+ }
+
+ if(isset($ical->STATUS)) {
+ $ev['event_status'] = (string) $ical->STATUS;
+ }
+
+ if(isset($ical->{'COMPLETED'})) {
+ $completed = $ical->{'COMPLETED'}->getDateTime();
+ $ev['event_status_date'] = datetime_convert('UTC','UTC',$completed->format(\DateTime::W3C));
+ }
+
+ if(isset($ical->{'PERCENT-COMPLETE'})) {
+ $ev['event_percent'] = (string) $ical->{'PERCENT-COMPLETE'} ;
+ }
+
+ $ev['type'] = 'task';
+
if($ev['summary'] && $ev['start']) {
$ev['event_xchan'] = $channel['channel_hash'];
$ev['uid'] = $channel['channel_id'];
@@ -522,6 +732,10 @@ function event_import_ical($ical, $uid) {
}
+
+
+
+
function event_store_item($arr, $event) {
require_once('include/datetime.php');
@@ -541,12 +755,15 @@ function event_store_item($arr, $event) {
}
}
+
+
$item_arr = array();
$prefix = '';
// $birthday = false;
if($event['type'] === 'birthday') {
- $prefix = t('This event has been added to your calendar.');
+ if(! is_sys_channel($arr['uid']))
+ $prefix = t('This event has been added to your calendar.');
// $birthday = true;
// The event is created on your own site by the system, but appears to belong
@@ -582,7 +799,12 @@ function event_store_item($arr, $event) {
$private = (($arr['allow_cid'] || $arr['allow_gid'] || $arr['deny_cid'] || $arr['deny_gid']) ? 1 : 0);
- q("UPDATE item SET title = '%s', body = '%s', object = '%s', allow_cid = '%s', allow_gid = '%s', deny_cid = '%s', deny_gid = '%s', edited = '%s', item_flags = %d, item_private = %d, obj_type = '%s' WHERE id = %d AND uid = %d",
+ // @FIXME can only update sig if we have the author's channel on this site
+ // Until fixed, set it to nothing so it won't give us signature errors
+
+ $sig = '';
+
+ q("UPDATE item SET title = '%s', body = '%s', object = '%s', allow_cid = '%s', allow_gid = '%s', deny_cid = '%s', deny_gid = '%s', edited = '%s', sig = '%s', item_flags = %d, item_private = %d, obj_type = '%s' WHERE id = %d AND uid = %d",
dbesc($arr['summary']),
dbesc($prefix . format_event_bbcode($arr)),
dbesc($object),
@@ -591,6 +813,7 @@ function event_store_item($arr, $event) {
dbesc($arr['deny_cid']),
dbesc($arr['deny_gid']),
dbesc($arr['edited']),
+ dbesc($sig),
intval($r[0]['item_flags']),
intval($private),
dbesc(ACTIVITY_OBJ_EVENT),
@@ -629,48 +852,61 @@ function event_store_item($arr, $event) {
$private = (($arr['allow_cid'] || $arr['allow_gid'] || $arr['deny_cid'] || $arr['deny_gid']) ? 1 : 0);
+ $item_wall = 0;
+ $item_origin = 0;
+ $item_thread_top = 0;
+
if($item) {
$item_arr['id'] = $item['id'];
}
else {
$wall = (($z[0]['channel_hash'] == $event['event_xchan']) ? true : false);
-
- $item_flags = ITEM_THREAD_TOP;
+ $item_thread_top = 1;
if($wall) {
- $item_flags |= ITEM_WALL;
- $item_flags |= ITEM_ORIGIN;
+ $item_wall = 1;
+ $item_origin = 1;
}
- $item_arr['item_flags'] = $item_flags;
}
if(! $arr['mid'])
$arr['mid'] = item_message_id();
- $item_arr['aid'] = $z[0]['channel_account_id'];
- $item_arr['uid'] = $arr['uid'];
- $item_arr['author_xchan'] = $arr['event_xchan'];
- $item_arr['mid'] = $arr['mid'];
- $item_arr['parent_mid'] = $arr['mid'];
-
- $item_arr['owner_xchan'] = (($wall) ? $z[0]['channel_hash'] : $arr['event_xchan']);
- $item_arr['author_xchan'] = $arr['event_xchan'];
- $item_arr['title'] = $arr['summary'];
- $item_arr['allow_cid'] = $arr['allow_cid'];
- $item_arr['allow_gid'] = $arr['allow_gid'];
- $item_arr['deny_cid'] = $arr['deny_cid'];
- $item_arr['deny_gid'] = $arr['deny_gid'];
- $item_arr['item_private'] = $private;
- $item_arr['verb'] = ACTIVITY_POST;
+ $item_arr['aid'] = $z[0]['channel_account_id'];
+ $item_arr['uid'] = $arr['uid'];
+ $item_arr['author_xchan'] = $arr['event_xchan'];
+ $item_arr['mid'] = $arr['mid'];
+ $item_arr['parent_mid'] = $arr['mid'];
+ $item_arr['owner_xchan'] = (($wall) ? $z[0]['channel_hash'] : $arr['event_xchan']);
+ $item_arr['author_xchan'] = $arr['event_xchan'];
+ $item_arr['title'] = $arr['summary'];
+ $item_arr['allow_cid'] = $arr['allow_cid'];
+ $item_arr['allow_gid'] = $arr['allow_gid'];
+ $item_arr['deny_cid'] = $arr['deny_cid'];
+ $item_arr['deny_gid'] = $arr['deny_gid'];
+ $item_arr['item_private'] = $private;
+ $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;;
+
+ $attach = array(array(
+ 'href' => z_root() . '/events/ical/' . urlencode($event['event_hash']),
+ 'length' => 0,
+ 'type' => 'text/calendar',
+ 'title' => t('event') . '-' . $event['event_hash'],
+ 'revision' => ''
+ ));
- if(array_key_exists('term', $arr))
- $item_arr['term'] = $arr['term'];
+ $item_arr['attach'] = $attach;
- $item_arr['resource_type'] = 'event';
- $item_arr['resource_id'] = $event['event_hash'];
- $item_arr['obj_type'] = ACTIVITY_OBJ_EVENT;
+ if(array_key_exists('term', $arr))
+ $item_arr['term'] = $arr['term'];
- $item_arr['body'] = $prefix . format_event_bbcode($arr);
+ $item_arr['resource_type'] = 'event';
+ $item_arr['resource_id'] = $event['event_hash'];
+ $item_arr['obj_type'] = ACTIVITY_OBJ_EVENT;
+ $item_arr['body'] = $prefix . format_event_bbcode($arr);
// if it's local send the permalink to the channel page.
// otherwise we'll fallback to /display/$message_id
@@ -710,3 +946,38 @@ function event_store_item($arr, $event) {
return $item_id;
}
}
+
+
+function todo_stat() {
+ return array(
+ '' => t('Not specified'),
+ 'NEEDS-ACTION' => t('Needs Action'),
+ 'COMPLETED' => t('Completed'),
+ 'IN-PROCESS' => t('In Process'),
+ 'CANCELLED' => t('Cancelled')
+ );
+}
+
+
+function tasks_fetch($arr) {
+
+ if(! local_channel())
+ return;
+
+ $ret = array();
+ $sql_extra = " and event_status != 'COMPLETED' ";
+ if($arr && $arr['all'] == 1)
+ $sql_extra = '';
+
+ $r = q("select * from event where type = 'task' and uid = %d $sql_extra order by created desc",
+ intval(local_channel())
+ );
+
+ $ret['success'] = (($r) ? true : false);
+ if($r) {
+ $ret['tasks'] = $r;
+ }
+
+ return $ret;
+
+}
diff --git a/include/expire.php b/include/expire.php
index e5d456896..e75594b5f 100644
--- a/include/expire.php
+++ b/include/expire.php
@@ -12,10 +12,7 @@ function expire_run($argv, $argc){
// perform final cleanup on previously delete items
- $r = q("select id from item where (item_restrict & %d) > 0 and (item_restrict & %d) = 0
- and changed < %s - INTERVAL %s",
- intval(ITEM_DELETED),
- intval(ITEM_PENDING_REMOVE),
+ $r = q("select id from item where item_deleted = 1 and item_pending_remove = 0 and changed < %s - INTERVAL %s",
db_utcnow(), db_quoteinterval('10 DAY')
);
if ($r) {
@@ -27,8 +24,7 @@ function expire_run($argv, $argc){
// physically remove anything that has been deleted for more than two months
/** @FIXME - this is a wretchedly inefficient query */
- $r = q("delete from item where ( item_restrict & %d ) > 0 and changed < %s - INTERVAL %s",
- intval(ITEM_PENDING_REMOVE),
+ $r = q("delete from item where item_pending_remove = 1 and changed < %s - INTERVAL %s",
db_utcnow(), db_quoteinterval('36 DAY')
);
@@ -49,7 +45,7 @@ function expire_run($argv, $argc){
foreach ($r as $rr) {
// expire the sys channel separately
- if ($rr['channel_pageflags'] & PAGE_SYSTEM)
+ if (intval($rr['channel_system']))
continue;
// service class default (if non-zero) over-rides the site default
diff --git a/include/externals.php b/include/externals.php
index b0f853dc6..18c034bb2 100644
--- a/include/externals.php
+++ b/include/externals.php
@@ -28,9 +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 order by $randfunc limit 1",
+ $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",
dbesc(z_root()),
- intval(DIRECTORY_MODE_STANDALONE)
+ intval(DIRECTORY_MODE_STANDALONE),
+ intval(SITE_TYPE_ZOT)
);
if($r)
$url = $r[0]['site_url'];
@@ -93,26 +94,6 @@ function externals_run($argv, $argc){
$results = process_delivery(array('hash' => 'undefined'), get_item_elements($message),
array(array('hash' => $sys['xchan_hash'])), false, true);
$total ++;
-// $z = q("select id from item where mid = '%s' and uid = %d limit 1",
-// dbesc($message['message_id']),
-// intval($sys['channel_id'])
-// );
-$z = null;
- if($z) {
- $flag_bits = ITEM_WALL|ITEM_ORIGIN|ITEM_UPLINK;
- // preserve the source
-
- $r = q("update item set source_xchan = owner_xchan where id = %d",
- intval($z[0]['id'])
- );
-
- $r = q("update item set item_flags = ( item_flags | %d ), owner_xchan = '%s'
- where id = %d",
- intval($flag_bits),
- dbesc($sys['xchan_hash']),
- intval($z[0]['id'])
- );
- }
}
logger('externals: import_public_posts: ' . $total . ' messages imported', LOGGER_DEBUG);
}
diff --git a/include/features.php b/include/features.php
index a6c4757cd..74ae7b3d7 100644
--- a/include/features.php
+++ b/include/features.php
@@ -55,10 +55,11 @@ function get_features() {
t('Post Composition Features'),
// array('richtext', t('Richtext Editor'), t('Enable richtext editor'),false),
array('markdown', t('Use Markdown'), t('Allow use of "Markdown" to format posts'),false),
- array('large_photos', t('Large Photos'), t('Include large (640px) photo thumbnails in posts. If not enabled, use small (320px) photo thumbnails'),false),
+ array('large_photos', t('Large Photos'), t('Include large (1024px) photo thumbnails in posts. If not enabled, use small (640px) photo thumbnails'),false),
array('channel_sources', t('Channel Sources'), t('Automatically import channel content from other channels or feeds'),false),
array('content_encrypt', t('Even More Encryption'), t('Allow optional encryption of content end-to-end with a shared secret key'),false),
- array('consensus_tools', t('Enable voting tools'), t('Provide a class of post which others can vote on'),false),
+ array('consensus_tools', t('Enable Voting Tools'), t('Provide a class of post which others can vote on'),false),
+ array('delayed_posting', t('Delayed Posting'), t('Allow posts to be published at a later date'),false),
),
diff --git a/include/follow.php b/include/follow.php
index 54e16703d..40ad2c299 100644
--- a/include/follow.php
+++ b/include/follow.php
@@ -37,9 +37,8 @@ function new_contact($uid,$url,$channel,$interactive = false, $confirm = false)
// check service class limits
- $r = q("select count(*) as total from abook where abook_channel = %d and not (abook_flags & %d)>0 ",
- intval($uid),
- intval(ABOOK_FLAG_SELF)
+ $r = q("select count(*) as total from abook where abook_channel = %d and abook_self = 0 ",
+ intval($uid)
);
if($r)
$total_channels = $r[0]['total'];
@@ -130,39 +129,31 @@ function new_contact($uid,$url,$channel,$interactive = false, $confirm = false)
}
}
else {
- if(! ($is_http)) {
- if(! intval(get_config('system','diaspora_enabled'))) {
- $result['message'] = t('Protocol disabled.');
- return $result;
- }
-
- $allowed = get_pconfig($uid,'system','diaspora_allowed');
- if($allowed === false)
- $allowed = 1;
-
- if(! intval($allowed)) {
- $result['message'] = t('Protocol blocked for this channel.');
- return $result;
- }
- }
$their_perms = 0;
$xchan_hash = '';
+
$r = q("select * from xchan where xchan_hash = '%s' or xchan_url = '%s' limit 1",
dbesc($url),
dbesc($url)
);
+
if(! $r) {
// attempt network auto-discovery
if(strpos($url,'@') && (! $is_http)) {
- $r = discover_by_webbie($url);
+ $d = discover_by_webbie($url);
}
elseif($is_http) {
- $r = discover_by_url($url);
+ if(get_config('system','feed_contacts'))
+ $d = discover_by_url($url);
+ else {
+ $result['message'] = t('Protocol disabled.');
+ return $result;
+ }
}
- if($r) {
+ if($d) {
$r = q("select * from xchan where xchan_hash = '%s' or xchan_url = '%s' limit 1",
dbesc($url),
dbesc($url)
@@ -181,6 +172,16 @@ 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);
+
+ call_hooks('follow_allow',$x);
+
+ if(! $x['allowed']) {
+ $result['message'] = t('Protocol disabled.');
+ return $result;
+ }
+
+
if((local_channel()) && $uid == local_channel()) {
$aid = get_account_id();
$hash = get_observer_hash();
@@ -202,14 +203,9 @@ function new_contact($uid,$url,$channel,$interactive = false, $confirm = false)
if($is_http) {
- if(! intval(get_config('system','feed_contacts'))) {
- $result['message'] = t('Protocol disabled.');
- return $result;
- }
- $r = q("select count(*) as total from abook where abook_account = %d and ( abook_flags & %d )>0",
- intval($aid),
- intval(ABOOK_FLAG_FEED)
+ $r = q("select count(*) as total from abook where abook_account = %d and abook_feed = 1 ",
+ intval($aid)
);
if($r)
$total_feeds = $r[0]['total'];
@@ -241,13 +237,13 @@ 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_flags, abook_their_perms, abook_my_perms, abook_created, abook_updated )
+ $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' ) ",
intval($aid),
intval($uid),
intval($closeness),
dbesc($xchan_hash),
- intval(($is_http) ? ABOOK_FLAG_FEED : 0),
+ intval(($is_http) ? 1 : 0),
intval(($is_http) ? $their_perms|PERMS_R_STREAM|PERMS_A_REPUBLISH : $their_perms),
intval($my_perms),
dbesc(datetime_convert()),
@@ -265,7 +261,7 @@ function new_contact($uid,$url,$channel,$interactive = false, $confirm = false)
);
if($r) {
$result['abook'] = $r[0];
- proc_run('php', 'include/notifier.php', 'permission_update', $result['abook']['abook_id']);
+ proc_run('php', 'include/notifier.php', 'permission_create', $result['abook']['abook_id']);
}
$arr = array('channel_id' => $uid, 'abook' => $result['abook']);
diff --git a/include/gprobe.php b/include/gprobe.php
index 48c1c8e14..d8d893d9e 100644
--- a/include/gprobe.php
+++ b/include/gprobe.php
@@ -14,6 +14,9 @@ function gprobe_run($argv, $argc){
$url = hex2bin($argv[1]);
+ if(! strpos($url,'@'))
+ return;
+
$r = q("select * from xchan where xchan_addr = '%s' limit 1",
dbesc($url)
);
diff --git a/include/group.php b/include/group.php
index fe55ec23f..0875b10f9 100644
--- a/include/group.php
+++ b/include/group.php
@@ -200,13 +200,10 @@ function group_get_members($gid) {
if(intval($gid)) {
$r = q("SELECT * FROM `group_member`
LEFT JOIN abook ON abook_xchan = `group_member`.`xchan` left join xchan on xchan_hash = abook_xchan
- WHERE `gid` = %d AND abook_channel = %d and `group_member`.`uid` = %d and not ( xchan_flags & %d )>0 and not ( abook_flags & %d )>0 and not ( abook_flags & %d )>0 ORDER BY xchan_name ASC ",
+ WHERE `gid` = %d AND abook_channel = %d and `group_member`.`uid` = %d and xchan_deleted = 0 and abook_blocked = 0 and abook_pending = 0 ORDER BY xchan_name ASC ",
intval($gid),
intval(local_channel()),
- intval(local_channel()),
- intval(XCHAN_FLAGS_DELETED),
- intval(ABOOK_FLAG_BLOCKED),
- intval(ABOOK_FLAG_PENDING)
+ intval(local_channel())
);
if(count($r))
$ret = $r;
@@ -232,7 +229,7 @@ function mini_group_select($uid,$group = '') {
logger('mini_group_select: ' . print_r($grps,true), LOGGER_DATA);
$o = replace_macros(get_markup_template('group_selection.tpl'), array(
- '$label' => t('Default privacy group for new contacts'),
+ '$label' => t('Add new connections to this collection (privacy group)'),
'$groups' => $grps
));
return $o;
@@ -245,7 +242,7 @@ function group_side($every="connections",$each="group",$edit = false, $group_id
$o = '';
- if(! local_channel())
+ if(! (local_channel() && feature_enabled(local_channel(),'groups')))
return '';
$groups = array();
diff --git a/include/hubloc.php b/include/hubloc.php
index a4efe1c75..a1171b0e2 100644
--- a/include/hubloc.php
+++ b/include/hubloc.php
@@ -16,7 +16,9 @@ function is_matrix_url($url) {
function prune_hub_reinstalls() {
- $r = q("select site_url from site where true");
+ $r = q("select site_url from site where site_type = %d",
+ intval(SITE_TYPE_ZOT)
+ );
if($r) {
foreach($r as $rr) {
$x = q("select count(*) as t, hubloc_sitekey, max(hubloc_connected) as c from hubloc where hubloc_url = '%s' group by hubloc_sitekey order by c",
@@ -96,8 +98,7 @@ function remove_obsolete_hublocs() {
? intval(get_config('system','delivery_interval')) : 2 );
foreach($r as $rr) {
- q("update hubloc set hubloc_flags = (hubloc_flags | %d) where hubloc_id = %d",
- intval(HUBLOC_FLAGS_DELETED),
+ q("update hubloc set hubloc_deleted = 1 where hubloc_id = %d",
intval($rr['hubloc_id'])
);
@@ -121,7 +122,7 @@ function hubloc_change_primary($hubloc) {
logger('no hubloc');
return false;
}
- if(! ($hubloc['hubloc_flags'] & HUBLOC_FLAGS_PRIMARY)) {
+ if(! (intval($hubloc['hubloc_primary']))) {
logger('not primary: ' . $hubloc['hubloc_url']);
return false;
}
@@ -206,7 +207,7 @@ function xchan_store($arr) {
if(! $arr['photo'])
$arr['photo'] = z_root() . '/' . get_default_profile_photo();
- $r = q("insert into xchan ( xchan_hash, xchan_guid, xchan_guid_sig, xchan_pubkey, xchan_addr, xchan_url, xchan_connurl, xchan_follow, xchan_connpage, xchan_name, xchan_network, xchan_instance_url, xchan_flags, xchan_name_date ) values ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s','%s','%s','%s',%d,'%s') ",
+ $r = q("insert into xchan ( xchan_hash, xchan_guid, xchan_guid_sig, xchan_pubkey, xchan_addr, xchan_url, xchan_connurl, xchan_follow, xchan_connpage, xchan_name, xchan_network, xchan_instance_url, xchan_hidden, xchan_orphan, xchan_censored, xchan_selfcensored, xchan_system, xchan_pubforum, xchan_deleted, xchan_name_date ) values ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s','%s','%s','%s',%d, %d, %d, %d, %d, %d, %d, '%s') ",
dbesc($arr['hash']),
dbesc($arr['guid']),
dbesc($arr['guid_sig']),
@@ -219,13 +220,19 @@ function xchan_store($arr) {
dbesc($arr['name']),
dbesc($arr['network']),
dbesc($arr['instance_url']),
- intval($arr['flags']),
+ intval($arr['hidden']),
+ intval($arr['orphan']),
+ intval($arr['censored']),
+ intval($arr['selfcensored']),
+ intval($arr['system']),
+ intval($arr['pubforum']),
+ intval($arr['deleted']),
dbesc(datetime_convert())
);
if(! $r)
return $r;
- $photos = import_profile_photo($arr['photo'],$arr['hash']);
+ $photos = import_xchan_photo($arr['photo'],$arr['hash']);
$r = q("update xchan set xchan_photo_date = '%s', xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s' where xchan_hash = '%s'",
dbesc(datetime_convert()),
dbesc($photos[0]),
@@ -270,4 +277,34 @@ function xchan_fetch($arr) {
$ret[str_replace('xchan_','',$k)] = $v;
}
return $ret;
-} \ No newline at end of file
+}
+
+
+
+function ping_site($url) {
+
+ $ret = array('success' => false);
+
+ $sys = get_sys_channel();
+
+ $m = zot_build_packet($sys,'ping');
+ $r = zot_zot($url . '/post',$m);
+ if(! $r['success']) {
+ $ret['message'] = 'no answer from ' . $url;
+ return $ret;
+ }
+ $packet_result = json_decode($r['body'],true);
+ if(! $packet_result['success']) {
+ $ret['message'] = 'packet failure from ' . $url;
+ return $ret;
+ }
+
+ if($packet_result['success']) {
+ $ret['success'] = true;
+ }
+ else {
+ $ret['message'] = 'unknown error from ' . $url;
+ }
+
+ return $ret;
+}
diff --git a/include/identity.php b/include/identity.php
index bcbb2bc75..0c4a9df45 100644
--- a/include/identity.php
+++ b/include/identity.php
@@ -24,9 +24,8 @@ require_once('include/menu.php');
function identity_check_service_class($account_id) {
$ret = array('success' => false, 'message' => '');
- $r = q("select count(channel_id) as total from channel where channel_account_id = %d and not ( channel_pageflags & %d )>0 ",
- intval($account_id),
- intval(PAGE_REMOVED)
+ $r = q("select count(channel_id) as total from channel where channel_account_id = %d and channel_removed = 0 ",
+ intval($account_id)
);
if(! ($r && count($r))) {
$ret['total_identities'] = 0;
@@ -98,9 +97,9 @@ function create_sys_channel() {
'account_id' => 'xxx', // This will create an identity with an (integer) account_id of 0, but account_id is required
'nickname' => 'sys',
'name' => 'System',
- 'pageflags' => PAGE_SYSTEM,
+ 'pageflags' => 0,
'publish' => 0,
- 'xchanflags' => XCHAN_FLAGS_SYSTEM
+ 'system' => 1
));
}
@@ -111,9 +110,7 @@ function create_sys_channel() {
* @return array|boolean
*/
function get_sys_channel() {
- $r = q("select * from channel left join xchan on channel_hash = xchan_hash where (channel_pageflags & %d)>0 limit 1",
- intval(PAGE_SYSTEM)
- );
+ $r = q("select * from channel left join xchan on channel_hash = xchan_hash where channel_system = 1 limit 1");
if ($r)
return $r[0];
@@ -129,11 +126,11 @@ function get_sys_channel() {
* @return boolean
*/
function is_sys_channel($channel_id) {
- $r = q("select channel_pageflags from channel where channel_id = %d limit 1",
+ $r = q("select channel_system from channel where channel_id = %d and channel_system = 1 limit 1",
intval($channel_id)
);
- if (($r) && ($r[0]['channel_pageflags'] & PAGE_SYSTEM))
+ if($r)
return true;
return false;
@@ -149,9 +146,7 @@ function is_sys_channel($channel_id) {
* on error returns boolean false
*/
function channel_total() {
- $r = q("select channel_id from channel where not ( channel_pageflags & %d )>0",
- intval(PAGE_REMOVED)
- );
+ $r = q("select channel_id from channel where channel_removed = 0");
if (is_array($r))
return count($r);
@@ -201,14 +196,14 @@ function create_identity($arr) {
$name = escape_tags($arr['name']);
$pageflags = ((x($arr,'pageflags')) ? intval($arr['pageflags']) : PAGE_NORMAL);
- $xchanflags = ((x($arr,'xchanflags')) ? intval($arr['xchanflags']) : XCHAN_FLAGS_NORMAL);
+ $system = ((x($arr,'system')) ? intval($arr['system']) : 0);
$name_error = validate_channelname($arr['name']);
if($name_error) {
$ret['message'] = $name_error;
return $ret;
}
- if($nick === 'sys' && (! ($pageflags & PAGE_SYSTEM))) {
+ if($nick === 'sys' && (! $system)) {
$ret['message'] = t('Reserved nickname. Please choose another.');
return $ret;
}
@@ -265,8 +260,8 @@ function create_identity($arr) {
$r = q("insert into channel ( channel_account_id, channel_primary,
channel_name, channel_address, channel_guid, channel_guid_sig,
- channel_hash, channel_prvkey, channel_pubkey, channel_pageflags, channel_expire_days, channel_timezone $perms_keys )
- values ( %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, '%s' $perms_vals ) ",
+ channel_hash, channel_prvkey, channel_pubkey, channel_pageflags, channel_system, channel_expire_days, channel_timezone $perms_keys )
+ values ( %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, %d, '%s' $perms_vals ) ",
intval($arr['account_id']),
intval($primary),
@@ -278,6 +273,7 @@ function create_identity($arr) {
dbesc($key['prvkey']),
dbesc($key['pubkey']),
intval($pageflags),
+ intval($system),
intval($expire),
dbesc($a->timezone)
);
@@ -300,14 +296,14 @@ function create_identity($arr) {
// Create a verified hub location pointing to this site.
- $r = q("insert into hubloc ( hubloc_guid, hubloc_guid_sig, hubloc_hash, hubloc_addr, hubloc_flags,
+ $r = q("insert into hubloc ( hubloc_guid, hubloc_guid_sig, hubloc_hash, hubloc_addr, hubloc_primary,
hubloc_url, hubloc_url_sig, hubloc_host, hubloc_callback, hubloc_sitekey, hubloc_network )
values ( '%s', '%s', '%s', '%s', %d, '%s', '%s', '%s', '%s', '%s', '%s' )",
dbesc($guid),
dbesc($sig),
dbesc($hash),
dbesc($ret['channel']['channel_address'] . '@' . get_app()->get_hostname()),
- intval(($primary) ? HUBLOC_FLAGS_PRIMARY : 0),
+ intval($primary),
dbesc(z_root()),
dbesc(base64url_encode(rsa_sign(z_root(),$ret['channel']['channel_prvkey']))),
dbesc(get_app()->get_hostname()),
@@ -320,7 +316,7 @@ function create_identity($arr) {
$newuid = $ret['channel']['channel_id'];
- $r = q("insert into xchan ( xchan_hash, xchan_guid, xchan_guid_sig, xchan_pubkey, xchan_photo_l, xchan_photo_m, xchan_photo_s, xchan_addr, xchan_url, xchan_follow, xchan_connurl, xchan_name, xchan_network, xchan_photo_date, xchan_name_date, xchan_flags ) values ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d)",
+ $r = q("insert into xchan ( xchan_hash, xchan_guid, xchan_guid_sig, xchan_pubkey, xchan_photo_l, xchan_photo_m, xchan_photo_s, xchan_addr, xchan_url, xchan_follow, xchan_connurl, xchan_name, xchan_network, xchan_photo_date, xchan_name_date, xchan_system ) values ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d)",
dbesc($hash),
dbesc($guid),
dbesc($sig),
@@ -336,7 +332,7 @@ function create_identity($arr) {
dbesc('zot'),
dbesc(datetime_convert()),
dbesc(datetime_convert()),
- intval($xchanflags)
+ intval($system)
);
// Not checking return value.
@@ -363,7 +359,7 @@ function create_identity($arr) {
|PERMS_W_STREAM|PERMS_W_WALL|PERMS_W_COMMENT|PERMS_W_MAIL|PERMS_W_CHAT
|PERMS_R_STORAGE|PERMS_R_PAGES|PERMS_W_LIKE;
- $r = q("insert into abook ( abook_account, abook_channel, abook_xchan, abook_closeness, abook_created, abook_updated, abook_flags, abook_my_perms )
+ $r = q("insert into abook ( abook_account, abook_channel, abook_xchan, abook_closeness, abook_created, abook_updated, abook_self, abook_my_perms )
values ( %d, %d, '%s', %d, '%s', '%s', %d, %d ) ",
intval($ret['channel']['channel_account_id']),
intval($newuid),
@@ -371,7 +367,7 @@ function create_identity($arr) {
intval(0),
dbesc(datetime_convert()),
dbesc(datetime_convert()),
- intval(ABOOK_FLAG_SELF),
+ intval(1),
intval($myperms)
);
@@ -410,6 +406,11 @@ function create_identity($arr) {
}
}
+ if(! $system) {
+ set_pconfig($ret['channel']['channel_id'],'system','photo_path', '%Y-%m');
+ set_pconfig($ret['channel']['channel_id'],'system','attach_path','%Y-%m');
+ }
+
// auto-follow any of the hub's pre-configured channel choices.
// Only do this if it's the first channel for this account;
// otherwise it could get annoying. Don't make this list too big
@@ -426,7 +427,7 @@ function create_identity($arr) {
}
}
- call_hooks('register_account', $newuid);
+ call_hooks('create_identity', $newuid);
proc_run('php','include/directory.php', $ret['channel']['channel_id']);
}
@@ -536,15 +537,14 @@ function identity_basic_export($channel_id, $items = false) {
if($r)
$ret['config'] = $r;
- $r = q("select type, data from photo where scale = 4 and profile = 1 and uid = %d limit 1",
+ $r = q("select type, data, os_storage from photo where scale = 4 and profile = 1 and uid = %d limit 1",
intval($channel_id)
);
if($r) {
- $ret['photo'] = array('type' => $r[0]['type'], 'data' => base64url_encode($r[0]['data']));
+ $ret['photo'] = array('type' => $r[0]['type'], 'data' => (($r[0]['os_storage']) ? base64url_encode(file_get_contents($r[0]['data'])) : base64url_encode($r[0]['data'])));
}
-
// All other term types will be included in items, if requested.
$r = q("select * from term where type in (%d,%d) and uid = %d",
@@ -556,13 +556,9 @@ function identity_basic_export($channel_id, $items = false) {
$ret['term'] = $r;
- // make the obj output match the hubzilla file format
-
- $datestamp = datetime_convert();
+ // add psuedo-column obj_baseurl to aid in relocations
- $r = q("select obj.*, term.term as obj_term, term.url as obj_url, term.imgurl as obj_imgurl, '%s' as obj_created, '%s' as obj_edited, '%s' as obj_baseurl from obj left join term on obj_obj = term.term_hash where obj_channel = %d",
- dbesc($datestamp),
- dbesc($datestamp),
+ $r = q("select obj.*, '%s' as obj_baseurl from obj where obj_channel = %d",
dbesc(z_root()),
intval($channel_id)
);
@@ -570,7 +566,6 @@ function identity_basic_export($channel_id, $items = false) {
if($r)
$ret['obj'] = $r;
-
$r = q("select * from app where app_channel = %d",
intval($channel_id)
);
@@ -600,6 +595,16 @@ function identity_basic_export($channel_id, $items = false) {
foreach($r as $rr)
$ret['event_item'][] = encode_item($rr,true);
}
+
+ $x = menu_list($channel_id);
+ if($x) {
+ $ret['menu'] = array();
+ for($y = 0; $y < count($x); $y ++) {
+ $m = menu_fetch($x[$y]['menu_name'],$channel_id,$ret['channel']['channel_hash']);
+ if($m)
+ $ret['menu'][] = menu_element($m);
+ }
+ }
$x = menu_list($channel_id);
if($x) {
@@ -611,6 +616,10 @@ function identity_basic_export($channel_id, $items = false) {
}
}
+ $addon = array('channel_id' => $channel_id,'data' => $ret);
+ call_hooks('identity_basic_export',$addon);
+ $ret = $addon['data'];
+
if(! $items)
return $ret;
@@ -626,25 +635,26 @@ function identity_basic_export($channel_id, $items = false) {
$r = q("select * from conv where uid = %d",
intval($channel_id)
);
- if($r)
+ if($r) {
+ for($x = 0; $x < count($r); $x ++) {
+ $r[$x]['subject'] = base64url_decode(str_rot47($r[$x]['subject']));
+ }
$ret['conv'] = $r;
+ }
- $r = q("select mail.*, conv.guid as conv_guid from mail left join conv on mail.convid = conv.id where mail.uid = %d",
+ $r = q("select * from mail where mail.uid = %d",
intval($channel_id)
);
if($r) {
$m = array();
foreach($r as $rr) {
xchan_mail_query($rr);
- $m[] = mail_encode($rr,true);
+ $m[] = mail_encode($rr,true);
}
$ret['mail'] = $m;
}
-
-
-
$r = q("select item_id.*, item.mid from item_id left join item on item_id.iid = item.id where item_id.uid = %d",
intval($channel_id)
);
@@ -656,12 +666,17 @@ function identity_basic_export($channel_id, $items = false) {
/** @warning this may run into memory limits on smaller systems */
- /** Don't export linked resource items. we'll have to pull those out separately. */
- $r = q("select * from item where (item_flags & %d) > 0 and not (item_restrict & %d) > 0 and uid = %d and resource_type = '' order by created",
- intval(ITEM_WALL),
- intval(ITEM_DELETED),
- intval($channel_id)
+ /** export three months of posts. If you want to export and import all posts you have to start with
+ * the first year and export/import them in ascending order.
+ *
+ * Don't export linked resource items. we'll have to pull those out separately.
+ */
+
+ $r = q("select * from item where item_wall = 1 and item_deleted = 0 and uid = %d and created > %s - INTERVAL %s and resource_type = '' order by created",
+ intval($channel_id),
+ db_utcnow(),
+ db_quoteinterval('3 MONTH')
);
if($r) {
$ret['item'] = array();
@@ -675,7 +690,6 @@ function identity_basic_export($channel_id, $items = false) {
}
-
function identity_export_year($channel_id,$year,$month = 0) {
if(! $year)
@@ -696,9 +710,7 @@ function identity_export_year($channel_id,$year,$month = 0) {
else
$maxdate = datetime_convert('UTC','UTC',$year+1 . '-01-01 00:00:00');
- $r = q("select * from item where (item_flags & %d) > 0 and (item_restrict & %d) = 0 and uid = %d and created >= '%s' and created < '%s' and resource_type = '' order by created ",
- intval(ITEM_WALL),
- intval(ITEM_DELETED),
+ $r = q("select * from item where item_wall = 1 and item_deleted = 0 and uid = %d and created >= '%s' and created < '%s' and resource_type = '' order by created",
intval($channel_id),
dbesc($mindate),
dbesc($maxdate)
@@ -712,7 +724,6 @@ function identity_export_year($channel_id,$year,$month = 0) {
$ret['item'][] = encode_item($rr,true);
}
-
$r = q("select item_id.*, item.mid from item_id left join item on item_id.iid = item.id where item_id.uid = %d
and item.created >= '%s' and item.created < '%s' order by created ",
intval($channel_id),
@@ -747,11 +758,10 @@ function identity_export_year($channel_id,$year,$month = 0) {
*/
function profile_load(&$a, $nickname, $profile = '') {
- logger('profile_load: ' . $nickname . (($profile) ? ' profile: ' . $profile : ''));
+// logger('profile_load: ' . $nickname . (($profile) ? ' profile: ' . $profile : ''));
- $user = q("select channel_id from channel where channel_address = '%s' and not ( channel_pageflags & %d ) > 0 limit 1",
- dbesc($nickname),
- intval(PAGE_REMOVED)
+ $user = q("select channel_id from channel where channel_address = '%s' and channel_removed = 0 limit 1",
+ dbesc($nickname)
);
if(! $user) {
@@ -794,10 +804,9 @@ function profile_load(&$a, $nickname, $profile = '') {
if(! $p) {
$p = q("SELECT profile.uid AS profile_uid, profile.*, channel.* FROM profile
LEFT JOIN channel ON profile.uid = channel.channel_id
- WHERE channel.channel_address = '%s' and not ( channel_pageflags & %d )>0
+ WHERE channel.channel_address = '%s' and channel_removed = 0
AND profile.is_default = 1 LIMIT 1",
- dbesc($nickname),
- intval(PAGE_REMOVED)
+ dbesc($nickname)
);
}
@@ -1012,7 +1021,8 @@ function profile_sidebar($profile, $block = 0, $show_connect = true) {
$marital = ((x($profile,'marital') == 1) ? t('Status:') : False);
$homepage = ((x($profile,'homepage') == 1) ? t('Homepage:') : False);
$profile['online'] = (($profile['online_status'] === 'online') ? t('Online Now') : False);
- logger('online: ' . $profile['online']);
+
+// logger('online: ' . $profile['online']);
if(! perm_is_allowed($profile['uid'],((is_array($observer)) ? $observer['xchan_hash'] : ''),'view_profile')) {
$block = true;
@@ -1504,7 +1514,7 @@ function get_default_profile_photo($size = 300) {
}
/**
- * @brief Test whether a given identity is NOT a member of the Red Matrix.
+ * @brief Test whether a given identity is NOT a member of the Hubzilla.
*
* @param string $s;
* xchan_hash of the identity in question
@@ -1515,7 +1525,7 @@ function is_foreigner($s) {
}
/**
- * @brief Test whether a given identity is a member of the Red Matrix.
+ * @brief Test whether a given identity is a member of the Hubzilla.
*
* @param string $s;
* xchan_hash of the identity in question
@@ -1587,9 +1597,8 @@ function get_channel_by_nick($nick) {
*/
function identity_selector() {
if (local_channel()) {
- $r = q("select channel.*, xchan.* from channel left join xchan on channel.channel_hash = xchan.xchan_hash where channel.channel_account_id = %d and (channel_pageflags & %d) = 0 order by channel_name ",
- intval(get_account_id()),
- intval(PAGE_REMOVED)
+ $r = q("select channel.*, xchan.* from channel left join xchan on channel.channel_hash = xchan.xchan_hash where channel.channel_account_id = %d and channel_removed = 0 order by channel_name ",
+ intval(get_account_id())
);
if (count($r) > 1) {
//$account = get_app()->get_account();
@@ -1685,9 +1694,8 @@ function notifications_on($channel_id,$value) {
function get_channel_default_perms($uid) {
- $r = q("select abook_my_perms from abook where abook_channel = %d and (abook_flags & %d) > 0 limit 1",
- intval($uid),
- intval(ABOOK_FLAG_SELF)
+ $r = q("select abook_my_perms from abook where abook_channel = %d and abook_self = 1 limit 1",
+ intval($uid)
);
if($r)
return $r[0]['abook_my_perms'];
diff --git a/include/import.php b/include/import.php
new file mode 100644
index 000000000..0fd1ab2a5
--- /dev/null
+++ b/include/import.php
@@ -0,0 +1,871 @@
+<?php
+
+require_once('include/menu.php');
+
+function import_channel($channel) {
+
+ if(! array_key_exists('channel_system',$channel)) {
+ $channel['channel_system'] = (($channel['channel_pageflags'] & 0x1000) ? 1 : 0);
+ $channel['channel_removed'] = (($channel['channel_pageflags'] & 0x8000) ? 1 : 0);
+ }
+
+ $r = q("select * from channel where (channel_guid = '%s' or channel_hash = '%s' or channel_address = '%s' ) limit 1",
+ dbesc($channel['channel_guid']),
+ dbesc($channel['channel_hash']),
+ dbesc($channel['channel_address'])
+ );
+
+ // We should probably also verify the hash
+
+ if($r) {
+ if($r[0]['channel_guid'] === $channel['channel_guid'] || $r[0]['channel_hash'] === $channel['channel_hash']) {
+ logger('mod_import: duplicate channel. ', print_r($channel,true));
+ notice( t('Cannot create a duplicate channel identifier on this system. Import failed.') . EOL);
+ return false;
+ }
+ else {
+ // try at most ten times to generate a unique address.
+ $x = 0;
+ $found_unique = false;
+ do {
+ $tmp = $channel['channel_address'] . mt_rand(1000,9999);
+ $r = q("select * from channel where channel_address = '%s' limit 1",
+ dbesc($tmp)
+ );
+ if(! $r) {
+ $channel['channel_address'] = $tmp;
+ $found_unique = true;
+ break;
+ }
+ $x ++;
+ } while ($x < 10);
+ if(! $found_unique) {
+ logger('mod_import: duplicate channel. randomisation failed.', print_r($channel,true));
+ notice( t('Unable to create a unique channel address. Import failed.') . EOL);
+ return false;
+ }
+ }
+ }
+
+ unset($channel['channel_id']);
+ $channel['channel_account_id'] = get_account_id();
+ $channel['channel_primary'] = (($seize) ? 1 : 0);
+
+ if($channel['channel_pageflags'] & PAGE_ALLOWCODE) {
+ if(! is_site_admin())
+ $channel['channel_pageflags'] = $channel['channel_pageflags'] ^ PAGE_ALLOWCODE;
+ }
+
+ dbesc_array($channel);
+
+ $r = dbq("INSERT INTO channel (`"
+ . implode("`, `", array_keys($channel))
+ . "`) VALUES ('"
+ . implode("', '", array_values($channel))
+ . "')"
+ );
+
+ if(! $r) {
+ logger('mod_import: channel clone failed. ', print_r($channel,true));
+ notice( t('Channel clone failed. Import failed.') . EOL);
+ return false;
+ }
+
+ $r = q("select * from channel where channel_account_id = %d and channel_guid = '%s' limit 1",
+ intval(get_account_id()),
+ $channel['channel_guid'] // Already dbesc'd
+ );
+ if(! $r) {
+ logger('mod_import: channel not found. ', print_r($channel,true));
+ notice( t('Cloned channel not found. Import failed.') . EOL);
+ return false;
+ }
+ // reset
+ $channel = $r[0];
+
+ set_default_login_identity(get_account_id(),$channel['channel_id'],false);
+ logger('import step 1');
+ $_SESSION['import_step'] = 1;
+ ref_session_write(session_id(), serialize($_SESSION));
+ return $channel;
+
+}
+
+function import_config($channel,$configs) {
+
+ if($channel && $configs) {
+ foreach($configs as $config) {
+ unset($config['id']);
+ $config['uid'] = $channel['channel_id'];
+ dbesc_array($config);
+ $r = dbq("INSERT INTO pconfig (`"
+ . implode("`, `", array_keys($config))
+ . "`) VALUES ('"
+ . implode("', '", array_values($config))
+ . "')" );
+ }
+ load_pconfig($channel['channel_id']);
+ }
+}
+
+
+function import_profiles($channel,$profiles) {
+
+ if($channel && $profiles) {
+ foreach($profiles as $profile) {
+ unset($profile['id']);
+ $profile['aid'] = get_account_id();
+ $profile['uid'] = $channel['channel_id'];
+
+ // we are going to reset all profile photos to the original
+ // somebody will have to fix this later and put all the applicable photos into the export
+
+ $profile['photo'] = z_root() . '/photo/profile/l/' . $channel['channel_id'];
+ $profile['thumb'] = z_root() . '/photo/profile/m/' . $channel['channel_id'];
+
+ dbesc_array($profile);
+ $r = dbq("INSERT INTO profile (`"
+ . implode("`, `", array_keys($profile))
+ . "`) VALUES ('"
+ . implode("', '", array_values($profile))
+ . "')"
+ );
+ }
+ }
+}
+
+
+function import_hublocs($channel,$hublocs,$seize) {
+
+ if($channel && $hublocs) {
+ foreach($hublocs as $hubloc) {
+
+ $hash = make_xchan_hash($hubloc['hubloc_guid'],$hubloc['hubloc_guid_sig']);
+ if($hubloc['hubloc_network'] === 'zot' && $hash !== $hubloc['hubloc_hash']) {
+ logger('forged hubloc: ' . print_r($hubloc,true));
+ continue;
+ }
+
+ if(! array_key_exists('hubloc_primary',$hubloc)) {
+ $hubloc['hubloc_primary'] = (($hubloc['hubloc_flags'] & 0x0001) ? 1 : 0);
+ $hubloc['hubloc_orphancheck'] = (($hubloc['hubloc_flags'] & 0x0004) ? 1 : 0);
+ $hubloc['hubloc_error'] = (($hubloc['hubloc_status'] & 0x0003) ? 1 : 0);
+ $hubloc['hubloc_deleted'] = (($hubloc['hubloc_flags'] & 0x1000) ? 1 : 0);
+ }
+
+ $arr = array(
+ 'guid' => $hubloc['hubloc_guid'],
+ 'guid_sig' => $hubloc['hubloc_guid_sig'],
+ 'url' => $hubloc['hubloc_url'],
+ 'url_sig' => $hubloc['hubloc_url_sig']
+ );
+ if(($hubloc['hubloc_hash'] === $channel['channel_hash']) && intval($hubloc['hubloc_primary']) && ($seize))
+ $hubloc['hubloc_primary'] = 0;
+
+ if(! zot_gethub($arr)) {
+ unset($hubloc['hubloc_id']);
+ dbesc_array($hubloc);
+
+ $r = dbq("INSERT INTO hubloc (`"
+ . implode("`, `", array_keys($hubloc))
+ . "`) VALUES ('"
+ . implode("', '", array_values($hubloc))
+ . "')"
+ );
+ }
+ }
+ }
+}
+
+
+
+function import_objs($channel,$objs) {
+
+ if($channel && $objs) {
+ foreach($objs as $obj) {
+
+ // if it's the old term format - too hard to support
+ if(! $obj['obj_created'])
+ continue;
+
+ $baseurl = $obj['obj_baseurl'];
+ unset($obj['obj_id']);
+ unset($obj['obj_baseurl']);
+
+ $obj['obj_channel'] = $channel['channel_id'];
+
+ if($baseurl && (strpos($obj['obj_url'],$baseurl . '/thing/') !== false)) {
+ $obj['obj_url'] = str_replace($baseurl,z_root(),$obj['obj_url']);
+ }
+
+ if($obj['obj_imgurl']) {
+ $x = import_xchan_photo($obj['obj_imgurl'],$channel['channel_hash'],true);
+ $obj['obj_imgurl'] = $x[0];
+ }
+
+ dbesc_array($obj);
+
+ $r = dbq("INSERT INTO obj (`"
+ . implode("`, `", array_keys($obj))
+ . "`) VALUES ('"
+ . implode("', '", array_values($obj))
+ . "')"
+ );
+ }
+ }
+}
+
+function sync_objs($channel,$objs) {
+
+ if($channel && $objs) {
+ foreach($objs as $obj) {
+
+ if(array_key_exists('obj_deleted',$obj) && $obj['obj_deleted'] && $obj['obj_obj']) {
+ q("delete from obj where obj_obj = '%s' and obj_channel = %d limit 1",
+ dbesc($obj['obj_obj']),
+ intval($channel['channel_id'])
+ );
+ continue;
+ }
+
+ // if it's the old term format - too hard to support
+ if(! $obj['obj_created'])
+ continue;
+
+ $baseurl = $obj['obj_baseurl'];
+ unset($obj['obj_id']);
+ unset($obj['obj_baseurl']);
+
+ $obj['obj_channel'] = $channel['channel_id'];
+
+ if($baseurl && (strpos($obj['obj_url'],$baseurl . '/thing/') !== false)) {
+ $obj['obj_url'] = str_replace($baseurl,z_root(),$obj['obj_url']);
+ }
+
+ $exists = false;
+
+ $x = q("select * from obj where obj_obj = '%s' and obj_channel = %d limit 1",
+ dbesc($obj['obj_obj']),
+ intval($channel['channel_id'])
+ );
+ if($x) {
+ if($x[0]['obj_edited'] >= $obj['obj_edited'])
+ continue;
+
+ $exists = true;
+ }
+
+ if($obj['obj_imgurl']) {
+ $x = import_xchan_photo($obj['obj_imgurl'],$channel['channel_hash'],true);
+ $obj['obj_imgurl'] = $x[0];
+ }
+
+ $hash = $obj['obj_obj'];
+
+ if($exists) {
+ unset($obj['obj_obj']);
+ foreach($obj as $k => $v) {
+ $r = q("UPDATE obj SET `%s` = '%s' WHERE obj_obj = '%s' AND obj_channel = %d",
+ dbesc($k),
+ dbesc($v),
+ dbesc($hash),
+ intval($channel['channel_id'])
+ );
+ }
+ }
+ else {
+
+ dbesc_array($obj);
+
+ $r = dbq("INSERT INTO obj (`"
+ . implode("`, `", array_keys($obj))
+ . "`) VALUES ('"
+ . implode("', '", array_values($obj))
+ . "')"
+ );
+ }
+ }
+ }
+}
+
+
+
+
+
+function import_apps($channel,$apps) {
+
+ if($channel && $apps) {
+ foreach($apps as $app) {
+
+ unset($app['id']);
+ unset($app['app_channel']);
+
+ $app['app_channel'] = $channel['channel_id'];
+
+ if($app['app_photo']) {
+ $x = import_xchan_photo($app['app_photo'],$channel['channel_hash'],true);
+ $app['app_photo'] = $x[0];
+ }
+
+ dbesc_array($app);
+ $r = dbq("INSERT INTO app (`"
+ . implode("`, `", array_keys($app))
+ . "`) VALUES ('"
+ . implode("', '", array_values($app))
+ . "')"
+ );
+ }
+ }
+}
+
+
+
+function sync_apps($channel,$apps) {
+
+ if($channel && $apps) {
+ foreach($apps as $app) {
+
+ if(array_key_exists('app_deleted',$app) && $app['app_deleted'] && $app['app_id']) {
+ q("delete from app where app_id = '%s' and app_channel = %d limit 1",
+ dbesc($app['app_id']),
+ intval($channel['channel_id'])
+ );
+ continue;
+ }
+
+ unset($app['id']);
+ unset($app['app_channel']);
+
+ if(! $app['app_created'] || $app['app_created'] === NULL_DATE)
+ $app['app_created'] = datetime_convert();
+ if(! $app['app_edited'] || $app['app_edited'] === NULL_DATE)
+ $app['app_edited'] = datetime_convert();
+
+ $app['app_channel'] = $channel['channel_id'];
+
+ if($app['app_photo']) {
+ $x = import_xchan_photo($app['app_photo'],$channel['channel_hash'],true);
+ $app['app_photo'] = $x[0];
+ }
+
+ $exists = false;
+
+ $x = q("select * from app where app_id = '%s' and app_channel = %d limit 1",
+ dbesc($app['app_id']),
+ intval($channel['channel_id'])
+ );
+ if($x) {
+ if($x[0]['app_edited'] >= $app['app_edited'])
+ continue;
+ $exists = true;
+ }
+ $hash = $app['app_id'];
+
+ if($exists) {
+ unset($app['app_id']);
+ foreach($app as $k => $v) {
+ $r = q("UPDATE app SET `%s` = '%s' WHERE app_id = '%s' AND app_channel = %d",
+ dbesc($k),
+ dbesc($v),
+ dbesc($hash),
+ intval($channel['channel_id'])
+ );
+ }
+ }
+ else {
+ dbesc_array($app);
+ $r = dbq("INSERT INTO app (`"
+ . implode("`, `", array_keys($app))
+ . "`) VALUES ('"
+ . implode("', '", array_values($app))
+ . "')"
+ );
+ }
+ }
+ }
+}
+
+
+
+function import_chatrooms($channel,$chatrooms) {
+
+ if($channel && $chatrooms) {
+ foreach($chatrooms as $chatroom) {
+
+ if(! $chatroom['cr_name'])
+ continue;
+
+ unset($chatroom['cr_id']);
+ unset($chatroom['cr_aid']);
+ unset($chatroom['cr_uid']);
+
+ $chatroom['cr_aid'] = $channel['channel_account_id'];
+ $chatroom['cr_uid'] = $channel['channel_id'];
+
+ dbesc_array($chatroom);
+ $r = dbq("INSERT INTO chatroom (`"
+ . implode("`, `", array_keys($chatroom))
+ . "`) VALUES ('"
+ . implode("', '", array_values($chatroom))
+ . "')"
+ );
+ }
+ }
+}
+
+
+
+function sync_chatrooms($channel,$chatrooms) {
+
+ if($channel && $chatrooms) {
+ foreach($chatrooms as $chatroom) {
+
+ if(! $chatroom['cr_name'])
+ continue;
+
+ if(array_key_exists('cr_deleted',$chatroom) && $chatroom['cr_deleted']) {
+ q("delete from chatroom where cr_name = '%s' and cr_uid = %d limit 1",
+ dbesc($chatroom['cr_name']),
+ intval($channel['channel_id'])
+ );
+ continue;
+ }
+
+
+ unset($chatroom['cr_id']);
+ unset($chatroom['cr_aid']);
+ unset($chatroom['cr_uid']);
+
+ if(! $chatroom['cr_created'] || $chatroom['cr_created'] === NULL_DATE)
+ $chatroom['cr_created'] = datetime_convert();
+ if(! $chatroom['cr_edited'] || $chatroom['cr_edited'] === NULL_DATE)
+ $chatroom['cr_edited'] = datetime_convert();
+
+ $chatroom['cr_aid'] = $channel['channel_account_id'];
+ $chatroom['cr_uid'] = $channel['channel_id'];
+
+ $exists = false;
+
+ $x = q("select * from chatroom where cr_name = '%s' and cr_uid = %d limit 1",
+ dbesc($chatroom['cr_name']),
+ intval($channel['channel_id'])
+ );
+ if($x) {
+ if($x[0]['cr_edited'] >= $chatroom['cr_edited'])
+ continue;
+ $exists = true;
+ }
+ $name = $chatroom['cr_name'];
+
+ if($exists) {
+ foreach($chatroom as $k => $v) {
+ $r = q("UPDATE chatroom SET `%s` = '%s' WHERE cr_name = '%s' AND cr_uid = %d",
+ dbesc($k),
+ dbesc($v),
+ dbesc($name),
+ intval($channel['channel_id'])
+ );
+ }
+ }
+ else {
+ dbesc_array($chatroom);
+ $r = dbq("INSERT INTO chatroom (`"
+ . implode("`, `", array_keys($chatroom))
+ . "`) VALUES ('"
+ . implode("', '", array_values($chatroom))
+ . "')"
+ );
+ }
+ }
+ }
+}
+
+
+
+function import_items($channel,$items) {
+
+ if($channel && $items) {
+ $allow_code = false;
+ $r = q("select account_id, account_roles, channel_pageflags from account left join channel on channel_account_id = account_id
+ where channel_id = %d limit 1",
+ intval($channel['channel_id'])
+ );
+ if($r) {
+ if(($r[0]['account_roles'] & ACCOUNT_ROLE_ALLOWCODE) || ($r[0]['channel_pageflags'] & PAGE_ALLOWCODE)) {
+ $allow_code = true;
+ }
+ }
+
+ foreach($items as $i) {
+ $item = get_item_elements($i,$allow_code);
+ if(! $item)
+ continue;
+
+ $r = q("select id, edited from item where mid = '%s' and uid = %d limit 1",
+ dbesc($item['mid']),
+ intval($channel['channel_id'])
+ );
+ if($r) {
+ if($item['edited'] > $r[0]['edited']) {
+ $item['id'] = $r[0]['id'];
+ $item['uid'] = $channel['channel_id'];
+ item_store_update($item);
+ continue;
+ }
+ }
+ else {
+ $item['aid'] = $channel['channel_account_id'];
+ $item['uid'] = $channel['channel_id'];
+ $item_result = item_store($item);
+ }
+
+ }
+ }
+}
+
+
+function sync_items($channel,$items) {
+ import_items($channel,$items);
+}
+
+
+
+function import_item_ids($channel,$itemids) {
+ if($channel && $itemids) {
+ foreach($itemids as $i) {
+ $r = q("select id from item where mid = '%s' and uid = %d limit 1",
+ dbesc($i['mid']),
+ intval($channel['channel_id'])
+ );
+ if(! $r)
+ continue;
+ $z = q("select * from item_id where service = '%s' and sid = '%s' and iid = %d and uid = %d limit 1",
+ dbesc($i['service']),
+ dbesc($i['sid']),
+ intval($r[0]['id']),
+ intval($channel['channel_id'])
+ );
+ if(! $z) {
+ q("insert into item_id (iid,uid,sid,service) values(%d,%d,'%s','%s')",
+ intval($r[0]['id']),
+ intval($channel['channel_id']),
+ dbesc($i['sid']),
+ dbesc($i['service'])
+ );
+ }
+ }
+ }
+}
+
+function import_events($channel,$events) {
+
+ if($channel && $events) {
+ foreach($events as $event) {
+ unset($event['id']);
+ $event['aid'] = $channel['channel_account_id'];
+ $event['uid'] = $channel['channel_id'];
+
+ dbesc_array($event);
+ $r = dbq("INSERT INTO event (`"
+ . implode("`, `", array_keys($event))
+ . "`) VALUES ('"
+ . implode("', '", array_values($event))
+ . "')"
+ );
+ }
+ }
+}
+
+
+function sync_events($channel,$events) {
+
+ if($channel && $events) {
+ foreach($events as $event) {
+
+ if((! $event['event_hash']) || (! $event['start']))
+ continue;
+
+ if($event['event_deleted']) {
+ $r = q("delete from event where event_hash = '%s' and uid = %d limit 1",
+ dbesc($event['event_hash']),
+ intval($channel['channel_id'])
+ );
+ continue;
+ }
+
+ unset($event['id']);
+ $event['aid'] = $channel['channel_account_id'];
+ $event['uid'] = $channel['channel_id'];
+
+ $exists = false;
+
+ $x = q("select * from event where event_hash = '%s' and uid = %d limit 1",
+ dbesc($event['event_hash']),
+ intval($channel['channel_id'])
+ );
+ if($x) {
+ if($x[0]['edited'] >= $event['edited'])
+ continue;
+ $exists = true;
+ }
+
+ if($exists) {
+ foreach($event as $k => $v) {
+ $r = q("UPDATE event SET `%s` = '%s' WHERE event_hash = '%s' AND uid = %d",
+ dbesc($k),
+ dbesc($v),
+ dbesc($event['event_hash']),
+ intval($channel['channel_id'])
+ );
+ }
+ }
+ else {
+ dbesc_array($event);
+ $r = dbq("INSERT INTO event (`"
+ . implode("`, `", array_keys($event))
+ . "`) VALUES ('"
+ . implode("', '", array_values($event))
+ . "')"
+ );
+ }
+ }
+ }
+}
+
+
+function import_menus($channel,$menus) {
+
+ if($channel && $menus) {
+ foreach($menus as $menu) {
+ $m = array();
+ $m['menu_channel_id'] = $channel['channel_id'];
+ $m['menu_name'] = $menu['pagetitle'];
+ $m['menu_desc'] = $menu['desc'];
+ if($menu['created'])
+ $m['menu_created'] = datetime_convert($menu['created']);
+ if($menu['edited'])
+ $m['menu_edited'] = datetime_convert($menu['edited']);
+
+ $m['menu_flags'] = 0;
+ if($menu['flags']) {
+ if(in_array('bookmark',$menu['flags']))
+ $m['menu_flags'] |= MENU_BOOKMARK;
+ if(in_array('system',$menu['flags']))
+ $m['menu_flags'] |= MENU_SYSTEM;
+
+ }
+
+ $menu_id = menu_create($m);
+
+ if($menu_id) {
+ if(is_array($menu['items'])) {
+ foreach($menu['items'] as $it) {
+ $mitem = array();
+
+ $mitem['mitem_link'] = str_replace('[baseurl]',z_root(),$it['link']);
+ $mitem['mitem_desc'] = escape_tags($it['desc']);
+ $mitem['mitem_order'] = intval($it['order']);
+ if(is_array($it['flags'])) {
+ $mitem['mitem_flags'] = 0;
+ if(in_array('zid',$it['flags']))
+ $mitem['mitem_flags'] |= MENU_ITEM_ZID;
+ if(in_array('new-window',$it['flags']))
+ $mitem['mitem_flags'] |= MENU_ITEM_NEWWIN;
+ if(in_array('chatroom',$it['flags']))
+ $mitem['mitem_flags'] |= MENU_ITEM_CHATROOM;
+ }
+ menu_add_item($menu_id,$channel['channel_id'],$mitem);
+ }
+ }
+ }
+ }
+ }
+}
+
+
+function sync_menus($channel,$menus) {
+
+ if($channel && $menus) {
+ foreach($menus as $menu) {
+ $m = array();
+ $m['menu_channel_id'] = $channel['channel_id'];
+ $m['menu_name'] = $menu['pagetitle'];
+ $m['menu_desc'] = $menu['desc'];
+ if($menu['created'])
+ $m['menu_created'] = datetime_convert($menu['created']);
+ if($menu['edited'])
+ $m['menu_edited'] = datetime_convert($menu['edited']);
+
+ $m['menu_flags'] = 0;
+ if($menu['flags']) {
+ if(in_array('bookmark',$menu['flags']))
+ $m['menu_flags'] |= MENU_BOOKMARK;
+ if(in_array('system',$menu['flags']))
+ $m['menu_flags'] |= MENU_SYSTEM;
+
+ }
+
+ $editing = false;
+
+ $r = q("select * from menu where menu_name = '%s' and menu_channel_id = %d limit 1",
+ dbesc($m['menu_name']),
+ intval($channel['channel_id'])
+ );
+ if($r) {
+ if($r[0]['menu_edited'] >= $m['menu_edited'])
+ continue;
+ if($menu['menu_deleted']) {
+ menu_delete_id($r[0]['menu_id'],$channel['channel_id']);
+ continue;
+ }
+ $menu_id = $r[0]['menu_id'];
+ $m['menu_id'] = $r[0]['menu_id'];
+ $x = menu_edit($m);
+ if(! $x)
+ continue;
+ $editing = true;
+ }
+ if(! $editing) {
+ $menu_id = menu_create($m);
+ }
+ if($menu_id) {
+ if($editing) {
+ // don't try syncing - just delete all the entries and start over
+ q("delete from menu_item where mitem_menu_id = %d",
+ intval($menu_id)
+ );
+ }
+
+ if(is_array($menu['items'])) {
+ foreach($menu['items'] as $it) {
+ $mitem = array();
+
+ $mitem['mitem_link'] = str_replace('[baseurl]',z_root(),$it['link']);
+ $mitem['mitem_desc'] = escape_tags($it['desc']);
+ $mitem['mitem_order'] = intval($it['order']);
+ if(is_array($it['flags'])) {
+ $mitem['mitem_flags'] = 0;
+ if(in_array('zid',$it['flags']))
+ $mitem['mitem_flags'] |= MENU_ITEM_ZID;
+ if(in_array('new-window',$it['flags']))
+ $mitem['mitem_flags'] |= MENU_ITEM_NEWWIN;
+ if(in_array('chatroom',$it['flags']))
+ $mitem['mitem_flags'] |= MENU_ITEM_CHATROOM;
+ }
+ menu_add_item($menu_id,$channel['channel_id'],$mitem);
+ }
+ }
+ }
+ }
+ }
+}
+
+
+
+function import_likes($channel,$likes) {
+ if($channel && $likes) {
+ foreach($likes as $like) {
+ if($like['deleted']) {
+ q("delete from likes where liker = '%s' and likee = '%s' and verb = '%s' and target_type = '%s' and target_id = '%s'",
+ dbesc($like['liker']),
+ dbesc($like['likee']),
+ dbesc($like['verb']),
+ dbesc($like['target_type']),
+ dbesc($like['target_id'])
+ );
+ continue;
+ }
+
+ unset($like['id']);
+ unset($like['iid']);
+ $like['channel_id'] = $channel['channel_id'];
+ $r = q("select * from likes where liker = '%s' and likee = '%s' and verb = '%s' and target_type = '%s' and target_id = '%s' and i_mid = '%s'",
+ dbesc($like['liker']),
+ dbesc($like['likee']),
+ dbesc($like['verb']),
+ dbesc($like['target_type']),
+ dbesc($like['target_id']),
+ dbesc($like['i_mid'])
+ );
+ if($r)
+ continue;
+
+ dbesc_array($like);
+ $r = dbq("INSERT INTO likes (`"
+ . implode("`, `", array_keys($like))
+ . "`) VALUES ('"
+ . implode("', '", array_values($like))
+ . "')" );
+ }
+ }
+}
+
+function import_conv($channel,$convs) {
+ if($channel && $convs) {
+ foreach($convs as $conv) {
+ if($conv['deleted']) {
+ q("delete from conv where guid = '%s' and uid = %d limit 1",
+ dbesc($conv['guid']),
+ intval($channel['channel_id'])
+ );
+ continue;
+ }
+
+ unset($conv['id']);
+
+ $conv['uid'] = $channel['channel_id'];
+ $conv['subject'] = str_rot47(base64url_encode($conv['subject']));
+
+ $r = q("select id from conv where guid = '%s' and uid = %d limit 1",
+ dbesc($conv['guid']),
+ intval($channel['channel_id'])
+ );
+ if($r)
+ continue;
+
+ dbesc_array($conv);
+ $r = dbq("INSERT INTO conv (`"
+ . implode("`, `", array_keys($conv))
+ . "`) VALUES ('"
+ . implode("', '", array_values($conv))
+ . "')" );
+ }
+ }
+}
+
+
+
+function import_mail($channel,$mails) {
+ if($channel && $mails) {
+ foreach($mails as $mail) {
+ if(array_key_exists('flags',$mail) && in_array('deleted',$mail['flags'])) {
+ q("delete from mail where mid = '%s' and uid = %d limit 1",
+ dbesc($mail['message_id']),
+ intval($channel['channel_id'])
+ );
+ continue;
+ }
+ if(array_key_exists('flags',$mail) && in_array('recalled',$mail['flags'])) {
+ q("update mail set mail_recalled = 1 where mid = '%s' and uid = %d limit 1",
+ dbesc($mail['message_id']),
+ intval($channel['channel_id'])
+ );
+ continue;
+ }
+
+ $m = get_mail_elements($mail);
+ if(! $m)
+ continue;
+
+ $m['aid'] = $channel['channel_account_id'];
+ $m['uid'] = $channel['channel_id'];
+ mail_store($m);
+ }
+ }
+}
+
+
+
+
+
+
diff --git a/include/importdoc.php b/include/importdoc.php
new file mode 100755
index 000000000..10f868697
--- /dev/null
+++ b/include/importdoc.php
@@ -0,0 +1,41 @@
+<?php
+
+
+
+require_once('include/cli_startup.php');
+
+
+function importdoc_run($argv, $argc){
+
+ cli_startup();
+
+ require_once('mod/help.php');
+
+
+ update_docs_dir('doc/*');
+
+}
+if (array_search(__file__,get_included_files())===0){
+ importdoc_run($argv,$argc);
+ killme();
+}
+
+function update_docs_dir($s) {
+ $f = basename($s);
+ $d = dirname($s);
+ if($s === 'doc/html')
+ return;
+ $files = glob("$d/$f");
+ if($files) {
+ foreach($files as $fi) {
+ if($fi === 'doc/html')
+ continue;
+ if(is_dir($fi))
+ update_docs_dir("$fi/*");
+ else
+ store_doc_file($fi);
+ }
+ }
+}
+
+
diff --git a/include/items.php b/include/items.php
index 54dcf2b51..3e4805212 100755
--- a/include/items.php
+++ b/include/items.php
@@ -42,9 +42,8 @@ function collect_recipients($item, &$private_envelope) {
// as that would allow the denied person to see the post by logging out.
if((! $item['allow_cid']) && (! $item['allow_gid'])) {
- $r = q("select * from abook where abook_channel = %d and not (abook_flags & %d)>0 ",
- intval($item['uid']),
- intval(ABOOK_FLAG_SELF|ABOOK_FLAG_PENDING|ABOOK_FLAG_ARCHIVED)
+ $r = q("select * from abook where abook_channel = %d and abook_self = 0 and abook_pending = 0 and abook_archived = 0 ",
+ intval($item['uid'])
);
if($r) {
@@ -82,9 +81,8 @@ function collect_recipients($item, &$private_envelope) {
//$sys = get_sys_channel();
if(array_key_exists('public_policy',$item) && $item['public_policy'] !== 'self') {
- $r = q("select abook_xchan, xchan_network from abook left join xchan on abook_xchan = xchan_hash where abook_channel = %d and not (abook_flags & %d)>0 ",
- intval($item['uid']),
- intval(ABOOK_FLAG_SELF|ABOOK_FLAG_PENDING|ABOOK_FLAG_ARCHIVED)
+ $r = q("select abook_xchan, xchan_network from abook left join xchan on abook_xchan = xchan_hash where abook_channel = %d and abook_self = 0 and abook_pending = 0 and abook_archived = 0 ",
+ intval($item['uid'])
);
if($r) {
@@ -192,20 +190,30 @@ function comments_are_now_closed($item) {
return false;
}
+function item_normal() {
+ return " and item.item_hidden = 0 and item.item_type = 0 and item.item_deleted = 0
+ and item.item_unpublished = 0 and item.item_delayed = 0 and item.item_pending_remove = 0
+ and item.item_blocked = 0 ";
+}
+
/**
* @brief
*
* This is a compatibility function primarily for plugins, because
- * in future hubzilla (and later) DB schemas the definition of a
- * normal item gets a bit more complicated.
+ * in earlier DB schemas this was a much simpler single integer compare
*
*/
function is_item_normal($item) {
- return((intval($item['item_restrict'])) ? false : true);
-}
+ if(intval($item['item_hidden']) || intval($item['item_type']) || intval($item['item_deleted'])
+ || intval($item['item_unpublished']) || intval($item['item_delayed']) || intval($item['item_pending_remove'])
+ || intval($item['item_blocked']))
+ return false;
+
+ return true;
+}
/**
* @brief
@@ -264,6 +272,8 @@ function can_comment_on_post($observer_xchan, $item) {
}
if(strstr($item['comment_policy'],'network:') && strstr($item['comment_policy'],'red'))
return true;
+ if(strstr($item['comment_policy'],'network:') && strstr($item['comment_policy'],'diaspora'))
+ return true;
if(strstr($item['comment_policy'],'site:') && strstr($item['comment_policy'],get_app()->get_hostname()))
return true;
@@ -396,12 +406,12 @@ function post_activity_item($arr) {
if((($arr['parent']) && $arr['parent'] != $arr['id']) || (($arr['parent_mid']) && $arr['parent_mid'] != $arr['mid']))
$is_comment = true;
- if(! x($arr,'item_flags')) {
- if($is_comment)
- $arr['item_flags'] = ITEM_ORIGIN;
- else
- $arr['item_flags'] = ITEM_ORIGIN | ITEM_WALL | ITEM_THREAD_TOP;
- }
+ if(! array_key_exists('item_origin',$arr))
+ $arr['item_origin'] = 1;
+ if(! array_key_exists('item_wall',$arr) && (! $is_comment))
+ $arr['item_wall'] = 1;
+ if(! array_key_exists('item_thread_top',$arr) && (! $is_comment))
+ $arr['item_thread_top'] = 1;
$channel = get_app()->get_channel();
$observer = get_app()->get_observer();
@@ -428,17 +438,9 @@ function post_activity_item($arr) {
if($channel) {
if($channel['channel_hash'] === $arr['author_xchan']) {
$arr['sig'] = base64url_encode(rsa_sign($arr['body'],$channel['channel_prvkey']));
- $arr['item_flags'] = $arr['item_flags'] | ITEM_VERIFIED;
+ $arr['item_verified'] = 1;
}
}
-
- logger('Encrypting local storage');
- $key = get_config('system','pubkey');
- $arr['item_flags'] = $arr['item_flags'] | ITEM_OBSCURED;
- if($arr['title'])
- $arr['title'] = json_encode(crypto_encapsulate($arr['title'],$key));
- if($arr['body'])
- $arr['body'] = json_encode(crypto_encapsulate($arr['body'],$key));
}
$arr['mid'] = ((x($arr,'mid')) ? $arr['mid'] : item_message_id());
@@ -460,7 +462,7 @@ function post_activity_item($arr) {
$arr['comment_policy'] = map_scope($channel['channel_w_comment']);
- if ((! $arr['plink']) && ($arr['item_flags'] & ITEM_THREAD_TOP)) {
+ if ((! $arr['plink']) && (intval($arr['item_thread_top']))) {
$arr['plink'] = z_root() . '/channel/' . $channel['channel_address'] . '/?f=&mid=' . $arr['mid'];
}
@@ -495,6 +497,32 @@ function post_activity_item($arr) {
return $ret;
}
+
+function validate_item_elements($message,$arr) {
+
+ $result = array('success' => false);
+
+ if(! array_key_exists('created',$arr))
+ $result['message'] = 'missing created, possible author/owner lookup failure';
+
+ if((! $arr['mid']) || (! $arr['parent_mid']))
+ $result['message'] = 'missing message-id or parent message-id';
+
+ if(array_key_exists('flags',$message) && in_array('relay',$message['flags']) && $arr['mid'] === $arr['parent_mid'])
+ $result['message'] = 'relay set on top level post';
+
+ if(! $result['message'])
+ $result['success'] = true;
+
+ return $result;
+
+}
+
+
+
+
+
+
/**
* @brief Generate an Atom feed.
*
@@ -807,7 +835,6 @@ function title_is_body($title, $body) {
function get_item_elements($x,$allow_code = false) {
-
$arr = array();
if($allow_code)
@@ -874,7 +901,8 @@ function get_item_elements($x,$allow_code = false) {
if(array_key_exists('diaspora_signature',$x) && is_array($x['diaspora_signature']))
$x['diaspora_signature'] = json_encode($x['diaspora_signature']);
- $arr['diaspora_meta'] = (($x['diaspora_signature']) ? json_encode(crypto_encapsulate($x['diaspora_signature'],$key)) : '');
+ $arr['diaspora_meta'] = (($x['diaspora_signature']) ? $x['diaspora_signature'] : '');
+
$arr['object'] = activity_sanitise($x['object']);
$arr['target'] = activity_sanitise($x['target']);
@@ -886,11 +914,12 @@ function get_item_elements($x,$allow_code = false) {
$arr['item_flags'] = 0;
if(array_key_exists('flags',$x) && in_array('consensus',$x['flags']))
- $arr['item_flags'] |= ITEM_CONSENSUS;
+ $arr['item_consensus'] = 1;
+
if(array_key_exists('flags',$x) && in_array('deleted',$x['flags']))
- $arr['item_restrict'] |= ITEM_DELETED;
+ $arr['item_deleted'] = 1;
if(array_key_exists('flags',$x) && in_array('hidden',$x['flags']))
- $arr['item_restrict'] |= ITEM_HIDDEN;
+ $arr['item_hidden'] = 1;
// Here's the deal - the site might be down or whatever but if there's a new person you've never
// seen before sending stuff to your stream, we MUST be able to look them up and import their data from their
@@ -918,26 +947,13 @@ function get_item_elements($x,$allow_code = false) {
dbesc($arr['author_xchan'])
);
if($r && rsa_verify($x['body'],base64url_decode($arr['sig']),$r[0]['xchan_pubkey']))
- $arr['item_flags'] |= ITEM_VERIFIED;
+ $arr['item_verified'] = 1;
else
logger('get_item_elements: message verification failed.');
}
- // if it's a private post, encrypt it in the DB.
- // We have to do that here because we need to cleanse the input and prevent bad stuff from getting in,
- // and we need plaintext to do that.
-
-
- if(intval($arr['item_private'])) {
- $arr['item_flags'] = $arr['item_flags'] | ITEM_OBSCURED;
- if($arr['title'])
- $arr['title'] = json_encode(crypto_encapsulate($arr['title'],$key));
- if($arr['body'])
- $arr['body'] = json_encode(crypto_encapsulate($arr['body'],$key));
- }
-
-
if(array_key_exists('revision',$x)) {
+
// extended export encoding
$arr['revision'] = $x['revision'];
@@ -950,66 +966,77 @@ function get_item_elements($x,$allow_code = false) {
$arr['resource_id'] = $x['resource_id'];
$arr['resource_type'] = $x['resource_type'];
$arr['attach'] = $x['attach'];
+ $arr['item_origin'] = $x['item_origin'];
+ $arr['item_unseen'] = $x['item_unseen'];
+ $arr['item_starred'] = $x['item_starred'];
+ $arr['item_uplink'] = $x['item_uplink'];
+ $arr['item_consensus'] = $x['item_consensus'];
+ $arr['item_wall'] = $x['item_wall'];
+ $arr['item_thread_top'] = $x['item_thread_top'];
+ $arr['item_notshown'] = $x['item_notshown'];
+ $arr['item_nsfw'] = $x['item_nsfw'];
+ // local only $arr['item_relay'] = $x['item_relay'];
+ $arr['item_mentionsme'] = $x['item_mentionsme'];
+ $arr['item_nocomment'] = $x['item_nocomment'];
+ // local only $arr['item_obscured'] = $x['item_obscured'];
+ // local only $arr['item_verified'] = $x['item_verified'];
+ $arr['item_retained'] = $x['item_retained'];
+ $arr['item_rss'] = $x['item_rss'];
+ $arr['item_deleted'] = $x['item_deleted'];
+ $arr['item_type'] = $x['item_type'];
+ $arr['item_hidden'] = $x['item_hidden'];
+ $arr['item_unpublished'] = $x['item_unpublished'];
+ $arr['item_delayed'] = $x['item_delayed'];
+ $arr['item_pending_remove'] = $x['item_pending_remove'];
+ $arr['item_blocked'] = $x['item_blocked'];
+ if(array_key_exists('item_flags',$x)) {
+ if($x['item_flags'] & 0x0004)
+ $arr['item_starred'] = 1;
+ if($x['item_flags'] & 0x0008)
+ $arr['item_uplink'] = 1;
+ if($x['item_flags'] & 0x0010)
+ $arr['item_consensus'] = 1;
+ if($x['item_flags'] & 0x0020)
+ $arr['item_wall'] = 1;
+ if($x['item_flags'] & 0x0040)
+ $arr['item_thread_top'] = 1;
+ if($x['item_flags'] & 0x0080)
+ $arr['item_notshown'] = 1;
+ if($x['item_flags'] & 0x0100)
+ $arr['item_nsfw'] = 1;
+ if($x['item_flags'] & 0x0400)
+ $arr['item_mentionsme'] = 1;
+ if($x['item_flags'] & 0x0800)
+ $arr['item_nocomment'] = 1;
+ if($x['item_flags'] & 0x4000)
+ $arr['item_retained'] = 1;
+ if($x['item_flags'] & 0x8000)
+ $arr['item_rss'] = 1;
- if(! array_key_exists('item_origin',$x)) {
- $arr['item_restrict'] = $x['item_restrict'];
- $arr['item_flags'] = $x['item_flags'];
}
-
- if(array_key_exists('item_origin',$x) && intval($x['item_origin']))
- $arr['item_flags'] |= ITEM_ORIGIN;
- if(array_key_exists('item_unseen',$x) && intval($x['item_unseen']))
- $arr['item_flags'] |= ITEM_UNSEEN;
- if(array_key_exists('item_starred',$x) && intval($x['item_starred']))
- $arr['item_flags'] |= ITEM_STARRED;
- if(array_key_exists('item_uplink',$x) && intval($x['item_uplink']))
- $arr['item_flags'] |= ITEM_UPLINK;
- if(array_key_exists('item_consensus',$x) && intval($x['item_consensus']))
- $arr['item_flags'] |= ITEM_CONSENSUS;
- if(array_key_exists('item_wall',$x) && intval($x['item_wall']))
- $arr['item_flags'] |= ITEM_WALL;
- if(array_key_exists('item_thread_top',$x) && intval($x['item_thread_top']))
- $arr['item_flags'] |= ITEM_THREAD_TOP;
- if(array_key_exists('item_notshown',$x) && intval($x['item_notshown']))
- $arr['item_flags'] |= ITEM_NOTSHOWN;
- if(array_key_exists('item_nsfw',$x) && intval($x['item_nsfw']))
- $arr['item_flags'] |= ITEM_NSFW;
- if(array_key_exists('item_mentionsme',$x) && intval($x['item_mentionsme']))
- $arr['item_flags'] |= ITEM_MENTIONSME;
- if(array_key_exists('item_nocomment',$x) && intval($x['item_nocomment']))
- $arr['item_flags'] |= ITEM_NOCOMMENT;
- if(array_key_exists('item_retained',$x) && intval($x['item_retained']))
- $arr['item_flags'] |= ITEM_RETAINED;
- if(array_key_exists('item_rss',$x) && intval($x['item_rss']))
- $arr['item_flags'] |= ITEM_RSS;
-
-
- if(array_key_exists('item_deleted',$x)&& intval($x['item_deleted']))
- $arr['item_restrict'] |= ITEM_DELETED;
- if(array_key_exists('item_unpublished',$x)&& intval($x['item_unpublished']))
- $arr['item_restrict'] |= ITEM_UNPUBLISHED;
- if(array_key_exists('item_delayed',$x)&& intval($x['item_delayed']))
- $arr['item_restrict'] |= ITEM_DELAYED_PUBLISH;
- if(array_key_exists('item_pending_remove',$x)&& intval($x['item_pending_remove']))
- $arr['item_restrict'] |= ITEM_PENDING_REMOVE;
- if(array_key_exists('item_type',$x)) {
- switch(intval($x['item_type'])) {
- case 1:
- $arr['item_restrict'] |= ITEM_BUILDBLOCK;
- break;
- case 2:
- $arr['item_restrict'] |= ITEM_PDL;
- break;
- case 3:
- $arr['item_restrict'] |= ITEM_WEBPAGE;
- break;
- case 4:
- $arr['item_restrict'] |= ITEM_BUG;
- break;
- case 0:
- default:
- break;
- }
+ if(array_key_exists('item_restrict',$x)) {
+ if($x['item_restrict'] & 0x0001)
+ $arr['item_hidden'] = 1;
+ if($x['item_restrict'] & 0x0002)
+ $arr['item_blocked'] = 1;
+ if($x['item_restrict'] & 0x0010)
+ $arr['item_deleted'] = 1;
+ if($x['item_restrict'] & 0x0020)
+ $arr['item_unpublished'] = 1;
+ if($x['item_restrict'] & 0x0040)
+ $arr['item_type'] = ITEM_TYPE_WEBPAGE;
+ if($x['item_restrict'] & 0x0080)
+ $arr['item_delayed'] = 1;
+ if($x['item_restrict'] & 0x0100)
+ $arr['item_type'] = ITEM_TYPE_BLOCK;
+ if($x['item_restrict'] & 0x0200)
+ $arr['item_type'] = ITEM_TYPE_PDL;
+ if($x['item_restrict'] & 0x0400)
+ $arr['item_type'] = ITEM_TYPE_BUG;
+ if($x['item_restrict'] & 0x0800)
+ $arr['item_pending_remove'] = 1;
+ if($x['item_restrict'] & 0x1000)
+ $arr['item_type'] = ITEM_TYPE_DOC;
}
}
@@ -1104,7 +1131,7 @@ function import_author_rss($x) {
if($r && $x['photo']) {
- $photos = import_profile_photo($x['photo']['src'],$x['url']);
+ $photos = import_xchan_photo($x['photo']['src'],$x['url']);
if($photos) {
/** @bug $arr is undefined in this SQL query */
@@ -1149,7 +1176,7 @@ function import_author_unknown($x) {
);
if($r && $x['photo']) {
- $photos = import_profile_photo($x['photo']['src'],$x['url']);
+ $photos = import_xchan_photo($x['photo']['src'],$x['url']);
if($photos) {
/** @bug $arr is undefined in this SQL query */
@@ -1193,7 +1220,7 @@ function encode_item($item,$mirror = false) {
$key = get_config('system','prvkey');
- if(array_key_exists('item_flags',$item) && ($item['item_flags'] & ITEM_OBSCURED)) {
+ if(array_key_exists('item_obscured',$item) && intval($item['item_obscured'])) {
if($item['title'])
$item['title'] = crypto_unencapsulate(json_decode_plus($item['title']),$key);
if($item['body'])
@@ -1216,67 +1243,30 @@ function encode_item($item,$mirror = false) {
$x['postopts'] = $item['postopts'];
$x['resource_id'] = $item['resource_id'];
$x['resource_type'] = $item['resource_type'];
- $x['item_restrict'] = $item['item_restrict'];
- $x['item_flags'] = $item['item_flags'];
- $x['item_unseen'] = $item['item_unseen'];
$x['attach'] = $item['attach'];
- if(array_key_exists('item_starred',$item) && intval($item['item_starred']))
- $x['item_flags'] |= ITEM_STARRED;
- if(array_key_exists('item_uplink',$item) && intval($item['item_uplink']))
- $x['item_flags'] |= ITEM_UPLINK;
- if(array_key_exists('item_consensus',$item) && intval($item['item_consensus']))
- $x['item_flags'] |= ITEM_CONSENSUS;
- if(array_key_exists('item_wall',$item) && intval($item['item_wall']))
- $x['item_flags'] |= ITEM_WALL;
- if(array_key_exists('item_thread_top',$item) && intval($item['item_thread_top']))
- $x['item_flags'] |= ITEM_THREAD_TOP;
- if(array_key_exists('item_notshown',$item) && intval($item['item_notshown']))
- $x['item_flags'] |= ITEM_NOTSHOWN;
- if(array_key_exists('item_nsfw',$item) && intval($item['item_nsfw']))
- $x['item_flags'] |= ITEM_NSFW;
- if(array_key_exists('item_mentionsme',$item) && intval($item['item_mentionsme']))
- $x['item_flags'] |= ITEM_MENTIONSME;
- if(array_key_exists('item_nocomment',$item) && intval($item['item_nocomment']))
- $x['item_flags'] |= ITEM_NOCOMMENT;
- if(array_key_exists('item_retained',$item) && intval($item['item_retained']))
- $x['item_flags'] |= ITEM_RETAINED;
- if(array_key_exists('item_rss',$item) && intval($item['item_rss']))
- $x['item_flags'] |= ITEM_RSS;
- if(array_key_exists('item_deleted',$item) && intval($item['item_deleted']))
- $x['item_restrict'] |= ITEM_DELETED;
- if(array_key_exists('item_hidden',$item) && intval($item['item_hidden']))
- $x['item_restrict'] |= ITEM_HIDDEN;
- if(array_key_exists('item_unpublished',$item) && intval($item['item_unpublished']))
- $x['item_restrict'] |= ITEM_UNPUBLISHED;
- if(array_key_exists('item_delayed',$item) && intval($item['item_delayed']))
- $x['item_restrict'] |= ITEM_DELAYED_PUBLISH;
- if(array_key_exists('item_pending_remove',$item) && intval($item['item_pending_remove']))
- $x['item_restrict'] |= ITEM_PENDING_REMOVE;
- if(array_key_exists('item_blocked',$item) && intval($item['item_blocked']))
- $x['item_flags'] |= ITEM_BLOCKED;
- if(array_key_exists('item_',$item) && intval($item['item_']))
- $x['item_flags'] |= ITEM_;
- if(array_key_exists('item_type',$item) && intval($item['item_type'])) {
- switch(intval($item['item_type'])) {
- case 1:
- $x['item_restrict'] |= ITEM_BUILDBLOCK;
- break;
- case 2:
- $x['item_restrict'] |= ITEM_PDL;
- break;
- case 3:
- $x['item_restrict'] |= ITEM_WEBPAGE;
- break;
- case 4:
- $x['item_restrict'] |= ITEM_BUG;
- break;
- case 5:
- $x['item_restrict'] |= ITEM_DOC;
- break;
- default:
- break;
- }
- }
+ $x['item_origin'] = $item['item_origin'];
+ $x['item_unseen'] = $item['item_unseen'];
+ $x['item_starred'] = $item['item_starred'];
+ $x['item_uplink'] = $item['item_uplink'];
+ $x['item_consensus'] = $item['item_consensus'];
+ $x['item_wall'] = $item['item_wall'];
+ $x['item_thread_top'] = $item['item_thread_top'];
+ $x['item_notshown'] = $item['item_notshown'];
+ $x['item_nsfw'] = $item['item_nsfw'];
+ $x['item_relay'] = $item['item_relay'];
+ $x['item_mentionsme'] = $item['item_mentionsme'];
+ $x['item_nocomment'] = $item['item_nocomment'];
+ $x['item_obscured'] = $item['item_obscured'];
+ $x['item_verified'] = $item['item_verified'];
+ $x['item_retained'] = $item['item_retained'];
+ $x['item_rss'] = $item['item_rss'];
+ $x['item_deleted'] = $item['item_deleted'];
+ $x['item_type'] = $item['item_type'];
+ $x['item_hidden'] = $item['item_hidden'];
+ $x['item_unpublished'] = $item['item_unpublished'];
+ $x['item_delayed'] = $item['item_delayed'];
+ $x['item_pending_remove'] = $item['item_pending_remove'];
+ $x['item_blocked'] = $item['item_blocked'];
}
@@ -1317,7 +1307,7 @@ function encode_item($item,$mirror = false) {
$x['public_scope'] = $scope;
- if($item['item_flags'] & ITEM_NOCOMMENT)
+ if($item['item_nocomment'])
$x['comment_scope'] = 'none';
else
$x['comment_scope'] = $c_scope;
@@ -1325,9 +1315,17 @@ function encode_item($item,$mirror = false) {
if($item['term'])
$x['tags'] = encode_item_terms($item['term'],$mirror);
- if($item['diaspora_meta'])
- $x['diaspora_signature'] = crypto_unencapsulate(json_decode($item['diaspora_meta'],true),$key);
-
+ if($item['diaspora_meta']) {
+ $z = json_decode($item['diaspora_meta'],true);
+ if($z) {
+ if(is_array($z) && array_key_exists('iv',$z))
+ $x['diaspora_signature'] = crypto_unencapsulate($z,$key);
+ else
+ $x['diaspora_signature'] = $z;
+ if(! is_array($z))
+ logger('encode_item: diaspora meta is not an array: ' . print_r($z,true));
+ }
+ }
logger('encode_item: ' . print_r($x,true), LOGGER_DATA);
return $x;
@@ -1407,7 +1405,7 @@ function encode_item_xchan($xchan) {
return $ret;
}
-function encode_item_terms($terms) {
+function encode_item_terms($terms,$mirror = false) {
$ret = array();
$allowed_export_terms = array( TERM_UNKNOWN, TERM_HASHTAG, TERM_MENTION, TERM_CATEGORY, TERM_BOOKMARK );
@@ -1545,17 +1543,17 @@ function encode_item_flags($item) {
$ret = array();
- if($item['item_restrict'] & ITEM_DELETED)
+ if(intval($item['item_deleted']))
$ret[] = 'deleted';
- if($item['item_restrict'] & ITEM_HIDDEN)
+ if(intval($item['item_hidden']))
$ret[] = 'hidden';
- if($item['item_flags'] & ITEM_THREAD_TOP)
+ if(intval($item['item_thread_top']))
$ret[] = 'thread_parent';
- if($item['item_flags'] & ITEM_NSFW)
+ if(intval($item['item_nsfw']))
$ret[] = 'nsfw';
- if($item['item_flags'] & ITEM_CONSENSUS)
+ if(intval($item['item_consensus']))
$ret[] = 'consensus';
- if($item['item_private'])
+ if(intval($item['item_private']))
$ret[] = 'private';
return $ret;
@@ -1566,12 +1564,11 @@ function encode_mail($item,$extended = false) {
$x['type'] = 'mail';
$x['encoding'] = 'zot';
- if(array_key_exists('mail_flags',$item) && ($item['mail_flags'] & MAIL_OBSCURED)) {
- $key = get_config('system','prvkey');
+ if(array_key_exists('mail_obscured',$item) && intval($item['mail_obscured'])) {
if($item['title'])
- $item['title'] = crypto_unencapsulate(json_decode_plus($item['title']),$key);
+ $item['title'] = base64url_decode(str_rot47($item['title']));
if($item['body'])
- $item['body'] = crypto_unencapsulate(json_decode_plus($item['body']),$key);
+ $item['body'] = base64url_decode(str_rot47($item['body']));
}
$x['message_id'] = $item['mid'];
@@ -1589,7 +1586,7 @@ function encode_mail($item,$extended = false) {
$x['flags'] = array();
- if($item['mail_flags'] & MAIL_RECALLED) {
+ if(intval($item['mail_recalled'])) {
$x['flags'][] = 'recalled';
$x['title'] = '';
$x['body'] = '';
@@ -1597,13 +1594,13 @@ function encode_mail($item,$extended = false) {
if($extended) {
$x['conv_guid'] = $item['conv_guid'];
- if($item['mail_flags'] & MAIL_DELETED)
+ if(intval($item['mail_deleted']))
$x['flags'][] = 'deleted';
- if($item['mail_flags'] & MAIL_REPLIED)
+ if(intval($item['mail_replied']))
$x['flags'][] = 'replied';
- if($item['mail_flags'] & MAIL_ISREPLY)
+ if(intval($item['mail_isreply']))
$x['flags'][] = 'isreply';
- if($item['mail_flags'] & MAIL_SEEN)
+ if(intval($item['mail_seen']))
$x['flags'][] = 'seen';
}
@@ -1619,6 +1616,8 @@ function get_mail_elements($x) {
$arr['body'] = (($x['body']) ? htmlspecialchars($x['body'], ENT_COMPAT,'UTF-8',false) : '');
$arr['title'] = (($x['title'])? htmlspecialchars($x['title'],ENT_COMPAT,'UTF-8',false) : '');
+ $arr['conv_guid'] = (($x['conv_guid'])? htmlspecialchars($x['conv_guid'],ENT_COMPAT,'UTF-8',false) : '');
+
$arr['created'] = datetime_convert('UTC','UTC',$x['created']);
if((! array_key_exists('expires',$x)) || ($x['expires'] === NULL_DATE))
$arr['expires'] = NULL_DATE;
@@ -1629,34 +1628,35 @@ function get_mail_elements($x) {
if($x['flags'] && is_array($x['flags'])) {
if(in_array('recalled',$x['flags'])) {
- $arr['mail_flags'] |= MAIL_RECALLED;
+ $arr['mail_recalled'] = 1;
}
if(in_array('replied',$x['flags'])) {
- $arr['mail_flags'] |= MAIL_REPLIED;
+ $arr['mail_replied'] = 1;
}
if(in_array('isreply',$x['flags'])) {
- $arr['mail_flags'] |= MAIL_ISREPLY;
+ $arr['mail_isreply'] = 1;
}
if(in_array('seen',$x['flags'])) {
- $arr['mail_flags'] |= MAIL_SEEN;
+ $arr['mail_seen'] = 1;
}
if(in_array('deleted',$x['flags'])) {
- $arr['mail_flags'] |= MAIL_DELETED;
+ $arr['mail_deleted'] = 1;
}
}
$key = get_config('system','pubkey');
- $arr['mail_flags'] |= MAIL_OBSCURED;
- $arr['body'] = htmlspecialchars($arr['body'],ENT_COMPAT,'UTF-8',false);
- if($arr['body'])
- $arr['body'] = json_encode(crypto_encapsulate($arr['body'],$key));
- $arr['title'] = htmlspecialchars($arr['title'],ENT_COMPAT,'UTF-8',false);
- if($arr['title'])
- $arr['title'] = json_encode(crypto_encapsulate($arr['title'],$key));
+ $arr['mail_obscured'] = 1;
+ if($arr['body']) {
+ $arr['body'] = str_rot47(base64url_encode($arr['body']));
+ }
+ if($arr['title']) {
+ $arr['title'] = str_rot47(base64url_encode($arr['title']));
+ }
if($arr['created'] > datetime_convert())
$arr['created'] = datetime_convert();
+
$arr['mid'] = (($x['message_id']) ? htmlspecialchars($x['message_id'], ENT_COMPAT,'UTF-8',false) : '');
$arr['parent_mid'] = (($x['message_parent']) ? htmlspecialchars($x['message_parent'], ENT_COMPAT,'UTF-8',false) : '');
@@ -1735,7 +1735,7 @@ function get_atom_elements($feed, $item, &$author) {
$res['title'] = unxmlify($item->get_title());
$res['body'] = unxmlify($item->get_content());
$res['plink'] = unxmlify($item->get_link(0));
- $res['item_flags'] = ITEM_RSS;
+ $res['item_rss'] = 1;
// removing the content of the title if its identically to the body
@@ -2175,11 +2175,11 @@ function item_store($arr, $allow_exec = false) {
// If a page layout is provided, ensure it exists and belongs to us.
if(array_key_exists('layout_mid',$arr) && $arr['layout_mid']) {
- $l = q("select item_restrict from item where mid = '%s' and uid = %d limit 1",
+ $l = q("select item_type from item where mid = '%s' and uid = %d limit 1",
dbesc($arr['layout_mid']),
intval($arr['uid'])
);
- if((! $l) || (! ($l[0]['item_restrict'] & ITEM_PDL)))
+ if((! $l) || (! ($l[0]['item_type'] != ITEM_TYPE_PDL)))
unset($arr['layout_mid']);
}
@@ -2208,12 +2208,13 @@ function item_store($arr, $allow_exec = false) {
$arr['deny_cid'] = ((x($arr,'deny_cid')) ? trim($arr['deny_cid']) : '');
$arr['deny_gid'] = ((x($arr,'deny_gid')) ? trim($arr['deny_gid']) : '');
$arr['item_private'] = ((x($arr,'item_private')) ? intval($arr['item_private']) : 0 );
- $arr['item_flags'] = ((x($arr,'item_flags')) ? intval($arr['item_flags']) : 0 );
+ $arr['item_wall'] = ((x($arr,'item_wall')) ? intval($arr['item_wall']) : 0 );
+ $arr['item_type'] = ((x($arr,'item_type')) ? intval($arr['item_type']) : 0 );
// only detect language if we have text content, and if the post is private but not yet
// obscured, make it so.
- if(! ($arr['item_flags'] & ITEM_OBSCURED)) {
+ if((! array_key_exists('item_obscured',$arr)) || $arr['item_obscured'] == 0) {
$arr['lang'] = detect_language($arr['body']);
// apply the input filter here - if it is obscured it has been filtered already
@@ -2223,7 +2224,7 @@ function item_store($arr, $allow_exec = false) {
$channel = get_app()->get_channel();
if($channel['channel_hash'] === $arr['author_xchan']) {
$arr['sig'] = base64url_encode(rsa_sign($arr['body'],$channel['channel_prvkey']));
- $arr['item_flags'] |= ITEM_VERIFIED;
+ $arr['item_verified'] = 1;
}
}
@@ -2239,14 +2240,6 @@ function item_store($arr, $allow_exec = false) {
}
$arr = $translate['item'];
}
- if($arr['item_private']) {
- $key = get_config('system','pubkey');
- $arr['item_flags'] = $arr['item_flags'] | ITEM_OBSCURED;
- if($arr['title'])
- $arr['title'] = json_encode(crypto_encapsulate($arr['title'],$key));
- if($arr['body'])
- $arr['body'] = json_encode(crypto_encapsulate($arr['body'],$key));
- }
}
if((x($arr,'object')) && is_array($arr['object'])) {
@@ -2288,16 +2281,16 @@ function item_store($arr, $allow_exec = false) {
$arr['plink'] = ((x($arr,'plink')) ? notags(trim($arr['plink'])) : '');
$arr['attach'] = ((x($arr,'attach')) ? notags(trim($arr['attach'])) : '');
$arr['app'] = ((x($arr,'app')) ? notags(trim($arr['app'])) : '');
- $arr['item_restrict'] = ((x($arr,'item_restrict')) ? intval($arr['item_restrict']) : 0 );
$arr['public_policy'] = ((x($arr,'public_policy')) ? notags(trim($arr['public_policy'])) : '' );
$arr['comment_policy'] = ((x($arr,'comment_policy')) ? notags(trim($arr['comment_policy'])) : 'contacts' );
+
+ if(! array_key_exists('item_unseen',$arr))
+ $arr['item_unseen'] = 1;
- $arr['item_unseen'] = ((array_key_exists('item_unseen',$arr)) ? intval($arr['item_unseen']) : 1);
-
- if($arr['comment_policy'] == 'none')
- $arr['item_flags'] = $arr['item_flags'] | ITEM_NOCOMMENT;
+ if((! array_key_exists('item_nocomment',$arr)) && ($arr['comment_policy'] == 'none'))
+ $arr['item_nocomment'] = 1;
// handle time travelers
// Allow a bit of fudge in case somebody just has a slightly slow/fast clock
@@ -2305,7 +2298,7 @@ function item_store($arr, $allow_exec = false) {
$d1 = new DateTime('now +10 minutes', new DateTimeZone('UTC'));
$d2 = new DateTime($arr['created'] . '+00:00');
if($d2 > $d1)
- $arr['item_restrict'] = $arr['item_restrict'] | ITEM_DELAYED_PUBLISH;
+ $arr['item_delayed'] = 1;
$arr['llink'] = z_root() . '/display/' . $arr['mid'];
@@ -2321,7 +2314,7 @@ function item_store($arr, $allow_exec = false) {
$deny_gid = $arr['deny_gid'];
$public_policy = $arr['public_policy'];
$comments_closed = $arr['comments_closed'];
- $arr['item_flags'] = $arr['item_flags'] | ITEM_THREAD_TOP;
+ $arr['item_thread_top'] = 1;
}
else {
@@ -2371,7 +2364,7 @@ function item_store($arr, $allow_exec = false) {
}
$parent_id = $r[0]['id'];
- $parent_deleted = $r[0]['item_restrict'] & ITEM_DELETED;
+ $parent_deleted = $r[0]['item_deleted'];
$allow_cid = $r[0]['allow_cid'];
$allow_gid = $r[0]['allow_gid'];
$deny_cid = $r[0]['deny_cid'];
@@ -2379,8 +2372,8 @@ function item_store($arr, $allow_exec = false) {
$public_policy = $r[0]['public_policy'];
$comments_closed = $r[0]['comments_closed'];
- if($r[0]['item_flags'] & ITEM_WALL)
- $arr['item_flags'] = $arr['item_flags'] | ITEM_WALL;
+ if(intval($r[0]['item_wall']))
+ $arr['item_wall'] = 1;
// An uplinked comment might arrive with a downstream owner.
// Fix it.
@@ -2399,7 +2392,7 @@ function item_store($arr, $allow_exec = false) {
// The original author commented, but as this is a comment, the permissions
// weren't fixed up so it will still show the comment as private unless we fix it here.
- if((intval($r[0]['item_flags']) & ITEM_UPLINK) && (! $r[0]['item_private']))
+ if(intval($r[0]['item_uplink']) && (! $r[0]['item_private']))
$arr['item_private'] = 0;
}
else {
@@ -2410,7 +2403,7 @@ function item_store($arr, $allow_exec = false) {
}
if($parent_deleted)
- $arr['item_restrict'] = $arr['item_restrict'] | ITEM_DELETED;
+ $arr['item_deleted'] = 1;
$r = q("SELECT `id` FROM `item` WHERE `mid` = '%s' AND `uid` = %d LIMIT 1",
dbesc($arr['mid']),
@@ -2522,10 +2515,9 @@ function item_store($arr, $allow_exec = false) {
// update the commented timestamp on the parent
- $z = q("select max(created) as commented from item where parent_mid = '%s' and uid = %d and not ( item_restrict & %d )>0 ",
+ $z = q("select max(created) as commented from item where parent_mid = '%s' and uid = %d and item_delayed = 0 ",
dbesc($arr['parent_mid']),
- intval($arr['uid']),
- intval(ITEM_DELAYED_PUBLISH)
+ intval($arr['uid'])
);
q("UPDATE item set commented = '%s', changed = '%s' WHERE id = %d",
@@ -2540,7 +2532,7 @@ function item_store($arr, $allow_exec = false) {
// so that we have an item in the DB that's marked deleted and won't store a fresh post
// that isn't aware that we were already told to delete it.
- if(! ($arr['item_restrict'] & ITEM_DELETED)) {
+ if(! intval($arr['item_deleted'])) {
send_status_notifications($current_post,$arr);
tag_deliver($arr['uid'],$current_post);
}
@@ -2587,17 +2579,8 @@ function item_store_update($arr,$allow_exec = false) {
// override the unseen flag with the original
- if(intval($arr['item_flags']))
- $arr['item_unseen'] = 0;
-
- if($orig[0]['item_flags'] & ITEM_VERIFIED)
- $orig[0]['item_flags'] = $orig[0]['item_flags'] ^ ITEM_VERIFIED;
+ $arr['item_unseen'] = $orig[0]['item_unseen'];
- if($orig[0]['item_flags'] & ITEM_OBSCURED)
- $orig[0]['item_flags'] = $orig[0]['item_flags'] ^ ITEM_OBSCURED;
-
- $arr['item_flags'] = intval($arr['item_flags']) | $orig[0]['item_flags'];
- $arr['item_restrict'] = intval($arr['item_restrict']) | $orig[0]['item_restrict'];
if(array_key_exists('edit',$arr))
unset($arr['edit']);
@@ -2610,19 +2593,20 @@ function item_store_update($arr,$allow_exec = false) {
return $ret;
}
- if(! ($arr['item_flags'] & ITEM_OBSCURED)) {
+ if((! array_key_exists('item_obscured', $arr)) || $arr['item_obscured'] == 0) {
$arr['lang'] = detect_language($arr['body']);
- // apply the input filter here - if it is obscured it has been filtered already
- $arr['body'] = trim(z_input_filter($arr['uid'],$arr['body'],$arr['mimetype']));
- if(local_channel() && (! $arr['sig'])) {
- $channel = get_app()->get_channel();
- if($channel['channel_hash'] === $arr['author_xchan']) {
- $arr['sig'] = base64url_encode(rsa_sign($arr['body'],$channel['channel_prvkey']));
- $arr['item_flags'] |= ITEM_VERIFIED;
- }
- }
+ // apply the input filter here - if it is obscured it has been filtered already
+ $arr['body'] = trim(z_input_filter($arr['uid'],$arr['body'],$arr['mimetype']));
+
+ if(local_channel() && (! $arr['sig'])) {
+ $channel = get_app()->get_channel();
+ if($channel['channel_hash'] === $arr['author_xchan']) {
+ $arr['sig'] = base64url_encode(rsa_sign($arr['body'],$channel['channel_prvkey']));
+ $arr['item_verified'] = 1;
+ }
+ }
$allowed_languages = get_pconfig($arr['uid'],'system','allowed_languages');
@@ -2636,14 +2620,6 @@ function item_store_update($arr,$allow_exec = false) {
}
$arr = $translate['item'];
}
- if($arr['item_private']) {
- $key = get_config('system','pubkey');
- $arr['item_flags'] = $arr['item_flags'] | ITEM_OBSCURED;
- if($arr['title'])
- $arr['title'] = json_encode(crypto_encapsulate($arr['title'],$key));
- if($arr['body'])
- $arr['body'] = json_encode(crypto_encapsulate($arr['body'],$key));
- }
}
if((x($arr,'object')) && is_array($arr['object'])) {
@@ -2701,13 +2677,38 @@ function item_store_update($arr,$allow_exec = false) {
$arr['deny_gid'] = ((array_key_exists('deny_gid',$arr)) ? trim($arr['deny_gid']) : $orig[0]['deny_gid']);
$arr['item_private'] = ((array_key_exists('item_private',$arr)) ? intval($arr['item_private']) : $orig[0]['item_private']);
- $arr['title'] = ((array_key_exists('title',$arr)) ? trim($arr['title']) : $orig[0]['title']);
- $arr['body'] = ((array_key_exists('body',$arr)) ? trim($arr['body']) : $orig[0]['body']);
+ $arr['title'] = ((array_key_exists('title',$arr) && strlen($arr['title'])) ? trim($arr['title']) : '');
+ $arr['body'] = ((array_key_exists('body',$arr) && strlen($arr['body'])) ? trim($arr['body']) : '');
+ $arr['html'] = ((array_key_exists('html',$arr) && strlen($arr['html'])) ? trim($arr['html']) : '');
+
+ $arr['attach'] = ((array_key_exists('attach',$arr)) ? notags(trim($arr['attach'])) : $orig[0]['attach']);
+ $arr['app'] = ((array_key_exists('app',$arr)) ? notags(trim($arr['app'])) : $orig[0]['app']);
+
+ $arr['item_origin'] = ((array_key_exists('item_origin',$arr)) ? intval($arr['item_origin']) : $orig[0]['item_origin'] );
+ $arr['item_unseen'] = ((array_key_exists('item_unseen',$arr)) ? intval($arr['item_unseen']) : $orig[0]['item_unseen'] );
+ $arr['item_starred'] = ((array_key_exists('item_starred',$arr)) ? intval($arr['item_starred']) : $orig[0]['item_starred'] );
+ $arr['item_uplink'] = ((array_key_exists('item_uplink',$arr)) ? intval($arr['item_uplink']) : $orig[0]['item_uplink'] );
+ $arr['item_consensus'] = ((array_key_exists('item_consensus',$arr)) ? intval($arr['item_consensus']) : $orig[0]['item_consensus'] );
+ $arr['item_wall'] = ((array_key_exists('item_wall',$arr)) ? intval($arr['item_wall']) : $orig[0]['item_wall'] );
+ $arr['item_thread_top'] = ((array_key_exists('item_thread_top',$arr)) ? intval($arr['item_thread_top']) : $orig[0]['item_thread_top'] );
+ $arr['item_notshown'] = ((array_key_exists('item_notshown',$arr)) ? intval($arr['item_notshown']) : $orig[0]['item_notshown'] );
+ $arr['item_nsfw'] = ((array_key_exists('item_nsfw',$arr)) ? intval($arr['item_nsfw']) : $orig[0]['item_nsfw'] );
+ $arr['item_relay'] = ((array_key_exists('item_relay',$arr)) ? intval($arr['item_relay']) : $orig[0]['item_relay'] );
+ $arr['item_mentionsme'] = ((array_key_exists('item_mentionsme',$arr)) ? intval($arr['item_mentionsme']) : $orig[0]['item_mentionsme'] );
+ $arr['item_nocomment'] = ((array_key_exists('item_nocomment',$arr)) ? intval($arr['item_nocomment']) : $orig[0]['item_nocomment'] );
+ $arr['item_obscured'] = ((array_key_exists('item_obscured',$arr)) ? intval($arr['item_obscured']) : $orig[0]['item_obscured'] );
+ $arr['item_verified'] = ((array_key_exists('item_verified',$arr)) ? intval($arr['item_verified']) : $orig[0]['item_verified'] );
+ $arr['item_retained'] = ((array_key_exists('item_retained',$arr)) ? intval($arr['item_retained']) : $orig[0]['item_retained'] );
+ $arr['item_rss'] = ((array_key_exists('item_rss',$arr)) ? intval($arr['item_rss']) : $orig[0]['item_rss'] );
+ $arr['item_deleted'] = ((array_key_exists('item_deleted',$arr)) ? intval($arr['item_deleted']) : $orig[0]['item_deleted'] );
+ $arr['item_type'] = ((array_key_exists('item_type',$arr)) ? intval($arr['item_type']) : $orig[0]['item_type'] );
+ $arr['item_hidden'] = ((array_key_exists('item_hidden',$arr)) ? intval($arr['item_hidden']) : $orig[0]['item_hidden'] );
+ $arr['item_unpublished'] = ((array_key_exists('item_unpublished',$arr)) ? intval($arr['item_unpublished']) : $orig[0]['item_unpublished'] );
+ $arr['item_delayed'] = ((array_key_exists('item_delayed',$arr)) ? intval($arr['item_delayed']) : $orig[0]['item_delayed'] );
+ $arr['item_pending_remove'] = ((array_key_exists('item_pending_remove',$arr)) ? intval($arr['item_pending_remove']) : $orig[0]['item_pending_remove'] );
+ $arr['item_blocked'] = ((array_key_exists('item_blocked',$arr)) ? intval($arr['item_blocked']) : $orig[0]['item_blocked'] );
+
- $arr['attach'] = ((x($arr,'attach')) ? notags(trim($arr['attach'])) : $orig[0]['attach']);
- $arr['app'] = ((x($arr,'app')) ? notags(trim($arr['app'])) : $orig[0]['app']);
-// $arr['item_restrict'] = ((x($arr,'item_restrict')) ? intval($arr['item_restrict']) : $orig[0]['item_restrict'] );
-// $arr['item_flags'] = ((x($arr,'item_flags')) ? intval($arr['item_flags']) : $orig[0]['item_flags'] );
$arr['sig'] = ((x($arr,'sig')) ? $arr['sig'] : '');
$arr['layout_mid'] = ((array_key_exists('layout_mid',$arr)) ? dbesc($arr['layout_mid']) : $orig[0]['layout_mid'] );
@@ -2818,11 +2819,10 @@ function store_diaspora_comment_sig($datarray, $channel, $parent_item, $post_id,
$x = array('signer' => $diaspora_handle, 'body' => $signed_body, 'signed_text' => $signed_text, 'signature' => base64_encode($authorsig));
- $key = get_config('system','pubkey');
- $y = crypto_encapsulate(json_encode($x),$key);
+ $y = json_encode($x);
$r = q("update item set diaspora_meta = '%s' where id = %d",
- dbesc(json_encode($y)),
+ dbesc($y),
intval($post_id)
);
@@ -2837,6 +2837,8 @@ function store_diaspora_comment_sig($datarray, $channel, $parent_item, $post_id,
function send_status_notifications($post_id,$item) {
$notify = false;
+ $unfollowed = false;
+
$parent = 0;
$r = q("select channel_hash from channel where channel_id = %d limit 1",
@@ -2864,6 +2866,14 @@ function send_status_notifications($post_id,$item) {
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
+ // but it will be extremely rare for this to be wrong.
+
+ if(($xx['verb'] === ACTIVITY_UNFOLLOW)
+ && ($xx['obj_type'] === ACTIVITY_OBJ_NOTE || $xx['obj_type'] === ACTIVITY_OBJ_PHOTO)
+ && ($xx['parent'] != $xx['id']))
+ $unfollowed = true;
}
if($xx['id'] == $xx['parent']) {
$parent = $xx['parent'];
@@ -2871,6 +2881,9 @@ function send_status_notifications($post_id,$item) {
}
}
+ if($unfollowed)
+ return;
+
$link = get_app()->get_baseurl() . '/display/' . $item['mid'];
$y = q("select id from notify where link = '%s' and uid = %d limit 1",
@@ -2947,8 +2960,8 @@ function tag_deliver($uid, $item_id) {
$item = $i[0];
- if(($item['source_xchan']) && ($item['item_flags'] & ITEM_UPLINK)
- && ($item['item_flags'] & ITEM_THREAD_TOP) && ($item['edited'] != $item['created'])) {
+ if(($item['source_xchan']) && intval($item['item_uplink'])
+ && intval($item['item_thread_top']) && ($item['edited'] != $item['created'])) {
// this is an update (edit) to a post which was already processed by us and has a second delivery chain
// Just start the second delivery chain to deliver the updated post
proc_run('php','include/notifier.php','tgroup',$item['id']);
@@ -2970,7 +2983,7 @@ function tag_deliver($uid, $item_id) {
if($obj['id'] !== $u[0]['channel_hash'])
$poke_notify = false;
}
- if($item['item_restrict'] & ITEM_DELETED)
+ if(intval($item['item_deleted']))
$poke_notify = false;
$verb = urldecode(substr($item['verb'],strpos($item['verb'],'#')+1));
@@ -3047,13 +3060,13 @@ function tag_deliver($uid, $item_id) {
// This might be a followup (e.g. comment) by the original post author to a tagged forum
// If so setup a second delivery chain
- if( ! ($item['item_flags'] & ITEM_THREAD_TOP)) {
+ if( ! intval($item['item_thread_top'])) {
$x = q("select * from item where id = parent and parent = %d and uid = %d limit 1",
intval($item['parent']),
intval($uid)
);
- if(($x) && ($x[0]['item_flags'] & ITEM_UPLINK)) {
+ if(($x) && intval($x[0]['item_uplink'])) {
start_delivery_chain($u[0],$item,$item_id,$x[0]);
}
}
@@ -3081,9 +3094,8 @@ function tag_deliver($uid, $item_id) {
if($mention) {
logger('tag_deliver: mention found for ' . $u[0]['channel_name']);
-
- $r = q("update item set item_flags = ( item_flags | %d ) where id = %d",
- intval(ITEM_MENTIONSME),
+
+ $r = q("update item set item_mentionsme = 1 where id = %d",
intval($item_id)
);
@@ -3093,7 +3105,7 @@ function tag_deliver($uid, $item_id) {
$body = '';
- if($item['item_flags'] & ITEM_OBSCURED) {
+ if(intval($item['item_obscured'])) {
$key = get_config('system','prvkey');
if($item['body'])
$body = crypto_unencapsulate(json_decode_plus($item['body']),$key);
@@ -3177,10 +3189,8 @@ function tag_deliver($uid, $item_id) {
// prevent delivery looping - only proceed
// if the message originated elsewhere and is a top-level post
- if(($item['item_flags'] & ITEM_WALL)
- || ($item['item_flags'] & ITEM_ORIGIN)
- || (!($item['item_flags'] & ITEM_THREAD_TOP))
- || ($item['id'] != $item['parent'])) {
+
+ if(intval($item['item_wall']) || intval($item['item_origin']) || (! intval($item['item_thread_top'])) || ($item['id'] != $item['parent'])) {
logger('tag_deliver: item was local or a comment. rejected.');
return;
}
@@ -3205,10 +3215,9 @@ function tgroup_check($uid,$item) {
// or is a followup and we have already accepted the top level post as an uplink
if($item['mid'] != $item['parent_mid']) {
- $r = q("select id from item where mid = '%s' and uid = %d and ( item_flags & %d )>0 limit 1",
+ $r = q("select id from item where mid = '%s' and uid = %d and item_uplink = 1 limit 1",
dbesc($item['parent_mid']),
- intval($uid),
- intval(ITEM_UPLINK)
+ intval($uid)
);
if($r)
return true;
@@ -3254,7 +3263,7 @@ function tgroup_check($uid,$item) {
$body = $item['body'];
- if(array_key_exists('item_flags',$item) && ($item['item_flags'] & ITEM_OBSCURED) && $body) {
+ if(array_key_exists('item_obscured',$item) && intval($item['item_obscured']) && $body) {
$key = get_config('system','prvkey');
$body = crypto_unencapsulate(json_decode($body,true),$key);
}
@@ -3317,20 +3326,14 @@ function start_delivery_chain($channel, $item, $item_id, $parent) {
if((! $private) && $new_public_policy)
$private = 1;
- $flag_bits = $item['item_flags'] | ITEM_WALL;
-
- // The message didn't necessarily originate on this site, (we'll honour it if it did),
- // but the parent post of this thread will be reset as a local post, as it is the top of
- // this delivery chain and is coming from this site, regardless of where the original
- // originated.
-
- if(! $parent)
- $flag_bits = $flag_bits | ITEM_ORIGIN;
- // unset the nocomment bit if it's there.
+ $item_wall = 1;
+ $item_origin = 1;
+ $item_uplink = 0;
+ $item_nocomment = 0;
+ $item_obscured = 0;
- if($flag_bits & ITEM_NOCOMMENT)
- $flag_bits = $flag_bits ^ ITEM_NOCOMMENT;
+ $flag_bits = $item['item_flags'];
// maintain the original source, which will be the original item owner and was stored in source_xchan
// when we created the delivery fork
@@ -3342,7 +3345,7 @@ function start_delivery_chain($channel, $item, $item_id, $parent) {
);
}
else {
- $flag_bits = $flag_bits | ITEM_UPLINK;
+ $item_uplink = 1;
$r = q("update item set source_xchan = owner_xchan where id = %d",
intval($item_id)
);
@@ -3351,29 +3354,11 @@ function start_delivery_chain($channel, $item, $item_id, $parent) {
$title = $item['title'];
$body = $item['body'];
- if($private) {
- if(!($flag_bits & ITEM_OBSCURED)) {
- $key = get_config('system','pubkey');
- $flag_bits = $flag_bits|ITEM_OBSCURED;
- if($title)
- $title = json_encode(crypto_encapsulate($title,$key));
- if($body)
- $body = json_encode(crypto_encapsulate($body,$key));
- }
- }
- else {
- if($flag_bits & ITEM_OBSCURED) {
- $key = get_config('system','prvkey');
- $flag_bits = $flag_bits ^ ITEM_OBSCURED;
- if($title)
- $title = crypto_unencapsulate(json_decode($title,true),$key);
- if($body)
- $body = crypto_unencapsulate(json_decode($body,true),$key);
- }
- }
-
- $r = q("update item set item_flags = %d, owner_xchan = '%s', allow_cid = '%s', allow_gid = '%s',
- deny_cid = '%s', deny_gid = '%s', item_private = %d, public_policy = '%s', comment_policy = '%s', title = '%s', body = '%s' where id = %d",
+ $r = q("update item set item_uplink = %d, item_nocomment = %d, item_obscured = %d, item_flags = %d, owner_xchan = '%s', allow_cid = '%s', allow_gid = '%s',
+ deny_cid = '%s', deny_gid = '%s', item_private = %d, public_policy = '%s', comment_policy = '%s', title = '%s', body = '%s', item_wall = %d, item_origin = %d where id = %d",
+ intval($item_uplink),
+ intval($item_nocomment),
+ intval($item_obscured),
intval($flag_bits),
dbesc($channel['channel_hash']),
dbesc($channel['channel_allow_cid']),
@@ -3385,6 +3370,8 @@ function start_delivery_chain($channel, $item, $item_id, $parent) {
dbesc(map_scope($channel['channel_w_comment'])),
dbesc($title),
dbesc($body),
+ intval($item_wall),
+ intval($item_origin),
intval($item_id)
);
@@ -3413,7 +3400,7 @@ function check_item_source($uid, $item) {
if(! $r)
return false;
- $x = q("select abook_their_perms, abook_flags from abook where abook_channel = %d and abook_xchan = '%s' limit 1",
+ $x = q("select abook_their_perms, abook_feed from abook where abook_channel = %d and abook_xchan = '%s' limit 1",
intval($uid),
dbesc($item['owner_xchan'])
);
@@ -3424,7 +3411,7 @@ function check_item_source($uid, $item) {
if(! ($x[0]['abook_their_perms'] & PERMS_A_REPUBLISH))
return false;
- if($item['item_private'] && (! ($x[0]['abook_flags'] & ABOOK_FLAG_FEED)))
+ if($item['item_private'] && (! intval($x[0]['abook_feed'])))
return false;
if($r[0]['src_channel_xchan'] === $item['owner_xchan'])
@@ -3481,6 +3468,7 @@ function post_is_importable($item,$abook) {
$text = prepare_text($item['body'],$item['mimetype']);
$text = html2plain($text);
+
$lang = null;
if((strpos($abook['abook_incl'],'lang=') !== false) || (strpos($abook['abook_excl'],'lang=') !== false)) {
@@ -3495,6 +3483,8 @@ function post_is_importable($item,$abook) {
if($exclude) {
foreach($exclude as $word) {
$word = trim($word);
+ if(! $word)
+ continue;
if(substr($word,0,1) === '#' && $tags) {
foreach($tags as $t)
if(($t['type'] == TERM_HASHTAG) && (($t['term'] === substr($word,1)) || (substr($word,1) === '*')))
@@ -3514,6 +3504,8 @@ function post_is_importable($item,$abook) {
if($include) {
foreach($include as $word) {
$word = trim($word);
+ if(! $word)
+ continue;
if(substr($word,0,1) === '#' && $tags) {
foreach($tags as $t)
if(($t['type'] == TERM_HASHTAG) && (($t['term'] === substr($word,1)) || (substr($word,1) === '*')))
@@ -3542,8 +3534,10 @@ function mail_store($arr) {
return 0;
}
- if((strpos($arr['body'],'<') !== false) || (strpos($arr['body'],'>') !== false))
- $arr['body'] = escape_tags($arr['body']);
+ if(! $arr['mail_obscured']) {
+ if((strpos($arr['body'],'<') !== false) || (strpos($arr['body'],'>') !== false))
+ $arr['body'] = escape_tags($arr['body']);
+ }
if(array_key_exists('attach',$arr) && is_array($arr['attach']))
$arr['attach'] = json_encode($arr['attach']);
@@ -3554,9 +3548,10 @@ function mail_store($arr) {
$arr['to_xchan'] = ((x($arr,'to_xchan')) ? notags(trim($arr['to_xchan'])) : '');
$arr['created'] = ((x($arr,'created') !== false) ? datetime_convert('UTC','UTC',$arr['created']) : datetime_convert());
$arr['expires'] = ((x($arr,'expires') !== false) ? datetime_convert('UTC','UTC',$arr['expires']) : NULL_DATE);
- $arr['title'] = ((x($arr,'title')) ? notags(trim($arr['title'])) : '');
+ $arr['title'] = ((x($arr,'title')) ? trim($arr['title']) : '');
$arr['parent_mid'] = ((x($arr,'parent_mid')) ? notags(trim($arr['parent_mid'])) : '');
$arr['body'] = ((x($arr,'body')) ? trim($arr['body']) : '');
+ $arr['conv_guid'] = ((x($arr,'conv_guid')) ? trim($arr['conv_guid']) : '');
$arr['mail_flags'] = ((x($arr,'mail_flags')) ? intval($arr['mail_flags']) : 0 );
@@ -3569,11 +3564,17 @@ function mail_store($arr) {
dbesc($arr['mid']),
intval($arr['channel_id'])
);
+
if($r) {
logger('mail_store: duplicate item ignored. ' . print_r($arr,true));
return 0;
}
+ if(! $r && $arr['mail_recalled'] == 1) {
+ logger('mail_store: recalled item not found. ' . print_r($arr,true));
+ return 0;
+ }
+
call_hooks('post_mail',$arr);
if(x($arr,'cancel')) {
@@ -3709,7 +3710,7 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) {
if($r) {
$item = $r[0];
- if(! ($item['item_restrict'] & ITEM_DELETED)) {
+ if(! intval($item['item_deleted'])) {
logger('consume_feed: deleting item ' . $item['id'] . ' mid=' . base64url_decode($item['mid']), LOGGER_DEBUG);
drop_item($item['id'],false);
}
@@ -4207,22 +4208,23 @@ function item_expire($uid,$days) {
$expire_network_only = 1;
+ $sql_extra = ((intval($expire_network_only)) ? " AND item_wall = 0 " : "");
+
$expire_limit = get_config('system','expire_limit');
if(! intval($expire_limit))
$expire_limit = 5000;
- $sql_extra = ((intval($expire_network_only)) ? " AND (item_flags & " . intval(ITEM_WALL) . ") = 0 " : "");
+ $item_normal = item_normal();
$r = q("SELECT * FROM `item`
WHERE `uid` = %d
AND `created` < %s - INTERVAL %s
AND `id` = `parent`
$sql_extra
- AND ( item_flags & %d ) = 0
- AND ( item_restrict = 0 ) LIMIT $expire_limit ",
+ AND item_retained = 0
+ $item_normal LIMIT $expire_limit ",
intval($uid),
- db_utcnow(), db_quoteinterval(intval($days).' DAY'),
- intval(ITEM_RETAINED)
+ db_utcnow(), db_quoteinterval(intval($days).' DAY')
);
if(! $r)
@@ -4246,7 +4248,7 @@ function item_expire($uid,$days) {
retain_item($item['id']);
continue;
}
- if($item['item_flags'] & ITEM_STARRED) {
+ if(intval($item['item_starred'])) {
retain_item($item['id']);
continue;
}
@@ -4258,8 +4260,7 @@ function item_expire($uid,$days) {
}
function retain_item($id) {
- $r = q("update item set item_flags = (item_flags | %d ) where id = %d",
- intval(ITEM_RETAINED),
+ $r = q("update item set item_retained = 1 where id = %d",
intval($id)
);
}
@@ -4304,7 +4305,7 @@ function drop_item($id,$interactive = true,$stage = DROPITEM_NORMAL,$force = fal
intval($id)
);
- if((! $r) || (($r[0]['item_restrict'] & ITEM_DELETED) && ($stage === DROPITEM_NORMAL))) {
+ if((! $r) || (intval($r[0]['item_deleted']) && ($stage === DROPITEM_NORMAL))) {
if(! $interactive)
return 0;
notice( t('Item not found.') . EOL);
@@ -4340,10 +4341,16 @@ function drop_item($id,$interactive = true,$stage = DROPITEM_NORMAL,$force = fal
// set the deleted flag immediately on this item just in case the
// hook calls a remote process which loops. We'll delete it properly in a second.
- $r = q("UPDATE item SET item_restrict = ( item_restrict | %d ) WHERE id = %d",
- intval(($linked_item && ! $force) ? ITEM_HIDDEN : ITEM_DELETED),
- intval($item['id'])
- );
+ if(($linked_item) && (! $force)) {
+ $r = q("UPDATE item SET item_hidden = 1 WHERE id = %d",
+ intval($item['id'])
+ );
+ }
+ else {
+ $r = q("UPDATE item SET item_deleted = 1 WHERE id = %d",
+ intval($item['id'])
+ );
+ }
$arr = array('item' => $item, 'interactive' => $interactive, 'stage' => $stage);
call_hooks('drop_item', $arr );
@@ -4372,7 +4379,7 @@ function drop_item($id,$interactive = true,$stage = DROPITEM_NORMAL,$force = fal
// We'll rely on the undocumented behaviour that DROPITEM_PHASE1 is (hopefully) only
// set if we know we're going to send delete notifications out to others.
- if((($item['item_flags'] & ITEM_WALL) && ($stage != DROPITEM_PHASE2)) || ($stage == DROPITEM_PHASE1))
+ if((intval($item['item_wall']) && ($stage != DROPITEM_PHASE2)) || ($stage == DROPITEM_PHASE1))
proc_run('php','include/notifier.php','drop',$notify_id);
goaway($a->get_baseurl() . '/' . $_SESSION['return_url']);
@@ -4404,9 +4411,8 @@ function delete_item_lowlevel($item, $stage = DROPITEM_NORMAL, $force = false) {
switch($stage) {
case DROPITEM_PHASE2:
- $r = q("UPDATE item SET item_restrict = ( item_restrict | %d ), body = '', title = '',
+ $r = q("UPDATE item SET item_pending_remove = 1, body = '', title = '',
changed = '%s', edited = '%s' WHERE id = %d",
- intval(ITEM_PENDING_REMOVE),
dbesc(datetime_convert()),
dbesc(datetime_convert()),
intval($item['id'])
@@ -4414,30 +4420,37 @@ function delete_item_lowlevel($item, $stage = DROPITEM_NORMAL, $force = false) {
break;
case DROPITEM_PHASE1:
- $r = q("UPDATE item SET item_restrict = ( item_restrict | %d ),
- changed = '%s', edited = '%s' WHERE id = %d",
- intval(($linked_item && ! $force) ? ITEM_HIDDEN : ITEM_DELETED),
- dbesc(datetime_convert()),
- dbesc(datetime_convert()),
- intval($item['id'])
- );
+ if($linked_item && ! $force) {
+ $r = q("UPDATE item SET item_hidden = 1,
+ changed = '%s', edited = '%s' WHERE id = %d",
+ dbesc(datetime_convert()),
+ dbesc(datetime_convert()),
+ intval($item['id'])
+ );
+ }
+ else {
+ $r = q("UPDATE item set item_deleted = 1, changed = '%s', edited = '%s' where id = %d",
+ dbesc(datetime_convert()),
+ dbesc(datetime_convert()),
+ intval($item['id'])
+ );
+ }
+
break;
case DROPITEM_NORMAL:
default:
if($linked_item && ! $force) {
- $r = q("UPDATE item SET item_restrict = ( item_restrict | %d ),
+ $r = q("UPDATE item SET item_hidden = 1,
changed = '%s', edited = '%s' WHERE id = %d",
- intval(ITEM_HIDDEN),
dbesc(datetime_convert()),
dbesc(datetime_convert()),
intval($item['id'])
);
}
else {
- $r = q("UPDATE item SET item_restrict = ( item_restrict | %d ), body = '', title = '',
+ $r = q("UPDATE item SET item_deleted = 1, body = '', title = '',
changed = '%s', edited = '%s' WHERE id = %d",
- intval(ITEM_DELETED),
dbesc(datetime_convert()),
dbesc(datetime_convert()),
intval($item['id'])
@@ -4453,6 +4466,18 @@ function delete_item_lowlevel($item, $stage = DROPITEM_NORMAL, $force = false) {
intval($item['uid'])
);
+ // remove delivery reports
+
+ $c = q("select channel_hash from channel where channel_id = %d limit 1",
+ intval($item['uid'])
+ );
+ if($c) {
+ q("delete from dreport where dreport_xchan = '%s' and dreport_mid = '%s'",
+ dbesc($c[0]['channel_hash']),
+ dbesc($item['mid'])
+ );
+ }
+
// network deletion request. Keep the message structure so that we can deliver delete notifications.
// Come back after several days (or perhaps a month) to do the lowlevel delete (DROPITEM_PHASE2).
@@ -4482,12 +4507,12 @@ function delete_item_lowlevel($item, $stage = DROPITEM_NORMAL, $force = false) {
function first_post_date($uid,$wall = false) {
- $wall_sql = (($wall) ? sprintf(" and (item_flags & %d)>0 ", ITEM_WALL) : "" );
+ $wall_sql = (($wall) ? " and item_wall = 1 " : "" );
+ $item_normal = item_normal();
$r = q("select id, created from item
- where item_restrict = %d and uid = %d and id = parent $wall_sql
+ where uid = %d and id = parent $item_normal $wall_sql
order by created asc limit 1",
- intval(ITEM_VISIBLE),
intval($uid)
);
@@ -4688,23 +4713,23 @@ function zot_feed($uid,$observer_hash,$arr) {
$groupby = 'GROUP BY parent';
}
+ $item_normal = item_normal();
+
if(is_sys_channel($uid)) {
$r = q("SELECT parent, created, postopts from item
WHERE uid != %d
- AND item_private = 0 AND item_restrict = 0 AND uid in (" . stream_perms_api_uids(PERMS_PUBLIC,10,1) . ")
- AND (item_flags & %d) > 0
- $sql_extra $groupby ORDER BY created ASC $limit",
- intval($uid),
- intval(ITEM_WALL)
+ $item_normal
+ AND item_wall = 1
+ and item_private = 0 $sql_extra $groupby ORDER BY created ASC $limit",
+ intval($uid)
);
}
else {
$r = q("SELECT parent, created, postopts from item
- WHERE uid = %d AND item_restrict = 0
- AND (item_flags & %d) > 0
+ WHERE uid = %d $item_normal
+ AND item_wall = 1
$sql_extra $groupby ORDER BY created ASC $limit",
- intval($uid),
- intval(ITEM_WALL)
+ intval($uid)
);
}
@@ -4717,10 +4742,10 @@ function zot_feed($uid,$observer_hash,$arr) {
$parents_str = ids_to_querystr($r,'parent');
$sys_query = ((is_sys_channel($uid)) ? $sql_extra : '');
+ $item_normal = item_normal();
$items = q("SELECT `item`.*, `item`.`id` AS `item_id` FROM `item`
- WHERE `item`.`item_restrict` = 0
- AND `item`.`parent` IN ( %s ) $sys_query ",
+ WHERE `item`.`parent` IN ( %s ) $item_normal $sys_query ",
dbesc($parents_str)
);
}
@@ -4758,6 +4783,8 @@ function items_fetch($arr,$channel = null,$observer_hash = null,$client_mode = C
$def_acl = '';
$item_uids = ' true ';
+ $item_normal = item_normal();
+
if ($arr['uid']) $uid= $arr['uid'];
@@ -4768,13 +4795,19 @@ function items_fetch($arr,$channel = null,$observer_hash = null,$client_mode = C
}
if($arr['star'])
- $sql_options .= " and (item_flags & " . intval(ITEM_STARRED) . ")>0 ";
+ $sql_options .= " and item_starred = 1 ";
if($arr['wall'])
- $sql_options .= " and (item_flags & " . intval(ITEM_WALL) . ")>0 ";
+ $sql_options .= " and item_wall = 1 ";
- $sql_extra = " AND item.parent IN ( SELECT parent FROM item WHERE (item_flags & " . intval(ITEM_THREAD_TOP) . ")>0 $sql_options ) ";
+ if($arr['item_id'])
+ $sql_options .= " and parent = " . intval($arr['item_id']) . " ";
+ if($arr['mid'])
+ $sql_options .= " and parent_mid = '" . dbesc($arr['mid']) . "' ";
+
+ $sql_extra = " AND item.parent IN ( SELECT parent FROM item WHERE item_thread_top = 1 $sql_options $item_normal ) ";
+
if($arr['since_id'])
$sql_extra .= " and item.id > " . $since_id . " ";
@@ -4804,19 +4837,19 @@ function items_fetch($arr,$channel = null,$observer_hash = null,$client_mode = C
return $result;
}
- $sql_extra = " AND item.parent IN ( SELECT DISTINCT parent FROM item WHERE true $sql_options AND (( author_xchan IN ( $contact_str ) OR owner_xchan in ( $contact_str)) or allow_gid like '" . protect_sprintf('%<' . dbesc($r[0]['hash']) . '>%') . "' ) and id = parent and item_restrict = 0 ) ";
+ $sql_extra = " AND item.parent IN ( SELECT DISTINCT parent FROM item WHERE true $sql_options AND (( author_xchan IN ( $contact_str ) OR owner_xchan in ( $contact_str)) or allow_gid like '" . protect_sprintf('%<' . dbesc($r[0]['hash']) . '>%') . "' ) and id = parent $item_normal ) ";
$x = group_rec_byhash($uid,$r[0]['hash']);
$result['headline'] = sprintf( t('Collection: %s'),$x['name']);
}
elseif($arr['cid'] && $uid) {
- $r = q("SELECT abook.*, xchan.* from abook left join xchan on abook_xchan = xchan_hash where abook_id = %d and abook_channel = %d and not ( abook_flags & " . intval(ABOOK_FLAG_BLOCKED) . ")>0 limit 1",
+ $r = q("SELECT abook.*, xchan.* from abook left join xchan on abook_xchan = xchan_hash where abook_id = %d and abook_channel = %d and abook_blocked = 0 limit 1",
intval($arr['cid']),
intval(local_channel())
);
if ($r) {
- $sql_extra = " AND item.parent IN ( SELECT DISTINCT parent FROM item WHERE true $sql_options AND uid = " . intval($arr['uid']) . " AND ( author_xchan = '" . dbesc($r[0]['abook_xchan']) . "' or owner_xchan = '" . dbesc($r[0]['abook_xchan']) . "' ) and item_restrict = 0 ) ";
+ $sql_extra = " AND item.parent IN ( SELECT DISTINCT parent FROM item WHERE true $sql_options AND uid = " . intval($arr['uid']) . " AND ( author_xchan = '" . dbesc($r[0]['abook_xchan']) . "' or owner_xchan = '" . dbesc($r[0]['abook_xchan']) . "' ) $item_normal ) ";
$result['headline'] = sprintf( t('Connection: %s'),$r[0]['xchan_name']);
} else {
$result['message'] = t('Connection not found.');
@@ -4837,24 +4870,24 @@ function items_fetch($arr,$channel = null,$observer_hash = null,$client_mode = C
}
if($arr['search']) {
- if(strpos($arr['search'],'#') === 0)
- $sql_extra .= term_query('item',substr($arr['search'],1),TERM_HASHTAG);
- else
- $sql_extra .= sprintf(" AND item.body like '%s' ",
- dbesc(protect_sprintf('%' . $arr['search'] . '%'))
- );
- }
- if (strlen($arr['file'])) {
- $sql_extra .= term_query('item',$arr['files'],TERM_FILE);
- }
+ if(strpos($arr['search'],'#') === 0)
+ $sql_extra .= term_query('item',substr($arr['search'],1),TERM_HASHTAG);
+ else
+ $sql_extra .= sprintf(" AND item.body like '%s' ",
+ dbesc(protect_sprintf('%' . $arr['search'] . '%'))
+ );
+ }
- if ($arr['conv'] && $channel) {
- $sql_extra .= sprintf(" AND parent IN (SELECT distinct parent from item where ( author_xchan like '%s' or ( item_flags & %d )>0)) ",
- dbesc(protect_sprintf($uidhash)),
- intval(ITEM_MENTIONSME)
- );
- }
+ if(strlen($arr['file'])) {
+ $sql_extra .= term_query('item',$arr['files'],TERM_FILE);
+ }
+
+ if($arr['conv'] && $channel) {
+ $sql_extra .= sprintf(" AND parent IN (SELECT distinct parent from item where ( author_xchan like '%s' or item_mentionsme = 1 )) ",
+ dbesc(protect_sprintf($uidhash))
+ );
+ }
if (($client_mode & CLIENT_MODE_UPDATE) && (! ($client_mode & CLIENT_MODE_LOAD))) {
// only setup pagination on initial page view
@@ -4889,19 +4922,23 @@ function items_fetch($arr,$channel = null,$observer_hash = null,$client_mode = C
}
}
- $simple_update = (($client_mode & CLIENT_MODE_UPDATE) ? " and ( item.item_unseen = 1 ) " : '');
- if ($client_mode & CLIENT_MODE_LOAD)
- $simple_update = '';
+ $simple_update = (($client_mode & CLIENT_MODE_UPDATE) ? " and item.item_unseen = 1 " : '');
+ if($client_mode & CLIENT_MODE_LOAD)
+ $simple_update = '';
//$start = dba_timer();
require_once('include/security.php');
$sql_extra .= item_permissions_sql($channel['channel_id'],$observer_hash);
- if ($arr['pages'])
- $item_restrict = " AND (item_restrict & " . ITEM_WEBPAGE . ") ";
+
+ if($arr['pages'])
+ $item_restrict = " AND item_type = " . ITEM_TYPE_WEBPAGE . " ";
else
- $item_restrict = " AND item_restrict = 0 ";
+ $item_restrict = " AND item_type = 0 ";
+
+ if($arr['item_type'] === '*')
+ $item_restrict = '';
if ($arr['nouveau'] && ($client_mode & CLIENT_MODE_LOAD) && $channel) {
// "New Item View" - show all items unthreaded in reverse created date order
@@ -4935,10 +4972,9 @@ function items_fetch($arr,$channel = null,$observer_hash = null,$client_mode = C
left join abook on item.author_xchan = abook.abook_xchan
WHERE $item_uids $item_restrict
AND item.parent = item.id
- and ((abook.abook_flags & %d) = 0 or abook.abook_flags is null)
+ and (abook.abook_blocked = 0 or abook.abook_flags is null)
$sql_extra3 $sql_extra $sql_nets
- ORDER BY item.$ordering DESC $pager_sql ",
- intval(ABOOK_FLAG_BLOCKED)
+ ORDER BY item.$ordering DESC $pager_sql "
);
}
@@ -4947,9 +4983,8 @@ function items_fetch($arr,$channel = null,$observer_hash = null,$client_mode = C
$r = q("SELECT item.parent AS item_id FROM item
left join abook on item.author_xchan = abook.abook_xchan
WHERE $item_uids $item_restrict $simple_update
- and ((abook.abook_flags & %d) = 0 or abook.abook_flags is null)
- $sql_extra3 $sql_extra $sql_nets ",
- intval(ABOOK_FLAG_BLOCKED)
+ and (abook.abook_blocked = 0 or abook.abook_flags is null)
+ $sql_extra3 $sql_extra $sql_nets "
);
}
@@ -5005,12 +5040,14 @@ function update_remote_id($channel,$post_id,$webpage,$pagetitle,$namespace,$remo
if(! $post_id)
return;
- if($webpage & ITEM_WEBPAGE)
+ if($webpage == ITEM_TYPE_WEBPAGE)
$page_type = 'WEBPAGE';
- elseif($webpage & ITEM_BUILDBLOCK)
+ elseif($webpage == ITEM_TYPE_BLOCK)
$page_type = 'BUILDBLOCK';
- elseif($webpage & ITEM_PDL)
+ elseif($webpage == ITEM_TYPE_PDL)
$page_type = 'PDL';
+ elseif($webpage == ITEM_TYPE_DOC)
+ $page_type = 'docfile';
elseif($namespace && $remote_id) {
$page_type = $namespace;
$pagetitle = $remote_id;
diff --git a/include/js_strings.php b/include/js_strings.php
index cae8da5de..a21461a52 100644
--- a/include/js_strings.php
+++ b/include/js_strings.php
@@ -39,7 +39,50 @@ function js_strings() {
'$t14' => t('about a year'),
'$t15' => t('%d years'),
'$t16' => t(' '), // wordSeparator
- '$t17' => ((t('timeago.numbers') != 'timeago.numbers') ? t('timeago.numbers') : '[]')
+ '$t17' => ((t('timeago.numbers') != 'timeago.numbers') ? t('timeago.numbers') : '[]'),
+ '$January' => t('January'),
+ '$February' => t('February'),
+ '$March' => t('March'),
+ '$April' => t('April'),
+ '$May' => t('May','long'),
+ '$June' => t('June'),
+ '$July' => t('July'),
+ '$August' => t('August'),
+ '$September' => t('September'),
+ '$October' => t('October'),
+ '$November' => t('November'),
+ '$December' => t('December'),
+ '$Jan' => t('Jan'),
+ '$Feb' => t('Feb'),
+ '$Mar' => t('Mar'),
+ '$Apr' => t('Apr'),
+ '$MayShort' => t('May','short'),
+ '$Jun' => t('Jun'),
+ '$Jul' => t('Jul'),
+ '$Aug' => t('Aug'),
+ '$Sep' => t('Sep'),
+ '$Oct' => t('Oct'),
+ '$Nov' => t('Nov'),
+ '$Dec' => t('Dec'),
+ '$Sunday' => t('Sunday'),
+ '$Monday' => t('Monday'),
+ '$Tuesday' => t('Tuesday'),
+ '$Wednesday' => t('Wednesday'),
+ '$Thursday' => t('Thursday'),
+ '$Friday' => t('Friday'),
+ '$Saturday' => t('Saturday'),
+ '$Sun' => t('Sun'),
+ '$Mon' => t('Mon'),
+ '$Tue' => t('Tue'),
+ '$Wed' => t('Wed'),
+ '$Thu' => t('Thu'),
+ '$Fri' => t('Fri'),
+ '$Sat' => t('Sat'),
+ '$today' => t('today','calendar'),
+ '$month' => t('month','calendar'),
+ '$week' => t('week','calendar'),
+ '$day' => t('day','calendar'),
+ '$allday' => t('All day','calendar')
));
}
diff --git a/include/language.php b/include/language.php
index 7dbe3dd02..59979aa85 100644
--- a/include/language.php
+++ b/include/language.php
@@ -120,7 +120,11 @@ function load_translation_table($lang, $install = false) {
global $a;
$a->strings = array();
- if(file_exists("view/$lang/strings.php")) {
+
+ if(file_exists("view/$lang/hstrings.php")) {
+ include("view/$lang/hstrings.php");
+ }
+ elseif(file_exists("view/$lang/strings.php")) {
include("view/$lang/strings.php");
}
@@ -129,7 +133,10 @@ function load_translation_table($lang, $install = false) {
if ($plugins !== false) {
foreach($plugins as $p) {
$name = $p['name'];
- if(file_exists("addon/$name/lang/$lang/strings.php")) {
+ if(file_exists("addon/$name/lang/$lang/hstrings.php")) {
+ include("addon/$name/lang/$lang/hstrings.php");
+ }
+ elseif(file_exists("addon/$name/lang/$lang/strings.php")) {
include("addon/$name/lang/$lang/strings.php");
}
}
@@ -139,7 +146,10 @@ function load_translation_table($lang, $install = false) {
// Allow individual strings to be over-ridden on this site
// Either for the default language or for all languages
- if(file_exists("view/local-$lang/strings.php")) {
+ if(file_exists("view/local-$lang/hstrings.php")) {
+ include("view/local-$lang/hstrings.php");
+ }
+ elseif(file_exists("view/local-$lang/strings.php")) {
include("view/local-$lang/strings.php");
}
}
diff --git a/include/menu.php b/include/menu.php
index fc8aa1386..075372515 100644
--- a/include/menu.php
+++ b/include/menu.php
@@ -3,9 +3,10 @@
require_once('include/security.php');
require_once('include/bbcode.php');
+
function menu_fetch($name,$uid,$observer_xchan) {
- $sql_options = permissions_sql($uid);
+ $sql_options = permissions_sql($uid,$observer_xchan);
$r = q("select * from menu where menu_channel_id = %d and menu_name = '%s' limit 1",
intval($uid),
@@ -237,7 +238,6 @@ function menu_edit($arr) {
return false;
}
-
$r = q("select * from menu where menu_id = %d and menu_channel_id = %d limit 1",
intval($menu_id),
intval($menu_channel_id)
@@ -299,19 +299,18 @@ function menu_add_item($menu_id, $uid, $arr) {
$channel = get_app()->get_channel();
}
- $str_group_allow = perms2str($arr['group_allow']);
- $str_contact_allow = perms2str($arr['contact_allow']);
- $str_group_deny = perms2str($arr['group_deny']);
- $str_contact_deny = perms2str($arr['contact_deny']);
+ $acl = new AccessList($channel);
+ $acl->set_from_array($arr);
+ $p = $acl->get();
$r = q("insert into menu_item ( mitem_link, mitem_desc, mitem_flags, allow_cid, allow_gid, deny_cid, deny_gid, mitem_channel_id, mitem_menu_id, mitem_order ) values ( '%s', '%s', %d, '%s', '%s', '%s', '%s', %d, %d, %d ) ",
dbesc($mitem_link),
dbesc($mitem_desc),
intval($mitem_flags),
- dbesc($str_contact_allow),
- dbesc($str_group_allow),
- dbesc($str_contact_deny),
- dbesc($str_group_deny),
+ dbesc($p['allow_cid']),
+ dbesc($p['allow_gid']),
+ dbesc($p['deny_cid']),
+ dbesc($p['deny_gid']),
intval($uid),
intval($menu_id),
intval($mitem_order)
@@ -341,19 +340,19 @@ function menu_edit_item($menu_id, $uid, $arr) {
$channel = get_app()->get_channel();
}
- $str_group_allow = perms2str($arr['group_allow']);
- $str_contact_allow = perms2str($arr['contact_allow']);
- $str_group_deny = perms2str($arr['group_deny']);
- $str_contact_deny = perms2str($arr['contact_deny']);
+ $acl = new AccessList($channel);
+ $acl->set_from_array($arr);
+ $p = $acl->get();
+
$r = q("update menu_item set mitem_link = '%s', mitem_desc = '%s', mitem_flags = %d, allow_cid = '%s', allow_gid = '%s', deny_cid = '%s', deny_gid = '%s', mitem_order = %d where mitem_channel_id = %d and mitem_menu_id = %d and mitem_id = %d",
dbesc($mitem_link),
dbesc($mitem_desc),
intval($mitem_flags),
- dbesc($str_contact_allow),
- dbesc($str_group_allow),
- dbesc($str_contact_deny),
- dbesc($str_group_deny),
+ dbesc($p['allow_cid']),
+ dbesc($p['allow_gid']),
+ dbesc($p['deny_cid']),
+ dbesc($p['deny_gid']),
intval($mitem_order),
intval($uid),
intval($menu_id),
@@ -391,7 +390,7 @@ function menu_del_item($menu_id,$uid,$item_id) {
function menu_sync_packet($uid,$observer_hash,$menu_id,$delete = false) {
$r = menu_fetch_id($menu_id,$uid);
if($r) {
- $m = menu_fetch($r['menu_name'],$uid,$observer_hash);
+ $m = menu_fetch($r['menu_name'],$uid,$observer_hash);
if($m) {
if($delete)
$m['menu_delete'] = 1;
diff --git a/include/message.php b/include/message.php
index bfc92cd6d..820d814b6 100644
--- a/include/message.php
+++ b/include/message.php
@@ -28,8 +28,6 @@ function send_message($uid = 0, $recipient='', $body='', $subject='', $replyto='
// $expires = datetime_convert(date_default_timezone_get(),'UTC',$expires);
-
-
if($uid) {
$r = q("select * from channel where channel_id = %d limit 1",
intval($uid)
@@ -49,17 +47,20 @@ function send_message($uid = 0, $recipient='', $body='', $subject='', $replyto='
// look for any existing conversation structure
+ $conv_guid = '';
+
if(strlen($replyto)) {
- $r = q("select convid from mail where channel_id = %d and ( mid = '%s' or parent_mid = '%s' ) limit 1",
+ $r = q("select conv_guid from mail where channel_id = %d and ( mid = '%s' or parent_mid = '%s' ) limit 1",
intval(local_channel()),
dbesc($replyto),
dbesc($replyto)
);
- if($r)
- $convid = $r[0]['convid'];
+ if($r) {
+ $conv_guid = $r[0]['conv_guid'];
+ }
}
- if(! $convid) {
+ if(! $conv_guid) {
// create a new conversation
@@ -75,13 +76,16 @@ function send_message($uid = 0, $recipient='', $body='', $subject='', $replyto='
$handles = $recip_handle . ';' . $sender_handle;
+ if($subject)
+ $nsubject = str_rot47(base64url_encode($subject));
+
$r = q("insert into conv (uid,guid,creator,created,updated,subject,recips) values(%d, '%s', '%s', '%s', '%s', '%s', '%s') ",
intval(local_channel()),
dbesc($conv_guid),
dbesc($sender_handle),
dbesc(datetime_convert()),
dbesc(datetime_convert()),
- dbesc($subject),
+ dbesc($nsubject),
dbesc($handles)
);
@@ -89,16 +93,28 @@ function send_message($uid = 0, $recipient='', $body='', $subject='', $replyto='
dbesc($conv_guid),
intval(local_channel())
);
- if($r)
- $convid = $r[0]['id'];
+ if($r) {
+ $retconv = $r[0];
+ $retconv['subject'] = base64url_decode(str_rot47($retconv['subject']));
+ }
}
- if(! $convid) {
+ if(! $retconv) {
+ $r = q("select * from conv where guid = '%s' and uid = %d limit 1",
+ dbesc($conv_guid),
+ intval(local_channel())
+ );
+ if($r) {
+ $retconv = $r[0];
+ $retconv['subject'] = base64url_decode(str_rot47($retconv['subject']));
+ }
+ }
+
+ if(! $retconv) {
$ret['message'] = 'conversation not found';
return $ret;
}
-
// generate a unique message_id
do {
@@ -163,19 +179,18 @@ function send_message($uid = 0, $recipient='', $body='', $subject='', $replyto='
$jattach = (($attachments) ? json_encode($attachments) : '');
- $key = get_config('system','pubkey');
if($subject)
- $subject = json_encode(crypto_encapsulate($subject,$key));
+ $subject = str_rot47(base64url_encode($subject));
if($body)
- $body = json_encode(crypto_encapsulate($body,$key));
+ $body = str_rot47(base64url_encode($body));
- $r = q("INSERT INTO mail ( account_id, convid, mail_flags, channel_id, from_xchan, to_xchan, title, body, attach, mid, parent_mid, created, expires )
- VALUES ( %d, %d, %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s' )",
+ $r = q("INSERT INTO mail ( account_id, conv_guid, mail_obscured, channel_id, from_xchan, to_xchan, title, body, attach, mid, parent_mid, created, expires )
+ VALUES ( %d, '%s', %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s' )",
intval($channel['channel_account_id']),
- intval($convid),
- intval(MAIL_OBSCURED),
+ dbesc($conv_guid),
+ intval(1),
intval($channel['channel_id']),
dbesc($channel['channel_hash']),
dbesc($recipient),
@@ -194,8 +209,11 @@ function send_message($uid = 0, $recipient='', $body='', $subject='', $replyto='
dbesc($mid),
intval($channel['channel_id'])
);
- if($r)
+ if($r) {
$post_id = $r[0]['id'];
+ $retmail = $r[0];
+ xchan_mail_query($retmail);
+ }
else {
$ret['message'] = t('Stored post could not be verified.');
return $ret;
@@ -213,6 +231,12 @@ function send_message($uid = 0, $recipient='', $body='', $subject='', $replyto='
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),
+ intval($channel['channel_id']),
+ dbesc('<' . $channel['channel_hash'] . '>')
+ );
}
}
@@ -233,6 +257,9 @@ function send_message($uid = 0, $recipient='', $body='', $subject='', $replyto='
$ret['success'] = true;
$ret['message_item'] = intval($post_id);
+ $ret['conv'] = $retconv;
+ $ret['mail'] = $retmail;
+
return $ret;
}
@@ -242,6 +269,8 @@ function private_messages_list($uid, $mailbox = '', $start = 0, $numitems = 0) {
$where = '';
$limit = '';
+ $t0 = dba_timer();
+
if($numitems)
$limit = " LIMIT " . intval($numitems) . " OFFSET " . intval($start);
@@ -251,18 +280,30 @@ function private_messages_list($uid, $mailbox = '', $start = 0, $numitems = 0) {
);
if(! $x)
return array();
- if($mailbox === 'inbox')
- $where = " and sender_xchan != '" . dbesc($x[0]['channel_hash']) . "' ";
- elseif($mailbox === 'outbox')
- $where = " and sender_xchan = '" . dbesc($x[0]['channel_hash']) . "' ";
+
+ $channel_hash = dbesc($x[0]['channel_hash']);
+ $local_channel = intval(local_channel());
+
+ switch($mailbox) {
+
+ case 'inbox':
+ $sql = "SELECT * FROM mail WHERE channel_id = $local_channel AND from_xchan != '$channel_hash' ORDER BY created DESC $limit";
+ break;
+
+ case 'outbox':
+ $sql = "SELECT * FROM mail WHERE channel_id = $local_channel AND from_xchan = '$channel_hash' ORDER BY created DESC $limit";
+ break;
+
+ case 'combined':
+ $sql = "SELECT * FROM ( SELECT * FROM mail WHERE channel_id = $local_channel ORDER BY created DESC $limit ) AS temp_table GROUP BY parent_mid ORDER BY created DESC";
+ break;
+
+ }
+
}
- // For different orderings, consider applying usort on the results. We thought of doing that
- // inside this function or having some preset sorts, but don't wish to limit app developers.
-
- $r = q("SELECT * from mail WHERE channel_id = %d $where order by created desc $limit",
- intval(local_channel())
- );
+ $r = q($sql);
+
if(! $r) {
return array();
}
@@ -282,13 +323,12 @@ function private_messages_list($uid, $mailbox = '', $start = 0, $numitems = 0) {
foreach($r as $k => $rr) {
$r[$k]['from'] = find_xchan_in_array($rr['from_xchan'],$c);
$r[$k]['to'] = find_xchan_in_array($rr['to_xchan'],$c);
- $r[$k]['seen'] = (($rr['mail_flags'] & MAIL_SEEN) ? 1 : 0);
- if($r[$k]['mail_flags'] & MAIL_OBSCURED) {
- $key = get_config('system','prvkey');
+ $r[$k]['seen'] = intval($rr['mail_seen']);
+ if(intval($r[$k]['mail_obscured'])) {
if($r[$k]['title'])
- $r[$k]['title'] = crypto_unencapsulate(json_decode_plus($r[$k]['title']),$key);
+ $r[$k]['title'] = base64url_decode(str_rot47($r[$k]['title']));
if($r[$k]['body'])
- $r[$k]['body'] = crypto_unencapsulate(json_decode_plus($r[$k]['body']),$key);
+ $r[$k]['body'] = base64url_decode(str_rot47($r[$k]['body']));
}
}
@@ -322,19 +362,17 @@ function private_messages_fetch_message($channel_id, $messageitem_id, $updatesee
foreach($messages as $k => $message) {
$messages[$k]['from'] = find_xchan_in_array($message['from_xchan'],$c);
$messages[$k]['to'] = find_xchan_in_array($message['to_xchan'],$c);
- if($messages[$k]['mail_flags'] & MAIL_OBSCURED) {
- $key = get_config('system','prvkey');
+ if(intval($messages[$k]['mail_obscured'])) {
if($messages[$k]['title'])
- $messages[$k]['title'] = crypto_unencapsulate(json_decode_plus($messages[$k]['title']),$key);
+ $messages[$k]['title'] = base64url_decode(str_rot47($messages[$k]['title']));
if($messages[$k]['body'])
- $messages[$k]['body'] = crypto_unencapsulate(json_decode_plus($messages[$k]['body']),$key);
+ $messages[$k]['body'] = base64url_decode(str_rot47($messages[$k]['body']));
}
}
+
if($updateseen) {
- $r = q("UPDATE `mail` SET mail_flags = (mail_flags | %d) where not (mail_flags & %d)>0 and id = %d AND channel_id = %d",
- intval(MAIL_SEEN),
- intval(MAIL_SEEN),
+ $r = q("UPDATE `mail` SET mail_seen = 1 where mail_seen = 0 and id = %d AND channel_id = %d",
dbesc($messageitem_id),
intval($channel_id)
);
@@ -347,30 +385,67 @@ function private_messages_fetch_message($channel_id, $messageitem_id, $updatesee
function private_messages_drop($channel_id, $messageitem_id, $drop_conversation = false) {
+
+ $x = q("select * from mail where id = %d and channel_id = %d limit 1",
+ intval($messageitem_id),
+ intval($channel_id)
+ );
+ if(! $x)
+ return false;
+
+ $conversation = null;
+
+ if($x[0]['conv_guid']) {
+ $y = q("select * from conv where guid = '%s' and uid = %d limit 1",
+ dbesc($x[0]['conv_guid']),
+ intval($channel_id)
+ );
+ if($y) {
+ $conversation = $y[0];
+ $conversation['subject'] = base64url_decode(str_rot47($conversation['subject']));
+ }
+ }
+
if($drop_conversation) {
- // find the parent_id
- $p = q("SELECT parent_mid FROM mail WHERE id = %d AND channel_id = %d LIMIT 1",
- intval($messageitem_id),
+ $m = array();
+ $m['conv'] = array($conversation);
+ $m['conv'][0]['deleted'] = 1;
+
+ $z = q("select * from mail where parent_mid = '%s' and channel_id = %d",
+ dbesc($x[0]['parent_mid']),
intval($channel_id)
);
- if($p) {
- $r = q("DELETE FROM mail WHERE parent_mid = '%s' AND channel_id = %d ",
- dbesc($p[0]['parent_mid']),
+ if($z) {
+ q("delete from conv where guid = '%s' and uid = %d limit 1",
+ dbesc($x[0]['conv_guid']),
+ intval($channel_id)
+ );
+ $m['mail'] = array();
+ foreach($z as $zz) {
+ xchan_mail_query($zz);
+ $zz['mail_deleted'] = 1;
+ $m['mail'][] = encode_mail($zz,true);
+ }
+ q("DELETE FROM mail WHERE parent_mid = '%s' AND channel_id = %d ",
+ dbesc($x[0]['parent_mid']),
intval($channel_id)
);
- if($r)
- return true;
}
+ build_sync_packet($channel_id,$m);
+ return true;
}
else {
+ xchan_mail_query($x[0]);
+ $x[0]['mail_deleted'] = true;
$r = q("DELETE FROM mail WHERE id = %d AND channel_id = %d",
intval($messageitem_id),
intval($channel_id)
);
- if($r)
- return true;
+ build_sync_packet($channel_id,array('mail' => array(encode_mail($x,true))));
+ return true;
}
return false;
+
}
@@ -410,20 +485,18 @@ function private_messages_fetch_conversation($channel_id, $messageitem_id, $upda
foreach($messages as $k => $message) {
$messages[$k]['from'] = find_xchan_in_array($message['from_xchan'],$c);
$messages[$k]['to'] = find_xchan_in_array($message['to_xchan'],$c);
- if($messages[$k]['mail_flags'] & MAIL_OBSCURED) {
- $key = get_config('system','prvkey');
+ if(intval($messages[$k]['mail_obscured'])) {
if($messages[$k]['title'])
- $messages[$k]['title'] = crypto_unencapsulate(json_decode_plus($messages[$k]['title']),$key);
+ $messages[$k]['title'] = base64url_decode(str_rot47($messages[$k]['title']));
if($messages[$k]['body'])
- $messages[$k]['body'] = crypto_unencapsulate(json_decode_plus($messages[$k]['body']),$key);
+ $messages[$k]['body'] = base64url_decode(str_rot47($messages[$k]['body']));
}
}
+
if($updateseen) {
- $r = q("UPDATE `mail` SET mail_flags = (mail_flags | %d) where not (mail_flags & %d)>0 and parent_mid = '%s' AND channel_id = %d",
- intval(MAIL_SEEN),
- intval(MAIL_SEEN),
+ $r = q("UPDATE `mail` SET mail_seen = 1 where mail_seen = 0 and parent_mid = '%s' AND channel_id = %d",
dbesc($r[0]['parent_mid']),
intval($channel_id)
);
@@ -431,4 +504,4 @@ function private_messages_fetch_conversation($channel_id, $messageitem_id, $upda
return $messages;
-} \ No newline at end of file
+}
diff --git a/include/nav.php b/include/nav.php
index 77287c021..1630c4731 100644
--- a/include/nav.php
+++ b/include/nav.php
@@ -30,14 +30,9 @@ EOT;
intval($channel['channel_id'])
);
- $chans = q("select channel_name, channel_id from channel where channel_account_id = %d and not ( channel_pageflags & %d )>0 order by channel_name ",
- intval(get_account_id()),
- intval(PAGE_REMOVED)
+ $chans = q("select channel_name, channel_id from channel where channel_account_id = %d and channel_removed = 0 order by channel_name ",
+ intval(get_account_id())
);
-
-
-
-
}
elseif(remote_channel())
$observer = $a->get_observer();
@@ -99,9 +94,8 @@ EOT;
require_once('include/chat.php');
$has_chats = chatroom_list_count(local_channel());
- if($has_chats) {
- $nav['usermenu'][] = Array('chat/' . $channel['channel_address'],t('Chat'),"",t('Your chatrooms'),'chat_nav_btn');
- }
+ $nav['usermenu'][] = Array('chat/' . $channel['channel_address'] . (($has_chats) ? '' : '/new'), t('Chat'),"",t('Your chatrooms'),'chat_nav_btn');
+
require_once('include/menu.php');
$has_bookmarks = menu_list_count(local_channel(),'',MENU_BOOKMARK) + menu_list_count(local_channel(),'',MENU_SYSTEM|MENU_BOOKMARK);
@@ -162,7 +156,7 @@ EOT;
$nav['apps'] = array('apps', t('Apps'), "", t('Applications, utilities, links, games'),'apps_nav_btn');
- $nav['search'] = array('search', t('Search'), "", t('Search site content'));
+ $nav['search'] = array('search', t('Search'), "", t('Search site @name, #tag, ?docs, content'));
$nav['directory'] = array('directory', t('Directory'), "", t('Channel Directory'),'directory_nav_btn');
@@ -177,8 +171,8 @@ EOT;
if(local_channel()) {
- $nav['network'] = array('network', t('Matrix'), "", t('Your matrix'),'network_nav_btn');
- $nav['network']['mark'] = array('', t('Mark all matrix notifications seen'), '','');
+ $nav['network'] = array('network', t('Grid'), "", t('Your grid'),'network_nav_btn');
+ $nav['network']['mark'] = array('', t('Mark all grid notifications seen'), '','');
$nav['home'] = array('channel/' . $channel['channel_address'], t('Channel Home'), "", t('Channel home'),'home_nav_btn');
$nav['home']['mark'] = array('', t('Mark all channel notifications seen'), '','');
@@ -191,11 +185,11 @@ EOT;
$nav['notifications']['all']=array('notifications/system', t('See all notifications'), "", "");
$nav['notifications']['mark'] = array('', t('Mark all system notifications seen'), '','');
- $nav['messages'] = array('message', t('Mail'), "", t('Private mail'),'mail_nav_btn');
- $nav['messages']['all']=array('message', t('See all private messages'), "", "");
+ $nav['messages'] = array('mail/combined', t('Mail'), "", t('Private mail'),'mail_nav_btn');
+ $nav['messages']['all']=array('mail/combined', t('See all private messages'), "", "");
$nav['messages']['mark'] = array('', t('Mark all private messages seen'), '','');
- $nav['messages']['inbox'] = array('message', t('Inbox'), "", t('Inbox'));
- $nav['messages']['outbox']= array('message/sent', t('Outbox'), "", t('Outbox'));
+ $nav['messages']['inbox'] = array('mail/inbox', t('Inbox'), "", t('Inbox'));
+ $nav['messages']['outbox']= array('mail/outbox', t('Outbox'), "", t('Outbox'));
$nav['messages']['new'] = array('mail/new', t('New Message'), "", t('New Message'));
@@ -249,7 +243,7 @@ $powered_by = '';
'$localuser' => local_channel(),
'$sel' => $a->nav_sel,
'$powered_by' => $powered_by,
- '$help' => t('@name, #tag, content'),
+ '$help' => t('@name, #tag, ?doc, content'),
'$pleasewait' => t('Please wait...')
));
diff --git a/include/network.php b/include/network.php
index d9546a074..c67c019ef 100644
--- a/include/network.php
+++ b/include/network.php
@@ -586,7 +586,7 @@ function scale_external_images($s, $include_link = true, $scale_replace = false)
if(substr($mtch[1],0,1) == '=') {
$owidth = intval(substr($mtch[2],1));
- if(intval($owidth) > 0 && intval($owidth) < 640)
+ if(intval($owidth) > 0 && intval($owidth) < 1024)
continue;
}
@@ -624,9 +624,9 @@ function scale_external_images($s, $include_link = true, $scale_replace = false)
$orig_width = $ph->getWidth();
$orig_height = $ph->getHeight();
- if($orig_width > 640 || $orig_height > 640) {
+ if($orig_width > 1024 || $orig_height > 1024) {
$tag = (($match[1] == 'z') ? 'zmg' : 'img');
- $ph->scaleImage(640);
+ $ph->scaleImage(1024);
$new_width = $ph->getWidth();
$new_height = $ph->getHeight();
logger('scale_external_images: ' . $orig_width . '->' . $new_width . 'w ' . $orig_height . '->' . $new_height . 'h' . ' match: ' . $mtch[0], LOGGER_DEBUG);
@@ -1035,7 +1035,7 @@ function discover_by_url($url,$arr = null) {
dbesc(datetime_convert())
);
- $photos = import_profile_photo($photo,$guid);
+ $photos = import_xchan_photo($photo,$guid);
$r = q("update xchan set xchan_photo_date = '%s', xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s' where xchan_hash = '%s'",
dbesc(datetime_convert()),
dbesc($photos[0]),
@@ -1053,21 +1053,30 @@ function discover_by_webbie($webbie) {
$webbie = strtolower($webbie);
- $x = webfinger_rfc7033($webbie);
+ $x = webfinger_rfc7033($webbie,true);
if($x && array_key_exists('links',$x) && $x['links']) {
foreach($x['links'] as $link) {
if(array_key_exists('rel',$link) && $link['rel'] == 'http://purl.org/zot/protocol') {
logger('discover_by_webbie: zot found for ' . $webbie, LOGGER_DEBUG);
- $z = z_fetch_url($link['href']);
- if($z['success']) {
- $j = json_decode($z['body'],true);
- $i = import_xchan($j);
- return true;
+ if(array_key_exists('zot',$x) && $x['zot']['success'])
+ $i = import_xchan($x['zot']);
+ else {
+ $z = z_fetch_url($link['href']);
+ if($z['success']) {
+ $j = json_decode($z['body'],true);
+ $i = import_xchan($j);
+ return true;
+ }
}
}
}
}
+ $arr = array('address' => $webbie, 'success' => false);
+ call_hooks('discover_by_webbie', $arr);
+ if($arr['success'])
+ return true;
+
$result = array();
$network = null;
$diaspora = false;
@@ -1132,12 +1141,32 @@ function discover_by_webbie($webbie) {
if($hcard) {
$vcard = scrape_vcard($hcard);
$vcard['nick'] = substr($webbie,0,strpos($webbie,'@'));
+ if(! $vcard['fn'])
+ $vcard['fn'] = $webbie;
}
$r = q("select * from xchan where xchan_hash = '%s' limit 1",
- dbesc($webbie)
+ dbesc($addr)
);
- if(! $r) {
+
+ /**
+ *
+ * Diaspora communications are notoriously unreliable and receiving profile update messages (indeed any messages)
+ * are pretty much random luck. We'll check the timestamp of the xchan_name_date at a higher level and refresh
+ * this record once a month; because if you miss a profile update message and they update their profile photo or name
+ * you're otherwise stuck with stale info until they change their profile again - which could be years from now.
+ *
+ */
+
+ if($r) {
+ $r = q("update xchan set xchan_name = '%s', xchan_network = '%s', xchan_name_date = '%s' where xchan_hash = '%s' limit 1",
+ dbesc($vcard['fn']),
+ dbesc($network),
+ dbesc(datetime_convert()),
+ dbesc($addr)
+ );
+ }
+ else {
$r = q("insert into xchan ( xchan_hash, xchan_guid, xchan_pubkey, xchan_addr, xchan_url, xchan_name, xchan_network, xchan_instance_url, xchan_name_date ) values ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s') ",
dbesc($addr),
@@ -1158,7 +1187,7 @@ function discover_by_webbie($webbie) {
if(! $r) {
- $r = q("insert into hubloc ( hubloc_guid, hubloc_hash, hubloc_addr, hubloc_network, hubloc_url, hubloc_host, hubloc_callback, hubloc_updated, hubloc_flags ) values ('%s','%s','%s','%s','%s','%s','%s','%s', %d)",
+ $r = q("insert into hubloc ( hubloc_guid, hubloc_hash, hubloc_addr, hubloc_network, hubloc_url, hubloc_host, hubloc_callback, hubloc_updated, hubloc_primary ) values ('%s','%s','%s','%s','%s','%s','%s','%s', 1)",
dbesc($guid),
dbesc($addr),
dbesc($addr),
@@ -1166,11 +1195,10 @@ function discover_by_webbie($webbie) {
dbesc(trim($diaspora_base,'/')),
dbesc($hostname),
dbesc($notify),
- dbescdate(datetime_convert()),
- intval(HUBLOC_FLAGS_PRIMARY)
+ dbescdate(datetime_convert())
);
}
- $photos = import_profile_photo($vcard['photo'],$addr);
+ $photos = import_xchan_photo($vcard['photo'],$addr);
$r = q("update xchan set xchan_photo_date = '%s', xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s' where xchan_hash = '%s'",
dbescdate(datetime_convert('UTC','UTC',$arr['photo_updated'])),
dbesc($photos[0]),
@@ -1258,7 +1286,7 @@ LSIeXnd14lQYK/uxW/8cTFjcmddsKxeXysoQxbSa9VdDK+KkpZdgYXYrTTofXs6v+
}
-function webfinger_rfc7033($webbie) {
+function webfinger_rfc7033($webbie,$zot = false) {
if(! strpos($webbie,'@'))
@@ -1268,7 +1296,7 @@ function webfinger_rfc7033($webbie) {
$resource = 'acct:' . $webbie;
- $s = z_fetch_url('https://' . $rhs . '/.well-known/webfinger?resource=' . $resource);
+ $s = z_fetch_url('https://' . $rhs . '/.well-known/webfinger?f=&resource=' . $resource . (($zot) ? '&zot=1' : ''));
if($s['success'])
$j = json_decode($s['body'],true);
@@ -1649,13 +1677,40 @@ function format_and_send_email($sender,$xchan,$item) {
'additionalMailHeader' => '',
));
+}
+
+
+function do_delivery($deliveries) {
+
+ if(! (is_array($deliveries) && count($deliveries)))
+ return;
+ $interval = ((get_config('system','delivery_interval') !== false)
+ ? intval(get_config('system','delivery_interval')) : 2 );
+ $deliveries_per_process = intval(get_config('system','delivery_batch_count'));
+ if($deliveries_per_process <= 0)
+ $deliveries_per_process = 1;
+ $deliver = array();
+ foreach($deliveries as $d) {
+ $deliver[] = $d;
+ if(count($deliver) >= $deliveries_per_process) {
+ proc_run('php','include/deliver.php',$deliver);
+ $deliver = array();
+ if($interval)
+ @time_sleep_until(microtime(true) + (float) $interval);
+ }
+ }
+ // catch any stragglers
+
+ if($deliver)
+ proc_run('php','include/deliver.php',$deliver);
+
}
diff --git a/include/notifier.php b/include/notifier.php
index ecd2ac86f..34a527e15 100644
--- a/include/notifier.php
+++ b/include/notifier.php
@@ -96,14 +96,25 @@ function notifier_run($argv, $argc){
require_once('include/identity.php');
$sys = get_sys_channel();
- if($cmd == 'permission_update') {
+ $deliveries = array();
+
+ $dead_hubs = array();
+
+ $dh = q("select site_url from site where site_dead = 1");
+ if(dh) {
+ foreach($dh as $dead) {
+ $dead_hubs[] = $dead['site_url'];
+ }
+ }
+
+
+ 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 not ( abook_flags & %d ) > 0
+ 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(ABOOK_FLAG_SELF),
intval(HUBLOC_FLAGS_DELETED),
intval(HUBLOC_OFFLINE)
);
@@ -114,11 +125,17 @@ function notifier_run($argv, $argc){
intval($r[0]['abook_channel'])
);
if($s) {
- if($r[0]['hubloc_network'] === 'diaspora' || $r[0]['hubloc_network'] === 'friendica-over-diaspora') {
- require_once('include/diaspora.php');
- diaspora_share($s[0],$r[0]);
- }
- else {
+ $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",
@@ -128,36 +145,40 @@ function notifier_run($argv, $argc){
);
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) {
- $result = zot_zot($hh['hubloc_callback'],$data);
-
- // if immediate delivery failed, stick it in the queue to try again later.
-
- if(! $result['success']) {
- $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('')
- );
- }
+ $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;
@@ -228,11 +249,9 @@ function notifier_run($argv, $argc){
$normal_mode = false;
$expire = true;
- $items = q("SELECT * FROM item WHERE uid = %d AND ( item_flags & %d )>0
- AND ( item_restrict & %d )>0 AND `changed` > %s - INTERVAL %s",
+ $items = q("SELECT * FROM item WHERE uid = %d AND item_wall = 1
+ AND item_deleted = 1 AND `changed` > %s - INTERVAL %s",
intval($item_id),
- intval(ITEM_WALL),
- intval(ITEM_DELETED),
db_utcnow(), db_quoteinterval('10 MINUTE')
);
$uid = $item_id;
@@ -338,19 +357,22 @@ function notifier_run($argv, $argc){
$target_item = $r[0];
$deleted_item = false;
- if($target_item['item_restrict'] & ITEM_DELETED) {
+ if(intval($target_item['item_deleted'])) {
logger('notifier: target item ITEM_DELETED', LOGGER_DEBUG);
$deleted_item = true;
}
- if(strpos($target_item['postopts'],'nodeliver') !== false) {
- logger('notifier: target item is undeliverable', LOGGER_DEBUG);
+ if(intval($target_item['item_type']) != ITEM_TYPE_POST) {
+ logger('notifier: target item not forwardable: type ' . $target_item['item_type'], LOGGER_DEBUG);
+ return;
+ }
+ if(intval($target_item['item_unpublished']) || intval($target_item['item_delayed'])) {
+ logger('notifier: target item not published, so not forwardable', LOGGER_DEBUG);
return;
}
- $unforwardable = ITEM_UNPUBLISHED|ITEM_DELAYED_PUBLISH|ITEM_WEBPAGE|ITEM_BUILDBLOCK|ITEM_PDL;
- if($target_item['item_restrict'] & $unforwardable) {
- logger('notifier: target item not forwardable: flags ' . $target_item['item_restrict'], LOGGER_DEBUG);
+ if(strpos($target_item['postopts'],'nodeliver') !== false) {
+ logger('notifier: target item is undeliverable', LOGGER_DEBUG);
return;
}
@@ -407,10 +429,7 @@ function notifier_run($argv, $argc){
// flag on comments for an extended period. So we'll also call comment_local_origin() which looks at
// the hostname in the message_id and provides a second (fallback) opinion.
- $relay_to_owner = (((! $top_level_post) && ($target_item['item_flags'] & ITEM_ORIGIN) && comment_local_origin($target_item))
- ? true
- : false
- );
+ $relay_to_owner = (((! $top_level_post) && (intval($target_item['item_origin'])) && comment_local_origin($target_item)) ? true : false);
@@ -421,11 +440,10 @@ function notifier_run($argv, $argc){
logger('notifier: relay_to_owner: ' . (($relay_to_owner) ? 'true' : 'false'), LOGGER_DATA);
logger('notifier: top_level_post: ' . (($top_level_post) ? 'true' : 'false'), LOGGER_DATA);
- logger('notifier: target_item_flags: ' . $target_item['item_flags'] . ' ' . (($target_item['item_flags'] & ITEM_ORIGIN ) ? 'true' : 'false'), LOGGER_DATA);
// tag_deliver'd post which needs to be sent back to the original author
- if(($cmd === 'uplink') && ($parent_item['item_flags'] & ITEM_UPLINK) && (! $top_level_post)) {
+ if(($cmd === 'uplink') && intval($parent_item['item_uplink']) && (! $top_level_post)) {
logger('notifier: uplink');
$uplink = true;
}
@@ -446,7 +464,7 @@ function notifier_run($argv, $argc){
// if our parent is a tag_delivery recipient, uplink to the original author causing
// a delivery fork.
- if(($parent_item['item_flags'] & ITEM_UPLINK) && (! $top_level_post) && ($cmd !== 'uplink')) {
+ 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);
}
@@ -459,7 +477,7 @@ function notifier_run($argv, $argc){
// don't send deletions onward for other people's stuff
// TODO verify this is needed - copied logic from same place in old code
- if(($target_item['item_restrict'] & ITEM_DELETED) && (!($target_item['item_flags'] & ITEM_WALL))) {
+ if(intval($target_item['item_deleted']) && (! intval($target_item['item_wall']))) {
logger('notifier: ignoring delete notification for non-wall item');
return;
}
@@ -492,20 +510,6 @@ function notifier_run($argv, $argc){
if($details) {
foreach($details as $d) {
- // If the recipient is federated from a traditional network they won't be able to
- // handle nomadic identity. If we're publishing from a site that they aren't
- // directly connected with, ignore them.
-
- // FIXME: make sure we run through a notifier loop on the hub they're connected
- // with if this post comes in from a different hub - so that we will deliver to them.
-
- // On the down side, these channels will stop working if the hub they connected with
- // goes down permanently, as they are (doh) not nomadic.
-
- if(($d['xchan_instance_url']) && ($d['xchan_instance_url'] != z_root()))
- continue;
-
-
$recip_list[] = $d['xchan_addr'] . ' (' . $d['xchan_hash'] . ')';
if($private)
$env_recips[] = array('guid' => $d['xchan_guid'],'guid_sig' => $d['xchan_guid_sig'],'hash' => $d['xchan_hash']);
@@ -532,34 +536,10 @@ function notifier_run($argv, $argc){
// Now we have collected recipients (except for external mentions, FIXME)
// Let's reduce this to a set of hubs.
- logger('notifier: hub choice: ' . intval($relay_to_owner) . ' ' . intval($private) . ' ' . $cmd, LOGGER_DEBUG);
-
- // FIXME: I think we need to remove the private bit or this clause will never execute. Needs more coffee to think it through.
- // We may in fact have to send it to clones in case the one we pick recently died.
-
- if($relay_to_owner && (! $private) && ($cmd !== 'relay')) {
-
- // If sending a followup to the post owner, only send it to one channel clone - to avoid race conditions.
- // In this case we'll pick the most recently contacted hub, as their primary might be down and the most
- // recently contacted has the best chance of being alive.
-
- // For private posts or uplinks we have to do things differently as only the sending clone will have the recipient list.
- // We have to send to all clone channels of the owner to find out who has the definitive list. Posts with
- // item_private set (but no ACL list) will return empty recipients (except for the sender and owner) in
- // collect_recipients() above. The end result is we should get only one delivery per delivery chain if we
- // aren't the owner or author.
-
-
- $r = q("select hubloc_guid, hubloc_url, hubloc_sitekey, hubloc_network, hubloc_flags, hubloc_callback, hubloc_host from hubloc
- where hubloc_hash in (" . implode(',',$recipients) . ") order by hubloc_connected desc limit 1");
- }
- else {
- $r = q("select hubloc_guid, hubloc_url, hubloc_sitekey, hubloc_network, hubloc_flags, hubloc_callback, hubloc_host from hubloc
- where hubloc_hash in (" . implode(',',$recipients) . ") and not (hubloc_flags & %d) > 0 and not (hubloc_status & %d) > 0",
- intval(HUBLOC_FLAGS_DELETED),
- intval(HUBLOC_OFFLINE)
- );
- }
+ $r = q("select * from hubloc where hubloc_hash in (" . implode(',',$recipients) . ")
+ and hubloc_error = 0 and hubloc_deleted = 0"
+ );
+
if(! $r) {
logger('notifier: no hubs');
@@ -569,6 +549,7 @@ function notifier_run($argv, $argc){
$hubs = $r;
+
/**
* Reduce the hubs to those that are unique. For zot hubs, we need to verify uniqueness by the sitekey, since it may have been
* a re-install which has not yet been detected and pruned.
@@ -583,6 +564,11 @@ function notifier_run($argv, $argc){
foreach($hubs as $hub) {
+ if(in_array($hub['hubloc_url'],$dead_hubs)) {
+ logger('skipping dead hub: ' . $hub['hubloc_url'], LOGGER_DEBUG);
+ continue;
+ }
+
if($hub['hubloc_network'] == 'zot') {
if(! in_array($hub['hubloc_sitekey'],$keys)) {
$hublist[] = $hub['hubloc_host'];
@@ -601,30 +587,12 @@ function notifier_run($argv, $argc){
logger('notifier: will notify/deliver to these hubs: ' . print_r($hublist,true), LOGGER_DEBUG);
- $interval = ((get_config('system','delivery_interval') !== false)
- ? intval(get_config('system','delivery_interval')) : 2 );
-
- $deliveries_per_process = intval(get_config('system','delivery_batch_count'));
-
- if($deliveries_per_process <= 0)
- $deliveries_per_process = 1;
-
- $deliver = array();
foreach($dhubs as $hub) {
- if($hub['hubloc_network'] === 'diaspora' || $hub['hubloc_network'] === 'friendica-over-diaspora') {
- if(! get_config('system','diaspora_enabled'))
- continue;
-
- // allow this to be set per message
+ if($hub['hubloc_network'] !== 'zot') {
- if(strpos($target_item['postopts'],'nodspr') !== false)
- continue;
-
- require_once('include/diaspora.php');
-
- diaspora_process_outbound(array(
+ $narr = array(
'channel' => $channel,
'env_recips' => $env_recips,
'recipients' => $recipients,
@@ -644,14 +612,20 @@ function notifier_run($argv, $argc){
'request' => $request,
'normal_mode' => $normal_mode,
'packet_type' => $packet_type,
- 'walltowall' => $walltowall
- ));
+ 'walltowall' => $walltowall,
+ 'queued' => array()
+ );
+
+ call_hooks('notifier_hub',$narr);
+ if($narr['queued']) {
+ foreach($narr['queued'] as $pq)
+ $deliveries[] = $pq;
+ }
continue;
}
-
// default: zot protocol
@@ -700,28 +674,33 @@ function notifier_run($argv, $argc){
dbesc($n),
dbesc(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' ) ",
+ dbesc($target_item['mid']),
+ dbesc($hub['hubloc_host']),
+ dbesc($hub['hubloc_host']),
+ dbesc('queued'),
+ dbesc(datetime_convert()),
+ dbesc($channel['channel_hash']),
+ dbesc($hash)
+ );
+ }
}
- $deliver[] = $hash;
- if(count($deliver) >= $deliveries_per_process) {
- proc_run('php','include/deliver.php',$deliver);
- $deliver = array();
- if($interval)
- @time_sleep_until(microtime(true) + (float) $interval);
- }
+ $deliveries[] = $hash;
}
-
- // catch any stragglers
-
- if(count($deliver)) {
- proc_run('php','include/deliver.php',$deliver);
+
+ if($normal_mode) {
+ $x = q("select * from hook where hook = 'notifier_normal'");
+ if($x)
+ proc_run('php','include/deliver_hooks.php', $target_item['id']);
}
- logger('notifier: basic loop complete.', LOGGER_DEBUG);
-
- if($normal_mode)
- call_hooks('notifier_normal',$target_item);
+ if($deliveries)
+ do_delivery($deliveries);
+ logger('notifier: basic loop complete.', LOGGER_DEBUG);
call_hooks('notifier_end',$target_item);
diff --git a/include/notify.php b/include/notify.php
index eef838664..2b032b56b 100644
--- a/include/notify.php
+++ b/include/notify.php
@@ -5,9 +5,6 @@ function format_notification($item) {
$ret = '';
-// return array();
-
-
require_once('include/conversation.php');
// Call localize_item with the "brief" flag to get a one line status for activities.
@@ -19,7 +16,7 @@ function format_notification($item) {
$itemem_text = $item['localize'];
}
else {
- $itemem_text = (($item['item_flags'] & ITEM_THREAD_TOP)
+ $itemem_text = (($item['item_thread_top'])
? t('created a new post')
: sprintf( t('commented on %s\'s post'), $item['owner']['xchan_name']));
}
diff --git a/include/oembed.php b/include/oembed.php
index 0628afaa9..e50d34c7d 100755
--- a/include/oembed.php
+++ b/include/oembed.php
@@ -2,6 +2,35 @@
function oembed_replacecb($matches){
$embedurl=$matches[1];
+
+ // implements a personal embed white/black list for logged in members
+ if(local_channel()) {
+ if(($x = get_pconfig(local_channel(),'system','embed_deny'))) {
+ $l = explode("\n",$x);
+ if($l) {
+ foreach($l as $ll) {
+ if(trim($ll) && strpos($embedurl,trim($ll)) !== false)
+ return '<a href="' . $embedurl . '">' . $embedurl . '</a>';
+ }
+ }
+ }
+ if(($x = get_pconfig(local_channel(),'system','embed_allow'))) {
+ $found = false;
+ $l = explode("\n",$x);
+ if($l) {
+ foreach($l as $ll) {
+ if(trim($ll) && strpos($embedurl,trim($ll)) !== false) {
+ $found = true;
+ break;
+ }
+ }
+ }
+ if(! $found) {
+ return '<a href="' . $embedurl . '">' . $embedurl . '</a>';
+ }
+ }
+ }
+
$j = oembed_fetch_url($embedurl);
$s = oembed_format_object($j);
return $s;
@@ -95,7 +124,8 @@ function oembed_fetch_url($embedurl){
Cache::set($a->videowidth . $embedurl,$txt);
}
-
+
+
$j = json_decode($txt);
$j->embedurl = $embedurl;
return $j;
diff --git a/include/onedirsync.php b/include/onedirsync.php
index de8dab92d..ce516da9d 100644
--- a/include/onedirsync.php
+++ b/include/onedirsync.php
@@ -41,7 +41,7 @@ function onedirsync_run($argv, $argc){
intval(UPDATE_FLAGS_UPDATED)
);
if($x) {
- $y = q("update updates set ud_flags = ( ud_flags | %d ) where ud_addr = '%s' and ( ud_flags & %d ) = 0 and ud_date < '%s' ",
+ $y = q("update updates set ud_flags = ( ud_flags | %d ) where ud_addr = '%s' and ( ud_flags & %d ) = 0 and ud_date != '%s'",
intval(UPDATE_FLAGS_UPDATED),
dbesc($r[0]['ud_addr']),
intval(UPDATE_FLAGS_UPDATED),
diff --git a/include/onepoll.php b/include/onepoll.php
index 66b000934..fedeb1e95 100644
--- a/include/onepoll.php
+++ b/include/onepoll.php
@@ -28,13 +28,9 @@ function onepoll_run($argv, $argc){
$contacts = q("SELECT abook.*, xchan.*, account.*
FROM abook LEFT JOIN account on abook_account = account_id left join xchan on xchan_hash = abook_xchan
where abook_id = %d
- AND (( abook_flags & %d )>0 OR ( abook_flags = %d ))
- AND NOT ( abook_flags & %d )>0
+ and abook_pending = 0 and abook_archived = 0 and abook_blocked = 0 and abook_ignored = 0
AND (( account_flags = %d ) OR ( account_flags = %d )) limit 1",
intval($contact_id),
- intval(ABOOK_FLAG_HIDDEN|ABOOK_FLAG_PENDING|ABOOK_FLAG_UNCONNECTED|ABOOK_FLAG_FEED),
- intval(0),
- intval(ABOOK_FLAG_ARCHIVED|ABOOK_FLAG_BLOCKED|ABOOK_FLAG_IGNORED),
intval(ACCOUNT_OK),
intval(ACCOUNT_UNVERIFIED)
);
diff --git a/include/permissions.php b/include/permissions.php
index f63c6da18..a8e761f87 100644
--- a/include/permissions.php
+++ b/include/permissions.php
@@ -25,9 +25,8 @@ function get_perms() {
// Read only permissions
'view_stream' => array('channel_r_stream', intval(PERMS_R_STREAM), true, t('Can view my normal stream and posts'), ''),
'view_profile' => array('channel_r_profile', intval(PERMS_R_PROFILE), true, t('Can view my default channel profile'), ''),
- 'view_photos' => array('channel_r_photos', intval(PERMS_R_PHOTOS), true, t('Can view my photo albums'), ''),
'view_contacts' => array('channel_r_abook', intval(PERMS_R_ABOOK), true, t('Can view my connections'), ''),
- 'view_storage' => array('channel_r_storage', intval(PERMS_R_STORAGE), true, t('Can view my file storage'), ''),
+ 'view_storage' => array('channel_r_storage', intval(PERMS_R_STORAGE), true, t('Can view my file storage and photos'), ''),
'view_pages' => array('channel_r_pages', intval(PERMS_R_PAGES), true, t('Can view my webpages'), ''),
// Write permissions
@@ -35,12 +34,11 @@ function get_perms() {
'post_wall' => array('channel_w_wall', intval(PERMS_W_WALL), false, t('Can post on my channel page ("wall")'), ''),
'post_comments' => array('channel_w_comment', intval(PERMS_W_COMMENT), false, t('Can comment on or like my posts'), ''),
'post_mail' => array('channel_w_mail', intval(PERMS_W_MAIL), false, t('Can send me private mail messages'), ''),
- 'post_photos' => array('channel_w_photos', intval(PERMS_W_PHOTOS), false, t('Can post photos to my photo albums'), ''),
'post_like' => array('channel_w_like', intval(PERMS_W_LIKE), false, t('Can like/dislike stuff'), t('Profiles and things other than posts/comments')),
'tag_deliver' => array('channel_w_tagwall', intval(PERMS_W_TAGWALL), false, t('Can forward to all my channel contacts via post @mentions'), t('Advanced - useful for creating group forum channels')),
'chat' => array('channel_w_chat', intval(PERMS_W_CHAT), false, t('Can chat with me (when available)'), t('')),
- 'write_storage' => array('channel_w_storage', intval(PERMS_W_STORAGE), false, t('Can write to my file storage'), ''),
+ 'write_storage' => array('channel_w_storage', intval(PERMS_W_STORAGE), false, t('Can write to my file storage and photos'), ''),
'write_pages' => array('channel_w_pages', intval(PERMS_W_PAGES), false, t('Can edit my webpages'), ''),
'republish' => array('channel_a_republish', intval(PERMS_A_REPUBLISH), false, t('Can source my public posts in derived channels'), t('Somewhat advanced - very useful in open communities')),
@@ -113,11 +111,10 @@ function get_all_perms($uid, $observer_xchan, $internal_use = true) {
}
if(! $abook_checked) {
- $x = q("select abook_my_perms, abook_flags, xchan_network from abook left join xchan on abook_xchan = xchan_hash
- where abook_channel = %d and abook_xchan = '%s' and not ( abook_flags & %d )>0 limit 1",
+ $x = q("select abook_my_perms, abook_blocked, abook_ignored, abook_pending, xchan_network from abook left join xchan on abook_xchan = xchan_hash
+ where abook_channel = %d and abook_xchan = '%s' and abook_self = 0 limit 1",
intval($uid),
- dbesc($observer_xchan),
- intval(ABOOK_FLAG_SELF)
+ dbesc($observer_xchan)
);
if(! $x) {
// not in address book, see if they've got an xchan
@@ -131,7 +128,7 @@ function get_all_perms($uid, $observer_xchan, $internal_use = true) {
// If they're blocked - they can't read or write
- if(($x) && ($x[0]['abook_flags'] & ABOOK_FLAG_BLOCKED)) {
+ if(($x) && intval($x[0]['abook_blocked'])) {
$ret[$perm_name] = false;
continue;
}
@@ -139,7 +136,7 @@ function get_all_perms($uid, $observer_xchan, $internal_use = true) {
// Check if this is a write permission and they are being ignored
// This flag is only visible internally.
- if(($x) && ($internal_use) && (! $global_perms[$perm_name][2]) && ($x[0]['abook_flags'] & ABOOK_FLAG_IGNORED)) {
+ if(($x) && ($internal_use) && (! $global_perms[$perm_name][2]) && intval($x[0]['abook_ignored'])) {
$ret[$perm_name] = false;
continue;
}
@@ -218,7 +215,7 @@ function get_all_perms($uid, $observer_xchan, $internal_use = true) {
continue;
}
- if($x[0]['abook_flags'] & ABOOK_FLAG_PENDING) {
+ if(intval($x[0]['abook_pending'])) {
$ret[$perm_name] = false;
continue;
}
@@ -300,19 +297,18 @@ function perm_is_allowed($uid, $observer_xchan, $permission) {
if($r[0][$channel_perm] & PERMS_AUTHED)
return true;
- $x = q("select abook_my_perms, abook_flags, xchan_network from abook left join xchan on abook_xchan = xchan_hash
- where abook_channel = %d and abook_xchan = '%s' and not ( abook_flags & %d )>0 limit 1",
+ $x = q("select abook_my_perms, abook_blocked, abook_ignored, abook_pending, xchan_network from abook left join xchan on abook_xchan = xchan_hash
+ where abook_channel = %d and abook_xchan = '%s' and abook_self = 0 limit 1",
intval($uid),
- dbesc($observer_xchan),
- intval(ABOOK_FLAG_SELF)
+ dbesc($observer_xchan)
);
// If they're blocked - they can't read or write
- if(($x) && ($x[0]['abook_flags'] & ABOOK_FLAG_BLOCKED))
+ if(($x) && intval($x[0]['abook_blocked']))
return false;
- if(($x) && (! $global_perms[$permission][2]) && ($x[0]['abook_flags'] & ABOOK_FLAG_IGNORED))
+ if(($x) && (! $global_perms[$permission][2]) && intval($x[0]['abook_ignored']))
return false;
if(! $x) {
@@ -374,7 +370,7 @@ function perm_is_allowed($uid, $observer_xchan, $permission) {
return true;
}
- if($x[0]['abook_flags'] & ABOOK_FLAG_PENDING) {
+ if(intval($x[0]['abook_pending'])) {
return false;
}
@@ -498,7 +494,6 @@ function site_default_perms() {
$typical = array(
'view_stream' => PERMS_PUBLIC,
'view_profile' => PERMS_PUBLIC,
- 'view_photos' => PERMS_PUBLIC,
'view_contacts' => PERMS_PUBLIC,
'view_storage' => PERMS_PUBLIC,
'view_pages' => PERMS_PUBLIC,
@@ -506,7 +501,6 @@ function site_default_perms() {
'post_wall' => PERMS_SPECIFIC,
'post_comments' => PERMS_SPECIFIC,
'post_mail' => PERMS_SPECIFIC,
- 'post_photos' => PERMS_SPECIFIC,
'tag_deliver' => PERMS_SPECIFIC,
'chat' => PERMS_SPECIFIC,
'write_storage' => PERMS_SPECIFIC,
@@ -556,22 +550,20 @@ function get_role_perms($role) {
$ret['default_collection'] = false;
$ret['directory_publish'] = true;
$ret['online'] = true;
- $ret['perms_follow'] = PERMS_R_STREAM|PERMS_R_PROFILE|PERMS_R_PHOTOS|PERMS_R_ABOOK
+ $ret['perms_follow'] = PERMS_R_STREAM|PERMS_R_PROFILE|PERMS_R_ABOOK
|PERMS_W_STREAM|PERMS_W_WALL|PERMS_W_COMMENT|PERMS_W_MAIL|PERMS_W_CHAT
|PERMS_R_STORAGE|PERMS_R_PAGES|PERMS_A_REPUBLISH|PERMS_W_LIKE;
- $ret['perms_accept'] = PERMS_R_STREAM|PERMS_R_PROFILE|PERMS_R_PHOTOS|PERMS_R_ABOOK
+ $ret['perms_accept'] = PERMS_R_STREAM|PERMS_R_PROFILE|PERMS_R_ABOOK
|PERMS_W_STREAM|PERMS_W_WALL|PERMS_W_COMMENT|PERMS_W_MAIL|PERMS_W_CHAT
|PERMS_R_STORAGE|PERMS_R_PAGES|PERMS_A_REPUBLISH|PERMS_W_LIKE;
$ret['channel_r_stream'] = PERMS_PUBLIC;
$ret['channel_r_profile'] = PERMS_PUBLIC;
- $ret['channel_r_photos'] = PERMS_PUBLIC;
$ret['channel_r_abook'] = PERMS_PUBLIC;
$ret['channel_w_stream'] = PERMS_SPECIFIC;
$ret['channel_w_wall'] = PERMS_SPECIFIC;
$ret['channel_w_tagwall'] = PERMS_SPECIFIC;
$ret['channel_w_comment'] = PERMS_SPECIFIC;
$ret['channel_w_mail'] = PERMS_SPECIFIC;
- $ret['channel_w_photos'] = PERMS_SPECIFIC;
$ret['channel_w_chat'] = PERMS_SPECIFIC;
$ret['channel_a_delegate'] = PERMS_SPECIFIC;
$ret['channel_r_storage'] = PERMS_PUBLIC;
@@ -588,22 +580,20 @@ function get_role_perms($role) {
$ret['default_collection'] = true;
$ret['directory_publish'] = true;
$ret['online'] = true;
- $ret['perms_follow'] = PERMS_R_STREAM|PERMS_R_PROFILE|PERMS_R_PHOTOS|PERMS_R_ABOOK
+ $ret['perms_follow'] = PERMS_R_STREAM|PERMS_R_PROFILE|PERMS_R_ABOOK
|PERMS_W_STREAM|PERMS_W_WALL|PERMS_W_COMMENT|PERMS_W_MAIL|PERMS_W_CHAT
|PERMS_R_STORAGE|PERMS_R_PAGES|PERMS_W_LIKE;
- $ret['perms_accept'] = PERMS_R_STREAM|PERMS_R_PROFILE|PERMS_R_PHOTOS|PERMS_R_ABOOK
+ $ret['perms_accept'] = PERMS_R_STREAM|PERMS_R_PROFILE|PERMS_R_ABOOK
|PERMS_W_STREAM|PERMS_W_WALL|PERMS_W_COMMENT|PERMS_W_MAIL|PERMS_W_CHAT
|PERMS_R_STORAGE|PERMS_R_PAGES|PERMS_W_LIKE;
$ret['channel_r_stream'] = PERMS_PUBLIC;
$ret['channel_r_profile'] = PERMS_PUBLIC;
- $ret['channel_r_photos'] = PERMS_PUBLIC;
$ret['channel_r_abook'] = PERMS_PUBLIC;
$ret['channel_w_stream'] = PERMS_SPECIFIC;
$ret['channel_w_wall'] = PERMS_SPECIFIC;
$ret['channel_w_tagwall'] = PERMS_SPECIFIC;
$ret['channel_w_comment'] = PERMS_SPECIFIC;
$ret['channel_w_mail'] = PERMS_SPECIFIC;
- $ret['channel_w_photos'] = PERMS_SPECIFIC;
$ret['channel_w_chat'] = PERMS_SPECIFIC;
$ret['channel_a_delegate'] = PERMS_SPECIFIC;
$ret['channel_r_storage'] = PERMS_PUBLIC;
@@ -620,22 +610,20 @@ function get_role_perms($role) {
$ret['default_collection'] = true;
$ret['directory_publish'] = false;
$ret['online'] = false;
- $ret['perms_follow'] = PERMS_R_STREAM|PERMS_R_PROFILE|PERMS_R_PHOTOS|PERMS_R_ABOOK
+ $ret['perms_follow'] = PERMS_R_STREAM|PERMS_R_PROFILE|PERMS_R_ABOOK
|PERMS_W_STREAM|PERMS_W_WALL|PERMS_W_COMMENT|PERMS_W_MAIL|PERMS_W_CHAT
|PERMS_R_STORAGE|PERMS_R_PAGES|PERMS_W_LIKE;
- $ret['perms_accept'] = PERMS_R_STREAM|PERMS_R_PROFILE|PERMS_R_PHOTOS|PERMS_R_ABOOK
+ $ret['perms_accept'] = PERMS_R_STREAM|PERMS_R_PROFILE|PERMS_R_ABOOK
|PERMS_W_STREAM|PERMS_W_WALL|PERMS_W_COMMENT|PERMS_W_MAIL|PERMS_W_CHAT
|PERMS_R_STORAGE|PERMS_R_PAGES|PERMS_W_LIKE;
$ret['channel_r_stream'] = PERMS_PUBLIC;
$ret['channel_r_profile'] = PERMS_PUBLIC;
- $ret['channel_r_photos'] = PERMS_PUBLIC;
$ret['channel_r_abook'] = PERMS_SPECIFIC;
$ret['channel_w_stream'] = PERMS_SPECIFIC;
$ret['channel_w_wall'] = PERMS_SPECIFIC;
$ret['channel_w_tagwall'] = PERMS_SPECIFIC;
$ret['channel_w_comment'] = PERMS_SPECIFIC;
$ret['channel_w_mail'] = PERMS_SPECIFIC;
- $ret['channel_w_photos'] = PERMS_SPECIFIC;
$ret['channel_w_chat'] = PERMS_SPECIFIC;
$ret['channel_a_delegate'] = PERMS_SPECIFIC;
$ret['channel_r_storage'] = PERMS_PUBLIC;
@@ -652,22 +640,20 @@ function get_role_perms($role) {
$ret['default_collection'] = false;
$ret['directory_publish'] = true;
$ret['online'] = false;
- $ret['perms_follow'] = PERMS_R_STREAM|PERMS_R_PROFILE|PERMS_R_PHOTOS|PERMS_R_ABOOK
+ $ret['perms_follow'] = PERMS_R_STREAM|PERMS_R_PROFILE|PERMS_R_ABOOK
|PERMS_W_STREAM|PERMS_W_WALL|PERMS_W_COMMENT|PERMS_W_MAIL|PERMS_W_CHAT
|PERMS_R_STORAGE|PERMS_R_PAGES|PERMS_A_REPUBLISH|PERMS_W_LIKE|PERMS_W_TAGWALL;
- $ret['perms_accept'] = PERMS_R_STREAM|PERMS_R_PROFILE|PERMS_R_PHOTOS|PERMS_R_ABOOK
+ $ret['perms_accept'] = PERMS_R_STREAM|PERMS_R_PROFILE|PERMS_R_ABOOK
|PERMS_W_STREAM|PERMS_W_WALL|PERMS_W_COMMENT|PERMS_W_MAIL|PERMS_W_CHAT
|PERMS_R_STORAGE|PERMS_R_PAGES|PERMS_A_REPUBLISH|PERMS_W_LIKE|PERMS_W_TAGWALL;
$ret['channel_r_stream'] = PERMS_PUBLIC;
$ret['channel_r_profile'] = PERMS_PUBLIC;
- $ret['channel_r_photos'] = PERMS_PUBLIC;
$ret['channel_r_abook'] = PERMS_PUBLIC;
$ret['channel_w_stream'] = PERMS_SPECIFIC;
$ret['channel_w_wall'] = PERMS_SPECIFIC;
$ret['channel_w_tagwall'] = PERMS_SPECIFIC;
$ret['channel_w_comment'] = PERMS_SPECIFIC;
$ret['channel_w_mail'] = PERMS_SPECIFIC;
- $ret['channel_w_photos'] = PERMS_SPECIFIC;
$ret['channel_w_chat'] = PERMS_SPECIFIC;
$ret['channel_a_delegate'] = PERMS_SPECIFIC;
$ret['channel_r_storage'] = PERMS_PUBLIC;
@@ -684,22 +670,20 @@ function get_role_perms($role) {
$ret['default_collection'] = true;
$ret['directory_publish'] = true;
$ret['online'] = false;
- $ret['perms_follow'] = PERMS_R_STREAM|PERMS_R_PROFILE|PERMS_R_PHOTOS|PERMS_R_ABOOK
+ $ret['perms_follow'] = PERMS_R_STREAM|PERMS_R_PROFILE|PERMS_R_ABOOK
|PERMS_W_STREAM|PERMS_W_WALL|PERMS_W_COMMENT|PERMS_W_MAIL|PERMS_W_CHAT
|PERMS_R_STORAGE|PERMS_R_PAGES|PERMS_W_LIKE|PERMS_W_TAGWALL;
- $ret['perms_accept'] = PERMS_R_STREAM|PERMS_R_PROFILE|PERMS_R_PHOTOS|PERMS_R_ABOOK
+ $ret['perms_accept'] = PERMS_R_STREAM|PERMS_R_PROFILE|PERMS_R_ABOOK
|PERMS_W_STREAM|PERMS_W_WALL|PERMS_W_COMMENT|PERMS_W_MAIL|PERMS_W_CHAT
|PERMS_R_STORAGE|PERMS_R_PAGES|PERMS_W_LIKE|PERMS_W_TAGWALL;
$ret['channel_r_stream'] = PERMS_PUBLIC;
$ret['channel_r_profile'] = PERMS_PUBLIC;
- $ret['channel_r_photos'] = PERMS_PUBLIC;
$ret['channel_r_abook'] = PERMS_PUBLIC;
$ret['channel_w_stream'] = PERMS_SPECIFIC;
$ret['channel_w_wall'] = PERMS_SPECIFIC;
$ret['channel_w_tagwall'] = PERMS_SPECIFIC;
$ret['channel_w_comment'] = PERMS_SPECIFIC;
$ret['channel_w_mail'] = PERMS_SPECIFIC;
- $ret['channel_w_photos'] = PERMS_SPECIFIC;
$ret['channel_w_chat'] = PERMS_SPECIFIC;
$ret['channel_a_delegate'] = PERMS_SPECIFIC;
$ret['channel_r_storage'] = PERMS_PUBLIC;
@@ -716,22 +700,20 @@ function get_role_perms($role) {
$ret['default_collection'] = true;
$ret['directory_publish'] = false;
$ret['online'] = false;
- $ret['perms_follow'] = PERMS_R_STREAM|PERMS_R_PROFILE|PERMS_R_PHOTOS|PERMS_R_ABOOK
+ $ret['perms_follow'] = PERMS_R_STREAM|PERMS_R_PROFILE|PERMS_R_ABOOK
|PERMS_W_STREAM|PERMS_W_WALL|PERMS_W_COMMENT|PERMS_W_MAIL|PERMS_W_CHAT
|PERMS_R_STORAGE|PERMS_R_PAGES|PERMS_W_LIKE;
- $ret['perms_accept'] = PERMS_R_STREAM|PERMS_R_PROFILE|PERMS_R_PHOTOS|PERMS_R_ABOOK
+ $ret['perms_accept'] = PERMS_R_STREAM|PERMS_R_PROFILEPERMS_R_ABOOK
|PERMS_W_STREAM|PERMS_W_WALL|PERMS_W_COMMENT|PERMS_W_MAIL|PERMS_W_CHAT
|PERMS_R_STORAGE|PERMS_R_PAGES|PERMS_W_LIKE;
$ret['channel_r_stream'] = PERMS_PUBLIC;
$ret['channel_r_profile'] = PERMS_SPECIFIC;
- $ret['channel_r_photos'] = PERMS_SPECIFIC;
$ret['channel_r_abook'] = PERMS_SPECIFIC;
$ret['channel_w_stream'] = PERMS_SPECIFIC;
$ret['channel_w_wall'] = PERMS_SPECIFIC;
$ret['channel_w_tagwall'] = PERMS_SPECIFIC;
$ret['channel_w_comment'] = PERMS_SPECIFIC;
$ret['channel_w_mail'] = PERMS_SPECIFIC;
- $ret['channel_w_photos'] = PERMS_SPECIFIC;
$ret['channel_w_chat'] = PERMS_SPECIFIC;
$ret['channel_a_delegate'] = PERMS_SPECIFIC;
$ret['channel_r_storage'] = PERMS_SPECIFIC;
@@ -748,22 +730,20 @@ function get_role_perms($role) {
$ret['default_collection'] = false;
$ret['directory_publish'] = true;
$ret['online'] = false;
- $ret['perms_follow'] = PERMS_R_STREAM|PERMS_R_PROFILE|PERMS_R_PHOTOS|PERMS_R_ABOOK
+ $ret['perms_follow'] = PERMS_R_STREAM|PERMS_R_PROFILE|PERMS_R_ABOOK
|PERMS_W_STREAM|PERMS_W_WALL|PERMS_W_COMMENT|PERMS_W_MAIL
|PERMS_R_STORAGE|PERMS_R_PAGES|PERMS_A_REPUBLISH|PERMS_W_LIKE;
- $ret['perms_accept'] = PERMS_R_STREAM|PERMS_R_PROFILE|PERMS_R_PHOTOS|PERMS_R_ABOOK
+ $ret['perms_accept'] = PERMS_R_STREAM|PERMS_R_PROFILE|PERMS_R_ABOOK
|PERMS_W_STREAM|PERMS_W_WALL|PERMS_W_COMMENT|PERMS_W_MAIL
|PERMS_R_STORAGE|PERMS_R_PAGES|PERMS_A_REPUBLISH|PERMS_W_LIKE;
$ret['channel_r_stream'] = PERMS_PUBLIC;
$ret['channel_r_profile'] = PERMS_PUBLIC;
- $ret['channel_r_photos'] = PERMS_PUBLIC;
$ret['channel_r_abook'] = PERMS_PUBLIC;
$ret['channel_w_stream'] = PERMS_SPECIFIC;
$ret['channel_w_wall'] = PERMS_SPECIFIC;
$ret['channel_w_tagwall'] = PERMS_SPECIFIC;
$ret['channel_w_comment'] = PERMS_SPECIFIC;
$ret['channel_w_mail'] = PERMS_SPECIFIC;
- $ret['channel_w_photos'] = PERMS_SPECIFIC;
$ret['channel_w_chat'] = PERMS_SPECIFIC;
$ret['channel_a_delegate'] = PERMS_SPECIFIC;
$ret['channel_r_storage'] = PERMS_PUBLIC;
@@ -780,22 +760,20 @@ function get_role_perms($role) {
$ret['default_collection'] = true;
$ret['directory_publish'] = false;
$ret['online'] = false;
- $ret['perms_follow'] = PERMS_R_STREAM|PERMS_R_PROFILE|PERMS_R_PHOTOS|PERMS_R_ABOOK
+ $ret['perms_follow'] = PERMS_R_STREAM|PERMS_R_PROFILE|PERMS_R_ABOOK
|PERMS_W_STREAM|PERMS_W_WALL|PERMS_W_COMMENT|PERMS_W_MAIL
|PERMS_R_STORAGE|PERMS_R_PAGES|PERMS_W_LIKE;
- $ret['perms_accept'] = PERMS_R_STREAM|PERMS_R_PROFILE|PERMS_R_PHOTOS|PERMS_R_ABOOK
+ $ret['perms_accept'] = PERMS_R_STREAM|PERMS_R_PROFILE|PERMS_R_ABOOK
|PERMS_W_STREAM|PERMS_W_WALL|PERMS_W_COMMENT|PERMS_W_MAIL
|PERMS_R_STORAGE|PERMS_R_PAGES|PERMS_W_LIKE;
$ret['channel_r_stream'] = PERMS_PUBLIC;
$ret['channel_r_profile'] = PERMS_PUBLIC;
- $ret['channel_r_photos'] = PERMS_PUBLIC;
$ret['channel_r_abook'] = PERMS_PUBLIC;
$ret['channel_w_stream'] = PERMS_SPECIFIC;
$ret['channel_w_wall'] = PERMS_SPECIFIC;
$ret['channel_w_tagwall'] = PERMS_SPECIFIC;
$ret['channel_w_comment'] = PERMS_SPECIFIC;
$ret['channel_w_mail'] = PERMS_SPECIFIC;
- $ret['channel_w_photos'] = PERMS_SPECIFIC;
$ret['channel_w_chat'] = PERMS_SPECIFIC;
$ret['channel_a_delegate'] = PERMS_SPECIFIC;
$ret['channel_r_storage'] = PERMS_PUBLIC;
@@ -812,20 +790,18 @@ function get_role_perms($role) {
$ret['default_collection'] = false;
$ret['directory_publish'] = true;
$ret['online'] = false;
- $ret['perms_follow'] = PERMS_R_STREAM|PERMS_R_PROFILE|PERMS_R_PHOTOS|PERMS_R_ABOOK
+ $ret['perms_follow'] = PERMS_R_STREAM|PERMS_R_PROFILE|PERMS_R_ABOOK
|PERMS_R_STORAGE|PERMS_R_PAGES|PERMS_A_REPUBLISH|PERMS_W_LIKE;
- $ret['perms_accept'] = PERMS_R_STREAM|PERMS_R_PROFILE|PERMS_R_PHOTOS|PERMS_R_ABOOK
+ $ret['perms_accept'] = PERMS_R_STREAM|PERMS_R_PROFILE|PERMS_R_ABOOK
|PERMS_R_STORAGE|PERMS_R_PAGES|PERMS_A_REPUBLISH|PERMS_W_LIKE;
$ret['channel_r_stream'] = PERMS_PUBLIC;
$ret['channel_r_profile'] = PERMS_PUBLIC;
- $ret['channel_r_photos'] = PERMS_PUBLIC;
$ret['channel_r_abook'] = PERMS_PUBLIC;
$ret['channel_w_stream'] = PERMS_SPECIFIC;
$ret['channel_w_wall'] = PERMS_SPECIFIC;
$ret['channel_w_tagwall'] = PERMS_SPECIFIC;
$ret['channel_w_comment'] = PERMS_SPECIFIC;
$ret['channel_w_mail'] = PERMS_SPECIFIC;
- $ret['channel_w_photos'] = PERMS_SPECIFIC;
$ret['channel_w_chat'] = PERMS_SPECIFIC;
$ret['channel_a_delegate'] = PERMS_SPECIFIC;
$ret['channel_r_storage'] = PERMS_PUBLIC;
@@ -842,22 +818,20 @@ function get_role_perms($role) {
$ret['default_collection'] = false;
$ret['directory_publish'] = true;
$ret['online'] = false;
- $ret['perms_follow'] = PERMS_R_STREAM|PERMS_R_PROFILE|PERMS_R_PHOTOS|PERMS_R_ABOOK
+ $ret['perms_follow'] = PERMS_R_STREAM|PERMS_R_PROFILE|PERMS_R_ABOOK
|PERMS_W_STREAM|PERMS_W_WALL|PERMS_W_COMMENT|PERMS_W_MAIL|PERMS_W_CHAT
|PERMS_R_STORAGE|PERMS_W_STORAGE|PERMS_R_PAGES|PERMS_A_REPUBLISH|PERMS_W_LIKE|PERMS_W_TAGWALL;
- $ret['perms_accept'] = PERMS_R_STREAM|PERMS_R_PROFILE|PERMS_R_PHOTOS|PERMS_R_ABOOK
+ $ret['perms_accept'] = PERMS_R_STREAM|PERMS_R_PROFILE|PERMS_R_ABOOK
|PERMS_W_STREAM|PERMS_W_WALL|PERMS_W_COMMENT|PERMS_W_MAIL|PERMS_W_CHAT
|PERMS_R_STORAGE|PERMS_W_STORAGE|PERMS_R_PAGES|PERMS_A_REPUBLISH|PERMS_W_LIKE|PERMS_W_TAGWALL;
$ret['channel_r_stream'] = PERMS_PUBLIC;
$ret['channel_r_profile'] = PERMS_PUBLIC;
- $ret['channel_r_photos'] = PERMS_PUBLIC;
$ret['channel_r_abook'] = PERMS_PUBLIC;
$ret['channel_w_stream'] = PERMS_SPECIFIC;
$ret['channel_w_wall'] = PERMS_SPECIFIC;
$ret['channel_w_tagwall'] = PERMS_SPECIFIC;
$ret['channel_w_comment'] = PERMS_SPECIFIC;
$ret['channel_w_mail'] = PERMS_SPECIFIC;
- $ret['channel_w_photos'] = PERMS_SPECIFIC;
$ret['channel_w_chat'] = PERMS_SPECIFIC;
$ret['channel_a_delegate'] = PERMS_SPECIFIC;
$ret['channel_r_storage'] = PERMS_PUBLIC;
diff --git a/include/photo/photo_driver.php b/include/photo/photo_driver.php
index 96bde7587..285cbc8fb 100644
--- a/include/photo/photo_driver.php
+++ b/include/photo/photo_driver.php
@@ -238,10 +238,12 @@ abstract class photo_driver {
if(! $this->is_valid())
return FALSE;
+
if((! function_exists('exif_read_data')) || ($this->getType() !== 'image/jpeg'))
return;
$exif = @exif_read_data($filename,null,true);
+
if($exif) {
$ort = $exif['IFD0']['Orientation'];
@@ -281,7 +283,6 @@ abstract class photo_driver {
break;
}
- // logger('exif: ' . print_r($exif,true));
return $exif;
}
@@ -302,7 +303,6 @@ abstract class photo_driver {
$p['filename'] = (($arr['filename']) ? $arr['filename'] : '');
$p['album'] = (($arr['album']) ? $arr['album'] : '');
$p['scale'] = ((intval($arr['scale'])) ? intval($arr['scale']) : 0);
- $p['photo_flags'] = ((intval($arr['photo_flags'])) ? intval($arr['photo_flags']) : 0);
$p['allow_cid'] = (($arr['allow_cid']) ? $arr['allow_cid'] : '');
$p['allow_gid'] = (($arr['allow_gid']) ? $arr['allow_gid'] : '');
$p['deny_cid'] = (($arr['deny_cid']) ? $arr['deny_cid'] : '');
@@ -311,12 +311,12 @@ abstract class photo_driver {
$p['edited'] = (($arr['edited']) ? $arr['edited'] : $p['created']);
$p['title'] = (($arr['title']) ? $arr['title'] : '');
$p['description'] = (($arr['description']) ? $arr['description'] : '');
+ $p['photo_usage'] = intval($arr['photo_usage']);
+ $p['os_storage'] = intval($arr['os_storage']);
+ $p['os_path'] = $arr['os_path'];
- // temporary until we get rid of photo['profile'] and just use photo['photo_flags']
- // but this will require updating all existing photos in the DB.
-
- $p['profile'] = (($p['photo_flags'] & PHOTO_PROFILE) ? 1 : 0);
-
+ if(! intval($p['scale']))
+ logger('save: ' . print_r($arr,true));
$x = q("select id from photo where resource_id = '%s' and uid = %d and xchan = '%s' and `scale` = %d limit 1",
dbesc($p['resource_id']),
@@ -338,10 +338,10 @@ abstract class photo_driver {
`height` = %d,
`width` = %d,
`data` = '%s',
+ `os_storage` = %d,
`size` = %d,
`scale` = %d,
- `profile` = %d,
- `photo_flags` = %d,
+ `photo_usage` = %d,
`title` = '%s',
`description` = '%s',
`allow_cid` = '%s',
@@ -361,11 +361,11 @@ abstract class photo_driver {
dbesc($p['album']),
intval($this->getHeight()),
intval($this->getWidth()),
- dbescbin($this->imageString()),
+ (intval($p['os_storage']) ? dbesc($p['os_path']) : dbescbin($this->imageString())),
+ intval($p['os_storage']),
intval(strlen($this->imageString())),
intval($p['scale']),
- intval($p['profile']),
- intval($p['photo_flags']),
+ intval($p['photo_usage']),
dbesc($p['title']),
dbesc($p['description']),
dbesc($p['allow_cid']),
@@ -377,7 +377,7 @@ abstract class photo_driver {
}
else {
$r = q("INSERT INTO `photo`
- ( `aid`, `uid`, `xchan`, `resource_id`, `created`, `edited`, `filename`, type, `album`, `height`, `width`, `data`, `size`, `scale`, `profile`, `photo_flags`, `title`, `description`, `allow_cid`, `allow_gid`, `deny_cid`, `deny_gid` )
+ ( `aid`, `uid`, `xchan`, `resource_id`, `created`, `edited`, `filename`, type, `album`, `height`, `width`, `data`, `os_storage`, `size`, `scale`, `photo_usage`, `title`, `description`, `allow_cid`, `allow_gid`, `deny_cid`, `deny_gid` )
VALUES ( %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, '%s', %d, %d, %d, %d, '%s', '%s', '%s', '%s', '%s', '%s' )",
intval($p['aid']),
intval($p['uid']),
@@ -390,11 +390,11 @@ abstract class photo_driver {
dbesc($p['album']),
intval($this->getHeight()),
intval($this->getWidth()),
- dbescbin($this->imageString()),
+ (intval($p['os_storage']) ? dbesc($p['os_path']) : dbescbin($this->imageString())),
+ intval($p['os_storage']),
intval(strlen($this->imageString())),
intval($p['scale']),
- intval($p['profile']),
- intval($p['photo_flags']),
+ intval($p['photo_usage']),
dbesc($p['title']),
dbesc($p['description']),
dbesc($p['allow_cid']),
@@ -406,7 +406,7 @@ abstract class photo_driver {
return $r;
}
- public function store($aid, $uid, $xchan, $rid, $filename, $album, $scale, $profile = 0, $allow_cid = '', $allow_gid = '', $deny_cid = '', $deny_gid = '') {
+ public function store($aid, $uid, $xchan, $rid, $filename, $album, $scale, $usage = PHOTO_NORMAL, $allow_cid = '', $allow_gid = '', $deny_cid = '', $deny_gid = '') {
$x = q("select id from photo where `resource_id` = '%s' and uid = %d and `xchan` = '%s' and `scale` = %d limit 1",
dbesc($rid),
@@ -430,7 +430,7 @@ abstract class photo_driver {
`data` = '%s',
`size` = %d,
`scale` = %d,
- `profile` = %d,
+ `photo_usage` = %d,
`allow_cid` = '%s',
`allow_gid` = '%s',
`deny_cid` = '%s',
@@ -451,7 +451,7 @@ abstract class photo_driver {
dbescbin($this->imageString()),
intval(strlen($this->imageString())),
intval($scale),
- intval($profile),
+ intval($photo_usage),
dbesc($allow_cid),
dbesc($allow_gid),
dbesc($deny_cid),
@@ -461,7 +461,7 @@ abstract class photo_driver {
}
else {
$r = q("INSERT INTO `photo`
- ( `aid`, `uid`, `xchan`, `resource_id`, `created`, `edited`, `filename`, type, `album`, `height`, `width`, `data`, `size`, `scale`, `profile`, `allow_cid`, `allow_gid`, `deny_cid`, `deny_gid` )
+ ( `aid`, `uid`, `xchan`, `resource_id`, `created`, `edited`, `filename`, type, `album`, `height`, `width`, `data`, `size`, `scale`, `photo_usage`, `allow_cid`, `allow_gid`, `deny_cid`, `deny_gid` )
VALUES ( %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, '%s', %d, %d, %d, '%s', '%s', '%s', '%s' )",
intval($aid),
intval($uid),
@@ -477,7 +477,7 @@ abstract class photo_driver {
dbescbin($this->imageString()),
intval(strlen($this->imageString())),
intval($scale),
- intval($profile),
+ intval($photo_usage),
dbesc($allow_cid),
dbesc($allow_gid),
dbesc($deny_cid),
@@ -564,19 +564,19 @@ function guess_image_type($filename, $headers = '') {
}
-function import_profile_photo($photo,$xchan,$thing = false) {
+function import_xchan_photo($photo,$xchan,$thing = false) {
$a = get_app();
$flags = (($thing) ? PHOTO_THING : PHOTO_XCHAN);
$album = (($thing) ? 'Things' : 'Contact Photos');
- logger('import_profile_photo: updating channel photo from ' . $photo . ' for ' . $xchan, LOGGER_DEBUG);
+ logger('import_xchan_photo: updating channel photo from ' . $photo . ' for ' . $xchan, LOGGER_DEBUG);
if($thing)
$hash = photo_new_resource();
else {
- $r = q("select resource_id from photo where xchan = '%s' and (photo_flags & %d )>0 and scale = 4 limit 1",
+ $r = q("select resource_id from photo where xchan = '%s' and photo_usage = %d and scale = 4 limit 1",
dbesc($xchan),
intval(PHOTO_XCHAN)
);
@@ -612,62 +612,67 @@ function import_profile_photo($photo,$xchan,$thing = false) {
}
}
}
+ else {
+ $photo_failure = true;
+ }
- $img = photo_factory($img_str, $type);
- if($img->is_valid()) {
- $width = $img->getWidth();
- $height = $img->getHeight();
+ if(! $photo_failure) {
+ $img = photo_factory($img_str, $type);
+ if($img->is_valid()) {
+ $width = $img->getWidth();
+ $height = $img->getHeight();
- if($width && $height) {
- if(($width / $height) > 1.2) {
- // crop out the sides
- $margin = $width - $height;
- $img->cropImage(300,($margin / 2),0,$height,$height);
- }
- elseif(($height / $width) > 1.2) {
- // crop out the bottom
- $margin = $height - $width;
- $img->cropImage(300,0,0,$width,$width);
-
- }
- else {
- $img->scaleImageSquare(300);
- }
-
- }
- else
- $photo_failure = true;
+ if($width && $height) {
+ if(($width / $height) > 1.2) {
+ // crop out the sides
+ $margin = $width - $height;
+ $img->cropImage(300,($margin / 2),0,$height,$height);
+ }
+ elseif(($height / $width) > 1.2) {
+ // crop out the bottom
+ $margin = $height - $width;
+ $img->cropImage(300,0,0,$width,$width);
- $p = array('xchan' => $xchan,'resource_id' => $hash, 'filename' => basename($photo), 'album' => $album, 'photo_flags' => $flags, 'scale' => 4);
+ }
+ else {
+ $img->scaleImageSquare(300);
+ }
- $r = $img->save($p);
+ }
+ else
+ $photo_failure = true;
- if($r === false)
- $photo_failure = true;
+ $p = array('xchan' => $xchan,'resource_id' => $hash, 'filename' => basename($photo), 'album' => $album, 'photo_usage' => $flags, 'scale' => 4);
- $img->scaleImage(80);
- $p['scale'] = 5;
+ $r = $img->save($p);
- $r = $img->save($p);
+ if($r === false)
+ $photo_failure = true;
- if($r === false)
- $photo_failure = true;
+ $img->scaleImage(80);
+ $p['scale'] = 5;
+
+ $r = $img->save($p);
- $img->scaleImage(48);
- $p['scale'] = 6;
+ if($r === false)
+ $photo_failure = true;
+
+ $img->scaleImage(48);
+ $p['scale'] = 6;
+
+ $r = $img->save($p);
- $r = $img->save($p);
+ if($r === false)
+ $photo_failure = true;
- if($r === false)
+ $photo = $a->get_baseurl() . '/photo/' . $hash . '-4';
+ $thumb = $a->get_baseurl() . '/photo/' . $hash . '-5';
+ $micro = $a->get_baseurl() . '/photo/' . $hash . '-6';
+ }
+ else {
+ logger('import_xchan_photo: invalid image from ' . $photo);
$photo_failure = true;
-
- $photo = $a->get_baseurl() . '/photo/' . $hash . '-4';
- $thumb = $a->get_baseurl() . '/photo/' . $hash . '-5';
- $micro = $a->get_baseurl() . '/photo/' . $hash . '-6';
- }
- else {
- logger('import_profile_photo: invalid image from ' . $photo);
- $photo_failure = true;
+ }
}
if($photo_failure) {
$photo = $a->get_baseurl() . '/' . get_default_profile_photo();
@@ -700,7 +705,7 @@ function import_channel_photo($photo,$type,$aid,$uid) {
$img->scaleImageSquare(300);
- $p = array('aid' => $aid, 'uid' => $uid, 'resource_id' => $hash, 'filename' => $filename, 'album' => t('Profile Photos'), 'photo_flags' => PHOTO_PROFILE, 'scale' => 4);
+ $p = array('aid' => $aid, 'uid' => $uid, 'resource_id' => $hash, 'filename' => $filename, 'album' => t('Profile Photos'), 'photo_usage' => PHOTO_PROFILE, 'scale' => 4);
$r = $img->save($p);
@@ -729,6 +734,11 @@ function import_channel_photo($photo,$type,$aid,$uid) {
$photo_failure = true;
}
- return(($photo_failure)? false : true);
+ //return(($photo_failure)? false : true);
+
+ if($photo_failure)
+ return false;
+ else
+ return $hash;
}
diff --git a/include/photos.php b/include/photos.php
index ca8c53679..c7360a956 100644
--- a/include/photos.php
+++ b/include/photos.php
@@ -7,6 +7,7 @@
require_once('include/permissions.php');
require_once('include/items.php');
require_once('include/photo/photo_driver.php');
+require_once('include/text.php');
/**
* @brief
@@ -18,44 +19,61 @@ require_once('include/photo/photo_driver.php');
*/
function photo_upload($channel, $observer, $args) {
+ $a = get_app();
+
$ret = array('success' => false);
$channel_id = $channel['channel_id'];
$account_id = $channel['channel_account_id'];
- if(! perm_is_allowed($channel_id, $observer['xchan_hash'], 'post_photos')) {
+ if(! perm_is_allowed($channel_id, $observer['xchan_hash'], 'write_storage')) {
$ret['message'] = t('Permission denied.');
return $ret;
}
- call_hooks('photo_upload_begin', $args);
+// call_hooks('photo_upload_begin', $args);
/*
* Determine the album to use
*/
$album = $args['album'];
- $newalbum = $args['newalbum'];
-
- logger('photo_upload: album= ' . $album . ' newalbum= ' . $newalbum , LOGGER_DEBUG);
-
- if(! $album) {
- if($newalbum)
- $album = $newalbum;
- else
- $album = datetime_convert('UTC',date_default_timezone_get(),'now', 'Y-m');
- }
if(intval($args['visible']) || $args['visible'] === 'true')
$visible = 1;
else
$visible = 0;
- $str_group_allow = perms2str(((is_array($args['group_allow'])) ? $args['group_allow'] : explode(',',$args['group_allow'])));
- $str_contact_allow = perms2str(((is_array($args['contact_allow'])) ? $args['contact_allow'] : explode(',',$args['contact_allow'])));
- $str_group_deny = perms2str(((is_array($args['group_deny'])) ? $args['group_deny'] : explode(',',$args['group_deny'])));
- $str_contact_deny = perms2str(((is_array($args['contact_deny'])) ? $args['contact_deny'] : explode(',',$args['contact_deny'])));
+ // Set to default channel permissions. If the parent directory (album) has permissions set,
+ // use those instead. If we have specific permissions supplied, they take precedence over
+ // all other settings. 'allow_cid' being passed from an external source takes priority over channel settings.
+ // ...messy... needs re-factoring once the photos/files integration stabilises
+
+ $acl = new AccessList($channel);
+ if(array_key_exists('directory',$args) && $args['directory'])
+ $acl->set($args['directory']);
+ if(array_key_exists('allow_cid',$args))
+ $acl->set($args);
+ if( (array_key_exists('group_allow',$args))
+ || (array_key_exists('contact_allow',$args))
+ || (array_key_exists('group_deny',$args))
+ || (array_key_exists('contact_deny',$args))) {
+ $acl->set_from_array($args);
+ }
+
+ $ac = $acl->get();
+
+ $os_storage = 0;
- if ($args['data']) {
+ if($args['os_path'] && $args['getimagesize']) {
+ $imagedata = @file_get_contents($args['os_path']);
+ $filename = $args['filename'];
+ $filesize = strlen($imagedata);
+ // this is going to be deleted if it exists
+ $src = '/tmp/deletemenow';
+ $type = $args['getimagesize']['mime'];
+ $os_storage = 1;
+ }
+ elseif ($args['data']) {
// allow an import from a binary string representing the image.
// This bypasses the upload step and max size limit checking
@@ -69,7 +87,7 @@ function photo_upload($channel, $observer, $args) {
} else {
$f = array('src' => '', 'filename' => '', 'filesize' => 0, 'type' => '');
- call_hooks('photo_upload_file',$f);
+// call_hooks('photo_upload_file',$f);
if (x($f,'src') && x($f,'filesize')) {
$src = $f['src'];
@@ -132,7 +150,7 @@ function photo_upload($channel, $observer, $args) {
return $ret;
}
- $exif = $ph->orient($src);
+ $exif = $ph->orient(($args['os_path']) ? $args['os_path'] : $src);
@unlink($src);
@@ -156,9 +174,10 @@ function photo_upload($channel, $observer, $args) {
$errors = false;
$p = array('aid' => $account_id, 'uid' => $channel_id, 'xchan' => $visitor, 'resource_id' => $photo_hash,
- 'filename' => $filename, 'album' => $album, 'scale' => 0, 'photo_flags' => PHOTO_NORMAL,
- 'allow_cid' => $str_contact_allow, 'allow_gid' => $str_group_allow,
- 'deny_cid' => $str_contact_deny, 'deny_gid' => $str_group_deny
+ 'filename' => $filename, 'album' => $album, 'scale' => 0, 'photo_usage' => PHOTO_NORMAL,
+ 'allow_cid' => $ac['allow_cid'], 'allow_gid' => $ac['allow_gid'],
+ 'deny_cid' => $ac['deny_cid'], 'deny_gid' => $ac['deny_gid'],
+ 'os_storage' => $os_storage, 'os_path' => $args['os_path']
);
if($args['created'])
$p['created'] = $args['created'];
@@ -169,27 +188,66 @@ function photo_upload($channel, $observer, $args) {
if($args['description'])
$p['description'] = $args['description'];
+ $link = array();
+
+ $r0 = $ph->save($p);
+ $link[0] = array(
+ 'rel' => 'alternate',
+ 'type' => 'text/html',
+ 'href' => $url = rawurlencode(z_root() . '/photo/' . $photo_hash . '-0.' . $ph->getExt()),
+ 'width' => $ph->getWidth(),
+ 'height' => $ph->getHeight()
+ );
+ if(! $r0)
+ $errors = true;
+
+ unset($p['os_storage']);
+ unset($p['os_path']);
+
+ if(($width > 1024 || $height > 1024) && (! $errors))
+ $ph->scaleImage(1024);
+
+ $p['scale'] = 1;
$r1 = $ph->save($p);
+ $link[1] = array(
+ 'rel' => 'alternate',
+ 'type' => 'text/html',
+ 'href' => $url = rawurlencode(z_root() . '/photo/' . $photo_hash . '-1.' . $ph->getExt()),
+ 'width' => $ph->getWidth(),
+ 'height' => $ph->getHeight()
+ );
if(! $r1)
$errors = true;
-
- if(($width > 640 || $height > 640) && (! $errors)) {
+
+ if(($width > 640 || $height > 640) && (! $errors))
$ph->scaleImage(640);
- $p['scale'] = 1;
- $r2 = $ph->save($p);
- $smallest = 1;
- if(! $r2)
- $errors = true;
- }
- if(($width > 320 || $height > 320) && (! $errors)) {
+ $p['scale'] = 2;
+ $r2 = $ph->save($p);
+ $link[2] = array(
+ 'rel' => 'alternate',
+ 'type' => 'text/html',
+ 'href' => $url = rawurlencode(z_root() . '/photo/' . $photo_hash . '-2.' . $ph->getExt()),
+ 'width' => $ph->getWidth(),
+ 'height' => $ph->getHeight()
+ );
+ if(! $r2)
+ $errors = true;
+
+ if(($width > 320 || $height > 320) && (! $errors))
$ph->scaleImage(320);
- $p['scale'] = 2;
- $r3 = $ph->save($p);
- $smallest = 2;
- if(! $r3)
- $errors = true;
- }
+
+ $p['scale'] = 3;
+ $r3 = $ph->save($p);
+ $link[3] = array(
+ 'rel' => 'alternate',
+ 'type' => 'text/html',
+ 'href' => $url = rawurlencode(z_root() . '/photo/' . $photo_hash . '-3.' . $ph->getExt()),
+ 'width' => $ph->getWidth(),
+ 'height' => $ph->getHeight()
+ );
+ if(! $r3)
+ $errors = true;
if($errors) {
q("delete from photo where resource_id = '%s' and uid = %d",
@@ -202,13 +260,7 @@ function photo_upload($channel, $observer, $args) {
return $ret;
}
- // This will be the width and height of the smallest representation
-
- $width_x_height = $ph->getWidth() . 'x' . $ph->getHeight();
-
- $mid = item_message_id();
-
- // Create item container
+ $item_hidden = (($visible) ? 0 : 1 );
$lat = $lon = null;
@@ -219,66 +271,138 @@ function photo_upload($channel, $observer, $args) {
}
}
- $item_flags = ITEM_WALL|ITEM_ORIGIN|ITEM_THREAD_TOP;
- $item_restrict = (($visible) ? ITEM_VISIBLE : ITEM_HIDDEN);
- $title = '';
- $mid = item_message_id();
+ $title = (($args['description']) ? $args['description'] : $args['filename']);
+
+ $large_photos = feature_enabled($channel['channel_id'], 'large_photos');
+
+ linkify_tags($a, $args['body'], $channel_id);
+
+ if($large_photos) {
+ $scale = 1;
+ $width = $link[1]['width'];
+ $height = $link[1]['height'];
+ $tag = (($r1) ? '[zmg=' . $width . 'x' . $height . ']' : '[zmg]');
- $arr = array();
- if($lat && $lon)
- $arr['coord'] = $lat . ' ' . $lon;
-
- $arr['aid'] = $account_id;
- $arr['uid'] = $channel_id;
- $arr['mid'] = $mid;
- $arr['parent_mid'] = $mid;
- $arr['item_flags'] = $item_flags;
- $arr['item_restrict'] = $item_restrict;
- $arr['resource_type'] = 'photo';
- $arr['resource_id'] = $photo_hash;
- $arr['owner_xchan'] = $channel['channel_hash'];
- $arr['author_xchan'] = $observer['xchan_hash'];
- $arr['title'] = $title;
- $arr['allow_cid'] = $str_contact_allow;
- $arr['allow_gid'] = $str_group_allow;
- $arr['deny_cid'] = $str_contact_deny;
- $arr['deny_gid'] = $str_group_deny;
- $arr['verb'] = ACTIVITY_POST;
-
- $arr['plink'] = z_root() . '/channel/' . $channel['channel_address'] . '/?f=&mid=' . $arr['mid'];
-
- // We should also put a width_x_height on large photos. Left as an exercise for
- // devs looking fo simple stuff to fix.
-
- $larger = feature_enabled($channel['channel_id'], 'large_photos');
- if($larger) {
- $tag = '[zmg]';
- if($r2)
- $smallest = 1;
- else
- $smallest = 0;
}
else {
- if ($width_x_height)
- $tag = '[zmg=' . $width_x_height. ']';
- else
- $tag = '[zmg]';
+ $scale = 2;
+ $width = $link[2]['width'];
+ $height = $link[2]['height'];
+ $tag = (($r2) ? '[zmg=' . $width . 'x' . $height . ']' : '[zmg]');
}
- $arr['body'] = '[zrl=' . z_root() . '/photos/' . $channel['channel_address'] . '/image/' . $photo_hash . ']'
- . $tag . z_root() . "/photo/{$photo_hash}-{$smallest}.".$ph->getExt() . '[/zmg]'
- . '[/zrl]';
+ $body = '[zrl=' . z_root() . '/photos/' . $channel['channel_address'] . '/image/' . $photo_hash . ']'
+ . $tag . z_root() . "/photo/{$photo_hash}-{$scale}." . $ph->getExt() . '[/zmg]'
+ . '[/zrl]';
- $result = item_store($arr);
- $item_id = $result['item_id'];
+ // 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
+ );
- if($visible)
- proc_run('php', "include/notifier.php", 'wall-new', $item_id);
+ // Create item container
+ if($args['item']) {
+ foreach($args['item'] as $i) {
+
+ $item = get_item_elements($i);
+ $force = false;
+
+ 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) : '');
+
+ if($item['author_xchan'] === $channel['channel_hash']) {
+ $item['sig'] = base64url_encode(rsa_sign($item['body'],$channel['channel_prvkey']));
+ $item['item_verified'] = 1;
+ }
+ else {
+ $item['sig'] = '';
+ }
+ $force = true;
+
+ }
+ $r = q("select id, edited from item where mid = '%s' and uid = %d limit 1",
+ dbesc($item['mid']),
+ intval($channel['channel_id'])
+ );
+ if($r) {
+ if(($item['edited'] > $r[0]['edited']) || $force) {
+ $item['id'] = $r[0]['id'];
+ $item['uid'] = $channel['channel_id'];
+ item_store_update($item);
+ continue;
+ }
+ }
+ else {
+ $item['aid'] = $channel['channel_account_id'];
+ $item['uid'] = $channel['channel_id'];
+ $item_result = item_store($item);
+ }
+ }
+ }
+ else {
+ $mid = item_message_id();
+
+ $arr = array();
+
+ if($lat && $lon)
+ $arr['coord'] = $lat . ' ' . $lon;
+
+ $arr['aid'] = $account_id;
+ $arr['uid'] = $channel_id;
+ $arr['mid'] = $mid;
+ $arr['parent_mid'] = $mid;
+ $arr['item_hidden'] = $item_hidden;
+ $arr['resource_type'] = 'photo';
+ $arr['resource_id'] = $photo_hash;
+ $arr['owner_xchan'] = $channel['channel_hash'];
+ $arr['author_xchan'] = $observer['xchan_hash'];
+ $arr['title'] = $title;
+ $arr['allow_cid'] = $ac['allow_cid'];
+ $arr['allow_gid'] = $ac['allow_gid'];
+ $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['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']);
+
+
+ // this one is tricky because the item and the photo have the same permissions, those of the photo.
+ // Use the channel read_stream permissions to get the correct public_policy for the item and recalculate the
+ // private flag accordingly. This may cause subtle bugs due to custom permissions roles. We want to use
+ // public policy when federating items to other sites, but should probably ignore them when accessing the item
+ // in the photos pages - using the photos permissions instead. We need the public policy to keep the photo
+ // linked item from leaking into the feed when somebody has a channel with read_stream restrictions.
+
+ $arr['public_policy'] = map_scope($channel['channel_r_stream'],true);
+ if($arr['public_policy'])
+ $arr['item_private'] = 1;
+
+
+
+ $result = item_store($arr);
+ $item_id = $result['item_id'];
+
+ if($visible)
+ proc_run('php', "include/notifier.php", 'wall-new', $item_id);
+ }
$ret['success'] = true;
$ret['item'] = $arr;
- $ret['body'] = $arr['body'];
+ $ret['body'] = $body;
$ret['resource_id'] = $photo_hash;
$ret['photoitem_id'] = $item_id;
@@ -294,7 +418,7 @@ function photo_upload($channel, $observer, $args) {
*
* @param array $channel
* @param array $observer
- * @return bool|array false if no view_photos permission or an array
+ * @return bool|array false if no view_storage permission or an array
* * success (bool)
* * albums (array)
*/
@@ -303,14 +427,14 @@ function photos_albums_list($channel, $observer) {
$channel_id = $channel['channel_id'];
$observer_xchan = (($observer) ? $observer['xchan_hash'] : '');
- if(! perm_is_allowed($channel_id, $observer_xchan, 'view_photos'))
+ if(! perm_is_allowed($channel_id, $observer_xchan, 'view_storage'))
return false;
/** @FIXME create a permissions SQL which works on arbitrary observers and channels, regardless of login or web status */
$sql_extra = permissions_sql($channel_id);
- $albums = q("SELECT count( distinct resource_id ) as total, album from photo where uid = %d and ( photo_flags = %d or photo_flags = %d ) $sql_extra group by album order by max(created) desc",
+ $albums = q("SELECT count( distinct resource_id ) as total, album from photo where uid = %d and photo_usage IN ( %d, %d ) $sql_extra group by album order by max(created) desc",
intval($channel_id),
intval(PHOTO_NORMAL),
intval(PHOTO_PROFILE)
@@ -325,7 +449,7 @@ function photos_albums_list($channel, $observer) {
$ret['albums'] = array();
foreach($albums as $k => $album) {
$entry = array(
- 'text' => $album['album'],
+ 'text' => (($album['album']) ? $album['album'] : '/'),
'total' => $album['total'],
'url' => z_root() . '/photos/' . $channel['channel_address'] . '/album/' . bin2hex($album['album']),
'urlencode' => urlencode($album['album']),
@@ -359,7 +483,7 @@ function photos_album_widget($channelx,$observer,$albums = null) {
'$title' => t('Photo Albums'),
'$albums' => $albums['albums'],
'$baseurl' => z_root(),
- '$upload' => ((perm_is_allowed($channelx['channel_id'],(($observer) ? $observer['xchan_hash'] : ''),'post_photos'))
+ '$upload' => ((perm_is_allowed($channelx['channel_id'],(($observer) ? $observer['xchan_hash'] : ''),'write_storage'))
? t('Upload New Photos') : '')
));
}
@@ -380,7 +504,7 @@ function photos_list_photos($channel, $observer, $album = '') {
$channel_id = $channel['channel_id'];
$observer_xchan = (($observer) ? $observer['xchan_hash'] : '');
- if(! perm_is_allowed($channel_id,$observer_xchan,'view_photos'))
+ if(! perm_is_allowed($channel_id,$observer_xchan,'view_storage'))
return false;
$sql_extra = permissions_sql($channel_id);
@@ -390,7 +514,7 @@ function photos_list_photos($channel, $observer, $album = '') {
$ret = array('success' => false);
- $r = q("select resource_id, created, edited, title, description, album, filename, type, height, width, size, scale, profile, photo_flags, allow_cid, allow_gid, deny_cid, deny_gid from photo where uid = %d and ( photo_flags = %d or photo_flags = %d ) $sql_extra ",
+ $r = q("select resource_id, created, edited, title, description, album, filename, type, height, width, size, scale, photo_usage, allow_cid, allow_gid, deny_cid, deny_gid from photo where uid = %d and photo_usage in ( %d, %d ) $sql_extra ",
intval($channel_id),
intval(PHOTO_NORMAL),
intval(PHOTO_PROFILE)
@@ -488,32 +612,34 @@ function photos_create_item($channel, $creator_hash, $photo, $visible = false) {
// Create item container
- $item_flags = ITEM_WALL|ITEM_ORIGIN|ITEM_THREAD_TOP;
- $item_restrict = (($visible) ? ITEM_VISIBLE : ITEM_HIDDEN);
+
+ $item_hidden = (($visible) ? 0 : 1 );
$mid = item_message_id();
$arr = array();
- $arr['aid'] = $channel['channel_account_id'];
- $arr['uid'] = $channel['channel_id'];
- $arr['mid'] = $mid;
- $arr['parent_mid'] = $mid;
- $arr['item_flags'] = $item_flags;
- $arr['item_restrict'] = $item_restrict;
- $arr['resource_type'] = 'photo';
- $arr['resource_id'] = $photo['resource_id'];
- $arr['owner_xchan'] = $channel['channel_hash'];
- $arr['author_xchan'] = $creator_hash;
-
- $arr['allow_cid'] = $photo['allow_cid'];
- $arr['allow_gid'] = $photo['allow_gid'];
- $arr['deny_cid'] = $photo['deny_cid'];
- $arr['deny_gid'] = $photo['deny_gid'];
-
- $arr['plink'] = z_root() . '/channel/' . $channel['channel_address'] . '/?f=&mid=' . $arr['mid'];
-
- $arr['body'] = '[zrl=' . z_root() . '/photos/' . $channel['channel_address'] . '/image/' . $photo['resource_id'] . ']'
+ $arr['aid'] = $channel['channel_account_id'];
+ $arr['uid'] = $channel['channel_id'];
+ $arr['mid'] = $mid;
+ $arr['parent_mid'] = $mid;
+ $arr['item_wall'] = 1;
+ $arr['item_origin'] = 1;
+ $arr['item_thread_top'] = 1;
+ $arr['item_hidden'] = $item_hidden;
+ $arr['resource_type'] = 'photo';
+ $arr['resource_id'] = $photo['resource_id'];
+ $arr['owner_xchan'] = $channel['channel_hash'];
+ $arr['author_xchan'] = $creator_hash;
+
+ $arr['allow_cid'] = $photo['allow_cid'];
+ $arr['allow_gid'] = $photo['allow_gid'];
+ $arr['deny_cid'] = $photo['deny_cid'];
+ $arr['deny_gid'] = $photo['deny_gid'];
+
+ $arr['plink'] = z_root() . '/channel/' . $channel['channel_address'] . '/?f=&mid=' . $arr['mid'];
+
+ $arr['body'] = '[zrl=' . z_root() . '/photos/' . $channel['channel_address'] . '/image/' . $photo['resource_id'] . ']'
. '[zmg]' . z_root() . '/photo/' . $photo['resource_id'] . '-' . $photo['scale'] . '[/zmg]'
. '[/zrl]';
@@ -535,6 +661,16 @@ function getGps($exifCoord, $hemi) {
return floatval($flip * ($degrees + ($minutes / 60) + ($seconds / 3600)));
}
+function getGpstimestamp($exifCoord) {
+
+ $hours = count($exifCoord) > 0 ? gps2Num($exifCoord[0]) : 0;
+ $minutes = count($exifCoord) > 1 ? gps2Num($exifCoord[1]) : 0;
+ $seconds = count($exifCoord) > 2 ? gps2Num($exifCoord[2]) : 0;
+
+ return sprintf('%02d:%02d:%02d',$hours,$minutes,$seconds);
+}
+
+
function gps2Num($coordPart) {
$parts = explode('/', $coordPart);
diff --git a/include/plugin.php b/include/plugin.php
index 4d8405b62..8749f3fbf 100755
--- a/include/plugin.php
+++ b/include/plugin.php
@@ -504,18 +504,21 @@ function script_path() {
$scheme = 'https';
else
$scheme = 'http';
+
+ // Some proxy setups may require using http_host
- if(x($_SERVER,'SERVER_NAME')) {
- $hostname = $_SERVER['SERVER_NAME'];
+ if(intval(get_app()->config['system']['script_path_use_http_host']))
+ $server_var = 'HTTP_HOST';
+ else
+ $server_var = 'SERVER_NAME';
+
+
+ if(x($_SERVER,$server_var)) {
+ $hostname = $_SERVER[$server_var];
}
else {
return z_root();
}
-
- if(x($_SERVER,'SERVER_PORT') && $_SERVER['SERVER_PORT'] != 80 && $_SERVER['SERVER_PORT'] != 443) {
- $hostname .= ':' . $_SERVER['SERVER_PORT'];
- }
-
return $scheme . '://' . $hostname;
}
diff --git a/include/poller.php b/include/poller.php
index bc48c3f00..031fb4533 100644
--- a/include/poller.php
+++ b/include/poller.php
@@ -59,10 +59,9 @@ function poller_run($argv, $argc){
// expire any expired items
$r = q("select id from item where expires != '%s' and expires < %s
- and ( item_restrict & %d ) = 0 ",
+ and item_deleted = 0 ",
dbesc(NULL_DATE),
- db_utcnow(),
- intval(ITEM_DELETED)
+ db_utcnow()
);
if($r) {
require_once('include/items.php');
@@ -91,15 +90,13 @@ function poller_run($argv, $argc){
// (time travel posts). Restrict to items that have come of age in the last
// couple of days to limit the query to something reasonable.
- $r = q("select id from item where ( item_restrict & %d ) > 0 and created <= %s and created > '%s' ",
- intval(ITEM_DELAYED_PUBLISH),
+ $r = q("select id from item where item_delayed = 1 and created <= %s and created > '%s' ",
db_utcnow(),
dbesc(datetime_convert('UTC','UTC','now - 2 days'))
);
if($r) {
foreach($r as $rr) {
- $x = q("update item set item_restrict = ( item_restrict & ~%d ) where id = %d",
- intval(ITEM_DELAYED_PUBLISH),
+ $x = q("update item set item_delayed = 0 where id = %d",
intval($rr['id'])
);
if($x) {
@@ -178,6 +175,12 @@ function poller_run($argv, $argc){
logger('regdir: ' . print_r(z_fetch_url(get_directory_primary() . '/regdir?f=&url=' . urlencode(z_root()) . '&realm=' . urlencode(get_directory_realm())),true));
}
+ // Check for dead sites
+ proc_run('php', 'include/checksites.php');
+
+ // update searchable doc indexes
+ proc_run('php', 'include/importdoc.php');
+
/**
* End Cron Weekly
*/
@@ -198,6 +201,17 @@ function poller_run($argv, $argc){
db_utcnow(), db_quoteinterval('30 DAY')
);
+ // expire old delivery reports
+
+ $keep_reports = intval(get_config('system','expire_delivery_reports'));
+ if($keep_reports === 0)
+ $keep_reports = 30;
+
+ q("delete from dreport where dreport_time < %s - INTERVAL %s",
+ db_utcnow(),
+ db_quoteinterval($keep_reports . ' DAY')
+ );
+
// expire any expired accounts
downgrade_accounts();
@@ -235,7 +249,7 @@ function poller_run($argv, $argc){
if($r) {
require_once('include/photo/photo_driver.php');
foreach($r as $rr) {
- $photos = import_profile_photo($rr['xchan_photo_l'],$rr['xchan_hash']);
+ $photos = import_xchan_photo($rr['xchan_photo_l'],$rr['xchan_hash']);
$x = q("update xchan set xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s'
where xchan_hash = '%s'",
dbesc($photos[0]),
@@ -296,13 +310,11 @@ function poller_run($argv, $argc){
$randfunc = db_getfunc('RAND');
- $contacts = q("SELECT abook_id, abook_flags, abook_updated, abook_connected, abook_closeness, abook_xchan, abook_channel, xchan_network
- FROM abook LEFT JOIN xchan on abook_xchan = xchan_hash LEFT JOIN account on abook_account = account_id
+ $contacts = q("SELECT * FROM abook LEFT JOIN xchan on abook_xchan = xchan_hash
+ LEFT JOIN account on abook_account = account_id
+ where abook_self = 0
$sql_extra
- AND (( abook_flags & %d ) > 0 OR ( abook_flags = %d ))
AND (( account_flags = %d ) OR ( account_flags = %d )) $abandon_sql ORDER BY $randfunc",
- intval(ABOOK_FLAG_HIDDEN|ABOOK_FLAG_PENDING|ABOOK_FLAG_UNCONNECTED|ABOOK_FLAG_FEED),
- intval(0),
intval(ACCOUNT_OK),
intval(ACCOUNT_UNVERIFIED) // FIXME
@@ -312,15 +324,12 @@ function poller_run($argv, $argc){
foreach($contacts as $contact) {
- if($contact['abook_flags'] & ABOOK_FLAG_SELF)
- continue;
-
$update = false;
$t = $contact['abook_updated'];
$c = $contact['abook_connected'];
- if($contact['abook_flags'] & ABOOK_FLAG_FEED) {
+ if(intval($contact['abook_feed'])) {
$min = service_class_fetch($contact['abook_channel'],'minimum_feedcheck_minutes');
if(! $min)
$min = intval(get_config('system','minimum_feedcheck_minutes'));
@@ -359,15 +368,14 @@ function poller_run($argv, $argc){
// He's dead, Jim
if(strcmp(datetime_convert('UTC','UTC', 'now'),datetime_convert('UTC','UTC', $c . " + 30 day")) > 0) {
- $r = q("update abook set abook_flags = (abook_flags | %d) where abook_id = %d",
- intval(ABOOK_FLAG_ARCHIVED),
+ $r = q("update abook set abook_archived = 1 where abook_id = %d",
intval($contact['abook_id'])
);
$update = false;
continue;
}
- if($contact['abook_flags'] & ABOOK_FLAG_ARCHIVED) {
+ if(intval($contact['abook_archived'])) {
$update = false;
continue;
}
@@ -388,7 +396,7 @@ function poller_run($argv, $argc){
}
- if($contact['abook_flags'] & (ABOOK_FLAG_PENDING|ABOOK_FLAG_ARCHIVED|ABOOK_FLAG_IGNORED))
+ if(intval($contact['abook_pending']) || intval($contact['abook_archived']) || intval($contact['abook_ignored']) || intval($contact['abook_blocked']))
continue;
if((! $update) && (! $force))
diff --git a/include/queue.php b/include/queue.php
index 7d2ad3b2d..71ac50c83 100644
--- a/include/queue.php
+++ b/include/queue.php
@@ -22,6 +22,25 @@ function queue_run($argv, $argc){
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
+
+ $r = q("select outq_posturl from outq where outq_created < %s - INTERVAL %s",
+ db_utcnow(), db_quoteinterval('3 DAY')
+ );
+ if($r) {
+ foreach($r as $rr) {
+ $site_url = '';
+ $h = parse_url($rr['outq_posturl']);
+ $desturl = $h['scheme'] . '://' . $h['host'] . (($h['port']) ? ':' . $h['port'] : '');
+ q("update site set site_dead = 1 where site_dead = 0 and site_url = '%s' and site_update < %s - INTERVAL %s",
+ dbesc($desturl),
+ db_utcnow(), db_quoteinterval('1 MONTH')
+ );
+ }
+ }
+
$r = q("DELETE FROM outq WHERE outq_created < %s - INTERVAL %s",
db_utcnow(), db_quoteinterval('3 DAY')
);
@@ -69,15 +88,34 @@ 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['ouq_hash'])
+ dbesc($rr['outq_hash'])
);
}
else {
@@ -86,6 +124,7 @@ function queue_run($argv, $argc){
dbesc(datetime_convert()),
dbesc($rr['outq_hash'])
);
+ $deadguys[] = $rr['outq_posturl'];
}
continue;
}
diff --git a/include/reddav.php b/include/reddav.php
index 750ca1b24..c592597a9 100644
--- a/include/reddav.php
+++ b/include/reddav.php
@@ -1,7 +1,7 @@
<?php
/**
* @file include/reddav.php
- * @brief some DAV related functions for RedMatrix.
+ * @brief some DAV related functions for Hubzilla.
*
* This file contains some functions which did not fit into one of the RedDAV
* classes.
@@ -42,8 +42,7 @@ require_once('include/RedDAV/RedBasicAuth.php');
function RedChannelList(&$auth) {
$ret = array();
- $r = q("SELECT channel_id, channel_address FROM channel WHERE NOT (channel_pageflags & %d)>0 AND NOT (channel_pageflags & %d)>0",
- intval(PAGE_REMOVED),
+ $r = q("SELECT channel_id, channel_address FROM channel WHERE channel_removed = 0 AND channel_system = 0 AND NOT (channel_pageflags & %d)>0",
intval(PAGE_HIDDEN)
);
@@ -115,20 +114,18 @@ function RedCollectionData($file, &$auth) {
$permission_error = false;
for ($x = 1; $x < count($path_arr); $x++) {
- $r = q("SELECT id, hash, filename, flags FROM attach WHERE folder = '%s' AND filename = '%s' AND uid = %d AND (flags & %d)>0 $perms LIMIT 1",
+ $r = q("SELECT id, hash, filename, flags, is_dir FROM attach WHERE folder = '%s' AND filename = '%s' AND uid = %d AND is_dir != 0 $perms LIMIT 1",
dbesc($folder),
dbesc($path_arr[$x]),
- intval($channel_id),
- intval(ATTACH_FLAG_DIR)
+ intval($channel_id)
);
if (! $r) {
// path wasn't found. Try without permissions to see if it was the result of permissions.
$errors = true;
- $r = q("select id, hash, filename, flags from attach where folder = '%s' and filename = '%s' and uid = %d and (flags & %d)>0 limit 1",
+ $r = q("select id, hash, filename, flags, is_dir from attach where folder = '%s' and filename = '%s' and uid = %d and is_dir != 0 limit 1",
dbesc($folder),
basename($path_arr[$x]),
- intval($channel_id),
- intval(ATTACH_FLAG_DIR)
+ intval($channel_id)
);
if ($r) {
$permission_error = true;
@@ -136,7 +133,7 @@ function RedCollectionData($file, &$auth) {
break;
}
- if ($r && ($r[0]['flags'] & ATTACH_FLAG_DIR)) {
+ if ($r && intval($r[0]['is_dir'])) {
$folder = $r[0]['hash'];
$path = $path . '/' . $r[0]['filename'];
}
@@ -162,18 +159,17 @@ function RedCollectionData($file, &$auth) {
$prefix = '';
$suffix = 'GROUP BY filename';
}
- $r = q("select $prefix id, uid, hash, filename, filetype, filesize, revision, folder, flags, created, edited from attach where folder = '%s' and uid = %d $perms $suffix",
+ $r = q("select $prefix id, uid, hash, filename, filetype, filesize, revision, folder, flags, is_dir, created, edited from attach where folder = '%s' and uid = %d $perms $suffix",
dbesc($folder),
intval($channel_id)
);
foreach ($r as $rr) {
//logger('filename: ' . $rr['filename'], LOGGER_DEBUG);
- if ($rr['flags'] & ATTACH_FLAG_DIR) {
- // @todo can't we drop '/cloud'? it gets stripped off anyway in RedDirectory
- $ret[] = new RedDAV\RedDirectory('/cloud' . $path . '/' . $rr['filename'], $auth);
+ if (intval($rr['is_dir'])) {
+ $ret[] = new RedDAV\RedDirectory($path . '/' . $rr['filename'], $auth);
} else {
- $ret[] = new RedDAV\RedFile('/cloud' . $path . '/' . $rr['filename'], $rr, $auth);
+ $ret[] = new RedDAV\RedFile($path . '/' . $rr['filename'], $rr, $auth);
}
}
@@ -200,6 +196,12 @@ function RedFileData($file, &$auth, $test = false) {
if ($x === 0) {
$file = substr($file, 6);
}
+ else {
+ $x = strpos($file,'/dav');
+ if($x === 0)
+ $file = substr($file,4);
+ }
+
if ((! $file) || ($file === '/')) {
return new RedDAV\RedDirectory('/', $auth);
@@ -237,19 +239,18 @@ function RedFileData($file, &$auth, $test = false) {
$errors = false;
for ($x = 1; $x < count($path_arr); $x++) {
- $r = q("select id, hash, filename, flags from attach where folder = '%s' and filename = '%s' and uid = %d and (flags & %d)>0 $perms",
+ $r = q("select id, hash, filename, flags, is_dir from attach where folder = '%s' and filename = '%s' and uid = %d and is_dir != 0 $perms",
dbesc($folder),
dbesc($path_arr[$x]),
- intval($channel_id),
- intval(ATTACH_FLAG_DIR)
+ intval($channel_id)
);
- if ($r && ( $r[0]['flags'] & ATTACH_FLAG_DIR)) {
+ if ($r && intval($r[0]['is_dir'])) {
$folder = $r[0]['hash'];
$path = $path . '/' . $r[0]['filename'];
}
if (! $r) {
- $r = q("select id, uid, hash, filename, filetype, filesize, revision, folder, flags, created, edited from attach
+ $r = q("select id, uid, hash, filename, filetype, filesize, revision, folder, flags, is_dir, os_storage, created, edited from attach
where folder = '%s' and filename = '%s' and uid = %d $perms order by filename limit 1",
dbesc($folder),
dbesc(basename($file)),
@@ -258,7 +259,7 @@ function RedFileData($file, &$auth, $test = false) {
}
if (! $r) {
$errors = true;
- $r = q("select id, uid, hash, filename, filetype, filesize, revision, folder, flags, created, edited from attach
+ $r = q("select id, uid, hash, filename, filetype, filesize, revision, folder, flags, is_dir, os_storage, created, edited from attach
where folder = '%s' and filename = '%s' and uid = %d order by filename limit 1",
dbesc($folder),
dbesc(basename($file)),
@@ -273,7 +274,7 @@ function RedFileData($file, &$auth, $test = false) {
if ($test)
return true;
// final component was a directory.
- return new RedDAV\RedDirectory('/cloud/' . $file, $auth);
+ return new RedDAV\RedDirectory($file, $auth);
}
if ($errors) {
@@ -291,11 +292,10 @@ function RedFileData($file, &$auth, $test = false) {
if ($test)
return true;
- if ($r[0]['flags'] & ATTACH_FLAG_DIR) {
- // @todo can't we drop '/cloud'? it gets stripped off anyway in RedDirectory
- return new RedDAV\RedDirectory('/cloud' . $path . '/' . $r[0]['filename'], $auth);
+ if (intval($r[0]['is_dir'])) {
+ return new RedDAV\RedDirectory($path . '/' . $r[0]['filename'], $auth);
} else {
- return new RedDAV\RedFile('/cloud' . $path . '/' . $r[0]['filename'], $r[0], $auth);
+ return new RedDAV\RedFile($path . '/' . $r[0]['filename'], $r[0], $auth);
}
}
return false;
diff --git a/include/security.php b/include/security.php
index 0c3dc29d6..9a25d9e0e 100644
--- a/include/security.php
+++ b/include/security.php
@@ -71,9 +71,8 @@ function authenticate_success($user_record, $login_initial = false, $interactive
/* This account has never created a channel. Send them to new_channel by default */
if($a->module === 'login') {
- $r = q("select count(channel_id) as total from channel where channel_account_id = %d and not ( channel_pageflags & %d)>0",
- intval($a->account['account_id']),
- intval(PAGE_REMOVED)
+ $r = q("select count(channel_id) as total from channel where channel_account_id = %d and channel_removed = 0 ",
+ intval($a->account['account_id'])
);
if(($r) && (! $r[0]['total']))
goaway(z_root() . '/new_channel');
@@ -94,20 +93,17 @@ 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 not ( channel_pageflags & %d)>0 limit 1",
+ $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()),
- intval(PAGE_REMOVED)
+ intval(get_account_id())
);
// It's not there. Is this an administrator, and is this the sys channel?
if (is_developer()) {
if (! $r) {
if (is_site_admin()) {
- $r = q("select channel.*, xchan.* from channel left join xchan on channel.channel_hash = xchan.xchan_hash where channel_id = %d and ( channel_pageflags & %d) and not (channel_pageflags & %d )>0 limit 1",
- intval($change_channel),
- intval(PAGE_SYSTEM),
- intval(PAGE_REMOVED)
+ $r = q("select channel.*, xchan.* from channel left join xchan on channel.channel_hash = xchan.xchan_hash where channel_id = %d and channel_system = 1 and channel_removed = 0 limit 1",
+ intval($change_channel)
);
}
}
@@ -249,6 +245,9 @@ function item_permissions_sql($owner_id, $remote_observer = null) {
$observer = (($remote_observer) ? $remote_observer : get_observer_hash());
if($observer) {
+
+ $s = scopes_sql($owner_id,$observer);
+
$groups = init_groups_visitor($observer);
$gs = '<<>>'; // should be impossible to match
@@ -259,9 +258,9 @@ function item_permissions_sql($owner_id, $remote_observer = null) {
}
$regexop = db_getfunc('REGEXP');
$sql = sprintf(
- " AND ( NOT (deny_cid like '%s' OR deny_gid $regexop '%s')
- AND ( allow_cid like '%s' OR allow_gid $regexop '%s' OR ( allow_cid = '' AND allow_gid = '' AND item_private = 0 ) )
- )
+ " AND (( NOT (deny_cid like '%s' OR deny_gid $regexop '%s')
+ AND ( allow_cid like '%s' OR allow_gid $regexop '%s' OR ( allow_cid = '' AND allow_gid = '' AND item_private = 0 ))
+ ) OR ( item_private = 1 $s ))
",
dbesc(protect_sprintf( '%<' . $observer . '>%')),
dbesc($gs),
@@ -275,6 +274,39 @@ function item_permissions_sql($owner_id, $remote_observer = null) {
}
/**
+ * Remote visitors also need to be checked against the public_scope parameter if item_private is set.
+ * This function checks the various permutations of that field for any which apply to this observer.
+ *
+ */
+
+
+
+function scopes_sql($uid,$observer) {
+ $str = " and ( public_policy = 'authenticated' ";
+ if(! is_foreigner($observer))
+ $str .= " or public_policy = 'network: red' ";
+ if(local_channel())
+ $str .= " or public_policy = 'site: " . get_app()->get_hostname() . "' ";
+
+ $ab = q("select * from abook where abook_xchan = '%s' and abook_channel = %d limit 1",
+ dbesc($observer),
+ intval($uid)
+ );
+ if(! $ab)
+ return $str . " ) ";
+ if($ab[0]['abook_pending'])
+ $str .= " or public_policy = 'any connections' ";
+ $str .= " or public_policy = 'contacts' ) ";
+ return $str;
+}
+
+
+
+
+
+
+
+/**
* @param string $observer_hash
*
* @return string additional SQL where statement
@@ -404,9 +436,9 @@ function stream_perms_api_uids($perms = NULL, $limit = 0, $rand = 0 ) {
$random_sql = (($rand) ? " ORDER BY " . db_getfunc('RAND') . " " : '');
if(local_channel())
$ret[] = local_channel();
- $r = q("select channel_id from channel where channel_r_stream > 0 and ( channel_r_stream & %d )>0 and ( channel_pageflags & %d ) = 0 $random_sql $limit_sql ",
+ $r = q("select channel_id from channel where channel_r_stream > 0 and ( channel_r_stream & %d )>0 and ( channel_pageflags & %d ) = 0 and channel_system = 0 and channel_removed = 0 $random_sql $limit_sql ",
intval($perms),
- intval(PAGE_ADULT|PAGE_CENSORED|PAGE_SYSTEM|PAGE_REMOVED)
+ intval(PAGE_ADULT|PAGE_CENSORED)
);
if($r) {
foreach($r as $rr)
@@ -437,9 +469,9 @@ function stream_perms_xchans($perms = NULL ) {
if(local_channel())
$ret[] = get_observer_hash();
- $r = q("select channel_hash from channel where channel_r_stream > 0 and (channel_r_stream & %d)>0 and not (channel_pageflags & %d)>0",
+ $r = q("select channel_hash from channel where channel_r_stream > 0 and (channel_r_stream & %d)>0 and not (channel_pageflags & %d)>0 and channel_system = 0 and channel_removed = 0 ",
intval($perms),
- intval(PAGE_ADULT|PAGE_CENSORED|PAGE_SYSTEM|PAGE_REMOVED)
+ intval(PAGE_ADULT|PAGE_CENSORED)
);
if($r) {
foreach($r as $rr)
diff --git a/include/session.php b/include/session.php
index 31b3f0614..92004bc18 100644
--- a/include/session.php
+++ b/include/session.php
@@ -98,9 +98,6 @@ function ref_session_destroy ($id) {
function ref_session_gc($expire) {
q("DELETE FROM session WHERE expire < %d", dbesc(time()));
- if (! get_config('system', 'innodb'))
- db_optimizetable('session');
-
return true;
}
diff --git a/include/socgraph.php b/include/socgraph.php
index 0ad7c4034..e44a8ea9a 100644
--- a/include/socgraph.php
+++ b/include/socgraph.php
@@ -40,7 +40,7 @@ function poco_load($xchan = '', $url = null) {
return;
}
- $url = $url . '?f=&fields=displayName,hash,urls,photos,rating' ;
+ $url = $url . '?f=&fields=displayName,hash,urls,photos' ;
logger('poco_load: ' . $url, LOGGER_DEBUG);
@@ -115,8 +115,6 @@ function poco_load($xchan = '', $url = null) {
$name = $entry['displayName'];
$hash = $entry['hash'];
- $rating = ((array_key_exists('rating',$entry) && (! is_array($entry['rating']))) ? intval($entry['rating']) : 0);
- $rating_text = ((array_key_exists('rating_text',$entry)) ? escape_tags($entry['rating_text']) :'');
if(x($entry,'urls') && is_array($entry['urls'])) {
foreach($entry['urls'] as $url) {
@@ -214,7 +212,7 @@ function poco_load($xchan = '', $url = null) {
function count_common_friends($uid,$xchan) {
$r = q("SELECT count(xlink_id) as total from xlink where xlink_xchan = '%s' and xlink_static = 0 and xlink_link in
- (select abook_xchan from abook where abook_xchan != '%s' and abook_channel = %d and abook_flags = 0 )",
+ (select abook_xchan from abook where abook_xchan != '%s' and abook_channel = %d and abook_self = 0 )",
dbesc($xchan),
dbesc($xchan),
intval($uid)
@@ -235,7 +233,7 @@ function common_friends($uid,$xchan,$start = 0,$limit=100000000,$shuffle = false
$sql_extra = " order by xchan_name asc ";
$r = q("SELECT * from xchan left join xlink on xlink_link = xchan_hash where xlink_xchan = '%s' and xlink_static = 0 and xlink_link in
- (select abook_xchan from abook where abook_xchan != '%s' and abook_channel = %d and abook_flags = 0 ) $sql_extra limit %d offset %d",
+ (select abook_xchan from abook where abook_xchan != '%s' and abook_channel = %d and abook_self = 0 ) $sql_extra limit %d offset %d",
dbesc($xchan),
dbesc($xchan),
intval($uid),
@@ -329,15 +327,13 @@ function suggestion_query($uid, $myxchan, $start = 0, $limit = 80) {
and not xlink_link in ( select abook_xchan from abook where abook_channel = %d )
and not xlink_link in ( select xchan from xign where uid = %d )
and xlink_xchan != ''
+ and xchan_hidden = 0
+ and xchan_deleted = 0
and xlink_static = 0
- and not ( xchan_flags & %d )>0
- and not ( xchan_flags & %d )>0
group by xchan_hash order by total desc limit %d offset %d ",
intval($uid),
intval($uid),
intval($uid),
- intval(XCHAN_FLAGS_HIDDEN),
- intval(XCHAN_FLAGS_DELETED),
intval($limit),
intval($start)
);
@@ -350,14 +346,12 @@ function suggestion_query($uid, $myxchan, $start = 0, $limit = 80) {
where xlink_xchan = ''
and not xlink_link in ( select abook_xchan from abook where abook_channel = %d )
and not xlink_link in ( select xchan from xign where uid = %d )
+ and xchan_hidden = 0
+ and xchan_deleted = 0
and xlink_static = 0
- and not ( xchan_flags & %d )>0
- and not ( xchan_flags & %d )>0
group by xchan_hash order by total desc limit %d offset %d ",
intval($uid),
intval($uid),
- intval(XCHAN_FLAGS_HIDDEN),
- intval(XCHAN_FLAGS_DELETED),
intval($limit),
intval($start)
);
@@ -465,16 +459,16 @@ function poco($a,$extended = false) {
}
if($justme)
- $sql_extra = " and ( abook_flags & " . ABOOK_FLAG_SELF . " )>0 ";
+ $sql_extra = " and abook_self = 1 ";
else
- $sql_extra = " and abook_flags = 0 ";
+ $sql_extra = " and abook_self = 0 ";
if($cid)
- $sql_extra = sprintf(" and abook_id = %d and ( abook_flags & " . ABOOK_FLAG_HIDDEN . " ) = 0 ",intval($cid));
+ $sql_extra = sprintf(" and abook_id = %d and abook_hidden = 0 ",intval($cid));
if($system_mode) {
- $r = q("SELECT count(*) as `total` from abook where ( abook_flags & " . ABOOK_FLAG_SELF .
- " )>0 and abook_channel in (select uid from pconfig where cat = 'system' and k = 'suggestme' and v = '1') ");
+ $r = q("SELECT count(*) as `total` from abook where abook_self = 1
+ and abook_channel in (select uid from pconfig where cat = 'system' and k = 'suggestme' and v = '1') ");
}
else {
$r = q("SELECT count(*) as `total` from abook where abook_channel = %d
@@ -497,8 +491,9 @@ function poco($a,$extended = false) {
$itemsPerPage = ((x($_GET,'count') && intval($_GET['count'])) ? intval($_GET['count']) : $totalResults);
if($system_mode) {
- $r = q("SELECT abook.*, xchan.* from abook left join xchan on abook_xchan = xchan_hash where ( abook_flags & " . ABOOK_FLAG_SELF .
- " )>0 and abook_channel in (select uid from pconfig where cat = 'system' and k = 'suggestme' and v = '1') limit %d offset %d ",
+ $r = q("SELECT abook.*, xchan.* from abook left join xchan on abook_xchan = xchan_hash where abook_self = 1
+ and abook_channel in (select uid from pconfig where cat = 'system' and k = 'suggestme' and v = '1')
+ limit %d offset %d ",
intval($itemsPerPage),
intval($startIndex)
);
@@ -580,13 +575,6 @@ function poco($a,$extended = false) {
$entry['preferredUsername'] = substr($rr['xchan_addr'],0,strpos($rr['xchan_addr'],'@'));
if($fields_ret['photos'])
$entry['photos'] = array(array('value' => $rr['xchan_photo_l'], 'mimetype' => $rr['xchan_photo_mimetype'], 'type' => 'profile'));
- if($fields_ret['rating']) {
- $entry['rating'] = ((array_key_exists('abook_rating',$rr)) ? intval($rr['abook_rating']) : 0);
- $entry['rating_text'] = ((array_key_exists('abook_rating_text',$rr)) ? $rr['abook_rating_text'] : '');
- // maybe this should be a composite calculated rating in $system_mode
- if($system_mode)
- $entry['rating'] = 0;
- }
$ret['entry'][] = $entry;
}
}
@@ -609,4 +597,4 @@ function poco($a,$extended = false) {
else
http_status_exit(500);
-} \ No newline at end of file
+}
diff --git a/include/statistics_fns.php b/include/statistics_fns.php
index 288925a2c..ce2eee5e7 100644
--- a/include/statistics_fns.php
+++ b/include/statistics_fns.php
@@ -23,8 +23,7 @@ function update_channels_active_halfyear_stat() {
$s .= ',';
$s .= intval($rr['channel_id']);
}
- $x = q("select uid from item where uid in ( $s ) and (item_flags & %d)>0 and created > %s - INTERVAL %s group by uid",
- intval(ITEM_WALL),
+ $x = q("select uid from item where uid in ( $s ) and item_wall = 1 and created > %s - INTERVAL %s group by uid",
db_utcnow(), db_quoteinterval('6 MONTH')
);
if($x) {
@@ -50,8 +49,7 @@ function update_channels_active_monthly_stat() {
$s .= ',';
$s .= intval($rr['channel_id']);
}
- $x = q("select uid from item where uid in ( $s ) and ( item_flags & %d )>0 and created > %s - INTERVAL %s group by uid",
- intval(ITEM_WALL),
+ $x = q("select uid from item where uid in ( $s ) and item_wall = 1 and created > %s - INTERVAL %s group by uid",
db_utcnow(), db_quoteinterval('1 MONTH')
);
if($x) {
@@ -66,8 +64,7 @@ function update_channels_active_monthly_stat() {
}
function update_local_posts_stat() {
- $posts = q("SELECT COUNT(*) AS local_posts FROM `item` WHERE (item_flags & %d)>0 ",
- intval(ITEM_WALL) );
+ $posts = q("SELECT COUNT(*) AS local_posts FROM `item` WHERE item_wall = 1 ");
if (is_array($posts)) {
$local_posts_stat = intval($posts[0]["local_posts"]);
set_config('system','local_posts_stat',$local_posts_stat);
diff --git a/include/taxonomy.php b/include/taxonomy.php
index 36490291d..e68b9659f 100644
--- a/include/taxonomy.php
+++ b/include/taxonomy.php
@@ -101,7 +101,7 @@ function format_term_for_display($term) {
// Tag cloud functions - need to be adpated to this database format
-function tagadelic($uid, $count = 0, $authors = '', $flags = 0, $restrict = 0, $type = TERM_HASHTAG) {
+function tagadelic($uid, $count = 0, $authors = '', $owner = '', $flags = 0, $restrict = 0, $type = TERM_HASHTAG) {
require_once('include/security.php');
@@ -111,8 +111,10 @@ function tagadelic($uid, $count = 0, $authors = '', $flags = 0, $restrict = 0, $
$sql_options = item_permissions_sql($uid);
$count = intval($count);
- if($flags)
- $sql_options .= " and ((item_flags & " . intval($flags) . ") = " . intval($flags) . ") ";
+ if($flags) {
+ if($flags === 'wall')
+ $sql_options .= " and item_wall = 1 ";
+ }
if($authors) {
if(! is_array($authors))
@@ -122,10 +124,15 @@ function tagadelic($uid, $count = 0, $authors = '', $flags = 0, $restrict = 0, $
$sql_options .= " and author_xchan in (" . implode(',',$authors) . ") ";
}
+ if($owner) {
+ $sql_options .= " and owner_xchan = '" . dbesc($owner) . "' ";
+ }
+
+
// Fetch tags
$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_restrict = %d
+ and otype = %d and item_type = %d and item_private = 0
$sql_options
group by term order by total desc %s",
intval($uid),
@@ -213,10 +220,10 @@ function dir_tagadelic($count = 0) {
}
-function tagblock($link,$uid,$count = 0,$authors = '',$flags = 0,$restrict = 0,$type = TERM_HASHTAG) {
+function tagblock($link,$uid,$count = 0,$authors = '',$owner = '', $flags = 0,$restrict = 0,$type = TERM_HASHTAG) {
$o = '';
- $r = tagadelic($uid,$count,$authors,$flags,$restrict,$type);
+ $r = tagadelic($uid,$count,$authors,$owner, $flags,$restrict,$type);
if($r) {
$o = '<div class="tagblock widget"><h3>' . t('Tags') . '</h3><div class="tags" align="center">';
@@ -230,10 +237,10 @@ function tagblock($link,$uid,$count = 0,$authors = '',$flags = 0,$restrict = 0,$
}
-function wtagblock($uid,$count = 0,$authors = '',$flags = 0,$restrict = 0,$type = TERM_HASHTAG) {
+function wtagblock($uid,$count = 0,$authors = '',$owner = '', $flags = 0,$restrict = 0,$type = TERM_HASHTAG) {
$o = '';
- $r = tagadelic($uid,$count,$authors,$flags,$restrict,$type);
+ $r = tagadelic($uid,$count,$authors,$owner, $flags,$restrict,$type);
if($r) {
$c = q("select channel_address from channel where channel_id = %d limit 1",
@@ -251,10 +258,10 @@ function wtagblock($uid,$count = 0,$authors = '',$flags = 0,$restrict = 0,$type
}
-function catblock($uid,$count = 0,$authors = '',$flags = 0,$restrict = 0,$type = TERM_CATEGORY) {
+function catblock($uid,$count = 0,$authors = '',$owner = '', $flags = 0,$restrict = 0,$type = TERM_CATEGORY) {
$o = '';
- $r = tagadelic($uid,$count,$authors,$flags,$restrict,$type);
+ $r = tagadelic($uid,$count,$authors,$owner,$flags,$restrict,$type);
if($r) {
$c = q("select channel_address from channel where channel_id = %d limit 1",
@@ -334,7 +341,7 @@ function get_things($profile_hash,$uid) {
$sql_extra = (($profile_hash) ? " and obj_page = '" . $profile_hash . "' " : '');
- $r = q("select * from obj left join term on obj_obj = term_hash where term_hash != '' and uid = %d and obj_type = %d $sql_extra order by obj_verb, term",
+ $r = q("select * from obj where obj_channel = %d and obj_type = %d $sql_extra order by obj_verb, obj_term",
intval($uid),
intval(TERM_OBJ_THING)
);
@@ -350,8 +357,8 @@ function get_things($profile_hash,$uid) {
foreach($r as $rr) {
$rr['profile_name'] = '';
- if(! in_array($rr['term_hash'],$profile_hashes))
- $profile_hashes[] = $rr['term_hash'];
+ if(! in_array($rr['obj_obj'],$profile_hashes))
+ $profile_hashes[] = $rr['obj_obj'];
}
stringify_array_elms($profile_hashes);
if(! $profile_hash) {
@@ -383,7 +390,7 @@ function get_things($profile_hash,$uid) {
$l = q("select xchan_name, xchan_url from likes left join xchan on likee = xchan_hash where
target_type = '%s' and target_id = '%s' and channel_id = %d",
dbesc(ACTIVITY_OBJ_THING),
- dbesc($rr['term_hash']),
+ dbesc($rr['obj_obj']),
intval($uid)
);
@@ -393,7 +400,7 @@ function get_things($profile_hash,$uid) {
if(! $things[$rr['obj_verb']])
$things[$rr['obj_verb']] = array();
- $things[$rr['obj_verb']][] = array('term' => $rr['term'],'url' => $rr['url'],'img' => $rr['imgurl'], 'profile' => $rr['profile_name'],'term_hash' => $rr['term_hash'], 'likes' => $l,'like_count' => count($l),'like_label' => tt('Like','Likes',count($l),'noun'));
+ $things[$rr['obj_verb']][] = array('term' => $rr['obj_term'],'url' => $rr['obj_url'],'img' => $rr['obj_imgurl'], 'profile' => $rr['profile_name'],'term_hash' => $rr['obj_obj'], 'likes' => $l,'like_count' => count($l),'like_label' => tt('Like','Likes',count($l),'noun'));
}
$sorted_things = array();
if($things) {
diff --git a/include/text.php b/include/text.php
index e0c8d018e..c2573da0c 100644
--- a/include/text.php
+++ b/include/text.php
@@ -454,63 +454,7 @@ function alt_pager(&$a, $i, $more = '', $less = '') {
}
-/**
- * @brief Turn user/group ACLs stored as angle bracketed text into arrays.
- *
- * turn string array of angle-bracketed elements into string array
- * e.g. "<123xyz><246qyo><sxo33e>" => array(123xyz,246qyo,sxo33e);
- *
- * @param string $s
- * @return array
- */
-function expand_acl($s) {
- $ret = array();
-
- if(strlen($s)) {
- $t = str_replace('<','',$s);
- $a = explode('>',$t);
- foreach($a as $aa) {
- if($aa)
- $ret[] = $aa;
- }
- }
-
- return $ret;
-}
-
-/**
- * @brief Used to wrap ACL elements in angle brackets for storage.
- *
- * @param[in,out] array &$item
- */
-function sanitise_acl(&$item) {
- if (strlen($item))
- $item = '<' . notags(trim($item)) . '>';
- else
- unset($item);
-}
-
-/**
- * @brief Convert an ACL array to a storable string.
- *
- * @param array $p
- * @return array
- */
-function perms2str($p) {
- $ret = '';
- if (is_array($p))
- $tmp = $p;
- else
- $tmp = explode(',', $p);
-
- if (is_array($tmp)) {
- array_walk($tmp, 'sanitise_acl');
- $ret = implode('', $tmp);
- }
-
- return $ret;
-}
/**
* @brief Generate a guaranteed unique (for this domain) item ID for ATOM.
@@ -575,9 +519,9 @@ function attribute_contains($attr, $s) {
}
/**
- * @brief Logging function for RedMatrix.
+ * @brief Logging function for Hubzilla.
*
- * Logging output is configured through RedMatrix's system config. The log file
+ * Logging output is configured through Hubzilla's system config. The log file
* is set in system logfile, log level in system loglevel and to enable logging
* set system debugging.
*
@@ -743,7 +687,7 @@ function get_tags($s) {
// make sure the longer tags are returned first so that if two or more have common substrings
// we'll replace the longest ones first. Otherwise the common substring would be found in
// both strings and the string replacement would link both to the shorter strings and
- // fail to link the longer string. RedMatrix github issue #378
+ // fail to link the longer string. Hubzilla github issue #378
usort($ret,'tag_sort_length');
@@ -808,20 +752,21 @@ function contact_block() {
return;
$is_owner = ((local_channel() && local_channel() == $a->profile['uid']) ? true : false);
+ $sql_extra = '';
+
+ $abook_flags = " and abook_pending = 0 and abook_self = 0 ";
- $abook_flags = ABOOK_FLAG_PENDING|ABOOK_FLAG_SELF;
- $xchan_flags = XCHAN_FLAGS_ORPHAN|XCHAN_FLAGS_DELETED;
if(! $is_owner) {
- $abook_flags = $abook_flags | ABOOK_FLAG_HIDDEN;
- $xchan_flags = $xchan_flags | XCHAN_FLAGS_HIDDEN;
+ $abook_flags .= " and abook_hidden = 0 ";
+ $sql_extra = " and xchan_hidden = 0 ";
}
if((! is_array($a->profile)) || ($a->profile['hide_friends']))
return $o;
- $r = q("SELECT COUNT(abook_id) AS total FROM abook left join xchan on abook_xchan = xchan_hash WHERE abook_channel = %d and ( abook_flags & %d ) = 0 and ( xchan_flags & %d ) = 0",
- intval($a->profile['uid']),
- intval($abook_flags),
- intval($xchan_flags)
+
+ $r = q("SELECT COUNT(abook_id) AS total FROM abook left join xchan on abook_xchan = xchan_hash WHERE abook_channel = %d
+ $abook_flags and xchan_orphan = 0 and xchan_deleted = 0 $sql_extra",
+ intval($a->profile['uid'])
);
if(count($r)) {
$total = intval($r[0]['total']);
@@ -830,21 +775,19 @@ function contact_block() {
$contacts = t('No connections');
$micropro = null;
} else {
-
+
$randfunc = db_getfunc('RAND');
-
- $r = q("SELECT abook.*, xchan.* FROM abook left join xchan on abook.abook_xchan = xchan.xchan_hash WHERE abook_channel = %d AND ( abook_flags & %d ) = 0 and ( xchan_flags & %d ) = 0 ORDER BY $randfunc LIMIT %d",
- intval($a->profile['uid']),
- intval($abook_flags|ABOOK_FLAG_ARCHIVED),
- intval($xchan_flags),
- intval($shown)
+
+ $r = q("SELECT abook.*, xchan.* FROM abook left join xchan on abook.abook_xchan = xchan.xchan_hash WHERE abook_channel = %d $abook_flags and abook_archived = 0 and xchan_orphan = 0 and xchan_deleted = 0 $sql_extra ORDER BY $randfunc LIMIT %d",
+ intval($a->profile['uid']),
+ intval($shown)
);
if(count($r)) {
$contacts = sprintf( tt('%d Connection','%d Connections', $total),$total);
$micropro = Array();
foreach($r as $rr) {
- $rr['archived'] = (($rr['abook_flags'] & ABOOK_FLAG_ARCHIVED) ? true : false);
+ $rr['archived'] = (intval($rr['abook_archived']) ? true : false);
$micropro[] = micropro($rr,true,'mpfriend');
}
}
@@ -969,8 +912,17 @@ function sslify($s) {
if (strpos(z_root(),'https:') === false)
return $s;
+ // By default we'll only sslify img tags because media files will probably choke.
+ // You can set sslify_everything if you want - but it will likely white-screen if it hits your php memory limit.
+ // The downside is that http: media files will likely be blocked by your browser
+ // Complain to your browser maker
+
+ $allow = get_config('system','sslify_everything');
+
+ $pattern = (($allow) ? "/\<(.*?)src=\"(http\:.*?)\"(.*?)\>/" : "/\<img(.*?)src=\"(http\:.*?)\"(.*?)\>/" );
+
$matches = null;
- $cnt = preg_match_all("/\<(.*?)src=\"(http\:.*?)\"(.*?)\>/",$s,$matches,PREG_SET_ORDER);
+ $cnt = preg_match_all($pattern,$s,$matches,PREG_SET_ORDER);
if ($cnt) {
foreach ($matches as $match) {
$filename = basename( parse_url($match[2], PHP_URL_PATH) );
@@ -1241,17 +1193,16 @@ function link_compare($a, $b) {
function unobscure(&$item) {
- if(array_key_exists('item_flags',$item) && ($item['item_flags'] & ITEM_OBSCURED)) {
+ if(array_key_exists('item_obscured',$item) && intval($item['item_obscured'])) {
$key = get_config('system','prvkey');
if($item['title'])
$item['title'] = crypto_unencapsulate(json_decode_plus($item['title']),$key);
if($item['body'])
$item['body'] = crypto_unencapsulate(json_decode_plus($item['body']),$key);
if(get_config('system','item_cache')) {
- q("update item set title = '%s', body = '%s', item_flags = %d where id = %d",
+ q("update item set title = '%s', body = '%s', item_obscured = 0 where id = %d",
dbesc($item['title']),
dbesc($item['body']),
- intval($item['item_flags'] - ITEM_OBSCURED),
intval($item['id'])
);
}
@@ -1259,12 +1210,11 @@ function unobscure(&$item) {
}
function unobscure_mail(&$item) {
- if(array_key_exists('mail_flags',$item) && ($item['mail_flags'] & MAIL_OBSCURED)) {
- $key = get_config('system','prvkey');
+ if(array_key_exists('mail_obscured',$item) && intval($item['mail_obscured'])) {
if($item['title'])
- $item['title'] = crypto_unencapsulate(json_decode_plus($item['title']),$key);
+ $item['title'] = base64url_decode(str_rot47($item['title']));
if($item['body'])
- $item['body'] = crypto_unencapsulate(json_decode_plus($item['body']),$key);
+ $item['body'] = base64url_decode(str_rot47($item['body']));
}
}
@@ -1275,36 +1225,15 @@ function theme_attachments(&$item) {
if(is_array($arr) && count($arr)) {
$attaches = array();
foreach($arr as $r) {
- $icon = '';
- $icontype = substr($r['type'],0,strpos($r['type'],'/'));
- /**
- * @FIXME This should probably be a giant "if" statement in the
- * template so that we don't have icon names embedded in php code.
- */
-
- switch($icontype) {
- case 'video':
- $icon = 'icon-facetime-video';
- break;
- case 'audio':
- $icon = 'icon-volume-up';
- break;
- case 'image':
- $icon = 'icon-picture';
- break;
- case 'text':
- $icon = 'icon-align-justify';
- break;
- default:
- $icon = 'icon-question';
- break;
- }
-
- $title = htmlspecialchars($r['title'], ENT_COMPAT,'UTF-8');
- if(! $title)
- $title = t('unknown.???');
- $title .= ' ' . $r['length'] . ' ' . t('bytes');
+ $icon = getIconFromType($r['type']);
+ $label = (($r['title']) ? urldecode(htmlspecialchars($r['title'], ENT_COMPAT, 'UTF-8')) : t('Unknown Attachment'));
+
+ //some feeds provide an attachment where title an empty space
+ if($label == ' ')
+ $label = t('Unknown Attachment');
+
+ $title = t('Size') . ' ' . (($r['length']) ? userReadableSize($r['length']) : t('unknown'));
require_once('include/identity.php');
if(is_foreigner($item['author_xchan']))
@@ -1312,14 +1241,14 @@ function theme_attachments(&$item) {
else
$url = z_root() . '/magic?f=&hash=' . $item['author_xchan'] . '&dest=' . $r['href'] . '/' . $r['revision'];
- $s .= '<a href="' . $url . '" title="' . $title . '" class="attachlink" >' . $icon . '</a>';
- $attaches[] = array('title' => $title, 'url' => $url, 'icon' => $icon );
+ //$s .= '<a href="' . $url . '" title="' . $title . '" class="attachlink" >' . $icon . '</a>';
+ $attaches[] = array('label' => $label, 'url' => $url, 'icon' => $icon, 'title' => $title);
}
- }
- $s = replace_macros(get_markup_template('item_attach.tpl'), array(
- '$attaches' => $attaches
- ));
+ $s = replace_macros(get_markup_template('item_attach.tpl'), array(
+ '$attaches' => $attaches
+ ));
+ }
return $s;
}
@@ -1338,11 +1267,12 @@ function format_categories(&$item,$writeable) {
$removelink = (($writeable) ? z_root() . '/filerm/' . $item['id'] . '?f=&cat=' . urlencode($t['term']) : '');
$categories[] = array('term' => $term, 'writeable' => $writeable, 'removelink' => $removelink, 'url' => zid($t['url']));
}
+
+ $s = replace_macros(get_markup_template('item_categories.tpl'),array(
+ '$remove' => t('remove category'),
+ '$categories' => $categories
+ ));
}
- $s = replace_macros(get_markup_template('item_categories.tpl'),array(
- '$remove' => t('remove category'),
- '$categories' => $categories
- ));
return $s;
}
@@ -1353,6 +1283,7 @@ function format_categories(&$item,$writeable) {
* @param[in] array &$item
* @return string HTML link of hashtag
*/
+
function format_hashtags(&$item) {
$s = '';
@@ -1413,11 +1344,12 @@ function format_filer(&$item) {
$removelink = z_root() . '/filerm/' . $item['id'] . '?f=&term=' . urlencode($t['term']);
$categories[] = array('term' => $term, 'removelink' => $removelink);
}
+
+ $s = replace_macros(get_markup_template('item_filer.tpl'),array(
+ '$remove' => t('remove from file'),
+ '$categories' => $categories
+ ));
}
- $s = replace_macros(get_markup_template('item_filer.tpl'),array(
- '$remove' => t('remove from file'),
- '$categories' => $categories
- ));
return $s;
}
@@ -1442,26 +1374,49 @@ function generate_named_map($location) {
function prepare_body(&$item,$attach = false) {
require_once('include/identity.php');
- call_hooks('prepare_body_init', $item);
+// 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);
+// }
- unobscure($item);
-
- $s = '';
+ $photo = '';
$is_photo = (($item['obj_type'] === ACTIVITY_OBJ_PHOTO) ? true : false);
+
if($is_photo) {
$object = json_decode($item['object'],true);
- if($object['link'][0]['width']) {
+
+ // if original photo width is <= 640px prepend it to item body
+ if($object['link'][0]['width'] && $object['link'][0]['width'] <= 640) {
+ $s = '<div class="inline-photo-item-wrapper"><a href="' . zid(rawurldecode($object['id'])) . '" target="_newwin"><img class="inline-photo-item" style="max-width:' . $object['link'][0]['width'] . 'px; width:100%; height:auto;" src="' . zid(rawurldecode($object['link'][0]['href'])) . '"></a></div>' . $s;
+ }
+
+ // if original photo width is > 640px make it a cover photo
+ if($object['link'][0]['width'] && $object['link'][0]['width'] > 640) {
$scale = ((($object['link'][1]['width'] == 1024) || ($object['link'][1]['height'] == 1024)) ? 1 : 0);
- $s = '<div class="inline-photo-item-wrapper"><a href="' . zid(rawurldecode($object['id'])) . '"><img class="inline-photo-item" style="max-width:' . $object['link'][$scale]['width'] . 'px; width:100%; height:auto;" src="' . zid(rawurldecode($object['link'][$scale]['href'])) . '"></a></div>';
+ $photo = '<a href="' . zid(rawurldecode($object['id'])) . '" target="_newwin"><img style="max-width:' . $object['link'][$scale]['width'] . 'px; width:100%; height:auto;" src="' . zid(rawurldecode($object['link'][$scale]['href'])) . '"></a>';
}
}
- $s .= prepare_text($item['body'],$item['mimetype']);
+ $prep_arr = array(
+ 'item' => $item,
+ 'html' => $s,
+ 'photo' => $photo
+ );
- $prep_arr = array('item' => $item, 'html' => $s);
call_hooks('prepare_body', $prep_arr);
+
$s = $prep_arr['html'];
+ $photo = $prep_arr['photo'];
+
+// q("update item set html = '%s' where id = %d",
+// dbesc($s),
+// intval($item['id'])
+// );
if(! $attach) {
return $s;
@@ -1472,21 +1427,21 @@ function prepare_body(&$item,$attach = false) {
if($x) {
$s = preg_replace('/\<div class\=\"map\"\>/','$0' . $x,$s);
}
- }
+ }
- $s .= theme_attachments($item);
+ $attachments = theme_attachments($item);
$writeable = ((get_observer_hash() == $item['owner_xchan']) ? true : false);
- $s .= format_hashtags($item);
+ $tags = format_hashtags($item);
if($item['resource_type'])
- $s .= format_mentions($item);
+ $mentions = format_mentions($item);
- $s .= format_categories($item,$writeable);
+ $categories = format_categories($item,$writeable);
if(local_channel() == $item['uid'])
- $s .= format_filer($item);
+ $filer = format_filer($item);
$s = sslify($s);
@@ -1519,10 +1474,22 @@ function prepare_body(&$item,$attach = false) {
$s = substr($s, 0, $pos).$authorreplace.substr($s, $pos+strlen($authorsearch));
}
- $prep_arr = array('item' => $item, 'html' => $s);
+ $prep_arr = array(
+ 'item' => $item,
+ 'photo' => $photo,
+ 'html' => $s,
+ 'categories' => $categories,
+ 'folders' => $filer,
+ 'tags' => $tags,
+ 'mentions' => $mentions,
+ 'attachments' => $attachments
+ );
+
call_hooks('prepare_body_final', $prep_arr);
- return $prep_arr['html'];
+ unset($prep_arr['item']);
+
+ return $prep_arr;
}
/**
@@ -1532,7 +1499,7 @@ function prepare_body(&$item,$attach = false) {
* @param sting $content_type
* @return string
*/
-function prepare_text($text, $content_type = 'text/bbcode') {
+function prepare_text($text, $content_type = 'text/bbcode', $cache = false) {
switch($content_type) {
case 'text/plain':
@@ -1570,9 +1537,9 @@ function prepare_text($text, $content_type = 'text/bbcode') {
require_once('include/bbcode.php');
if(stristr($text,'[nosmile]'))
- $s = bbcode($text);
+ $s = bbcode($text,false,true,$cache);
else
- $s = smilies(bbcode($text));
+ $s = smilies(bbcode($text,false,true,$cache));
$s = zidify_links($s);
break;
}
@@ -1684,9 +1651,9 @@ function unamp($s) {
}
function layout_select($channel_id, $current = '') {
- $r = q("select mid,sid from item left join item_id on iid = item.id where service = 'PDL' and item.uid = item_id.uid and item_id.uid = %d and (item_restrict & %d)>0",
+ $r = q("select mid,sid from item left join item_id on iid = item.id where service = 'PDL' and item.uid = item_id.uid and item_id.uid = %d and item_type = %d ",
intval($channel_id),
- intval(ITEM_PDL)
+ intval(ITEM_TYPE_PDL)
);
if($r) {
@@ -1750,14 +1717,14 @@ function mimetype_select($channel_id, $current = 'text/bbcode') {
function lang_selector() {
global $a;
- $langs = glob('view/*/strings.php');
+ $langs = glob('view/*/hstrings.php');
$lang_options = array();
$selected = "";
if(is_array($langs) && count($langs)) {
$langs[] = '';
- if(! in_array('view/en/strings.php',$langs))
+ if(! in_array('view/en/hstrings.php',$langs))
$langs[] = 'view/en/';
asort($langs);
foreach($langs as $l) {
@@ -2039,15 +2006,15 @@ function xchan_query(&$items,$abook = true,$effective_uid = 0) {
if(count($arr)) {
if($abook) {
$chans = q("select * from xchan left join hubloc on hubloc_hash = xchan_hash left join abook on abook_xchan = xchan_hash and abook_channel = %d
- where xchan_hash in (" . implode(',', $arr) . ") and ( hubloc_flags & " . intval(HUBLOC_FLAGS_PRIMARY) . " )>0",
+ where xchan_hash in (" . protect_sprintf(implode(',', $arr)) . ") and hubloc_primary = 1",
intval($item['uid'])
);
}
else {
$chans = q("select xchan.*,hubloc.* from xchan left join hubloc on hubloc_hash = xchan_hash
- where xchan_hash in (" . implode(',', $arr) . ") and ( hubloc_flags & " . intval(HUBLOC_FLAGS_PRIMARY) . " )>0");
+ where xchan_hash in (" . protect_sprintf(implode(',', $arr)) . ") and hubloc_primary = 1");
}
- $xchans = q("select * from xchan where xchan_hash in (" . implode(',',$arr) . ") and xchan_network in ('rss','unknown')");
+ $xchans = q("select * from xchan where xchan_hash in (" . protect_sprintf(implode(',',$arr)) . ") and xchan_network in ('rss','unknown')");
if(! $chans)
$chans = $xchans;
else
@@ -2073,7 +2040,7 @@ function xchan_mail_query(&$item) {
if(count($arr)) {
$chans = q("select xchan.*,hubloc.* from xchan left join hubloc on hubloc_hash = xchan_hash
- where xchan_hash in (" . implode(',', $arr) . ") and ( hubloc_flags & " . intval(HUBLOC_FLAGS_PRIMARY) . " )>0");
+ where xchan_hash in (" . implode(',', $arr) . ") and hubloc_primary = 1");
}
if($chans) {
$item['from'] = find_xchan_in_array($item['from_xchan'],$chans);
@@ -2285,7 +2252,7 @@ function handle_tag($a, &$body, &$access_tag, &$str_tags, $profile_uid, $tag, $d
}
if($tag == '#getzot') {
$basetag = 'getzot';
- $url = 'https://redmatrix.me';
+ $url = 'http://hubzilla.org';
$newtag = '#[zrl=' . $url . ']' . $basetag . '[/zrl]';
$body = str_replace($tag,$newtag,$body);
$replaced = true;
@@ -2554,6 +2521,7 @@ function linkify_tags($a, &$body, $uid, $diaspora = false) {
*
* @param string $type mime type
* @return string
+ * @todo rename to get_icon_from_type()
*/
function getIconFromType($type) {
$iconMap = array(
@@ -2606,6 +2574,7 @@ function getIconFromType($type) {
*
* @param int $size filesize in bytes
* @return string human readable formatted filesize
+ * @todo rename to user_readable_size()
*/
function userReadableSize($size) {
$ret = '';
@@ -2622,3 +2591,53 @@ function userReadableSize($size) {
return $ret;
}
+
+function str_rot47($str) {
+ return strtr($str,
+ '!"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~',
+ 'PQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~!"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNO');
+}
+
+
+function string_replace($old,$new,&$s) {
+
+ $x = str_replace($old,$new,$s);
+ $replaced = false;
+ if($x !== $s) {
+ $replaced = true;
+ }
+ $s = $x;
+ return $replaced;
+}
+
+
+function json_url_replace($old,$new,&$s) {
+
+ $old = str_replace('/','\\/',$old);
+ $new = str_replace('/','\\/',$new);
+
+ $x = str_replace($old,$new,$s);
+ $replaced = false;
+ if($x !== $s) {
+ $replaced = true;
+ }
+ $s = $x;
+ return $replaced;
+}
+
+
+function item_url_replace($channel,&$item,$old,$new) {
+
+ if($item['attach'])
+ json_url_replace($old,$new,$item['attach']);
+ if($item['object'])
+ json_url_replace($old,$new,$item['object']);
+ if($item['target'])
+ json_url_replace($old,$new,$item['target']);
+
+ if(string_replace($old,$new,$item['body'])) {
+ $item['sig'] = base64url_encode(rsa_sign($item['body'],$channel['channel_prvkey']));
+ $item['item_verified'] = 1;
+ }
+
+}
diff --git a/include/widgets.php b/include/widgets.php
index 032b1c67e..0f61a04a0 100644
--- a/include/widgets.php
+++ b/include/widgets.php
@@ -29,7 +29,7 @@ function widget_tagcloud($args) {
$type = TERM_CATEGORY;
// FIXME there exists no $authors variable
- $r = tagadelic($uid, $count, $authors, $flags, ITEM_WEBPAGE, $type);
+ $r = tagadelic($uid, $count, $authors, $owner, $flags, ITEM_TYPE_WEBPAGE, $type);
if($r) {
$o = '<div class="tagblock widget"><h3>' . t('Categories') . '</h3><div class="tags" align="center">';
@@ -155,9 +155,8 @@ function widget_follow($args) {
$a = get_app();
$uid =$a->channel['channel_id'];
- $r = q("select count(*) as total from abook where abook_channel = %d and not (abook_flags & %d)>0 ",
- intval($uid),
- intval(ABOOK_FLAG_SELF)
+ $r = q("select count(*) as total from abook where abook_channel = %d and abook_self = 0 ",
+ intval($uid)
);
if($r)
$total_channels = $r[0]['total'];
@@ -394,7 +393,7 @@ function widget_tagcloud_wall($arr) {
$limit = ((array_key_exists('limit', $arr)) ? intval($arr['limit']) : 50);
if(feature_enabled($a->profile['profile_uid'], 'tagadelic'))
- return wtagblock($a->profile['profile_uid'], $limit, $a->profile['channel_hash'], ITEM_WALL);
+ return wtagblock($a->profile['profile_uid'], $limit, '', $a->profile['channel_hash'], 'wall');
return '';
}
@@ -409,8 +408,7 @@ function widget_catcloud_wall($arr) {
$limit = ((array_key_exists('limit',$arr)) ? intval($arr['limit']) : 50);
- return catblock($a->profile['profile_uid'], $limit, $a->profile['channel_hash'], ITEM_WALL);
-
+ return catblock($a->profile['profile_uid'], $limit, '', $a->profile['channel_hash'], 'wall');
}
@@ -475,9 +473,8 @@ function widget_settings_menu($arr) {
$role = get_pconfig(local_channel(),'system','permissions_role');
- $abk = q("select abook_id from abook where abook_channel = %d and ( abook_flags & %d )>0 limit 1",
- intval(local_channel()),
- intval(ABOOK_FLAG_SELF)
+ $abk = q("select abook_id from abook where abook_channel = %d and abook_self = 1 limit 1",
+ intval(local_channel())
);
if($abk)
$abook_self_id = $abk[0]['abook_id'];
@@ -565,13 +562,23 @@ function widget_mailmenu($arr) {
return;
$a = get_app();
+
return replace_macros(get_markup_template('message_side.tpl'), array(
- '$title' => t('Messages'),
- '$tabs'=> array(),
- '$check'=>array(
- 'label' => t('Check Mail'),
- 'url' => $a->get_baseurl(true) . '/message',
- 'sel' => (argv(1) == ''),
+ '$title' => t('Private Mail Menu'),
+ '$combined'=>array(
+ 'label' => t('Combined View'),
+ 'url' => $a->get_baseurl(true) . '/mail/combined',
+ 'sel' => (argv(1) == 'combined'),
+ ),
+ '$inbox'=>array(
+ 'label' => t('Inbox'),
+ 'url' => $a->get_baseurl(true) . '/mail/inbox',
+ 'sel' => (argv(1) == 'inbox'),
+ ),
+ '$outbox'=>array(
+ 'label' => t('Outbox'),
+ 'url' => $a->get_baseurl(true) . '/mail/outbox',
+ 'sel' => (argv(1) == 'outbox'),
),
'$new'=>array(
'label' => t('New Message'),
@@ -581,6 +588,80 @@ function widget_mailmenu($arr) {
));
}
+
+function widget_conversations($arr) {
+ if (! local_channel())
+ return;
+
+ $a = get_app();
+
+ if(argc() > 1) {
+
+ switch(argv(1)) {
+ case 'combined':
+ $mailbox = 'combined';
+ $header = t('Conversations');
+ break;
+ case 'inbox':
+ $mailbox = 'inbox';
+ $header = t('Received Messages');
+ break;
+ case 'outbox':
+ $mailbox = 'outbox';
+ $header = t('Sent Messages');
+ break;
+ default:
+ $mailbox = 'combined';
+ $header = t('Conversations');
+ break;
+ }
+
+ require_once('include/message.php');
+
+ // private_messages_list() can do other more complicated stuff, for now keep it simple
+ $r = private_messages_list(local_channel(), $mailbox, $a->pager['start'], $a->pager['itemspage']);
+
+ if(! $r) {
+ info( t('No messages.') . EOL);
+ return $o;
+ }
+
+ $messages = array();
+
+ foreach($r as $rr) {
+
+ $messages[] = array(
+ 'mailbox' => $mailbox,
+ 'id' => $rr['id'],
+ 'from_name' => $rr['from']['xchan_name'],
+ 'from_url' => chanlink_hash($rr['from_xchan']),
+ 'from_photo' => $rr['from']['xchan_photo_s'],
+ 'to_name' => $rr['to']['xchan_name'],
+ 'to_url' => chanlink_hash($rr['to_xchan']),
+ 'to_photo' => $rr['to']['xchan_photo_s'],
+ 'subject' => (($rr['seen']) ? $rr['title'] : '<strong>' . $rr['title'] . '</strong>'),
+ 'delete' => t('Delete conversation'),
+ 'body' => $rr['body'],
+ 'date' => datetime_convert('UTC',date_default_timezone_get(),$rr['created'], 'c'),
+ 'seen' => $rr['seen'],
+ 'selected' => ((argv(2)) ? (argv(2) == $rr['id']) : ($r[0]['id'] == $rr['id']))
+ );
+ }
+
+ $tpl = get_markup_template('mail_head.tpl');
+ $o .= replace_macros($tpl, array(
+ '$header' => $header,
+ '$messages' => $messages
+ ));
+
+ $o .= alt_pager($a,count($r));
+
+ }
+
+ return $o;
+}
+
+
function widget_design_tools($arr) {
$a = get_app();
@@ -597,6 +678,7 @@ function widget_design_tools($arr) {
return design_tools();
}
+
function widget_findpeople($arr) {
return findpeople_widget();
}
@@ -608,7 +690,7 @@ function widget_photo_albums($arr) {
if(! $a->profile['profile_uid'])
return '';
$channelx = channelx_by_n($a->profile['profile_uid']);
- if((! $channelx) || (! perm_is_allowed($a->profile['profile_uid'], get_observer_hash(), 'view_photos')))
+ if((! $channelx) || (! perm_is_allowed($a->profile['profile_uid'], get_observer_hash(), 'view_storage')))
return '';
require_once('include/photos.php');
@@ -706,7 +788,7 @@ function widget_item($arr) {
require_once('include/security.php');
$sql_extra = item_permissions_sql($uid);
- $r = q("select * from item where mid = '%s' and uid = %d and item_restrict = " . intval(ITEM_WEBPAGE) . " $sql_extra limit 1",
+ $r = q("select * from item where mid = '%s' and uid = %d and item_type = " . intval(ITEM_TYPE_WEBPAGE) . " $sql_extra limit 1",
dbesc($arr['mid']),
intval($uid)
);
@@ -904,10 +986,10 @@ function widget_random_block($arr) {
$r = q("select item.* from item left join item_id on item.id = item_id.iid
where item.uid = %d and sid like '%s' and service = 'BUILDBLOCK' and
- item_restrict = %d $sql_options order by $randfunc limit 1",
+ item_type = %d $sql_options order by $randfunc limit 1",
intval($channel_id),
dbesc('%' . $contains . '%'),
- intval(ITEM_BUILDBLOCK)
+ intval(ITEM_TYPE_BLOCK)
);
if($r) {
@@ -983,8 +1065,159 @@ function widget_rating($arr) {
}
// used by site ratings pages to provide a return link
-function widget_pubsites() {
+function widget_pubsites($arr) {
if(get_app()->poi)
return;
return '<div class="widget"><ul class="nav nav-pills"><li><a href="pubsites">' . t('Public Hubs') . '</a></li></ul></div>';
}
+
+
+function widget_forums($arr) {
+
+ $a = get_app();
+
+ if(! local_channel())
+ return '';
+
+ $o = '';
+
+ if(is_array($arr) && array_key_exists('limit',$arr))
+ $limit = " limit " . intval($limit) . " ";
+ else
+ $limit = '';
+
+ $unseen = 0;
+ if(is_array($arr) && array_key_exists('unseen',$arr) && intval($arr['unseen']))
+ $unseen = 1;
+
+ $perms_sql = item_permissions_sql(local_channel()) . item_normal();
+
+ $r1 = q("select * from abook left join xchan on abook_xchan = xchan_hash where ( xchan_pubforum = 1 or ((abook_their_perms & %d ) != 0 and (abook_their_perms & %d ) = 0) ) and abook_channel = %d order by xchan_name $limit ",
+ intval(PERMS_W_TAGWALL),
+ intval(PERMS_W_STREAM),
+ intval(local_channel())
+ );
+ if(! $r1)
+ return $o;
+
+ $str = '';
+
+ // Trying to cram all this into a single query with joins and the proper group by's is tough.
+ // There also should be a way to update this via ajax.
+
+ for($x = 0; $x < count($r1); $x ++) {
+ $r = q("select sum(item_unseen) as unseen from item where owner_xchan = '%s' and uid = %d $perms_sql ",
+ dbesc($r1[$x]['xchan_hash']),
+ intval(local_channel())
+ );
+ if($r)
+ $r1[$x]['unseen'] = $r[0]['unseen'];
+ }
+
+ if($r1) {
+ $o .= '<div class="widget">';
+ $o .= '<h3>' . t('Forums') . '</h3><ul class="nav nav-pills nav-stacked">';
+
+ 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 .= '</ul></div>';
+ }
+ return $o;
+
+}
+
+
+function widget_tasklist($arr) {
+
+
+ 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>';
+ $o .= '<script>function taskComplete(id) { $.post("tasks/complete/"+id, function(data) { tasksFetch();}); }
+ function tasksFetch() {
+ $.get("tasks/fetch" + ((tasksShowAll) ? "/all" : ""), function(data) {
+ $(".tasklist-tasks").html(data.html);
+ });
+ }
+ </script>';
+
+ $o .= '<div class="widget">' . '<h3>' . t('Tasks') . '</h3><div class="tasklist-tasks">';
+ $o .= '</div><form id="tasklist-new-form" action="" ><input id="tasklist-new-summary" type="text" name="summary" value="" /></form>';
+ $o .= '</div>';
+ return $o;
+
+}
+
+
+function widget_helpindex($arr) {
+ $o .= '<div class="widget">' . '<h3>' . t('Documentation') . '</h3>';
+ $o .= '<ul class="nav nav-pills nav-stacked">';
+ $o .= '<li><a href="help/general">' . t('Project/Site Information') . '</a></li>';
+ $o .= '<li><a href="help/members">' . t('For Members') . '</a></li>';
+ $o .= '<li><a href="help/admins">' . t('For Administrators') . '</a></li>';
+ $o .= '<li><a href="help/develop">' . t('For Developers') . '</a></li>';
+ $o .= '</ul></div>';
+ return $o;
+
+}
+
+
+
+function widget_admin($arr) {
+
+ /*
+ * Side bar links
+ */
+
+ if(! is_site_admin()) {
+ return login(false);
+ }
+
+
+ $a = get_app();
+ $o = '';
+
+ // array( url, name, extra css classes )
+
+ $aside = array(
+ 'site' => array(z_root() . '/admin/site/', t('Site'), 'site'),
+ 'users' => array(z_root() . '/admin/users/', t('Accounts'), 'users'),
+ 'channels' => array(z_root() . '/admin/channels/', t('Channels'), 'channels'),
+ 'plugins' => array(z_root() . '/admin/plugins/', t('Plugins'), 'plugins'),
+ 'themes' => array(z_root() . '/admin/themes/', t('Themes'), 'themes'),
+ 'queue' => array(z_root() . '/admin/queue', t('Inspect queue'), 'queue'),
+ 'profs' => array(z_root() . '/admin/profs', t('Profile Config'), 'profs'),
+ 'dbsync' => array(z_root() . '/admin/dbsync/', t('DB updates'), 'dbsync')
+
+ );
+
+ /* get plugins admin page */
+
+ $r = q("SELECT * FROM addon WHERE plugin_admin = 1");
+
+ $aside['plugins_admin'] = array();
+ if($r) {
+ foreach ($r as $h){
+ $plugin = $h['name'];
+ $aside['plugins_admin'][] = array(z_root() . '/admin/plugins/' . $plugin, $plugin, 'plugin');
+ // temp plugins with admin
+ $a->plugins_admin[] = $plugin;
+ }
+ }
+
+ $aside['logs'] = array(z_root() . '/admin/logs/', t('Logs'), 'logs');
+
+ $o .= replace_macros(get_markup_template('admin_aside.tpl'), array(
+ '$admin' => $aside,
+ '$admtxt' => t('Admin'),
+ '$plugadmtxt' => t('Plugin Features'),
+ '$logtxt' => t('Logs'),
+ '$h_pending' => t('User registrations waiting for confirmation'),
+ '$admurl'=> z_root() . '/admin/'
+ ));
+
+ return $o;
+
+}
diff --git a/include/zot.php b/include/zot.php
index 75ce40ffc..d5d68f72c 100644
--- a/include/zot.php
+++ b/include/zot.php
@@ -1,7 +1,7 @@
<?php
/**
* @file include/zot.php
- * @brief RedMatrix implementation of zot protocol.
+ * @brief Hubzilla implementation of zot protocol.
*
* https://github.com/friendica/red/wiki/zot
* https://github.com/friendica/red/wiki/Zot---A-High-Level-Overview
@@ -11,6 +11,7 @@
require_once('include/crypto.php');
require_once('include/items.php');
require_once('include/hubloc.php');
+require_once('include/DReport.php');
/**
@@ -80,9 +81,8 @@ function zot_get_hublocs($hash) {
/* Only search for active hublocs - e.g. those that haven't been marked deleted */
- $ret = q("select * from hubloc where hubloc_hash = '%s' and not ( hubloc_flags & %d )>0 order by hubloc_url ",
- dbesc($hash),
- intval(HUBLOC_FLAGS_DELETED)
+ $ret = q("select * from hubloc where hubloc_hash = '%s' and hubloc_deleted = 0 order by hubloc_url ",
+ dbesc($hash)
);
return $ret;
@@ -117,7 +117,8 @@ function zot_build_packet($channel, $type = 'notify', $recipients = null, $remot
'guid' => $channel['channel_guid'],
'guid_sig' => base64url_encode(rsa_sign($channel['channel_guid'],$channel['channel_prvkey'])),
'url' => z_root(),
- 'url_sig' => base64url_encode(rsa_sign(z_root(),$channel['channel_prvkey']))
+ 'url_sig' => base64url_encode(rsa_sign(z_root(),$channel['channel_prvkey'])),
+ 'sitekey' => get_config('system','pubkey')
),
'callback' => '/post',
'version' => ZOT_REVISION
@@ -200,9 +201,8 @@ function zot_finger($webbie, $channel = null, $autofallback = true) {
$r = q("select xchan.*, hubloc.* from xchan
left join hubloc on xchan_hash = hubloc_hash
- where xchan_addr = '%s' and (hubloc_flags & %d) > 0 limit 1",
- dbesc($xchan_addr),
- intval(HUBLOC_FLAGS_PRIMARY)
+ where xchan_addr = '%s' and hubloc_primary = 1 limit 1",
+ dbesc($xchan_addr)
);
if ($r) {
@@ -298,19 +298,24 @@ function zot_refresh($them, $channel = null, $force = false) {
} else {
$r = null;
+ // if they re-installed the server we could end up with the wrong record - pointing to the old install.
+ // We'll order by reverse id to try and pick off the newest one first and hopefully end up with the
+ // correct hubloc. If this doesn't work we may have to re-write this section to try them all.
+
if(array_key_exists('xchan_addr',$them) && $them['xchan_addr']) {
- $r = q("select hubloc_url, hubloc_flags from hubloc where hubloc_addr = '%s'",
+ $r = q("select hubloc_url, hubloc_primary from hubloc where hubloc_addr = '%s' order by hubloc_id desc",
dbesc($them['xchan_addr'])
);
}
if(! $r) {
- $r = q("select hubloc_url, hubloc_flags from hubloc where hubloc_hash = '%s'",
+ $r = q("select hubloc_url, hubloc_primary from hubloc where hubloc_hash = '%s' order by hubloc_id desc",
dbesc($them['xchan_hash'])
);
}
+
if ($r) {
foreach ($r as $rr) {
- if ($rr['hubloc_flags'] & HUBLOC_FLAGS_PRIMARY) {
+ if (intval($rr['hubloc_primary'])) {
$url = $rr['hubloc_url'];
break;
}
@@ -402,10 +407,9 @@ function zot_refresh($them, $channel = null, $force = false) {
$next_birthday = NULL_DATE;
}
- $r = q("select * from abook where abook_xchan = '%s' and abook_channel = %d and not (abook_flags & %d) > 0 limit 1",
+ $r = q("select * from abook where abook_xchan = '%s' and abook_channel = %d and abook_self = 0 limit 1",
dbesc($x['hash']),
- intval($channel['channel_id']),
- intval(ABOOK_FLAG_SELF)
+ intval($channel['channel_id'])
);
if($r) {
@@ -419,16 +423,15 @@ function zot_refresh($them, $channel = null, $force = false) {
if(substr($r[0]['abook_dob'],5) == substr($next_birthday,5))
$next_birthday = $r[0]['abook_dob'];
- $current_abook_connected = (($r[0]['abook_flags'] & ABOOK_FLAG_UNCONNECTED) ? 0 : 1);
+ $current_abook_connected = (intval($r[0]['abook_unconnected']) ? 0 : 1);
$y = q("update abook set abook_their_perms = %d, abook_dob = '%s'
where abook_xchan = '%s' and abook_channel = %d
- and not (abook_flags & %d) > 0 ",
+ and abook_self = 0 ",
intval($their_perms),
dbescdate($next_birthday),
dbesc($x['hash']),
- intval($channel['channel_id']),
- intval(ABOOK_FLAG_SELF)
+ intval($channel['channel_id'])
);
// if(($connected_set === 0 || $connected_set === 1) && ($connected_set !== $current_abook_unconnected)) {
@@ -437,13 +440,11 @@ function zot_refresh($them, $channel = null, $force = false) {
// match your current connected state setting, toggle it.
/** @FIXME uncoverted to postgres */
/** @FIXME when this was enabled, all contacts became unconnected. Currently disabled intentionally */
-// $y1 = q("update abook set abook_flags = (abook_flags ^ %d)
+// $y1 = q("update abook set abook_unconnected = 1
// where abook_xchan = '%s' and abook_channel = %d
-// and not (abook_flags & %d) limit 1",
-// intval(ABOOK_FLAG_UNCONNECTED),
+// and abook_self = 0 limit 1",
// dbesc($x['hash']),
-// intval($channel['channel_id']),
-// intval(ABOOK_FLAG_SELF)
+// intval($channel['channel_id'])
// );
// }
@@ -477,7 +478,7 @@ function zot_refresh($them, $channel = null, $force = false) {
if($closeness === false)
$closeness = 80;
- $y = q("insert into abook ( abook_account, abook_channel, abook_closeness, abook_xchan, abook_their_perms, abook_my_perms, abook_created, abook_updated, abook_dob, abook_flags ) values ( %d, %d, %d, '%s', %d, %d, '%s', '%s', '%s', %d )",
+ $y = q("insert into abook ( abook_account, abook_channel, abook_closeness, abook_xchan, abook_their_perms, abook_my_perms, abook_created, abook_updated, abook_dob, abook_pending ) values ( %d, %d, %d, '%s', %d, %d, '%s', '%s', '%s', %d )",
intval($channel['channel_account_id']),
intval($channel['channel_id']),
intval($closeness),
@@ -487,7 +488,7 @@ function zot_refresh($them, $channel = null, $force = false) {
dbesc(datetime_convert()),
dbesc(datetime_convert()),
dbesc($next_birthday),
- intval(($default_perms) ? 0 : ABOOK_FLAG_PENDING)
+ intval(($default_perms) ? 0 : 1)
);
if($y) {
@@ -496,15 +497,14 @@ function zot_refresh($them, $channel = null, $force = false) {
// Send a clone sync packet and a permissions update if permissions have changed
- $new_connection = q("select * from abook left join xchan on abook_xchan = xchan_hash where abook_xchan = '%s' and abook_channel = %d and not (abook_flags & %d) > 0 order by abook_created desc limit 1",
+ $new_connection = q("select * from abook left join xchan on abook_xchan = xchan_hash where abook_xchan = '%s' and abook_channel = %d and abook_self = 0 order by abook_created desc limit 1",
dbesc($x['hash']),
- intval($channel['channel_id']),
- intval(ABOOK_FLAG_SELF)
+ intval($channel['channel_id'])
);
if($new_connection) {
if($new_perms != $previous_perms)
- proc_run('php','include/notifier.php','permission_update',$new_connection[0]['abook_id']);
+ proc_run('php','include/notifier.php','permission_create',$new_connection[0]['abook_id']);
require_once('include/enotify.php');
notification(array(
'type' => NOTIFY_INTRO,
@@ -515,7 +515,7 @@ function zot_refresh($them, $channel = null, $force = false) {
if($their_perms & PERMS_R_STREAM) {
if(($channel['channel_w_stream'] & PERMS_PENDING)
- || (! ($new_connection[0]['abook_flags'] & ABOOK_FLAG_PENDING)) )
+ || (! intval($new_connection[0]['abook_pending'])) )
proc_run('php','include/onepoll.php',$new_connection[0]['abook_id']);
}
@@ -571,7 +571,7 @@ function zot_gethub($arr,$multiple = false) {
$limit = (($multiple) ? '' : ' limit 1 ');
$sitekey = ((array_key_exists('sitekey',$arr) && $arr['sitekey']) ? " and hubloc_sitekey = '" . protect_sprintf($arr['sitekey']) . "' " : '');
-
+
$r = q("select * from hubloc
where hubloc_guid = '%s' and hubloc_guid_sig = '%s'
and hubloc_url = '%s' and hubloc_url_sig = '%s'
@@ -592,7 +592,7 @@ function zot_gethub($arr,$multiple = false) {
}
/**
- * @brief Registers an unknown hup.
+ * @brief Registers an unknown hub.
*
* A communication has been received which has an unknown (to us) sender.
* Perform discovery based on our calculated hash of the sender at the
@@ -728,43 +728,36 @@ function import_xchan($arr,$ud_flags = UPDATE_FLAGS_UPDATED, $ud_arr = null) {
$hidden = (1 - intval($arr['searchable']));
- // Be careful - XCHAN_FLAGS_HIDDEN should evaluate to 1
- if(($r[0]['xchan_flags'] & XCHAN_FLAGS_HIDDEN) != $hidden)
- $new_flags = $r[0]['xchan_flags'] ^ XCHAN_FLAGS_HIDDEN;
- else
- $new_flags = $r[0]['xchan_flags'];
-
- $adult = (($r[0]['xchan_flags'] & XCHAN_FLAGS_SELFCENSORED) ? true : false);
- $adult_changed = ((intval($adult) != intval($arr['adult_content'])) ? true : false);
- if($adult_changed)
- $new_flags = $new_flags ^ XCHAN_FLAGS_SELFCENSORED;
-
- $deleted = (($r[0]['xchan_flags'] & XCHAN_FLAGS_DELETED) ? true : false);
- $deleted_changed = ((intval($deleted) != intval($arr['deleted'])) ? true : false);
- if($deleted_changed)
- $new_flags = $new_flags ^ XCHAN_FLAGS_DELETED;
-
- $public_forum = (($r[0]['xchan_flags'] & XCHAN_FLAGS_PUBFORUM) ? true : false);
- $pubforum_changed = ((intval($public_forum) != intval($arr['public_forum'])) ? true : false);
- if($pubforum_changed)
- $new_flags = $r[0]['xchan_flags'] ^ XCHAN_FLAGS_PUBFORUM;
-
- if(($r[0]['xchan_name_date'] != $arr['name_updated'])
- || ($r[0]['xchan_connurl'] != $arr['connections_url'])
- || ($r[0]['xchan_flags'] != $new_flags)
+ $hidden_changed = $adult_changed = $deleted_changed = $pubforum_changed = 0;
+
+ if(intval($r[0]['xchan_hidden']) != (1 - intval($arr['searchable'])))
+ $hidden_changed = 1;
+ if(intval($r[0]['xchan_selfcensored']) != intval($arr['adult_content']))
+ $adult_changed = 1;
+ if(intval($r[0]['xchan_deleted']) != intval($arr['deleted']))
+ $deleted_changed = 1;
+ if(intval($r[0]['xchan_pubforum']) != intval($arr['public_forum']))
+ $pubforum_changed = 1;
+
+ if(($r[0]['xchan_name_date'] != $arr['name_updated'])
+ || ($r[0]['xchan_connurl'] != $arr['connections_url'])
|| ($r[0]['xchan_addr'] != $arr['address'])
|| ($r[0]['xchan_follow'] != $arr['follow_url'])
- || ($r[0]['xchan_connpage'] != $arr['connect_url'])
- || ($r[0]['xchan_url'] != $arr['url'])) {
- $r = q("update xchan set xchan_name = '%s', xchan_name_date = '%s', xchan_connurl = '%s', xchan_follow = '%s',
- xchan_connpage = '%s', xchan_flags = %d,
+ || ($r[0]['xchan_connpage'] != $arr['connect_url'])
+ || ($r[0]['xchan_url'] != $arr['url'])
+ || $hidden_changed || adult_changed || deleted_changed || $pubforum_changed ) {
+ $r = q("update xchan set xchan_name = '%s', xchan_name_date = '%s', xchan_connurl = '%s', xchan_follow = '%s',
+ xchan_connpage = '%s', xchan_hidden = %d, xchan_selfcensored = %d, xchan_deleted = %d, xchan_pubforum = %d,
xchan_addr = '%s', xchan_url = '%s' where xchan_hash = '%s'",
dbesc(($arr['name']) ? $arr['name'] : '-'),
dbesc($arr['name_updated']),
dbesc($arr['connections_url']),
dbesc($arr['follow_url']),
dbesc($arr['connect_url']),
- intval($new_flags),
+ intval(1 - intval($arr['searchable'])),
+ intval($arr['adult_content']),
+ intval($arr['deleted']),
+ intval($arr['public_forum']),
dbesc($arr['address']),
dbesc($arr['url']),
dbesc($xchan_hash)
@@ -783,20 +776,9 @@ function import_xchan($arr,$ud_flags = UPDATE_FLAGS_UPDATED, $ud_arr = null) {
&& ($arr['site']['url'] != z_root()))
$arr['searchable'] = false;
- $hidden = (1 - intval($arr['searchable']));
-
- if($hidden)
- $new_flags = XCHAN_FLAGS_HIDDEN;
- else
- $new_flags = 0;
- if($arr['adult_content'])
- $new_flags |= XCHAN_FLAGS_SELFCENSORED;
- if(array_key_exists('deleted',$arr) && $arr['deleted'])
- $new_flags |= XCHAN_FLAGS_DELETED;
-
$x = q("insert into xchan ( xchan_hash, xchan_guid, xchan_guid_sig, xchan_pubkey, xchan_photo_mimetype,
- xchan_photo_l, xchan_addr, xchan_url, xchan_connurl, xchan_follow, xchan_connpage, xchan_name, xchan_network, xchan_photo_date, xchan_name_date, xchan_flags)
- values ( '%s', '%s', '%s', '%s' , '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d) ",
+ xchan_photo_l, xchan_addr, xchan_url, xchan_connurl, xchan_follow, xchan_connpage, xchan_name, xchan_network, xchan_photo_date, xchan_name_date, xchan_hidden, xchan_selfcensored, xchan_deleted, xchan_pubforum )
+ values ( '%s', '%s', '%s', '%s' , '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, %d, %d) ",
dbesc($xchan_hash),
dbesc($arr['guid']),
dbesc($arr['guid_sig']),
@@ -812,7 +794,10 @@ function import_xchan($arr,$ud_flags = UPDATE_FLAGS_UPDATED, $ud_arr = null) {
dbesc('zot'),
dbescdate($arr['photo_updated']),
dbescdate($arr['name_updated']),
- intval($new_flags)
+ intval(1 - intval($arr['searchable'])),
+ intval($arr['adult_content']),
+ intval($arr['deleted']),
+ intval($arr['public_forum'])
);
$what .= 'new_xchan';
@@ -831,7 +816,34 @@ function import_xchan($arr,$ud_flags = UPDATE_FLAGS_UPDATED, $ud_arr = null) {
if ($local) {
$ph = z_fetch_url($arr['photo'], true);
if ($ph['success']) {
- import_channel_photo($ph['body'], $arr['photo_mimetype'], $local[0]['channel_account_id'],$local[0]['channel_id']);
+
+ $hash = import_channel_photo($ph['body'], $arr['photo_mimetype'], $local[0]['channel_account_id'], $local[0]['channel_id']);
+
+ if($hash) {
+ // unless proven otherwise
+ $is_default_profile = 1;
+
+ $profile = q("select is_default from profile where aid = %d and uid = %d limit 1",
+ intval($local[0]['channel_account_id']),
+ intval($local[0]['channel_id'])
+ );
+ if($profile) {
+ if(! intval($profile[0]['is_default']))
+ $is_default_profile = 0;
+ }
+
+ // If setting for the default profile, unset the profile photo flag from any other photos I own
+ if($is_default_profile) {
+ q("UPDATE photo SET photo_usage = %d WHERE photo_usage = %d AND resource_id != '%s' AND aid = %d AND uid = %d",
+ intval(PHOTO_NORMAL),
+ intval(PHOTO_PROFILE),
+ dbesc($hash),
+ intval($local[0]['channel_account_id']),
+ intval($local[0]['channel_id'])
+ );
+ }
+ }
+
// reset the names in case they got messed up when we had a bug in this function
$photos = array(
z_root() . '/photo/profile/l/' . $local[0]['channel_id'],
@@ -842,7 +854,7 @@ function import_xchan($arr,$ud_flags = UPDATE_FLAGS_UPDATED, $ud_arr = null) {
);
}
} else {
- $photos = import_profile_photo($arr['photo'], $xchan_hash);
+ $photos = import_xchan_photo($arr['photo'], $xchan_hash);
}
if ($photos) {
if ($photos[4]) {
@@ -980,9 +992,28 @@ function zot_process_response($hub, $arr, $outq) {
logger('zot_process_response: headers: ' . print_r($arr['header'],true), LOGGER_DATA);
}
+ if(is_array($x) && array_key_exists('delivery_report',$x) && is_array($x['delivery_report'])) {
+ foreach($x['delivery_report'] as $xx) {
+ if(is_array($xx) && array_key_exists('message_id',$xx) && delivery_report_is_storable($xx)) {
+ q("insert into dreport ( dreport_mid, dreport_site, dreport_recip, dreport_result, dreport_time, dreport_xchan ) values ( '%s', '%s','%s','%s','%s','%s' ) ",
+ dbesc($xx['message_id']),
+ dbesc($xx['location']),
+ dbesc($xx['recipient']),
+ dbesc($xx['status']),
+ dbesc(datetime_convert($xx['date'])),
+ dbesc($xx['sender'])
+ );
+ }
+ }
+ }
+
+ q("delete from dreport where dreport_queue = '%s' limit 1",
+ dbesc($outq['outq_hash'])
+ );
+
// update the timestamp for this site
- q("update site set site_update = '%s' where site_url = '%s'",
+ q("update site set site_dead = 0, site_update = '%s' where site_url = '%s'",
dbesc(datetime_convert()),
dbesc(dirname($hub))
);
@@ -1150,14 +1181,15 @@ function zot_import($arr, $sender_url) {
$recip_arr[] = make_xchan_hash($recip['guid'],$recip['guid_sig']);
}
}
+
$r = false;
if($recip_arr) {
stringify_array_elms($recip_arr);
$recips = implode(',',$recip_arr);
- $r = q("select channel_hash as hash from channel where channel_hash in ( " . $recips . " ) and not ( channel_pageflags & %d ) > 0 ",
- intval(PAGE_REMOVED)
- );
+ $r = q("select channel_hash as hash from channel where channel_hash in ( " . $recips . " )
+ and channel_removed = 0 ");
}
+
if(! $r) {
logger('recips: no recipients on this site');
continue;
@@ -1235,8 +1267,10 @@ function zot_import($arr, $sender_url) {
if($i['message']['type'] === 'activity') {
$arr = get_item_elements($i['message']);
- if(! array_key_exists('created',$arr)) {
- logger('Activity rejected: probable failure to lookup author/owner. ' . print_r($i['message'],true));
+ $v = validate_item_elements($i['message'],$arr);
+
+ if(! $v['success']) {
+ logger('Activity rejected: ' . $v['message'] . ' ' . print_r($i['message'],true));
continue;
}
@@ -1372,13 +1406,13 @@ function public_recips($msg) {
or ( " . $col . " & " . intval(PERMS_PUBLIC) . ") > 0
or ( " . $col . " & " . intval(PERMS_AUTHED) . ") > 0 ) ";
} else {
- $sql = " where (( " . $col . " & " . intval(PERMS_NETWORK) . " ) > 0
- or ( " . $col . " & " . intval(PERMS_PUBLIC) . ") > 0
- or ( " . $col . " & " . intval(PERMS_AUTHED) . ") > 0 ) ";
+ $sql = " where ( " . $col . " = " . intval(PERMS_NETWORK) . "
+ or " . $col . " = " . intval(PERMS_PUBLIC) . "
+ or " . $col . " = " . intval(PERMS_AUTHED) . " ) ";
}
$r = q("select channel_hash as hash from channel $sql or channel_hash = '%s'
- and ( channel_pageflags & " . intval(PAGE_REMOVED) . " ) = 0 ",
+ and channel_removed = 0 ",
dbesc($msg['notify']['sender']['hash'])
);
@@ -1389,10 +1423,10 @@ function public_recips($msg) {
// and is allowing this sender at least at a high level.
$x = q("select channel_hash as hash from channel left join abook on abook_channel = channel_id
- where abook_xchan = '%s' and ( channel_pageflags & " . intval(PAGE_REMOVED) . " ) = 0
- and (( " . $col . " & " . intval(PERMS_SPECIFIC) . " ) > 0 and ( abook_my_perms & " . intval($field) . " ) > 0 )
- OR ( " . $col . " & " . intval(PERMS_PENDING) . " ) > 0
- OR (( " . $col . " & " . intval(PERMS_CONTACTS) . " ) > 0 and ( abook_flags & " . intval(ABOOK_FLAG_PENDING) . " ) = 0 ) ",
+ where abook_xchan = '%s' and channel_removed = 0
+ and (( " . $col . " = " . intval(PERMS_SPECIFIC) . " and ( abook_my_perms & " . intval($field) . " ) > 0 )
+ OR " . $col . " = " . intval(PERMS_PENDING) . "
+ OR ( " . $col . " = " . intval(PERMS_CONTACTS) . " and abook_pending = 0 )) ",
dbesc($msg['notify']['sender']['hash'])
);
@@ -1421,7 +1455,7 @@ function public_recips($msg) {
$address = basename($tag['url']);
if($address) {
$z = q("select channel_hash as hash from channel where channel_address = '%s'
- and ( channel_pageflags & " . intval(PAGE_REMOVED) . " ) = 0 limit 1",
+ and channel_removed = 0 limit 1",
dbesc($address)
);
if($z)
@@ -1439,8 +1473,7 @@ function public_recips($msg) {
if($msg['message']['message_top']) {
$z = q("select owner_xchan as hash from item where parent_mid = '%s' ",
- dbesc($msg['message']['message_top']),
- intval(ITEM_UPLINK)
+ dbesc($msg['message']['message_top'])
);
if($z)
$r = array_merge($r,$z);
@@ -1525,9 +1558,8 @@ function allowed_public_recips($msg) {
$condensed_recips[] = $rr['hash'];
$results = array();
- $r = q("select channel_hash as hash from channel left join abook on abook_channel = channel_id where abook_xchan = '%s' and ( channel_pageflags & %d ) = 0 ",
- dbesc($hash),
- intval(PAGE_REMOVED)
+ $r = q("select channel_hash as hash from channel left join abook on abook_channel = channel_id where abook_xchan = '%s' and channel_removed = 0 ",
+ dbesc($hash)
);
if($r) {
foreach($r as $rr)
@@ -1554,7 +1586,6 @@ function allowed_public_recips($msg) {
function process_delivery($sender, $arr, $deliveries, $relay, $public = false, $request = false) {
$result = array();
- require_once('include/DReport.php');
$result['site'] = z_root();
@@ -1567,7 +1598,6 @@ function process_delivery($sender, $arr, $deliveries, $relay, $public = false, $
}
}
-logger('sender: ' . print_r($sender,true));
foreach($deliveries as $d) {
$local_public = $public;
@@ -1603,19 +1633,18 @@ logger('sender: ' . print_r($sender,true));
// continue;
// }
-
// allow public postings to the sys channel regardless of permissions, but not
// for comments travelling upstream. Wait and catch them on the way down.
// They may have been blocked by the owner.
- if(($channel['channel_pageflags'] & PAGE_SYSTEM) && (! $arr['item_private']) && (! $relay)) {
+ if(intval($channel['channel_system']) && (! $arr['item_private']) && (! $relay)) {
$local_public = true;
- $r = q("select xchan_flags from xchan where xchan_hash = '%s' limit 1",
+ $r = q("select xchan_selfcensored from xchan where xchan_hash = '%s' limit 1",
dbesc($sender['hash'])
);
// don't import sys channel posts from selfcensored authors
- if($r && ($r[0]['xchan_flags'] & XCHAN_FLAGS_SELFCENSORED)) {
+ if($r && (intval($r[0]['xchan_selfcensored']))) {
$local_public = false;
continue;
}
@@ -1630,13 +1659,10 @@ logger('sender: ' . print_r($sender,true));
// This is our own post, possibly coming from a channel clone
if($arr['owner_xchan'] == $d['hash']) {
- $arr['item_flags'] = $arr['item_flags'] | ITEM_WALL;
+ $arr['item_wall'] = 1;
}
else {
- // clear the wall flag if it is set
- if($arr['item_flags'] & ITEM_WALL) {
- $arr['item_flags'] = ($arr['item_flags'] ^ ITEM_WALL);
- }
+ $arr['item_wall'] = 0;
}
if((! perm_is_allowed($channel['channel_id'],$sender['hash'],$perm)) && (! $tag_delivery) && (! $local_public)) {
@@ -1733,7 +1759,7 @@ logger('sender: ' . print_r($sender,true));
);
$abook = (($ab) ? $ab[0] : null);
- if($arr['item_restrict'] & ITEM_DELETED) {
+ if(intval($arr['item_deleted'])) {
// remove_community_tag is a no-op if this isn't a community tag activity
remove_community_tag($sender,$arr,$channel['channel_id']);
@@ -1758,17 +1784,19 @@ logger('sender: ' . print_r($sender,true));
continue;
}
- $r = q("select id, edited, item_restrict, item_flags, mid, parent_mid from item where mid = '%s' and uid = %d limit 1",
+ $r = q("select * from item where mid = '%s' and uid = %d limit 1",
dbesc($arr['mid']),
intval($channel['channel_id'])
);
if($r) {
// We already have this post.
$item_id = $r[0]['id'];
- if($r[0]['item_restrict'] & ITEM_DELETED) {
- // It was deleted locally.
+
+ if(intval($r[0]['item_deleted'])) {
+ // It was deleted locally.
$DR->update('update ignored');
$result[] = $DR->get();
+
continue;
}
// Maybe it has been edited?
@@ -1780,7 +1808,7 @@ logger('sender: ' . print_r($sender,true));
$result[] = $DR->get();
}
else {
- update_imported_item($sender,$arr,$channel['channel_id']);
+ update_imported_item($sender,$arr,$r[0],$channel['channel_id']);
$DR->update('updated');
$result[] = $DR->get();
if(! $relay)
@@ -1791,9 +1819,10 @@ logger('sender: ' . print_r($sender,true));
$DR->update('update ignored');
$result[] = $DR->get();
- // We need this line to ensure wall-to-wall comments are relayed (by falling through to the relay bit),
- // and at the same time not relay any other relayable posts more than once, because to do so is very wasteful.
- if(! ($r[0]['item_flags'] & ITEM_ORIGIN))
+
+ // We need this line to ensure wall-to-wall comments are relayed (by falling through to the relay bit),
+ // and at the same time not relay any other relayable posts more than once, because to do so is very wasteful.
+ if(! intval($r[0]['item_origin']))
continue;
}
}
@@ -1922,9 +1951,20 @@ function remove_community_tag($sender, $arr, $uid) {
* @param array $item
* @param int $uid (unused)
*/
-function update_imported_item($sender, $item, $uid) {
+function update_imported_item($sender, $item, $orig, $uid) {
+
$x = item_store_update($item);
+
+ // If we're updating an event that we've saved locally, we store the item info first
+ // because event_addtocal will parse the body to get the 'new' event details
+
+ if($orig['resource_type'] === 'event') {
+ $res = event_addtocal($orig['id'],$uid);
+ if(! $res)
+ logger('update event: failed');
+ }
+
if(! $x['item_id'])
logger('update_imported_item: failed: ' . $x['message']);
else
@@ -1949,10 +1989,15 @@ function delete_imported_item($sender, $item, $uid, $relay) {
$item_found = false;
$post_id = 0;
- $r = q("select id, item_restrict, author_xchan, owner_xchan, source_xchan from item where mid = '%s' and uid = %d limit 1",
+ $r = q("select id, author_xchan, owner_xchan, source_xchan, item_deleted from item where ( author_xchan = '%s' or owner_xchan = '%s' or source_xchan = '%s' )
+ and mid = '%s' and uid = %d limit 1",
+ dbesc($sender['hash']),
+ dbesc($sender['hash']),
+ dbesc($sender['hash']),
dbesc($item['mid']),
intval($uid)
);
+
if ($r) {
if ($r[0]['author_xchan'] === $sender['hash'] || $r[0]['owner_xchan'] === $sender['hash'] || $r[0]['source_xchan'] === $sender['hash'])
$ownership_valid = true;
@@ -1981,8 +2026,10 @@ function delete_imported_item($sender, $item, $uid, $relay) {
return false;
}
+ require_once('include/items.php');
+
if ($item_found) {
- if ($r[0]['item_restrict'] & ITEM_DELETED) {
+ if (intval($r[0]['item_deleted'])) {
logger('delete_imported_item: item was already deleted');
if (! $relay)
return false;
@@ -1994,9 +2041,8 @@ function delete_imported_item($sender, $item, $uid, $relay) {
// back, and we aren't going to (or shouldn't at any rate) delete it again in the future - so losing
// this information from the metadata should have no other discernible impact.
- if (($r[0]['id'] != $r[0]['parent']) && ($r[0]['item_flags'] & ITEM_ORIGIN)) {
- q("update item set item_flags = %d where id = %d and uid = %d",
- intval($r[0]['item_flags'] ^ ITEM_ORIGIN),
+ if (($r[0]['id'] != $r[0]['parent']) && intval($r[0]['item_origin'])) {
+ q("update item set item_origin = 0 where id = %d and uid = %d",
intval($r[0]['id']),
intval($r[0]['uid'])
);
@@ -2025,20 +2071,26 @@ function process_mail_delivery($sender, $arr, $deliveries) {
}
foreach($deliveries as $d) {
+
+ $DR = new DReport(z_root(),$sender['hash'],$d['hash'],$arr['mid']);
+
$r = q("select * from channel where channel_hash = '%s' limit 1",
dbesc($d['hash'])
);
if(! $r) {
- $result[] = array($d['hash'],'not found');
+ $DR->update('recipient not found');
+ $result[] = $DR->get();
continue;
}
$channel = $r[0];
+ $DR->addto_recipient($channel['channel_name'] . ' <' . $channel['channel_address'] . '@' . get_app()->get_hostname() . '>');
if(! perm_is_allowed($channel['channel_id'],$sender['hash'],'post_mail')) {
logger("permission denied for mail delivery {$channel['channel_id']}");
- $result[] = array($d['hash'],'permission denied',$channel['channel_name'],$arr['mid']);
+ $DR->update('permission denied');
+ $result[] = $DR->get();
continue;
}
@@ -2047,16 +2099,18 @@ function process_mail_delivery($sender, $arr, $deliveries) {
intval($channel['channel_id'])
);
if($r) {
- if($arr['mail_flags'] & MAIL_RECALLED) {
+ if(intval($arr['mail_recalled'])) {
$x = q("delete from mail where id = %d and channel_id = %d",
intval($r[0]['id']),
intval($channel['channel_id'])
);
- $result[] = array($d['hash'],'mail recalled',$channel['channel_name'],$arr['mid']);
+ $DR->update('mail recalled');
+ $result[] = $DR->get();
logger('mail_recalled');
}
else {
- $result[] = array($d['hash'],'duplicate mail received',$channel['channel_name'],$arr['mid']);
+ $DR->update('duplicate mail received');
+ $result[] = $DR->get();
logger('duplicate mail received');
}
continue;
@@ -2065,7 +2119,8 @@ function process_mail_delivery($sender, $arr, $deliveries) {
$arr['account_id'] = $channel['channel_account_id'];
$arr['channel_id'] = $channel['channel_id'];
$item_id = mail_store($arr);
- $result[] = array($d['hash'],'mail delivered',$channel['channel_name'],$arr['mid']);
+ $DR->update('mail delivered');
+ $result[] = $DR->get();
}
}
@@ -2257,23 +2312,16 @@ function sync_locations($sender, $arr, $absolute = false) {
$current_site = true;
}
- // If it is the site we're currently talking to, and it's marked offline,
- // either we have some bad information - or the thing came back to life.
-
- if(($current_site) && ($r[0]['hubloc_status'] & HUBLOC_OFFLINE)) {
- q("update hubloc set hubloc_status = (hubloc_status & ~%d) where hubloc_id = %d",
- intval(HUBLOC_OFFLINE),
+ if($current_site && intval($r[0]['hubloc_error'])) {
+ q("update hubloc set hubloc_error = 0 where hubloc_id = %d",
intval($r[0]['hubloc_id'])
);
- if($r[0]['hubloc_flags'] & HUBLOC_FLAGS_ORPHANCHECK) {
- q("update hubloc set hubloc_flags = (hubloc_flags & ~%d) where hubloc_id = %d",
- intval(HUBLOC_FLAGS_ORPHANCHECK),
+ if(intval($r[0]['hubloc_orphancheck'])) {
+ q("update hubloc set hubloc_orphancheck = 0 where hubloc_id = %d",
intval($r[0]['hubloc_id'])
);
}
- q("update xchan set xchan_flags = (xchan_flags & ~%d) where (xchan_flags & %d)>0 and xchan_hash = '%s'",
- intval(XCHAN_FLAGS_ORPHAN),
- intval(XCHAN_FLAGS_ORPHAN),
+ q("update xchan set xchan_orphan = 0 where xchan_orphan = 1 and xchan_hash = '%s'",
dbesc($sender['hash'])
);
}
@@ -2289,25 +2337,23 @@ function sync_locations($sender, $arr, $absolute = false) {
}
}
- if(($r[0]['hubloc_flags'] & HUBLOC_FLAGS_PRIMARY) && (! $location['primary'])) {
- $m = q("update hubloc set hubloc_flags = (hubloc_flags & ~%d), hubloc_updated = '%s' where hubloc_id = %d",
- intval(HUBLOC_FLAGS_PRIMARY),
+ if(intval($r[0]['hubloc_primary']) && (! $location['primary'])) {
+ $m = q("update hubloc set hubloc_primary = 0, hubloc_updated = '%s' where hubloc_id = %d",
dbesc(datetime_convert()),
intval($r[0]['hubloc_id'])
);
- $r[0]['hubloc_flags'] = $r[0]['hubloc_flags'] ^ HUBLOC_FLAGS_PRIMARY;
+ $r[0]['hubloc_primary'] = intval($location['primary']);
hubloc_change_primary($r[0]);
$what .= 'primary_hub ';
$changed = true;
}
- elseif((! ($r[0]['hubloc_flags'] & HUBLOC_FLAGS_PRIMARY)) && ($location['primary'])) {
- $m = q("update hubloc set hubloc_flags = (hubloc_flags | %d), hubloc_updated = '%s' where hubloc_id = %d",
- intval(HUBLOC_FLAGS_PRIMARY),
+ elseif((! intval($r[0]['hubloc_primary'])) && ($location['primary'])) {
+ $m = q("update hubloc set hubloc_primary = 1, hubloc_updated = '%s' where hubloc_id = %d",
dbesc(datetime_convert()),
intval($r[0]['hubloc_id'])
);
// make sure hubloc_change_primary() has current data
- $r[0]['hubloc_flags'] = $r[0]['hubloc_flags'] ^ HUBLOC_FLAGS_PRIMARY;
+ $r[0]['hubloc_primary'] = intval($location['primary']);
hubloc_change_primary($r[0]);
$what .= 'primary_hub ';
$changed = true;
@@ -2316,22 +2362,21 @@ function sync_locations($sender, $arr, $absolute = false) {
// Absolute sync - make sure the current primary is correctly reflected in the xchan
$pr = hubloc_change_primary($r[0]);
if($pr) {
- $what .= 'xchan_primary';
+ $what .= 'xchan_primary ';
$changed = true;
}
}
- if(($r[0]['hubloc_flags'] & HUBLOC_FLAGS_DELETED) && (! $location['deleted'])) {
- $n = q("update hubloc set hubloc_flags = (hubloc_flags & ~%d), hubloc_updated = '%s' where hubloc_id = %d",
- intval(HUBLOC_FLAGS_DELETED),
+ if(intval($r[0]['hubloc_deleted']) && (! intval($location['deleted']))) {
+ $n = q("update hubloc set hubloc_deleted = 0, hubloc_updated = '%s' where hubloc_id = %d",
dbesc(datetime_convert()),
intval($r[0]['hubloc_id'])
);
- $what .= 'delete_hub ';
+ $what .= 'undelete_hub ';
$changed = true;
}
- elseif((! ($r[0]['hubloc_flags'] & HUBLOC_FLAGS_DELETED)) && ($location['deleted'])) {
- $n = q("update hubloc set hubloc_flags = (hubloc_flags | %d), hubloc_updated = '%s' where hubloc_id = %d",
- intval(HUBLOC_FLAGS_DELETED),
+ elseif((! intval($r[0]['hubloc_deleted'])) && (intval($location['deleted']))) {
+ logger('deleting hubloc: ' . $r[0]['hubloc_addr']);
+ $n = q("update hubloc set hubloc_deleted = 1, hubloc_updated = '%s' where hubloc_id = %d",
dbesc(datetime_convert()),
intval($r[0]['hubloc_id'])
);
@@ -2345,22 +2390,20 @@ function sync_locations($sender, $arr, $absolute = false) {
// New hub claiming to be primary. Make it so by removing any existing primaries.
if(intval($location['primary'])) {
- $r = q("update hubloc set hubloc_flags = (hubloc_flags & ~%d), hubloc_updated = '%s' where hubloc_hash = '%s' and (hubloc_flags & %d )>0",
- intval(HUBLOC_FLAGS_PRIMARY),
+ $r = q("update hubloc set hubloc_primary = 0, hubloc_updated = '%s' where hubloc_hash = '%s' and hubloc_primary = 1",
dbesc(datetime_convert()),
- dbesc($sender['hash']),
- intval(HUBLOC_FLAGS_PRIMARY)
+ dbesc($sender['hash'])
);
}
logger('sync_locations: new hub: ' . $location['url']);
- $r = q("insert into hubloc ( hubloc_guid, hubloc_guid_sig, hubloc_hash, hubloc_addr, hubloc_network, hubloc_flags, hubloc_url, hubloc_url_sig, hubloc_host, hubloc_callback, hubloc_sitekey, hubloc_updated, hubloc_connected)
+ $r = q("insert into hubloc ( hubloc_guid, hubloc_guid_sig, hubloc_hash, hubloc_addr, hubloc_network, hubloc_primary, hubloc_url, hubloc_url_sig, hubloc_host, hubloc_callback, hubloc_sitekey, hubloc_updated, hubloc_connected)
values ( '%s','%s','%s','%s', '%s', %d ,'%s','%s','%s','%s','%s','%s','%s')",
dbesc($sender['guid']),
dbesc($sender['guid_sig']),
dbesc($sender['hash']),
dbesc($location['address']),
dbesc('zot'),
- intval((intval($location['primary'])) ? HUBLOC_FLAGS_PRIMARY : 0),
+ intval($location['primary']),
dbesc($location['url']),
dbesc($location['url_sig']),
dbesc($location['host']),
@@ -2387,9 +2430,8 @@ function sync_locations($sender, $arr, $absolute = false) {
if($absolute && $xisting) {
foreach($xisting as $x) {
if(! array_key_exists('updated',$x)) {
- logger('sync_locations: deleting unreferenced hub location ' . $x['hubloc_url']);
- $r = q("update hubloc set hubloc_flags = (hubloc_flags | %d), hubloc_updated = '%s' where hubloc_id = %d",
- intval(HUBLOC_FLAGS_DELETED),
+ logger('sync_locations: deleting unreferenced hub location ' . $x['hubloc_addr']);
+ $r = q("update hubloc set hubloc_deleted = 1, hubloc_updated = '%s' where hubloc_id = %d",
dbesc(datetime_convert()),
intval($x['hubloc_id'])
);
@@ -2399,6 +2441,9 @@ function sync_locations($sender, $arr, $absolute = false) {
}
}
}
+ else {
+ logger('No locations to sync!');
+ }
$ret['change_message'] = $what;
$ret['changed'] = $changed;
@@ -2418,20 +2463,26 @@ function zot_encode_locations($channel) {
$ret = array();
$x = zot_get_hublocs($channel['channel_hash']);
- if ($x && count($x)) {
- foreach ($x as $hub) {
- if (! ($hub['hubloc_flags'] & HUBLOC_FLAGS_UNVERIFIED)) {
- $ret[] = array(
- 'host' => $hub['hubloc_host'],
- 'address' => $hub['hubloc_addr'],
- 'primary' => (($hub['hubloc_flags'] & HUBLOC_FLAGS_PRIMARY) ? true : false),
- 'url' => $hub['hubloc_url'],
- 'url_sig' => $hub['hubloc_url_sig'],
- 'callback' => $hub['hubloc_callback'],
- 'sitekey' => $hub['hubloc_sitekey'],
- 'deleted' => (($hub['hubloc_flags'] & HUBLOC_FLAGS_DELETED) ? true : false)
- );
- }
+
+ if($x && count($x)) {
+ foreach($x as $hub) {
+
+ // if this is a local channel that has been deleted, the hubloc is no good - make sure it is marked deleted
+ // so that nobody tries to use it.
+
+ if(intval($channel['channel_removed']) && $hub['hubloc_url'] === z_root())
+ $hub['hubloc_deleted'] = 1;
+
+ $ret[] = array(
+ 'host' => $hub['hubloc_host'],
+ 'address' => $hub['hubloc_addr'],
+ 'primary' => (intval($hub['hubloc_primary']) ? true : false),
+ 'url' => $hub['hubloc_url'],
+ 'url_sig' => $hub['hubloc_url_sig'],
+ 'callback' => $hub['hubloc_callback'],
+ 'sitekey' => $hub['hubloc_sitekey'],
+ 'deleted' => (intval($hub['hubloc_deleted']) ? true : false)
+ );
}
}
@@ -2487,9 +2538,8 @@ function import_directory_profile($hash, $profile, $addr, $ud_flags = UPDATE_FLA
// These are not translated, so the German "erwachsenen" keyword will not censor the directory profile. Only the English form - "adult".
- if (in_arrayi('nsfw', $clean) || in_arrayi('adult', $clean)) {
- q("update xchan set xchan_flags = (xchan_flags | %d) where xchan_hash = '%s'",
- intval(XCHAN_FLAGS_SELFCENSORED),
+ if(in_arrayi('nsfw',$clean) || in_arrayi('adult',$clean)) {
+ q("update xchan set xchan_selfcensored = 1 where xchan_hash = '%s'",
dbesc($hash)
);
}
@@ -2751,7 +2801,8 @@ function import_site($arr, $pubkey) {
// logger('import_site: input: ' . print_r($arr,true));
// logger('import_site: stored: ' . print_r($siterecord,true));
- $r = q("update site set site_location = '%s', site_flags = %d, site_access = %d, site_directory = '%s', site_register = %d, site_update = '%s', site_sellpage = '%s', site_realm = '%s', site_project = '%s'
+
+ $r = q("update site set site_dead = 0, site_location = '%s', site_flags = %d, site_access = %d, site_directory = '%s', site_register = %d, site_update = '%s', site_sellpage = '%s', site_realm = '%s', site_type = %d, site_project = '%s'
where site_url = '%s'",
dbesc($site_location),
intval($site_directory),
@@ -2761,6 +2812,7 @@ function import_site($arr, $pubkey) {
dbesc(datetime_convert()),
dbesc($sellpage),
dbesc($site_realm),
+ intval(SITE_TYPE_ZOT),
dbesc($site_project),
dbesc($url)
);
@@ -2770,7 +2822,7 @@ function import_site($arr, $pubkey) {
}
else {
// update the timestamp to indicate we communicated with this site
- q("update site set site_update = '%s' where site_url = '%s'",
+ q("update site set site_dead = 0, site_update = '%s' where site_url = '%s'",
dbesc(datetime_convert()),
dbesc($url)
);
@@ -2778,8 +2830,9 @@ function import_site($arr, $pubkey) {
}
else {
$update = true;
- $r = q("insert into site ( site_location, site_url, site_access, site_flags, site_update, site_directory, site_register, site_sellpage, site_realm, site_project )
- values ( '%s', '%s', %d, %d, '%s', '%s', %d, '%s', '%s', '%s' )",
+
+ $r = q("insert into site ( site_location, site_url, site_access, site_flags, site_update, site_directory, site_register, site_sellpage, site_realm, site_type, site_project )
+ values ( '%s', '%s', %d, %d, '%s', '%s', %d, '%s', '%s', %d, '%s' )",
dbesc($site_location),
dbesc($url),
intval($access_policy),
@@ -2789,6 +2842,7 @@ function import_site($arr, $pubkey) {
intval($register_policy),
dbesc($sellpage),
dbesc($site_realm),
+ intval(SITE_TYPE_ZOT),
dbesc($site_project)
);
if(! $r) {
@@ -2831,13 +2885,11 @@ function build_sync_packet($uid = 0, $packet = null, $groups_changed = false) {
$channel = $r[0];
- if(intval($channel['channel_pageflags']) & PAGE_REMOVED)
+ if(intval($channel['channel_removed']))
return;
- $h = q("select * from hubloc where hubloc_hash = '%s' and not (hubloc_flags & %d) > 0 and not (hubloc_status & %d) > 0",
- dbesc($channel['channel_hash']),
- intval(HUBLOC_FLAGS_DELETED),
- intval(HUBLOC_OFFLINE)
+ $h = q("select * from hubloc where hubloc_hash = '%s' and hubloc_deleted = 0",
+ dbesc($channel['channel_hash'])
);
if(! $h)
@@ -2886,10 +2938,7 @@ function build_sync_packet($uid = 0, $packet = null, $groups_changed = false) {
// don't pass these elements, they should not be synchronised
- if(($k === 'channel_pageflags') && ($v & PAGE_SYSTEM))
- $v = (string) intval($v - PAGE_SYSTEM);
-
- $disallowed = array('channel_id','channel_account_id','channel_primary','channel_prvkey','channel_address');
+ $disallowed = array('channel_id','channel_account_id','channel_primary','channel_prvkey','channel_address','channel_deleted','channel_removed','channel_system');
if(in_array($k,$disallowed))
continue;
@@ -2949,6 +2998,8 @@ function build_sync_packet($uid = 0, $packet = null, $groups_changed = false) {
*/
function process_channel_sync_delivery($sender, $arr, $deliveries) {
+ require_once('include/import.php');
+
/** @FIXME this will sync red structures (channel, pconfig and abook). Eventually we need to make this application agnostic. */
$result = array();
@@ -2981,17 +3032,55 @@ function process_channel_sync_delivery($sender, $arr, $deliveries) {
}
}
+ if(array_key_exists('obj',$arr) && $arr['obj'])
+ sync_objs($channel,$arr['obj']);
+
+ if(array_key_exists('likes',$arr) && $arr['likes'])
+ import_likes($channel,$arr['likes']);
+
+ if(array_key_exists('app',$arr) && $arr['app'])
+ sync_apps($channel,$arr['app']);
+
+ if(array_key_exists('chatroom',$arr) && $arr['chatroom'])
+ sync_chatrooms($channel,$arr['chatroom']);
+
+ if(array_key_exists('conv',$arr) && $arr['conv'])
+ import_conv($channel,$arr['conv']);
+
+ if(array_key_exists('mail',$arr) && $arr['mail'])
+ import_mail($channel,$arr['mail']);
+
+ if(array_key_exists('event',$arr) && $arr['event'])
+ sync_events($channel,$arr['event']);
+
+ if(array_key_exists('event_item',$arr) && $arr['event_item'])
+ sync_items($channel,$arr['event_item']);
+
+ if(array_key_exists('item',$arr) && $arr['item'])
+ sync_items($channel,$arr['item']);
+
+ if(array_key_exists('item_id',$arr) && $arr['item_id'])
+ sync_items($channel,$arr['item_id']);
+
+ if(array_key_exists('menu',$arr) && $arr['menu'])
+ sync_menus($channel,$arr['menu']);
+
if(array_key_exists('channel',$arr) && is_array($arr['channel']) && count($arr['channel'])) {
- // These flags cannot be sync'd.
- // If these bits aren't set locally, remove the bits from the incoming flags.
+ if(array_key_exists('channel_pageflags',$arr['channel']) && intval($arr['channel']['channel_pageflags'])) {
+ // These flags cannot be sync'd.
+ // remove the bits from the incoming flags.
- if((! ($channel['channel_pageflags'] & PAGE_REMOVED)) && ($arr['channel']['channel_pageflags'] & PAGE_REMOVED))
- $arr['channel']['channel_pageflags'] = $arr['channel']['channel_pageflags'] - PAGE_REMOVED;
- if((! ($channel['channel_pageflags'] & PAGE_SYSTEM)) && ($arr['channel']['channel_pageflags'] & PAGE_SYSTEM))
- $arr['channel']['channel_pageflags'] = $arr['channel']['channel_pageflags'] - PAGE_SYSTEM;
+ // These correspond to PAGE_REMOVED and PAGE_SYSTEM on redmatrix
- $disallowed = array('channel_id','channel_account_id','channel_primary','channel_prvkey', 'channel_address', 'channel_notifyflags', 'channel_removed', 'channel_system', 'channel_deleted' );
+ if($arr['channel']['channel_pageflags'] & 0x8000)
+ $arr['channel']['channel_pageflags'] = $arr['channel']['channel_pageflags'] - 0x8000;
+ if($arr['channel']['channel_pageflags'] & 0x1000)
+ $arr['channel']['channel_pageflags'] = $arr['channel']['channel_pageflags'] - 0x1000;
+
+ }
+
+ $disallowed = array('channel_id','channel_account_id','channel_primary','channel_prvkey', 'channel_address', 'channel_notifyflags', 'channel_removed', 'channel_deleted', 'channel_system');
$clean = array();
foreach($arr['channel'] as $k => $v) {
@@ -3011,43 +3100,32 @@ function process_channel_sync_delivery($sender, $arr, $deliveries) {
$total_friends = 0;
$total_feeds = 0;
- $r = q("select abook_id, abook_flags from abook where abook_channel = %d",
+ $r = q("select abook_id, abook_feed from abook where abook_channel = %d",
intval($channel['channel_id'])
);
if($r) {
// don't count yourself
$total_friends = ((count($r) > 0) ? count($r) - 1 : 0);
foreach($r as $rr)
- if($rr['abook_flags'] & ABOOK_FLAG_FEED)
+ if(intval($rr['abook_feed']))
$total_feeds ++;
}
- $disallowed = array('abook_id','abook_account','abook_channel','abook_blocked','abook_ignored','abook_hidden','abook_archived','abook_pending','abook_unconnected','abook_self','abook_feed');
- foreach($arr['abook'] as $abook) {
+ $disallowed = array('abook_id','abook_account','abook_channel','abook_rating','abook_rating_text');
- if(array_key_exists('abook_blocked',$abook)) {
-
- // convert from hubzilla
-
- $abook['abook_flags'] = 0;
- if(intval($abook['abook_blocked']))
- $abook['abook_flags'] |= ABOOK_FLAG_BLOCKED;
- if(intval($abook['abook_ignored']))
- $abook['abook_flags'] |= ABOOK_FLAG_IGNORED;
- if(intval($abook['abook_hidden']))
- $abook['abook_flags'] |= ABOOK_FLAG_HIDDEN;
- if(intval($abook['abook_archived']))
- $abook['abook_flags'] |= ABOOK_FLAG_ARCHIVED;
- if(intval($abook['abook_pending']))
- $abook['abook_flags'] |= ABOOK_FLAG_PENDING;
- if(intval($abook['abook_unconnected']))
- $abook['abook_flags'] |= ABOOK_FLAG_UNCONNECTED;
- if(intval($abook['abook_self']))
- $abook['abook_flags'] |= ABOOK_FLAG_SELF;
- if(intval($abook['abook_feed']))
- $abook['abook_flags'] |= ABOOK_FLAG_FEED;
+ foreach($arr['abook'] as $abook) {
+ if(! array_key_exists('abook_blocked',$abook)) {
+ // convert from redmatrix
+ $abook['abook_blocked'] = (($abook['abook_flags'] & 0x0001) ? 1 : 0);
+ $abook['abook_ignored'] = (($abook['abook_flags'] & 0x0002) ? 1 : 0);
+ $abook['abook_hidden'] = (($abook['abook_flags'] & 0x0004) ? 1 : 0);
+ $abook['abook_archived'] = (($abook['abook_flags'] & 0x0008) ? 1 : 0);
+ $abook['abook_pending'] = (($abook['abook_flags'] & 0x0010) ? 1 : 0);
+ $abook['abook_unconnected'] = (($abook['abook_flags'] & 0x0020) ? 1 : 0);
+ $abook['abook_self'] = (($abook['abook_flags'] & 0x0080) ? 1 : 0);
+ $abook['abook_feed'] = (($abook['abook_flags'] & 0x0100) ? 1 : 0);
}
$clean = array();
@@ -3055,16 +3133,15 @@ function process_channel_sync_delivery($sender, $arr, $deliveries) {
logger('process_channel_sync_delivery: removing abook entry for ' . $abook['abook_xchan']);
require_once('include/Contact.php');
- $r = q("select abook_id, abook_flags from abook where abook_xchan = '%s' and abook_channel = %d and not ( abook_flags & %d )>0 limit 1",
+ $r = q("select abook_id, abook_feed from abook where abook_xchan = '%s' and abook_channel = %d and abook_self = 0 limit 1",
dbesc($abook['abook_xchan']),
- intval($channel['channel_id']),
- intval(ABOOK_FLAG_SELF)
+ intval($channel['channel_id'])
);
if($r) {
contact_remove($channel['channel_id'],$r[0]['abook_id']);
if($total_friends)
$total_friends --;
- if($r[0]['abook_flags'] & ABOOK_FLAG_FEED)
+ if(intval($r[0]['abook_feed']))
$total_feeds --;
}
continue;
@@ -3106,7 +3183,7 @@ function process_channel_sync_delivery($sender, $arr, $deliveries) {
logger('process_channel_sync_delivery: total_channels service class limit exceeded');
continue;
}
- if($max_feeds !== false && ($clean['abook_flags'] & ABOOK_FLAG_FEED) && $total_feeds > $max_feeds) {
+ if($max_feeds !== false && intval($clean['abook_feed']) && $total_feeds > $max_feeds) {
logger('process_channel_sync_delivery: total_feeds service class limit exceeded');
continue;
}
@@ -3115,7 +3192,7 @@ function process_channel_sync_delivery($sender, $arr, $deliveries) {
intval($channel['channel_id'])
);
$total_friends ++;
- if($clean['abook_flags'] & ABOOK_FLAG_FEED)
+ if(intval($clean['abook_feed']))
$total_feeds ++;
}
@@ -3127,6 +3204,9 @@ function process_channel_sync_delivery($sender, $arr, $deliveries) {
. "' where abook_xchan = '" . dbesc($clean['abook_xchan']) . "' and abook_channel = " . intval($channel['channel_id']));
}
}
+
+
+
}
}
@@ -3319,6 +3399,8 @@ function process_channel_sync_delivery($sender, $arr, $deliveries) {
if(array_key_exists('item_id',$arr) && $arr['item_id'])
sync_items($channel,$arr['item_id']);
+ $addon = array('channel' => $channel,'data' => $arr);
+ call_hooks('process_channel_sync_delivery',$addon);
// we should probably do this for all items, but usually we only send one.
@@ -3363,11 +3445,11 @@ function get_rpost_path($observer) {
* @return boolean|string return false or a hash
*/
function import_author_zot($x) {
- $hash = make_xchan_hash($x['guid'], $x['guid_sig']);
- $r = q("select hubloc_url from hubloc where hubloc_guid = '%s' and hubloc_guid_sig = '%s' and (hubloc_flags & %d)>0 limit 1",
+
+ $hash = make_xchan_hash($x['guid'],$x['guid_sig']);
+ $r = q("select hubloc_url from hubloc where hubloc_guid = '%s' and hubloc_guid_sig = '%s' and hubloc_primary = 1 limit 1",
dbesc($x['guid']),
- dbesc($x['guid_sig']),
- intval(HUBLOC_FLAGS_PRIMARY)
+ dbesc($x['guid_sig'])
);
if ($r) {
@@ -3437,12 +3519,9 @@ function zot_process_message_request($data) {
if ($messages) {
$env_recips = null;
- $r = q("select hubloc_guid, hubloc_url, hubloc_sitekey, hubloc_network, hubloc_flags, hubloc_callback, hubloc_host
- from hubloc where hubloc_hash = '%s' and not (hubloc_flags & %d)>0
- and not (hubloc_status & %d)>0 ",
- dbesc($sender_hash),
- intval(HUBLOC_FLAGS_DELETED),
- intval(HUBLOC_OFFLINE)
+ $r = q("select * from hubloc where hubloc_hash = '%s' and not hubloc_error and not hubloc_deleted
+ group by hubloc_sitekey",
+ dbesc($sender_hash)
);
if (! $r) {
logger('no hubs');
@@ -3492,78 +3571,401 @@ function zot_process_message_request($data) {
}
+function zotinfo($arr) {
-function import_items($channel,$items) {
+ $ret = array('success' => false);
- if($channel && $items) {
- $allow_code = false;
- $r = q("select account_id, account_roles, channel_pageflags from account left join channel on channel_account_id = account_id
- where channel_id = %d limit 1",
- intval($channel['channel_id'])
- );
- if($r) {
- if(($r[0]['account_roles'] & ACCOUNT_ROLE_ALLOWCODE) || ($r[0]['channel_pageflags'] & PAGE_ALLOWCODE)) {
- $allow_code = true;
- }
+ $zhash = ((x($arr,'guid_hash')) ? $arr['guid_hash'] : '');
+ $zguid = ((x($arr,'guid')) ? $arr['guid'] : '');
+ $zguid_sig = ((x($arr,'guid_sig')) ? $arr['guid_sig'] : '');
+ $zaddr = ((x($arr,'address')) ? $arr['address'] : '');
+ $ztarget = ((x($arr,'target')) ? $arr['target'] : '');
+ $zsig = ((x($arr,'target_sig')) ? $arr['target_sig'] : '');
+ $zkey = ((x($arr,'key')) ? $arr['key'] : '');
+ $mindate = ((x($arr,'mindate')) ? $arr['mindate'] : '');
+ $feed = ((x($arr,'feed')) ? intval($arr['feed']) : 0);
+
+ if($ztarget) {
+ if((! $zkey) || (! $zsig) || (! rsa_verify($ztarget,base64url_decode($zsig),$zkey))) {
+ logger('zfinger: invalid target signature');
+ $ret['message'] = t("invalid target signature");
+ return($ret);
}
+ }
- foreach($items as $i) {
- $item = get_item_elements($i,$allow_code);
- if(! $item)
- continue;
+ $r = null;
- $r = q("select id, edited from item where mid = '%s' and uid = %d limit 1",
- dbesc($item['mid']),
- intval($channel['channel_id'])
+ if(strlen($zhash)) {
+ $r = q("select channel.*, xchan.* from channel left join xchan on channel_hash = xchan_hash
+ where channel_hash = '%s' limit 1",
+ dbesc($zhash)
+ );
+ }
+ elseif(strlen($zguid) && strlen($zguid_sig)) {
+ $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($zguid),
+ dbesc($zguid_sig)
+ );
+ }
+ elseif(strlen($zaddr)) {
+ if(strpos($zaddr,'[system]') === false) { /* normal address lookup */
+ $r = q("select channel.*, xchan.* from channel left join xchan on channel_hash = xchan_hash
+ where ( channel_address = '%s' or xchan_addr = '%s' ) limit 1",
+ dbesc($zaddr),
+ dbesc($zaddr)
);
- if($r) {
- if($item['edited'] > $r[0]['edited']) {
- $item['id'] = $r[0]['id'];
- $item['uid'] = $channel['channel_id'];
- item_store_update($item);
- continue;
- }
+ }
+
+ else {
+
+ /**
+ * The special address '[system]' will return a system channel if one has been defined,
+ * Or the first valid channel we find if there are no system channels.
+ *
+ * This is used by magic-auth if we have no prior communications with this site - and
+ * returns an identity on this site which we can use to create a valid hub record so that
+ * we can exchange signed messages. The precise identity is irrelevant. It's the hub
+ * information that we really need at the other end - and this will return it.
+ *
+ */
+
+ $r = q("select channel.*, xchan.* from channel left join xchan on channel_hash = xchan_hash
+ where channel_system = 1 order by channel_id limit 1");
+ if(! $r) {
+ $r = q("select channel.*, xchan.* from channel left join xchan on channel_hash = xchan_hash
+ where channel_removed = 0 order by channel_id limit 1");
}
- else {
- $item['aid'] = $channel['channel_account_id'];
- $item['uid'] = $channel['channel_id'];
- $item_result = item_store($item);
+ }
+ }
+ else {
+ $ret['message'] = 'Invalid request';
+ return($ret);
+ }
+
+ if(! $r) {
+ $ret['message'] = 'Item not found.';
+ return($ret);
+ }
+
+ $e = $r[0];
+
+ $id = $e['channel_id'];
+
+ $sys_channel = (intval($e['channel_system']) ? true : false);
+ $special_channel = (($e['channel_pageflags'] & PAGE_PREMIUM) ? true : false);
+ $adult_channel = (($e['channel_pageflags'] & PAGE_ADULT) ? true : false);
+ $censored = (($e['channel_pageflags'] & PAGE_CENSORED) ? true : false);
+ $searchable = (($e['channel_pageflags'] & PAGE_HIDDEN) ? false : true);
+ $deleted = (intval($e['xchan_deleted']) ? true : false);
+
+ if($deleted || $censored || $sys_channel)
+ $searchable = false;
+
+ $public_forum = false;
+
+ $role = get_pconfig($e['channel_id'],'system','permissions_role');
+ if($role === 'forum' || $role === 'repository') {
+ $public_forum = true;
+ }
+ else {
+ // check if it has characteristics of a public forum based on custom permissions.
+ $t = q("select abook_my_perms from abook where abook_channel = %d and abook_self = 1 limit 1",
+ intval($e['channel_id'])
+ );
+ if(($t) && (($t[0]['abook_my_perms'] & PERMS_W_TAGWALL) && (! ($t[0]['abook_my_perms'] & PERMS_W_STREAM))))
+ $public_forum = true;
+ }
+
+
+ // This is for birthdays and keywords, but must check access permissions
+ $p = q("select * from profile where uid = %d and is_default = 1",
+ intval($e['channel_id'])
+ );
+
+ $profile = array();
+
+ if($p) {
+
+ if(! intval($p[0]['publish']))
+ $searchable = false;
+
+ $profile['description'] = $p[0]['pdesc'];
+ $profile['birthday'] = $p[0]['dob'];
+ if(($profile['birthday'] != '0000-00-00') && (($bd = z_birthday($p[0]['dob'],$e['channel_timezone'])) !== ''))
+ $profile['next_birthday'] = $bd;
+
+ if($age = age($p[0]['dob'],$e['channel_timezone'],''))
+ $profile['age'] = $age;
+ $profile['gender'] = $p[0]['gender'];
+ $profile['marital'] = $p[0]['marital'];
+ $profile['sexual'] = $p[0]['sexual'];
+ $profile['locale'] = $p[0]['locality'];
+ $profile['region'] = $p[0]['region'];
+ $profile['postcode'] = $p[0]['postal_code'];
+ $profile['country'] = $p[0]['country_name'];
+ $profile['about'] = $p[0]['about'];
+ $profile['homepage'] = $p[0]['homepage'];
+ $profile['hometown'] = $p[0]['hometown'];
+
+ if($p[0]['keywords']) {
+ $tags = array();
+ $k = explode(' ',$p[0]['keywords']);
+ if($k) {
+ foreach($k as $kk) {
+ if(trim($kk," \t\n\r\0\x0B,")) {
+ $tags[] = trim($kk," \t\n\r\0\x0B,");
+ }
+ }
}
+ if($tags)
+ $profile['keywords'] = $tags;
+ }
+ }
+
+ $ret['success'] = true;
+
+ // Communication details
+
+ $ret['guid'] = $e['xchan_guid'];
+ $ret['guid_sig'] = $e['xchan_guid_sig'];
+ $ret['key'] = $e['xchan_pubkey'];
+ $ret['name'] = $e['xchan_name'];
+ $ret['name_updated'] = $e['xchan_name_date'];
+ $ret['address'] = $e['xchan_addr'];
+ $ret['photo_mimetype'] = $e['xchan_photo_mimetype'];
+ $ret['photo'] = $e['xchan_photo_l'];
+ $ret['photo_updated'] = $e['xchan_photo_date'];
+ $ret['url'] = $e['xchan_url'];
+ $ret['connections_url']= (($e['xchan_connurl']) ? $e['xchan_connurl'] : z_root() . '/poco/' . $e['channel_address']);
+ $ret['target'] = $ztarget;
+ $ret['target_sig'] = $zsig;
+ $ret['searchable'] = $searchable;
+ $ret['adult_content'] = $adult_channel;
+ $ret['public_forum'] = $public_forum;
+ if($deleted)
+ $ret['deleted'] = $deleted;
+ if(intval($e['channel_removed']))
+ $ret['deleted_locally'] = true;
+
+ // premium or other channel desiring some contact with potential followers before connecting.
+ // This is a template - %s will be replaced with the follow_url we discover for the return channel.
+
+ if($special_channel)
+ $ret['connect_url'] = z_root() . '/connect/' . $e['channel_address'];
+
+ // This is a template for our follow url, %s will be replaced with a webbie
+
+ $ret['follow_url'] = z_root() . '/follow?f=&url=%s';
+
+ $ztarget_hash = (($ztarget && $zsig)
+ ? make_xchan_hash($ztarget,$zsig)
+ : '' );
+
+ $permissions = get_all_perms($e['channel_id'],$ztarget_hash,false);
+
+ if($ztarget_hash) {
+ $permissions['connected'] = false;
+ $b = q("select * from abook where abook_xchan = '%s' and abook_channel = %d limit 1",
+ dbesc($ztarget_hash),
+ intval($e['channel_id'])
+ );
+ if($b)
+ $permissions['connected'] = true;
+ }
+
+ $ret['permissions'] = (($ztarget && $zkey) ? crypto_encapsulate(json_encode($permissions),$zkey) : $permissions);
+
+ if($permissions['view_profile'])
+ $ret['profile'] = $profile;
+
+ // array of (verified) hubs this channel uses
+
+ $x = zot_encode_locations($e);
+ if($x)
+ $ret['locations'] = $x;
+
+ $ret['site'] = array();
+ $ret['site']['url'] = z_root();
+ $ret['site']['url_sig'] = base64url_encode(rsa_sign(z_root(),$e['channel_prvkey']));
+
+ $dirmode = get_config('system','directory_mode');
+ if(($dirmode === false) || ($dirmode == DIRECTORY_MODE_NORMAL))
+ $ret['site']['directory_mode'] = 'normal';
+
+ if($dirmode == DIRECTORY_MODE_PRIMARY)
+ $ret['site']['directory_mode'] = 'primary';
+ elseif($dirmode == DIRECTORY_MODE_SECONDARY)
+ $ret['site']['directory_mode'] = 'secondary';
+ elseif($dirmode == DIRECTORY_MODE_STANDALONE)
+ $ret['site']['directory_mode'] = 'standalone';
+ if($dirmode != DIRECTORY_MODE_NORMAL)
+ $ret['site']['directory_url'] = z_root() . '/dirsearch';
+
+
+ // hide detailed site information if you're off the grid
+
+ if($dirmode != DIRECTORY_MODE_STANDALONE) {
+
+ $register_policy = intval(get_config('system','register_policy'));
+
+ if($register_policy == REGISTER_CLOSED)
+ $ret['site']['register_policy'] = 'closed';
+ if($register_policy == REGISTER_APPROVE)
+ $ret['site']['register_policy'] = 'approve';
+ if($register_policy == REGISTER_OPEN)
+ $ret['site']['register_policy'] = 'open';
+
+
+ $access_policy = intval(get_config('system','access_policy'));
+ if($access_policy == ACCESS_PRIVATE)
+ $ret['site']['access_policy'] = 'private';
+ if($access_policy == ACCESS_PAID)
+ $ret['site']['access_policy'] = 'paid';
+ if($access_policy == ACCESS_FREE)
+ $ret['site']['access_policy'] = 'free';
+ if($access_policy == ACCESS_TIERED)
+ $ret['site']['access_policy'] = 'tiered';
+
+ $ret['site']['accounts'] = account_total();
+
+ require_once('include/identity.php');
+ $ret['site']['channels'] = channel_total();
+
+
+ $ret['site']['version'] = PLATFORM_NAME . ' ' . RED_VERSION . '[' . DB_UPDATE_VERSION . ']';
+
+ $ret['site']['admin'] = get_config('system','admin_email');
+
+ $a = get_app();
+
+ $visible_plugins = array();
+ if(is_array($a->plugins) && count($a->plugins)) {
+ $r = q("select * from addon where hidden = 0");
+ if($r)
+ foreach($r as $rr)
+ $visible_plugins[] = $rr['name'];
}
+
+ $ret['site']['plugins'] = $visible_plugins;
+ $ret['site']['sitehash'] = get_config('system','location_hash');
+ $ret['site']['sitename'] = get_config('system','sitename');
+ $ret['site']['sellpage'] = get_config('system','sellpage');
+ $ret['site']['location'] = get_config('system','site_location');
+ $ret['site']['realm'] = get_directory_realm();
+ $ret['site']['project'] = PLATFORM_NAME;
+
}
-}
+ check_zotinfo($e,$x,$ret);
+
+
+ call_hooks('zot_finger',$ret);
+ return($ret);
-function sync_items($channel,$items) {
- import_items($channel,$items);
}
+function check_zotinfo($channel,$locations,&$ret) {
-function import_item_ids($channel,$itemids) {
- if($channel && $itemids) {
- foreach($itemids as $i) {
- $r = q("select id from item where mid = '%s' and uid = %d limit 1",
- dbesc($i['mid']),
- intval($channel['channel_id'])
+
+// logger('locations: ' . print_r($locations,true),LOGGER_DATA);
+
+ // This function will likely expand as we find more things to detect and fix.
+ // 1. Because magic-auth is reliant on it, ensure that the system channel has a valid hubloc
+ // Force this to be the case if anything is found to be wrong with it.
+
+ // @FIXME ensure that the system channel exists in the first place and has an xchan
+
+ if($channel['channel_system']) {
+ // the sys channel must have a location (hubloc)
+ $valid_location = false;
+ if((count($locations) === 1) && ($locations[0]['primary']) && (! $locations[0]['deleted'])) {
+ if((rsa_verify($locations[0]['url'],base64url_decode($locations[0]['url_sig']),$channel['channel_pubkey']))
+ && ($locations[0]['sitekey'] === get_config('system','pubkey'))
+ && ($locations[0]['url'] === z_root()))
+ $valid_location = true;
+ else
+ logger('sys channel: invalid url signature');
+ }
+
+ if((! $locations) || (! $valid_location)) {
+
+ logger('System channel locations are not valid. Attempting repair.');
+
+ // Don't trust any existing records. Just get rid of them, but only do this
+ // for the sys channel as normal channels will be trickier.
+
+ q("delete from hubloc where hubloc_hash = '%s'",
+ dbesc($channel['channel_hash'])
);
- if(! $r)
- continue;
- $z = q("select * from item_id where service = '%s' and sid = '%s' and iid = %d and uid = %d limit 1",
- dbesc($i['service']),
- dbesc($i['sid']),
- intval($r[0]['id']),
- intval($channel['channel_id'])
+ $r = q("insert into hubloc ( hubloc_guid, hubloc_guid_sig, hubloc_hash, hubloc_addr, hubloc_primary,
+ hubloc_url, hubloc_url_sig, hubloc_host, hubloc_callback, hubloc_sitekey, hubloc_network )
+ values ( '%s', '%s', '%s', '%s', %d, '%s', '%s', '%s', '%s', '%s', '%s' )",
+ dbesc($channel['channel_guid']),
+ dbesc($channel['channel_guid_sig']),
+ dbesc($channel['channel_hash']),
+ dbesc($channel['channel_address'] . '@' . get_app()->get_hostname()),
+ intval(1),
+ dbesc(z_root()),
+ dbesc(base64url_encode(rsa_sign(z_root(),$channel['channel_prvkey']))),
+ dbesc(get_app()->get_hostname()),
+ dbesc(z_root() . '/post'),
+ dbesc(get_config('system','pubkey')),
+ dbesc('zot')
);
- if(! $z) {
- q("insert into item_id (iid,uid,sid,service) values(%d,%d,'%s','%s')",
- intval($r[0]['id']),
- intval($channel['channel_id']),
- dbesc($i['sid']),
- dbesc($i['service'])
- );
+ if($r) {
+ $x = zot_encode_locations($channel);
+ if($x) {
+ $ret['locations'] = $x;
+ }
+ }
+ else {
+ logger('Unable to store sys hub location');
}
}
}
}
+
+function delivery_report_is_storable($dr) {
+
+ call_hooks('dreport_is_storable',$dr);
+
+ // let plugins accept or reject - if neither, continue on
+ if(array_key_exists('accept',$dr) && intval($dr['accept']))
+ return true;
+ if(array_key_exists('reject',$dr) && intval($dr['reject']))
+ return false;
+
+ if(! ($dr['sender']))
+ return false;
+
+ // Is the sender one of our channels?
+
+ $c = q("select channel_id from channel where channel_hash = '%s' limit 1",
+ dbesc($dr['sender'])
+ );
+ if(! $c)
+ return false;
+
+ // is the recipient one of our connections, or do we want to store every report?
+
+ $r = explode(' ', $dr['recipient']);
+ $rxchan = $r[0];
+ $pcf = get_pconfig($c[0]['channel_id'],'system','dreport_store_all');
+ if($pcf)
+ return true;
+
+ $r = q("select abook_id from abook where abook_xchan = '%s' and abook_channel = %d limit 1",
+ dbesc($rxchan),
+ intval($c[0]['channel_id'])
+ );
+ if($r)
+ return true;
+
+ return false;
+
+}
+
+