This commit is contained in:
Mike Macgirvin 2019-04-03 12:57:00 +11:00
commit c8deb88a00
25 changed files with 339 additions and 161 deletions

View file

@ -5,6 +5,7 @@ namespace Zotlabs\Lib;
use Zotlabs\Web\HTTPSig; use Zotlabs\Web\HTTPSig;
use Zotlabs\Access\Permissions; use Zotlabs\Access\Permissions;
use Zotlabs\Access\PermissionRoles; use Zotlabs\Access\PermissionRoles;
use Zotlabs\Access\PermissionLimits;
use Zotlabs\Daemon\Master; use Zotlabs\Daemon\Master;
@ -273,6 +274,16 @@ class Activity {
$ret['inheritPrivacy'] = true; $ret['inheritPrivacy'] = true;
if(intval($i['item_wall']) && $i['mid'] === $i['parent_mid']) {
$ret['commentPolicy'] = map_scope(PermissionLimits::Get($i['uid'],'post_comments'));
}
if(array_key_exists('comments_closed',$i) && $i['comments_closed'] !== EMPTY_STR && $i['comments_closed'] !== NULL_DATE) {
if($ret['commentPolicy']) {
$ret['commentPolicy'] .= ' ';
}
$ret['commentPolicy'] .= 'until=' . datetime_convert('UTC','UTC',$i['comments_closed'],ATOM_TIME);
}
$ret['attributedTo'] = $i['author']['xchan_url']; $ret['attributedTo'] = $i['author']['xchan_url'];

View file

@ -273,6 +273,9 @@ class ActivityStreams {
} }
static function is_an_actor($s) { static function is_an_actor($s) {
if (! $s) {
return false;
}
return(in_array($s,[ 'Application','Group','Organization','Person','Service' ])); return(in_array($s,[ 'Application','Group','Organization','Person','Service' ]));
} }

View file

@ -1152,16 +1152,26 @@ class Libzot {
logger($AS->debug(), LOGGER_DATA); logger($AS->debug(), LOGGER_DATA);
} }
// There is nothing inherently wrong with getting a message-id which isn't a canonical URI/URL, but // There is nothing inherently wrong with getting a message-id which isn't a canonical URI/URL, but
// at the present time (2019/02) during the Hubzilla transition to zot6 it is likely to cause lots of duplicates for // at the present time (2019/02) during the Hubzilla transition to zot6 it is likely to cause lots of duplicates for
// messages arriving from different protocols and sources with different message-id semantics. This // messages arriving from different protocols and sources with different message-id semantics. This
// restriction can be relaxed once most Hubzilla sites are upgraded to > 4.0. // restriction can be relaxed once most Hubzilla sites are upgraded to > 4.0.
if($arr && (strpos($arr['mid'],'http') === false)) { if($arr) {
if(strpos($arr['mid'],'http') === false && strpos($arr['mid'],'x-zot') === false) {
logger('activity rejected: legacy message-id'); logger('activity rejected: legacy message-id');
return; return;
} }
if($arr['verb'] === 'Create' && ActivityStreams::is_an_actor($arr['obj_type'])) {
logger('activity rejected: create actor');
return;
}
}
$deliveries = null; $deliveries = null;
@ -1250,10 +1260,23 @@ class Libzot {
if($private) { if($private) {
$arr['item_private'] = true; $arr['item_private'] = true;
} }
if($arr['mid'] === $arr['parent_mid']) {
if(is_array($AS->obj) && array_key_exists('commentPolicy',$AS->obj)) {
$p = strstr($AS->obj['commentPolicy'],'until=');
if($p !== false) {
$arr['comments_closed'] = datetime_convert('UTC','UTC', substr($p,6));
$arr['comment_policy'] = trim(str_replace($p,'',$AS->obj['commentPolicy']));
}
else {
$arr['comment_policy'] = $AS->obj['commentPolicy'];
}
}
}
// @fixme - spoofable // @fixme - spoofable
if($AS->data['hubloc']) { if($AS->data['hubloc']) {
$arr['item_verified'] = true; $arr['item_verified'] = true;
if(! array_key_exists('comment_policy',$arr)) {
// set comment policy depending on source hub. Unknown or osada is ActivityPub. // set comment policy depending on source hub. Unknown or osada is ActivityPub.
// Anything else we'll say is zot - which could have a range of project names // Anything else we'll say is zot - which could have a range of project names
$s = q("select site_project from site where site_url = '%s' limit 1", $s = q("select site_project from site where site_url = '%s' limit 1",
@ -1267,6 +1290,7 @@ class Libzot {
$arr['comment_policy'] = 'contacts'; $arr['comment_policy'] = 'contacts';
} }
} }
}
if($AS->data['signed_data']) { if($AS->data['signed_data']) {
IConfig::Set($arr,'activitypub','signed_data',$AS->data['signed_data'],false); IConfig::Set($arr,'activitypub','signed_data',$AS->data['signed_data'],false);
$j = json_decode($AS->data['signed_data'],true); $j = json_decode($AS->data['signed_data'],true);

View file

@ -127,7 +127,7 @@ class Libzotdir {
$safe_mode = self::get_directory_setting($observer, 'safemode'); $safe_mode = self::get_directory_setting($observer, 'safemode');
$globaldir = self::get_directory_setting($observer, 'globaldir'); $globaldir = self::get_directory_setting($observer, 'globaldir');
$pubforums = self::get_directory_setting($observer, 'pubforums'); $pubforums = self::get_directory_setting($observer, 'chantype');
$hide_local = intval(get_config('system','localdir_hide')); $hide_local = intval(get_config('system','localdir_hide'));
if($hide_local) if($hide_local)
@ -149,6 +149,7 @@ class Libzotdir {
$tmp = array_merge($_GET,$_POST); $tmp = array_merge($_GET,$_POST);
unset($tmp['suggest']); unset($tmp['suggest']);
unset($tmp['pubforums']); unset($tmp['pubforums']);
unset($tmp['type']);
unset($tmp['global']); unset($tmp['global']);
unset($tmp['safe']); unset($tmp['safe']);
unset($tmp['req']); unset($tmp['req']);
@ -159,7 +160,8 @@ class Libzotdir {
'$header' => t('Directory Options'), '$header' => t('Directory Options'),
'$forumsurl' => $forumsurl, '$forumsurl' => $forumsurl,
'$safemode' => array('safemode', t('Safe Mode'),$safe_mode,'',array(t('No'), t('Yes')),' onchange=\'window.location.href="' . $forumsurl . '&safe="+(this.checked ? 1 : 0)\''), '$safemode' => array('safemode', t('Safe Mode'),$safe_mode,'',array(t('No'), t('Yes')),' onchange=\'window.location.href="' . $forumsurl . '&safe="+(this.checked ? 1 : 0)\''),
'$pubforums' => array('pubforums', t('Public Groups Only'),$pubforums,'',array(t('No'), t('Yes')),' onchange=\'window.location.href="' . $forumsurl . '&pubforums="+(this.checked ? 1 : 0)\''), '$pubforums' => array('pubforums', t('Public Groups Only'),(($pubforums == 1) ? true : false),'',array(t('No'), t('Yes')),' onchange=\'window.location.href="' . $forumsurl . '&type="+(this.checked ? 1 : 0)\''),
'$collections' => array('collections', t('Collections Only'),(($pubforums == 2) ? true : false),'',array(t('No'), t('Yes')),' onchange=\'window.location.href="' . $forumsurl . '&type="+(this.checked ? 2 : 0)\''),
'$hide_local' => $hide_local, '$hide_local' => $hide_local,
'$globaldir' => array('globaldir', t('This Website Only'), 1-intval($globaldir),'',array(t('No'), t('Yes')),' onchange=\'window.location.href="' . $forumsurl . '&global="+(this.checked ? 0 : 1)\''), '$globaldir' => array('globaldir', t('This Website Only'), 1-intval($globaldir),'',array(t('No'), t('Yes')),' onchange=\'window.location.href="' . $forumsurl . '&global="+(this.checked ? 0 : 1)\''),
]); ]);

View file

@ -20,7 +20,7 @@ class Affinity extends \Zotlabs\Web\Controller {
$cmin = intval($_POST['affinity_cmin']); $cmin = intval($_POST['affinity_cmin']);
if($cmin < 0 || $cmin > 99) if($cmin < 0 || $cmin > 99)
$cmin = 0; $cmin = 0;
set_pconfig(local_channel(),'affinity','cmin',$cmin); set_pconfig(local_channel(),'affinity','cmin',0);
set_pconfig(local_channel(),'affinity','cmax',$cmax); set_pconfig(local_channel(),'affinity','cmax',$cmax);
info( t('Affinity Tool settings updated.') . EOL); info( t('Affinity Tool settings updated.') . EOL);
@ -42,20 +42,42 @@ class Affinity extends \Zotlabs\Web\Controller {
return $text; return $text;
} }
$text .= EOL . t('The numbers below represent the minimum and maximum slider default positions for your network/stream page as a percentage.') . EOL . EOL; $text .= EOL . t('The number below represents the default maximum slider position for your network/stream page as a percentage.') . EOL . EOL;
$setting_fields = $text; $setting_fields = $text;
$cmax = intval(get_pconfig(local_channel(),'affinity','cmax')); $cmax = intval(get_pconfig(local_channel(),'affinity','cmax'));
$cmax = (($cmax) ? $cmax : 99); $cmax = (($cmax) ? $cmax : 99);
$setting_fields .= replace_macros(get_markup_template('field_input.tpl'), array( // $setting_fields .= replace_macros(get_markup_template('field_input.tpl'), array(
'$field' => array('affinity_cmax', t('Default maximum affinity level'), $cmax, t('0-99 default 99')) // '$field' => array('affinity_cmax', t('Default maximum affinity level'), $cmax, t('0-99 default 99'))
)); // ));
$cmin = intval(get_pconfig(local_channel(),'affinity','cmin'));
$cmin = (($cmin) ? $cmin : 0); if(Apps::system_app_installed(local_channel(),'Affinity Tool')) {
$setting_fields .= replace_macros(get_markup_template('field_input.tpl'), array(
'$field' => array('affinity_cmin', t('Default minimum affinity level'), $cmin, t('0-99 - default 0')) $labels = array(
)); 0 => t('Me'),
20 => t('Family'),
40 => t('Friends'),
60 => t('Peers'),
80 => t('Connections'),
99 => t('All')
);
call_hooks('affinity_labels',$labels);
$tpl = get_markup_template('affinity.tpl');
$x = replace_macros($tpl, [
'$cmin' => 0,
'$cmax' => $cmax,
'$lbl' => t('Default friend zoom in/out'),
'$refresh' => t('Refresh'),
'$labels' => $labels,
]);
$arr = array('html' => $x);
call_hooks('affinity_slider',$arr);
$setting_fields .= $arr['html'];
}
$s .= replace_macros(get_markup_template('generic_app_settings.tpl'), array( $s .= replace_macros(get_markup_template('generic_app_settings.tpl'), array(
'$addon' => array('affinity', '' . t('Affinity Tool Settings'), '', t('Submit')), '$addon' => array('affinity', '' . t('Affinity Tool Settings'), '', t('Submit')),

View file

@ -222,8 +222,8 @@ class Connedit extends \Zotlabs\Web\Controller {
intval($channel['channel_id']) intval($channel['channel_id'])
); );
if(($pr) && (! intval($orig_record[0]['abook_hidden'])) && (intval(get_pconfig($channel['channel_id'],'system','post_newfriend')))) { if(($pr) && (! intval($orig_record[0]['abook_hidden'])) && (intval(get_pconfig($channel['channel_id'],'system','post_newfriend')))) {
$xarr = array(); $xarr = [];
$xarr['verb'] = ACTIVITY_FRIEND;
$xarr['item_wall'] = 1; $xarr['item_wall'] = 1;
$xarr['item_origin'] = 1; $xarr['item_origin'] = 1;
$xarr['item_thread_top'] = 1; $xarr['item_thread_top'] = 1;
@ -233,17 +233,6 @@ class Connedit extends \Zotlabs\Web\Controller {
$xarr['deny_cid'] = $channel['channel_deny_cid']; $xarr['deny_cid'] = $channel['channel_deny_cid'];
$xarr['deny_gid'] = $channel['channel_deny_gid']; $xarr['deny_gid'] = $channel['channel_deny_gid'];
$xarr['item_private'] = (($xarr['allow_cid']||$xarr['allow_gid']||$xarr['deny_cid']||$xarr['deny_gid']) ? 1 : 0); $xarr['item_private'] = (($xarr['allow_cid']||$xarr['allow_gid']||$xarr['deny_cid']||$xarr['deny_gid']) ? 1 : 0);
$obj = array(
'type' => ACTIVITY_OBJ_PERSON,
'title' => \App::$poi['xchan_name'],
'id' => \App::$poi['xchan_hash'],
'link' => array(
array('rel' => 'alternate', 'type' => 'text/html', 'href' => \App::$poi['xchan_url']),
array('rel' => 'photo', 'type' => \App::$poi['xchan_photo_mimetype'], 'href' => \App::$poi['xchan_photo_l'])
),
);
$xarr['obj'] = json_encode($obj);
$xarr['obj_type'] = ACTIVITY_OBJ_PERSON;
$xarr['body'] = '[zrl=' . $channel['xchan_url'] . ']' . $channel['xchan_name'] . '[/zrl]' . ' ' . t('is now connected to') . ' ' . '[zrl=' . \App::$poi['xchan_url'] . ']' . \App::$poi['xchan_name'] . '[/zrl]'; $xarr['body'] = '[zrl=' . $channel['xchan_url'] . ']' . $channel['xchan_name'] . '[/zrl]' . ' ' . t('is now connected to') . ' ' . '[zrl=' . \App::$poi['xchan_url'] . ']' . \App::$poi['xchan_name'] . '[/zrl]';

View file

@ -340,8 +340,8 @@ class Directory extends \Zotlabs\Web\Controller {
'about' => $about, 'about' => $about,
'about_label' => t('About:'), 'about_label' => t('About:'),
'conn_label' => t('Connect'), 'conn_label' => t('Connect'),
'forum_label' => t('Group:'), 'forum_label' => t('Group'),
'collections_label' => t('Collection:'), 'collections_label' => t('Collection'),
'connect' => $connect_link, 'connect' => $connect_link,
'online' => $online, 'online' => $online,
'kw' => (($out) ? t('Keywords: ') : ''), 'kw' => (($out) ? t('Keywords: ') : ''),

View file

@ -40,25 +40,48 @@ class Embedphotos extends \Zotlabs\Web\Controller {
} }
$resource_id = array_pop(explode("/", $href)); $resource_id = array_pop(explode("/", $href));
$x = self::photolink($resource_id);
if($x)
json_return_and_die(array('status' => true, 'photolink' => $x, 'resource_id' => $resource_id));
json_return_and_die(array('errormsg' => 'Error retrieving resource ' . $resource_id, 'status' => false));
$r = q("SELECT obj from item where resource_type = 'photo' and resource_id = '%s' limit 1", }
dbesc($resource_id) }
protected static function photolink($resource) {
$channel = \App::get_channel();
$output = EMPTY_STR;
if($channel) {
$resolution = ((feature_enabled($channel['channel_id'],'large_photos')) ? 2 : 3);
$r = q("select mimetype, height, width from photo where resource_id = '%s' and $resolution = %d and uid = %d limit 1",
dbesc($resource),
intval($resolution),
intval($channel['channel_id'])
); );
if(!$r) { if(! $r)
json_return_and_die(array('errormsg' => 'Error retrieving resource ' . $resource_id, 'status' => false)); return $output;
}
$obj = json_decode($r[0]['obj'], true);
if(array_path_exists('source/content',$obj)) {
$photolink = $obj['source']['content'];
}
else {
json_return_and_die(array('errormsg' => 'Error retrieving resource ' . $resource_id, 'status' => false));
}
json_return_and_die(array('status' => true, 'photolink' => $photolink, 'resource_id' => $resource_id));
if($r[0]['mimetype'] === 'image/jpeg')
$ext = '.jpg';
elseif($r[0]['mimetype'] === 'image/png')
$ext = '.png';
elseif($r[0]['mimetype'] === 'image/gif')
$ext = '.gif';
else
$ext = EMPTY_STR;
$output = '[zrl=' . z_root() . '/photos/' . $channel['channel_address'] . '/image/' . $resource . ']' .
'[zmg=' . $r[0]['width'] . 'x' . $r[0]['height'] . ']' . z_root() . '/photo/' . $resource . '-' . $resolution . $ext . '[/zmg][/zrl]';
return $output;
} }
} }
/** /**
* Copied from include/widgets.php::widget_album() with a modification to get the profile_uid from * Copied from include/widgets.php::widget_album() with a modification to get the profile_uid from
* the input array as in widget_item() * the input array as in widget_item()

View file

@ -2,6 +2,7 @@
namespace Zotlabs\Module; namespace Zotlabs\Module;
use Zotlabs\Lib\Libsync; use Zotlabs\Lib\Libsync;
use Zotlabs\Daemon\Master;
require_once('include/security.php'); require_once('include/security.php');
require_once('include/bbcode.php'); require_once('include/bbcode.php');
@ -9,8 +10,6 @@ require_once('include/event.php');
class Like extends \Zotlabs\Web\Controller { class Like extends \Zotlabs\Web\Controller {
private function reaction_to_activity($reaction) { private function reaction_to_activity($reaction) {
$acts = [ $acts = [
@ -309,7 +308,7 @@ class Like extends \Zotlabs\Web\Controller {
// drop_item was not done interactively, so we need to invoke the notifier // drop_item was not done interactively, so we need to invoke the notifier
// in order to push the changes to connections // in order to push the changes to connections
\Zotlabs\Daemon\Master::Summon(array('Notifier','drop',$rr['id'])); Master::Summon(array('Notifier','drop',$rr['id']));
} }
@ -353,12 +352,13 @@ class Like extends \Zotlabs\Web\Controller {
if(intval($item['item_wall'])) if(intval($item['item_wall']))
$arr['item_wall'] = 1; $arr['item_wall'] = 1;
// if this was a linked photo and was hidden, unhide it. // if this was a linked photo and was hidden, unhide it and distribute it.
if(intval($item['item_hidden'])) { if(intval($item['item_hidden'])) {
$r = q("update item set item_hidden = 0 where id = %d", $r = q("update item set item_hidden = 0 where id = %d",
intval($item['id']) intval($item['id'])
); );
Master::Summon(array('Notifier','wall-new',$item['id']));
} }
} }

View file

@ -1,15 +1,15 @@
<?php <?php
namespace Zotlabs\Module; namespace Zotlabs\Module;
use Zotlabs\Web\Controller;
class Linkinfo extends Controller {
class Linkinfo extends \Zotlabs\Web\Controller {
function get() { function get() {
logger('linkinfo: ' . print_r($_REQUEST,true)); logger('linkinfo: ' . print_r($_REQUEST,true), LOGGER_DEBUG);
$text = null; $text = null;
$str_tags = ''; $str_tags = '';
@ -47,7 +47,19 @@ class Linkinfo extends \Zotlabs\Web\Controller {
} }
} }
logger('linkinfo: ' . $url); logger('linkinfo: ' . $url, LOGGER_DEBUG);
$zrl = is_matrix_url($url);
if(! $process_embed) {
if($zrl) {
echo $br . '[zrl]' . $url . '[/zrl]' . $br;
}
else {
echo $br . '[url]' . $url . '[/url]' . $br;
}
killme();
}
$result = z_fetch_url($url,false,0,array('novalidate' => true, 'nobody' => true)); $result = z_fetch_url($url,false,0,array('novalidate' => true, 'nobody' => true));
if($result['success']) { if($result['success']) {
@ -60,7 +72,6 @@ class Linkinfo extends \Zotlabs\Web\Controller {
if (array_key_exists('content-type', $hdrs)) if (array_key_exists('content-type', $hdrs))
$type = $hdrs['content-type']; $type = $hdrs['content-type'];
if($type) { if($type) {
$zrl = is_matrix_url($url);
if(stripos($type,'image/') !== false) { if(stripos($type,'image/') !== false) {
if($zrl) if($zrl)
echo $br . '[zmg]' . $url . '[/zmg]' . $br; echo $br . '[zmg]' . $url . '[/zmg]' . $br;
@ -100,15 +111,6 @@ class Linkinfo extends \Zotlabs\Web\Controller {
killme(); killme();
} }
if(! $process_embed) {
if($zrl) {
echo $br . '[zrl]' . $url . '[/zrl]' . $br;
}
else {
echo $br . '[url]' . $url . '[/url]' . $br;
}
killme();
}
$x = oembed_process($url); $x = oembed_process($url);
if($x) { if($x) {

View file

@ -1,12 +1,16 @@
<?php <?php
namespace Zotlabs\Module; namespace Zotlabs\Module;
use App;
use Zotlabs\Web\Controller;
require_once('include/channel.php'); require_once('include/channel.php');
require_once('include/permissions.php'); require_once('include/permissions.php');
class New_channel extends \Zotlabs\Web\Controller { class New_channel extends Controller {
function init() { function init() {
@ -94,7 +98,15 @@ class New_channel extends \Zotlabs\Web\Controller {
$arr = $_POST; $arr = $_POST;
$acc = \App::get_account(); $acc = App::get_account();
if(local_channel()) {
$parent_channel = App::get_channel();
if($parent_channel) {
$arr['parent_hash'] = $parent_channel['channel_hash'];
}
}
$arr['account_id'] = get_account_id(); $arr['account_id'] = get_account_id();
// prevent execution by delegated channels as well as those not logged in. // prevent execution by delegated channels as well as those not logged in.
@ -124,7 +136,7 @@ class New_channel extends \Zotlabs\Web\Controller {
function get() { function get() {
$acc = \App::get_account(); $acc = App::get_account();
if((! $acc) || $acc['account_id'] != get_account_id()) { if((! $acc) || $acc['account_id'] != get_account_id()) {
notice( t('Permission denied.') . EOL); notice( t('Permission denied.') . EOL);

View file

@ -5,6 +5,7 @@ use App;
use Zotlabs\Lib\Libsync; use Zotlabs\Lib\Libsync;
use Zotlabs\Lib\PermissionDescription; use Zotlabs\Lib\PermissionDescription;
use Zotlabs\Access\AccessControl; use Zotlabs\Access\AccessControl;
use Zotlabs\Daemon\Master;
require_once('include/photo/photo_driver.php'); require_once('include/photo/photo_driver.php');
require_once('include/photos.php'); require_once('include/photos.php');
@ -224,7 +225,7 @@ class Photos extends \Zotlabs\Web\Controller {
$resource_id = argv(2); $resource_id = argv(2);
$p = q("SELECT mimetype, is_nsfw, description, resource_id, imgscale, allow_cid, allow_gid, deny_cid, deny_gid FROM photo WHERE resource_id = '%s' AND uid = %d ORDER BY imgscale DESC", $p = q("SELECT mimetype, is_nsfw, filename, description, resource_id, imgscale, allow_cid, allow_gid, deny_cid, deny_gid FROM photo WHERE resource_id = '%s' AND uid = %d ORDER BY imgscale DESC",
dbesc($resource_id), dbesc($resource_id),
intval($page_owner_uid) intval($page_owner_uid)
); );
@ -264,6 +265,8 @@ class Photos extends \Zotlabs\Web\Controller {
} }
$obj = EMPTY_STR;
if($item_id) { if($item_id) {
$r = q("SELECT * FROM item WHERE id = %d AND uid = %d LIMIT 1", $r = q("SELECT * FROM item WHERE id = %d AND uid = %d LIMIT 1",
intval($item_id), intval($item_id),
@ -274,16 +277,28 @@ class Photos extends \Zotlabs\Web\Controller {
$old_tag = $r[0]['tag']; $old_tag = $r[0]['tag'];
$old_inform = $r[0]['inform']; $old_inform = $r[0]['inform'];
} }
if($r[0]['obj']) {
$obj = json_decode($r[0]['obj'],true);
$obj['name'] = (($desc) ? $desc : $p[0]['filename']);
$obj['updated'] = datetime_convert('UTC','UTC','now',ATOM_TIME);
$obj = json_encode($obj);
}
} }
// make sure the linked item has the same permissions as the photo regardless of any other changes // make sure the linked item has the same permissions as the photo regardless of any other changes
$x = q("update item set allow_cid = '%s', allow_gid = '%s', deny_cid = '%s', deny_gid = '%s', item_private = %d $x = q("update item set allow_cid = '%s', allow_gid = '%s', deny_cid = '%s', deny_gid = '%s', title = '%s', obj = '%s', edited = '%s', item_private = %d
where id = %d", where id = %d",
dbesc($perm['allow_cid']), dbesc($perm['allow_cid']),
dbesc($perm['allow_gid']), dbesc($perm['allow_gid']),
dbesc($perm['deny_cid']), dbesc($perm['deny_cid']),
dbesc($perm['deny_gid']), dbesc($perm['deny_gid']),
dbesc(($desc) ? $desc : $p[0]['filename']),
dbesc($obj),
dbesc(datetime_convert()),
intval($acl->is_private()), intval($acl->is_private()),
intval($item_id) intval($item_id)
); );
@ -349,6 +364,10 @@ class Photos extends \Zotlabs\Web\Controller {
} }
if($visibility) {
Master::Summon(array('Notifier','edit_post',$item_id));
}
$sync = attach_export_data(App::$data['channel'],$resource_id); $sync = attach_export_data(App::$data['channel'],$resource_id);
if($sync) if($sync)

32
Zotlabs/Update/_1231.php Normal file
View file

@ -0,0 +1,32 @@
<?php
namespace Zotlabs\Update;
class _1231 {
function run() {
q("START TRANSACTION");
if(ACTIVE_DBTYPE == DBTYPE_POSTGRES) {
$r1 = q("ALTER TABLE channel ADD channel_parent text NOT NULL DEFAULT '' ");
$r2 = q("create index \"channel_parent\" on channel (\"channel_parent\")");
$r = ($r1 && $r2);
}
else {
$r = q("ALTER TABLE `channel` ADD `channel_parent` char(191) NOT NULL DEFAULT '' ,
ADD INDEX `channel_parent` (`channel_parent`)");
}
if($r) {
q("COMMIT");
return UPDATE_SUCCESS;
}
q("ROLLBACK");
return UPDATE_FAILED;
}
}

View file

@ -33,10 +33,10 @@ require_once('include/items.php');
define ( 'STD_VERSION', '2.8.2' ); define ( 'STD_VERSION', '2.9' );
define ( 'ZOT_REVISION', '6.0' ); define ( 'ZOT_REVISION', '6.0' );
define ( 'DB_UPDATE_VERSION', 1230 ); define ( 'DB_UPDATE_VERSION', 1231 );
define ( 'PROJECT_BASE', __DIR__ ); define ( 'PROJECT_BASE', __DIR__ );

View file

@ -130,6 +130,10 @@ function videowithopts($match) {
if ($matches[1] != "") if ($matches[1] != "")
$poster = 'poster="' . (($zrl) ? zid($matches[1]) : $matches[1]) . '"'; $poster = 'poster="' . (($zrl) ? zid($matches[1]) : $matches[1]) . '"';
preg_match("/poster=\&quot\;(.*?)\&quot\;/ism", $attributes, $matches);
if ($matches[1] != "")
$poster = 'poster="' . (($zrl) ? zid($matches[1]) : $matches[1]) . '"';
return '<video ' . $poster . ' controls="controls" preload="none" src="' . str_replace(' ','%20',$link) . '" style="width:100%; max-width:' . App::$videowidth . 'px"><a href="' . str_replace(' ','%20',$link) . '">' . $link . '</a></video>'; return '<video ' . $poster . ' controls="controls" preload="none" src="' . str_replace(' ','%20',$link) . '" style="width:100%; max-width:' . App::$videowidth . 'px"><a href="' . str_replace(' ','%20',$link) . '">' . $link . '</a></video>';
} }

View file

@ -242,9 +242,13 @@ function create_identity($arr) {
$publish = intval($arr['publish']); $publish = intval($arr['publish']);
$role_permissions = null; $role_permissions = null;
$parent_channel_hash = EMPTY_STR;
if(array_key_exists('permissions_role',$arr) && $arr['permissions_role']) { if(array_key_exists('permissions_role',$arr) && $arr['permissions_role']) {
$role_permissions = PermissionRoles::role_perms($arr['permissions_role']); $role_permissions = PermissionRoles::role_perms($arr['permissions_role']);
if(strpos($arr['permissions_role'],'collection') !== false) {
$parent_channel_hash = $arr['parent_hash'];
}
} }
if($role_permissions && array_key_exists('directory_publish',$role_permissions)) if($role_permissions && array_key_exists('directory_publish',$role_permissions))
@ -262,6 +266,7 @@ function create_identity($arr) {
'channel_account_id' => intval($arr['account_id']), 'channel_account_id' => intval($arr['account_id']),
'channel_primary' => intval($primary), 'channel_primary' => intval($primary),
'channel_name' => $name, 'channel_name' => $name,
'channel_parent' => $parent_channel_hash,
'channel_address' => $nick, 'channel_address' => $nick,
'channel_guid' => $guid, 'channel_guid' => $guid,
'channel_guid_sig' => $sig, 'channel_guid_sig' => $sig,
@ -454,6 +459,15 @@ function create_identity($arr) {
set_pconfig($ret['channel']['channel_id'],'system','attach_path','%Y/%Y-%m'); set_pconfig($ret['channel']['channel_id'],'system','attach_path','%Y/%Y-%m');
} }
// If this channel has a parent, auto follow them.
if($parent_channel_hash) {
$ch = channelx_by_hash($parent_channel_hash);
if($ch) {
connect_and_sync($ret['channel'],channel_reddress($ch));
}
}
// auto-follow any of the hub's pre-configured channel choices. // auto-follow any of the hub's pre-configured channel choices.
// Only do this if it's the first channel for this account; // Only do this if it's the first channel for this account;
// otherwise it could get annoying. Don't make this list too big // otherwise it could get annoying. Don't make this list too big
@ -466,7 +480,46 @@ function create_identity($arr) {
foreach($accts as $acct) { foreach($accts as $acct) {
if(trim($acct)) { if(trim($acct)) {
$f = Connect::connect($ret['channel'],trim($acct)); $f = $connect_and_sync($ret['channel'],trim($acct));
if($f['success']) {
$can_view_stream = their_perms_contains($ret['channel']['channel_id'],$f['abook']['abook_xchan'],'view_stream');
// If we can view their stream, pull in some posts
if(($can_view_stream) || ($f['abook']['xchan_network'] === 'rss')) {
Master::Summon([ 'Onepoll',$f['abook']['abook_id'] ]);
}
}
}
}
}
/**
* @hooks create_identity
* Called when creating a channel.
* * \e int - The UID of the created identity
*/
call_hooks('create_identity', $newuid);
Master::Summon(array('Directory', $ret['channel']['channel_id']));
}
$ret['success'] = true;
return $ret;
}
function connect_and_sync($channel,$address) {
if((! $channel) || (! $address)) {
return false;
}
$f = Connect::connect($channel,$address);
if($f['success']) { if($f['success']) {
$clone = []; $clone = [];
foreach($f['abook'] as $k => $v) { foreach($f['abook'] as $k => $v) {
@ -478,37 +531,15 @@ function create_identity($arr) {
unset($clone['abook_account']); unset($clone['abook_account']);
unset($clone['abook_channel']); unset($clone['abook_channel']);
$abconfig = load_abconfig($ret['channel']['channel_id'],$clone['abook_xchan']); $abconfig = load_abconfig($channel['channel_id'],$clone['abook_xchan']);
if($abconfig) { if($abconfig) {
$clone['abconfig'] = $abconfig; $clone['abconfig'] = $abconfig;
} }
Libsync::build_sync_packet($ret['channel']['channel_id'], [ 'abook' => [ $clone ] ], true); Libsync::build_sync_packet($channel['channel_id'], [ 'abook' => [ $clone ] ], true);
return $f;
$can_view_stream = their_perms_contains($ret['channel']['channel_id'],$clone['abook_xchan'],'view_stream');
// If we can view their stream, pull in some posts
if(($can_view_stream) || ($f['abook']['xchan_network'] === 'rss')) {
Master::Summon([ 'Onepoll',$f['abook']['abook_id'] ]);
} }
} return false;
}
}
}
/**
* @hooks create_identity
* Called when creating a channel.
* * \e int - The UID of the created identity
*/
call_hooks('create_identity', $newuid);
Master::Summon(array('Directory', $ret['channel']['channel_id']));
}
$ret['success'] = true;
return $ret;
} }
@ -2435,6 +2466,7 @@ function channel_store_lowlevel($arr) {
'channel_account_id' => ((array_key_exists('channel_account_id',$arr)) ? $arr['channel_account_id'] : '0'), 'channel_account_id' => ((array_key_exists('channel_account_id',$arr)) ? $arr['channel_account_id'] : '0'),
'channel_primary' => ((array_key_exists('channel_primary',$arr)) ? $arr['channel_primary'] : '0'), 'channel_primary' => ((array_key_exists('channel_primary',$arr)) ? $arr['channel_primary'] : '0'),
'channel_name' => ((array_key_exists('channel_name',$arr)) ? $arr['channel_name'] : ''), 'channel_name' => ((array_key_exists('channel_name',$arr)) ? $arr['channel_name'] : ''),
'channel_parent' => ((array_key_exists('channel_parent',$arr)) ? $arr['channel_parent'] : ''),
'channel_address' => ((array_key_exists('channel_address',$arr)) ? $arr['channel_address'] : ''), 'channel_address' => ((array_key_exists('channel_address',$arr)) ? $arr['channel_address'] : ''),
'channel_guid' => ((array_key_exists('channel_guid',$arr)) ? $arr['channel_guid'] : ''), 'channel_guid' => ((array_key_exists('channel_guid',$arr)) ? $arr['channel_guid'] : ''),
'channel_guid_sig' => ((array_key_exists('channel_guid_sig',$arr)) ? $arr['channel_guid_sig'] : ''), 'channel_guid_sig' => ((array_key_exists('channel_guid_sig',$arr)) ? $arr['channel_guid_sig'] : ''),

View file

@ -1231,6 +1231,9 @@ function sync_files($channel, $files) {
require_once('include/attach.php'); require_once('include/attach.php');
if($channel && $files) { if($channel && $files) {
$limit = service_class_fetch($channel['channel_id'], 'attach_upload_limit');
foreach($files as $f) { foreach($files as $f) {
if(! $f) if(! $f)
continue; continue;
@ -1352,6 +1355,17 @@ function sync_files($channel, $files) {
} }
else { else {
logger('sync_files attach does not exists: ' . print_r($att,true), LOGGER_DEBUG); logger('sync_files attach does not exists: ' . print_r($att,true), LOGGER_DEBUG);
if($limit !== false) {
$r = q("select sum(filesize) as total from attach where aid = %d ",
intval($channel['channel_account_id'])
);
if(($r) && (($r[0]['total'] + $att['filesize']) > $limit)) {
logger('service class limit exceeded');
continue;
}
}
create_table_from_array('attach',$att); create_table_from_array('attach',$att);
} }

View file

@ -478,7 +478,7 @@ function photo_upload($channel, $observer, $args) {
'obj' => json_encode($object), 'obj' => json_encode($object),
// 'tgt_type' => ACTIVITY_OBJ_ALBUM, // 'tgt_type' => ACTIVITY_OBJ_ALBUM,
// 'target' => json_encode($target), // 'target' => json_encode($target),
'item_wall' => $visible, 'item_wall' => 1,
'item_origin' => 1, 'item_origin' => 1,
'item_thread_top' => 1, 'item_thread_top' => 1,
'item_private' => intval($acl->is_private()), 'item_private' => intval($acl->is_private()),

View file

@ -245,6 +245,7 @@ CREATE TABLE IF NOT EXISTS `channel` (
`channel_account_id` int(10) unsigned NOT NULL DEFAULT 0 , `channel_account_id` int(10) unsigned NOT NULL DEFAULT 0 ,
`channel_primary` tinyint(1) unsigned NOT NULL DEFAULT 0 , `channel_primary` tinyint(1) unsigned NOT NULL DEFAULT 0 ,
`channel_name` char(191) NOT NULL DEFAULT '', `channel_name` char(191) NOT NULL DEFAULT '',
`channel_parent` char(191) NOT NULL DEFAULT '',
`channel_address` char(191) NOT NULL DEFAULT '', `channel_address` char(191) NOT NULL DEFAULT '',
`channel_guid` char(191) NOT NULL DEFAULT '', `channel_guid` char(191) NOT NULL DEFAULT '',
`channel_guid_sig` text NOT NULL, `channel_guid_sig` text NOT NULL,
@ -280,6 +281,7 @@ CREATE TABLE IF NOT EXISTS `channel` (
KEY `channel_account_id` (`channel_account_id`), KEY `channel_account_id` (`channel_account_id`),
KEY `channel_primary` (`channel_primary`), KEY `channel_primary` (`channel_primary`),
KEY `channel_name` (`channel_name`), KEY `channel_name` (`channel_name`),
KEY `channel_parent` (`channel_parent`),
KEY `channel_timezone` (`channel_timezone`), KEY `channel_timezone` (`channel_timezone`),
KEY `channel_location` (`channel_location`), KEY `channel_location` (`channel_location`),
KEY `channel_theme` (`channel_theme`), KEY `channel_theme` (`channel_theme`),
@ -690,19 +692,6 @@ CREATE TABLE IF NOT EXISTS `item` (
KEY `item_pending_remove_changed` (`item_pending_remove`, `changed`) KEY `item_pending_remove_changed` (`item_pending_remove`, `changed`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE IF NOT EXISTS `item_id` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`iid` int(11) NOT NULL DEFAULT 0 ,
`uid` int(11) NOT NULL DEFAULT 0 ,
`sid` char(191) NOT NULL DEFAULT '',
`service` char(191) NOT NULL DEFAULT '',
PRIMARY KEY (`id`),
KEY `uid` (`uid`),
KEY `sid` (`sid`),
KEY `service` (`service`),
KEY `iid` (`iid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE IF NOT EXISTS `likes` ( CREATE TABLE IF NOT EXISTS `likes` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT, `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`channel_id` int(10) unsigned NOT NULL DEFAULT 0 , `channel_id` int(10) unsigned NOT NULL DEFAULT 0 ,
@ -1087,21 +1076,6 @@ CREATE TABLE IF NOT EXISTS `profile` (
KEY `profile_guid` (`profile_guid`) KEY `profile_guid` (`profile_guid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE IF NOT EXISTS `profile_check` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`uid` int(10) unsigned NOT NULL DEFAULT 0 ,
`cid` int(10) unsigned NOT NULL DEFAULT 0 ,
`dfrn_id` char(191) NOT NULL DEFAULT '',
`sec` char(191) NOT NULL DEFAULT '',
`expire` int(11) NOT NULL DEFAULT 0 ,
PRIMARY KEY (`id`),
KEY `uid` (`uid`),
KEY `cid` (`cid`),
KEY `dfrn_id` (`dfrn_id`),
KEY `sec` (`sec`),
KEY `expire` (`expire`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE IF NOT EXISTS `register` ( CREATE TABLE IF NOT EXISTS `register` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT, `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`hash` char(191) NOT NULL DEFAULT '', `hash` char(191) NOT NULL DEFAULT '',

View file

@ -239,6 +239,7 @@ CREATE TABLE "channel" (
"channel_account_id" bigint NOT NULL DEFAULT '0', "channel_account_id" bigint NOT NULL DEFAULT '0',
"channel_primary" numeric(1) NOT NULL DEFAULT '0', "channel_primary" numeric(1) NOT NULL DEFAULT '0',
"channel_name" text NOT NULL DEFAULT '', "channel_name" text NOT NULL DEFAULT '',
"channel_parent" text NOT NULL DEFAULT '',
"channel_address" text NOT NULL DEFAULT '', "channel_address" text NOT NULL DEFAULT '',
"channel_guid" text NOT NULL DEFAULT '', "channel_guid" text NOT NULL DEFAULT '',
"channel_guid_sig" text NOT NULL, "channel_guid_sig" text NOT NULL,
@ -275,6 +276,7 @@ CREATE TABLE "channel" (
create index "channel_account_id" on channel ("channel_account_id"); create index "channel_account_id" on channel ("channel_account_id");
create index "channel_primary" on channel ("channel_primary"); create index "channel_primary" on channel ("channel_primary");
create index "channel_name" on channel ("channel_name"); create index "channel_name" on channel ("channel_name");
create index "channel_parent" on channel ("channel_parent");
create index "channel_timezone" on channel ("channel_timezone"); create index "channel_timezone" on channel ("channel_timezone");
create index "channel_location" on channel ("channel_location"); create index "channel_location" on channel ("channel_location");
create index "channel_theme" on channel ("channel_theme"); create index "channel_theme" on channel ("channel_theme");
@ -691,19 +693,6 @@ create index "item_allow_gid" on item ("allow_gid");
create index "item_deny_cid" on item ("deny_cid"); create index "item_deny_cid" on item ("deny_cid");
create index "item_deny_gid" on item ("deny_gid"); create index "item_deny_gid" on item ("deny_gid");
CREATE TABLE "item_id" (
"id" serial NOT NULL,
"iid" bigint NOT NULL,
"uid" bigint NOT NULL,
"sid" text NOT NULL,
"service" text NOT NULL,
PRIMARY KEY ("id")
);
create index "itemid_uid" on item_id ("uid");
create index "itemid_sid" on item_id ("sid");
create index "itemid_service" on item_id ("service");
create index "itemid_iid" on item_id ("iid");
CREATE TABLE "likes" ( CREATE TABLE "likes" (
"id" serial NOT NULL, "id" serial NOT NULL,
"channel_id" bigint NOT NULL DEFAULT '0', "channel_id" bigint NOT NULL DEFAULT '0',
@ -1083,20 +1072,6 @@ create index "profile_hide_friends" on profile ("hide_friends");
create index "profile_postal_code" on profile ("postal_code"); create index "profile_postal_code" on profile ("postal_code");
create index "profile_country_name" on profile ("country_name"); create index "profile_country_name" on profile ("country_name");
create index "profile_guid" on profile ("profile_guid"); create index "profile_guid" on profile ("profile_guid");
CREATE TABLE "profile_check" (
"id" serial NOT NULL,
"uid" bigint NOT NULL,
"cid" bigint NOT NULL DEFAULT '0',
"dfrn_id" text NOT NULL,
"sec" text NOT NULL,
"expire" bigint NOT NULL,
PRIMARY KEY ("id")
);
create index "pc_uid" on profile_check ("uid");
create index "pc_cid" on profile_check ("cid");
create index "pc_dfrn_id" on profile_check ("dfrn_id");
create index "pc_sec" on profile_check ("sec");
create index "pc_expire" on profile_check ("expire");
CREATE TABLE "register" ( CREATE TABLE "register" (
"id" serial NOT NULL, "id" serial NOT NULL,

View file

@ -57,12 +57,12 @@ li:hover .widget-nav-pills-icons {
/* affinity slider */ /* affinity slider */
#main-slider { #main-slider, #affinity_slider {
margin: 10px 7px 2rem 7px; margin: 10px 7px 2rem 7px;
} }
@media screen and (max-width: 767px) { @media screen and (max-width: 767px) {
#main-slider { #main-slider, #affinity_slider {
margin: 4rem 7px 2rem 7px; margin: 4rem 7px 2rem 7px;
} }
} }
@ -73,7 +73,7 @@ li:hover .widget-nav-pills-icons {
justify-content: flex-center; justify-content: flex-center;
} }
#main-range, #contact-range { #main-range, #affinity-range, #contact-range {
background-color: #EEE; background-color: #EEE;
border-radius: 0.25rem; border-radius: 0.25rem;
width: 90%; width: 90%;

39
view/tpl/affinity.tpl Normal file
View file

@ -0,0 +1,39 @@
<div id="affinity-slider" class="slider" >
<div id="slider-container">
<i class="fa fa-fw fa-user range-icon"></i>
<input id="affinity-range" title="{{$cmax}}" type="range" min="0" max="99" name="cmax" value="{{$cmax}}" list="affinity_labels" >
<datalist id="affinity_labels">
{{foreach $labels as $k => $v}}
<option value={{$k}} label="{{$v}}">
{{/foreach}}
</datalist>
<i class="fa fa-fw fa-users range-icon"></i>
<input type="hidden" class="range-value" name="affinity_cmax" value="{{$cmax}}" >
<span class="range-value">{{$cmax}}</span>
</div>
</div>
<br><br>
<script>
$(document).ready(function() {
var old_cmin = 0;
var old_cmax = {{$cmax}};
var slideTimer = null;
var cmax = {{$cmax}};
$("#affinity-range").on('input', function() { sliderUpdate(); });
$("#affinity-range").on('change', function() { sliderUpdate(); });
function sliderUpdate() {
var cmax = $("#affinity-range").val();
if(cmax == old_cmax)
return;
old_cmax = cmax;
$("#affinity-range").attr('title',cmax);
$("input[name=affinity_cmax]").val(cmax);
$(".range-value").html(cmax);
}
});
</script>

View file

@ -5,6 +5,7 @@
{{include file="field_checkbox.tpl" field=$globaldir}} {{include file="field_checkbox.tpl" field=$globaldir}}
{{/if}} {{/if}}
{{include file="field_checkbox.tpl" field=$pubforums}} {{include file="field_checkbox.tpl" field=$pubforums}}
{{include file="field_checkbox.tpl" field=$collections}}
{{include file="field_checkbox.tpl" field=$safemode}} {{include file="field_checkbox.tpl" field=$safemode}}
</div> </div>

View file

@ -14,7 +14,7 @@
{{if $entry.canrate}}<button class="btn btn-outline-secondary btn-sm" onclick="doRatings('{{$entry.hash}}'); return false;" ><i class="fa fa-pencil"></i><span id="edited-{{$entry.hash}}" class="required" id="edited-{{$entry.hash}}" style="display: none;" >&nbsp;*</span></button>{{/if}} {{if $entry.canrate}}<button class="btn btn-outline-secondary btn-sm" onclick="doRatings('{{$entry.hash}}'); return false;" ><i class="fa fa-pencil"></i><span id="edited-{{$entry.hash}}" class="required" id="edited-{{$entry.hash}}" style="display: none;" >&nbsp;*</span></button>{{/if}}
{{/if}} {{/if}}
</div> </div>
<h3>{{if $entry.type == 2}}<i class="fa fa-tags" title="{{$entry.collections_label}}{{elseif $entry.type == 1}}<i class="fa fa-comments-o" title="{{$entry.forum_label}} @{{$entry.nickname}}+"></i>&nbsp;{{/if}}<a href='{{$entry.profile_link}}' >{{$entry.name}}</a>{{if $entry.online}}&nbsp;<i class="fa fa-asterisk online-now" title="{{$entry.online}}"></i>{{/if}}</h3> <h3>{{if $entry.type == 2}}<i class="fa fa-tags" title="{{$entry.collections_label}}"></i>&nbsp;{{elseif $entry.type == 1}}<i class="fa fa-comments-o" title="{{$entry.forum_label}}"></i>&nbsp;{{/if}}<a href='{{$entry.profile_link}}' >{{$entry.name}}</a>{{if $entry.online}}&nbsp;<i class="fa fa-asterisk online-now" title="{{$entry.online}}"></i>{{/if}}</h3>
</div> </div>
<div class="section-content-tools-wrapper directory-collapse"> <div class="section-content-tools-wrapper directory-collapse">
<div class="contact-photo-wrapper" id="directory-photo-wrapper-{{$entry.hash}}" > <div class="contact-photo-wrapper" id="directory-photo-wrapper-{{$entry.hash}}" >