function init() { if (argc() != 3 || !in_array(argv(1), ['post', 'status_message', 'reshare'])) { http_status_exit(404, 'Not found'); } $guid = argv(2); // Fetch the item $item = q("SELECT * from item where mid = '%s' and item_private = 0 and mid = parent_mid limit 1", dbesc($guid)); if (!$item) { http_status_exit(404, 'Not found'); } xchan_query($item); $item = fetch_post_tags($item, true); $channel = channelx_by_hash($item[0]['author_xchan']); if (!$channel) { $r = q("select * from xchan where xchan_hash = '%s' limit 1", dbesc($item[0]['author_xchan'])); if ($r) { $url = $r[0]['xchan_url']; if (strpos($url, z_root()) === false) { $m = parse_url($url); goaway($m['scheme'] . '://' . $m['host'] . ($m['port'] ? ':' . $m['port'] : '') . '/fetch/' . argv(1) . '/' . argv(2)); } } http_status_exit(404, 'Not found'); } $status = diaspora_build_status($item[0], $channel); header("Content-type: application/magic-envelope+xml; charset=utf-8"); echo diaspora_magic_env($channel, $status); killme(); }
function post() { $hash = $_POST['hash']; $time = $_POST['time']; $sig = $_POST['signature']; $resource = $_POST['resource']; $revision = intval($_POST['revision']); if (!$hash) { killme(); } $channel = channelx_by_hash($hash); if (!$channel || !$time || !$sig) { killme(); } $slop = intval(get_pconfig($channel['channel_id'], 'system', 'getfile_time_slop')); if ($slop < 1) { $slop = 3; } $d1 = datetime_convert('UTC', 'UTC', "now + {$slop} minutes"); $d2 = datetime_convert('UTC', 'UTC', "now - {$slop} minutes"); if ($time > $d1 || $time < $d2) { logger('time outside allowable range'); killme(); } if (!rsa_verify($hash . '.' . $time, base64url_decode($sig), $channel['channel_pubkey'])) { logger('verify failed.'); killme(); } $r = attach_by_hash($resource, $revision); if (!$r['success']) { notice($r['message'] . EOL); return; } $unsafe_types = array('text/html', 'text/css', 'application/javascript'); if (in_array($r['data']['filetype'], $unsafe_types)) { header('Content-type: text/plain'); } else { header('Content-type: ' . $r['data']['filetype']); } header('Content-disposition: attachment; filename="' . $r['data']['filename'] . '"'); if (intval($r['data']['os_storage'])) { $fname = dbunescbin($r['data']['data']); if (strpos($fname, 'store') !== false) { $istream = fopen($fname, 'rb'); } else { $istream = fopen('store/' . $channel['channel_address'] . '/' . $fname, 'rb'); } $ostream = fopen('php://output', 'wb'); if ($istream && $ostream) { pipe_streams($istream, $ostream); fclose($istream); fclose($ostream); } } else { echo dbunescbin($r['data']['data']); } killme(); }
function get() { if (!local_channel()) { return; } if (get_pconfig(local_channel(), 'cdav', 'enabled') != 1) { return t('You have to enable this plugin in Feature/Addon Settings > CalDAV/CardDAV Settings before you can use it.'); } //TODO: add a possibility to enable this plugin here. $channel = \App::get_channel(); $principalUri = 'principals/' . $channel['channel_address']; if (!cdav_principal($principalUri)) { return; } if (\DBA::$dba && \DBA::$dba->connected) { $pdovars = \DBA::$dba->pdo_get(); } else { killme(); } $pdo = new \PDO($pdovars[0], $pdovars[1], $pdovars[2]); $pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION); require_once 'vendor/autoload.php'; head_add_css('addon/cdav/view/css/cdav.css'); if (argv(1) === 'calendar') { $caldavBackend = new \Sabre\CalDAV\Backend\PDO($pdo); $calendars = $caldavBackend->getCalendarsForUser($principalUri); } //Display calendar(s) here if (argc() == 2 && argv(1) === 'calendar') { head_add_css('library/fullcalendar/fullcalendar.css'); head_add_css('addon/cdav/view/css/cdav_calendar.css'); head_add_js('library/moment/moment.min.js', 1); head_add_js('library/fullcalendar/fullcalendar.min.js', 1); head_add_js('library/fullcalendar/locale-all.js', 1); 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'; $sharer = $calendar['share-access'] == 3 ? $calendar['{urn:ietf:params:xml:ns:caldav}calendar-description'] : ''; $switch = get_pconfig(local_channel(), 'cdav_calendar', $calendar['id'][0]); if ($switch) { $sources .= '{ url: \'/cdav/calendar/json/' . $calendar['id'][0] . '/' . $calendar['id'][1] . '\', color: \'' . $color . '\' }, '; } if ($calendar['share-access'] != 2) { $writable_calendars[] = ['displayname' => $calendar['{DAV:}displayname'], 'sharer' => $sharer, 'id' => $calendar['id']]; } } $sources = rtrim($sources, ', '); $first_day = get_pconfig(local_channel(), 'system', 'cal_first_day'); $first_day = $first_day ? $first_day : 0; $title = ['title', t('Event title')]; $dtstart = ['dtstart', t('Start date and time'), '', t('Example: YYYY-MM-DD HH:mm')]; $dtend = ['dtend', t('End date and time'), '', t('Example: YYYY-MM-DD HH:mm')]; $description = ['description', t('Description')]; $location = ['location', t('Location')]; $o .= replace_macros(get_markup_template('cdav_calendar.tpl', 'addon/cdav'), ['$sources' => $sources, '$color' => $color, '$lang' => \App::$language, '$first_day' => $first_day, '$prev' => t('Previous'), '$next' => t('Next'), '$today' => t('Today'), '$month' => t('Month'), '$week' => t('Week'), '$day' => t('Day'), '$list_month' => t('List month'), '$list_week' => t('List week'), '$list_day' => t('List day'), '$title' => $title, '$writable_calendars' => $writable_calendars, '$dtstart' => $dtstart, '$dtend' => $dtend, '$description' => $description, '$location' => $location, '$more' => t('More'), '$less' => t('Less'), '$calendar_select_label' => t('Select calendar'), '$delete' => t('Delete'), '$delete_all' => t('Delete all'), '$cancel' => t('Cancel'), '$recurrence_warning' => t('Sorry! Editing of recurrent events is not yet implemented.')]); return $o; } //Provide json data for calendar if (argc() == 5 && argv(1) === 'calendar' && argv(2) === 'json' && intval(argv(3)) && intval(argv(4))) { $id = [argv(3), argv(4)]; if (!cdav_perms($id[0], $calendars)) { killme(); } if (x($_GET, 'start')) { $start = new \DateTime($_GET['start']); } if (x($_GET, 'end')) { $end = new \DateTime($_GET['end']); } $filters['name'] = 'VCALENDAR'; $filters['prop-filters'][0]['name'] = 'VEVENT'; $filters['comp-filters'][0]['name'] = 'VEVENT'; $filters['comp-filters'][0]['time-range']['start'] = $start; $filters['comp-filters'][0]['time-range']['end'] = $end; $uris = $caldavBackend->calendarQuery($id, $filters); if ($uris) { $objects = $caldavBackend->getMultipleCalendarObjects($id, $uris); foreach ($objects as $object) { $vcalendar = \Sabre\VObject\Reader::read($object['calendardata']); if (isset($vcalendar->VEVENT->RRULE)) { $vcalendar = $vcalendar->expand($start, $end); } foreach ($vcalendar->VEVENT as $vevent) { $title = (string) $vevent->SUMMARY; $dtstart = (string) $vevent->DTSTART; $dtend = (string) $vevent->DTEND; $description = (string) $vevent->DESCRIPTION; $location = (string) $vevent->LOCATION; $rw = cdav_perms($id[0], $calendars, true) ? true : false; $recurrent = isset($vevent->{'RECURRENCE-ID'}) ? true : false; $editable = $rw ? true : false; if ($recurrent) { $editable = false; } $allDay = false; // allDay event rules if (!strpos($dtstart, 'T') && !strpos($dtend, 'T')) { $allDay = true; } if (strpos($dtstart, 'T000000') && strpos($dtend, 'T000000')) { $allDay = true; } $events[] = ['calendar_id' => $id, 'uri' => $object['uri'], 'title' => $title, 'start' => $dtstart, 'end' => $dtend, 'description' => $description, 'location' => $location, 'allDay' => $allDay, 'editable' => $editable, 'recurrent' => $recurrent, 'rw' => $rw]; } } json_return_and_die($events); } else { killme(); } } //enable/disable calendars if (argc() == 5 && argv(1) === 'calendar' && argv(2) === 'switch' && intval(argv(3)) && (argv(4) == 1 || argv(4) == 0)) { $id = argv(3); if (!cdav_perms($id, $calendars)) { killme(); } set_pconfig(local_channel(), 'cdav_calendar', argv(3), argv(4)); killme(); } //drop calendar if (argc() == 5 && argv(1) === 'calendar' && argv(2) === 'drop' && intval(argv(3)) && intval(argv(4))) { $id = [argv(3), argv(4)]; if (!cdav_perms($id[0], $calendars)) { killme(); } $caldavBackend->deleteCalendar($id); killme(); } //drop sharee if (argc() == 6 && argv(1) === 'calendar' && argv(2) === 'dropsharee' && intval(argv(3)) && intval(argv(4))) { $id = [argv(3), argv(4)]; $hash = argv(5); if (!cdav_perms($id[0], $calendars)) { killme(); } $sharee_arr = channelx_by_hash($hash); $sharee = new \Sabre\DAV\Xml\Element\Sharee(); $sharee->href = 'mailto:' . $sharee_arr['channel_hash']; $sharee->principal = 'principals/' . $sharee_arr['channel_address']; $sharee->access = 4; $caldavBackend->updateInvites($id, [$sharee]); killme(); } if (argv(1) === 'addressbook') { $carddavBackend = new \Sabre\CardDAV\Backend\PDO($pdo); $addressbooks = $carddavBackend->getAddressBooksForUser($principalUri); } //Display Adressbook here if (argc() == 3 && argv(1) === 'addressbook' && intval(argv(2))) { $id = argv(2); $displayname = cdav_perms($id, $addressbooks); if (!$displayname) { return; } head_add_css('addon/cdav/view/css/cdav_addressbook.css'); $o = ''; $sabrecards = $carddavBackend->getCards($id); foreach ($sabrecards as $sabrecard) { $uris[] = $sabrecard['uri']; } if ($uris) { $objects = $carddavBackend->getMultipleCards($id, $uris); foreach ($objects as $object) { $vcard = \Sabre\VObject\Reader::read($object['carddata']); $photo = ''; if ($vcard->PHOTO) { $photo_value = strtolower($vcard->PHOTO->getValueType()); // binary or uri if ($photo_value === 'binary') { $photo_type = strtolower($vcard->PHOTO['TYPE']); // mime jpeg, png or gif $photo = 'data:image/' . $photo_type . ';base64,' . base64_encode((string) $vcard->PHOTO); } else { $url = parse_url((string) $vcard->PHOTO); $photo = 'data:' . $url['path']; } } $fn = ''; if ($vcard->FN) { $fn = (string) $vcard->FN; } $org = ''; if ($vcard->ORG) { $org = (string) $vcard->ORG; } $title = ''; if ($vcard->TITLE) { $title = (string) $vcard->TITLE; } $tels = []; if ($vcard->TEL) { foreach ($vcard->TEL as $tel) { $type = $tel['TYPE'] ? translate_type((string) $tel['TYPE']) : ''; $tels[] = ['type' => $type, 'nr' => (string) $tel]; } } $emails = []; if ($vcard->EMAIL) { foreach ($vcard->EMAIL as $email) { $type = $email['TYPE'] ? translate_type((string) $email['TYPE']) : ''; $emails[] = ['type' => $type, 'address' => (string) $email]; } } $impps = []; if ($vcard->IMPP) { foreach ($vcard->IMPP as $impp) { $type = $impp['TYPE'] ? translate_type((string) $impp['TYPE']) : ''; $impps[] = ['type' => $type, 'address' => (string) $impp]; } } $urls = []; if ($vcard->URL) { foreach ($vcard->URL as $url) { $type = $url['TYPE'] ? translate_type((string) $url['TYPE']) : ''; $urls[] = ['type' => $type, 'address' => (string) $url]; } } $adrs = []; if ($vcard->ADR) { foreach ($vcard->ADR as $adr) { $type = $adr['TYPE'] ? translate_type((string) $adr['TYPE']) : ''; $adrs[] = ['type' => $type, 'address' => $adr->getParts()]; } } $note = ''; if ($vcard->NOTE) { $note = (string) $vcard->NOTE; } $cards[] = ['id' => $object['id'], 'uri' => $object['uri'], 'photo' => $photo, 'fn' => $fn, 'org' => $org, 'title' => $title, 'tels' => $tels, 'emails' => $emails, 'impps' => $impps, 'urls' => $urls, 'adrs' => $adrs, 'note' => $note]; } usort($cards, function ($a, $b) { return strcasecmp($a['fn'], $b['fn']); }); } $o .= replace_macros(get_markup_template('cdav_addressbook.tpl', 'addon/cdav'), ['$id' => $id, '$cards' => $cards, '$displayname' => $displayname, '$name_label' => t('Name'), '$org_label' => t('Organisation'), '$title_label' => t('Title'), '$tel_label' => t('Phone'), '$email_label' => t('Email'), '$impp_label' => t('Instant messenger'), '$url_label' => t('Website'), '$adr_label' => t('Address'), '$note_label' => t('Note'), '$mobile' => t('Mobile'), '$home' => t('Home'), '$work' => t('Work'), '$other' => t('Other'), '$add_card' => t('Add Contact'), '$add_field' => t('Add Field'), '$create' => t('Create'), '$update' => t('Update'), '$delete' => t('Delete'), '$cancel' => t('Cancel'), '$po_box' => t('P.O. Box'), '$extra' => t('Additional'), '$street' => t('Street'), '$locality' => t('Locality'), '$region' => t('Region'), '$zip_code' => t('ZIP Code'), '$country' => t('Country')]); return $o; } //delete addressbook if (argc() > 3 && argv(1) === 'addressbook' && argv(2) === 'drop' && intval(argv(3))) { $id = argv(3); if (!cdav_perms($id, $addressbooks)) { return; } $carddavBackend->deleteAddressBook($id); killme(); } }
function diaspora_post_local(&$a, &$item) { /** * If all the conditions are met, generate an instance of the Diaspora Comment Virus * * Previously all comments from any Hubzilla source (including those who have not opted in to * Diaspora federation), were required to locally generate a Diaspora comment signature. * The only exception was wall-to-wall posts which have no local signing authority. * * Going forward, if we are asked to propagate the virus and it is not present (due to the post author * not opting in to Diaspora federation); we will generate a "wall-to-wall" comment and not require * a source signature. This allows hubs and communities to opt-out of Diaspora federation and not be * forced to generate the comment virus regardless. This is necessary because Diaspora now requires * the virus not just to provide a stored signature and Diaspora formatted text body, but must also * include all XML fields presented by the Diaspora protocol when transmitting the comment, while * maintaining their source order. This is fine for federated communities using UNO, but it makes * no sense to require this low-level baggage in channels and communities that have chosen not to use * the Diaspora protocol and services. * */ require_once 'include/bb2diaspora.php'; if ($item['mid'] === $item['parent_mid']) { return; } if ($item['created'] != $item['edited']) { return; } $meta = null; $author = channelx_by_hash($item['author_xchan']); if ($author) { // The author has a local channel, If they have this connector installed, // sign the comment and create a Diaspora Comment Virus. $dspr_allowed = get_pconfig($author['channel_id'], 'system', 'diaspora_allowed'); if (!$dspr_allowed) { return; } $handle = channel_reddress($author); if ($item['verb'] === ACTIVITY_LIKE) { if ($item['thr_parent'] == $item['parent_mid'] && $item['obj_type'] == ACTIVITY_OBJ_NOTE) { $meta = ['positive' => 'true', 'guid' => $item['mid'], 'target_type' => 'Post', 'parent_guid' => $item['parent_mid'], 'diaspora_handle' => $handle]; } } else { $body = bb2diaspora_itembody($item, true, true); $meta = ['guid' => $item['mid'], 'parent_guid' => $item['parent_mid'], 'text' => $body, 'diaspora_handle' => $handle]; } $meta['author_signature'] = diaspora_sign_fields($meta, $author['channel_prvkey']); if ($item['author_xchan'] === $item['owner_xchan']) { $meta['parent_author_signature'] = diaspora_sign_fields($meta, $author['channel_prvkey']); } } if (!$meta && $item['author_xchan'] !== $item['owner_xchan']) { // A local comment arrived but the commenter does not have a local channel // or the commenter doesn't have the Diaspora plugin enabled. // The owner *should* have a local channel // Find the owner and if the owner has this addon installed, turn the comment into // a 'wall-to-wall' message containing the author attribution, // with the comment signed by the owner. $owner = channelx_by_hash($item['owner_xchan']); if (!$owner) { return; } $dspr_allowed = get_pconfig($owner['channel_id'], 'system', 'diaspora_allowed'); if (!$dspr_allowed) { return; } $handle = channel_reddress($owner); if ($item['verb'] === ACTIVITY_LIKE) { if ($item['thr_parent'] == $item['parent_mid'] && $item['obj_type'] == ACTIVITY_OBJ_NOTE) { $meta = ['positive' => 'true', 'guid' => $item['mid'], 'target_type' => 'Post', 'parent_guid' => $item['parent_mid'], 'diaspora_handle' => $handle]; } } else { $body = bb2diaspora_itembody($item, true, false); $meta = ['guid' => $item['mid'], 'parent_guid' => $item['parent_mid'], 'text' => $body, 'diaspora_handle' => $handle]; } $meta['author_signature'] = diaspora_sign_fields($meta, $owner['channel_prvkey']); $meta['parent_author_signature'] = diaspora_sign_fields($meta, $owner['channel_prvkey']); } if ($meta) { set_iconfig($item, 'diaspora', 'fields', $meta, true); } // otherwise, neither the author or owner have this plugin installed. Do nothing. // logger('ditem: ' . print_r($item,true)); }
/** * API: map_getSharedData * Retrieve the available data * @param type $type * @param type $filter */ function map_getSharedData($type, $filter) { if (local_channel() || remote_channel()) { $channel = App::get_channel(); $sql_extra = item_permissions_sql($channel['channel_id'], get_observer_hash()); } else { $sql_extra = " AND item_private = 0 "; } switch ($filter) { case 'owner': $shares = q("SELECT owner_xchan,resource_id FROM item WHERE resource_type = '%s' AND owner_xchan != '%s' AND object LIKE '%s' {$sql_extra}", dbesc('locserv'), dbesc(App::get_channel()['channel_hash']), dbesc('%"locationDataType":"' . $type . '"%')); $channels = []; foreach ($shares as $share) { $channel = channelx_by_hash($share['owner_xchan']); $channels[] = array('name' => $channel['channel_name'], 'address' => $channel['xchan_addr'], 'photo_address' => $channel['xchan_photo_s']); } echo json_encode(array('sharedData' => $shares, 'channels' => $channels, 'status' => true)); die; case 'all': $shares = q("SELECT owner_xchan,resource_id FROM item WHERE resource_type = '%s' AND owner_xchan != '%s' AND object LIKE '%s' {$sql_extra}", dbesc('locserv'), dbesc(App::get_channel()['channel_hash']), dbesc('%"locationDataType":"' . $type . '"%')); $channels = []; $markers = []; foreach ($shares as $share) { $channel = channelx_by_hash($share['owner_xchan']); $channels[] = array('name' => $channel['channel_name'], 'address' => $channel['xchan_addr'], 'photo_address' => $channel['xchan_photo_s']); // FIXME: Not sure the permissions are checked appropriately here $marker = q("SELECT lat,lon,title,body,layer,created,resource_id FROM `locserv-static-markers` WHERE resource_id = '%s' limit 1", dbesc($share['resource_id'])); $markers[] = $marker[0]; } echo json_encode(array('sharedData' => $shares, 'channels' => $channels, 'markers' => $markers, 'status' => true)); die; default: echo json_encode(array('sharedData' => null, 'channels' => null, 'markers' => null, 'status' => false)); die; } }
function jappixmini_init(&$a) { require_once 'include/Contact.php'; // module page where other Friendica sites can submit Jabber addresses to and also // can query Jabber addresses of local users $address = base64url_decode($_REQUEST['address']); $requestor = $_REQUEST['requestor']; $requestee = $_REQUEST['requestee']; if (!$address || !$requestor || !$requestee) { killme(); } $channel = channelx_by_hash($requestee); if (!$channel) { killme(); } $r = q("select * from abook left join xchan on abook_xchan = xchan_hash where abook_channel = %d\n\t\tand not ( abook_flags & %d ) > 0 and xchan_hash = '%s' limit 1", intval($channel['channel_id']), intval(ABOOK_FLAG_SELF), dbesc($requestor)); if (!$r) { killme(); } $req = $r[0]; // save the Jabber address we received try { $trusted_address = ""; openssl_public_decrypt($address, $trusted_address, $req['xchan_pubkey']); $now = intval(time()); set_pconfig($channel['channel_id'], "jappixmini", "id:{$requestor}", "{$now}:{$trusted_address}"); } catch (Exception $e) { } // do not return an address if user deactivated plugin $activated = get_pconfig($channel['channel_id'], 'jappixmini', 'activate'); if (!$activated) { killme(); } if (!perm_is_allowed($channel['channel_id'], $req['xchan_hash'], 'chat')) { killme(); } // return the requested Jabber address try { $username = get_pconfig($channel['channel_id'], 'jappixmini', 'username'); $server = get_pconfig($channel['channel_id'], 'jappixmini', 'server'); $address = "{$username}@{$server}"; $encrypted_address = ""; openssl_private_encrypt($address, $encrypted_address, $channel['channel_prvkey']); $encoded = base64url_encode($encrypted_address); $answer = array("status" => "ok", "address" => $encoded); $answer_json = json_encode($answer); echo $answer_json; killme(); } catch (Exception $e) { killme(); } }
function ratenotif_run($argv, $argc) { cli_startup(); $a = get_app(); require_once "session.php"; require_once "datetime.php"; require_once 'include/items.php'; require_once 'include/Contact.php'; if ($argc < 3) { return; } logger('ratenotif: invoked: ' . print_r($argv, true), LOGGER_DEBUG); $cmd = $argv[1]; $item_id = $argv[2]; if ($cmd === 'rating') { $r = q("select * from xlink where xlink_id = %d and xlink_static = 1 limit 1", intval($item_id)); if (!$r) { logger('rating not found'); return; } $encoded_item = array('type' => 'rating', 'encoding' => 'zot', 'target' => $r[0]['xlink_link'], 'rating' => intval($r[0]['xlink_rating']), 'rating_text' => $r[0]['xlink_rating_text'], 'signature' => $r[0]['xlink_sig'], 'edited' => $r[0]['xlink_updated']); } $channel = channelx_by_hash($r[0]['xlink_xchan']); if (!$channel) { logger('no channel'); return; } $primary = get_directory_primary(); if (!$primary) { return; } $interval = get_config('system', 'delivery_interval') !== false ? intval(get_config('system', 'delivery_interval')) : 2; $deliveries_per_process = intval(get_config('system', 'delivery_batch_count')); if ($deliveries_per_process <= 0) { $deliveries_per_process = 1; } $deliver = array(); $x = z_fetch_url($primary . '/regdir'); if ($x['success']) { $j = json_decode($x['body'], true); if ($j && $j['success'] && is_array($j['directories'])) { foreach ($j['directories'] as $h) { if ($h == z_root()) { continue; } $hash = random_string(); $n = zot_build_packet($channel, 'notify', null, null, $hash); q("insert into outq ( outq_hash, outq_account, outq_channel, outq_driver, outq_posturl, outq_async, outq_created, outq_updated, outq_notify, outq_msg ) values ( '%s', %d, %d, '%s', '%s', %d, '%s', '%s', '%s', '%s' )", dbesc($hash), intval($channel['channel_account_id']), intval($channel['channel_id']), dbesc('zot'), dbesc($h . '/post'), intval(1), dbesc(datetime_convert()), dbesc(datetime_convert()), dbesc($n), dbesc(json_encode($encoded_item))); $deliver[] = $hash; if (count($deliver) >= $deliveries_per_process) { proc_run('php', 'include/deliver.php', $deliver); $deliver = array(); if ($interval) { @time_sleep_until(microtime(true) + (double) $interval); } } } // catch any stragglers if (count($deliver)) { proc_run('php', 'include/deliver.php', $deliver); } } } logger('ratenotif: complete.'); return; }
function widget_cdav() { if (!local_channel() || get_pconfig(local_channel(), 'cdav', 'enabled') != 1) { return; } $channel = \App::get_channel(); $principalUri = 'principals/' . $channel['channel_address']; if (!cdav_principal($principalUri)) { return; } if (\DBA::$dba && \DBA::$dba->connected) { $pdovars = \DBA::$dba->pdo_get(); } else { killme(); } $pdo = new \PDO($pdovars[0], $pdovars[1], $pdovars[2]); $pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION); require_once 'vendor/autoload.php'; $o = ''; if (argc() == 2 && argv(1) === 'calendar') { $caldavBackend = new \Sabre\CalDAV\Backend\PDO($pdo); $sabrecals = $caldavBackend->getCalendarsForUser($principalUri); //TODO: we should probably also check for permission to send stream here $local_channels = q("SELECT * FROM channel LEFT JOIN abook ON abook_xchan = channel_hash WHERE channel_system = 0 AND channel_removed = 0 AND channel_hash != '%s' AND abook_channel = %d", dbesc($channel['channel_hash']), intval($channel['channel_id'])); $sharee_options .= '<option value="">' . t('Select Channel') . '</option>' . "\r\n"; foreach ($local_channels as $local_channel) { $sharee_options .= '<option value="' . $local_channel['channel_hash'] . '">' . $local_channel['channel_name'] . '</option>' . "\r\n"; } $access_options = '<option value="3">' . t('Read-write') . '</option>' . "\r\n"; $access_options .= '<option value="2">' . t('Read-only') . '</option>' . "\r\n"; //list calendars foreach ($sabrecals as $sabrecal) { if ($sabrecal['share-access'] == 1) { $access = ''; } if ($sabrecal['share-access'] == 2) { $access = 'read'; } if ($sabrecal['share-access'] == 3) { $access = 'read-write'; } $invites = $caldavBackend->getInvites($sabrecal['id']); $json_source = '/cdav/calendar/json/' . $sabrecal['id'][0] . '/' . $sabrecal['id'][1]; $switch = get_pconfig(local_channel(), 'cdav_calendar', $sabrecal['id'][0]); $color = $sabrecal['{http://apple.com/ns/ical/}calendar-color'] ? $sabrecal['{http://apple.com/ns/ical/}calendar-color'] : '#3a87ad'; $editable = $sabrecal['share-access'] == 2 ? 'false' : 'true'; // false/true must be string since we're passing it to javascript $sharees = []; $share_displayname = []; foreach ($invites as $invite) { if (strpos($invite->href, 'mailto:') !== false) { $sharee = channelx_by_hash(substr($invite->href, 7)); $sharees[] = ['name' => $sharee['channel_name'], 'access' => $invite->access == 3 ? ' (RW)' : ' (R)', 'hash' => $sharee['channel_hash']]; } } if (!$access) { $my_calendars[] = ['ownernick' => $channel['channel_address'], 'uri' => $sabrecal['uri'], 'displayname' => $sabrecal['{DAV:}displayname'], 'calendarid' => $sabrecal['id'][0], 'instanceid' => $sabrecal['id'][1], 'json_source' => $json_source, 'color' => $color, 'editable' => $editable, 'switch' => $switch, 'sharees' => $sharees]; } else { $shared_calendars[] = ['ownernick' => $channel['channel_address'], 'uri' => $sabrecal['uri'], 'displayname' => $sabrecal['{DAV:}displayname'], 'calendarid' => $sabrecal['id'][0], 'instanceid' => $sabrecal['id'][1], 'json_source' => $json_source, 'color' => $color, 'editable' => $editable, 'switch' => $switch, 'sharer' => $sabrecal['{urn:ietf:params:xml:ns:caldav}calendar-description'], 'access' => $access]; } if (!$access || $access === 'read-write') { $writable_calendars[] = ['displayname' => !$access ? $sabrecal['{DAV:}displayname'] : $share_displayname[0], 'id' => $sabrecal['id']]; } } $o .= replace_macros(get_markup_template('cdav_widget_calendar.tpl', 'addon/cdav'), ['$my_calendars_label' => t('My Calendars'), '$my_calendars' => $my_calendars, '$shared_calendars_label' => t('Shared Calendars'), '$shared_calendars' => $shared_calendars, '$sharee_options' => $sharee_options, '$access_options' => $access_options, '$share_label' => t('Share this calendar'), '$share' => t('Share'), '$edit_label' => t('Calendar name and color'), '$edit' => t('Edit'), '$create_label' => t('Create new calendar'), '$create' => t('Create'), '$create_placeholder' => t('Calendar Name'), '$tools_label' => t('Calendar Tools'), '$import_label' => t('Import calendar'), '$import_placeholder' => t('Select a calendar to import to'), '$upload' => t('Upload'), '$writable_calendars' => $writable_calendars]); return $o; } if (argc() >= 2 && argv(1) === 'addressbook') { $carddavBackend = new \Sabre\CardDAV\Backend\PDO($pdo); $sabreabooks = $carddavBackend->getAddressBooksForUser($principalUri); //list addressbooks foreach ($sabreabooks as $sabreabook) { $addressbooks[] = ['ownernick' => $channel['channel_address'], 'uri' => $sabreabook['uri'], 'displayname' => $sabreabook['{DAV:}displayname'], 'id' => $sabreabook['id']]; } $o .= replace_macros(get_markup_template('cdav_widget_addressbook.tpl', 'addon/cdav'), ['$addressbooks_label' => t('Addressbooks'), '$addressbooks' => $addressbooks, '$edit_label' => t('Addressbook name'), '$edit' => t('Edit'), '$create_label' => t('Create new addressbook'), '$create_placeholder' => t('Addressbook Name'), '$create' => t('Create'), '$tools_label' => t('Addressbook Tools'), '$import_label' => t('Import addressbook'), '$import_placeholder' => t('Select an addressbook to import to'), '$upload' => t('Upload')]); return $o; } }
public static function run($argc, $argv) { require_once "datetime.php"; require_once 'include/items.php'; if ($argc < 3) { return; } logger('ratenotif: invoked: ' . print_r($argv, true), LOGGER_DEBUG); $cmd = $argv[1]; $item_id = $argv[2]; if ($cmd === 'rating') { $r = q("select * from xlink where xlink_id = %d and xlink_static = 1 limit 1", intval($item_id)); if (!$r) { logger('rating not found'); return; } $encoded_item = array('type' => 'rating', 'encoding' => 'zot', 'target' => $r[0]['xlink_link'], 'rating' => intval($r[0]['xlink_rating']), 'rating_text' => $r[0]['xlink_rating_text'], 'signature' => $r[0]['xlink_sig'], 'edited' => $r[0]['xlink_updated']); } $channel = channelx_by_hash($r[0]['xlink_xchan']); if (!$channel) { logger('no channel'); return; } $primary = get_directory_primary(); if (!$primary) { return; } $interval = get_config('system', 'delivery_interval') !== false ? intval(get_config('system', 'delivery_interval')) : 2; $deliveries_per_process = intval(get_config('system', 'delivery_batch_count')); if ($deliveries_per_process <= 0) { $deliveries_per_process = 1; } $deliver = array(); $x = z_fetch_url($primary . '/regdir'); if ($x['success']) { $j = json_decode($x['body'], true); if ($j && $j['success'] && is_array($j['directories'])) { foreach ($j['directories'] as $h) { if ($h == z_root()) { continue; } $hash = random_string(); $n = zot_build_packet($channel, 'notify', null, null, $hash); queue_insert(array('hash' => $hash, 'account_id' => $channel['channel_account_id'], 'channel_id' => $channel['channel_id'], 'posturl' => $h . '/post', 'notify' => $n, 'msg' => json_encode($encoded_item))); $deliver[] = $hash; if (count($deliver) >= $deliveries_per_process) { Master::Summon(array('Deliver', $deliver)); $deliver = array(); if ($interval) { @time_sleep_until(microtime(true) + (double) $interval); } } } // catch any stragglers if (count($deliver)) { Master::Summon(array('Deliver', $deliver)); } } } logger('ratenotif: complete.'); return; }