aboutsummaryrefslogtreecommitdiffstats
path: root/mod/item.php
diff options
context:
space:
mode:
Diffstat (limited to 'mod/item.php')
-rw-r--r--mod/item.php266
1 files changed, 159 insertions, 107 deletions
diff --git a/mod/item.php b/mod/item.php
index 6ea434542..164b345f0 100644
--- a/mod/item.php
+++ b/mod/item.php
@@ -33,6 +33,8 @@ function item_post(&$a) {
$uid = local_user();
+ $channel = null;
+
if(x($_REQUEST,'dropitems')) {
require_once('include/items.php');
$arr_drop = explode(',',$_REQUEST['dropitems']);
@@ -150,26 +152,21 @@ function item_post(&$a) {
// can_comment_on_post() needs info from the following xchan_query
xchan_query($r);
+
$parent_item = $r[0];
$parent = $r[0]['id'];
// multi-level threading - preserve the info but re-parent to our single level threading
- //if(($parid) && ($parid != $parent))
- $thr_parent = $parent_mid;
-
-// if($parent_item['contact-id'] && $uid) {
-// $r = q("SELECT * FROM `contact` WHERE `id` = %d AND `uid` = %d LIMIT 1",
-// intval($parent_item['contact-id']),
-// intval($uid)
-// );
-// if(count($r))
-// $parent_contact = $r[0];
-// }
+
+ $thr_parent = $parent_mid;
+
}
+
$observer = $a->get_observer();
+
if($parent) {
logger('mod_item: item_post parent=' . $parent);
$can_comment = false;
@@ -219,20 +216,22 @@ function item_post(&$a) {
$orig_post = $i[0];
}
- $channel = null;
- if(local_user() && local_user() == $profile_uid) {
- $channel = $a->get_channel();
- }
- else {
- $r = q("SELECT channel.*, account.* FROM channel left join account on channel.channel_account_id = account.account_id
- where channel.channel_id = %d LIMIT 1",
- intval($profile_uid)
- );
- if(count($r))
- $channel = $r[0];
+ if(! $channel) {
+ if(local_user() && local_user() == $profile_uid) {
+ $channel = $a->get_channel();
+ }
+ else {
+ // posting as yourself but not necessarily to a channel you control
+ $r = q("select * from channel left join account on channel_account_id = account_id where channel_id = %d LIMIT 1",
+ intval($profile_uid)
+ );
+ if($r)
+ $channel = $r[0];
+ }
}
+
if(! $channel) {
logger("mod_item: no channel.");
if(x($_REQUEST,'return'))
@@ -260,11 +259,17 @@ function item_post(&$a) {
}
+
+
if($orig_post) {
- $str_group_allow = $orig_post['allow_gid'];
- $str_contact_allow = $orig_post['allow_cid'];
- $str_group_deny = $orig_post['deny_gid'];
- $str_contact_deny = $orig_post['deny_cid'];
+ $str_group_allow = ((array_key_exists('group_allow',$_REQUEST))
+ ? perms2str($_REQUEST['group_allow']) : $orig_post['allow_gid']);
+ $str_contact_allow = ((array_key_exists('contact_allow',$_REQUEST))
+ ? perms2str($_REQUEST['contact_allow']) : $orig_post['allow_cid']);
+ $str_group_deny = ((array_key_exists('group_deny',$_REQUEST))
+ ? perms2str($_REQUEST['group_deny']) : $orig_post['deny_gid']);
+ $str_contact_deny = ((array_key_exists('contact_deny',$_REQUEST))
+ ? perms2str($_REQUEST['contact_deny']) : $orig_post['deny_cid']);
$location = $orig_post['location'];
$coord = $orig_post['coord'];
$verb = $orig_post['verb'];
@@ -306,6 +311,7 @@ function item_post(&$a) {
$str_contact_deny = perms2str($_REQUEST['contact_deny']);
}
+
$location = notags(trim($_REQUEST['location']));
$coord = notags(trim($_REQUEST['coord']));
$verb = notags(trim($_REQUEST['verb']));
@@ -360,20 +366,18 @@ function item_post(&$a) {
}
}
-
-
$post_type = notags(trim($_REQUEST['type']));
$mimetype = notags(trim($_REQUEST['mimetype']));
if(! $mimetype)
$mimetype = 'text/bbcode';
- // Verify ability to use html or php!!!
-
if($preview) {
$body = z_input_filter($profile_uid,$body,$mimetype);
}
+ // Verify ability to use html or php!!!
+
$execflag = false;
if($mimetype === 'application/x-php') {
@@ -496,8 +500,6 @@ function item_post(&$a) {
$tagged = array();
- $private_forum = false;
-
if(count($tags)) {
$first_access_tag = true;
foreach($tags as $tag) {
@@ -516,9 +518,9 @@ function item_post(&$a) {
continue;
$success = handle_tag($a, $body, $access_tag, $str_tags, (local_user()) ? local_user() : $profile_uid , $tag);
- logger('handle_tag: ' . print_r($success,tue), LOGGER_DEBUG);
+ logger('handle_tag: ' . print_r($success,tue), LOGGER_DATA);
if(($access_tag) && (! $parent_item)) {
- logger('access_tag: ' . $tag . ' ' . print_r($access_tag,true), LOGGER_DEBUG);
+ logger('access_tag: ' . $tag . ' ' . print_r($access_tag,true), LOGGER_DATA);
if ($first_access_tag) {
$str_contact_allow = '';
$str_group_allow = '';
@@ -544,22 +546,12 @@ function item_post(&$a) {
'url' => $success['url']
);
}
-// if(is_array($success['contact']) && intval($success['contact']['prv'])) {
-// $private_forum = true;
-// $private_id = $success['contact']['id'];
-// }
}
}
// logger('post_tags: ' . print_r($post_tags,true));
- if(($private_forum) && (! $parent) && (! $private)) {
- // we tagged a private forum in a top level post and the message was public.
- // Restrict it.
- $private = 1;
- $str_contact_allow = '<' . $private_id . '>';
- }
$attachments = '';
$match = false;
@@ -573,7 +565,7 @@ function item_post(&$a) {
if($r['success']) {
$attachments[] = array(
'href' => $a->get_baseurl() . '/attach/' . $r['data']['hash'],
- 'length' => $r['data']['filesize'],
+ 'length' => $r['data']['filesize'],
'type' => $r['data']['filetype'],
'title' => urlencode($r['data']['filename']),
'revision' => $r['data']['revision']
@@ -601,7 +593,6 @@ function item_post(&$a) {
}
$item_flags |= ITEM_UNSEEN;
-// $item_restrict |= ITEM_VISIBLE;
if($post_type === 'wall' || $post_type === 'wall-comment')
$item_flags = $item_flags | ITEM_WALL;
@@ -652,11 +643,11 @@ function item_post(&$a) {
$datarray['owner_xchan'] = (($owner_hash) ? $owner_hash : $owner_xchan['xchan_hash']);
$datarray['author_xchan'] = $observer['xchan_hash'];
$datarray['created'] = $created;
- $datarray['edited'] = datetime_convert();
+ $datarray['edited'] = (($orig_post) ? datetime_convert() : $created);
$datarray['expires'] = $expires;
- $datarray['commented'] = datetime_convert();
- $datarray['received'] = datetime_convert();
- $datarray['changed'] = datetime_convert();
+ $datarray['commented'] = (($orig_post) ? datetime_convert() : $created);
+ $datarray['received'] = (($orig_post) ? datetime_convert() : $created);
+ $datarray['changed'] = (($orig_post) ? datetime_convert() : $created);
$datarray['mid'] = $mid;
$datarray['parent_mid'] = $parent_mid;
$datarray['mimetype'] = $mimetype;
@@ -757,31 +748,12 @@ function item_post(&$a) {
$post = item_store($datarray,$execflag);
-
$post_id = $post['item_id'];
if($post_id) {
logger('mod_item: saved item ' . $post_id);
if($parent) {
-
- $r = q("UPDATE `item` SET `changed` = '%s' WHERE `parent` = %d ",
- dbesc(datetime_convert()),
- intval($parent)
- );
-
- // Inherit ACL's from the parent item.
-
- $r = q("UPDATE `item` SET `allow_cid` = '%s', `allow_gid` = '%s', `deny_cid` = '%s', `deny_gid` = '%s', `item_private` = %d
- WHERE `id` = %d LIMIT 1",
- dbesc($parent_item['allow_cid']),
- dbesc($parent_item['allow_gid']),
- dbesc($parent_item['deny_cid']),
- dbesc($parent_item['deny_gid']),
- intval($parent_item['item_private']),
- intval($post_id)
- );
-
if($datarray['owner_xchan'] != $datarray['author_xchan']) {
notification(array(
'type' => NOTIFY_COMMENT,
@@ -796,7 +768,6 @@ function item_post(&$a) {
));
}
-
}
else {
$parent = $post_id;
@@ -814,25 +785,10 @@ function item_post(&$a) {
}
}
- // fallback so that parent always gets set to non-zero.
-
- if(! $parent)
- $parent = $post_id;
-
- $r = q("UPDATE `item` SET `parent` = %d, `parent_mid` = '%s', `changed` = '%s'
- WHERE `id` = %d LIMIT 1",
- intval($parent),
- dbesc(($parent == $post_id) ? $mid : $parent_item['mid']),
- dbesc(datetime_convert()),
- intval($post_id)
- );
-
// photo comments turn the corresponding item visible to the profile wall
// This way we don't see every picture in your new photo album posted to your wall at once.
// They will show up as people comment on them.
-// fixme set item visible as well
-
if($parent_item['item_restrict'] & ITEM_HIDDEN) {
$r = q("UPDATE `item` SET `item_restrict` = %d WHERE `id` = %d LIMIT 1",
intval($parent_item['item_restrict'] - ITEM_HIDDEN),
@@ -890,9 +846,40 @@ function item_content(&$a) {
require_once('include/security.php');
- if(($a->argc == 3) && ($a->argv[1] === 'drop') && intval($a->argv[2])) {
+ if((argc() == 3) && (argv(1) === 'drop') && intval(argv(2))) {
require_once('include/items.php');
- drop_item($a->argv[2]);
+ $i = q("select id, uid, author_xchan, owner_xchan, source_xchan, item_restrict from item where id = %d and uid = %d limit 1",
+ intval(argv(2)),
+ intval(local_user())
+ );
+
+ if($i) {
+ $can_delete = false;
+ $local_delete = false;
+ if(local_user() && local_user() == $i[0]['uid'])
+ $local_delete = true;
+
+ $ob_hash = get_observer_hash();
+ if($ob_hash && ($ob_hash === $i[0]['author_xchan'] || $ob_hash === $i[0]['owner_xchan'] || $ob_hash === $i[0]['source_xchan']))
+ $can_delete = true;
+
+ if(! ($can_delete || $local_delete)) {
+ notice( t('Permission denied.') . EOL);
+ return;
+ }
+
+ // if this is a different page type or it's just a local delete
+ // but not by the item author or owner, do a simple deletion
+
+ if($i[0]['item_restrict'] || ($local_delete && (! $can_delete))) {
+ drop_item($i[0]['id']);
+ }
+ else {
+ // complex deletion that needs to propagate and be performed in phases
+ drop_item($i[0]['id'],true,DROPITEM_PHASE1);
+ tag_deliver($i[0]['uid'],$i[0]['id']);
+ }
+ }
}
}
@@ -942,8 +929,16 @@ function handle_tag($a, &$body, &$access_tag, &$str_tags, $profile_uid, $tag) {
$replaced = true;
}
if(! $replaced) {
+
//base tag has the tags name only
- $basetag = str_replace('_',' ',substr($tag,1));
+
+ if((substr($tag,0,7) === '#&quot;') && (substr($tag,-6,6) === '&quot;')) {
+ $basetag = substr($tag,7);
+ $basetag = substr($basetag,0,-6);
+ }
+ else
+ $basetag = str_replace('_',' ',substr($tag,1));
+
//create text for link
$url = $a->get_baseurl() . '/search?tag=' . rawurlencode($basetag);
$newtag = '#[zrl=' . $a->get_baseurl() . '/search?tag=' . rawurlencode($basetag) . ']' . $basetag . '[/zrl]';
@@ -962,40 +957,83 @@ function handle_tag($a, &$body, &$access_tag, &$str_tags, $profile_uid, $tag) {
}
//is it a person tag?
+
if(strpos($tag,'@') === 0) {
+
+ // The @! tag will alter permissions
$exclusive = ((strpos($tag,'!') === 1) ? true : false);
+
//is it already replaced?
if(strpos($tag,'[zrl='))
return $replaced;
- $stat = false;
+
//get the person's name
- $name = substr($tag,(($exclusive) ? 2 : 1));
- $newname = $name;
- $alias = '';
+
+ $name = substr($tag,(($exclusive) ? 2 : 1)); // The name or name fragment we are going to replace
+ $newname = $name; // a copy that we can mess with
$tagcid = 0;
+ $r = null;
+
// is it some generated name?
+ $forum = false;
+ $trailing_plus_name = false;
+
+ // @channel+ is a forum or network delivery tag
+
+ if(substr($newname,-1,1) === '+') {
+ $forum = true;
+ $newname = substr($newname,0,-1);
+ }
+
+ // Here we're looking for an address book entry as provided by the auto-completer
+ // of the form something+nnn where nnn is an abook_id or the first chars of xchan_hash
+
if(strrpos($newname,'+')) {
//get the id
- $tagcid = intval(substr($newname,strrpos($newname,'+') + 1));
+
+ if(strrpos($tagcid,' '))
+ $tagcid = substr($tagcid,0,strrpos($tagcid,' '));
+
+ $tagcid = substr($newname,strrpos($newname,'+') + 1);
+
+ if(strlen($tagcid) < 16)
+ $abook_id = intval($tagcid);
//remove the next word from tag's name
if(strpos($name,' ')) {
$name = substr($name,0,strpos($name,' '));
}
- if($tagcid) { // if there was an id
+ if($abook_id) { // if there was an id
// select channel with that id from the logged in user's address book
$r = q("SELECT * FROM abook left join xchan on abook_xchan = xchan_hash
WHERE abook_id = %d AND abook_channel = %d LIMIT 1",
- intval($tagcid),
+ intval($abook_id),
intval($profile_uid)
);
}
+ else {
+ $r = q("SELECT * FROM xchan
+ WHERE xchan_hash like '%s%%' LIMIT 1",
+ dbesc($tagcid)
+ );
+ }
}
- else {
- $newname = str_replace('_',' ',$name);
+ if(! $r) {
+
+ // look for matching names in the address book
+
+ // Two ways to deal with spaces - doube quote the name or use underscores
+ // we see this after input filtering so quotes have been html entity encoded
+
+ if((substr($name,0,6) === '&quot;') && (substr($name,-6,6) === '&quot;')) {
+ $newname = substr($name,6);
+ $newname = substr($newname,0,-6);
+ }
+ else
+ $newname = str_replace('_',' ',$name);
//select someone from this user's contacts by name
$r = q("SELECT * FROM abook left join xchan on abook_xchan = xchan_hash
@@ -1012,14 +1050,28 @@ function handle_tag($a, &$body, &$access_tag, &$str_tags, $profile_uid, $tag) {
intval($profile_uid)
);
}
+
+ if(! $r) {
+
+ // it's possible somebody has a name ending with '+', which we stripped off as a forum indicator
+ // This is very rare but we want to get it right.
+
+ $r = q("SELECT * FROM abook left join xchan on abook_xchan = xchan_hash
+ WHERE xchan_name = '%s' AND abook_channel = %d LIMIT 1",
+ dbesc($newname . '+'),
+ intval($profile_uid)
+ );
+ if($r)
+ $trailing_plus_name = true;
+ }
}
- // $r is set, if someone could be selected
+ // $r is set if we found something
if($r) {
$profile = $r[0]['xchan_url'];
$newname = $r[0]['xchan_name'];
- //add person's id to $access_tag if exclusive
+ // add the channel's xchan_hash to $access_tag if exclusive
if($exclusive) {
$access_tag .= 'cid:' . $r[0]['xchan_hash'];
}
@@ -1044,20 +1096,21 @@ function handle_tag($a, &$body, &$access_tag, &$str_tags, $profile_uid, $tag) {
}
$channel = get_app()->get_channel();
if($channel) {
- $newtag = '@' . (($exclusive) ? '!' : '') . '[zrl=' . z_root() . '/channel/' . $channel['channel_address'] . ']' . $newname . '[/zrl]';
+ $newtag = '@' . (($exclusive) ? '!' : '') . '[zrl=' . z_root() . '/channel/' . $channel['channel_address'] . ']' . $newname . '[/zrl]';
$body = str_replace('@' . (($exclusive) ? '!' : '') . $name, $newtag, $body);
}
}
}
}
- //if there is an url for this persons profile
+ // if there is an url for this channel
+
if(isset($profile)) {
$replaced = true;
//create profile link
$profile = str_replace(',','%2c',$profile);
$url = $profile;
- $newtag = '@' . (($exclusive) ? '!' : '') . '[zrl=' . $profile . ']' . $newname . '[/zrl]';
+ $newtag = '@' . (($exclusive) ? '!' : '') . '[zrl=' . $profile . ']' . $newname . (($forum && ! $trailing_plus_name) ? '+' : '') . '[/zrl]';
$body = str_replace('@' . (($exclusive) ? '!' : '') . $name, $newtag, $body);
//append tag to str_tags
if(! stristr($str_tags,$newtag)) {
@@ -1077,8 +1130,8 @@ function fix_attached_photo_permissions($uid,$xchan_hash,$body,
$match = null;
// match img and zmg image links
- if(preg_match_all("/\[[zi]mg\](.*?)\[\/[zi]mg\]/",$body,$match)) {
- $images = $match[1];
+ if(preg_match_all("/\[[zi]mg(.*?)\](.*?)\[\/[zi]mg\]/",$body,$match)) {
+ $images = $match[2];
if($images) {
foreach($images as $image) {
if(! stristr($image,get_app()->get_baseurl() . '/photo/'))
@@ -1102,14 +1155,13 @@ function fix_attached_photo_permissions($uid,$xchan_hash,$body,
if($r) {
$r = q("UPDATE photo SET allow_cid = '%s', allow_gid = '%s', deny_cid = '%s', deny_gid = '%s'
- WHERE resource_id = '%s' AND uid = %d AND album = '%s' ",
+ WHERE resource_id = '%s' AND uid = %d ",
dbesc($str_contact_allow),
dbesc($str_group_allow),
dbesc($str_contact_deny),
dbesc($str_group_deny),
dbesc($image_uri),
- intval($uid),
- dbesc( t('Wall Photos'))
+ intval($uid)
);
// also update the linked item (which is probably invisible)