function post() { if (!local_channel()) { return; } if (\App::$argc != 2) { return; } $contact_id = intval(\App::$argv[1]); $r = q("SELECT * FROM `contact` WHERE `id` = %d AND `uid` = %d LIMIT 1", intval($contact_id), intval(local_channel())); if (!count($r)) { notice(t('Contact not found.') . EOL); return; } $contact = $r[0]; $new_contact = intval($_POST['suggest']); $hash = random_string(); $note = escape_tags(trim($_POST['note'])); if ($new_contact) { $r = q("SELECT * FROM `contact` WHERE `id` = %d AND `uid` = %d LIMIT 1", intval($new_contact), intval(local_channel())); if (count($r)) { $x = q("INSERT INTO `fsuggest` ( `uid`,`cid`,`name`,`url`,`request`,`photo`,`note`,`created`)\n\t\t\t\t\tVALUES ( %d, %d, '%s','%s','%s','%s','%s','%s')", intval(local_channel()), intval($contact_id), dbesc($r[0]['name']), dbesc($r[0]['url']), dbesc($r[0]['request']), dbesc($r[0]['photo']), dbesc($hash), dbesc(datetime_convert())); $r = q("SELECT `id` FROM `fsuggest` WHERE `note` = '%s' AND `uid` = %d LIMIT 1", dbesc($hash), intval(local_channel())); if (count($r)) { $fsuggest_id = $r[0]['id']; q("UPDATE `fsuggest` SET `note` = '%s' WHERE `id` = %d AND `uid` = %d", dbesc($note), intval($fsuggest_id), intval(local_channel())); proc_run('php', 'include/notifier.php', 'suggest', $fsuggest_id); } info(t('Friend suggestion sent.') . EOL); } } }
function user_allow($hash) { $a = get_app(); $register = q("SELECT * FROM `register` WHERE `hash` = '%s' LIMIT 1", dbesc($hash)); if (!count($register)) { return false; } $user = q("SELECT * FROM `user` WHERE `uid` = %d LIMIT 1", intval($register[0]['uid'])); if (!count($user)) { killme(); } $r = q("DELETE FROM `register` WHERE `hash` = '%s'", dbesc($register[0]['hash'])); $r = q("UPDATE `user` SET `blocked` = 0, `verified` = 1 WHERE `uid` = %d", intval($register[0]['uid'])); $r = q("SELECT * FROM `profile` WHERE `uid` = %d AND `is-default` = 1", intval($user[0]['uid'])); if (count($r) && $r[0]['net-publish']) { $url = $a->get_baseurl() . '/profile/' . $user[0]['nickname']; if ($url && strlen(get_config('system', 'directory'))) { proc_run('php', "include/directory.php", "{$url}"); } } push_lang($register[0]['language']); send_register_open_eml($user[0]['email'], $a->config['sitename'], $a->get_baseurl(), $user[0]['username'], $register[0]['password']); pop_lang(); if ($res) { info(t('Account approved.') . EOL); return true; } }
function user_allow($hash) { $a = get_app(); $register = q("SELECT * FROM `register` WHERE `hash` = '%s' LIMIT 1", dbesc($hash)); if (!count($register)) { return false; } $user = q("SELECT * FROM `user` WHERE `uid` = %d LIMIT 1", intval($register[0]['uid'])); if (!count($user)) { killme(); } $r = q("DELETE FROM `register` WHERE `hash` = '%s' LIMIT 1", dbesc($register[0]['hash'])); $r = q("UPDATE `user` SET `blocked` = 0, `verified` = 1 WHERE `uid` = %d LIMIT 1", intval($register[0]['uid'])); $r = q("SELECT * FROM `profile` WHERE `uid` = %d AND `is-default` = 1", intval($user[0]['uid'])); if (count($r) && $r[0]['net-publish']) { $url = $a->get_baseurl() . '/profile/' . $user[0]['nickname']; if ($url && strlen(get_config('system', 'directory_submit_url'))) { proc_run('php', "include/directory.php", "{$url}"); } } push_lang($register[0]['language']); $email_tpl = get_intltext_template("register_open_eml.tpl"); $email_tpl = replace_macros($email_tpl, array('$sitename' => $a->config['sitename'], '$siteurl' => $a->get_baseurl(), '$username' => $user[0]['username'], '$email' => $user[0]['email'], '$password' => $register[0]['password'], '$uid' => $user[0]['uid'])); $res = mail($user[0]['email'], sprintf(t('Registration details for %s'), $a->config['sitename']), $email_tpl, 'From: ' . t('Administrator') . '@' . $_SERVER['SERVER_NAME'] . "\n" . 'Content-type: text/plain; charset=UTF-8' . "\n" . 'Content-transfer-encoding: 8bit'); pop_lang(); if ($res) { info(t('Account approved.') . EOL); return true; } }
function follow_init(&$a) { if (!local_channel()) { return; } $uid = local_channel(); $url = notags(trim($_REQUEST['url'])); $return_url = $_SESSION['return_url']; $confirm = intval($_REQUEST['confirm']); $result = new_contact($uid, $url, $a->get_channel(), true, $confirm); if ($result['success'] == false) { if ($result['message']) { notice($result['message']); } goaway($return_url); } info(t('Channel added.') . EOL); $clone = array(); foreach ($result['abook'] as $k => $v) { if (strpos($k, 'abook_') === 0) { $clone[$k] = $v; } } unset($clone['abook_id']); unset($clone['abook_account']); unset($clone['abook_channel']); build_sync_packet(0, array('abook' => array($clone))); // If we can view their stream, pull in some posts if ($result['abook']['abook_their_perms'] & PERMS_R_STREAM || $result['abook']['xchan_network'] === 'rss') { proc_run('php', 'include/onepoll.php', $result['abook']['abook_id']); } goaway(z_root() . '/connedit/' . $result['abook']['abook_id'] . '?f=&follow=1'); }
/** * @brief * * @param array $argv * @param array $argc */ function directory_run($argv, $argc) { cli_startup(); if ($argc < 2) { return; } $force = false; $pushall = true; if ($argc > 2) { if ($argv[2] === 'force') { $force = true; } if ($argv[2] === 'nopush') { $pushall = false; } } logger('directory update', LOGGER_DEBUG); $dirmode = get_config('system', 'directory_mode'); if ($dirmode === false) { $dirmode = DIRECTORY_MODE_NORMAL; } $x = q("select * from channel where channel_id = %d limit 1", intval($argv[1])); if (!$x) { return; } $channel = $x[0]; if ($dirmode != DIRECTORY_MODE_NORMAL) { // this is an in-memory update and we don't need to send a network packet. local_dir_update($argv[1], $force); q("update channel set channel_dirdate = '%s' where channel_id = %d", dbesc(datetime_convert()), intval($channel['channel_id'])); // Now update all the connections if ($pushall) { proc_run('php', 'include/notifier.php', 'refresh_all', $channel['channel_id']); } return; } // otherwise send the changes upstream $directory = find_upstream_directory($dirmode); $url = $directory['url'] . '/post'; // ensure the upstream directory is updated $packet = zot_build_packet($channel, $force ? 'force_refresh' : 'refresh'); $z = zot_zot($url, $packet); // re-queue if unsuccessful if (!$z['success']) { /** @FIXME we aren't updating channel_dirdate if we have to queue * the directory packet. That means we'll try again on the next poll run. */ $hash = random_string(); q("insert into outq ( outq_hash, outq_account, outq_channel, outq_driver, outq_posturl, outq_async, outq_created, outq_updated, outq_notify, outq_msg ) \n\t\t\tvalues ( '%s', %d, %d, '%s', '%s', %d, '%s', '%s', '%s', '%s' )", dbesc($hash), intval($channel['channel_account_id']), intval($channel['channel_id']), dbesc('zot'), dbesc($url), intval(1), dbesc(datetime_convert()), dbesc(datetime_convert()), dbesc($packet), dbesc('')); } else { q("update channel set channel_dirdate = '%s' where channel_id = %d", dbesc(datetime_convert()), intval($channel['channel_id'])); } // Now update all the connections if ($pushall) { proc_run('php', 'include/notifier.php', 'refresh_all', $channel['channel_id']); } }
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 poormancron_hook(&$a, &$b) { $now = time(); $lastupdate = get_config('poormancron', 'lastupdate'); // 300 secs, 5 mins if (!$lastupdate || $now - $lastupdate > 300) { set_config('poormancron', 'lastupdate', $now); proc_run('php', "include/poller.php"); } }
function cronhooks_run(&$argv, &$argc) { global $a, $db; if (is_null($a)) { $a = new App(); } if (is_null($db)) { @(include ".htconfig.php"); require_once "include/dba.php"; $db = new dba($db_host, $db_user, $db_pass, $db_data); unset($db_host, $db_user, $db_pass, $db_data); } require_once 'include/session.php'; require_once 'include/datetime.php'; require_once 'include/pidfile.php'; load_config('config'); load_config('system'); $maxsysload = intval(get_config('system', 'maxloadavg')); if ($maxsysload < 1) { $maxsysload = 50; } if (function_exists('sys_getloadavg')) { $load = sys_getloadavg(); if (intval($load[0]) > $maxsysload) { logger('system: load ' . $load . ' too high. Poller deferred to next scheduled run.'); return; } } $lockpath = get_lockpath(); if ($lockpath != '') { $pidfile = new pidfile($lockpath, 'cronhooks'); if ($pidfile->is_already_running()) { logger("cronhooks: Already running"); if ($pidfile->running_time() > 19 * 60) { $pidfile->kill(); logger("cronhooks: killed stale process"); // Calling a new instance proc_run('php', 'include/cronhooks.php'); } exit; } } $a->set_baseurl(get_config('system', 'url')); load_hooks(); logger('cronhooks: start'); $d = datetime_convert(); call_hooks('cron', $d); logger('cronhooks: end'); return; }
function frphotos_init(&$a) { if (!local_channel()) { return; } if (intval(get_pconfig(local_channel(), 'frphotos', 'complete'))) { return; } $channel = $a->get_channel(); $fr_server = $_REQUEST['fr_server']; $fr_username = $_REQUEST['fr_username']; $fr_password = $_REQUEST['fr_password']; $cookies = 'store/[data]/frphoto_cookie_' . $channel['channel_address']; if ($fr_server && $fr_username && $fr_password) { $ch = curl_init($fr_server . '/api/friendica/photos/list'); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_COOKIEFILE, $cookies); curl_setopt($ch, CURLOPT_COOKIEJAR, $cookies); curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); curl_setopt($ch, CURLOPT_USERPWD, $fr_username . ':' . $fr_password); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); curl_setopt($ch, CURLOPT_USERAGENT, 'Hubzilla'); $output = curl_exec($ch); curl_close($ch); $j = json_decode($output, true); // echo print_r($j,true); $total = 0; if (count($j)) { foreach ($j as $jj) { $r = q("select uid from photo where resource_id = '%s' and uid = %d limit 1", dbesc($jj), intval($channel['channel_id'])); if ($r) { continue; } $total++; proc_run('php', 'addon/frphotos/frphotohelper.php', $jj, $channel['channel_address'], urlencode($fr_server)); sleep(3); } } if ($total) { set_pconfig(local_channel(), 'frphotos', 'complete', '1'); } @unlink($cookies); goaway(z_root() . '/photos/' . $channel['channel_address']); } }
/** @file */ function locs_post(&$a) { if (!local_channel()) { return; } $channel = $a->get_channel(); if ($_REQUEST['primary']) { $hubloc_id = intval($_REQUEST['primary']); if ($hubloc_id) { $r = q("select hubloc_id from hubloc where hubloc_id = %d and hubloc_hash = '%s' limit 1", intval($hubloc_id), dbesc($channel['channel_hash'])); if (!$r) { notice(t('Location not found.') . EOL); return; } $r = q("update hubloc set hubloc_primary = 0 where hubloc_primary = 1 and hubloc_hash = '%s' ", dbesc($channel['channel_hash'])); $r = q("update hubloc set hubloc_primary = 1 where hubloc_id = %d and hubloc_hash = '%s'", intval($hubloc_id), dbesc($channel['channel_hash'])); proc_run('php', 'include/notifier.php', 'location', $channel['channel_id']); return; } } if ($_REQUEST['drop']) { $hubloc_id = intval($_REQUEST['drop']); if ($hubloc_id) { $r = q("select * from hubloc where hubloc_id = %d and hubloc_url != '%s' and hubloc_hash = '%s' limit 1", intval($hubloc_id), dbesc(z_root()), dbesc($channel['channel_hash'])); if (!$r) { notice(t('Location not found.') . EOL); return; } if (intval($r[0]['hubloc_primary'])) { $x = q("select hubloc_id from hubloc where hubloc_primary = 1 and hubloc_hash = '%s'", dbesc($channel['channel_hash'])); if (!$x) { notice(t('Location lookup failed.')); return; } if (count($x) == 1) { notice(t('Please select another location to become primary before removing the primary location.') . EOL); return; } } $r = q("update hubloc set hubloc_deleted = 1 where hubloc_id = %d and hubloc_hash = '%s'", intval($hubloc_id), dbesc($channel['channel_hash'])); proc_run('php', 'include/notifier.php', 'location', $channel['channel_id']); return; } } }
function user_remove($uid) { if (!$uid) { return; } $a = get_app(); logger('Removing user: '******'remove_user', $r[0]); // save username (actually the nickname as it is guaranteed // unique), so it cannot be re-registered in the future. q("insert into userd ( username ) values ( '%s' )", $r[0]['nickname']); // don't delete yet, will be done later when contacts have deleted my stuff // q("DELETE FROM `contact` WHERE `uid` = %d", intval($uid)); q("DELETE FROM `gcign` WHERE `uid` = %d", intval($uid)); q("DELETE FROM `group` WHERE `uid` = %d", intval($uid)); q("DELETE FROM `group_member` WHERE `uid` = %d", intval($uid)); q("DELETE FROM `intro` WHERE `uid` = %d", intval($uid)); q("DELETE FROM `event` WHERE `uid` = %d", intval($uid)); q("DELETE FROM `item` WHERE `uid` = %d", intval($uid)); q("DELETE FROM `item_id` WHERE `uid` = %d", intval($uid)); q("DELETE FROM `mail` WHERE `uid` = %d", intval($uid)); q("DELETE FROM `mailacct` WHERE `uid` = %d", intval($uid)); q("DELETE FROM `manage` WHERE `uid` = %d", intval($uid)); q("DELETE FROM `notify` WHERE `uid` = %d", intval($uid)); q("DELETE FROM `photo` WHERE `uid` = %d", intval($uid)); q("DELETE FROM `attach` WHERE `uid` = %d", intval($uid)); q("DELETE FROM `profile` WHERE `uid` = %d", intval($uid)); q("DELETE FROM `profile_check` WHERE `uid` = %d", intval($uid)); q("DELETE FROM `pconfig` WHERE `uid` = %d", intval($uid)); q("DELETE FROM `search` WHERE `uid` = %d", intval($uid)); q("DELETE FROM `spam` WHERE `uid` = %d", intval($uid)); // don't delete yet, will be done later when contacts have deleted my stuff // q("DELETE FROM `user` WHERE `uid` = %d", intval($uid)); q("UPDATE `user` SET `account_removed` = 1, `account_expires_on` = UTC_TIMESTAMP() WHERE `uid` = %d", intval($uid)); proc_run('php', "include/notifier.php", "removeme", $uid); // Send an update to the directory proc_run('php', "include/directory.php", $r[0]['url']); if ($uid == local_user()) { unset($_SESSION['authenticated']); unset($_SESSION['uid']); goaway($a->get_baseurl()); } }
function remove_obsolete_hublocs() { logger('remove_obsolete_hublocs', LOGGER_DEBUG); // Get rid of any hublocs which are ours but aren't valid anymore - // e.g. they point to a different and perhaps transient URL that we aren't using. // I need to stress that this shouldn't happen. fix_system_urls() fixes hublocs // when it discovers the URL has changed. So it's unclear how we could end up // with URLs pointing to the old site name. But it happens. This may be an artifact // of an old bug or maybe a regression in some newer code. In any event, they // mess up communications and we have to take action if we find any. // First make sure we have any hublocs (at all) with this URL and sitekey. // We don't want to perform this operation while somebody is in the process // of renaming their hub or installing certs. $r = q("select hubloc_id from hubloc where hubloc_url = '%s' and hubloc_sitekey = '%s'", dbesc(z_root()), dbesc(get_config('system', 'pubkey'))); if (!$r || !count($r)) { return; } $channels = array(); // Good. We have at least one *valid* hubloc. // Do we have any invalid ones? $r = q("select hubloc_id from hubloc where hubloc_sitekey = '%s' and hubloc_url != '%s'", dbesc(get_config('system', 'pubkey')), dbesc(z_root())); $p = q("select hubloc_id from hubloc where hubloc_sitekey != '%s' and hubloc_url = '%s'", dbesc(get_config('system', 'pubkey')), dbesc(z_root())); if (is_array($r) && is_array($p)) { $r = array_merge($r, $p); } if (!$r) { return; } // We've got invalid hublocs. Get rid of them. logger('remove_obsolete_hublocs: removing ' . count($r) . ' hublocs.'); $interval = get_config('system', 'delivery_interval') !== false ? intval(get_config('system', 'delivery_interval')) : 2; foreach ($r as $rr) { q("update hubloc set hubloc_flags = (hubloc_flags | %d) where hubloc_id = %d", intval(HUBLOC_FLAGS_DELETED), intval($rr['hubloc_id'])); $x = q("select channel_id from channel where channel_hash = '%s' limit 1", dbesc($rr['hubloc_hash'])); if ($x) { proc_run('php', 'include/notifier.php', 'location', $x[0]['channel_id']); if ($interval) { @time_sleep_until(microtime(true) + (double) $interval); } } } }
function pumpio_sync_run(&$argv, &$argc) { global $a, $db; if (is_null($a)) { $a = new App(); } if (is_null($db)) { @(include ".htconfig.php"); require_once "include/dba.php"; $db = new dba($db_host, $db_user, $db_pass, $db_data); unset($db_host, $db_user, $db_pass, $db_data); } require_once "addon/pumpio/pumpio.php"; require_once "include/pidfile.php"; $maxsysload = intval(get_config('system', 'maxloadavg')); if ($maxsysload < 1) { $maxsysload = 50; } if (function_exists('sys_getloadavg')) { $load = sys_getloadavg(); if (intval($load[0]) > $maxsysload) { logger('system: load ' . $load[0] . ' too high. Pumpio sync deferred to next scheduled run.'); return; } } $lockpath = get_lockpath(); if ($lockpath != '') { $pidfile = new pidfile($lockpath, 'pumpio_sync'); if ($pidfile->is_already_running()) { logger("Already running"); if ($pidfile->running_time() > 9 * 60) { $pidfile->kill(); logger("killed stale process"); // Calling a new instance proc_run('php', 'addon/pumpio/pumpio_sync.php'); } exit; } } pumpio_sync($a); }
function init() { if (!local_channel()) { return; } $uid = local_channel(); $url = notags(trim($_REQUEST['url'])); $return_url = $_SESSION['return_url']; $confirm = intval($_REQUEST['confirm']); $channel = \App::get_channel(); // Warning: Do not edit the following line. The first symbol is UTF-8 @ $url = str_replace('@', '@', $url); $result = new_contact($uid, $url, $channel, true, $confirm); if ($result['success'] == false) { if ($result['message']) { notice($result['message']); } goaway($return_url); } info(t('Channel added.') . EOL); $clone = array(); foreach ($result['abook'] as $k => $v) { if (strpos($k, 'abook_') === 0) { $clone[$k] = $v; } } unset($clone['abook_id']); unset($clone['abook_account']); unset($clone['abook_channel']); $abconfig = load_abconfig($channel['channel_hash'], $clone['abook_xchan']); if ($abconfig) { $clone['abconfig'] = $abconfig; } build_sync_packet(0, array('abook' => array($clone))); // If we can view their stream, pull in some posts if ($result['abook']['abook_their_perms'] & PERMS_R_STREAM || $result['abook']['xchan_network'] === 'rss') { proc_run('php', 'include/onepoll.php', $result['abook']['abook_id']); } goaway(z_root() . '/connedit/' . $result['abook']['abook_id'] . '?f=&follow=1'); }
function pubsubpublish_run(&$argv, &$argc) { global $a, $db; if (is_null($a)) { $a = new App(); } if (is_null($db)) { @(include ".htconfig.php"); require_once "include/dba.php"; $db = new dba($db_host, $db_user, $db_pass, $db_data); unset($db_host, $db_user, $db_pass, $db_data); } require_once 'include/items.php'; require_once 'include/pidfile.php'; load_config('config'); load_config('system'); $lockpath = get_lockpath(); if ($lockpath != '') { $pidfile = new pidfile($lockpath, 'pubsubpublish'); if ($pidfile->is_already_running()) { logger("Already running"); if ($pidfile->running_time() > 9 * 60) { $pidfile->kill(); logger("killed stale process"); // Calling a new instance proc_run('php', "include/pubsubpublish.php"); } return; } } $a->set_baseurl(get_config('system', 'url')); load_hooks(); if ($argc > 1) { $pubsubpublish_id = intval($argv[1]); } else { $pubsubpublish_id = 0; } handle_pubsubhubbub(); return; }
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)); }
/** @file */ function locs_post(&$a) { if (!local_channel()) { return; } $channel = $a->get_channel(); if ($_REQUEST['primary']) { $hubloc_id = intval($_REQUEST['primary']); if ($hubloc_id) { $r = q("select hubloc_id from hubloc where hubloc_id = %d and hubloc_hash = '%s' limit 1", intval($hubloc_id), dbesc($channel['channel_hash'])); if (!$r) { notice(t('Location not found.') . EOL); return; } $r = q("update hubloc set hubloc_flags = (hubloc_flags - %d) where (hubloc_flags & %d)>0 and hubloc_hash = '%s' ", intval(HUBLOC_FLAGS_PRIMARY), intval(HUBLOC_FLAGS_PRIMARY), dbesc($channel['channel_hash'])); $r = q("update hubloc set hubloc_flags = (hubloc_flags | %d) where hubloc_id = %d and hubloc_hash = '%s'", intval(HUBLOC_FLAGS_PRIMARY), intval($hubloc_id), dbesc($channel['channel_hash'])); proc_run('php', 'include/notifier.php', 'location', $channel['channel_id']); return; } } if ($_REQUEST['drop']) { $hubloc_id = intval($_REQUEST['drop']); if ($hubloc_id) { $r = q("select hubloc_id, hubloc_flags from hubloc where hubloc_id = %d and hubloc_url != '%s' and hubloc_hash = '%s' limit 1", intval($hubloc_id), dbesc(z_root()), dbesc($channel['channel_hash'])); if (!$r) { notice(t('Location not found.') . EOL); return; } if ($r[0]['hubloc_flags'] & HUBLOC_FLAGS_PRIMARY) { notice(t('Primary location cannot be removed.') . EOL); return; } $r = q("update hubloc set hubloc_flags = (hubloc_flags | %d) where hubloc_id = %d and hubloc_hash = '%s'", intval(HUBLOC_FLAGS_DELETED), intval($hubloc_id), dbesc($channel['channel_hash'])); proc_run('php', 'include/notifier.php', 'location', $channel['channel_id']); return; } } }
function follow_init(&$a) { if (!local_channel()) { return; } $uid = local_channel(); $url = notags(trim($_REQUEST['url'])); $return_url = $_SESSION['return_url']; $confirm = intval($_REQUEST['confirm']); $result = new_contact($uid, $url, $a->get_channel(), true, $confirm); if ($result['success'] == false) { if ($result['message']) { notice($result['message']); } goaway($return_url); } info(t('Channel added.') . EOL); // If we can view their stream, pull in some posts if ($result['abook']['abook_their_perms'] & PERMS_R_STREAM || $result['abook']['xchan_network'] === 'rss') { proc_run('php', 'include/onepoll.php', $result['abook']['abook_id']); } goaway(z_root() . '/connedit/' . $result['abook']['abook_id'] . '?f=&follow=1'); }
function connect_post(&$a) { if (!array_key_exists('channel', $a->data)) { return; } $edit = local_user() && local_user() == $a->data['channel']['channel_id'] ? true : false; if ($edit) { $has_premium = $a->data['channel']['channel_pageflags'] & PAGE_PREMIUM ? 1 : 0; $premium = $_POST['premium'] ? intval($_POST['premium']) : 0; $text = escape_tags($_POST['text']); if ($has_premium != $premium) { $r = q("update channel set channel_pageflags = ( channel_pageflags ^ %d ) where channel_id = %d limit 1", intval(PAGE_PREMIUM), intval(local_user())); proc_run('php', 'include/notifier.php', 'refresh_all', $a->data['channel']['channel_id']); } set_pconfig($a->data['channel']['channel_id'], 'system', 'selltext', $text); // reload the page completely to get fresh data goaway(z_root() . '/' . $a->query_string); } $url = ''; $observer = $a->get_observer(); if ($observer && $_POST['submit'] === t('Continue')) { if ($observer['xchan_follow']) { $url = sprintf($observer['xchan_follow'], urlencode($a->data['channel']['channel_address'] . '@' . $a->get_hostname())); } if (!$url) { $r = q("select * from hubloc where hubloc_hash = '%s' order by hubloc_id desc limit 1", dbesc($observer['xchan_hash'])); if ($r) { $url = $r[0]['hubloc_url'] . '/follow?f=&url=' . urlencode($a->data['channel']['channel_address'] . '@' . $a->get_hostname()); } } } if ($url) { goaway($url . '&confirm=1'); } else { notice('Unable to connect to your home hub location.'); } }
function get() { if (!local_channel()) { notice(t('Permission denied.') . EOL); return; } $channel = \App::get_channel(); if ($_REQUEST['sync']) { proc_run('php', 'include/notifier.php', 'location', $channel['channel_id']); info(t('Syncing locations') . EOL); goaway(z_root() . '/locs'); } $r = q("select * from hubloc where hubloc_hash = '%s'", dbesc($channel['channel_hash'])); if (!$r) { notice(t('No locations found.') . EOL); return; } for ($x = 0; $x < count($r); $x++) { $r[$x]['primary'] = intval($r[$x]['hubloc_primary']) ? true : false; $r[$x]['deleted'] = intval($r[$x]['hubloc_deleted']) ? true : false; } $o = replace_macros(get_markup_template('locmanage.tpl'), array('$header' => t('Manage Channel Locations'), '$loc' => t('Location'), '$addr' => t('Address'), '$mkprm' => t('Primary'), '$drop' => t('Drop'), '$submit' => t('Submit'), '$sync' => t('Sync Now'), '$sync_text' => t('Please wait several minutes between consecutive operations.'), '$drop_text' => t('When possible, drop a location by logging into that website/hub and removing your channel.'), '$last_resort' => t('Use this form to drop the location if the hub is no longer operating.'), '$hubs' => $r)); return $o; }
function profile_photo_content(&$a) { if (!local_channel()) { notice(t('Permission denied.') . EOL); return; } $channel = App::get_channel(); $newuser = false; if (argc() == 2 && argv(1) === 'new') { $newuser = true; } if (argv(1) === 'use') { if (argc() < 3) { notice(t('Permission denied.') . EOL); return; } // check_form_security_token_redirectOnErr('/profile_photo', 'profile_photo'); $resource_id = argv(2); $r = q("SELECT id, album, scale FROM photo WHERE uid = %d AND resource_id = '%s' ORDER BY scale ASC", intval(local_channel()), dbesc($resource_id)); if (!$r) { notice(t('Photo not available.') . EOL); return; } $havescale = false; foreach ($r as $rr) { if ($rr['scale'] == 5) { $havescale = true; } } // set an already loaded photo as profile photo if ($r[0]['album'] == t('Profile Photos') && $havescale) { // unset any existing profile photos $r = q("UPDATE photo SET photo_usage = %d WHERE photo_usage = %d AND uid = %d", intval(PHOTO_NORMAL), intval(PHOTO_PROFILE), intval(local_channel())); $r = q("UPDATE photo SET photo_usage = %d WHERE uid = %d AND resource_id = '%s'", intval(PHOTO_PROFILE), intval(local_channel()), dbesc($resource_id)); $r = q("UPDATE xchan set xchan_photo_date = '%s' \n\t\t\t\twhere xchan_hash = '%s'", dbesc(datetime_convert()), dbesc($channel['xchan_hash'])); profile_photo_set_profile_perms(); //Reset default photo permissions to public proc_run('php', 'include/directory.php', local_channel()); goaway(z_root() . '/profiles'); } $r = q("SELECT `data`, `type`, resource_id, os_storage FROM photo WHERE id = %d and uid = %d limit 1", intval($r[0]['id']), intval(local_channel())); if (!$r) { notice(t('Photo not available.') . EOL); return; } if (intval($r[0]['os_storage'])) { $data = @file_get_contents($r[0]['data']); } else { $data = dbunescbin($r[0]['data']); } $ph = photo_factory($data, $r[0]['type']); $smallest = 0; if ($ph->is_valid()) { // go ahead as if we have just uploaded a new photo to crop $i = q("select resource_id, scale from photo where resource_id = '%s' and uid = %d order by scale", dbesc($r[0]['resource_id']), intval(local_channel())); if ($i) { $hash = $i[0]['resource_id']; foreach ($i as $ii) { if (intval($ii['scale']) < 2) { $smallest = intval($ii['scale']); } } } } profile_photo_crop_ui_head($a, $ph, $hash, $smallest); } $profiles = q("select id, profile_name as name, is_default from profile where uid = %d", intval(local_channel())); if (!x(App::$data, 'imagecrop')) { $tpl = get_markup_template('profile_photo.tpl'); $o .= replace_macros($tpl, array('$user' => App::$channel['channel_address'], '$lbl_upfile' => t('Upload File:'), '$lbl_profiles' => t('Select a profile:'), '$title' => t('Upload Profile Photo'), '$submit' => t('Upload'), '$profiles' => $profiles, '$single' => count($profiles) == 1 ? true : false, '$profile0' => $profiles[0], '$form_security_token' => get_form_security_token("profile_photo"), '$select' => sprintf('%s %s', t('or'), $newuser ? '<a href="' . z_root() . '">' . t('skip this step') . '</a>' : '<a href="' . z_root() . '/photos/' . App::$channel['channel_address'] . '">' . t('select a photo from your photo albums') . '</a>'))); call_hooks('profile_photo_content_end', $o); return $o; } else { $filename = App::$data['imagecrop'] . '-' . App::$data['imagecrop_resolution']; $resolution = App::$data['imagecrop_resolution']; $tpl = get_markup_template("cropbody.tpl"); $o .= replace_macros($tpl, array('$filename' => $filename, '$profile' => intval($_REQUEST['profile']), '$resource' => App::$data['imagecrop'] . '-' . App::$data['imagecrop_resolution'], '$image_url' => z_root() . '/photo/' . $filename, '$title' => t('Crop Image'), '$desc' => t('Please adjust the image cropping for optimum viewing.'), '$form_security_token' => get_form_security_token("profile_photo"), '$done' => t('Done Editing'))); return $o; } return; // NOTREACHED }
function diaspora_signed_retraction($importer, $xml, $msg) { $guid = notags(unxmlify($xml->target_guid)); $diaspora_handle = notags(unxmlify($xml->sender_handle)); $type = notags(unxmlify($xml->target_type)); $sig = notags(unxmlify($xml->target_author_signature)); $parent_author_signature = $xml->parent_author_signature ? notags(unxmlify($xml->parent_author_signature)) : ''; $contact = diaspora_get_contact_by_handle($importer['uid'], $diaspora_handle); if (!$contact) { logger('diaspora_signed_retraction: no contact ' . $diaspora_handle . ' for ' . $importer['uid']); return; } $signed_data = $guid . ';' . $type; $key = $msg['key']; /* How Diaspora performs relayable_retraction signature checking: - If an item has been sent by the item author to the top-level post owner to relay on to the rest of the contacts on the top-level post, the top-level post owner checks the author_signature, then creates a parent_author_signature before relaying the item on - If an item has been relayed on by the top-level post owner, the contacts who receive it check only the parent_author_signature. Basically, they trust that the top-level post owner has already verified the authenticity of anything he/she sends out - In either case, the signature that get checked is the signature created by the person who sent the salmon */ if ($parent_author_signature) { $parent_author_signature = base64_decode($parent_author_signature); if (!rsa_verify($signed_data, $parent_author_signature, $key, 'sha256')) { logger('diaspora_signed_retraction: top-level post owner verification failed'); return; } } else { $sig_decode = base64_decode($sig); if (!rsa_verify($signed_data, $sig_decode, $key, 'sha256')) { logger('diaspora_signed_retraction: retraction owner verification failed.' . print_r($msg, true)); return; } } if ($type === 'StatusMessage' || $type === 'Comment' || $type === 'Like') { $r = q("select * from item where guid = '%s' and uid = %d and not file like '%%[%%' limit 1", dbesc($guid), intval($importer['uid'])); if (count($r)) { if (link_compare($r[0]['author-link'], $contact['url'])) { q("update item set `deleted` = 1, `edited` = '%s', `changed` = '%s', `body` = '' , `title` = '' where `id` = %d", dbesc(datetime_convert()), dbesc(datetime_convert()), intval($r[0]['id'])); delete_thread($r[0]['id'], $r[0]['parent-uri']); // Now check if the retraction needs to be relayed by us // // The first item in the `item` table with the parent id is the parent. However, MySQL doesn't always // return the items ordered by `item`.`id`, in which case the wrong item is chosen as the parent. // The only item with `parent` and `id` as the parent id is the parent item. $p = q("select origin from item where parent = %d and id = %d limit 1", $r[0]['parent'], $r[0]['parent']); if (count($p)) { if ($p[0]['origin'] && !$parent_author_signature) { q("insert into sign (`retract_iid`,`signed_text`,`signature`,`signer`) values (%d,'%s','%s','%s') ", $r[0]['id'], dbesc($signed_data), dbesc($sig), dbesc($diaspora_handle)); // the existence of parent_author_signature would have meant the parent_author or owner // is already relaying. logger('diaspora_signed_retraction: relaying relayable_retraction'); proc_run('php', 'include/notifier.php', 'drop', $r[0]['id']); } } } } } else { logger('diaspora_signed_retraction: unknown type: ' . $type); } return 202; // NOTREACHED }
/** * @brief Process a message request. * * If a site receives a comment to a post but finds they have no parent to attach it with, they * may send a 'request' packet containing the message_id of the missing parent. This is the handler * for that packet. We will create a message_list array of the entire conversation starting with * the missing parent and invoke delivery to the sender of the packet. * * include/deliver.php (for local delivery) and mod/post.php (for web delivery) detect the existence of * this 'message_list' at the destination and split it into individual messages which are * processed/delivered in order. * * Called from mod/post.php * * @param array $data * @return array */ function zot_process_message_request($data) { $ret = array('success' => false); if (!$data['message_id']) { $ret['message'] = 'no message_id'; logger('no message_id'); return $ret; } $sender = $data['sender']; $sender_hash = make_xchan_hash($sender['guid'], $sender['guid_sig']); /* * Find the local channel in charge of this post (the first and only recipient of the request packet) */ $arr = $data['recipients'][0]; $recip_hash = make_xchan_hash($arr['guid'], $arr['guid_sig']); $c = q("select * from channel left join xchan on channel_hash = xchan_hash where channel_hash = '%s' limit 1", dbesc($recip_hash)); if (!$c) { logger('recipient channel not found.'); $ret['message'] .= 'recipient not found.' . EOL; return $ret; } /* * fetch the requested conversation */ $messages = zot_feed($c[0]['channel_id'], $sender_hash, array('message_id' => $data['message_id'])); if ($messages) { $env_recips = null; $r = q("select * from hubloc where hubloc_hash = '%s' and not hubloc_error and not hubloc_deleted \n\t\t\tgroup by hubloc_sitekey", dbesc($sender_hash)); if (!$r) { logger('no hubs'); return $ret; } $hubs = $r; $private = array_key_exists('flags', $messages[0]) && in_array('private', $messages[0]['flags']) ? true : false; if ($private) { $env_recips = array('guid' => $sender['guid'], 'guid_sig' => $sender['guid_sig'], 'hash' => $sender_hash); } $data_packet = json_encode(array('message_list' => $messages)); foreach ($hubs as $hub) { $hash = random_string(); /* * create a notify packet and drop the actual message packet in the queue for pickup */ $n = zot_build_packet($c[0], 'notify', $env_recips, $private ? $hub['hubloc_sitekey'] : null, $hash, array('message_id' => $data['message_id'])); q("insert into outq ( outq_hash, outq_account, outq_channel, outq_driver, outq_posturl, outq_async,\n\t\t\t\toutq_created, outq_updated, outq_notify, outq_msg )\n\t\t\t\tvalues ( '%s', %d, %d, '%s', '%s', %d, '%s', '%s', '%s', '%s' )", dbesc($hash), intval($c[0]['channel_account_id']), intval($c[0]['channel_id']), dbesc('zot'), dbesc($hub['hubloc_callback']), intval(1), dbesc(datetime_convert()), dbesc(datetime_convert()), dbesc($n), dbesc($data_packet)); /* * invoke delivery to send out the notify packet */ proc_run('php', 'include/deliver.php', $hash); } } $ret['success'] = true; return $ret; }
function drop_item($id, $interactive = true, $stage = DROPITEM_NORMAL, $force = false) { $a = get_app(); // locate item to be deleted $r = q("SELECT * FROM item WHERE id = %d LIMIT 1", intval($id)); if (!$r || $r[0]['item_restrict'] & ITEM_DELETED && $stage === DROPITEM_NORMAL) { if (!$interactive) { return 0; } notice(t('Item not found.') . EOL); goaway($a->get_baseurl() . '/' . $_SESSION['return_url']); } $item = $r[0]; $linked_item = $item['resource_id'] ? true : false; $ok_to_delete = false; // system deletion if (!$interactive) { $ok_to_delete = true; } // owner deletion if (local_channel() && local_channel() == $item['uid']) { $ok_to_delete = true; } // sys owned item, requires site admin to delete $sys = get_sys_channel(); if (is_site_admin() && $sys['channel_id'] == $item['uid']) { $ok_to_delete = true; } // author deletion $observer = $a->get_observer(); if ($observer && $observer['xchan_hash'] && $observer['xchan_hash'] === $item['author_xchan']) { $ok_to_delete = true; } if ($ok_to_delete) { // set the deleted flag immediately on this item just in case the // hook calls a remote process which loops. We'll delete it properly in a second. $r = q("UPDATE item SET item_restrict = ( item_restrict | %d ) WHERE id = %d", intval($linked_item && !$force ? ITEM_HIDDEN : ITEM_DELETED), intval($item['id'])); $arr = array('item' => $item, 'interactive' => $interactive, 'stage' => $stage); call_hooks('drop_item', $arr); $notify_id = intval($item['id']); $items = q("select * from item where parent = %d and uid = %d", intval($item['id']), intval($item['uid'])); if ($items) { foreach ($items as $i) { delete_item_lowlevel($i, $stage, $force); } } else { delete_item_lowlevel($item, $stage, $force); } if (!$interactive) { return 1; } // send the notification upstream/downstream as the case may be // only send notifications to others if this is the owner's wall item. // This isn't optimal. We somehow need to pass to this function whether or not // to call the notifier, or we need to call the notifier from the calling function. // We'll rely on the undocumented behaviour that DROPITEM_PHASE1 is (hopefully) only // set if we know we're going to send delete notifications out to others. if ($item['item_flags'] & ITEM_WALL && $stage != DROPITEM_PHASE2 || $stage == DROPITEM_PHASE1) { proc_run('php', 'include/notifier.php', 'drop', $notify_id); } goaway($a->get_baseurl() . '/' . $_SESSION['return_url']); } else { if (!$interactive) { return 0; } notice(t('Permission denied.') . EOL); goaway($a->get_baseurl() . '/' . $_SESSION['return_url']); } }
/** * @brief * * If somebody arrives at our site using a zid, add their xchan to our DB if we don't have it already. * And if they aren't already authenticated here, attempt reverse magic auth. * * @param App &$a * * @hooks 'zid_init' * string 'zid' - their zid * string 'url' - the destination url */ function zid_init(&$a) { $tmp_str = get_my_address(); if (validate_email($tmp_str)) { proc_run('php', 'include/gprobe.php', bin2hex($tmp_str)); $arr = array('zid' => $tmp_str, 'url' => $a->cmd); call_hooks('zid_init', $arr); if (!local_channel()) { $r = q("select * from hubloc where hubloc_addr = '%s' order by hubloc_connected desc limit 1", dbesc($tmp_str)); if ($r && remote_channel() && remote_channel() === $r[0]['hubloc_hash']) { return; } logger('zid_init: not authenticated. Invoking reverse magic-auth for ' . $tmp_str); // try to avoid recursion - but send them home to do a proper magic auth $query = $a->query_string; $query = str_replace(array('?zid=', '&zid='), array('?rzid=', '&rzid='), $query); $dest = '/' . urlencode($query); if ($r && $r[0]['hubloc_url'] != z_root() && !strstr($dest, '/magic') && !strstr($dest, '/rmagic')) { goaway($r[0]['hubloc_url'] . '/magic' . '?f=&rev=1&dest=' . z_root() . $dest); } else { logger('zid_init: no hubloc found.'); } } } }
function tagger_content(&$a) { if (!local_user() && !remote_user()) { return; } $term = notags(trim($_GET['term'])); // no commas allowed $term = str_replace(array(',', ' '), array('', '_'), $term); if (!$term) { return; } $item_id = $a->argc > 1 ? notags(trim($a->argv[1])) : 0; logger('tagger: tag ' . $term . ' item ' . $item_id); $r = q("SELECT * FROM `item` WHERE `id` = '%s' LIMIT 1", dbesc($item_id)); if (!$item_id || !count($r)) { logger('tagger: no item ' . $item_id); return; } $item = $r[0]; $owner_uid = $item['uid']; $r = q("select `nickname`,`blocktags` from user where uid = %d limit 1", intval($owner_uid)); if (count($r)) { $owner_nick = $r[0]['nickname']; $blocktags = $r[0]['blocktags']; } if (local_user() != $owner_uid) { return; } if (remote_user()) { $r = q("select * from contact where id = %d AND `uid` = %d limit 1", intval(remote_user()), intval($item['uid'])); } else { $r = q("select * from contact where self = 1 and uid = %d limit 1", intval(local_user())); } if (count($r)) { $contact = $r[0]; } else { logger('tagger: no contact_id'); return; } $uri = item_new_uri($a->get_hostname(), $owner_uid); $post_type = $item['resource-id'] ? t('photo') : t('status'); $targettype = $item['resource-id'] ? ACTIVITY_OBJ_PHOTO : ACTIVITY_OBJ_NOTE; $link = xmlify('<link rel="alternate" type="text/html" href="' . $a->get_baseurl() . '/display/' . $owner['nickname'] . '/' . $item['id'] . '" />' . "\n"); $body = $item['body']; $target = <<<EOT \t<target> \t\t<type>{$targettype}</type> \t\t<local>1</local> \t\t<id>{$item['uri']}</id> \t\t<link>{$link}</link> \t\t<title></title> \t\t<content>{$body}</content> \t</target> EOT; $tagid = $a->get_baseurl() . '/search?search=' . $term; $objtype = ACTIVITY_OBJ_TAGTERM; $obj = <<<EOT \t<object> \t\t<type>{$objtype}</type> \t\t<local>1</local> \t\t<id>{$tagid}</id> \t\t<link>{$tagid}</link> \t\t<title>{$term}</title> \t\t<content>{$term}</content> \t</object> EOT; $bodyverb = t('%1$s tagged %2$s\'s %3$s with %4$s'); if (!isset($bodyverb)) { return; } $termlink = html_entity_decode('⌗') . '[url=' . $a->get_baseurl() . '/search?search=' . urlencode($term) . ']' . $term . '[/url]'; $arr = array(); $arr['uri'] = $uri; $arr['uid'] = $owner_uid; $arr['contact-id'] = $contact['id']; $arr['type'] = 'activity'; $arr['wall'] = $item['wall']; $arr['gravity'] = GRAVITY_COMMENT; $arr['parent'] = $item['id']; $arr['parent-uri'] = $item['uri']; $arr['owner-name'] = $item['author-name']; $arr['owner-link'] = $item['author-link']; $arr['owner-avatar'] = $item['author-avatar']; $arr['author-name'] = $contact['name']; $arr['author-link'] = $contact['url']; $arr['author-avatar'] = $contact['thumb']; $ulink = '[url=' . $contact['url'] . ']' . $contact['name'] . '[/url]'; $alink = '[url=' . $item['author-link'] . ']' . $item['author-name'] . '[/url]'; $plink = '[url=' . $item['plink'] . ']' . $post_type . '[/url]'; $arr['body'] = sprintf($bodyverb, $ulink, $alink, $plink, $termlink); $arr['verb'] = ACTIVITY_TAG; $arr['target-type'] = $targettype; $arr['target'] = $target; $arr['object-type'] = $objtype; $arr['object'] = $obj; $arr['allow_cid'] = $item['allow_cid']; $arr['allow_gid'] = $item['allow_gid']; $arr['deny_cid'] = $item['deny_cid']; $arr['deny_gid'] = $item['deny_gid']; $arr['visible'] = 1; $arr['unseen'] = 1; $arr['last-child'] = 1; $arr['origin'] = 1; $post_id = item_store($arr); q("UPDATE `item` set plink = '%s' where id = %d limit 1", dbesc($a->get_baseurl() . '/display/' . $owner_nick . '/' . $post_id), intval($post_id)); if (!$item['visible']) { $r = q("UPDATE `item` SET `visible` = 1 WHERE `id` = %d AND `uid` = %d LIMIT 1", intval($item['id']), intval($owner_uid)); } if (!$blocktags && !stristr($item['tag'], ']' . $term . '[')) { q("update item set tag = '%s' where id = %d limit 1", dbesc($item['tag'] . (strlen($item['tag']) ? ',' : '') . '#[url=' . $a->get_baseurl() . '/search?search=' . $term . ']' . $term . '[/url]'), intval($item['id'])); } // if the original post is on this site, update it. $r = q("select `tag`,`id`,`uid` from item where `origin` = 1 AND `uri` = '%s' LIMIT 1", dbesc($item['uri'])); if (count($r)) { $x = q("SELECT `blocktags` FROM `user` WHERE `uid` = %d limit 1", intval($r[0]['uid'])); if (count($x) && !$x[0]['blocktags'] && !stristr($r[0]['tag'], ']' . $term . '[')) { q("update item set tag = '%s' where id = %d limit 1", dbesc($r[0]['tag'] . (strlen($r[0]['tag']) ? ',' : '') . '#[url=' . $a->get_baseurl() . '/search?search=' . $term . ']' . $term . '[/url]'), intval($r[0]['id'])); } } $arr['id'] = $post_id; call_hooks('post_local_end', $arr); proc_run('php', "include/notifier.php", "tag", "{$post_id}"); killme(); return; // NOTREACHED }
function connections_post(&$a) { if (!local_channel()) { return; } $contact_id = intval(argv(1)); if (!$contact_id) { return; } $orig_record = q("SELECT * FROM abook WHERE abook_id = %d AND abook_channel = %d LIMIT 1", intval($contact_id), intval(local_channel())); if (!$orig_record) { notice(t('Could not access contact record.') . EOL); goaway(z_root() . '/connections'); return; // NOTREACHED } call_hooks('contact_edit_post', $_POST); $profile_id = $_POST['profile_assign']; if ($profile_id) { $r = q("SELECT profile_guid FROM profile WHERE profile_guid = '%s' AND `uid` = %d LIMIT 1", dbesc($profile_id), intval(local_channel())); if (!count($r)) { notice(t('Could not locate selected profile.') . EOL); return; } } $hidden = intval($_POST['hidden']); $priority = intval($_POST['poll']); if ($priority > 5 || $priority < 0) { $priority = 0; } $closeness = intval($_POST['closeness']); if ($closeness < 0) { $closeness = 99; } $abook_my_perms = 0; foreach ($_POST as $k => $v) { if (strpos($k, 'perms_') === 0) { $abook_my_perms += $v; } } $abook_flags = $orig_record[0]['abook_flags']; $new_friend = false; if ($_REQUEST['pending'] && $abook_flags & ABOOK_FLAG_PENDING) { $abook_flags = $abook_flags ^ ABOOK_FLAG_PENDING; $new_friend = true; } $r = q("UPDATE abook SET abook_profile = '%s', abook_my_perms = %d , abook_closeness = %d, abook_flags = %d\n\t\twhere abook_id = %d AND abook_channel = %d", dbesc($profile_id), intval($abook_my_perms), intval($closeness), intval($abook_flags), intval($contact_id), intval(local_channel())); if ($r) { info(t('Connection updated.') . EOL); } else { notice(t('Failed to update connection record.') . EOL); } if (x($a->data, 'abook') && $a->data['abook']['abook_my_perms'] != $abook_my_perms && !($a->data['abook']['abook_flags'] & ABOOK_FLAG_SELF)) { proc_run('php', 'include/notifier.php', 'permission_update', $contact_id); } if ($new_friend) { $channel = $a->get_channel(); $default_group = $channel['channel_default_group']; if ($default_group) { require_once 'include/group.php'; $g = group_rec_byhash(local_channel(), $default_group); if ($g) { group_add_member(local_channel(), '', $a->data['abook_xchan'], $g['id']); } } // Check if settings permit ("post new friend activity" is allowed, and // friends in general or this friend in particular aren't hidden) // and send out a new friend activity // TODO // pull in a bit of content if there is any to pull in proc_run('php', 'include/onepoll.php', $contact_id); } // Refresh the structure in memory with the new data $r = q("SELECT abook.*, xchan.* \n\t\tFROM abook left join xchan on abook_xchan = xchan_hash\n\t\tWHERE abook_channel = %d and abook_id = %d LIMIT 1", intval(local_channel()), intval($contact_id)); if ($r) { $a->data['abook'] = $r[0]; } if ($new_friend) { $arr = array('channel_id' => local_channel(), 'abook' => $a->data['abook']); call_hooks('accept_follow', $arr); } connections_clone($a); return; }
function like_content(&$a) { if (!local_user() && !remote_user()) { return; } $verb = notags(trim($_GET['verb'])); if (!$verb) { $verb = 'like'; } switch ($verb) { case 'like': case 'unlike': $activity = ACTIVITY_LIKE; break; case 'dislike': case 'undislike': $activity = ACTIVITY_DISLIKE; break; case 'attendyes': case 'unattendyes': $activity = ACTIVITY_ATTEND; break; case 'attendno': case 'unattendno': $activity = ACTIVITY_ATTENDNO; break; case 'attendmaybe': case 'unattendmaybe': $activity = ACTIVITY_ATTENDMAYBE; break; default: return; break; } $item_id = $a->argc > 1 ? notags(trim($a->argv[1])) : 0; logger('like: verb ' . $verb . ' item ' . $item_id); $r = q("SELECT * FROM `item` WHERE `id` = '%s' OR `uri` = '%s' LIMIT 1", dbesc($item_id), dbesc($item_id)); if (!$item_id || !count($r)) { logger('like: no item ' . $item_id); return; } $item = $r[0]; $owner_uid = $item['uid']; if (!can_write_wall($a, $owner_uid)) { return; } $remote_owner = null; if (!$item['wall']) { // The top level post may have been written by somebody on another system $r = q("SELECT * FROM `contact` WHERE `id` = %d AND `uid` = %d LIMIT 1", intval($item['contact-id']), intval($item['uid'])); if (!count($r)) { return; } if (!$r[0]['self']) { $remote_owner = $r[0]; } } // this represents the post owner on this system. $r = q("SELECT `contact`.*, `user`.`nickname` FROM `contact` LEFT JOIN `user` ON `contact`.`uid` = `user`.`uid`\n\t\tWHERE `contact`.`self` = 1 AND `contact`.`uid` = %d LIMIT 1", intval($owner_uid)); if (count($r)) { $owner = $r[0]; } if (!$owner) { logger('like: no owner'); return; } if (!$remote_owner) { $remote_owner = $owner; } // This represents the person posting if (local_user() && local_user() == $owner_uid) { $contact = $owner; } else { $r = q("SELECT * FROM `contact` WHERE `id` = %d AND `uid` = %d LIMIT 1", intval($_SESSION['visitor_id']), intval($owner_uid)); if (count($r)) { $contact = $r[0]; } } if (!$contact) { return; } // See if we've been passed a return path to redirect to $return_path = x($_REQUEST, 'return') ? $_REQUEST['return'] : ''; $verbs = " '" . dbesc($activity) . "' "; // event participation are essentially radio toggles. If you make a subsequent choice, // we need to eradicate your first choice. if ($activity === ACTIVITY_ATTEND || $activity === ACTIVITY_ATTENDNO || $activity === ACTIVITY_ATTENDMAYBE) { $verbs = " '" . dbesc(ACTIVITY_ATTEND) . "','" . dbesc(ACTIVITY_ATTENDNO) . "','" . dbesc(ACTIVITY_ATTENDMAYBE) . "' "; } $r = q("SELECT `id`, `guid` FROM `item` WHERE `verb` IN ( {$verbs} ) AND `deleted` = 0\n\t\tAND `contact-id` = %d AND `uid` = %d\n\t\tAND (`parent` = '%s' OR `parent-uri` = '%s' OR `thr-parent` = '%s') LIMIT 1", intval($contact['id']), intval($owner_uid), dbesc($item_id), dbesc($item_id), dbesc($item['uri'])); if (count($r)) { $like_item = $r[0]; // Already voted, undo it $r = q("UPDATE `item` SET `deleted` = 1, `unseen` = 1, `changed` = '%s' WHERE `id` = %d", dbesc(datetime_convert()), intval($like_item['id'])); // Clean up the Diaspora signatures for this like // Go ahead and do it even if Diaspora support is disabled. We still want to clean up // if it had been enabled in the past $r = q("DELETE FROM `sign` WHERE `iid` = %d", intval($like_item['id'])); // Save the author information for the unlike in case we need to relay to Diaspora store_diaspora_like_retract_sig($activity, $item, $like_item, $contact); // proc_run('php',"include/notifier.php","like","$post_id"); // $post_id isn't defined here! $like_item_id = $like_item['id']; proc_run('php', "include/notifier.php", "like", "{$like_item_id}"); like_content_return($a->get_baseurl(), $return_path); return; // NOTREACHED } $uri = item_new_uri($a->get_hostname(), $owner_uid); $post_type = $item['resource-id'] ? t('photo') : t('status'); if ($item['obj_type'] === ACTIVITY_OBJ_EVENT) { $post_type = t('event'); } $objtype = $item['resource-id'] ? ACTIVITY_OBJ_PHOTO : ACTIVITY_OBJ_NOTE; $link = xmlify('<link rel="alternate" type="text/html" href="' . $a->get_baseurl() . '/display/' . $owner['nickname'] . '/' . $item['id'] . '" />' . "\n"); $body = $item['body']; $obj = <<<EOT \t<object> \t\t<type>{$objtype}</type> \t\t<local>1</local> \t\t<id>{$item['uri']}</id> \t\t<link>{$link}</link> \t\t<title></title> \t\t<content>{$body}</content> \t</object> EOT; if ($verb === 'like') { $bodyverb = t('%1$s likes %2$s\'s %3$s'); } if ($verb === 'dislike') { $bodyverb = t('%1$s doesn\'t like %2$s\'s %3$s'); } if ($verb === 'attendyes') { $bodyverb = t('%1$s is attending %2$s\'s %3$s'); } if ($verb === 'attendno') { $bodyverb = t('%1$s is not attending %2$s\'s %3$s'); } if ($verb === 'attendmaybe') { $bodyverb = t('%1$s may attend %2$s\'s %3$s'); } if (!isset($bodyverb)) { return; } $arr = array(); $arr['uri'] = $uri; $arr['uid'] = $owner_uid; $arr['contact-id'] = $contact['id']; $arr['type'] = 'activity'; $arr['wall'] = $item['wall']; $arr['origin'] = 1; $arr['gravity'] = GRAVITY_LIKE; $arr['parent'] = $item['id']; $arr['parent-uri'] = $item['uri']; $arr['thr-parent'] = $item['uri']; $arr['owner-name'] = $remote_owner['name']; $arr['owner-link'] = $remote_owner['url']; $arr['owner-avatar'] = $remote_owner['thumb']; $arr['author-name'] = $contact['name']; $arr['author-link'] = $contact['url']; $arr['author-avatar'] = $contact['thumb']; $ulink = '[url=' . $contact['url'] . ']' . $contact['name'] . '[/url]'; $alink = '[url=' . $item['author-link'] . ']' . $item['author-name'] . '[/url]'; $plink = '[url=' . $a->get_baseurl() . '/display/' . $owner['nickname'] . '/' . $item['id'] . ']' . $post_type . '[/url]'; $arr['body'] = sprintf($bodyverb, $ulink, $alink, $plink); $arr['verb'] = $activity; $arr['object-type'] = $objtype; $arr['object'] = $obj; $arr['allow_cid'] = $item['allow_cid']; $arr['allow_gid'] = $item['allow_gid']; $arr['deny_cid'] = $item['deny_cid']; $arr['deny_gid'] = $item['deny_gid']; $arr['visible'] = 1; $arr['unseen'] = 1; $arr['last-child'] = 0; $post_id = item_store($arr); if (!$item['visible']) { $r = q("UPDATE `item` SET `visible` = 1 WHERE `id` = %d AND `uid` = %d", intval($item['id']), intval($owner_uid)); } // Save the author information for the like in case we need to relay to Diaspora store_diaspora_like_sig($activity, $post_type, $contact, $post_id); $arr['id'] = $post_id; call_hooks('post_local_end', $arr); proc_run('php', "include/notifier.php", "like", "{$post_id}"); like_content_return($a->get_baseurl(), $return_path); killme(); // NOTREACHED // return; // NOTREACHED }
/** * Admin Site Page * @param App $a */ function admin_page_site_post(&$a) { if (!x($_POST, "page_site")) { return; } check_form_security_token_redirectOnErr('/admin/site', 'admin_site'); // relocate if (x($_POST, 'relocate') && x($_POST, 'relocate_url') && $_POST['relocate_url'] != "") { $new_url = $_POST['relocate_url']; $new_url = rtrim($new_url, "/"); $parsed = @parse_url($new_url); if (!$parsed || (!x($parsed, 'host') || !x($parsed, 'scheme'))) { notice(t("Can not parse base url. Must have at least <scheme>://<domain>")); goaway($a->get_baseurl(true) . '/admin/site'); } /* steps: * replace all "baseurl" to "new_url" in config, profile, term, items and contacts * send relocate for every local user * */ $old_url = $a->get_baseurl(true); function update_table($table_name, $fields, $old_url, $new_url) { global $db, $a; $dbold = dbesc($old_url); $dbnew = dbesc($new_url); $upd = array(); foreach ($fields as $f) { $upd[] = "`{$f}` = REPLACE(`{$f}`, '{$dbold}', '{$dbnew}')"; } $upds = implode(", ", $upd); $q = sprintf("UPDATE %s SET %s;", $table_name, $upds); $r = q($q); if (!$r) { notice("Failed updating '{$table_name}': " . $db->error); goaway($a->get_baseurl(true) . '/admin/site'); } } // update tables update_table("profile", array('photo', 'thumb'), $old_url, $new_url); update_table("term", array('url'), $old_url, $new_url); update_table("contact", array('photo', 'thumb', 'micro', 'url', 'nurl', 'request', 'notify', 'poll', 'confirm', 'poco'), $old_url, $new_url); update_table("unique_contacts", array('url'), $old_url, $new_url); update_table("item", array('owner-link', 'owner-avatar', 'author-name', 'author-link', 'author-avatar', 'body', 'plink', 'tag'), $old_url, $new_url); // update config $a->set_baseurl($new_url); set_config('system', 'url', $new_url); // send relocate $users = q("SELECT uid FROM user WHERE account_removed = 0 AND account_expired = 0"); foreach ($users as $user) { proc_run('php', 'include/notifier.php', 'relocate', $user['uid']); } info("Relocation started. Could take a while to complete."); goaway($a->get_baseurl(true) . '/admin/site'); } // end relocate $sitename = x($_POST, 'sitename') ? notags(trim($_POST['sitename'])) : ''; $hostname = x($_POST, 'hostname') ? notags(trim($_POST['hostname'])) : ''; $sender_email = x($_POST, 'sender_email') ? notags(trim($_POST['sender_email'])) : ''; $banner = x($_POST, 'banner') ? trim($_POST['banner']) : false; $shortcut_icon = x($_POST, 'shortcut_icon') ? notags(trim($_POST['shortcut_icon'])) : ''; $touch_icon = x($_POST, 'touch_icon') ? notags(trim($_POST['touch_icon'])) : ''; $info = x($_POST, 'info') ? trim($_POST['info']) : false; $language = x($_POST, 'language') ? notags(trim($_POST['language'])) : ''; $theme = x($_POST, 'theme') ? notags(trim($_POST['theme'])) : ''; $theme_mobile = x($_POST, 'theme_mobile') ? notags(trim($_POST['theme_mobile'])) : ''; $maximagesize = x($_POST, 'maximagesize') ? intval(trim($_POST['maximagesize'])) : 0; $maximagelength = x($_POST, 'maximagelength') ? intval(trim($_POST['maximagelength'])) : MAX_IMAGE_LENGTH; $jpegimagequality = x($_POST, 'jpegimagequality') ? intval(trim($_POST['jpegimagequality'])) : JPEG_QUALITY; $register_policy = x($_POST, 'register_policy') ? intval(trim($_POST['register_policy'])) : 0; $daily_registrations = x($_POST, 'max_daily_registrations') ? intval(trim($_POST['max_daily_registrations'])) : 0; $abandon_days = x($_POST, 'abandon_days') ? intval(trim($_POST['abandon_days'])) : 0; $register_text = x($_POST, 'register_text') ? notags(trim($_POST['register_text'])) : ''; $allowed_sites = x($_POST, 'allowed_sites') ? notags(trim($_POST['allowed_sites'])) : ''; $allowed_email = x($_POST, 'allowed_email') ? notags(trim($_POST['allowed_email'])) : ''; $block_public = x($_POST, 'block_public') ? True : False; $force_publish = x($_POST, 'publish_all') ? True : False; $global_directory = x($_POST, 'directory_submit_url') ? notags(trim($_POST['directory_submit_url'])) : ''; $thread_allow = x($_POST, 'thread_allow') ? True : False; $newuser_private = x($_POST, 'newuser_private') ? True : False; $enotify_no_content = x($_POST, 'enotify_no_content') ? True : False; $private_addons = x($_POST, 'private_addons') ? True : False; $disable_embedded = x($_POST, 'disable_embedded') ? True : False; $allow_users_remote_self = x($_POST, 'allow_users_remote_self') ? True : False; $no_multi_reg = x($_POST, 'no_multi_reg') ? True : False; $no_openid = !(x($_POST, 'no_openid') ? True : False); $no_regfullname = !(x($_POST, 'no_regfullname') ? True : False); $no_utf = !(x($_POST, 'no_utf') ? True : False); $community_page_style = x($_POST, 'community_page_style') ? intval(trim($_POST['community_page_style'])) : 0; $max_author_posts_community_page = x($_POST, 'max_author_posts_community_page') ? intval(trim($_POST['max_author_posts_community_page'])) : 0; $verifyssl = x($_POST, 'verifyssl') ? True : False; $proxyuser = x($_POST, 'proxyuser') ? notags(trim($_POST['proxyuser'])) : ''; $proxy = x($_POST, 'proxy') ? notags(trim($_POST['proxy'])) : ''; $timeout = x($_POST, 'timeout') ? intval(trim($_POST['timeout'])) : 60; $delivery_interval = x($_POST, 'delivery_interval') ? intval(trim($_POST['delivery_interval'])) : 0; $poll_interval = x($_POST, 'poll_interval') ? intval(trim($_POST['poll_interval'])) : 0; $maxloadavg = x($_POST, 'maxloadavg') ? intval(trim($_POST['maxloadavg'])) : 50; $dfrn_only = x($_POST, 'dfrn_only') ? True : False; $ostatus_disabled = !(x($_POST, 'ostatus_disabled') ? True : False); $ostatus_poll_interval = x($_POST, 'ostatus_poll_interval') ? intval(trim($_POST['ostatus_poll_interval'])) : 0; $diaspora_enabled = x($_POST, 'diaspora_enabled') ? True : False; $ssl_policy = x($_POST, 'ssl_policy') ? intval($_POST['ssl_policy']) : 0; $force_ssl = x($_POST, 'force_ssl') ? True : False; $old_share = x($_POST, 'old_share') ? True : False; $hide_help = x($_POST, 'hide_help') ? True : False; $suppress_language = x($_POST, 'suppress_language') ? True : False; $suppress_tags = x($_POST, 'suppress_tags') ? True : False; $use_fulltext_engine = x($_POST, 'use_fulltext_engine') ? True : False; $itemcache = x($_POST, 'itemcache') ? notags(trim($_POST['itemcache'])) : ''; $itemcache_duration = x($_POST, 'itemcache_duration') ? intval($_POST['itemcache_duration']) : 0; $max_comments = x($_POST, 'max_comments') ? intval($_POST['max_comments']) : 0; $lockpath = x($_POST, 'lockpath') ? notags(trim($_POST['lockpath'])) : ''; $temppath = x($_POST, 'temppath') ? notags(trim($_POST['temppath'])) : ''; $basepath = x($_POST, 'basepath') ? notags(trim($_POST['basepath'])) : ''; $singleuser = x($_POST, 'singleuser') ? notags(trim($_POST['singleuser'])) : ''; $proxy_disabled = x($_POST, 'proxy_disabled') ? True : False; $old_pager = x($_POST, 'old_pager') ? True : False; $only_tag_search = x($_POST, 'only_tag_search') ? True : False; if ($ssl_policy != intval(get_config('system', 'ssl_policy'))) { if ($ssl_policy == SSL_POLICY_FULL) { q("update `contact` set\n\t\t\t\t`url` = replace(`url` , 'http:' , 'https:'),\n\t\t\t\t`photo` = replace(`photo` , 'http:' , 'https:'),\n\t\t\t\t`thumb` = replace(`thumb` , 'http:' , 'https:'),\n\t\t\t\t`micro` = replace(`micro` , 'http:' , 'https:'),\n\t\t\t\t`request` = replace(`request`, 'http:' , 'https:'),\n\t\t\t\t`notify` = replace(`notify` , 'http:' , 'https:'),\n\t\t\t\t`poll` = replace(`poll` , 'http:' , 'https:'),\n\t\t\t\t`confirm` = replace(`confirm`, 'http:' , 'https:'),\n\t\t\t\t`poco` = replace(`poco` , 'http:' , 'https:')\n\t\t\t\twhere `self` = 1"); q("update `profile` set\n\t\t\t\t`photo` = replace(`photo` , 'http:' , 'https:'),\n\t\t\t\t`thumb` = replace(`thumb` , 'http:' , 'https:')\n\t\t\t\twhere 1 "); } elseif ($ssl_policy == SSL_POLICY_SELFSIGN) { q("update `contact` set\n\t\t\t\t`url` = replace(`url` , 'https:' , 'http:'),\n\t\t\t\t`photo` = replace(`photo` , 'https:' , 'http:'),\n\t\t\t\t`thumb` = replace(`thumb` , 'https:' , 'http:'),\n\t\t\t\t`micro` = replace(`micro` , 'https:' , 'http:'),\n\t\t\t\t`request` = replace(`request`, 'https:' , 'http:'),\n\t\t\t\t`notify` = replace(`notify` , 'https:' , 'http:'),\n\t\t\t\t`poll` = replace(`poll` , 'https:' , 'http:'),\n\t\t\t\t`confirm` = replace(`confirm`, 'https:' , 'http:'),\n\t\t\t\t`poco` = replace(`poco` , 'https:' , 'http:')\n\t\t\t\twhere `self` = 1"); q("update `profile` set\n\t\t\t\t`photo` = replace(`photo` , 'https:' , 'http:'),\n\t\t\t\t`thumb` = replace(`thumb` , 'https:' , 'http:')\n\t\t\t\twhere 1 "); } } set_config('system', 'ssl_policy', $ssl_policy); set_config('system', 'delivery_interval', $delivery_interval); set_config('system', 'poll_interval', $poll_interval); set_config('system', 'maxloadavg', $maxloadavg); set_config('config', 'sitename', $sitename); set_config('config', 'hostname', $hostname); set_config('config', 'sender_email', $sender_email); set_config('system', 'suppress_language', $suppress_language); set_config('system', 'suppress_tags', $suppress_tags); set_config('system', 'shortcut_icon', $shortcut_icon); set_config('system', 'touch_icon', $touch_icon); if ($banner == "") { // don't know why, but del_config doesn't work... q("DELETE FROM `config` WHERE `cat` = '%s' AND `k` = '%s' LIMIT 1", dbesc("system"), dbesc("banner")); } else { set_config('system', 'banner', $banner); } if ($info == "") { del_config('config', 'info'); } else { set_config('config', 'info', $info); } set_config('system', 'language', $language); set_config('system', 'theme', $theme); if ($theme_mobile === '---') { del_config('system', 'mobile-theme'); } else { set_config('system', 'mobile-theme', $theme_mobile); } if ($singleuser === '---') { del_config('system', 'singleuser'); } else { set_config('system', 'singleuser', $singleuser); } set_config('system', 'maximagesize', $maximagesize); set_config('system', 'max_image_length', $maximagelength); set_config('system', 'jpeg_quality', $jpegimagequality); set_config('config', 'register_policy', $register_policy); set_config('system', 'max_daily_registrations', $daily_registrations); set_config('system', 'account_abandon_days', $abandon_days); set_config('config', 'register_text', $register_text); set_config('system', 'allowed_sites', $allowed_sites); set_config('system', 'allowed_email', $allowed_email); set_config('system', 'block_public', $block_public); set_config('system', 'publish_all', $force_publish); if ($global_directory == "") { // don't know why, but del_config doesn't work... q("DELETE FROM `config` WHERE `cat` = '%s' AND `k` = '%s' LIMIT 1", dbesc("system"), dbesc("directory_submit_url")); } else { set_config('system', 'directory_submit_url', $global_directory); } set_config('system', 'thread_allow', $thread_allow); set_config('system', 'newuser_private', $newuser_private); set_config('system', 'enotify_no_content', $enotify_no_content); set_config('system', 'disable_embedded', $disable_embedded); set_config('system', 'allow_users_remote_self', $allow_users_remote_self); set_config('system', 'block_extended_register', $no_multi_reg); set_config('system', 'no_openid', $no_openid); set_config('system', 'no_regfullname', $no_regfullname); set_config('system', 'community_page_style', $community_page_style); set_config('system', 'max_author_posts_community_page', $max_author_posts_community_page); set_config('system', 'no_utf', $no_utf); set_config('system', 'verifyssl', $verifyssl); set_config('system', 'proxyuser', $proxyuser); set_config('system', 'proxy', $proxy); set_config('system', 'curl_timeout', $timeout); set_config('system', 'dfrn_only', $dfrn_only); set_config('system', 'ostatus_disabled', $ostatus_disabled); set_config('system', 'ostatus_poll_interval', $ostatus_poll_interval); set_config('system', 'diaspora_enabled', $diaspora_enabled); set_config('config', 'private_addons', $private_addons); set_config('system', 'force_ssl', $force_ssl); set_config('system', 'old_share', $old_share); set_config('system', 'hide_help', $hide_help); set_config('system', 'use_fulltext_engine', $use_fulltext_engine); set_config('system', 'itemcache', $itemcache); set_config('system', 'itemcache_duration', $itemcache_duration); set_config('system', 'max_comments', $max_comments); set_config('system', 'lockpath', $lockpath); set_config('system', 'temppath', $temppath); set_config('system', 'basepath', $basepath); set_config('system', 'proxy_disabled', $proxy_disabled); set_config('system', 'old_pager', $old_pager); set_config('system', 'only_tag_search', $only_tag_search); info(t('Site settings updated.') . EOL); goaway($a->get_baseurl(true) . '/admin/site'); return; // NOTREACHED }
function send_message($uid = 0, $recipient = '', $body = '', $subject = '', $replyto = '', $expires = '') { $ret = array('success' => false); $a = get_app(); if (!$recipient) { $ret['message'] = t('No recipient provided.'); return $ret; } if (!strlen($subject)) { $subject = t('[no subject]'); } // if(! $expires) // $expires = NULL_DATE; // else // $expires = datetime_convert(date_default_timezone_get(),'UTC',$expires); if ($uid) { $r = q("select * from channel where channel_id = %d limit 1", intval($uid)); if ($r) { $channel = $r[0]; } } else { $channel = get_app()->get_channel(); } if (!$channel) { $ret['message'] = t('Unable to determine sender.'); return $ret; } // look for any existing conversation structure $conv_guid = ''; if (strlen($replyto)) { $r = q("select conv_guid from mail where channel_id = %d and ( mid = '%s' or parent_mid = '%s' ) limit 1", intval(local_channel()), dbesc($replyto), dbesc($replyto)); if ($r) { $conv_guid = $r[0]['conv_guid']; } } if (!$conv_guid) { // create a new conversation $conv_guid = random_string(); $recip = q("select * from xchan where xchan_hash = '%s' limit 1", dbesc($recipient)); if ($recip) { $recip_handle = $recip[0]['xchan_addr']; } $sender_handle = $channel['channel_address'] . '@' . get_app()->get_hostname(); $handles = $recip_handle . ';' . $sender_handle; if ($subject) { $nsubject = str_rot47(base64url_encode($subject)); } $r = q("insert into conv (uid,guid,creator,created,updated,subject,recips) values(%d, '%s', '%s', '%s', '%s', '%s', '%s') ", intval(local_channel()), dbesc($conv_guid), dbesc($sender_handle), dbesc(datetime_convert()), dbesc(datetime_convert()), dbesc($nsubject), dbesc($handles)); $r = q("select * from conv where guid = '%s' and uid = %d limit 1", dbesc($conv_guid), intval(local_channel())); if ($r) { $retconv = $r[0]; $retconv['subject'] = base64url_decode(str_rot47($retconv['subject'])); } } if (!$retconv) { $r = q("select * from conv where guid = '%s' and uid = %d limit 1", dbesc($conv_guid), intval(local_channel())); if ($r) { $retconv = $r[0]; $retconv['subject'] = base64url_decode(str_rot47($retconv['subject'])); } } if (!$retconv) { $ret['message'] = 'conversation not found'; return $ret; } // generate a unique message_id do { $dups = false; $hash = random_string(); $mid = $hash . '@' . get_app()->get_hostname(); $r = q("SELECT id FROM mail WHERE mid = '%s' LIMIT 1", dbesc($mid)); if (count($r)) { $dups = true; } } while ($dups == true); if (!strlen($replyto)) { $replyto = $mid; } /** * * When a photo was uploaded into the message using the (profile wall) ajax * uploader, The permissions are initially set to disallow anybody but the * owner from seeing it. This is because the permissions may not yet have been * set for the post. If it's private, the photo permissions should be set * appropriately. But we didn't know the final permissions on the post until * now. So now we'll look for links of uploaded messages that are in the * post and set them to the same permissions as the post itself. * */ $match = null; $images = null; if (preg_match_all("/\\[zmg\\](.*?)\\[\\/zmg\\]/", strpos($body, '[/crypt]') ? $_POST['media_str'] : $body, $match)) { $images = $match[1]; } $match = false; if (preg_match_all("/\\[attachment\\](.*?)\\[\\/attachment\\]/", strpos($body, '[/crypt]') ? $_POST['media_str'] : $body, $match)) { $attaches = $match[1]; } $attachments = ''; if (preg_match_all('/(\\[attachment\\](.*?)\\[\\/attachment\\])/', $body, $match)) { $attachments = array(); foreach ($match[2] as $mtch) { $hash = substr($mtch, 0, strpos($mtch, ',')); $rev = intval(substr($mtch, strpos($mtch, ','))); $r = attach_by_hash_nodata($hash, $rev); if ($r['success']) { $attachments[] = array('href' => $a->get_baseurl() . '/attach/' . $r['data']['hash'], 'length' => $r['data']['filesize'], 'type' => $r['data']['filetype'], 'title' => urlencode($r['data']['filename']), 'revision' => $r['data']['revision']); } $body = str_replace($match[1], '', $body); } } $jattach = $attachments ? json_encode($attachments) : ''; if ($subject) { $subject = str_rot47(base64url_encode($subject)); } if ($body) { $body = str_rot47(base64url_encode($body)); } $r = q("INSERT INTO mail ( account_id, conv_guid, mail_obscured, channel_id, from_xchan, to_xchan, title, body, attach, mid, parent_mid, created, expires )\n\t\tVALUES ( %d, '%s', %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s' )", intval($channel['channel_account_id']), dbesc($conv_guid), intval(1), intval($channel['channel_id']), dbesc($channel['channel_hash']), dbesc($recipient), dbesc($subject), dbesc($body), dbesc($jattach), dbesc($mid), dbesc($replyto), dbesc(datetime_convert()), dbescdate($expires)); // verify the save $r = q("SELECT * FROM mail WHERE mid = '%s' and channel_id = %d LIMIT 1", dbesc($mid), intval($channel['channel_id'])); if ($r) { $post_id = $r[0]['id']; $retmail = $r[0]; xchan_mail_query($retmail); } else { $ret['message'] = t('Stored post could not be verified.'); return $ret; } if (count($images)) { foreach ($images as $image) { if (!stristr($image, $a->get_baseurl() . '/photo/')) { continue; } $image_uri = substr($image, strrpos($image, '/') + 1); $image_uri = substr($image_uri, 0, strpos($image_uri, '-')); $r = q("UPDATE photo SET allow_cid = '%s' WHERE resource_id = '%s' AND uid = %d and allow_cid = '%s'", dbesc('<' . $recipient . '>'), dbesc($image_uri), intval($channel['channel_id']), dbesc('<' . $channel['channel_hash'] . '>')); $r = q("UPDATE attach SET allow_cid = '%s' WHERE hash = '%s' AND is_photo = 1 and uid = %d and allow_cid = '%s'", dbesc('<' . $recipient . '>'), dbesc($image_uri), intval($channel['channel_id']), dbesc('<' . $channel['channel_hash'] . '>')); } } if ($attaches) { foreach ($attaches as $attach) { $hash = substr($attach, 0, strpos($attach, ',')); $rev = intval(substr($attach, strpos($attach, ','))); attach_store($channel, $observer_hash, $options = 'update', array('hash' => $hash, 'revision' => $rev, 'allow_cid' => '<' . $recipient . '>')); } } proc_run('php', 'include/notifier.php', 'mail', $post_id); $ret['success'] = true; $ret['message_item'] = intval($post_id); $ret['conv'] = $retconv; $ret['mail'] = $retmail; return $ret; }