more work on polls

This commit is contained in:
zotlabs 2020-02-06 18:50:18 -08:00
parent d7b933cf8c
commit 6f6e67078c
6 changed files with 72 additions and 67 deletions

View file

@ -503,8 +503,12 @@ class Activity {
}
$ret['published'] = datetime_convert('UTC','UTC',$i['created'],ATOM_TIME);
if ($i['created'] !== $i['edited'])
if ($i['created'] !== $i['edited']) {
$ret['updated'] = datetime_convert('UTC','UTC',$i['edited'],ATOM_TIME);
if ($ret['type'] === 'Create') {
$ret['type'] = 'Update';
}
}
if ($i['app']) {
$ret['generator'] = [ 'type' => 'Application', 'name' => $i['app'] ];
}
@ -823,10 +827,11 @@ class Activity {
}
}
if ($i['title']) {
$ret['name'] = $i['title'];
}
if ($i['mimetype'] === 'text/bbcode') {
if ($i['title']) {
$ret['name'] = $i['title'];
}
if ($i['summary']) {
$ret['summary'] = bbcode($i['summary'], [ $bbopts => true ]);
}
@ -1145,10 +1150,6 @@ class Activity {
static function activity_mapper($verb) {
if ($verb === 'Answer') {
return 'Note';
}
if (strpos($verb,'/') === false) {
return $verb;
}
@ -1771,6 +1772,10 @@ class Activity {
return false;
}
$o = json_decode($item['obj'],true);
if ($o && array_key_exists('anyOf',$o)) {
$multi = true;
@ -1815,6 +1820,15 @@ class Activity {
}
}
}
if ($item['comments_closed'] > NULL_DATE) {
if ($item['comments_closed'] > datetime_convert()) {
$o['closed'] = datetime_convert('UTC','UTC',$item['comments_closed'], ATOM_TIME);
// set this to force an update
$answer_found = true;
}
}
logger('updated_poll: ' . print_r($o,true),LOGGER_DATA);
if ($answer_found && ! $found) {
$x = q("update item set obj = '%s', edited = '%s' where id = %d",
@ -1839,9 +1853,15 @@ class Activity {
if (is_array($act->obj)) {
$content = self::get_content($act->obj);
}
// These activities should have been handled separately in the Inbox module and should not be turned into posts
if (in_array($act->type, ['Follow', 'Accept', 'Reject', 'Create', 'Update'])
&& is_array($a->obj) && array_key_exists('type',$a->obj) && ActivityStreams::is_an_actor($a->obj['type'])) {
return false;
}
$s['owner_xchan'] = $act->actor['id'];
$s['author_xchan'] = $act->actor['id'];
@ -1874,24 +1894,6 @@ class Activity {
$s['mid'] = $s['parent_mid'] = $act->id;
}
if ($act->obj['type'] === 'Note' && $act->data['name']) {
$parent = self::fetch($act->parent_id);
if ($parent && array_path_exists('object/type',$parent) && $parent['object']['type'] === 'Question') {
$s['mid'] = $act->id;
$s['replyto'] = $act->replyto;
$s['verb'] = 'Answer';
$content['content'] = EMPTY_STR;
}
}
if ($act->type === 'Note' && $act->obj['type'] === 'Question' && $act->data['name']) {
$s['mid'] = $act->id;
$s['parent_mid'] = $act->obj['id'];
$s['replyto'] = $act->replyto;
$s['verb'] = 'Answer';
$content['content'] = EMPTY_STR;
}
if (in_array($act->type, [ 'Like', 'Dislike', 'Flag', 'Block', 'Announce', 'Accept', 'Reject',
'TentativeAccept', 'TentativeReject', 'emojiReaction', 'EmojiReaction', 'EmojiReact' ])) {
@ -1997,11 +1999,6 @@ class Activity {
$s['verb'] = self::activity_mapper($act->type);
if ($act->type === 'Note' && $act->obj['type'] === 'Question' && $act->data['name'] && ! $content['content']) {
$s['verb'] = 'Answer';
$s['title'] = purify_html($act->data['name']);
}
// Mastodon does not provide update timestamps when updating poll tallies which means race conditions may occur here.
if ($act->type === 'Update' && $act->obj['type'] === 'Question' && $s['edited'] === $s['created']) {
$s['edited'] = datetime_convert();
@ -2316,7 +2313,7 @@ class Activity {
$allowed = false;
if ($is_child_node) {
$p = q("select id from item where mid = '%s' and uid = %d and item_wall = 1",
$p = q("select id, obj_type from item where mid = '%s' and uid = %d and item_wall = 1",
dbesc($item['parent_mid']),
intval($channel['channel_id'])
);
@ -2342,6 +2339,12 @@ class Activity {
$allowed = false;
}
}
if ($p && $p[0]['obj_type'] === 'Question') {
if ($item['obj_type'] === 'Note' && $item['title'] && (! $item['content']) && (! $item['summary'])) {
$item['obj_type'] = 'Answer';
}
}
}
elseif (perm_is_allowed($channel['channel_id'],$observer_hash,'send_stream') || ($is_sys_channel && $pubstream)) {
$allowed = true;
@ -2567,14 +2570,7 @@ class Activity {
Activity::actor_store($a->actor['id'],$a->actor);
}
// we don't support Create/Person which may have landed here accidentally due to an implied_create
// added to an incorrectly translated Hubzilla like of a "new friend" activity. There is no perfect mapping from that AS1
// construct to AS2. The above fetch of the parent will return a naked Person object which is turned into a Create by the AS parser.
// There may be other solutions but this should catch it.
if ($a->implied_create && is_array($a->obj) && array_key_exists('type',$a->obj) && ActivityStreams::is_an_actor($a->obj['type'])) {
return false;
}
$item = Activity::decode_note($a);

View file

@ -1784,7 +1784,7 @@ class Libzot {
// As a side effect we will also do a preliminary check that we have the top-level-post, otherwise
// processing it is pointless.
$r = q("select route, id, parent_mid, mid, owner_xchan, item_private from item where mid = '%s' and uid = %d limit 1",
$r = q("select route, id, parent_mid, mid, owner_xchan, item_private, obj_type from item where mid = '%s' and uid = %d limit 1",
dbesc($arr['parent_mid']),
intval($channel['channel_id'])
);
@ -1794,6 +1794,15 @@ class Libzot {
$arr['thr_parent'] = $arr['parent_mid'];
$arr['parent_mid'] = $r[0]['parent_mid'];
}
if ($r[0]['obj_type'] === 'Question') {
// route checking doesn't work here because we've changed the privacy
$r[0]['route'] = EMPTY_STR;
// If this is a poll response, convert the obj_type to our (internal-only) "Answer" type
if ($arr['obj_type'] === 'Note' && $arr['title'] && (! $arr['content']) && (! $arr['summary'])) {
$arr['obj_type'] = 'Answer';
}
}
}
else {
$DR->update('comment parent not found');
@ -1816,7 +1825,8 @@ class Libzot {
}
continue;
}
if ($relay || $friendofriend || (intval($r[0]['item_private']) === 0 && intval($arr['item_private']) === 0)) {
// reset the route in case it travelled a great distance upstream
// use our parent's route so when we go back downstream we'll match

View file

@ -880,13 +880,6 @@ class Item extends Controller {
// and will require alternatives for alternative content-types (text/html, text/markdown, text/plain, etc.)
// we may need virtual or template classes to implement the possible alternatives
// $obj = $this->extract_poll_data($body);
// if ($obj) {
// $obj['attributedTo'] = channel_url($channel);
// $datarray['obj'] = $obj;
// $obj_type = 'Question';
// }
if(strpos($body,'[/summary]') !== false) {
$match = '';
$cnt = preg_match("/\[summary\](.*?)\[\/summary\]/ism",$body,$match);
@ -1109,23 +1102,14 @@ class Item extends Controller {
}
}
// this will generally only happen when creating a poll and it cannot be
// done earlier because the $mid has only just now been defined
$obj = $this->extract_poll_data($body,[ 'item_private' => $private, 'allow_cid' => $str_contact_allow, 'allow_gid' => $str_contact_deny ]);
if ($obj) {
$obj['url'] = $mid;
$obj['attributedTo'] = channel_url($channel);
$datarray['obj'] = $obj;
$obj_type = 'Question';
}
if ($datarray['obj'] && ! $datarray['obj']['url']) {
$datarray['obj']['url'] = $mid;
}
if(! $parent_mid) {
$parent_mid = $mid;
}

View file

@ -31,7 +31,6 @@ class Vote extends Controller {
);
}
if ($fetch && $fetch[0]['obj_type'] === 'Question') {
$obj = json_decode($fetch[0]['obj'],true);
@ -80,22 +79,34 @@ class Vote extends Controller {
$item = [];
$item['aid'] = $channel['channel_account_id'];
$item['uid'] = $channel['channel_id'];
$item['item_origin'] = true;
$item['parent'] = $fetch[0]['id'];
$item['parent_mid'] = $fetch[0]['mid'];
$item['thr_parent'] = $fetch[0]['mid'];
$item['uuid'] = new_uuid();
$item['mid'] = z_root() . '/item/' . $item['uuid'];
$item['verb'] = 'Answer';
$item['verb'] = 'Create';
$item['title'] = $res;
$item['author_xchan'] = $channel['channel_hash'];
$item['owner_xchan'] = $fetch[0]['author_xchan'];
$item['allow_cid'] = '<' . $fetch[0]['author_xchan'] . '>';
$item['item_private'] = 1;
$item['obj'] = $obj;
$item['obj_type'] = 'Question';
// These two are placeholder values that will be reset after
// we encode the item
$item['obj_type'] = 'Note';
$item['author'] = channelx_by_n($channel['channel_id']);
$item['obj'] = Activity::encode_item($item,((get_config('system','activitypub')) ? true : false));
// now reset the placeholders
$item['obj_type'] = 'Answer';
unset($item['author']);
$x = item_store($item);
retain_item($fetch[0]['id']);

View file

@ -403,11 +403,15 @@ function count_descendants($item) {
* @return boolean
*/
function visible_activity($item) {
$hidden_activities = [ ACTIVITY_LIKE, ACTIVITY_DISLIKE, 'Answer' ];
$hidden_activities = [ ACTIVITY_LIKE, ACTIVITY_DISLIKE ];
if(intval($item['item_notshown']))
return false;
if ($item['obj_type'] === 'Answer') {
return false;
}
foreach($hidden_activities as $act) {
if((activity_match($item['verb'], $act)) && ($item['mid'] != $item['parent_mid'])) {
return false;

View file

@ -1813,7 +1813,7 @@ function item_store($arr, $allow_exec = false, $deliver = true, $linkid = true)
if(intval($r[0]['item_uplink']) && (! $r[0]['item_private']))
$arr['item_private'] = 0;
if(in_array($arr['verb'], ['Note','Answer']) && $arr['obj_type'] === 'Question' && intval($r[0]['item_wall'])) {
if(in_array($arr['obj_type'], ['Note','Answer']) && $r[0]['obj_type'] === 'Question' && intval($r[0]['item_wall'])) {
Activity::update_poll($r[0],$arr['mid'],$arr['title']);
}
}