aboutsummaryrefslogtreecommitdiffstats
path: root/Zotlabs/Module
diff options
context:
space:
mode:
Diffstat (limited to 'Zotlabs/Module')
-rw-r--r--Zotlabs/Module/Cdav.php91
-rw-r--r--Zotlabs/Module/Channel.php18
-rw-r--r--Zotlabs/Module/Channel_calendar.php611
-rw-r--r--Zotlabs/Module/Directory.php38
-rw-r--r--Zotlabs/Module/Editpost.php3
-rw-r--r--Zotlabs/Module/Import.php47
-rw-r--r--Zotlabs/Module/Item.php14
-rw-r--r--Zotlabs/Module/Linkinfo.php45
-rw-r--r--Zotlabs/Module/Magic.php4
-rw-r--r--Zotlabs/Module/Owa.php26
-rw-r--r--Zotlabs/Module/Ping.php2
-rw-r--r--Zotlabs/Module/Poster.php37
-rw-r--r--Zotlabs/Module/Setup.php2
-rw-r--r--Zotlabs/Module/Wall_attach.php21
-rw-r--r--Zotlabs/Module/Wfinger.php2
15 files changed, 914 insertions, 47 deletions
diff --git a/Zotlabs/Module/Cdav.php b/Zotlabs/Module/Cdav.php
index a34948489..6e302935c 100644
--- a/Zotlabs/Module/Cdav.php
+++ b/Zotlabs/Module/Cdav.php
@@ -890,7 +890,7 @@ class Cdav extends Controller {
}
//Display calendar(s) here
- if(argc() == 2 && argv(1) === 'calendar') {
+ if(argc() <= 3 && argv(1) === 'calendar') {
head_add_css('/library/fullcalendar/packages/core/main.min.css');
head_add_css('/library/fullcalendar/packages/daygrid/main.min.css');
@@ -905,6 +905,63 @@ class Cdav extends Controller {
head_add_js('/library/fullcalendar/packages/list/main.min.js');
$sources = '';
+ $resource_id = '';
+ $resource = null;
+
+ if(argc() == 3)
+ $resource_id = argv(2);
+
+ if($resource_id) {
+ $r = q("SELECT event.*, item.author_xchan, item.owner_xchan, item.plink, item.id as item_id FROM event LEFT JOIN item ON event.event_hash = item.resource_id
+ WHERE event.uid = %d AND event.event_hash = '%s' LIMIT 1",
+ intval(local_channel()),
+ dbesc($resource_id)
+ );
+ if($r) {
+ xchan_query($r);
+ $r = fetch_post_tags($r,true);
+
+ $r[0]['dtstart'] = (($r[0]['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$r[0]['dtstart'], 'c') : datetime_convert('UTC','UTC',$r[0]['dtstart'],'c'));
+ $r[0]['dtend'] = (($r[0]['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$r[0]['dtend'], 'c') : datetime_convert('UTC','UTC',$r[0]['dtend'],'c'));
+
+ $r[0]['plink'] = [$r[0]['plink'], t('Link to source')];
+
+ $resource = $r[0];
+
+ $catsenabled = feature_enabled(local_channel(),'categories');
+ $categories = '';
+ if($catsenabled){
+ if($r[0]['term']) {
+ $cats = get_terms_oftype($r[0]['term'], TERM_CATEGORY);
+ foreach ($cats as $cat) {
+ if(strlen($categories))
+ $categories .= ', ';
+ $categories .= $cat['term'];
+ }
+ }
+ }
+
+ if($r[0]['dismissed'] == 0) {
+ q("UPDATE event SET dismissed = 1 WHERE event.uid = %d AND event.event_hash = '%s'",
+ intval(local_channel()),
+ dbesc($resource_id)
+ );
+ }
+ }
+ }
+
+ if(get_pconfig(local_channel(), 'cdav_calendar', 'channel_calendar')) {
+ $sources .= '{
+ id: \'channel_calendar\',
+ url: \'/channel_calendar/json/\',
+ color: \'#3a87ad\'
+ }, ';
+ }
+
+ $channel_calendars[] = [
+ 'displayname' => $channel['channel_name'],
+ 'id' => 'channel_calendar'
+ ];
foreach($calendars as $calendar) {
$editable = (($calendar['share-access'] == 2) ? 'false' : 'true'); // false/true must be string since we're passing it to javascript
@@ -939,6 +996,19 @@ class Cdav extends Controller {
$description = ['description', t('Description')];
$location = ['location', t('Location')];
+ $catsenabled = feature_enabled(local_channel(), 'categories');
+
+ require_once('include/acl_selectors.php');
+
+ $accesslist = new \Zotlabs\Access\AccessList($channel);
+ $perm_defaults = $accesslist->get();
+
+ //$acl = (($orig_event['event_xchan']) ? '' : populate_acl(((x($orig_event)) ? $orig_event : $perm_defaults), false, \Zotlabs\Lib\PermissionDescription::fromGlobalPermission('view_stream')));
+ $acl = populate_acl($perm_defaults, false, \Zotlabs\Lib\PermissionDescription::fromGlobalPermission('view_stream'));
+
+ //$permissions = ((x($orig_event)) ? $orig_event : $perm_defaults);
+ $permissions = $perm_defaults;
+
$o .= replace_macros(get_markup_template('cdav_calendar.tpl'), [
'$sources' => $sources,
'$color' => $color,
@@ -955,6 +1025,7 @@ class Cdav extends Controller {
'$list_week' => t('List week'),
'$list_day' => t('List day'),
'$title' => $title,
+ '$channel_calendars' => $channel_calendars,
'$writable_calendars' => $writable_calendars,
'$dtstart' => $dtstart,
'$dtend' => $dtend,
@@ -964,10 +1035,24 @@ class Cdav extends Controller {
'$less' => t('Less'),
'$update' => t('Update'),
'$calendar_select_label' => t('Select calendar'),
+ '$calendar_optiopns_label' => [t('Channel Calendars'), t('CalDAV Calendars')],
'$delete' => t('Delete'),
'$delete_all' => t('Delete all'),
'$cancel' => t('Cancel'),
- '$recurrence_warning' => t('Sorry! Editing of recurrent events is not yet implemented.')
+ '$recurrence_warning' => t('Sorry! Editing of recurrent events is not yet implemented.'),
+
+ '$channel_hash' => $channel['channel_hash'],
+ '$acl' => $acl,
+ '$lockstate' => (($accesslist->is_private()) ? 'lock' : 'unlock'),
+ '$allow_cid' => acl2json($permissions['allow_cid']),
+ '$allow_gid' => acl2json($permissions['allow_gid']),
+ '$deny_cid' => acl2json($permissions['deny_cid']),
+ '$deny_gid' => acl2json($permissions['deny_gid']),
+ '$catsenabled' => $catsenabled,
+ '$categories_label' => t('Categories'),
+
+ '$resource' => json_encode($resource),
+ '$categories' => $categories
]);
return $o;
@@ -1054,7 +1139,7 @@ class Cdav extends Controller {
}
//enable/disable calendars
- if(argc() == 5 && argv(1) === 'calendar' && argv(2) === 'switch' && intval(argv(3)) && (argv(4) == 1 || argv(4) == 0)) {
+ if(argc() == 5 && argv(1) === 'calendar' && argv(2) === 'switch' && argv(3) && (argv(4) == 1 || argv(4) == 0)) {
$id = argv(3);
if(! cdav_perms($id,$calendars))
diff --git a/Zotlabs/Module/Channel.php b/Zotlabs/Module/Channel.php
index d4ef94e06..144c2472a 100644
--- a/Zotlabs/Module/Channel.php
+++ b/Zotlabs/Module/Channel.php
@@ -46,14 +46,14 @@ class Channel extends Controller {
$channel = App::get_channel();
if((local_channel()) && (argc() > 2) && (argv(2) === 'view')) {
- $which = $channel['channel_address'];
- $profile = argv(1);
- }
+ $which = $channel['channel_address'];
+ $profile = argv(1);
+ }
$channel = channelx_by_nick($which);
- if(! $channel) {
- http_status_exit(404, 'Not found');
- }
+ if(! $channel) {
+ http_status_exit(404, 'Not found');
+ }
// handle zot6 channel discovery
@@ -310,10 +310,6 @@ class Channel extends Controller {
$sql_extra2 .= protect_sprintf(sprintf(" AND item.created >= '%s' ", dbesc(datetime_convert(date_default_timezone_get(),'',$datequery2))));
}
- if($datequery || $datequery2) {
- $sql_extra2 .= " and item.item_thread_top != 0 ";
- }
-
if($order === 'post')
$ordering = "created";
else
@@ -342,7 +338,7 @@ class Channel extends Controller {
AND (abook.abook_blocked = 0 or abook.abook_flags is null)
AND item.item_wall = 1 AND item.item_thread_top = 1
$sql_extra $sql_extra2
- ORDER BY $ordering DESC $pager_sql ",
+ ORDER BY $ordering DESC, item_id $pager_sql ",
intval(App::$profile['profile_uid'])
);
}
diff --git a/Zotlabs/Module/Channel_calendar.php b/Zotlabs/Module/Channel_calendar.php
new file mode 100644
index 000000000..67e6557f9
--- /dev/null
+++ b/Zotlabs/Module/Channel_calendar.php
@@ -0,0 +1,611 @@
+<?php
+namespace Zotlabs\Module;
+
+require_once('include/conversation.php');
+require_once('include/bbcode.php');
+require_once('include/datetime.php');
+require_once('include/event.php');
+require_once('include/items.php');
+require_once('include/html2plain.php');
+
+class Channel_calendar extends \Zotlabs\Web\Controller {
+
+ function post() {
+
+ logger('post: ' . print_r($_REQUEST,true), LOGGER_DATA);
+
+ if(! local_channel())
+ return;
+
+ if(($_FILES) && array_key_exists('userfile',$_FILES) && intval($_FILES['userfile']['size'])) {
+ $src = $_FILES['userfile']['tmp_name'];
+ if($src) {
+ $result = parse_ical_file($src,local_channel());
+ if($result)
+ info( t('Calendar entries imported.') . EOL);
+ else
+ notice( t('No calendar entries found.') . EOL);
+ @unlink($src);
+ }
+ goaway(z_root() . '/channel_calendar');
+ }
+
+
+ $event_id = ((x($_POST,'event_id')) ? intval($_POST['event_id']) : 0);
+ $event_hash = ((x($_POST,'event_hash')) ? $_POST['event_hash'] : '');
+
+ $xchan = ((x($_POST,'xchan')) ? dbesc($_POST['xchan']) : '');
+ $uid = local_channel();
+
+ $start_text = escape_tags($_REQUEST['dtstart']);
+ $finish_text = escape_tags($_REQUEST['dtend']);
+
+ $adjust = intval($_POST['adjust']);
+ $nofinish = intval($_POST['nofinish']);
+
+ $timezone = ((x($_POST,'timezone_select')) ? notags(trim($_POST['timezone_select'])) : '');
+
+ $tz = (($timezone) ? $timezone : date_default_timezone_get());
+
+ $categories = escape_tags(trim($_POST['categories']));
+
+ // only allow editing your own events.
+
+ if(($xchan) && ($xchan !== get_observer_hash()))
+ return;
+
+ if($start_text) {
+ $start = $start_text;
+ }
+ else {
+ $start = sprintf('%d-%d-%d %d:%d:0',$startyear,$startmonth,$startday,$starthour,$startminute);
+ }
+
+ if($finish_text) {
+ $finish = $finish_text;
+ }
+ else {
+ $finish = sprintf('%d-%d-%d %d:%d:0',$finishyear,$finishmonth,$finishday,$finishhour,$finishminute);
+ }
+
+ if($nofinish) {
+ $finish = NULL_DATE;
+ }
+
+
+
+ if($adjust) {
+ $start = datetime_convert($tz,'UTC',$start);
+ if(! $nofinish)
+ $finish = datetime_convert($tz,'UTC',$finish);
+ }
+ else {
+ $start = datetime_convert('UTC','UTC',$start);
+ if(! $nofinish)
+ $finish = datetime_convert('UTC','UTC',$finish);
+ }
+
+
+
+ // Don't allow the event to finish before it begins.
+ // It won't hurt anything, but somebody will file a bug report
+ // and we'll waste a bunch of time responding to it. Time that
+ // could've been spent doing something else.
+
+
+ $summary = escape_tags(trim($_POST['summary']));
+ $desc = escape_tags(trim($_POST['desc']));
+ $location = escape_tags(trim($_POST['location']));
+ $type = escape_tags(trim($_POST['type']));
+
+ require_once('include/text.php');
+ linkify_tags($desc, local_channel());
+ linkify_tags($location, local_channel());
+
+ //$action = ($event_hash == '') ? 'new' : "event/" . $event_hash;
+
+ //fixme: this url gives a wsod if there is a linebreak detected in one of the variables ($desc or $location)
+ //$onerror_url = z_root() . "/events/" . $action . "?summary=$summary&description=$desc&location=$location&start=$start_text&finish=$finish_text&adjust=$adjust&nofinish=$nofinish&type=$type";
+ //$onerror_url = z_root() . "/events";
+
+ if(strcmp($finish,$start) < 0 && !$nofinish) {
+ notice( t('Event can not end before it has started.') . EOL);
+ if(intval($_REQUEST['preview'])) {
+ echo( t('Unable to generate preview.'));
+ killme();
+ }
+ //goaway($onerror_url);
+ }
+
+ if((! $summary) || (! $start)) {
+ notice( t('Event title and start time are required.') . EOL);
+ if(intval($_REQUEST['preview'])) {
+ echo( t('Unable to generate preview.'));
+ killme();
+ }
+ //goaway($onerror_url);
+ }
+
+ $channel = \App::get_channel();
+
+ $acl = new \Zotlabs\Access\AccessList(false);
+
+ if($event_id) {
+ $x = q("select * from event where id = %d and uid = %d limit 1",
+ intval($event_id),
+ intval(local_channel())
+ );
+ if(! $x) {
+ notice( t('Event not found.') . EOL);
+ if(intval($_REQUEST['preview'])) {
+ echo( t('Unable to generate preview.'));
+ killme();
+ }
+ return;
+ }
+
+ $acl->set($x[0]);
+
+ $created = $x[0]['created'];
+ $edited = datetime_convert();
+ }
+ else {
+ $created = $edited = datetime_convert();
+ $acl->set_from_array($_POST);
+ }
+
+ $post_tags = array();
+ $channel = \App::get_channel();
+ $ac = $acl->get();
+
+ if(strlen($categories)) {
+ $cats = explode(',',$categories);
+ foreach($cats as $cat) {
+ $post_tags[] = array(
+ 'uid' => $profile_uid,
+ 'ttype' => TERM_CATEGORY,
+ 'otype' => TERM_OBJ_POST,
+ 'term' => trim($cat),
+ 'url' => $channel['xchan_url'] . '?f=&cat=' . urlencode(trim($cat))
+ );
+ }
+ }
+
+ $datarray = array();
+ $datarray['dtstart'] = $start;
+ $datarray['dtend'] = $finish;
+ $datarray['summary'] = $summary;
+ $datarray['description'] = $desc;
+ $datarray['location'] = $location;
+ $datarray['etype'] = $type;
+ $datarray['adjust'] = $adjust;
+ $datarray['nofinish'] = $nofinish;
+ $datarray['uid'] = local_channel();
+ $datarray['account'] = get_account_id();
+ $datarray['event_xchan'] = $channel['channel_hash'];
+ $datarray['allow_cid'] = $ac['allow_cid'];
+ $datarray['allow_gid'] = $ac['allow_gid'];
+ $datarray['deny_cid'] = $ac['deny_cid'];
+ $datarray['deny_gid'] = $ac['deny_gid'];
+ $datarray['private'] = (($acl->is_private()) ? 1 : 0);
+ $datarray['id'] = $event_id;
+ $datarray['created'] = $created;
+ $datarray['edited'] = $edited;
+
+ if(intval($_REQUEST['preview'])) {
+ $html = format_event_html($datarray);
+ echo $html;
+ killme();
+ }
+
+ $event = event_store_event($datarray);
+
+ if($post_tags)
+ $datarray['term'] = $post_tags;
+
+ $item_id = event_store_item($datarray,$event);
+
+ if($item_id) {
+ $r = q("select * from item where id = %d",
+ intval($item_id)
+ );
+ if($r) {
+ xchan_query($r);
+ $sync_item = fetch_post_tags($r);
+ $z = q("select * from event where event_hash = '%s' and uid = %d limit 1",
+ dbesc($r[0]['resource_id']),
+ intval($channel['channel_id'])
+ );
+ if($z) {
+ build_sync_packet($channel['channel_id'],array('event_item' => array(encode_item($sync_item[0],true)),'event' => $z));
+ }
+ }
+ }
+
+ \Zotlabs\Daemon\Master::Summon(array('Notifier','event',$item_id));
+
+ killme();
+
+ }
+
+
+
+ function get() {
+
+ if(argc() > 2 && argv(1) == 'ical') {
+ $event_id = argv(2);
+
+ require_once('include/security.php');
+ $sql_extra = permissions_sql(local_channel());
+
+ $r = q("select * from event where event_hash = '%s' $sql_extra limit 1",
+ dbesc($event_id)
+ );
+ if($r) {
+ header('Content-type: text/calendar');
+ header('content-disposition: attachment; filename="' . t('event') . '-' . $event_id . '.ics"' );
+ echo ical_wrapper($r);
+ killme();
+ }
+ else {
+ notice( t('Event not found.') . EOL );
+ return;
+ }
+ }
+
+ if(! local_channel()) {
+ notice( t('Permission denied.') . EOL);
+ return;
+ }
+
+ if((argc() > 2) && (argv(1) === 'ignore') && intval(argv(2))) {
+ $r = q("update event set dismissed = 1 where id = %d and uid = %d",
+ intval(argv(2)),
+ intval(local_channel())
+ );
+ }
+
+ if((argc() > 2) && (argv(1) === 'unignore') && intval(argv(2))) {
+ $r = q("update event set dismissed = 0 where id = %d and uid = %d",
+ intval(argv(2)),
+ intval(local_channel())
+ );
+ }
+
+ $channel = \App::get_channel();
+
+ $mode = 'view';
+ $y = 0;
+ $m = 0;
+ $ignored = ((x($_REQUEST,'ignored')) ? " and dismissed = " . intval($_REQUEST['ignored']) . " " : '');
+
+ if(argc() > 1) {
+ if(argc() > 2 && argv(1) === 'add') {
+ $mode = 'add';
+ $item_id = intval(argv(2));
+ }
+ if(argc() > 2 && argv(1) === 'drop') {
+ $mode = 'drop';
+ $event_id = argv(2);
+ }
+ if(argc() > 2 && intval(argv(1)) && intval(argv(2))) {
+ $mode = 'view';
+ $y = intval(argv(1));
+ $m = intval(argv(2));
+ }
+ if(argc() <= 2) {
+ $mode = 'view';
+ $event_id = argv(1);
+ }
+ }
+
+ if($mode === 'add') {
+ event_addtocal($item_id,local_channel());
+ killme();
+ }
+
+ if($mode == 'view') {
+
+ /* edit/create form */
+ if($event_id) {
+ $r = q("SELECT * FROM event WHERE event_hash = '%s' AND uid = %d LIMIT 1",
+ dbesc($event_id),
+ intval(local_channel())
+ );
+ if(count($r))
+ $orig_event = $r[0];
+ }
+
+ $channel = \App::get_channel();
+
+ // Passed parameters overrides anything found in the DB
+ if(!x($orig_event))
+ $orig_event = array();
+
+ $n_checked = ((x($orig_event) && $orig_event['nofinish']) ? ' checked="checked" ' : '');
+ $a_checked = ((x($orig_event) && $orig_event['adjust']) ? ' checked="checked" ' : '');
+ $t_orig = ((x($orig_event)) ? $orig_event['summary'] : '');
+ $d_orig = ((x($orig_event)) ? $orig_event['description'] : '');
+ $l_orig = ((x($orig_event)) ? $orig_event['location'] : '');
+ $eid = ((x($orig_event)) ? $orig_event['id'] : 0);
+ $event_xchan = ((x($orig_event)) ? $orig_event['event_xchan'] : $channel['channel_hash']);
+ $mid = ((x($orig_event)) ? $orig_event['mid'] : '');
+
+ $sdt = ((x($orig_event)) ? $orig_event['dtstart'] : 'now');
+
+ $fdt = ((x($orig_event)) ? $orig_event['dtend'] : '+1 hour');
+
+ $tz = date_default_timezone_get();
+ if(x($orig_event))
+ $tz = (($orig_event['adjust']) ? date_default_timezone_get() : 'UTC');
+
+ $syear = datetime_convert('UTC', $tz, $sdt, 'Y');
+ $smonth = datetime_convert('UTC', $tz, $sdt, 'm');
+ $sday = datetime_convert('UTC', $tz, $sdt, 'd');
+ $shour = datetime_convert('UTC', $tz, $sdt, 'H');
+ $sminute = datetime_convert('UTC', $tz, $sdt, 'i');
+
+ $stext = datetime_convert('UTC',$tz,$sdt);
+ $stext = substr($stext,0,14) . "00:00";
+
+ $fyear = datetime_convert('UTC', $tz, $fdt, 'Y');
+ $fmonth = datetime_convert('UTC', $tz, $fdt, 'm');
+ $fday = datetime_convert('UTC', $tz, $fdt, 'd');
+ $fhour = datetime_convert('UTC', $tz, $fdt, 'H');
+ $fminute = datetime_convert('UTC', $tz, $fdt, 'i');
+
+ $ftext = datetime_convert('UTC',$tz,$fdt);
+ $ftext = substr($ftext,0,14) . "00:00";
+
+ $type = ((x($orig_event)) ? $orig_event['etype'] : 'event');
+
+ $f = get_config('system','event_input_format');
+ if(! $f)
+ $f = 'ymd';
+
+ $thisyear = datetime_convert('UTC',date_default_timezone_get(),'now','Y');
+ $thismonth = datetime_convert('UTC',date_default_timezone_get(),'now','m');
+ if(! $y)
+ $y = intval($thisyear);
+ if(! $m)
+ $m = intval($thismonth);
+
+ $export = false;
+ if(argc() === 4 && argv(3) === 'export')
+ $export = true;
+
+ // Put some limits on dates. The PHP date functions don't seem to do so well before 1900.
+ // An upper limit was chosen to keep search engines from exploring links millions of years in the future.
+
+ if($y < 1901)
+ $y = 1900;
+ if($y > 2099)
+ $y = 2100;
+
+ $nextyear = $y;
+ $nextmonth = $m + 1;
+ if($nextmonth > 12) {
+ $nextmonth = 1;
+ $nextyear ++;
+ }
+
+ $prevyear = $y;
+ if($m > 1)
+ $prevmonth = $m - 1;
+ else {
+ $prevmonth = 12;
+ $prevyear --;
+ }
+
+ $dim = get_dim($y,$m);
+ $start = sprintf('%d-%d-%d %d:%d:%d',$y,$m,1,0,0,0);
+ $finish = sprintf('%d-%d-%d %d:%d:%d',$y,$m,$dim,23,59,59);
+
+
+ if (argv(1) === 'json'){
+ if (x($_GET,'start')) $start = $_GET['start'];
+ if (x($_GET,'end')) $finish = $_GET['end'];
+ }
+
+ $start = datetime_convert('UTC','UTC',$start);
+ $finish = datetime_convert('UTC','UTC',$finish);
+
+ $adjust_start = datetime_convert('UTC', date_default_timezone_get(), $start);
+ $adjust_finish = datetime_convert('UTC', date_default_timezone_get(), $finish);
+
+ if (x($_GET,'id')){
+ $r = q("SELECT event.*, item.plink, item.item_flags, item.author_xchan, item.owner_xchan
+ from event left join item on resource_id = event_hash where resource_type = 'event' and event.uid = %d and event.id = %d limit 1",
+ intval(local_channel()),
+ intval($_GET['id'])
+ );
+ } elseif($export) {
+ $r = q("SELECT * from event where uid = %d
+ AND (( adjust = 0 AND ( dtend >= '%s' or nofinish = 1 ) AND dtstart <= '%s' )
+ OR ( adjust = 1 AND ( dtend >= '%s' or nofinish = 1 ) AND dtstart <= '%s' )) ",
+ intval(local_channel()),
+ dbesc($start),
+ dbesc($finish),
+ dbesc($adjust_start),
+ dbesc($adjust_finish)
+ );
+ }
+ else {
+ // fixed an issue with "nofinish" events not showing up in the calendar.
+ // There's still an issue if the finish date crosses the end of month.
+ // Noting this for now - it will need to be fixed here and in Friendica.
+ // Ultimately the finish date shouldn't be involved in the query.
+
+ $r = q("SELECT event.*, item.plink, item.item_flags, item.author_xchan, item.owner_xchan, item.id as item_id
+ from event left join item on event_hash = resource_id
+ where resource_type = 'event' and event.uid = %d and event.uid = item.uid $ignored
+ AND (( adjust = 0 AND ( dtend >= '%s' or nofinish = 1 ) AND dtstart <= '%s' )
+ OR ( adjust = 1 AND ( dtend >= '%s' or nofinish = 1 ) AND dtstart <= '%s' )) ",
+ intval(local_channel()),
+ dbesc($start),
+ dbesc($finish),
+ dbesc($adjust_start),
+ dbesc($adjust_finish)
+ );
+
+
+ }
+
+ $links = array();
+
+ if($r && ! $export) {
+ xchan_query($r);
+ $r = fetch_post_tags($r,true);
+
+ $r = sort_by_date($r);
+ }
+
+ if($r) {
+ foreach($r as $rr) {
+ $j = (($rr['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$rr['dtstart'], 'j') : datetime_convert('UTC','UTC',$rr['dtstart'],'j'));
+ if(! x($links,$j))
+ $links[$j] = z_root() . '/' . \App::$cmd . '#link-' . $j;
+ }
+ }
+
+ $events=array();
+
+ $last_date = '';
+ $fmt = t('l, F j');
+
+ if($r) {
+
+ foreach($r as $rr) {
+ $j = (($rr['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$rr['dtstart'], 'j') : datetime_convert('UTC','UTC',$rr['dtstart'],'j'));
+ $d = (($rr['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$rr['dtstart'], $fmt) : datetime_convert('UTC','UTC',$rr['dtstart'],$fmt));
+ $d = day_translate($d);
+
+ $start = (($rr['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$rr['dtstart'], 'c') : datetime_convert('UTC','UTC',$rr['dtstart'],'c'));
+ if ($rr['nofinish']){
+ $end = null;
+ } else {
+ $end = (($rr['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$rr['dtend'], 'c') : datetime_convert('UTC','UTC',$rr['dtend'],'c'));
+
+ // give a fake end to birthdays so they get crammed into a
+ // single day on the calendar
+
+ if($rr['etype'] === 'birthday')
+ $end = null;
+ }
+
+ $catsenabled = feature_enabled(local_channel(),'categories');
+ $categories = '';
+ if($catsenabled){
+ if($rr['term']) {
+ $cats = get_terms_oftype($rr['term'], TERM_CATEGORY);
+ foreach ($cats as $cat) {
+ if(strlen($categories))
+ $categories .= ', ';
+ $categories .= $cat['term'];
+ }
+ }
+ }
+
+ $allDay = false;
+
+ // allDay event rules
+ if(!strpos($start, 'T') && !strpos($end, 'T'))
+ $allDay = true;
+ if(strpos($start, 'T00:00:00') && strpos($end, 'T00:00:00'))
+ $allDay = true;
+
+ $is_first = ($d !== $last_date);
+
+ $last_date = $d;
+
+ $edit = ((local_channel() && $rr['author_xchan'] == get_observer_hash()) ? array(z_root().'/events/'.$rr['event_hash'].'?expandform=1',t('Edit event'),'','') : false);
+
+ $drop = array(z_root().'/events/drop/'.$rr['event_hash'],t('Delete event'),'','');
+
+ $title = strip_tags(html_entity_decode(zidify_links(bbcode($rr['summary'])),ENT_QUOTES,'UTF-8'));
+ if(! $title) {
+ list($title, $_trash) = explode("<br",bbcode($rr['desc']),2);
+ $title = strip_tags(html_entity_decode($title,ENT_QUOTES,'UTF-8'));
+ }
+ $html = format_event_html($rr);
+ $rr['desc'] = zidify_links(smilies(bbcode($rr['desc'])));
+ $rr['description'] = htmlentities(html2plain(bbcode($rr['description'])),ENT_COMPAT,'UTF-8',false);
+ $rr['location'] = zidify_links(smilies(bbcode($rr['location'])));
+ $events[] = array(
+ 'calendar_id' => 'channel_calendar',
+ 'rw' => true,
+
+ 'id'=>$rr['id'],
+ 'uri' => $rr['event_hash'],
+ 'start'=> $start,
+ 'end' => $end,
+ 'drop' => $drop,
+ 'allDay' => $allDay,
+ 'title' => $title,
+
+ 'j' => $j,
+ 'd' => $d,
+
+ 'editable' => $edit ? true : false,
+
+ 'is_first'=>$is_first,
+ 'item'=>$rr,
+ 'html'=>$html,
+ 'plink' => [$rr['plink'], t('Link to source')],
+
+ 'description' => $rr['description'],
+ 'location' => $rr['location'],
+
+ 'allow_cid' => expand_acl($rr['allow_cid']),
+ 'allow_gid' => expand_acl($rr['allow_gid']),
+ 'deny_cid' => expand_acl($rr['deny_cid']),
+ 'deny_gid' => expand_acl($rr['deny_gid']),
+
+ 'categories' => $categories
+ );
+ }
+ }
+
+ if($export) {
+ header('Content-type: text/calendar');
+ header('content-disposition: attachment; filename="' . t('calendar') . '-' . $channel['channel_address'] . '.ics"' );
+ echo ical_wrapper($r);
+ killme();
+ }
+
+ if (\App::$argv[1] === 'json'){
+ json_return_and_die($events);
+ }
+ }
+
+
+ if($mode === 'drop' && $event_id) {
+ $r = q("SELECT * FROM event WHERE event_hash = '%s' AND uid = %d LIMIT 1",
+ dbesc($event_id),
+ intval(local_channel())
+ );
+
+ $sync_event = $r[0];
+
+ if($r) {
+ $r = q("delete from event where event_hash = '%s' and uid = %d",
+ dbesc($event_id),
+ intval(local_channel())
+ );
+ if($r) {
+ $r = q("update item set resource_type = '', resource_id = '' where resource_type = 'event' and resource_id = '%s' and uid = %d",
+ dbesc($event_id),
+ intval(local_channel())
+ );
+ $sync_event['event_deleted'] = 1;
+ build_sync_packet(0,array('event' => array($sync_event)));
+ killme();
+ }
+ notice( t('Failed to remove event' ) . EOL);
+ killme();
+ }
+ }
+
+ }
+
+}
diff --git a/Zotlabs/Module/Directory.php b/Zotlabs/Module/Directory.php
index 5448a4816..8f5db6635 100644
--- a/Zotlabs/Module/Directory.php
+++ b/Zotlabs/Module/Directory.php
@@ -103,8 +103,14 @@ class Directory extends \Zotlabs\Web\Controller {
$suggest = (local_channel() && x($_REQUEST,'suggest')) ? $_REQUEST['suggest'] : '';
if($suggest) {
-
- $r = suggestion_query(local_channel(),get_observer_hash());
+
+ // the directory options have no effect in suggestion mode
+
+ $globaldir = 1;
+ $safe_mode = 1;
+ $type = 0;
+
+ $r = suggestion_query(local_channel(),get_observer_hash(),0,60);
if(! $r) {
notice( t('No default suggestions were found.') . EOL);
@@ -212,12 +218,17 @@ class Directory extends \Zotlabs\Web\Controller {
if($j) {
if($j['results']) {
-
+
+ $results = $j['results'];
+ if($suggest) {
+ $results = self::reorder_results($results,$addresses);
+ }
+
$entries = array();
$photo = 'thumb';
- foreach($j['results'] as $rr) {
+ foreach($results as $rr) {
$profile_link = chanlink_url($rr['url']);
@@ -438,5 +449,22 @@ class Directory extends \Zotlabs\Web\Controller {
return $o;
}
-
+ static public function reorder_results($results,$suggests) {
+
+ if(! $suggests)
+ return $results;
+
+ $out = [];
+ foreach($suggests as $k => $v) {
+ foreach($results as $rv) {
+ if($k == $rv['address']) {
+ $out[intval($v)] = $rv;
+ break;
+ }
+ }
+ }
+
+ return $out;
+ }
+
}
diff --git a/Zotlabs/Module/Editpost.php b/Zotlabs/Module/Editpost.php
index 1c9068e07..49b2892e8 100644
--- a/Zotlabs/Module/Editpost.php
+++ b/Zotlabs/Module/Editpost.php
@@ -45,7 +45,8 @@ class Editpost extends \Zotlabs\Web\Controller {
}
if($itm[0]['resource_type'] === 'event' && $itm[0]['resource_id']) {
- goaway(z_root() . '/events/' . $itm[0]['resource_id'] . '?expandform=1');
+ goaway(z_root() . '/cdav/calendar/' . $itm[0]['resource_id']);
+ //goaway(z_root() . '/events/' . $itm[0]['resource_id'] . '?expandform=1');
}
$owner_uid = $itm[0]['uid'];
diff --git a/Zotlabs/Module/Import.php b/Zotlabs/Module/Import.php
index a48c690a7..18cb5560e 100644
--- a/Zotlabs/Module/Import.php
+++ b/Zotlabs/Module/Import.php
@@ -280,8 +280,9 @@ class Import extends \Zotlabs\Web\Controller {
// replace any existing xchan we may have on this site if we're seizing control
- $r = q("delete from xchan where xchan_hash = '%s'",
- dbesc($channel['channel_hash'])
+ $r = q("delete from xchan where ( xchan_hash = '%s' or xchan_hash = '%s' ) ",
+ dbesc($channel['channel_hash']),
+ dbesc($channel['channel_portable_id'])
);
$r = xchan_store_lowlevel(
@@ -303,6 +304,30 @@ class Import extends \Zotlabs\Web\Controller {
'xchan_name_date' => datetime_convert()
]
);
+
+ if($channel['channel_portable_id']) {
+ $r = xchan_store_lowlevel(
+ [
+ 'xchan_hash' => \Zotlabs\Lib\Libzot::make_xchan_hash($channel['channel_guid'],$channel['channel_pubkey']),
+ 'xchan_guid' => $channel['channel_guid'],
+ 'xchan_guid_sig' => 'sha256.' . $channel['channel_guid_sig'],
+ 'xchan_pubkey' => $channel['channel_pubkey'],
+ 'xchan_photo_l' => z_root() . "/photo/profile/l/" . $channel['channel_id'],
+ 'xchan_photo_m' => z_root() . "/photo/profile/m/" . $channel['channel_id'],
+ 'xchan_photo_s' => z_root() . "/photo/profile/s/" . $channel['channel_id'],
+ 'xchan_addr' => channel_reddress($channel),
+ 'xchan_url' => z_root() . '/channel/' . $channel['channel_address'],
+ 'xchan_connurl' => z_root() . '/poco/' . $channel['channel_address'],
+ 'xchan_follow' => z_root() . '/follow?f=&url=%s',
+ 'xchan_name' => $channel['channel_name'],
+ 'xchan_network' => 'zot6',
+ 'xchan_photo_date' => datetime_convert(),
+ 'xchan_name_date' => datetime_convert()
+ ]
+ );
+ }
+
+
}
logger('import step 6');
@@ -312,10 +337,20 @@ class Import extends \Zotlabs\Web\Controller {
if($xchans) {
foreach($xchans as $xchan) {
- $hash = make_xchan_hash($xchan['xchan_guid'],$xchan['xchan_guid_sig']);
- if($xchan['xchan_network'] === 'zot' && $hash !== $xchan['xchan_hash']) {
- logger('forged xchan: ' . print_r($xchan,true));
- continue;
+ if($xchan['xchan_network'] === 'zot') {
+ $hash = make_xchan_hash($xchan['xchan_guid'],$xchan['xchan_guid_sig']);
+ if($hash !== $xchan['xchan_hash']) {
+ logger('forged xchan: ' . print_r($xchan,true));
+ continue;
+ }
+ }
+
+ if($xchan['xchan_network'] === 'zot6') {
+ $zhash = \Zotlabs\Lib\Libzot::make_xchan_hash($xchan['xchan_guid'],$xchan['xchan_pubkey']);
+ if($zhash !== $xchan['xchan_hash']) {
+ logger('forged xchan: ' . print_r($xchan,true));
+ continue;
+ }
}
if(! array_key_exists('xchan_hidden',$xchan)) {
diff --git a/Zotlabs/Module/Item.php b/Zotlabs/Module/Item.php
index 93df95f49..6bc8c645f 100644
--- a/Zotlabs/Module/Item.php
+++ b/Zotlabs/Module/Item.php
@@ -216,7 +216,7 @@ class Item extends Controller {
$parent = ((x($_REQUEST,'parent')) ? intval($_REQUEST['parent']) : 0);
$parent_mid = ((x($_REQUEST,'parent_mid')) ? trim($_REQUEST['parent_mid']) : '');
-
+
$remote_xchan = ((x($_REQUEST,'remote_xchan')) ? trim($_REQUEST['remote_xchan']) : false);
$r = q("select * from xchan where xchan_hash = '%s' limit 1",
dbesc($remote_xchan)
@@ -329,13 +329,8 @@ class Item extends Controller {
$obj_type = ACTIVITY_OBJ_COMMENT;
if($parent) {
- // Get replied comment data
- $reply = q("SELECT parent, mid FROM item WHERE id = %d LIMIT 1",
- intval($parent)
- );
- // and its parent
$r = q("SELECT * FROM item WHERE id = %d LIMIT 1",
- intval($reply[0]['parent'])
+ intval($parent)
);
}
elseif($parent_mid && $uid) {
@@ -379,7 +374,7 @@ class Item extends Controller {
// multi-level threading - preserve the info but re-parent to our single level threading
- $thr_parent = $reply[0]['mid'];
+ $thr_parent = $parent_mid;
$route = $parent_item['route'];
@@ -918,6 +913,7 @@ class Item extends Controller {
$parent_mid = $parent_item['mid'];
+
// Fallback so that we alway have a thr_parent
if(!$thr_parent)
@@ -1018,7 +1014,7 @@ class Item extends Controller {
$datarray['term'] = $post_tags;
$datarray['plink'] = $plink;
$datarray['route'] = $route;
-
+
// A specific ACL over-rides public_policy completely
diff --git a/Zotlabs/Module/Linkinfo.php b/Zotlabs/Module/Linkinfo.php
index 32b4c0281..b9f90deec 100644
--- a/Zotlabs/Module/Linkinfo.php
+++ b/Zotlabs/Module/Linkinfo.php
@@ -69,6 +69,14 @@ class Linkinfo extends \Zotlabs\Web\Controller {
killme();
}
if(stripos($type,'video/') !== false) {
+ $thumb = self::get_video_poster($url);
+ if($thumb) {
+ if ($zrl)
+ echo $br . '[zvideo poster=\'' . $thumb . '\']' . $url . '[/zvideo]' . $br;
+ else
+ echo $br . '[video poster=\'' . $thumb . '\']' . $url . '[/video]' . $br;
+ killme();
+ }
if($zrl)
echo $br . '[zvideo]' . $url . '[/zvideo]' . $br;
else
@@ -216,7 +224,42 @@ class Linkinfo extends \Zotlabs\Web\Controller {
return($complete);
}
-
+
+ public static function get_video_poster($url) {
+
+ if(strpos($url,z_root() . '/cloud/') === false) {
+ return EMPTY_STR;
+ }
+ $m = parse_url($url,PHP_URL_PATH);
+ if($m) {
+ // strip leading '/cloud/'
+ $m = substr($m,7);
+ }
+ $nick = substr($m,0,strpos($m,'/'));
+ $p = substr($m,strpos($m,'/')+1);
+
+ // get the channel to check permissions
+
+ $u = channelx_by_nick($nick);
+
+ if($u && $p) {
+
+ $sql_extra = permissions_sql(intval($u['channel_id']));
+
+ $r = q("select hash, content from attach where display_path = '%s' and uid = %d and os_storage = 1 $sql_extra limit 1",
+ dbesc($p),
+ intval($u['channel_id'])
+ );
+ if($r) {
+ $path = dbunescbin($r[0]['content']);
+ if($path && @file_exists($path . '.thumb')) {
+ return z_root() . '/poster/' . $nick . '/' . $r[0]['hash'];
+ }
+ }
+ }
+ return EMPTY_STR;
+ }
+
public static function parseurl_getsiteinfo($url) {
$siteinfo = array();
diff --git a/Zotlabs/Module/Magic.php b/Zotlabs/Module/Magic.php
index 71737eef8..e8e960574 100644
--- a/Zotlabs/Module/Magic.php
+++ b/Zotlabs/Module/Magic.php
@@ -169,8 +169,8 @@ class Magic extends \Zotlabs\Web\Controller {
$token = $j['token'];
}
- $x = strpbrk($dest,'?&');
- $args = (($x) ? '&owt=' . $token : '?f=&owt=' . $token) . (($delegate) ? '&delegate=1' : '');
+ $strp = strpbrk($dest,'?&');
+ $args = (($strp) ? '&owt=' . $token : '?f=&owt=' . $token) . (($delegate) ? '&delegate=1' : '');
goaway($dest . $args);
}
}
diff --git a/Zotlabs/Module/Owa.php b/Zotlabs/Module/Owa.php
index ad57f883c..cf116a96c 100644
--- a/Zotlabs/Module/Owa.php
+++ b/Zotlabs/Module/Owa.php
@@ -30,12 +30,29 @@ class Owa extends \Zotlabs\Web\Controller {
$keyId = $sigblock['keyId'];
if($keyId) {
+
+ // Hubzilla connections can have both zot and zot6 hublocs
+ // The connections will usually be zot so match those first
+
$r = q("select * from hubloc left join xchan on hubloc_hash = xchan_hash
- where ( hubloc_addr = '%s' or hubloc_id_url = '%s' ) ",
+ where ( hubloc_addr = '%s' or hubloc_id_url = '%s' ) and hubloc_network = 'zot' ",
dbesc(str_replace('acct:','',$keyId)),
dbesc($keyId)
);
- if(! $r) {
+
+ // If nothing was found, try searching on any network
+
+ if (! $r) {
+ $r = q("select * from hubloc left join xchan on hubloc_hash = xchan_hash
+ where ( hubloc_addr = '%s' or hubloc_id_url = '%s' )",
+ dbesc(str_replace('acct:','',$keyId)),
+ dbesc($keyId)
+ );
+ }
+
+ // If nothing was found on any network, use network discovery and create a new record
+
+ if (! $r) {
$found = discover_by_webbie(str_replace('acct:','',$keyId));
if($found) {
$r = q("select * from hubloc left join xchan on hubloc_hash = xchan_hash
@@ -45,7 +62,8 @@ class Owa extends \Zotlabs\Web\Controller {
);
}
}
- if($r) {
+
+ if ($r) {
foreach($r as $hubloc) {
$verified = \Zotlabs\Web\HTTPSig::verify(file_get_contents('php://input'),$hubloc['xchan_pubkey']);
if($verified && $verified['header_signed'] && $verified['header_valid']) {
@@ -53,7 +71,7 @@ class Owa extends \Zotlabs\Web\Controller {
logger('OWA success: ' . $hubloc['hubloc_addr'],LOGGER_DATA);
$ret['success'] = true;
$token = random_string(32);
- \Zotlabs\Lib\Verify::create('owt',0,$token,$hubloc['hubloc_addr']);
+ \Zotlabs\Lib\Verify::create('owt',0,$token,$hubloc['hubloc_network'] . ',' . $hubloc['hubloc_addr']);
$result = '';
openssl_public_encrypt($token,$result,$hubloc['xchan_pubkey']);
$ret['encrypted_token'] = base64url_encode($result);
diff --git a/Zotlabs/Module/Ping.php b/Zotlabs/Module/Ping.php
index a367b1062..3dabe0f7b 100644
--- a/Zotlabs/Module/Ping.php
+++ b/Zotlabs/Module/Ping.php
@@ -447,7 +447,7 @@ class Ping extends \Zotlabs\Web\Controller {
$when = day_translate(datetime_convert('UTC', (($rr['adjust']) ? date_default_timezone_get() : 'UTC'), $rr['dtstart'], $bd_format)) . (($today) ? ' ' . t('[today]') : '');
$result[] = array(
- 'notify_link' => z_root() . '/events', /// @FIXME this takes you to an edit page and it may not be yours, we really want to just view the single event --> '/events/event/' . $rr['event_hash'],
+ 'notify_link' => z_root() . '/cdav/calendar/' . $rr['event_hash'],
'name' => $rr['xchan_name'],
'addr' => $rr['xchan_addr'],
'url' => $rr['xchan_url'],
diff --git a/Zotlabs/Module/Poster.php b/Zotlabs/Module/Poster.php
new file mode 100644
index 000000000..10317ee61
--- /dev/null
+++ b/Zotlabs/Module/Poster.php
@@ -0,0 +1,37 @@
+<?php
+
+namespace Zotlabs\Module;
+
+use Zotlabs\Web\Controller;
+
+require_once('include/security.php');
+
+class Poster extends Controller {
+
+ function init() {
+
+ $nick = argv(1);
+ $hash = argv(2);
+
+ if(! ($nick && $hash)) {
+ return;
+ }
+
+ $u = channelx_by_nick($nick);
+
+ $sql_extra = permissions_sql(intval($u['channel_id']));
+
+ $r = q("select content from attach where hash = '%s' and uid = %d and os_storage = 1 $sql_extra limit 1",
+ dbesc($hash),
+ intval($u['channel_id'])
+ );
+ if($r) {
+ $path = dbunescbin($r[0]['content']);
+ if($path && @file_exists($path . '.thumb')) {
+ header('Content-Type: image/jpeg');
+ echo file_get_contents($path . '.thumb');
+ killme();
+ }
+ }
+ }
+}
diff --git a/Zotlabs/Module/Setup.php b/Zotlabs/Module/Setup.php
index c809ff5ec..541e4fa21 100644
--- a/Zotlabs/Module/Setup.php
+++ b/Zotlabs/Module/Setup.php
@@ -377,7 +377,7 @@ class Setup extends \Zotlabs\Web\Controller {
if(version_compare(PHP_VERSION, '7.1') < 0) {
$help .= t('PHP version 7.1 or greater is required.');
- $this->check_add($checks, t('PHP version'), false, false, $help);
+ $this->check_add($checks, t('PHP version'), false, true, $help);
}
if(strlen($phpath)) {
diff --git a/Zotlabs/Module/Wall_attach.php b/Zotlabs/Module/Wall_attach.php
index 2250e6e44..0ede3ad90 100644
--- a/Zotlabs/Module/Wall_attach.php
+++ b/Zotlabs/Module/Wall_attach.php
@@ -96,9 +96,26 @@ class Wall_attach extends \Zotlabs\Web\Controller {
$s = "\n\n" . $r['body'] . "\n\n";
}
else {
- $s = "\n\n" . '[attachment]' . $r['data']['hash'] . ',' . $r['data']['revision'] . '[/attachment]' . "\n";
+ if(strpos($r['data']['filetype'],'video') === 0) {
+ // give a wee bit of time for the background thumbnail processor to do its thing
+ // or else we'll never see a video poster
+ sleep(3);
+ $url = z_root() . '/cloud/' . $channel['channel_address'] . '/' . $r['data']['display_path'];
+ $thumb = Linkinfo::get_video_poster($url);
+ if($thumb) {
+ $s = "\n\n" . '[zvideo poster=\'' . $thumb . '\']' . $url . '[/zvideo]' . "\n\n";
+ }
+ else {
+ $s = "\n\n" . '[zvideo]' . $url . '[/zvideo]' . "\n\n";
+ }
+ }
+ if(strpos($r['data']['filetype'],'audio') === 0) {
+ $url = z_root() . '/cloud/' . $channel['channel_address'] . '/' . $r['data']['display_path'];
+ echo "\n\n" . '[zaudio]' . $url . '[/zaudio]' . "\n\n";
+ }
+
+ $s .= "\n\n" . '[attachment]' . $r['data']['hash'] . ',' . $r['data']['revision'] . '[/attachment]' . "\n";
}
-
$sync = attach_export_data($channel,$r['data']['hash']);
if($sync) {
diff --git a/Zotlabs/Module/Wfinger.php b/Zotlabs/Module/Wfinger.php
index 03275abbc..a19bdbedc 100644
--- a/Zotlabs/Module/Wfinger.php
+++ b/Zotlabs/Module/Wfinger.php
@@ -128,7 +128,7 @@ class Wfinger extends \Zotlabs\Web\Controller {
'http://webfinger.net/ns/name' => $r[0]['channel_name'],
'http://xmlns.com/foaf/0.1/name' => $r[0]['channel_name'],
'https://w3id.org/security/v1#publicKeyPem' => $r[0]['xchan_pubkey'],
- 'http://purl.org/zot/federation' => 'zot'
+ 'http://purl.org/zot/federation' => 'zot,zot6'
];
foreach($aliases as $alias)