aboutsummaryrefslogtreecommitdiffstats
path: root/include/items.php
diff options
context:
space:
mode:
Diffstat (limited to 'include/items.php')
-rwxr-xr-xinclude/items.php378
1 files changed, 359 insertions, 19 deletions
diff --git a/include/items.php b/include/items.php
index 44f9633a9..f5eccfccd 100755
--- a/include/items.php
+++ b/include/items.php
@@ -159,7 +159,7 @@ function filter_insecure($channel_id, $arr) {
$ret = array();
- if((! intval(get_pconfig($channel_id, 'system', 'filter_insecure_collections'))) || (! $arr))
+ if((! intval(get_pconfig($channel_id, 'system', 'filter_insecure_privacy_groups'))) || (! $arr))
return $arr;
$str = '';
@@ -552,6 +552,12 @@ function get_public_feed($channel, $params) {
$params['top'] = ((x($params,'top')) ? intval($params['top']) : 0);
$params['cat'] = ((x($params,'cat')) ? $params['cat'] : '');
+
+ // put a sane lower limit on feed requests if not specified
+
+ if($params['begin'] === NULL_DATE)
+ $params['begin'] = datetime_convert('UTC','UTC','now - 1 month');
+
switch($params['type']) {
case 'json':
header("Content-type: application/atom+json");
@@ -587,8 +593,8 @@ function get_feed_for($channel, $observer_hash, $params) {
}
$items = items_fetch(array(
'wall' => '1',
- 'datequery' => $params['begin'],
- 'datequery2' => $params['end'],
+ 'datequery' => $params['end'],
+ 'datequery2' => $params['begin'],
'start' => $params['start'], // FIXME
'records' => $params['records'], // FIXME
'direction' => $params['direction'], // FIXME
@@ -604,8 +610,8 @@ function get_feed_for($channel, $observer_hash, $params) {
$atom = '';
$atom .= replace_macros($feed_template, array(
- '$version' => xmlify(RED_VERSION),
- '$red' => xmlify(PLATFORM_NAME),
+ '$version' => xmlify(get_project_version()),
+ '$red' => xmlify(get_platform_name()),
'$feed_id' => xmlify($channel['xchan_url']),
'$feed_title' => xmlify($channel['channel_name']),
'$feed_updated' => xmlify(datetime_convert('UTC', 'UTC', 'now' , ATOM_TIME)) ,
@@ -623,6 +629,7 @@ function get_feed_for($channel, $observer_hash, $params) {
'$community' => '',
));
+
call_hooks('atom_feed', $atom);
if($items) {
@@ -842,7 +849,7 @@ function get_item_elements($x,$allow_code = false) {
if($allow_code)
$arr['body'] = $x['body'];
else
- $arr['body'] = (($x['body']) ? htmlspecialchars($x['body'],ENT_COMPAT,'UTF-8',false) : '');
+ $arr['body'] = (($x['body']) ? htmlspecialchars($x['body'],ENT_COMPAT,'UTF-8',false) : '');
$key = get_config('system','pubkey');
@@ -910,6 +917,7 @@ function get_item_elements($x,$allow_code = false) {
$arr['attach'] = activity_sanitise($x['attach']);
$arr['term'] = decode_tags($x['tags']);
+ $arr['iconfig'] = decode_item_meta($x['meta']);
$arr['item_private'] = ((array_key_exists('flags',$x) && is_array($x['flags']) && in_array('private',$x['flags'])) ? 1 : 0);
@@ -1317,6 +1325,9 @@ function encode_item($item,$mirror = false) {
if($item['term'])
$x['tags'] = encode_item_terms($item['term'],$mirror);
+ if($item['iconfig'])
+ $x['meta'] = encode_item_meta($item['iconfig'],$mirror);
+
if($item['diaspora_meta']) {
$z = json_decode($item['diaspora_meta'],true);
if($z) {
@@ -1427,6 +1438,30 @@ function encode_item_terms($terms,$mirror = false) {
return $ret;
}
+function encode_item_meta($meta,$mirror = false) {
+ $ret = array();
+
+ if($meta) {
+ foreach($meta as $m) {
+ if($m['sharing'] || $mirror)
+ $ret[] = array('family' => $m['cat'], 'key' => $m['k'], 'value' => $m['v'], 'sharing' => intval($m['sharing']));
+ }
+ }
+
+ return $ret;
+}
+
+function decode_item_meta($meta) {
+ $ret = array();
+
+ if(is_array($meta) && $meta) {
+ foreach($meta as $m) {
+ $ret[] = array('cat' => escape_tags($m['family']),'k' => escape_tags($m['key']),'v' => $m['value'],'sharing' => $m['sharing']);
+ }
+ }
+ return $ret;
+}
+
/**
* @brief
*
@@ -2160,7 +2195,7 @@ function encode_rel_links($links) {
* * \e boolean \b success
* * \e int \b item_id
*/
-function item_store($arr, $allow_exec = false) {
+function item_store($arr, $allow_exec = false, $deliver = true) {
$d = array('item' => $arr, 'allow_exec' => $allow_exec);
call_hooks('item_store', $d );
@@ -2439,6 +2474,13 @@ function item_store($arr, $allow_exec = false) {
unset($arr['term']);
}
+ $meta = null;
+ if(array_key_exists('iconfig',$arr)) {
+ $meta = $arr['iconfig'];
+ unset($arr['iconfig']);
+ }
+
+
if(strlen($allow_cid) || strlen($allow_gid) || strlen($deny_cid) || strlen($deny_gid) || strlen($public_policy))
$private = 1;
else
@@ -2516,6 +2558,15 @@ function item_store($arr, $allow_exec = false) {
$arr['term'] = $terms;
}
+ if($meta) {
+ foreach($meta as $m) {
+ set_iconfig($current_post,$m['cat'],$m['k'],$m['v'],$m['sharing']);
+ }
+ $arr['iconfig'] = $meta;
+ }
+
+
+
call_hooks('post_remote_end',$arr);
// update the commented timestamp on the parent
@@ -2537,7 +2588,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(! intval($arr['item_deleted'])) {
+ if(($deliver) && (! intval($arr['item_deleted']))) {
send_status_notifications($current_post,$arr);
tag_deliver($arr['uid'],$current_post);
}
@@ -2550,7 +2601,7 @@ function item_store($arr, $allow_exec = false) {
-function item_store_update($arr,$allow_exec = false) {
+function item_store_update($arr,$allow_exec = false, $deliver = true) {
$d = array('item' => $arr, 'allow_exec' => $allow_exec);
call_hooks('item_store_update', $d );
@@ -2737,6 +2788,13 @@ function item_store_update($arr,$allow_exec = false) {
unset($arr['term']);
}
+ $meta = null;
+ if(array_key_exists('iconfig',$arr)) {
+ $meta = $arr['iconfig'];
+ unset($arr['iconfig']);
+ }
+
+
dbesc_array($arr);
logger('item_store_update: ' . print_r($arr,true), LOGGER_DATA);
@@ -2778,11 +2836,24 @@ function item_store_update($arr,$allow_exec = false) {
$arr['term'] = $terms;
}
+ $r = q("delete from iconfig where iid = %d",
+ intval($orig_post_id)
+ );
+
+ if($meta) {
+ foreach($meta as $m) {
+ set_iconfig($orig_post_id,$m['cat'],$m['k'],$m['v'],$m['sharing']);
+ }
+ $arr['iconfig'] = $meta;
+ }
+
call_hooks('post_remote_update_end',$arr);
- send_status_notifications($orig_post_id,$arr);
+ if($deliver) {
+ send_status_notifications($orig_post_id,$arr);
+ tag_deliver($uid,$orig_post_id);
+ }
- tag_deliver($uid,$orig_post_id);
$ret['success'] = true;
$ret['item_id'] = $orig_post_id;
@@ -3436,6 +3507,7 @@ function check_item_source($uid, $item) {
if(! $r[0]['src_patt'])
return true;
+
require_once('include/html2plain.php');
$text = prepare_text($item['body'],$item['mimetype']);
$text = html2plain($text);
@@ -3685,6 +3757,16 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) {
return;
}
+ $sys_expire = intval(get_config('system','default_expire_days'));
+ $chn_expire = intval($importer['channel_expire_days']);
+
+ $expire_days = $sys_expire;
+
+ if(($chn_expire != 0) && ($chn_expire < $sys_expire))
+ $expire_days = $chn_expire;
+
+logger('expire_days: ' . $expire_days);
+
$feed = new SimplePie();
$feed->set_raw_data($xml);
$feed->init();
@@ -3788,6 +3870,7 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) {
intval($importer['channel_id'])
);
+
// Update content if 'updated' changes
if($r) {
@@ -3846,6 +3929,17 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) {
$datarray['owner_xchan'] = $contact['xchan_hash'];
+ if(array_key_exists('created',$datarray) && $datarray['created'] != NULL_DATE && $expire_days) {
+ $t1 = $datarray['created'];
+ $t2 = datetime_convert('UTC','UTC','now - ' . $expire_days . 'days');
+ if($t1 < $t2) {
+ logger('feed content older than expiration. Ignoring.', LOGGER_DEBUG, LOG_INFO);
+ continue;
+ }
+ }
+
+
+
$r = q("SELECT edited FROM item WHERE mid = '%s' AND uid = %d LIMIT 1",
dbesc($item_id),
intval($importer['channel_id'])
@@ -3975,12 +4069,25 @@ function atom_entry($item,$type,$author,$owner,$comment = false,$cid = 0) {
$o .= '<thr:in-reply-to ref="' . xmlify($parent_item) . '" type="text/html" href="' . xmlify($item['plink']) . '" />' . "\r\n";
}
+ if(activity_compare($item['obj_type'],ACTIVITY_OBJ_EVENT) && activity_compare($item['verb'],ACTIVITY_POST)) {
+ $obj = ((is_array($item['obj'])) ? $item['object'] : json_decode($item['object'],true));
+
+ $o .= '<title>' . xmlify($item['title']) . '</title>' . "\r\n";
+ $o .= '<summary>' . xmlify(bbcode($obj['title'])) . '</summary>' . "\r\n";
+ $o .= '<dtstart xmlns="urn:ietf:params:xml:ns:xcal">' . datetime_convert('UTC','UTC', $obj['start'],'Ymd\\THis' . (($obj['adjust']) ? '\\Z' : '')) . '</dtstart>' . "\r\n";
+ $o .= '<dtend xmlns="urn:ietf:params:xml:ns:xcal">' . datetime_convert('UTC','UTC', $obj['finish'],'Ymd\\THis' . (($obj['adjust']) ? '\\Z' : '')) . '</dtend>' . "\r\n";
+ $o .= '<location>' . bbcode($obj['location']) . '</location>' . "\r\n";
+ $o .= '<content type="' . $type . '" >' . xmlify(bbcode($obj['description'])) . '</content>' . "\r\n";
+ }
+ else {
+ $o .= '<title>' . xmlify($item['title']) . '</title>' . "\r\n";
+ $o .= '<content type="' . $type . '" >' . xmlify(prepare_text($body,$item['mimetype'])) . '</content>' . "\r\n";
+ }
+
$o .= '<id>' . xmlify($item['mid']) . '</id>' . "\r\n";
- $o .= '<title>' . xmlify($item['title']) . '</title>' . "\r\n";
$o .= '<published>' . xmlify(datetime_convert('UTC','UTC',$item['created'] . '+00:00',ATOM_TIME)) . '</published>' . "\r\n";
$o .= '<updated>' . xmlify(datetime_convert('UTC','UTC',$item['edited'] . '+00:00',ATOM_TIME)) . '</updated>' . "\r\n";
- $o .= '<content type="' . $type . '" >' . xmlify(prepare_text($body,$item['mimetype'])) . '</content>' . "\r\n";
$o .= '<link rel="alternate" type="text/html" href="' . xmlify($item['plink']) . '" />' . "\r\n";
if($item['location']) {
@@ -4643,6 +4750,10 @@ function fetch_post_tags($items,$link = false) {
dbesc($tag_finder_str),
intval(TERM_OBJ_POST)
);
+ $imeta = q("select * from iconfig where iid in ( %s )",
+ dbesc($tag_finder_str)
+ );
+
}
for($x = 0; $x < count($items); $x ++) {
@@ -4666,6 +4777,26 @@ function fetch_post_tags($items,$link = false) {
}
}
}
+ if($imeta) {
+ foreach($imeta as $i) {
+ if(array_key_exists('item_id',$items[$x])) {
+ if($i['iid'] == $items[$x]['item_id']) {
+ if(! is_array($items[$x]['iconfig']))
+ $items[$x]['iconfig'] = array();
+ $i['v'] = ((preg_match('|^a:[0-9]+:{.*}$|s',$i['v'])) ? unserialize($i['v']) : $i['v']);
+ $items[$x]['iconfig'][] = $i;
+ }
+ }
+ else {
+ if($i['iid'] == $items[$x]['id']) {
+ if(! is_array($items[$x]['iconfig']))
+ $items[$x]['iconfig'] = array();
+ $i['v'] = ((preg_match('|^a:[0-9]+:{.*}$|s',$i['v'])) ? unserialize($i['v']) : $i['v']);
+ $items[$x]['iconfig'][] = $i;
+ }
+ }
+ }
+ }
}
return $items;
@@ -4835,7 +4966,7 @@ function items_fetch($arr,$channel = null,$observer_hash = null,$client_mode = C
intval($uid)
);
if(! $r) {
- $result['message'] = t('Collection not found.');
+ $result['message'] = t('Privacy group not found.');
return $result;
}
@@ -4851,14 +4982,14 @@ function items_fetch($arr,$channel = null,$observer_hash = null,$client_mode = C
}
} else {
$contact_str = ' 0 ';
- $result['message'] = t('Collection is empty.');
+ $result['message'] = t('Privacy group is empty.');
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 $item_normal ) ";
$x = group_rec_byhash($uid,$r[0]['hash']);
- $result['headline'] = sprintf( t('Collection: %s'),$x['name']);
+ $result['headline'] = sprintf( t('Privacy group: %s'),$x['name']);
}
elseif($arr['cid'] && $uid) {
@@ -4876,15 +5007,15 @@ function items_fetch($arr,$channel = null,$observer_hash = null,$client_mode = C
}
if ($arr['datequery']) {
- $sql_extra3 .= protect_sprintf(sprintf(" AND item.created <= '%s' ", dbesc(datetime_convert(date_default_timezone_get(),'',$arr['datequery']))));
+ $sql_extra3 .= protect_sprintf(sprintf(" AND item.created <= '%s' ", dbesc(datetime_convert('UTC','UTC',$arr['datequery']))));
}
if ($arr['datequery2']) {
- $sql_extra3 .= protect_sprintf(sprintf(" AND item.created >= '%s' ", dbesc(datetime_convert(date_default_timezone_get(),'',$arr['datequery2']))));
+ $sql_extra3 .= protect_sprintf(sprintf(" AND item.created >= '%s' ", dbesc(datetime_convert('UTC','UTC',$arr['datequery2']))));
}
if(! array_key_exists('nouveau',$arr)) {
$sql_extra2 = " AND item.parent = item.id ";
- $sql_extra3 = '';
+// $sql_extra3 = '';
}
if($arr['search']) {
@@ -5274,3 +5405,212 @@ function asencode_person($p) {
return $ret;
}
+
+
+function send_profile_photo_activity($channel,$photo,$profile) {
+
+ // for now only create activities for the default profile
+
+ if(! intval($profile['is_default']))
+ return;
+
+ $arr = array();
+ $arr['item_thread_top'] = 1;
+ $arr['item_origin'] = 1;
+ $arr['item_wall'] = 1;
+ $arr['obj_type'] = ACTIVITY_OBJ_PHOTO;
+ $arr['verb'] = ACTIVITY_UPDATE;
+
+ $arr['object'] = json_encode(array(
+ 'type' => $arr['obj_type'],
+ 'id' => z_root() . '/photo/profile/l/' . $channel['channel_id'],
+ 'link' => array('rel' => 'photo', 'type' => $photo['type'], 'href' => z_root() . '/photo/profile/l/' . $channel['channel_id'])
+ ));
+
+ if(stripos($profile['gender'],t('female')) !== false)
+ $t = t('%1$s updated her %2$s');
+ elseif(stripos($profile['gender'],t('male')) !== false)
+ $t = t('%1$s updated his %2$s');
+ else
+ $t = t('%1$s updated their %2$s');
+
+ $ptext = '[zrl=' . z_root() . '/photos/' . $channel['channel_address'] . '/image/' . $photo['resource_id'] . ']' . t('profile photo') . '[/zrl]';
+
+ $ltext = '[zrl=' . z_root() . '/profile/' . $channel['channel_address'] . ']' . '[zmg=150x150]' . z_root() . '/photo/' . $photo['resource_id'] . '-4[/zmg][/zrl]';
+
+ $arr['body'] = sprintf($t,$channel['channel_name'],$ptext) . "\n\n" . $ltext;
+
+ $acl = new AccessList($channel);
+ $x = $acl->get();
+ $arr['allow_cid'] = $x['allow_cid'];
+
+ $arr['allow_gid'] = $x['allow_gid'];
+ $arr['deny_cid'] = $x['deny_cid'];
+ $arr['deny_gid'] = $x['deny_gid'];
+
+ $arr['uid'] = $channel['channel_id'];
+ $arr['aid'] = $channel['channel_account_id'];
+
+ $arr['owner_xchan'] = $channel['channel_hash'];
+ $arr['author_xchan'] = $channel['channel_hash'];
+
+ post_activity_item($arr);
+
+
+}
+
+
+
+
+
+function get_iconfig(&$item, $family, $key) {
+
+ $is_item = false;
+ if(is_array($item)) {
+ $is_item = true;
+ if((! array_key_exists('iconfig',$item)) || (! is_array($item['iconfig'])))
+ $item['iconfig'] = array();
+
+ if(array_key_exists('item_id',$item))
+ $iid = $item['item_id'];
+ else
+ $iid = $item['id'];
+ }
+ elseif(intval($item))
+ $iid = $item;
+
+ if(! $iid)
+ return false;
+
+ if(is_array($item) && array_key_exists('iconfig',$item) && is_array($item['iconfig'])) {
+ foreach($item['iconfig'] as $c) {
+ if($c['iid'] == $iid && $c['cat'] == $family && $c['k'] == $key)
+ return $c['v'];
+ }
+ }
+
+ $r = q("select * from iconfig where iid = %d and cat = '%s' and k = '%s' limit 1",
+ intval($iid),
+ dbesc($family),
+ dbesc($key)
+ );
+ if($r) {
+ $r[0]['v'] = ((preg_match('|^a:[0-9]+:{.*}$|s',$r[0]['v'])) ? unserialize($r[0]['v']) : $r[0]['v']);
+ if($is_item)
+ $item['iconfig'][] = $r[0];
+ return $r[0]['v'];
+ }
+ return false;
+
+}
+
+/**
+ * set_iconfig(&$item, $family, $key, $value, $sharing = false);
+ *
+ * $item - item array or item id. If passed an array the iconfig meta information is
+ * added to the item structure (which will need to be saved with item_store eventually).
+ * If passed an id, the DB is updated, but may not be federated and/or cloned.
+ * $family - namespace of meta variable
+ * $key - key of meta variable
+ * $value - value of meta variable
+ * $sharing - boolean (default false); if true the meta information is propagated with the item
+ * to other sites/channels, mostly useful when $item is an array and has not yet been stored/delivered.
+ * If the meta information is added after delivery and you wish it to be shared, it may be necessary to
+ * alter the item edited timestamp and invoke the delivery process on the updated item. The edited
+ * timestamp needs to be altered in order to trigger an item_store_update() at the receiving end.
+ */
+
+
+function set_iconfig(&$item, $family, $key, $value, $sharing = false) {
+
+ $dbvalue = ((is_array($value)) ? serialize($value) : $value);
+ $dbvalue = ((is_bool($dbvalue)) ? intval($dbvalue) : $dbvalue);
+
+ $is_item = false;
+ $idx = null;
+
+ if(is_array($item)) {
+ $is_item = true;
+ if((! array_key_exists('iconfig',$item)) || (! is_array($item['iconfig'])))
+ $item['iconfig'] = array();
+ elseif($item['iconfig']) {
+ for($x = 0; $x < count($item['iconfig']); $x ++) {
+ if($item['iconfig'][$x]['cat'] == $family && $item['iconfig'][$x]['k'] == $key) {
+ $idx = $x;
+ }
+ }
+ }
+ $entry = array('cat' => $family, 'k' => $key, 'v' => $value, 'sharing' => $sharing);
+
+ if(is_null($idx))
+ $item['iconfig'][] = $entry;
+ else
+ $item['iconfig'][$idx] = $entry;
+ return $value;
+ }
+
+ if(intval($item))
+ $iid = intval($item);
+
+ if(! $iid)
+ return false;
+
+ if(get_iconfig($item, $family, $key) === false) {
+ $r = q("insert into iconfig( iid, cat, k, v, sharing ) values ( %d, '%s', '%s', '%s', %d ) ",
+ intval($iid),
+ dbesc($family),
+ dbesc($key),
+ dbesc($dbvalue),
+ intval($sharing)
+ );
+ }
+ else {
+ $r = q("update iconfig set v = '%s', sharing = %d where iid = %d and cat = '%s' and k = '%s' ",
+ dbesc($dbvalue),
+ intval($sharing),
+ intval($iid),
+ dbesc($family),
+ dbesc($key)
+ );
+ }
+
+ if(! $r)
+ return false;
+
+ return $value;
+}
+
+
+
+function del_iconfig(&$item, $family, $key) {
+
+
+ $is_item = false;
+ $idx = null;
+
+ if(is_array($item)) {
+ $is_item = true;
+ if(is_array($item['iconfig'])) {
+ for($x = 0; $x < count($item['iconfig']); $x ++) {
+ if($item['iconfig'][$x]['cat'] == $family && $item['iconfig'][$x]['k'] == $key) {
+ unset($item['iconfig'][$x]);
+ }
+ }
+ }
+ return true;
+ }
+
+ if(intval($item))
+ $iid = intval($item);
+
+ if(! $iid)
+ return false;
+
+ return q("delete from iconfig where iid = %d and cat = '%s' and k = '%s' ",
+ intval($iid),
+ dbesc($family),
+ dbesc($key)
+ );
+
+}
+