aboutsummaryrefslogtreecommitdiffstats
path: root/Zotlabs
diff options
context:
space:
mode:
authorzotlabs <mike@macgirvin.com>2019-04-24 16:21:13 -0700
committerzotlabs <mike@macgirvin.com>2019-04-24 16:21:13 -0700
commit831b9d443330cb806871ab06aaa977adafbe661e (patch)
tree4c067a3b701ea56f10070c386b26a30f93666eb0 /Zotlabs
parente56c0a6251e8361ba65702151473a0560506db77 (diff)
parente937e8fff96a935b14a479c062f6b0d00b90b99d (diff)
downloadvolse-hubzilla-831b9d443330cb806871ab06aaa977adafbe661e.tar.gz
volse-hubzilla-831b9d443330cb806871ab06aaa977adafbe661e.tar.bz2
volse-hubzilla-831b9d443330cb806871ab06aaa977adafbe661e.zip
Merge branch 'dev' of https://framagit.org/hubzilla/core into dev
Diffstat (limited to 'Zotlabs')
-rw-r--r--Zotlabs/Module/Cdav.php43
-rw-r--r--Zotlabs/Module/Channel_calendar.php620
-rw-r--r--Zotlabs/Module/Editpost.php3
-rw-r--r--Zotlabs/Module/Photo.php72
-rw-r--r--Zotlabs/Module/Ping.php2
-rw-r--r--Zotlabs/Module/Profile_photo.php34
-rw-r--r--Zotlabs/Widget/Cdav.php18
7 files changed, 740 insertions, 52 deletions
diff --git a/Zotlabs/Module/Cdav.php b/Zotlabs/Module/Cdav.php
index 5dd233d28..8985e257a 100644
--- a/Zotlabs/Module/Cdav.php
+++ b/Zotlabs/Module/Cdav.php
@@ -906,6 +906,19 @@ class Cdav extends Controller {
$sources = '';
+ 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
$color = (($calendar['{http://apple.com/ns/ical/}calendar-color']) ? $calendar['{http://apple.com/ns/ical/}calendar-color'] : '#3a87ad');
@@ -939,6 +952,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 +981,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,
@@ -962,11 +989,23 @@ class Cdav extends Controller {
'$location' => $location,
'$more' => t('More'),
'$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')
]);
return $o;
@@ -1053,7 +1092,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_calendar.php b/Zotlabs/Module/Channel_calendar.php
new file mode 100644
index 000000000..d47d5ad49
--- /dev/null
+++ b/Zotlabs/Module/Channel_calendar.php
@@ -0,0 +1,620 @@
+<?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);
+ }
+
+ // $share = ((intval($_POST['distr'])) ? intval($_POST['distr']) : 0);
+
+ $share = 1;
+
+ $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();
+
+ if($x[0]['allow_cid'] === '<' . $channel['channel_hash'] . '>'
+ && $x[0]['allow_gid'] === '' && $x[0]['deny_cid'] === '' && $x[0]['deny_gid'] === '') {
+ $share = false;
+ }
+ else {
+ $share = true;
+ }
+ }
+ else {
+ $created = $edited = datetime_convert();
+ if($share) {
+ $acl->set_from_array($_POST);
+ }
+ else {
+ $acl->set(array('allow_cid' => '<' . $channel['channel_hash'] . '>', 'allow_gid' => '', 'deny_cid' => '', 'deny_gid' => ''));
+ }
+ }
+
+ $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));
+ }
+ }
+ }
+
+ if($share)
+ \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'];
+ }
+ }
+ }
+
+ $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' => false,
+ 'title' => $title,
+
+ 'j' => $j,
+ 'd' => $d,
+ 'is_editable' => $edit ? true : false,
+
+ 'is_first'=>$is_first,
+ 'item'=>$rr,
+ 'html'=>$html,
+ 'plink' => array($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/Editpost.php b/Zotlabs/Module/Editpost.php
index 1c9068e07..85882bf0a 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');
+ //goaway(z_root() . '/events/' . $itm[0]['resource_id'] . '?expandform=1');
}
$owner_uid = $itm[0]['uid'];
diff --git a/Zotlabs/Module/Photo.php b/Zotlabs/Module/Photo.php
index 37ae03460..30670c329 100644
--- a/Zotlabs/Module/Photo.php
+++ b/Zotlabs/Module/Photo.php
@@ -40,7 +40,7 @@ class Photo extends \Zotlabs\Web\Controller {
call_hooks('cache_mode_hook', $cache_mode);
$observer_xchan = get_observer_hash();
- $ismodified = $_SERVER['HTTP_IF_MODIFIED_SINCE'];
+ $cachecontrol = '';
if(isset($type)) {
@@ -68,8 +68,6 @@ class Photo extends \Zotlabs\Web\Controller {
}
}
- $modified = filemtime($default);
- $default = z_root() . '/' . $default;
$uid = $person;
$data = '';
@@ -97,13 +95,17 @@ class Photo extends \Zotlabs\Web\Controller {
$default = $d['default'];
$data = $d['data'];
$mimetype = $d['mimetype'];
+ $modified = 0;
}
if(! $data) {
- $x = z_fetch_url($default,true,0,[ 'novalidate' => true ]);
+ $x = z_fetch_url(z_root() . '/' . $default, true, 0, [ 'novalidate' => true ]);
$data = ($x['success'] ? $x['body'] : EMPTY_STR);
$mimetype = 'image/png';
+ $modified = filemtime($default);
}
+
+ $cachecontrol = ', must-revalidate';
}
else {
@@ -160,18 +162,20 @@ class Photo extends \Zotlabs\Web\Controller {
$allowed = (-1);
if($u === PHOTO_CACHE) {
// Validate cache
- $cache = array(
- 'resid' => $photo,
- 'status' => false
- );
- if($cache_mode['on'])
+ if($cache_mode['on']) {
+ $cache = array(
+ 'resid' => $photo,
+ 'status' => false
+ );
call_hooks('cache_url_hook', $cache);
- if(! $cache['status']) {
- $url = htmlspecialchars_decode($r[0]['display_path']);
- if(strpos(z_root(),'https:') !== false && strpos($url,'https:') === false)
- $url = z_root() . '/sslify/' . $filename . '?f=&url=' . urlencode($url);
- header("Location: " . $url);
- killme();
+ if(! $cache['status']) {
+ $url = htmlspecialchars_decode($r[0]['display_path']);
+ // SSLify if needed
+ if(strpos(z_root(),'https:') !== false && strpos($url,'https:') === false)
+ $url = z_root() . '/sslify/' . $filename . '?f=&url=' . urlencode($url);
+ header("Location: " . $url);
+ killme();
+ }
}
}
}
@@ -216,38 +220,23 @@ class Photo extends \Zotlabs\Web\Controller {
http_status_exit(404,'not found');
}
+ if(! $data)
+ killme();
+
+ $etag = md5($data . $modified);
+
+ if($modified == 0)
+ $modified = time();
+
header_remove('Pragma');
- if($ismodified === gmdate("D, d M Y H:i:s", $modified) . " GMT") {
+ if($_SERVER['HTTP_IF_NONE_MATCH'] === $etag || $_SERVER['HTTP_IF_MODIFIED_SINCE'] === gmdate("D, d M Y H:i:s", $modified) . " GMT") {
header_remove('Expires');
header_remove('Cache-Control');
header_remove('Set-Cookie');
http_status_exit(304,'not modified');
- }
-
- if(! isset($data)) {
- if(isset($resolution)) {
- switch($resolution) {
- case 4:
- $default = get_default_profile_photo();
- break;
- case 5:
- $default = get_default_profile_photo(80);
- break;
- case 6:
- $default = get_default_profile_photo(48);
- break;
- default:
- killme();
- // NOTREACHED
- break;
- }
- $x = z_fetch_url(z_root() . '/' . $default,true,0,[ 'novalidate' => true ]);
- $data = ($x['success'] ? $x['body'] : EMPTY_STR);
- $mimetype = 'image/png';
- }
}
-
+
if(isset($res) && intval($res) && $res < 500) {
$ph = photo_factory($data, $mimetype);
if($ph->is_valid()) {
@@ -284,12 +273,13 @@ class Photo extends \Zotlabs\Web\Controller {
$maxage = $expires - time();
header("Expires: " . gmdate("D, d M Y H:i:s", $expires) . " GMT");
- header("Cache-Control: max-age=" . $maxage);
+ header("Cache-Control: max-age=" . $maxage . $cachecontrol);
}
header("Content-type: " . $mimetype);
header("Last-Modified: " . gmdate("D, d M Y H:i:s", $modified) . " GMT");
+ header("ETag: " . $etag);
header("Content-Length: " . (isset($filesize) ? $filesize : strlen($data)));
// If it's a file resource, stream it.
diff --git a/Zotlabs/Module/Ping.php b/Zotlabs/Module/Ping.php
index a367b1062..f0c3a8821 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', /// @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'],
'name' => $rr['xchan_name'],
'addr' => $rr['xchan_addr'],
'url' => $rr['xchan_url'],
diff --git a/Zotlabs/Module/Profile_photo.php b/Zotlabs/Module/Profile_photo.php
index 9f1928e52..a812ca210 100644
--- a/Zotlabs/Module/Profile_photo.php
+++ b/Zotlabs/Module/Profile_photo.php
@@ -52,14 +52,39 @@ class Profile_photo extends \Zotlabs\Web\Controller {
return;
}
+ $channel = \App::get_channel();
+
check_form_security_token_redirectOnErr('/profile_photo', 'profile_photo');
+
+ // Remove cover photo
+ if(isset($_POST['remove'])) {
+
+ $r = q("SELECT resource_id FROM photo WHERE photo_usage = %d AND uid = %d LIMIT 1",
+ intval(PHOTO_PROFILE),
+ intval(local_channel())
+ );
+
+ if($r) {
+ q("update photo set photo_usage = %d where photo_usage = %d and uid = %d",
+ intval(PHOTO_NORMAL),
+ intval(PHOTO_PROFILE),
+ intval(local_channel())
+ );
+
+ $sync = attach_export_data($channel,$r[0]['resource_id']);
+ if($sync)
+ build_sync_packet($channel['channel_id'],array('file' => array($sync)));
+ }
+
+ $_SESSION['reload_avatar'] = true;
+
+ goaway(z_root() . '/profiles');
+ }
if((array_key_exists('cropfinal',$_POST)) && (intval($_POST['cropfinal']) == 1)) {
// logger('crop: ' . print_r($_POST,true));
-
-
// phase 2 - we have finished cropping
if(argc() != 2) {
@@ -161,8 +186,6 @@ class Profile_photo extends \Zotlabs\Web\Controller {
return;
}
- $channel = \App::get_channel();
-
// If setting for the default profile, unset the profile photo flag from any other photos I own
if($is_default_profile) {
@@ -390,8 +413,10 @@ class Profile_photo extends \Zotlabs\Web\Controller {
if($sync)
build_sync_packet($channel['channel_id'],array('file' => array($sync)));
+ $_SESSION['reload_avatar'] = true;
\Zotlabs\Daemon\Master::Summon(array('Directory',local_channel()));
+
goaway(z_root() . '/profiles');
}
@@ -471,6 +496,7 @@ class Profile_photo extends \Zotlabs\Web\Controller {
'$lbl_profiles' => t('Select a profile:'),
'$title' => (($importing) ? t('Use Photo for Profile') : t('Change Profile Photo')),
'$submit' => (($importing) ? t('Use') : t('Upload')),
+ '$remove' => t('Remove'),
'$profiles' => $profiles,
'$single' => ((count($profiles) == 1) ? true : false),
'$profile0' => $profiles[0],
diff --git a/Zotlabs/Widget/Cdav.php b/Zotlabs/Widget/Cdav.php
index 589f915c5..c88530c0b 100644
--- a/Zotlabs/Widget/Cdav.php
+++ b/Zotlabs/Widget/Cdav.php
@@ -113,10 +113,22 @@ class Cdav {
}
}
+ $channel_calendars[] = [
+ 'ownernick' => $channel['channel_address'],
+ 'displayname' => $channel['channel_name'],
+ 'calendarid' => 'channel_calendar',
+ 'json_source' => '/channel_calendar/json',
+ 'color' => '#3a87ad',
+ 'editable' => true,
+ 'switch' => get_pconfig(local_channel(), 'cdav_calendar', 'channel_calendar')
+ ];
+
$o .= replace_macros(get_markup_template('cdav_widget_calendar.tpl'), [
- '$my_calendars_label' => t('My Calendars'),
+ '$channel_calendars_label' => t('Channel Calendar'),
+ '$channel_calendars' => $channel_calendars,
+ '$my_calendars_label' => t('CalDAV Calendars'),
'$my_calendars' => $my_calendars,
- '$shared_calendars_label' => t('Shared Calendars'),
+ '$shared_calendars_label' => t('Shared CalDAV Calendars'),
'$shared_calendars' => $shared_calendars,
'$sharee_options' => $sharee_options,
'$access_options' => $access_options,
@@ -127,7 +139,7 @@ class Cdav {
'$create_label' => t('Create new calendar'),
'$create' => t('Create'),
'$create_placeholder' => t('Calendar Name'),
- '$tools_label' => t('Calendar Tools'),
+ '$tools_label' => t('CalDAV Calendar Tools'),
'$import_label' => t('Import calendar'),
'$import_placeholder' => t('Select a calendar to import to'),
'$upload' => t('Upload'),