function zfinger_init(&$a) { require_once 'include/zot.php'; require_once 'include/crypto.php'; $x = zotinfo($_REQUEST); json_return_and_die($x); }
/** @file */ function notes_init(&$a) { if (!local_channel()) { return; } $ret = array('success' => true); if (array_key_exists('note_text', $_REQUEST)) { $body = escape_tags($_REQUEST['note_text']); // I've had my notes vanish into thin air twice in four years. // Provide a backup copy if there were contents previously // and there are none being saved now. if (!$body) { $old_text = get_pconfig(local_channel(), 'notes', 'text'); if ($old_text) { set_pconfig(local_channel(), 'notes', 'text.bak', $old_text); } } set_pconfig(local_channel(), 'notes', 'text', $body); } // push updates to channel clones if (argc() > 1 && argv(1) === 'sync') { require_once 'include/zot.php'; build_sync_packet(); } logger('notes saved.', LOGGER_DEBUG); json_return_and_die($ret); }
function export_identity(&$a, $channel_hash) { if ($channel_hash == '') { json_error_die(422, 'Unprocessable Entity', 'Must supply channel_hash parameter.'); } json_return_and_die(identity_basic_export(get_channel_id($channel_hash), $_REQUEST['posts'] ? intval($_REQUEST['posts']) : 0)); }
function init() { $result = null; $cmd = argc() > 1 ? argv(1) : ''; // Provide a stored request for somebody desiring a connection // when they first need to register someplace. Once they've // created a channel, we'll try to revive the connection request // and process it. if ($_REQUEST['connect']) { $_SESSION['connect'] = $_REQUEST['connect']; } switch ($cmd) { case 'invite_check.json': $result = check_account_invite($_REQUEST['invite_code']); break; case 'email_check.json': $result = check_account_email($_REQUEST['email']); break; case 'password_check.json': $result = check_account_password($_REQUEST['password']); break; default: break; } if ($result) { json_return_and_die($result); } }
function init() { if (argv(1) === 'json') { $data = get_site_info(); json_return_and_die($data); } }
function dirstats_content(&$a) { $hubcount = get_config('dirstats', 'hubcount'); $zotcount = get_config('dirstats', 'zotcount'); $friendicacount = get_config('dirstats', 'friendicacount'); $diasporacount = get_config('dirstats', 'diasporacount'); $channelcount = get_config('dirstats', 'channelcount'); $friendicachannelcount = get_config('dirstats', 'friendicachannelcount'); $diasporachannelcount = get_config('dirstats', 'diasporachannelcount'); $over35s = get_config('dirstats', 'over35s'); $under35s = get_config('dirstats', 'under35s'); $average = get_config('dirstats', 'averageage'); $chatrooms = get_config('dirstats', 'chatrooms'); $tags = get_config('dirstats', 'tags'); $ob = $a->get_observer(); $observer = $ob['xchan_hash']; // Requested by Martin $fountainofyouth = get_xconfig($observer, 'dirstats', 'averageage'); if (intval($fountainofyouth)) { $average = $fountainofyouth; } if (argv(1) == 'json') { $dirstats = array('hubcount' => $hubcount, 'zotcount' => $zotcount, 'friendicacount' => $friendicacount, 'diasporacount' => $diasporacount, 'channelcount' => $channelcount, 'friendicachannelcount' => $friendicachannelcount, 'diasporachannelcount' => $diasporachannelcount, 'over35s' => $over35s, 'under35s' => $under35s, 'average' => $average, 'chatrooms' => $chatrooms, 'tags' => $tags); echo json_return_and_die($dirstats); } elseif (argv(1) == 'genpost' && get_config('dirstats', 'allowfiledump')) { $result = '[b]Hub count[/b] : ' . $hubcount . "\n" . '[b]Hubzilla Hubs[/b] : ' . $zotcount . "\n" . '[b]Friendica Hubs[/b] : ' . $friendicacount . "\n" . '[b]Diaspora Pods[/b] : ' . $diasporacount . "\n" . '[b]Hubzilla Channels[/b] : ' . $channelcount . "\n" . '[b]Friendica Profiles[/b] : ' . $friendicachannelcount . "\n" . '[b]Diaspora Profiles[/b] : ' . $diasporachannelcount . "\n" . '[b]People aged 35 and above[/b] : ' . $over35s . "\n" . '[b]People aged 34 and below[/b] : ' . $under35s . "\n" . '[b]Average Age[/b] : ' . $average . "\n" . '[b]Known Chatrooms[/b] : ' . $chatrooms . "\n" . '[b]Unique Profile Tags[/b] : ' . $tags . "\n"; file_put_contents('genpost', $result); } else { $tpl = get_markup_template("dirstats.tpl", "addon/dirstats/"); return replace_macros($tpl, array('$title' => t('Hubzilla Directory Stats'), '$hubtitle' => t('Total Hubs'), '$hubcount' => $hubcount, '$zotlabel' => t('Hubzilla Hubs'), '$zotcount' => $zotcount, '$friendicalabel' => t('Friendica Hubs'), '$friendicacount' => $friendicacount, '$diasporalabel' => t('Diaspora Pods'), '$diasporacount' => $diasporacount, '$zotchanlabel' => t('Hubzilla Channels'), '$channelcount' => $channelcount, '$friendicachanlabel' => t('Friendica Channels'), '$friendicachannelcount' => $friendicachannelcount, '$diasporachanlabel' => t('Diaspora Channels'), '$diasporachannelcount' => $diasporachannelcount, '$over35label' => t('Aged 35 and above'), '$over35s' => $over35s, '$under35label' => t('Aged 34 and under'), '$under35s' => $under35s, '$averageagelabel' => t('Average Age'), '$average' => $average, '$chatlabel' => t('Known Chatrooms'), '$chatrooms' => $chatrooms, '$tagslabel' => t('Known Tags'), '$tags' => $tags, '$disclaimer' => t('Please note Diaspora and Friendica statistics are merely those **this directory** is aware of, and not all those known in the network. This also applies to chatrooms,'))); } }
function zotfeed_init(&$a) { $result = array('success' => false); $mindate = $_REQUEST['mindate'] ? datetime_convert('UTC', 'UTC', $_REQUEST['mindate']) : ''; if (!$mindate) { $mindate = datetime_convert('UTC', 'UTC', 'now - 1 month'); } if (get_config('system', 'block_public') && !get_account_id() && !remote_user()) { $result['message'] = 'Public access denied'; json_return_and_die($result); } $observer = $a->get_observer(); $channel_address = argc() > 1 ? argv(1) : ''; if ($channel_address) { $r = q("select channel_id, channel_name from channel where channel_address = '%s' and not (channel_pageflags & %d) limit 1", dbesc(argv(1)), intval(PAGE_REMOVED)); } else { $x = get_sys_channel(); if ($x) { $r = array($x); } } if (!$r) { $result['message'] = 'Channel not found.'; json_return_and_die($result); } logger('zotfeed request: ' . $r[0]['channel_name'], LOGGER_DEBUG); $result['messages'] = zot_feed($r[0]['channel_id'], $observer['xchan_hash'], $mindate); $result['success'] = true; json_return_and_die($result); }
function init() { $result = array('success' => false); $mindate = $_REQUEST['mindate'] ? datetime_convert('UTC', 'UTC', $_REQUEST['mindate']) : ''; if (!$mindate) { $mindate = datetime_convert('UTC', 'UTC', 'now - 14 days'); } if (observer_prohibited()) { $result['message'] = 'Public access denied'; json_return_and_die($result); } $observer = \App::get_observer(); $channel_address = argc() > 1 ? argv(1) : ''; if ($channel_address) { $r = q("select channel_id, channel_name from channel where channel_address = '%s' and channel_removed = 0 limit 1", dbesc(argv(1))); } else { $x = get_sys_channel(); if ($x) { $r = array($x); } $mindate = datetime_convert('UTC', 'UTC', 'now - 14 days'); } if (!$r) { $result['message'] = 'Channel not found.'; json_return_and_die($result); } logger('zotfeed request: ' . $r[0]['channel_name'], LOGGER_DEBUG); $result['messages'] = zot_feed($r[0]['channel_id'], $observer['xchan_hash'], array('mindate' => $mindate)); $result['success'] = true; json_return_and_die($result); }
function migrator_init(&$a) { $x = argc(); if ($x > 1) { api_login($a); switch (argv(1)) { case "version": json_return_and_die(array("status" => "OK", 'platform' => PLATFORM_NAME, 'platform_version' => RED_VERSION, 'zot_version' => ZOT_REVISION, 'db_version' => DB_UPDATE_VERSION, 'migrator_version' => MIGRATOR_VERSION)); break; case "import": if (PLATFORM_NAME == "redmatrix") { json_error_die(400, 'Bad Request', 'Cannot import to Redmatrix, only to Hubzilla.'); } switch (argv(2)) { case 'account': migrator_import_account($a); break; case 'identity': migrator_import_identity($a, argv(3)); break; case 'items': migrator_import_items($a, argv(3)); break; case 'directory': migrator_update_directory($a, argv(3)); break; default: json_error_die(404, 'Not Found', 'No such endpoint'); break; } case "export": switch (argv(2)) { case "users": export_users($a); break; case "channel_hashes": export_channel_hashes($a, argv(3)); break; case "identity": export_identity($a, argv(3)); break; case "first_post": first_post($a, argv(3)); break; case "items": export_items($a, argv(3), argv(4), argv(5)); break; default: json_error_die(404, 'Not Found', 'No such endpoint'); break; } break; default: json_error_die(404, 'Not Found', 'No such endpoint'); break; } } }
function init() { $ret = array('result' => false); if (argc() != 2) { json_return_and_die($ret); } $ret = get_online_status(argv(1)); json_return_and_die($ret); }
function tasks_post(&$a) { // logger('post: ' . print_r($_POST,true)); if (!local_channel()) { return; } $channel = App::get_channel(); if (argc() > 2 && argv(1) === 'complete' && intval(argv(2))) { $ret = array('success' => false); $r = q("select * from event where `type` = 'task' and uid = %d and id = %d limit 1", intval(local_channel()), intval(argv(2))); if ($r) { $event = $r[0]; if ($event['event_status'] === 'COMPLETED') { $event['event_status'] = 'IN-PROCESS'; $event['event_status_date'] = NULL_DATE; $event['event_percent'] = 0; $event['event_sequence'] = $event['event_sequence'] + 1; $event['edited'] = datetime_convert(); } else { $event['event_status'] = 'COMPLETED'; $event['event_status_date'] = datetime_convert(); $event['event_percent'] = 100; $event['event_sequence'] = $event['event_sequence'] + 1; $event['edited'] = datetime_convert(); } $x = event_store_event($event); if ($x) { $ret['success'] = true; } } json_return_and_die($ret); } if (argc() == 2 && argv(1) === 'new') { $text = escape_tags(trim($_REQUEST['summary'])); if (!$text) { return array('success' => false); } $event = array(); $event['account'] = $channel['channel_account_id']; $event['uid'] = $channel['channel_id']; $event['event_xchan'] = $channel['channel_hash']; $event['type'] = 'task'; $event['nofinish'] = true; $event['created'] = $event['edited'] = $event['start'] = datetime_convert(); $event['adjust'] = 1; $event['allow_cid'] = '<' . $channel['channel_hash'] . '>'; $event['summary'] = escape_tags($_REQUEST['summary']); $x = event_store_event($event); if ($x) { $x['success'] = true; } else { $x = array('success' => false); } json_return_and_die($x); } }
function migrator_update_directory(&$a, $channel_hash) { $channel_id = get_channel_id($channel_hash); if (!$channel_id) { json_error_die(404, 'Not Found', 'No such channel ' . $channel_hash); } proc_run('php', 'include/notifier.php', 'location', $channel_id); proc_run('php', 'include/directory.php', $channel_id); json_return_and_die(array("status" => 'OK', 'channel_hash' => $channel_hash, 'channel_id' => $channel_id)); }
function get() { if (\App::$argv[1] === "json") { $tmp = list_smilies(); $results = array(); for ($i = 0; $i < count($tmp['texts']); $i++) { $results[] = array('text' => $tmp['texts'][$i], 'icon' => $tmp['icons'][$i]); } json_return_and_die($results); } else { return smilies('', true); } }
function chatsvc_content(&$a) { $status = strip_tags($_REQUEST['status']); $room_id = intval($a->data['chat']['room_id']); $stopped = x($_REQUEST, 'stopped') && intval($_REQUEST['stopped']) ? true : false; if ($status && $room_id) { $x = q("select channel_address from channel where channel_id = %d limit 1", intval($a->data['chat']['uid'])); $r = q("update chatpresence set cp_status = '%s', cp_last = '%s' where cp_room = %d and cp_xchan = '%s' and cp_client = '%s' limit 1", dbesc($status), dbesc(datetime_convert()), intval($room_id), dbesc(get_observer_hash()), dbesc($_SERVER['REMOTE_ADDR'])); goaway(z_root() . '/chat/' . $x[0]['channel_address'] . '/' . $room_id); } if (!$stopped) { $lastseen = intval($_REQUEST['last']); $ret = array('success' => false); $sql_extra = permissions_sql($a->data['chat']['uid']); $r = q("select * from chatroom where cr_uid = %d and cr_id = %d {$sql_extra}", intval($a->data['chat']['uid']), intval($a->data['chat']['room_id'])); if (!$r) { json_return_and_die($ret); } $inroom = array(); $r = q("select * from chatpresence left join xchan on xchan_hash = cp_xchan where cp_room = %d order by xchan_name", intval($a->data['chat']['room_id'])); if ($r) { foreach ($r as $rr) { switch ($rr['cp_status']) { case 'away': $status = t('Away'); break; case 'online': default: $status = t('Online'); break; } $inroom[] = array('img' => zid($rr['xchan_photo_m']), 'img_type' => $rr['xchan_photo_mimetype'], 'name' => $rr['xchan_name'], status => $status); } } $chats = array(); $r = q("select * from chat left join xchan on chat_xchan = xchan_hash where chat_room = %d and chat_id > %d order by created", intval($a->data['chat']['room_id']), intval($lastseen)); if ($r) { foreach ($r as $rr) { $chats[] = array('id' => $rr['chat_id'], 'img' => zid($rr['xchan_photo_m']), 'img_type' => $rr['xchan_photo_mimetype'], 'name' => $rr['xchan_name'], 'isotime' => datetime_convert('UTC', date_default_timezone_get(), $rr['created'], 'c'), 'localtime' => datetime_convert('UTC', date_default_timezone_get(), $rr['created'], 'r'), 'text' => smilies(bbcode($rr['chat_text']))); } } } $r = q("update chatpresence set cp_last = '%s' where cp_room = %d and cp_xchan = '%s' and cp_client = '%s' limit 1", dbesc(datetime_convert()), intval($a->data['chat']['room_id']), dbesc(get_observer_hash()), dbesc($_SERVER['REMOTE_ADDR'])); $ret['success'] = true; if (!$stopped) { $ret['inroom'] = $inroom; $ret['chats'] = $chats; } json_return_and_die($ret); }
function ratingsearch_init(&$a) { $ret = array('success' => false); $dirmode = intval(get_config('system', 'directory_mode')); if ($dirmode == DIRECTORY_MODE_NORMAL) { $ret['message'] = 'This site is not a directory server.'; json_return_and_die($ret); } if (argc() > 1) { $hash = argv(1); } if (!$hash) { $ret['message'] = 'No channel identifier'; json_return_and_die($ret); } if (strpos($hash, '@')) { $r = q("select * from hubloc where hubloc_addr = '%s' limit 1", dbesc($hash)); if ($r) { $hash = $r[0]['hubloc_hash']; } } $p = q("select * from xchan where xchan_hash like '%s'", dbesc($hash . '%')); if ($p) { $target = $p[0]['xchan_hash']; } else { $p = q("select * from site where site_url like '%s' and site_type = %d ", dbesc('%' . $hash), intval(SITE_TYPE_ZOT)); if ($p) { $target = strtolower($hash); } else { $ret['message'] = 'Rating target not found'; json_return_and_die($ret); } } if ($p) { $ret['target'] = $p[0]; } $ret['success'] = true; $r = q("select * from xlink left join xchan on xlink_xchan = xchan_hash \n\t\twhere xlink_link = '%s' and xlink_rating != 0 and xlink_static = 1 order by xchan_name asc", dbesc($target)); if ($r) { $ret['ratings'] = $r; } else { $ret['ratings'] = array(); } json_return_and_die($ret); }
/** @file */ function notes_init(&$a) { if (!local_user()) { return; } $ret = array('success' => true); if ($_REQUEST['note_text'] || $_REQUEST['note_text'] == '') { $body = escape_tags($_REQUEST['note_text']); set_pconfig(local_user(), 'notes', 'text', $body); } // push updates to channel clones if (argc() > 1 && argv(1) === 'sync') { require_once 'include/zot.php'; build_sync_packet(); } logger('notes saved.', LOGGER_DEBUG); json_return_and_die($ret); }
function oexchange_content(&$a) { if (!local_channel()) { if (remote_channel()) { $observer = $a->get_observer(); if ($observer && $observer['xchan_url']) { $parsed = @parse_url($observer['xchan_url']); if (!$parsed) { notice(t('Unable to find your hub.') . EOL); return; } $url = $parsed['scheme'] . '://' . $parsed['host'] . ($parsed['port'] ? ':' . $parsed['port'] : ''); $url .= '/oexchange'; $result = z_post_url($url, $_REQUEST); json_return_and_die($result); } } return login(false); } if (argc() > 1 && argv(1) === 'done') { info(t('Post successful.') . EOL); return; } $url = x($_REQUEST, 'url') && strlen($_REQUEST['url']) ? urlencode(notags(trim($_REQUEST['url']))) : ''; $title = x($_REQUEST, 'title') && strlen($_REQUEST['title']) ? '&title=' . urlencode(notags(trim($_REQUEST['title']))) : ''; $description = x($_REQUEST, 'description') && strlen($_REQUEST['description']) ? '&description=' . urlencode(notags(trim($_REQUEST['description']))) : ''; $tags = x($_REQUEST, 'tags') && strlen($_REQUEST['tags']) ? '&tags=' . urlencode(notags(trim($_REQUEST['tags']))) : ''; $ret = z_fetch_url($a->get_baseurl() . '/urlinfo?f=&url=' . $url . $title . $description . $tags); if ($ret['success']) { $s = $ret['body']; } if (!strlen($s)) { return; } $post = array(); $post['profile_uid'] = local_channel(); $post['return'] = '/oexchange/done'; $post['body'] = $s; $post['type'] = 'wall'; $_REQUEST = $post; require_once 'mod/item.php'; item_post($a); }
function new_channel_init(&$a) { $cmd = argc() > 1 ? argv(1) : ''; if ($cmd === 'autofill.json') { require_once 'library/urlify/URLify.php'; $result = array('error' => false, 'message' => ''); $n = trim($_REQUEST['name']); $x = strtolower(URLify::transliterate($n)); $test = array(); // first name if (strpos($x, ' ')) { $test[] = legal_webbie(substr($x, 0, strpos($x, ' '))); } if ($test[0]) { // first name plus first initial of last $test[] = strpos($x, ' ') ? $test[0] . legal_webbie(trim(substr($x, strpos($x, ' '), 2))) : ''; // first name plus random number $test[] = $test[0] . mt_rand(1000, 9999); } // fullname $test[] = legal_webbie($x); // fullname plus random number $test[] = legal_webbie($x) . mt_rand(1000, 9999); json_return_and_die(check_webbie($test)); } if ($cmd === 'checkaddr.json') { require_once 'library/urlify/URLify.php'; $result = array('error' => false, 'message' => ''); $n = trim($_REQUEST['nick']); $x = strtolower(URLify::transliterate($n)); $test = array(); $n = legal_webbie($x); if (strlen($n)) { $test[] = $n; $test[] = $n . mt_rand(1000, 9999); } for ($y = 0; $y < 100; $y++) { $test[] = 'id' . mt_rand(1000, 9999); } json_return_and_die(check_webbie($test)); } }
function post() { if (argc() > 1 && argv(1) === 'album') { // API: /embedphotos/album $name = x($_POST, 'name') ? $_POST['name'] : null; if (!$name) { json_return_and_die(array('errormsg' => 'Error retrieving album', 'status' => false)); } $album = $this->embedphotos_widget_album(array('channel' => \App::get_channel(), 'album' => $name)); json_return_and_die(array('status' => true, 'content' => $album)); } if (argc() > 1 && argv(1) === 'albumlist') { // API: /embedphotos/albumlist $album_list = $this->embedphotos_album_list($a); json_return_and_die(array('status' => true, 'albumlist' => $album_list)); } if (argc() > 1 && argv(1) === 'photolink') { // API: /embedphotos/photolink $href = x($_POST, 'href') ? $_POST['href'] : null; if (!$href) { json_return_and_die(array('errormsg' => 'Error retrieving link ' . $href, 'status' => false)); } $resource_id = array_pop(explode("/", $href)); $r = q("SELECT obj,body from item where resource_type = 'photo' and resource_id = '%s' limit 1", dbesc($resource_id)); if (!$r) { json_return_and_die(array('errormsg' => 'Error retrieving resource ' . $resource_id, 'status' => false)); } $obj = json_decode($r[0]['obj'], true); if (x($obj, 'body')) { $photolink = $obj['body']; } elseif (x($obj, 'bbcode')) { $photolink = $obj['bbcode']; } elseif ($r[0]['body'] !== '') { $photolink = $r[0]['body']; } else { json_return_and_die(array('errormsg' => 'Error retrieving resource ' . $resource_id, 'status' => false)); } json_return_and_die(array('status' => true, 'photolink' => $photolink)); } }
function prate_post(&$a) { if (!local_channel()) { return; } $channel = App::get_channel(); $target = trim($_REQUEST['target']); if (!$target) { return; } if ($target === $channel['channel_hash']) { return; } $rating = intval($_POST['rating']); if ($rating < -10) { $rating = -10; } if ($rating > 10) { $rating = 10; } $rating_text = trim(escape_tags($_REQUEST['rating_text'])); $signed = $target . '.' . $rating . '.' . $rating_text; $sig = base64url_encode(rsa_sign($signed, $channel['channel_prvkey'])); $z = q("select * from xlink where xlink_xchan = '%s' and xlink_link = '%s' and xlink_static = 1 limit 1", dbesc($channel['channel_hash']), dbesc($target)); if ($z) { $record = $z[0]['xlink_id']; $w = q("update xlink set xlink_rating = '%d', xlink_rating_text = '%s', xlink_sig = '%s', xlink_updated = '%s'\n\t\t\twhere xlink_id = %d", intval($rating), dbesc($rating_text), dbesc($sig), dbesc(datetime_convert()), intval($record)); } else { $w = q("insert into xlink ( xlink_xchan, xlink_link, xlink_rating, xlink_rating_text, xlink_sig, xlink_updated, xlink_static ) values ( '%s', '%s', %d, '%s', '%s', '%s', 1 ) ", dbesc($channel['channel_hash']), dbesc($target), intval($rating), dbesc($rating_text), dbesc($sig), dbesc(datetime_convert())); $z = q("select * from xlink where xlink_xchan = '%s' and xlink_link = '%s' and xlink_static = 1 limit 1", dbesc($channel['channel_hash']), dbesc($orig_record[0]['abook_xchan'])); if ($z) { $record = $z[0]['xlink_id']; } } if ($record) { proc_run('php', 'include/ratenotif.php', 'rating', $record); } json_return_and_die(array('result' => true)); }
function get() { $theme = argv(1); if (!$theme) { killme(); } $schemalist = array(); $theme_config = ""; if (($themeconfigfile = $this->get_theme_config_file($theme)) != null) { require_once $themeconfigfile; if (class_exists('\\Zotlabs\\Theme\\' . ucfirst($theme) . 'Config')) { $clsname = '\\Zotlabs\\Theme\\' . ucfirst($theme) . 'Config'; $th_config = new $clsname(); $schemas = $th_config->get_schemas(); if ($schemas) { foreach ($schemas as $k => $v) { $schemalist[] = ['key' => $k, 'val' => $v]; } } $theme_config = $th_config->get(); } } $info = get_theme_info($theme); if ($info) { // unfortunately there will be no translation for this string $desc = $info['description']; $version = $info['version']; $credits = $info['credits']; } else { $desc = ''; $version = ''; $credits = ''; } $ret = ['theme' => $theme, 'img' => get_theme_screenshot($theme), 'desc' => $desc, 'version' => $version, 'credits' => $credits, 'schemas' => $schemalist, 'config' => $theme_config]; json_return_and_die($ret); }
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 admin_page_plugins_post($action) { switch ($action) { case 'updaterepo': if (array_key_exists('repoName', $_REQUEST)) { $repoName = $_REQUEST['repoName']; } else { json_return_and_die(array('message' => 'No repo name provided.', 'success' => false)); } $repoDir = __DIR__ . '/../../store/git/sys/extend/addon/' . $repoName; if (!is_dir($repoDir)) { logger('Repo directory does not exist: ' . $repoDir); json_return_and_die(array('message' => 'Invalid addon repo.', 'success' => false)); } if (!is_writable($repoDir)) { logger('Repo directory not writable to web server: ' . $repoDir); json_return_and_die(array('message' => 'Repo directory not writable to web server.', 'success' => false)); } $git = new GitRepo('sys', null, false, $repoName, $repoDir); try { if ($git->pull()) { json_return_and_die(array('message' => 'Repo updated.', 'success' => true)); } else { json_return_and_die(array('message' => 'Error updating addon repo.', 'success' => false)); } } catch (\PHPGit\Exception\GitException $e) { json_return_and_die(array('message' => 'Error updating addon repo.', 'success' => false)); } case 'removerepo': if (array_key_exists('repoName', $_REQUEST)) { $repoName = $_REQUEST['repoName']; } else { json_return_and_die(array('message' => 'No repo name provided.', 'success' => false)); } $repoDir = __DIR__ . '/../../store/git/sys/extend/addon/' . $repoName; if (!is_dir($repoDir)) { logger('Repo directory does not exist: ' . $repoDir); json_return_and_die(array('message' => 'Invalid addon repo.', 'success' => false)); } if (!is_writable($repoDir)) { logger('Repo directory not writable to web server: ' . $repoDir); json_return_and_die(array('message' => 'Repo directory not writable to web server.', 'success' => false)); } // TODO: remove directory and unlink /addon/files if (rrmdir($repoDir)) { json_return_and_die(array('message' => 'Repo deleted.', 'success' => true)); } else { json_return_and_die(array('message' => 'Error deleting addon repo.', 'success' => false)); } case 'installrepo': require_once 'library/markdown.php'; if (array_key_exists('repoURL', $_REQUEST)) { require __DIR__ . '/../../library/PHPGit.autoload.php'; // Load PHPGit dependencies $repoURL = $_REQUEST['repoURL']; $extendDir = __DIR__ . '/../../store/git/sys/extend'; $addonDir = $extendDir . '/addon'; if (!file_exists($extendDir)) { if (!mkdir($extendDir, 0770, true)) { logger('Error creating extend folder: ' . $extendDir); json_return_and_die(array('message' => 'Error creating extend folder: ' . $extendDir, 'success' => false)); } else { if (!symlink(__DIR__ . '/../../extend/addon', $addonDir)) { logger('Error creating symlink to addon folder: ' . $addonDir); json_return_and_die(array('message' => 'Error creating symlink to addon folder: ' . $addonDir, 'success' => false)); } } } if (!is_writable($extendDir)) { logger('Directory not writable to web server: ' . $extendDir); json_return_and_die(array('message' => 'Directory not writable to web server.', 'success' => false)); } $repoName = null; if (array_key_exists('repoName', $_REQUEST) && $_REQUEST['repoName'] !== '') { $repoName = $_REQUEST['repoName']; } else { $repoName = GitRepo::getRepoNameFromURL($repoURL); } if (!$repoName) { logger('Invalid git repo'); json_return_and_die(array('message' => 'Invalid git repo', 'success' => false)); } $repoDir = $addonDir . '/' . $repoName; $tempRepoBaseDir = __DIR__ . '/../../store/git/sys/temp/'; $tempAddonDir = $tempRepoBaseDir . $repoName; if (!is_writable($addonDir) || !is_writable($tempAddonDir)) { logger('Temp repo directory or /extend/addon not writable to web server: ' . $tempAddonDir); json_return_and_die(array('message' => 'Temp repo directory not writable to web server.', 'success' => false)); } rename($tempAddonDir, $repoDir); if (!is_writable(realpath(__DIR__ . '/../../addon/'))) { logger('/addon directory not writable to web server: ' . $tempAddonDir); json_return_and_die(array('message' => '/addon directory not writable to web server.', 'success' => false)); } $files = array_diff(scandir($repoDir), array('.', '..')); foreach ($files as $file) { if (is_dir($repoDir . '/' . $file) && $file !== '.git') { $source = '../extend/addon/' . $repoName . '/' . $file; $target = realpath(__DIR__ . '/../../addon/') . '/' . $file; unlink($target); if (!symlink($source, $target)) { logger('Error linking addons to /addon'); json_return_and_die(array('message' => 'Error linking addons to /addon', 'success' => false)); } } } $git = new GitRepo('sys', $repoURL, false, $repoName, $repoDir); $repo = $git->probeRepo(); json_return_and_die(array('repo' => $repo, 'message' => '', 'success' => true)); } case 'addrepo': require_once 'library/markdown.php'; if (array_key_exists('repoURL', $_REQUEST)) { require __DIR__ . '/../../library/PHPGit.autoload.php'; // Load PHPGit dependencies $repoURL = $_REQUEST['repoURL']; $extendDir = __DIR__ . '/../../store/git/sys/extend'; $addonDir = $extendDir . '/addon'; $tempAddonDir = __DIR__ . '/../../store/git/sys/temp'; if (!file_exists($extendDir)) { if (!mkdir($extendDir, 0770, true)) { logger('Error creating extend folder: ' . $extendDir); json_return_and_die(array('message' => 'Error creating extend folder: ' . $extendDir, 'success' => false)); } else { if (!symlink(__DIR__ . '/../../extend/addon', $addonDir)) { logger('Error creating symlink to addon folder: ' . $addonDir); json_return_and_die(array('message' => 'Error creating symlink to addon folder: ' . $addonDir, 'success' => false)); } } } $repoName = null; if (array_key_exists('repoName', $_REQUEST) && $_REQUEST['repoName'] !== '') { $repoName = $_REQUEST['repoName']; } else { $repoName = GitRepo::getRepoNameFromURL($repoURL); } if (!$repoName) { logger('Invalid git repo'); json_return_and_die(array('message' => 'Invalid git repo: ' . $repoName, 'success' => false)); } $repoDir = $tempAddonDir . '/' . $repoName; if (!is_writable($tempAddonDir)) { logger('Temporary directory for new addon repo is not writable to web server: ' . $tempAddonDir); json_return_and_die(array('message' => 'Temporary directory for new addon repo is not writable to web server.', 'success' => false)); } // clone the repo if new automatically $git = new GitRepo('sys', $repoURL, true, $repoName, $repoDir); $remotes = $git->git->remote(); $fetchURL = $remotes['origin']['fetch']; if ($fetchURL !== $git->url) { if (rrmdir($repoDir)) { $git = new GitRepo('sys', $repoURL, true, $repoName, $repoDir); } else { json_return_and_die(array('message' => 'Error deleting existing addon repo.', 'success' => false)); } } $repo = $git->probeRepo(); $repo['readme'] = $repo['manifest'] = null; foreach ($git->git->tree('master') as $object) { if ($object['type'] == 'blob' && (strtolower($object['file']) === 'readme.md' || strtolower($object['file']) === 'readme')) { $repo['readme'] = Markdown($git->git->cat->blob($object['hash'])); } else { if ($object['type'] == 'blob' && strtolower($object['file']) === 'manifest.json') { $repo['manifest'] = $git->git->cat->blob($object['hash']); } } } json_return_and_die(array('repo' => $repo, 'message' => '', 'success' => true)); } else { json_return_and_die(array('message' => 'No repo URL provided', 'success' => false)); } break; default: break; } }
function zfinger_init(&$a) { require_once 'include/zot.php'; require_once 'include/crypto.php'; $ret = array('success' => false); $zhash = x($_REQUEST, 'guid_hash') ? $_REQUEST['guid_hash'] : ''; $zguid = x($_REQUEST, 'guid') ? $_REQUEST['guid'] : ''; $zguid_sig = x($_REQUEST, 'guid_sig') ? $_REQUEST['guid_sig'] : ''; $zaddr = x($_REQUEST, 'address') ? $_REQUEST['address'] : ''; $ztarget = x($_REQUEST, 'target') ? $_REQUEST['target'] : ''; $zsig = x($_REQUEST, 'target_sig') ? $_REQUEST['target_sig'] : ''; $zkey = x($_REQUEST, 'key') ? $_REQUEST['key'] : ''; $mindate = x($_REQUEST, 'mindate') ? $_REQUEST['mindate'] : ''; $feed = x($_REQUEST, 'feed') ? intval($_REQUEST['feed']) : 0; if ($ztarget) { if (!$zkey || !$zsig || !rsa_verify($ztarget, base64url_decode($zsig), $zkey)) { logger('zfinger: invalid target signature'); $ret['message'] = t("invalid target signature"); json_return_and_die($ret); } } // allow re-written domains so bob@foo.example.com can provide an address of bob@example.com // The top-level domain also needs to redirect .well-known/zot-info to the sub-domain with a 301 or 308 // TODO: Make 308 work in include/network.php for zot_fetch_url and zot_post_url if ($zaddr && ($s = get_config('system', 'zotinfo_domainrewrite'))) { $arr = explode('^', $s); if (count($arr) == 2) { $zaddr = str_replace($arr[0], $arr[1], $zaddr); } } $r = null; if (strlen($zhash)) { $r = q("select channel.*, xchan.* from channel left join xchan on channel_hash = xchan_hash \n\t\t\twhere channel_hash = '%s' limit 1", dbesc($zhash)); } elseif (strlen($zguid) && strlen($zguid_sig)) { $r = q("select channel.*, xchan.* from channel left join xchan on channel_hash = xchan_hash \n\t\t\twhere channel_guid = '%s' and channel_guid_sig = '%s' limit 1", dbesc($zguid), dbesc($zguid_sig)); } elseif (strlen($zaddr)) { if (strpos($zaddr, '[system]') === false) { /* normal address lookup */ $r = q("select channel.*, xchan.* from channel left join xchan on channel_hash = xchan_hash\n\t\t\t\twhere ( channel_address = '%s' or xchan_addr = '%s' ) limit 1", dbesc($zaddr), dbesc($zaddr)); } else { /** * The special address '[system]' will return a system channel if one has been defined, * Or the first valid channel we find if there are no system channels. * * This is used by magic-auth if we have no prior communications with this site - and * returns an identity on this site which we can use to create a valid hub record so that * we can exchange signed messages. The precise identity is irrelevant. It's the hub * information that we really need at the other end - and this will return it. * */ $r = q("select channel.*, xchan.* from channel left join xchan on channel_hash = xchan_hash\n\t\t\t\twhere ( channel_pageflags & %d )>0 order by channel_id limit 1", intval(PAGE_SYSTEM)); if (!$r) { $r = q("select channel.*, xchan.* from channel left join xchan on channel_hash = xchan_hash\n\t\t\t\t\twhere not ( channel_pageflags & %d )>0 order by channel_id limit 1", intval(PAGE_REMOVED)); } } } else { $ret['message'] = 'Invalid request'; json_return_and_die($ret); } if (!$r) { $ret['message'] = 'Item not found.'; json_return_and_die($ret); } $e = $r[0]; $id = $e['channel_id']; $sys_channel = $e['channel_pageflags'] & PAGE_SYSTEM ? true : false; $special_channel = $e['channel_pageflags'] & PAGE_PREMIUM ? true : false; $adult_channel = $e['channel_pageflags'] & PAGE_ADULT ? true : false; $censored = $e['channel_pageflags'] & PAGE_CENSORED ? true : false; $searchable = $e['channel_pageflags'] & PAGE_HIDDEN ? false : true; $deleted = $e['xchan_flags'] & XCHAN_FLAGS_DELETED ? true : false; if ($deleted || $censored || $sys_channel) { $searchable = false; } $public_forum = false; $role = get_pconfig($e['channel_id'], 'system', 'permissions_role'); if ($role === 'forum') { $public_forum = true; } else { // check if it has characteristics of a public forum based on custom permissions. $t = q("select abook_my_perms from abook where abook_channel = %d and (abook_flags & %d)>0 limit 1", intval($e['channel_id']), intval(ABOOK_FLAG_SELF)); if ($t && $t[0]['abook_my_perms'] & PERMS_W_TAGWALL) { $public_forum = true; } } // This is for birthdays and keywords, but must check access permissions $p = q("select * from profile where uid = %d and is_default = 1", intval($e['channel_id'])); $profile = array(); if ($p) { if (!intval($p[0]['publish'])) { $searchable = false; } $profile['description'] = $p[0]['pdesc']; $profile['birthday'] = $p[0]['dob']; if ($profile['birthday'] != '0000-00-00' && ($bd = z_birthday($p[0]['dob'], $e['channel_timezone'])) !== '') { $profile['next_birthday'] = $bd; } if ($age = age($p[0]['dob'], $e['channel_timezone'], '')) { $profile['age'] = $age; } $profile['gender'] = $p[0]['gender']; $profile['marital'] = $p[0]['marital']; $profile['sexual'] = $p[0]['sexual']; $profile['locale'] = $p[0]['locality']; $profile['region'] = $p[0]['region']; $profile['postcode'] = $p[0]['postal_code']; $profile['country'] = $p[0]['country_name']; $profile['about'] = $p[0]['about']; $profile['homepage'] = $p[0]['homepage']; $profile['hometown'] = $p[0]['hometown']; if ($p[0]['keywords']) { $tags = array(); $k = explode(' ', $p[0]['keywords']); if ($k) { foreach ($k as $kk) { if (trim($kk, " \t\n\r\v,")) { $tags[] = trim($kk, " \t\n\r\v,"); } } } if ($tags) { $profile['keywords'] = $tags; } } } $ret['success'] = true; // Communication details $ret['guid'] = $e['xchan_guid']; $ret['guid_sig'] = $e['xchan_guid_sig']; $ret['key'] = $e['xchan_pubkey']; $ret['name'] = $e['xchan_name']; $ret['name_updated'] = $e['xchan_name_date']; $ret['address'] = $e['xchan_addr']; $ret['photo_mimetype'] = $e['xchan_photo_mimetype']; $ret['photo'] = $e['xchan_photo_l']; $ret['photo_updated'] = $e['xchan_photo_date']; $ret['url'] = $e['xchan_url']; $ret['connections_url'] = $e['xchan_connurl'] ? $e['xchan_connurl'] : z_root() . '/poco/' . $e['channel_address']; $ret['target'] = $ztarget; $ret['target_sig'] = $zsig; $ret['searchable'] = $searchable; $ret['adult_content'] = $adult_channel; $ret['public_forum'] = $public_forum; if ($deleted) { $ret['deleted'] = $deleted; } // premium or other channel desiring some contact with potential followers before connecting. // This is a template - %s will be replaced with the follow_url we discover for the return channel. if ($special_channel) { $ret['connect_url'] = z_root() . '/connect/' . $e['channel_address']; } // This is a template for our follow url, %s will be replaced with a webbie $ret['follow_url'] = z_root() . '/follow?f=&url=%s'; $ztarget_hash = $ztarget && $zsig ? make_xchan_hash($ztarget, $zsig) : ''; $permissions = get_all_perms($e['channel_id'], $ztarget_hash, false); if ($ztarget_hash) { $permissions['connected'] = false; $b = q("select * from abook where abook_xchan = '%s' and abook_channel = %d limit 1", dbesc($ztarget_hash), intval($e['channel_id'])); if ($b) { $permissions['connected'] = true; } } $ret['permissions'] = $ztarget && $zkey ? crypto_encapsulate(json_encode($permissions), $zkey) : $permissions; if ($permissions['view_profile']) { $ret['profile'] = $profile; } // array of (verified) hubs this channel uses $x = zot_encode_locations($e); if ($x) { $ret['locations'] = $x; } $ret['site'] = array(); $ret['site']['url'] = z_root(); $ret['site']['url_sig'] = base64url_encode(rsa_sign(z_root(), $e['channel_prvkey'])); $dirmode = get_config('system', 'directory_mode'); if ($dirmode === false || $dirmode == DIRECTORY_MODE_NORMAL) { $ret['site']['directory_mode'] = 'normal'; } if ($dirmode == DIRECTORY_MODE_PRIMARY) { $ret['site']['directory_mode'] = 'primary'; } elseif ($dirmode == DIRECTORY_MODE_SECONDARY) { $ret['site']['directory_mode'] = 'secondary'; } elseif ($dirmode == DIRECTORY_MODE_STANDALONE) { $ret['site']['directory_mode'] = 'standalone'; } if ($dirmode != DIRECTORY_MODE_NORMAL) { $ret['site']['directory_url'] = z_root() . '/dirsearch'; } // hide detailed site information if you're off the grid if ($dirmode != DIRECTORY_MODE_STANDALONE) { $register_policy = intval(get_config('system', 'register_policy')); if ($register_policy == REGISTER_CLOSED) { $ret['site']['register_policy'] = 'closed'; } if ($register_policy == REGISTER_APPROVE) { $ret['site']['register_policy'] = 'approve'; } if ($register_policy == REGISTER_OPEN) { $ret['site']['register_policy'] = 'open'; } $access_policy = intval(get_config('system', 'access_policy')); if ($access_policy == ACCESS_PRIVATE) { $ret['site']['access_policy'] = 'private'; } if ($access_policy == ACCESS_PAID) { $ret['site']['access_policy'] = 'paid'; } if ($access_policy == ACCESS_FREE) { $ret['site']['access_policy'] = 'free'; } if ($access_policy == ACCESS_TIERED) { $ret['site']['access_policy'] = 'tiered'; } $ret['site']['accounts'] = account_total(); require_once 'include/identity.php'; $ret['site']['channels'] = channel_total(); $ret['site']['version'] = PLATFORM_NAME . ' ' . RED_VERSION . '[' . DB_UPDATE_VERSION . ']'; $ret['site']['admin'] = get_config('system', 'admin_email'); $visible_plugins = array(); if (is_array($a->plugins) && count($a->plugins)) { $r = q("select * from addon where hidden = 0"); if ($r) { foreach ($r as $rr) { $visible_plugins[] = $rr['name']; } } } $ret['site']['plugins'] = $visible_plugins; $ret['site']['sitehash'] = get_config('system', 'location_hash'); $ret['site']['sitename'] = get_config('system', 'sitename'); $ret['site']['sellpage'] = get_config('system', 'sellpage'); $ret['site']['location'] = get_config('system', 'site_location'); $ret['site']['realm'] = get_directory_realm(); } call_hooks('zot_finger', $ret); json_return_and_die($ret); }
function chat_content(&$a) { if (local_channel()) { $channel = $a->get_channel(); } $ob = $a->get_observer(); $observer = get_observer_hash(); if (!$observer) { notice(t('Permission denied.') . EOL); return; } if (!perm_is_allowed($a->profile['profile_uid'], $observer, 'chat')) { notice(t('Permission denied.') . EOL); return; } if (argc() > 3 && intval(argv(2)) && argv(3) === 'leave') { chatroom_leave($observer, argv(2), $_SERVER['REMOTE_ADDR']); goaway(z_root() . '/channel/' . argv(1)); } if (argc() > 3 && intval(argv(2)) && argv(3) === 'status') { $ret = array('success' => false); $room_id = intval(argv(2)); if (!$room_id || !$observer) { return; } $r = q("select * from chatroom where cr_id = %d limit 1", intval($room_id)); if (!$r) { json_return_and_die($ret); } require_once 'include/security.php'; $sql_extra = permissions_sql($r[0]['cr_uid']); $x = q("select * from chatroom where cr_id = %d and cr_uid = %d {$sql_extra} limit 1", intval($room_id), intval($r[0]['cr_uid'])); if (!$x) { json_return_and_die($ret); } $y = q("select count(*) as total from chatpresence where cp_room = %d", intval($room_id)); if ($y) { $ret['success'] = true; $ret['chatroom'] = $r[0]['cr_name']; $ret['inroom'] = $y[0]['total']; } // figure out how to present a timestamp of the last activity, since we don't know the observer's timezone. $z = q("select created from chat where chat_room = %d order by created desc limit 1", intval($room_id)); if ($z) { $ret['last'] = $z[0]['created']; } json_return_and_die($ret); } if (argc() > 2 && intval(argv(2))) { $room_id = intval(argv(2)); $bookmark_link = get_bookmark_link($ob); $x = chatroom_enter($observer, $room_id, 'online', $_SERVER['REMOTE_ADDR']); if (!$x) { return; } $x = q("select * from chatroom where cr_id = %d and cr_uid = %d {$sql_extra} limit 1", intval($room_id), intval($a->profile['profile_uid'])); if ($x) { $acl = new AccessList(false); $acl->set($x[0]); $private = $acl->is_private(); $room_name = $x[0]['cr_name']; if ($bookmark_link) { $bookmark_link .= '&url=' . z_root() . '/chat/' . argv(1) . '/' . argv(2) . '&title=' . urlencode($x[0]['cr_name']) . ($private ? '&private=1' : '') . '&ischat=1'; } } else { notice(t('Room not found') . EOL); return; } $o = replace_macros(get_markup_template('chat.tpl'), array('$is_owner' => local_channel() && local_channel() == $x[0]['cr_uid'] ? true : false, '$room_name' => $room_name, '$room_id' => $room_id, '$baseurl' => z_root(), '$nickname' => argv(1), '$submit' => t('Submit'), '$leave' => t('Leave Room'), '$drop' => t('Delete This Room'), '$away' => t('I am away right now'), '$online' => t('I am online'), '$bookmark_link' => $bookmark_link, '$bookmark' => t('Bookmark this room'))); return $o; } if (local_channel() && argc() > 2 && argv(2) === 'new') { $acl = new AccessList($channel); $channel_acl = $acl->get(); require_once 'include/acl_selectors.php'; $o = replace_macros(get_markup_template('chatroom_new.tpl'), array('$header' => t('New Chatroom'), '$name' => array('room_name', t('Chatroom Name'), '', ''), '$chat_expire' => array('chat_expire', t('Expiration of chats (minutes)'), 120, ''), '$permissions' => t('Permissions'), '$acl' => populate_acl($channel_acl, false), '$submit' => t('Submit'))); return $o; } require_once 'include/conversation.php'; $o = profile_tabs($a, local_channel() && local_channel() == $a->profile['profile_uid'] ? true : false, $a->profile['channel_address']); require_once 'include/widgets.php'; $o .= replace_macros(get_markup_template('chatrooms.tpl'), array('$header' => sprintf(t('%1$s\'s Chatrooms'), $a->profile['name']), '$baseurl' => z_root(), '$nickname' => $channel['channel_address'], '$rooms' => widget_chatroom_list(array()), '$newroom' => t('New Chatroom'), '$is_owner' => local_channel() && local_channel() == $a->profile['profile_uid'] ? 1 : 0)); return $o; }
function dirsearch_content(&$a) { $ret = array('success' => false); // logger('request: ' . print_r($_REQUEST,true)); $dirmode = intval(get_config('system', 'directory_mode')); if ($dirmode == DIRECTORY_MODE_NORMAL) { $ret['message'] = t('This site is not a directory server'); json_return_and_die($ret); } $access_token = $_REQUEST['t']; $token = get_config('system', 'realm_token'); if ($token && $access_token != $token) { $result['message'] = t('This directory server requires an access token'); return; } if (argc() > 1 && argv(1) === 'sites') { $ret = list_public_sites(); json_return_and_die($ret); } $sql_extra = ''; $tables = array('name', 'address', 'locale', 'region', 'postcode', 'country', 'gender', 'marital', 'sexual', 'keywords'); if ($_REQUEST['query']) { $advanced = dir_parse_query($_REQUEST['query']); if ($advanced) { foreach ($advanced as $adv) { if (in_array($adv['field'], $tables)) { if ($adv['field'] === 'name') { $sql_extra .= dir_query_build($adv['logic'], 'xchan_name', $adv['value']); } elseif ($adv['field'] === 'address') { $sql_extra .= dir_query_build($adv['logic'], 'xchan_addr', $adv['value']); } else { $sql_extra .= dir_query_build($adv['logic'], 'xprof_' . $adv['field'], $adv['value']); } } } } } $hash = x($_REQUEST['hash']) ? $_REQUEST['hash'] : ''; $name = x($_REQUEST, 'name') ? $_REQUEST['name'] : ''; $hub = x($_REQUEST, 'hub') ? $_REQUEST['hub'] : ''; $address = x($_REQUEST, 'address') ? $_REQUEST['address'] : ''; $locale = x($_REQUEST, 'locale') ? $_REQUEST['locale'] : ''; $region = x($_REQUEST, 'region') ? $_REQUEST['region'] : ''; $postcode = x($_REQUEST, 'postcode') ? $_REQUEST['postcode'] : ''; $country = x($_REQUEST, 'country') ? $_REQUEST['country'] : ''; $gender = x($_REQUEST, 'gender') ? $_REQUEST['gender'] : ''; $marital = x($_REQUEST, 'marital') ? $_REQUEST['marital'] : ''; $sexual = x($_REQUEST, 'sexual') ? $_REQUEST['sexual'] : ''; $keywords = x($_REQUEST, 'keywords') ? $_REQUEST['keywords'] : ''; $agege = x($_REQUEST, 'agege') ? intval($_REQUEST['agege']) : 0; $agele = x($_REQUEST, 'agele') ? intval($_REQUEST['agele']) : 0; $kw = x($_REQUEST, 'kw') ? intval($_REQUEST['kw']) : 0; $forums = array_key_exists('pubforums', $_REQUEST) ? intval($_REQUEST['pubforums']) : 0; // by default use a safe search $safe = x($_REQUEST, 'safe'); // ? intval($_REQUEST['safe']) : 1 ); if ($safe === false) { $safe = 1; } if (array_key_exists('sync', $_REQUEST)) { if ($_REQUEST['sync']) { $sync = datetime_convert('UTC', 'UTC', $_REQUEST['sync']); } else { $sync = datetime_convert('UTC', 'UTC', '2010-01-01 01:01:00'); } } else { $sync = false; } if ($hub) { $hub_query = " and xchan_hash in (select hubloc_hash from hubloc where hubloc_host = '" . protect_sprintf(dbesc($hub)) . "') "; } else { $hub_query = ''; } $sort_order = x($_REQUEST, 'order') ? $_REQUEST['order'] : ''; $joiner = ' OR '; if ($_REQUEST['and']) { $joiner = ' AND '; } if ($name) { $sql_extra .= dir_query_build($joiner, 'xchan_name', $name); } if ($address) { $sql_extra .= dir_query_build($joiner, 'xchan_addr', $address); } if ($city) { $sql_extra .= dir_query_build($joiner, 'xprof_locale', $city); } if ($region) { $sql_extra .= dir_query_build($joiner, 'xprof_region', $region); } if ($post) { $sql_extra .= dir_query_build($joiner, 'xprof_postcode', $post); } if ($country) { $sql_extra .= dir_query_build($joiner, 'xprof_country', $country); } if ($gender) { $sql_extra .= dir_query_build($joiner, 'xprof_gender', $gender); } if ($marital) { $sql_extra .= dir_query_build($joiner, 'xprof_marital', $marital); } if ($sexual) { $sql_extra .= dir_query_build($joiner, 'xprof_sexual', $sexual); } if ($keywords) { $sql_extra .= dir_query_build($joiner, 'xprof_keywords', $keywords); } if ($forums) { $safesql .= dir_flag_build(' AND ', 'xchan_flags', XCHAN_FLAGS_PUBFORUM, $forums); } // we only support an age range currently. You must set both agege // (greater than or equal) and agele (less than or equal) if ($agele && $agege) { $sql_extra .= " {$joiner} ( xprof_age <= " . intval($agele) . " "; $sql_extra .= " AND xprof_age >= " . intval($agege) . ") "; } if ($hash) { $sql_extra = " AND xchan_hash like '" . dbesc($hash) . protect_sprintf('%') . "' "; } $perpage = $_REQUEST['n'] ? $_REQUEST['n'] : 60; $page = $_REQUEST['p'] ? intval($_REQUEST['p'] - 1) : 0; $startrec = ($page + 1) * $perpage - $perpage; $limit = $_REQUEST['limit'] ? intval($_REQUEST['limit']) : 0; $return_total = x($_REQUEST, 'return_total') ? intval($_REQUEST['return_total']) : 0; // mtime is not currently working $mtime = x($_REQUEST, 'mtime') ? datetime_convert('UTC', 'UTC', $_REQUEST['mtime']) : ''; // ok a separate tag table won't work. // merge them into xprof $ret['success'] = true; // If &limit=n, return at most n entries // If &return_total=1, we count matching entries and return that as 'total_items' for use in pagination. // By default we return one page (default 80 items maximum) and do not count total entries $logic = strlen($sql_extra) ? 'false' : 'true'; if ($hash) { $logic = 'true'; } if ($dirmode == DIRECTORY_MODE_STANDALONE) { $sql_extra .= " and xchan_addr like '%%" . get_app()->get_hostname() . "' "; } $safesql = $safe > 0 ? " and xchan_censored = 0 and xchan_selfcensored = 0 " : ''; if ($safe < 0) { $safesql = " and ( xchan_censored = 1 OR xchan_selfcensored = 1 ) "; } if ($limit) { $qlimit = " LIMIT {$limit} "; } else { $qlimit = " LIMIT " . intval($perpage) . " OFFSET " . intval($startrec); if ($return_total) { $r = q("SELECT COUNT(xchan_hash) AS `total` FROM xchan left join xprof on xchan_hash = xprof_hash where {$logic} {$sql_extra} and xchan_network = 'zot' and xchan_hidden = 0 and xchan_orphan = 0 and xchan_deleted = 0 {$safesql} "); if ($r) { $ret['total_items'] = $r[0]['total']; } } } if ($sort_order == 'normal') { $order = " order by xchan_name asc "; // Start the alphabetic search at 'A' // This will make a handful of channels whose names begin with // punctuation un-searchable in this mode $safesql .= " and ascii(substring(xchan_name FROM 1 FOR 1)) > 64 "; } elseif ($sort_order == 'reverse') { $order = " order by xchan_name desc "; } elseif ($sort_order == 'reversedate') { $order = " order by xchan_name_date asc "; } else { $order = " order by xchan_name_date desc "; } if ($sync) { $spkt = array('transactions' => array()); $r = q("select * from updates where ud_date >= '%s' and ud_guid != '' order by ud_date desc", dbesc($sync)); if ($r) { foreach ($r as $rr) { $flags = array(); if ($rr['ud_flags'] & UPDATE_FLAGS_DELETED) { $flags[] = 'deleted'; } if ($rr['ud_flags'] & UPDATE_FLAGS_FORCED) { $flags[] = 'forced'; } $spkt['transactions'][] = array('hash' => $rr['ud_hash'], 'address' => $rr['ud_addr'], 'transaction_id' => $rr['ud_guid'], 'timestamp' => $rr['ud_date'], 'flags' => $flags); } } $r = q("select * from xlink where xlink_static = 1 and xlink_updated >= '%s' ", dbesc($sync)); if ($r) { $spkt['ratings'] = array(); foreach ($r as $rr) { $spkt['ratings'][] = array('type' => 'rating', 'encoding' => 'zot', 'channel' => $rr['xlink_xchan'], 'target' => $rr['xlink_link'], 'rating' => intval($rr['xlink_rating']), 'rating_text' => $rr['xlink_rating_text'], 'signature' => $rr['xlink_sig'], 'edited' => $rr['xlink_updated']); } } json_return_and_die($spkt); } else { $r = q("SELECT xchan.*, xprof.* from xchan left join xprof on xchan_hash = xprof_hash \n\t\t\twhere ( {$logic} {$sql_extra} ) {$hub_query} and xchan_network = 'zot' and xchan_hidden = 0 and xchan_orphan = 0 and xchan_deleted = 0 \n\t\t\t{$safesql} {$order} {$qlimit} "); $ret['page'] = $page + 1; $ret['records'] = count($r); } if ($r) { $entries = array(); foreach ($r as $rr) { $entry = array(); $pc = q("select count(xlink_rating) as total_ratings from xlink where xlink_link = '%s' and xlink_rating != 0 and xlink_static = 1 group by xlink_rating", dbesc($rr['xchan_hash'])); if ($pc) { $entry['total_ratings'] = intval($pc[0]['total_ratings']); } else { $entry['total_ratings'] = 0; } $entry['name'] = $rr['xchan_name']; $entry['hash'] = $rr['xchan_hash']; $entry['public_forum'] = intval($rr['xchan_pubforum']) ? true : false; $entry['url'] = $rr['xchan_url']; $entry['photo_l'] = $rr['xchan_photo_l']; $entry['photo'] = $rr['xchan_photo_m']; $entry['address'] = $rr['xchan_addr']; $entry['description'] = $rr['xprof_desc']; $entry['locale'] = $rr['xprof_locale']; $entry['region'] = $rr['xprof_region']; $entry['postcode'] = $rr['xprof_postcode']; $entry['country'] = $rr['xprof_country']; $entry['birthday'] = $rr['xprof_dob']; $entry['age'] = $rr['xprof_age']; $entry['gender'] = $rr['xprof_gender']; $entry['marital'] = $rr['xprof_marital']; $entry['sexual'] = $rr['xprof_sexual']; $entry['about'] = $rr['xprof_about']; $entry['homepage'] = $rr['xprof_homepage']; $entry['hometown'] = $rr['xprof_hometown']; $entry['keywords'] = $rr['xprof_keywords']; $entries[] = $entry; } $ret['results'] = $entries; if ($kw) { $k = dir_tagadelic($kw); if ($k) { $ret['keywords'] = array(); foreach ($k as $kv) { $ret['keywords'][] = array('term' => $kv[0], 'weight' => $kv[1], 'normalise' => $kv[2]); } } } } json_return_and_die($ret); }
function siteinfo_init(&$a) { global $db; if ($a->argv[1] == "json") { $register_policy = array('REGISTER_CLOSED', 'REGISTER_APPROVE', 'REGISTER_OPEN'); $directory_mode = array('DIRECTORY_MODE_NORMAL', 'DIRECTORY_MODE_SECONDARY', 'DIRECTORY_MODE_PRIMARY', 'DIRECTORY_MODE_STANDALONE'); $sql_extra = ''; $r = q("select * from channel left join account on account_id = channel_account_id where ( account_roles & 4096 )>0 and account_default_channel = channel_id"); if ($r) { $admin = array(); foreach ($r as $rr) { if ($rr['channel_pageflags'] & PAGE_HUBADMIN) { $admin[] = array('name' => $rr['channel_name'], 'address' => $rr['channel_address'] . '@' . get_app()->get_hostname(), 'channel' => z_root() . '/channel/' . $rr['channel_address']); } } if (!$admin) { foreach ($r as $rr) { $admin[] = array('name' => $rr['channel_name'], 'address' => $rr['channel_address'] . '@' . get_app()->get_hostname(), 'channel' => z_root() . '/channel/' . $rr['channel_address']); } } } else { $admin = false; } $def_service_class = get_config('system', 'default_service_class'); if ($def_service_class) { $service_class = get_config('service_class', $def_service_class); } else { $service_class = false; } $visible_plugins = array(); if (is_array($a->plugins) && count($a->plugins)) { $r = q("select * from addon where hidden = 0"); if (count($r)) { foreach ($r as $rr) { $visible_plugins[] = $rr['name']; } } } sort($visible_plugins); if (@is_dir('.git') && function_exists('shell_exec')) { $commit = trim(@shell_exec('git log -1 --format="%h"')); } if (!isset($commit) || strlen($commit) > 16) { $commit = ''; } $site_info = get_config('system', 'info'); $site_name = get_config('system', 'sitename'); if (!get_config('system', 'hidden_version_siteinfo')) { $version = RED_VERSION; if (@is_dir('.git') && function_exists('shell_exec')) { $commit = trim(@shell_exec('git log -1 --format="%h"')); if (!get_config('system', 'hidden_tag_siteinfo')) { $tag = trim(@shell_exec('git describe --tags --abbrev=0')); } else { $tag = ''; } } if (!isset($commit) || strlen($commit) > 16) { $commit = ''; } } else { $version = $commit = ''; } //Statistics $channels_total_stat = intval(get_config('system', 'channels_total_stat')); $channels_active_halfyear_stat = intval(get_config('system', 'channels_active_halfyear_stat')); $channels_active_monthly_stat = intval(get_config('system', 'channels_active_monthly_stat')); $local_posts_stat = intval(get_config('system', 'local_posts_stat')); $hide_in_statistics = intval(get_config('system', 'hide_in_statistics')); $site_expire = intval(get_config('system', 'default_expire_days')); $data = array('version' => $version, 'version_tag' => $tag, 'commit' => $commit, 'url' => z_root(), 'plugins' => $visible_plugins, 'register_policy' => $register_policy[$a->config['system']['register_policy']], 'directory_mode' => $directory_mode[$a->config['system']['directory_mode']], 'language' => get_config('system', 'language'), 'diaspora_emulation' => get_config('system', 'diaspora_enabled'), 'rss_connections' => get_config('system', 'feed_contacts'), 'expiration' => $site_expire, 'default_service_restrictions' => $service_class, 'admin' => $admin, 'site_name' => $site_name ? $site_name : '', 'platform' => PLATFORM_NAME, 'dbdriver' => $db->getdriver(), 'lastpoll' => get_config('system', 'lastpoll'), 'info' => $site_info ? $site_info : '', 'channels_total' => $channels_total_stat, 'channels_active_halfyear' => $channels_active_halfyear_stat, 'channels_active_monthly' => $channels_active_monthly_stat, 'local_posts' => $local_posts_stat, 'hide_in_statistics' => $hide_in_statistics); json_return_and_die($data); } }
function init() { $result = array('success' => false); $url = $_REQUEST['url']; $access_token = $_REQUEST['t']; $valid = 0; // we probably don't need the realm as we will find out in the probe. // What we may want to die is throw an error if you're trying to register in a different realm // so this configuration issue can be discovered. $realm = $_REQUEST['realm']; if (!$realm) { $realm = DIRECTORY_REALM; } if ($realm === DIRECTORY_REALM) { $valid = 1; } else { $token = get_config('system', 'realm_token'); if ($token && $access_token != $token) { $result['message'] = 'This realm requires an access token'; return; } $valid = 1; } $dirmode = intval(get_config('system', 'directory_mode')); if ($dirmode == DIRECTORY_MODE_NORMAL) { $ret['message'] = t('This site is not a directory server'); json_return_and_die($ret); } $m = null; if ($url) { $m = parse_url($url); if (!$m || !@dns_get_record($m['host'], DNS_A + DNS_CNAME + DNS_PTR) && !filter_var($m['host'], FILTER_VALIDATE_IP)) { $result['message'] = 'unparseable url'; json_return_and_die($result); } $j = \Zotlabs\Zot\Finger::run('[system]@' . $m['host']); if ($j['success'] && $j['guid']) { $x = import_xchan($j); if ($x['success']) { $result['success'] = true; } } if (!$result['success']) { $valid = 0; } q("update site set site_valid = %d where site_url = '%s' limit 1", intval($valid), strtolower($url)); json_return_and_die($result); } else { // We can put this in the sql without the condition after 31 august 2015 assuming // most directory servers will have updated by then // This just makes sure it happens if I forget $sql_extra = datetime_convert() > datetime_convert('UTC', 'UTC', '2015-08-31') ? ' and site_valid = 1 ' : ''; if ($dirmode == DIRECTORY_MODE_STANDALONE) { $r = array(array('site_url' => z_root())); } else { $r = q("select site_url from site where site_flags in ( 1, 2 ) and site_realm = '%s' and site_type = %d {$sql_extra} ", dbesc(get_directory_realm()), intval(SITE_TYPE_ZOT)); } if ($r) { $result['success'] = true; $result['directories'] = array(); foreach ($r as $rr) { $result['directories'][] = $rr['site_url']; } json_return_and_die($result); } } json_return_and_die($result); }
function red_item(&$a, $type) { if (api_user() === false) { logger('api_red_item_full: no user'); return false; } if ($_REQUEST['mid']) { $arr = array('mid' => $_REQUEST['mid']); } elseif ($_REQUEST['item_id']) { $arr = array('item_id' => $_REQUEST['item_id']); } else { json_return_and_die(array()); } $arr['start'] = 0; $arr['records'] = 999999; $arr['item_type'] = '*'; $i = items_fetch($arr, $a->get_channel(), get_observer_hash()); if (!$i) { json_return_and_die(array()); } $ret = array(); $tmp = array(); $str = ''; foreach ($i as $ii) { $tmp[] = encode_item($ii, true); if ($str) { $str .= ','; } $str .= $ii['id']; } $ret['item'] = $tmp; if ($str) { $r = q("select item_id.*, item.mid from item_id left join item on item_id.iid = item.id where item.id in ( {$str} ) "); if ($r) { $ret['item_id'] = $r; } } json_return_and_die($ret); }
function search_content(&$a, $update = 0, $load = false) { if (get_config('system', 'block_public') || get_config('system', 'block_public_search')) { if (!local_channel() && !remote_channel()) { notice(t('Public access denied.') . EOL); return; } } if ($load) { $_SESSION['loadtime'] = datetime_convert(); } nav_set_selected('search'); require_once "include/bbcode.php"; require_once 'include/security.php'; require_once 'include/conversation.php'; require_once 'include/items.php'; $format = $_REQUEST['format'] ? $_REQUEST['format'] : ''; if ($format !== '') { $update = $load = 1; } $observer = $a->get_observer(); $observer_hash = $observer ? $observer['xchan_hash'] : ''; $o = '<div id="live-search"></div>' . "\r\n"; $o .= '<h3>' . t('Search') . '</h3>'; if (x($a->data, 'search')) { $search = trim($a->data['search']); } else { $search = x($_GET, 'search') ? trim(rawurldecode($_GET['search'])) : ''; } $tag = false; if (x($_GET, 'tag')) { $tag = true; $search = x($_GET, 'tag') ? trim(rawurldecode($_GET['tag'])) : ''; } if (!local_channel() || !feature_enabled(local_channel(), 'savedsearch')) { $o .= search($search, 'search-box', '/search', local_channel() ? true : false); } if (strpos($search, '#') === 0) { $tag = true; $search = substr($search, 1); } if (strpos($search, '@') === 0) { $search = substr($search, 1); goaway(z_root() . '/directory' . '?f=1&search=' . $search); } // look for a naked webbie if (strpos($search, '@') !== false) { goaway(z_root() . '/directory' . '?f=1&search=' . $search); } if (!$search) { return $o; } if ($tag) { $sql_extra = sprintf(" AND `item`.`id` IN (select `oid` from term where otype = %d and type = %d and term = '%s') ", intval(TERM_OBJ_POST), intval(TERM_HASHTAG), dbesc(protect_sprintf($search))); } else { $regstr = db_getfunc('REGEXP'); $sql_extra = sprintf(" AND `item`.`body` {$regstr} '%s' ", dbesc(protect_sprintf(preg_quote($search)))); } // Here is the way permissions work in the search module... // Only public posts can be shown // OR your own posts if you are a logged in member // No items will be shown if the member has a blocked profile wall. if (!$update && !$load) { // This is ugly, but we can't pass the profile_uid through the session to the ajax updater, // because browser prefetching might change it on us. We have to deliver it with the page. $o .= '<div id="live-search"></div>' . "\r\n"; $o .= "<script> var profile_uid = " . (intval(local_channel()) ? local_channel() : -1) . "; var netargs = '?f='; var profile_page = " . $a->pager['page'] . "; </script>\r\n"; $a->page['htmlhead'] .= replace_macros(get_markup_template("build_query.tpl"), array('$baseurl' => z_root(), '$pgtype' => 'search', '$uid' => $a->profile['profile_uid'] ? $a->profile['profile_uid'] : '0', '$gid' => '0', '$cid' => '0', '$cmin' => '0', '$cmax' => '0', '$star' => '0', '$liked' => '0', '$conv' => '0', '$spam' => '0', '$fh' => '0', '$nouveau' => '0', '$wall' => '0', '$list' => x($_REQUEST, 'list') ? intval($_REQUEST['list']) : 0, '$page' => $a->pager['page'] != 1 ? $a->pager['page'] : 1, '$search' => ($tag ? urlencode('#') : '') . $search, '$order' => '', '$file' => '', '$cats' => '', '$tags' => '', '$mid' => '', '$verb' => '', '$dend' => '', '$dbegin' => '')); } $pub_sql = public_permissions_sql($observer_hash); require_once 'include/identity.php'; $sys = get_sys_channel(); if ($update && $load) { $itemspage = get_pconfig(local_channel(), 'system', 'itemspage'); $a->set_pager_itemspage(intval($itemspage) ? $itemspage : 20); $pager_sql = sprintf(" LIMIT %d OFFSET %d ", intval($a->pager['itemspage']), intval($a->pager['start'])); // in case somebody turned off public access to sys channel content with permissions if (!perm_is_allowed($sys['channel_id'], $observer_hash, 'view_stream')) { $sys['xchan_hash'] .= 'disabled'; } if ($load) { $r = null; if (ACTIVE_DBTYPE == DBTYPE_POSTGRES) { $prefix = 'distinct on (created, mid)'; $suffix = 'ORDER BY created DESC, mid'; } else { $prefix = 'distinct'; $suffix = 'group by mid ORDER BY created DESC'; } if (local_channel()) { $r = q("SELECT {$prefix} mid, item.id as item_id, item.* from item\n\t\t\t\t\tWHERE item_restrict = 0\n\t\t\t\t\tAND ((( `item`.`allow_cid` = '' AND `item`.`allow_gid` = '' AND `item`.`deny_cid` = '' AND `item`.`deny_gid` = '' AND item_private = 0 ) \n\t\t\t\t\tOR ( `item`.`uid` = %d )) OR item.owner_xchan = '%s' )\n\t\t\t\t\t{$sql_extra}\n\t\t\t\t\t{$suffix} {$pager_sql} ", intval(local_channel()), dbesc($sys['xchan_hash'])); } if ($r === null) { $r = q("SELECT {$prefix} mid, item.id as item_id, item.* from item\n\t\t\t\t\tWHERE item_restrict = 0\n\t\t\t\t\tAND (((( `item`.`allow_cid` = '' AND `item`.`allow_gid` = '' AND `item`.`deny_cid` = ''\n\t\t\t\t\tAND `item`.`deny_gid` = '' AND item_private = 0 )\n\t\t\t\t\tand owner_xchan in ( " . stream_perms_xchans($observer ? PERMS_NETWORK | PERMS_PUBLIC : PERMS_PUBLIC) . " ))\n\t\t\t\t\t\t{$pub_sql} ) OR owner_xchan = '%s')\n\t\t\t\t\t{$sql_extra} \n\t\t\t\t\t{$suffix} {$pager_sql}", dbesc($sys['xchan_hash'])); } } else { $r = array(); } } if ($r) { xchan_query($r); $items = fetch_post_tags($r, true); } else { $items = array(); } if ($format == 'json') { $result = array(); require_once 'include/conversation.php'; foreach ($items as $item) { $item['html'] = bbcode($item['body']); $x = encode_item($item); $x['html'] = prepare_text($item['body'], $item['mimetype']); $result[] = $x; } json_return_and_die(array('success' => true, 'messages' => $result)); } if ($tag) { $o .= '<h2>Items tagged with: ' . htmlspecialchars($search, ENT_COMPAT, 'UTF-8') . '</h2>'; } else { $o .= '<h2>Search results for: ' . htmlspecialchars($search, ENT_COMPAT, 'UTF-8') . '</h2>'; } $o .= conversation($a, $items, 'search', $update, 'client'); return $o; }