aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorzotlabs <mike@macgirvin.com>2017-06-18 22:25:41 -0700
committerzotlabs <mike@macgirvin.com>2017-06-18 22:25:41 -0700
commitb917cf1eccc62f5f533c0a61ffd699764b39e404 (patch)
tree09c849b0a4e545a360ad6910a2cf322d98dbc494
parent4d5469f27ed2bea05dcfc4c286a9d14413a9e6b6 (diff)
downloadvolse-hubzilla-b917cf1eccc62f5f533c0a61ffd699764b39e404.tar.gz
volse-hubzilla-b917cf1eccc62f5f533c0a61ffd699764b39e404.tar.bz2
volse-hubzilla-b917cf1eccc62f5f533c0a61ffd699764b39e404.zip
allow moderated comments like wordpress if permissions are compatible
-rw-r--r--Zotlabs/Access/PermissionLimits.php2
-rw-r--r--Zotlabs/Lib/Enotify.php11
-rw-r--r--Zotlabs/Lib/ThreadItem.php8
-rw-r--r--Zotlabs/Lib/ThreadStream.php2
-rw-r--r--Zotlabs/Module/Item.php31
-rw-r--r--Zotlabs/Module/Moderate.php77
-rw-r--r--Zotlabs/Module/Settings/Channel.php2
-rw-r--r--include/channel.php66
-rw-r--r--include/conversation.php22
-rwxr-xr-xinclude/items.php2
-rw-r--r--view/js/main.js2
-rwxr-xr-xview/tpl/comment_item.tpl7
-rwxr-xr-xview/tpl/search_item.tpl11
13 files changed, 221 insertions, 22 deletions
diff --git a/Zotlabs/Access/PermissionLimits.php b/Zotlabs/Access/PermissionLimits.php
index 909b654d5..8caeedb91 100644
--- a/Zotlabs/Access/PermissionLimits.php
+++ b/Zotlabs/Access/PermissionLimits.php
@@ -10,7 +10,7 @@ class PermissionLimits {
$perms = Permissions::Perms();
$limits = array();
foreach($perms as $k => $v) {
- if(strstr($k,'view'))
+ if(strstr($k,'view') || $k === 'post_comments')
$limits[$k] = PERMS_PUBLIC;
else
$limits[$k] = PERMS_SPECIFIC;
diff --git a/Zotlabs/Lib/Enotify.php b/Zotlabs/Lib/Enotify.php
index a10675a87..114021568 100644
--- a/Zotlabs/Lib/Enotify.php
+++ b/Zotlabs/Lib/Enotify.php
@@ -170,6 +170,7 @@ class Enotify {
xchan_query($p);
+ $moderated = (($p[0]['item_blocked'] = ITEM_MODERATED) ? true : false);
$item_post_type = item_post_type($p[0]);
// $private = $p[0]['item_private'];
@@ -208,13 +209,21 @@ class Enotify {
// Before this we have the name of the replier on the subject rendering
// differents subjects for messages on the same thread.
- $subject = sprintf( t('[$Projectname:Notify] Comment to conversation #%1$d by %2$s'), $parent_id, $sender['xchan_name']);
+ if($moderated)
+ $subject = sprintf( t('[$Projectname:Notify] Moderated Comment to conversation #%1$d by %2$s'), $parent_id, $sender['xchan_name']);
+ else
+ $subject = sprintf( t('[$Projectname: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;
$sitelink = t('Please visit %s to view and/or reply to the conversation.');
$tsitelink = sprintf( $sitelink, $siteurl );
$hsitelink = sprintf( $sitelink, '<a href="' . $siteurl . '">' . $sitename . '</a>');
+ if($moderated) {
+ $tsitelink .= "\n\n" . sprintf( t('Please visit %s to approve or reject this comment.'), z_root() . '/moderate' );
+ $hsitelink .= "\n\n" . sprintf( t('Please visit %s to approve or reject this comment.'), z_root() . '/moderate' );
+ }
+
}
if ($params['type'] == NOTIFY_LIKE) {
diff --git a/Zotlabs/Lib/ThreadItem.php b/Zotlabs/Lib/ThreadItem.php
index ff4e3205e..50c67c466 100644
--- a/Zotlabs/Lib/ThreadItem.php
+++ b/Zotlabs/Lib/ThreadItem.php
@@ -741,8 +741,12 @@ class ThreadItem {
'$feature_encrypt' => ((feature_enabled($conv->get_profile_owner(),'content_encrypt')) ? true : false),
'$encrypt' => t('Encrypt text'),
'$cipher' => $conv->get_cipher(),
- '$sourceapp' => \App::$sourcename
-
+ '$sourceapp' => \App::$sourcename,
+ '$observer' => get_observer_hash(),
+ '$anoncomments' => perm_is_allowed($conv->get_profile_owner(),'','post_comments'),
+ '$anonname' => [ 'anonname', t('Your full name (required)'),'','' ],
+ '$anonmail' => [ 'anonmail', t('Your email address (required)'),'','' ],
+ '$anonurl' => [ 'anonurl', t('Your website URL (optional)'),'','' ]
));
return $comment_box;
diff --git a/Zotlabs/Lib/ThreadStream.php b/Zotlabs/Lib/ThreadStream.php
index beb626f31..1fd746c38 100644
--- a/Zotlabs/Lib/ThreadStream.php
+++ b/Zotlabs/Lib/ThreadStream.php
@@ -158,7 +158,7 @@ class ThreadStream {
if(intval($item->get_data_value('item_nocomment'))) {
$item->set_commentable(false);
}
- elseif(($this->observer) && (! $item->is_commentable())) {
+ elseif(! $item->is_commentable()) {
if((array_key_exists('owner',$item->data)) && intval($item->data['owner']['abook_self']))
$item->set_commentable(perm_is_allowed($this->profile_owner,$ob_hash,'post_comments'));
else
diff --git a/Zotlabs/Module/Item.php b/Zotlabs/Module/Item.php
index ec36c22d8..952ecf487 100644
--- a/Zotlabs/Module/Item.php
+++ b/Zotlabs/Module/Item.php
@@ -33,7 +33,7 @@ class Item extends \Zotlabs\Web\Controller {
// This will change. Figure out who the observer is and whether or not
// they have permission to post here. Else ignore the post.
- if((! local_channel()) && (! remote_channel()) && (! x($_REQUEST,'commenter')))
+ if((! local_channel()) && (! remote_channel()) && (! x($_REQUEST,'anonname')))
return;
$uid = local_channel();
@@ -77,7 +77,7 @@ class Item extends \Zotlabs\Web\Controller {
call_hooks('post_local_start', $_REQUEST);
- // logger('postvars ' . print_r($_REQUEST,true), LOGGER_DATA);
+ // logger('postvars ' . print_r($_REQUEST,true), LOGGER_DATA);
$api_source = ((x($_REQUEST,'api_source') && $_REQUEST['api_source']) ? true : false);
@@ -205,10 +205,29 @@ class Item extends \Zotlabs\Web\Controller {
$route = $parent_item['route'];
}
+
+ $moderated = false;
- if(! $observer)
+ if(! $observer) {
$observer = \App::get_observer();
+ if(! $observer) {
+ $observer = anon_identity_init($_REQUEST);
+ if($observer) {
+ $moderated = true;
+ $remote_xchan = $remote_observer = $observer;
+ }
+ }
+ }
+ if(! $observer) {
+ notice( t('Permission denied.') . EOL) ;
+ if($api_source)
+ return ( [ 'success' => false, 'message' => 'permission denied' ] );
+ if(x($_REQUEST,'return'))
+ goaway(z_root() . "/" . $return_path );
+ killme();
+ }
+
if($parent) {
logger('mod_item: item_post parent=' . $parent);
$can_comment = false;
@@ -312,7 +331,7 @@ class Item extends \Zotlabs\Web\Controller {
$walltowall = false;
$walltowall_comment = false;
- if($remote_xchan)
+ if($remote_xchan && ! $moderated)
$observer = $remote_observer;
if($observer) {
@@ -996,6 +1015,10 @@ class Item extends \Zotlabs\Web\Controller {
\Zotlabs\Daemon\Master::Summon(array('Notifier', $notify_type, $post_id));
logger('post_complete');
+
+ if($moderated) {
+ info(t('Your comment is awaiting approval.') . EOL);
+ }
// figure out how to return, depending on from whence we came
diff --git a/Zotlabs/Module/Moderate.php b/Zotlabs/Module/Moderate.php
new file mode 100644
index 000000000..b7f05e4b2
--- /dev/null
+++ b/Zotlabs/Module/Moderate.php
@@ -0,0 +1,77 @@
+<?php
+
+namespace Zotlabs\Module;
+
+require_once('include/conversation.php');
+
+
+class Moderate extends \Zotlabs\Web\Controller {
+
+
+ function get() {
+ if(! local_channel()) {
+ notice( t('Permission denied.') . EOL);
+ return;
+ }
+
+
+ if(argc() > 2) {
+ $post_id = intval(argv(1));
+ if(! $post_id)
+ goaway(z_root() . '/moderate');
+
+ $action = argv(2);
+
+ $r = q("select * from item where uid = %d and id = %d and item_blocked = %d limit 1",
+ intval(local_channel()),
+ intval($post_id),
+ intval(ITEM_MODERATED)
+ );
+
+
+
+ if($r) {
+ if($action === 'approve') {
+ q("update item set item_blocked = 0 where uid = %d and id = %d",
+ intval(local_channel()),
+ intval($post_id)
+ );
+ notice( t('Comment approved') . EOL);
+ }
+ elseif($action === 'drop') {
+ drop_item($post_id,false);
+ notice( t('Comment deleted') . EOL);
+ }
+ }
+
+ $r = q("select * from item where id = %d",
+ intval($post_id)
+ );
+ if($r) {
+ xchan_query($r);
+ $sync_item = fetch_post_tags($r);
+ build_sync_packet(local_channel(),array('item' => array(encode_item($sync_item[0],true))));
+ }
+ goaway(z_root() . '/moderate');
+ }
+
+ $r = q("select item.id as item_id, item.* from item where item.uid = %d and item_blocked = %d and item_deleted = 0 order by created desc limit 60",
+ intval(local_channel()),
+ intval(ITEM_MODERATED)
+ );
+
+ if($r) {
+ xchan_query($r);
+ $items = fetch_post_tags($r,true);
+ }
+ else {
+ $items = array();
+ }
+
+ $o = conversation($a,$items,'moderate',false,'traditional');
+
+ return $o;
+
+ }
+
+} \ No newline at end of file
diff --git a/Zotlabs/Module/Settings/Channel.php b/Zotlabs/Module/Settings/Channel.php
index 7c30ef93e..3e6adcf8d 100644
--- a/Zotlabs/Module/Settings/Channel.php
+++ b/Zotlabs/Module/Settings/Channel.php
@@ -324,7 +324,7 @@ class Channel {
foreach($global_perms as $k => $perm) {
$options = array();
foreach($perm_opts as $opt) {
- if((! strstr($k,'view')) && $opt[1] == PERMS_PUBLIC)
+ if(((! strstr($k,'view')) && $k !== 'post_comments') && $opt[1] == PERMS_PUBLIC)
continue;
$options[$opt[1]] = $opt[0];
}
diff --git a/include/channel.php b/include/channel.php
index b06c1994f..86fa2a63a 100644
--- a/include/channel.php
+++ b/include/channel.php
@@ -2306,3 +2306,69 @@ function channel_codeallowed($channel_id) {
}
+function anon_identity_init($reqvars) {
+
+ $x = [ 'request_vars' => $reqvars, 'xchan' => null, 'success' => 'unset' ];
+ call_hooks('anon_identity_init',$x);
+ if($x['success'] !== 'unset' && intval($x['success']) && $x['xchan'])
+ return $x['xchan'];
+
+ // allow a captcha handler to over-ride
+ if($x['success'] !== 'unset' && (intval($x['success']) === 0))
+ return false;
+
+
+ $anon_name = strip_tags(trim($reqvars['anonname']));
+ $anon_email = strip_tags(trim($reqvars['anonmail']));
+ $anon_url = strip_tags(trim($reqvars['anonurl']));
+
+ if(! ($anon_name && $anon_email)) {
+ logger('anonymous commenter did not complete form');
+ return false;
+ }
+
+ if(! validate_email($anon_email)) {
+ logger('enonymous email not valid');
+ return false;
+ }
+
+ if(! $anon_url)
+ $anon_url = z_root();
+
+ $x = q("select * from xchan where xchan_guid = '%s' and xchan_hash = '%s' and xchan_network = 'unknown' limit 1",
+ dbesc($anon_email),
+ dbesc($anon_email)
+ );
+
+ if(! $x) {
+ xchan_store_lowlevel([
+ 'xchan_guid' => $anon_email,
+ 'xchan_hash' => $anon_email,
+ 'xchan_name' => $anon_name,
+ 'xchan_url' => $anon_url,
+ 'xchan_network' => 'unknown',
+ 'xchan_name_date' => datetime_convert()
+ ]);
+
+ $x = q("select * from xchan where xchan_guid = '%s' and xchan_hash = '%s' and xchan_network = 'unknown' limit 1",
+ dbesc($anon_email),
+ dbesc($anon_email)
+ );
+
+ $photo = z_root() . '/' . get_default_profile_photo(300);
+ $photos = import_xchan_photo($photo,$anon_email);
+ $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_guid = '%s' and xchan_hash = '%s' and xchan_network = 'unknown' ",
+ dbesc(datetime_convert()),
+ dbesc($photos[0]),
+ dbesc($photos[1]),
+ dbesc($photos[2]),
+ dbesc($photos[3]),
+ dbesc($anon_email),
+ dbesc($anon_email)
+ );
+
+ }
+
+ return $x[0];
+
+} \ No newline at end of file
diff --git a/include/conversation.php b/include/conversation.php
index 3f9ee5cfa..2eac2adde 100644
--- a/include/conversation.php
+++ b/include/conversation.php
@@ -533,6 +533,10 @@ function conversation(&$a, $items, $mode, $update, $page_mode = 'traditional', $
$live_update_div = '<div id="live-search"></div>' . "\r\n";
}
+ elseif ($mode === 'moderate') {
+ $profile_owner = local_channel();
+ }
+
elseif ($mode === 'photos') {
$profile_onwer = App::$profile['profile_uid'];
$page_writeable = ($profile_owner == local_channel());
@@ -577,7 +581,7 @@ function conversation(&$a, $items, $mode, $update, $page_mode = 'traditional', $
if($items) {
- if($mode === 'network-new' || $mode === 'search' || $mode === 'community') {
+ if(in_array($mode, [ 'network-new', 'search', 'community', 'moderate' ])) {
// "New Item View" on network page or search page results
// - just loop through the items and format them minimally for display
@@ -609,14 +613,14 @@ function conversation(&$a, $items, $mode, $update, $page_mode = 'traditional', $
if(((activity_match($item['verb'],ACTIVITY_LIKE)) || (activity_match($item['verb'],ACTIVITY_DISLIKE)))
&& ($item['id'] != $item['parent']))
continue;
- $nickname = $item['nickname'];
+// $nickname = $item['nickname'];
}
- else
- $nickname = App::$user['nickname'];
+// else
+// $nickname = App::$user['nickname'];
- $profile_name = ((strlen($item['author-name'])) ? $item['author-name'] : $item['name']);
- if($item['author-link'] && (! $item['author-name']))
- $profile_name = $item['author-link'];
+// $profile_name = ((strlen($item['author-name'])) ? $item['author-name'] : $item['name']);
+// if($item['author-link'] && (! $item['author-name']))
+// $profile_name = $item['author-link'];
$sp = false;
$profile_link = best_link_url($item,$sp);
@@ -625,7 +629,7 @@ function conversation(&$a, $items, $mode, $update, $page_mode = 'traditional', $
else
$profile_link = zid($profile_link);
- $normalised = normalise_link((strlen($item['author-link'])) ? $item['author-link'] : $item['url']);
+// $normalised = normalise_link((strlen($item['author-link'])) ? $item['author-link'] : $item['url']);
$profile_name = $item['author']['xchan_name'];
$profile_link = $item['author']['xchan_url'];
@@ -679,6 +683,8 @@ function conversation(&$a, $items, $mode, $update, $page_mode = 'traditional', $
'template' => $tpl,
'toplevel' => 'toplevel_item',
'mode' => $mode,
+ 'approve' => t('Approve'),
+ 'delete' => t('Delete'),
'id' => (($preview) ? 'P0' : $item['item_id']),
'linktitle' => sprintf( t('View %s\'s profile @ %s'), $profile_name, $profile_url),
'profile_url' => $profile_link,
diff --git a/include/items.php b/include/items.php
index e79707aeb..9e1d5c1ba 100755
--- a/include/items.php
+++ b/include/items.php
@@ -906,7 +906,7 @@ function import_author_unknown($x) {
$photos = import_xchan_photo($x['photo']['src'],$x['url']);
if($photos) {
- $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_url = '%s' and xchan_network = 'unknown'",
+ $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' and xchan_network = 'unknown'",
dbesc(datetime_convert()),
dbesc($photos[0]),
dbesc($photos[1]),
diff --git a/view/js/main.js b/view/js/main.js
index 38b9754a1..6c42531ea 100644
--- a/view/js/main.js
+++ b/view/js/main.js
@@ -13,6 +13,7 @@ function commentOpenUI(obj, id) {
$("#comment-edit-text-" + id).attr('tabindex','9');
$("#comment-edit-submit-" + id).attr('tabindex','10');
$("#comment-tools-" + id).show();
+ $("#comment-edit-anon-" + id).show();
}
};
@@ -41,6 +42,7 @@ function commentOpen(obj, id) {
$("#comment-edit-text-" + id).addClass("comment-edit-text-full");
$("#comment-edit-text-" + id).removeClass("comment-edit-text-empty");
$("#mod-cmnt-wrap-" + id).show();
+ $("#comment-edit-anon-" + id).show();
openMenu("comment-tools-" + id);
return true;
}
diff --git a/view/tpl/comment_item.tpl b/view/tpl/comment_item.tpl
index 92eeac056..02b0c527c 100755
--- a/view/tpl/comment_item.tpl
+++ b/view/tpl/comment_item.tpl
@@ -11,9 +11,10 @@
<input type="hidden" name="jsreload" value="{{$jsreload}}" />
<input type="hidden" name="preview" id="comment-preview-inp-{{$id}}" value="0" />
{{if $anoncomments && ! $observer}}
- <div id="comment-edit-anon-{{$id}}">
- {{include file="field_input.tpl" field=$authorname}}
- {{include file="field_input.tpl" field=$authormail}}
+ <div id="comment-edit-anon-{{$id}}" style="display: none;" >
+ {{include file="field_input.tpl" field=$anonname}}
+ {{include file="field_input.tpl" field=$anonmail}}
+ {{include file="field_input.tpl" field=$anonurl}}
{{$anon_extras}}
</div>
{{/if}}
diff --git a/view/tpl/search_item.tpl b/view/tpl/search_item.tpl
index 66618a216..4ca6378b8 100755
--- a/view/tpl/search_item.tpl
+++ b/view/tpl/search_item.tpl
@@ -102,6 +102,17 @@
<div class="dropdown-menu">{{$item.attachments}}</div>
</div>
{{/if}}
+ {{if $item.mode === 'moderate'}}
+
+ <div class="wall-item-tools-left btn-group">
+ <a href="moderate/{{$item.id}}/approve" class="btn btn-outline-secondary btn-small">{{$item.approve}}</a>
+ <a href="moderate/{{$item.id}}/drop" class="btn btn-outline-secondary btn-small">{{$item.delete}}</a>
+
+ </div>
+
+
+
+ {{/if}}
</div>
</div>
{{if $item.conv}}