diff options
Diffstat (limited to 'mod')
84 files changed, 3480 insertions, 2426 deletions
diff --git a/mod/achievements.php b/mod/achievements.php new file mode 100644 index 000000000..1910def73 --- /dev/null +++ b/mod/achievements.php @@ -0,0 +1,84 @@ +<?php + +function achievements_content(&$a) { + + if(argc() > 1) + $which = argv(1); + else { + notice( t('Requested profile is not available.') . EOL ); + return; +} + + $profile = 0; + $profile = argv(1); + profile_load($a,$which,$profile); + + $r = q("select channel_id from channel where channel_address = '%s'", + dbesc($which) + ); + if($r) { + $owner = intval($r[0]['channel_id']); + } + + $observer = $a->get_observer(); + $ob_hash = (($observer) ? $observer['xchan_hash'] : ''); + $perms = get_all_perms($owner,$ob_hash); + if(! $perms['view_profile']) { + notice( t('Permission denied.') . EOL); + return; + } + +// By default, all badges are false + $contactbadge = false; + $profilebadge = false; + $keywordsbadge = false; + +// Check number of contacts. Award a badge if over 10 +// We'll figure these out on each page load instead of +// writing them to the DB because that will mean one needs +// to retain their achievements - eg, you can't add +// a bunch of channels just to get your badge, and then +// delete them all again. If these become popular or +// used in profiles or something, we may need to reconsider +// and add a table for this - because this won't scale. + + $r = q("select * from abook where abook_channel = %d", + intval($owner) + ); + + if (count($r)) + $contacts = count($r); + // We're checking for 11 to adjust for the abook record for self + if ($contacts >= 11) + $contactbadge = true; + +// Check if an about field in the profile has been created. + + $r = q("select * from profile where uid = %d and about <> ''", + intval($owner) + ); + + if ($r) + $profilebadge = 1; + +// Check if keywords have been set + + $r = q("select * from profile where uid = %d and keywords <> ''", + intval($owner) + ); + + if($r) + $keywordsbadge = 1; + +// FIXME - stick ths in a template, and make it look pretty. + $o .= "Template not implemented"; + $o .= "If this is one, you get the profile badge" . $profilebadge . "<br>"; + $o .= "If this is one, you get the contact badge" . $contactbadge . "<br>"; + $o .= "If this is one you get the keywords badge" . $keywordsbadge . "<br>"; + $o .= "I haven't done the top level posts badge yet" . $toplevelpostsbadge . "<br>"; + $o .= "I haven't done the number of channels badge yet" . $channelsbadge; + + +return $o; + +} diff --git a/mod/acl.php b/mod/acl.php index bd19c4bb7..ed9e935e9 100644 --- a/mod/acl.php +++ b/mod/acl.php @@ -39,7 +39,7 @@ function acl_init(&$a){ // count groups and contacts if ($type=='' || $type=='g'){ - $r = q("SELECT COUNT(`id`) AS g FROM `group` WHERE `deleted` = 0 AND `uid` = %d $sql_extra", + $r = q("SELECT COUNT(`id`) AS g FROM `groups` WHERE `deleted` = 0 AND `uid` = %d $sql_extra", intval(local_user()) ); $group_count = (int)$r[0]['g']; @@ -49,9 +49,10 @@ function acl_init(&$a){ if ($type=='' || $type=='c'){ $r = q("SELECT COUNT(abook_id) AS c FROM abook left join xchan on abook_xchan = xchan_hash - WHERE abook_channel = %d AND not ( abook_flags & %d ) $sql_extra2" , + WHERE abook_channel = %d AND not ( abook_flags & %d ) and not (xchan_flags & %d ) $sql_extra2" , intval(local_user()), - intval(ABOOK_FLAG_SELF|ABOOK_FLAG_BLOCKED|ABOOK_FLAG_PENDING|ABOOK_FLAG_ARCHIVED) + intval(ABOOK_FLAG_BLOCKED|ABOOK_FLAG_PENDING|ABOOK_FLAG_ARCHIVED), + intval(XCHAN_FLAGS_DELETED) ); $contact_count = (int)$r[0]['c']; } @@ -64,9 +65,11 @@ function acl_init(&$a){ $r = q("SELECT count(xchan_hash) as c FROM abook left join xchan on abook_xchan = xchan_hash WHERE abook_channel = %d and ( (abook_their_perms = null) or (abook_their_perms & %d )) + and not ( xchan_flags & %d ) $sql_extra2 ", intval(local_user()), - intval(PERMS_W_MAIL) + intval(PERMS_W_MAIL), + intval(XCHAN_FLAGS_DELETED) ); if($r) @@ -78,8 +81,9 @@ function acl_init(&$a){ // autocomplete for Contacts $r = q("SELECT COUNT(abook_id) AS c FROM abook left join xchan on abook_xchan = xchan_hash - WHERE abook_channel = %d $sql_extra2" , - intval(local_user()) + WHERE abook_channel = %d and not ( xchan_flags & %d ) $sql_extra2" , + intval(local_user()), + intval(XCHAN_FLAGS_DELETED) ); $contact_count = (int)$r[0]['c']; @@ -94,14 +98,14 @@ function acl_init(&$a){ if ($type=='' || $type=='g'){ - $r = q("SELECT `group`.`id`, `group`.`hash`, `group`.`name`, + $r = q("SELECT `groups`.`id`, `groups`.`hash`, `groups`.`name`, GROUP_CONCAT(DISTINCT `group_member`.`xchan` SEPARATOR ',') as uids - FROM `group`,`group_member` - WHERE `group`.`deleted` = 0 AND `group`.`uid` = %d - AND `group_member`.`gid`=`group`.`id` + FROM `groups`,`group_member` + WHERE `groups`.`deleted` = 0 AND `groups`.`uid` = %d + AND `group_member`.`gid`=`groups`.`id` $sql_extra - GROUP BY `group`.`id` - ORDER BY `group`.`name` + GROUP BY `groups`.`id` + ORDER BY `groups`.`name` LIMIT %d,%d", intval(local_user()), intval($start), @@ -121,32 +125,39 @@ function acl_init(&$a){ ); } } - + if ($type=='' || $type=='c') { - $r = q("SELECT abook_id as id, xchan_hash as hash, xchan_name as name, xchan_photo_s as micro, xchan_url as url, xchan_addr as nick, abook_their_perms + $r = q("SELECT abook_id as id, xchan_hash as hash, xchan_name as name, xchan_photo_s as micro, xchan_url as url, xchan_addr as nick, abook_their_perms, abook_flags FROM abook left join xchan on abook_xchan = xchan_hash - WHERE abook_channel = %d AND not ( abook_flags & %d ) $sql_extra2 order by xchan_name asc" , + WHERE abook_channel = %d AND not ( abook_flags & %d ) and not (xchan_flags & %d ) $sql_extra2 order by xchan_name asc" , intval(local_user()), - intval(ABOOK_FLAG_SELF|ABOOK_FLAG_BLOCKED|ABOOK_FLAG_PENDING|ABOOK_FLAG_ARCHIVED) + intval(ABOOK_FLAG_BLOCKED|ABOOK_FLAG_PENDING|ABOOK_FLAG_ARCHIVED), + intval(XCHAN_FLAGS_DELETED) ); + } elseif($type == 'm') { $r = q("SELECT xchan_hash as id, xchan_name as name, xchan_addr as nick, xchan_photo_s as micro, xchan_url as url FROM abook left join xchan on abook_xchan = xchan_hash WHERE abook_channel = %d and ( (abook_their_perms = null) or (abook_their_perms & %d )) + and not (xchan_flags & %d) $sql_extra3 ORDER BY `xchan_name` ASC ", intval(local_user()), - intval(PERMS_W_MAIL) + intval(PERMS_W_MAIL), + intval(XCHAN_FLAGS_DELETED) ); } elseif($type == 'a') { $r = q("SELECT abook_id as id, xchan_name as name, xchan_hash as hash, xchan_addr as nick, xchan_photo_s as micro, xchan_network as network, xchan_url as url, xchan_addr as attag , abook_their_perms FROM abook left join xchan on abook_xchan = xchan_hash WHERE abook_channel = %d + and not (xchan_flags & %d) $sql_extra3 ORDER BY xchan_name ASC ", - intval(local_user()) + intval(local_user()), + intval(XCHAN_FLAGS_DELETED) + ); } elseif($type == 'x') { @@ -203,7 +214,7 @@ function acl_init(&$a){ "xid" => $g['hash'], "link" => $g['nick'], "nick" => substr($g['nick'],0,strpos($g['nick'],'@')), - "network" => '', + "self" => (($g['abook_flags'] & ABOOK_FLAG_SELF) ? 'abook-self' : ''), "taggable" => (($g['abook_their_perms'] & PERMS_W_TAGWALL) ? 'taggable' : '') ); } diff --git a/mod/admin.php b/mod/admin.php index 9a6aea35a..c4a284941 100644 --- a/mod/admin.php +++ b/mod/admin.php @@ -9,7 +9,7 @@ * @param App $a */ function admin_post(&$a){ - + logger('admin_post', LOGGER_DEBUG); if(!is_site_admin()) { return; @@ -74,6 +74,7 @@ function admin_post(&$a){ */ function admin_content(&$a) { + logger('admin_content', LOGGER_DEBUG); if(!is_site_admin()) { return login(false); } @@ -215,13 +216,14 @@ function admin_page_site_post(&$a){ check_form_security_token_redirectOnErr('/admin/site', 'admin_site'); $sitename = ((x($_POST,'sitename')) ? notags(trim($_POST['sitename'])) : ''); - $banner = ((x($_POST,'banner')) ? trim($_POST['banner']) : false); + $banner = ((x($_POST,'banner')) ? trim($_POST['banner']) : false); + $admininfo = ((x($_POST,'admininfo')) ? trim($_POST['admininfo']) : 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'])) : ''); - $theme_accessibility = ((x($_POST,'theme_accessibility')) ? notags(trim($_POST['theme_accessibility'])) : ''); - $site_channel = ((x($_POST,'site_channel')) ? notags(trim($_POST['site_channel'])) : ''); - $maximagesize = ((x($_POST,'maximagesize')) ? intval(trim($_POST['maximagesize'])) : 0); + $theme_mobile = ((x($_POST,'theme_mobile')) ? notags(trim($_POST['theme_mobile'])) : ''); + $theme_accessibility = ((x($_POST,'theme_accessibility')) ? notags(trim($_POST['theme_accessibility'])) : ''); + $site_channel = ((x($_POST,'site_channel')) ? notags(trim($_POST['site_channel'])) : ''); + $maximagesize = ((x($_POST,'maximagesize')) ? intval(trim($_POST['maximagesize'])) : 0); $register_policy = ((x($_POST,'register_policy')) ? intval(trim($_POST['register_policy'])) : 0); @@ -301,6 +303,12 @@ function admin_page_site_post(&$a){ set_config('system','banner', $banner); } + if ($admininfo==''){ + del_config('system','admininfo'); + } + else { + set_config('system','admininfo', $admininfo); + } set_config('system','language', $language); set_config('system','theme', $theme); if ( $theme_mobile === '---' ) { @@ -393,6 +401,9 @@ function admin_page_site(&$a) { $banner = 'red'; $banner = htmlspecialchars($banner); + /* Admin Info */ + $admininfo = get_config('system','admininfo'); + /* Register policy */ $register_choices = Array( REGISTER_CLOSED => t("Closed"), @@ -425,8 +436,9 @@ function admin_page_site(&$a) { '$baseurl' => $a->get_baseurl(true), // name, label, value, help string, extra data... - '$sitename' => array('sitename', t("Site name"), htmlentities(get_config('system','sitename'), ENT_QUOTES), ""), + '$sitename' => array('sitename', t("Site name"), htmlspecialchars(get_config('system','sitename'), ENT_QUOTES, 'UTF-8'),''), '$banner' => array('banner', t("Banner/Logo"), $banner, ""), + '$admininfo' => array('admininfo', t("Administrator Information"), $admininfo, t("Contact information for site administrators. Displayed on siteinfo page. BBCode can be used here")), '$language' => array('language', t("System language"), get_config('system','language'), "", $lang_choices), '$theme' => array('theme', t("System theme"), get_config('system','theme'), t("Default system theme - may be over-ridden by user profiles - <a href='#' id='cnftheme'>change theme settings</a>"), $theme_choices), '$theme_mobile' => array('theme_mobile', t("Mobile system theme"), get_config('system','mobile_theme'), t("Theme for mobile devices"), $theme_choices_mobile), @@ -436,7 +448,7 @@ function admin_page_site(&$a) { '$maximagesize' => array('maximagesize', t("Maximum image size"), get_config('system','maximagesize'), t("Maximum size in bytes of uploaded images. Default is 0, which means no limits.")), '$register_policy' => array('register_policy', t("Register policy"), get_config('system','register_policy'), "", $register_choices), '$access_policy' => array('access_policy', t("Access policy"), get_config('system','access_policy'), "", $access_choices), - '$register_text' => array('register_text', t("Register text"), htmlentities(get_config('system','register_text'), ENT_QUOTES, 'UTF-8'), t("Will be displayed prominently on the registration page.")), + '$register_text' => array('register_text', t("Register text"), htmlspecialchars(get_config('system','register_text'), ENT_QUOTES, 'UTF-8'), t("Will be displayed prominently on the registration page.")), '$abandon_days' => array('abandon_days', t('Accounts abandoned after x days'), get_config('system','account_abandon_days'), t('Will not waste system resources polling external sites for abandonded accounts. Enter 0 for no time limit.')), '$allowed_sites' => array('allowed_sites', t("Allowed friend domains"), get_config('system','allowed_sites'), t("Comma separated list of domains which are allowed to establish friendships with this site. Wildcards are accepted. Empty to allow any domains")), '$allowed_email' => array('allowed_email', t("Allowed email domains"), get_config('system','allowed_email'), t("Comma separated list of domains which are allowed in email addresses for registrations to this site. Wildcards are accepted. Empty to allow any domains")), @@ -456,7 +468,46 @@ function admin_page_site(&$a) { } function admin_page_hubloc_post(&$a){ - check_form_security_token_redirectOnErr('/admin/hubloc', 'hubloc'); + check_form_security_token_redirectOnErr('/admin/hubloc', 'admin_hubloc'); + require_once('include/zot.php'); + + //prepare for ping + + if ( $_POST['hublocid']) { + $hublocid = $_POST['hublocid']; + $arrhublocurl = q("SELECT hubloc_url FROM hubloc WHERE hubloc_id = %d ", + intval($hublocid) + ); + $hublocurl = $arrhublocurl[0]['hubloc_url'] . '/post'; + + //perform ping + $m = zot_build_packet($a->get_channel(),'ping'); + $r = zot_zot($hublocurl,$m); + //handle results and set the hubloc flags in db to make results visible + $r2 = $r['body']; + $r3 = $r2['success']; + if ( $r3['success'] == True ){ + //set HUBLOC_OFFLINE to 0 + logger(' success = true ',LOGGER_DEBUG); + } else { + //set HUBLOC_OFFLINE to 1 + logger(' success = false ', LOGGER_DEBUG); + + } + + //unfotunatly zping wont work, I guess return format is not correct + //require_once('mod/zping.php'); + //$r = zping_content($hublocurl); + //logger('zping answer: ' . $r, LOGGER_DEBUG); + + + //in case of repair store new pub key for tested hubloc (all channel with this hubloc) in db + //after repair set hubloc flags to 0 + + } + + + goaway($a->get_baseurl(true) . '/admin/hubloc' ); return; } @@ -479,7 +530,8 @@ function admin_page_hubloc(&$a) { '$queues' => $queues, //'$accounts' => $accounts, /*$accounts is empty here*/ '$pending' => Array( t('Pending registrations'), $pending), - '$plugins' => Array( t('Active plugins'), $a->plugins ) + '$plugins' => Array( t('Active plugins'), $a->plugins ), + '$form_security_token' => get_form_security_token("admin_hubloc") )); return $o; } @@ -654,9 +706,10 @@ function admin_page_users(&$a){ $users =q("SELECT `account_id` , `account_email`, `account_lastlog`, `account_created`, `account_expires`, " . "`account_service_class`, ( account_flags & %d ) > 0 as `blocked`, " . "(SELECT GROUP_CONCAT( ch.channel_address SEPARATOR ' ') FROM channel as ch " . - "WHERE ch.channel_account_id = ac.account_id) as `channels` " . + "WHERE ch.channel_account_id = ac.account_id and not (ch.channel_pageflags & %d )) as `channels` " . "FROM account as ac where true $serviceclass $order limit %d , %d ", - intval(ACCOUNT_BLOCKED), + intval(ACCOUNT_BLOCKED), + intval(PAGE_REMOVED), intval($a->pager['start']), intval($a->pager['itemspage']) ); @@ -686,7 +739,7 @@ function admin_page_users(&$a){ '$submit' => t('Submit'), '$select_all' => t('select all'), '$h_pending' => t('User registrations waiting for confirm'), - '$th_pending' => array( t('Request date'), t('Name'), t('Email') ), + '$th_pending' => array( t('Request date'), t('Email') ), '$no_pending' => t('No registrations.'), '$approve' => t('Approve'), '$deny' => t('Deny'), diff --git a/mod/allfriends.php b/mod/allfriends.php deleted file mode 100644 index bb4df30be..000000000 --- a/mod/allfriends.php +++ /dev/null @@ -1,60 +0,0 @@ -<?php - -require_once('include/socgraph.php'); - -function allfriends_content(&$a) { - - $o = ''; - - if(! local_user()) { - notice( t('Permission denied.') . EOL); - return; - } - - if(argc() > 1) - $cid = intval(argv(1)); - if(! $cid) - return; - - $c = q("select name, url, photo from contact where id = %d and uid = %d limit 1", - intval($cid), - intval(local_user()) - ); - - $a->page['aside'] .= '<div class="vcard">' - . '<div class="fn label">' . $c[0]['name'] . '</div>' - . '<div id="profile-photo-wrapper">' - . '<a href="/contacts/' . $cid . '"><img class="photo" width="175" height="175" - src="' . $c[0]['photo'] . '" alt="' . $c[0]['name'] . '" /></div>' - . '</div>'; - - - if(! count($c)) - return; - - $o .= '<h2>' . sprintf( t('Friends of %s'), $c[0]['name']) . '</h2>'; - - - $r = all_friends(local_user(),$cid); - - if(! count($r)) { - $o .= t('No friends to display.'); - return $o; - } - - $tpl = get_markup_template('common_friends.tpl'); - - foreach($r as $rr) { - - $o .= replace_macros($tpl,array( - '$url' => $rr['url'], - '$name' => $rr['name'], - '$photo' => $rr['photo'], - '$tags' => '' - )); - } - - $o .= cleardiv(); -// $o .= paginate($a); - return $o; -} diff --git a/mod/attach.php b/mod/attach.php index a5f9d1a6b..cf72d09c6 100644 --- a/mod/attach.php +++ b/mod/attach.php @@ -17,12 +17,35 @@ function attach_init(&$a) { return; } - header('Content-type: ' . $r['data']['filetype']); - header('Content-disposition: attachment; filename=' . $r['data']['filename']); - if($r['data']['flags'] & ATTACH_FLAG_OS ) - echo @file_get_contents($r['data']['data']); + $c = q("select channel_address from channel where channel_id = %d limit 1", + intval($r['data']['uid']) + ); + + if(! $c) + return; + + + $unsafe_types = array('text/html','text/css','application/javascript'); + + if(in_array($r['data']['filetype'],$unsafe_types)) { + header('Content-type: text/plain'); + } + else { + header('Content-type: ' . $r['data']['filetype']); + } + + header('Content-disposition: attachment; filename="' . $r['data']['filename'] . '"'); + if($r['data']['flags'] & ATTACH_FLAG_OS ) { + $istream = fopen('store/' . $c[0]['channel_address'] . '/' . $r['data']['data'],'rb'); + $ostream = fopen('php://output','wb'); + if($istream && $ostream) { + pipe_streams($istream,$ostream); + fclose($istream); + fclose($ostream); + } + } else echo $r['data']['data']; killme(); -}
\ No newline at end of file +} diff --git a/mod/authtest.php b/mod/authtest.php index 2c8d7b4b4..3044a880b 100644 --- a/mod/authtest.php +++ b/mod/authtest.php @@ -6,7 +6,7 @@ require_once('mod/magic.php'); function authtest_content(&$a) { - + $auth_success = false; $o .= '<h3>Magic-Auth Diagnostic</h3>'; if(! local_user()) { @@ -34,11 +34,16 @@ function authtest_content(&$a) { if(! $j) $o .= 'json_decode failure from remote site. ' . print_r($z['body'],true); $o .= 'Remote site responded: ' . print_r($j,true); + if($j['success'] && strpos($j['message'],'Authentication Success')) + $auth_success = true; } else { $o .= 'fetch url failure.' . print_r($z,true); } } + + if(! $auth_success) + $o .= 'Authentication Failed!' . EOL; } return str_replace("\n",'<br />',$o); diff --git a/mod/blocks.php b/mod/blocks.php index 4604790c3..9a4e0b1ca 100644 --- a/mod/blocks.php +++ b/mod/blocks.php @@ -45,9 +45,9 @@ function blocks_content(&$a) { return; } - if(local_user() && local_user() == $owner) { - $a->set_widget('design',design_tools()); - } +// if(local_user() && local_user() == $owner) { + // $a->set_widget('design',design_tools()); + // } diff --git a/mod/bookmarks.php b/mod/bookmarks.php new file mode 100644 index 000000000..c5be68b8e --- /dev/null +++ b/mod/bookmarks.php @@ -0,0 +1,81 @@ +<?php + +function bookmarks_init(&$a) { + if(! local_user()) + return; + $item_id = intval($_REQUEST['item']); + if(! $item_id) + return; + + $u = $a->get_channel(); + + $i = q("select * from item where id = %d and uid = %d limit 1", + intval($item_id), + intval(local_user()) + ); + + if(! $i) + return; + + $i = fetch_post_tags($i); + + $item = $i[0]; + + $terms = get_terms_oftype($item['term'],TERM_BOOKMARK); + + if($terms && (! $item['item_restrict'])) { + require_once('include/bookmarks.php'); + + $s = q("select * from xchan where xchan_hash = '%s' limit 1", + dbesc($item['author_xchan']) + ); + if(! $s) { + logger('mod_bookmarks: author lookup failed.'); + killme(); + } + foreach($terms as $t) { + bookmark_add($u,$s[0],$t,$item['item_private']); + info( t('Bookmark added') . EOL); + } + } + killme(); +} + +function bookmarks_content(&$a) { + if(! local_user()) { + notice( t('Permission denied.') . EOL); + return; + } + + + require_once('include/menu.php'); + + $o = '<h3>' . t('My Bookmarks') . '</h3>'; + + $x = menu_list(local_user(),'',MENU_BOOKMARK); + + if($x) { + foreach($x as $xx) { + $y = menu_fetch($xx['menu_name'],local_user(),get_observer_hash()); + $o .= menu_render($y,true); + } + } + + $o .= '<h3>' . t('My Connections Bookmarks') . '</h3>'; + + + $x = menu_list(local_user(),'',MENU_SYSTEM|MENU_BOOKMARK); + + if($x) { + foreach($x as $xx) { + $y = menu_fetch($xx['menu_name'],local_user(),get_observer_hash()); + $o .= menu_render($y,true); + } + } + + + + return $o; + +} + diff --git a/mod/channel.php b/mod/channel.php index 149936dd7..34a1e2dda 100644 --- a/mod/channel.php +++ b/mod/channel.php @@ -47,6 +47,8 @@ function channel_content(&$a, $update = 0, $load = false) { $category = $datequery = $datequery2 = ''; + $mid = $_GET['mid']; + $datequery = ((x($_GET,'dend') && is_a_date_arg($_GET['dend'])) ? notags($_GET['dend']) : ''); $datequery2 = ((x($_GET,'dbegin') && is_a_date_arg($_GET['dbegin'])) ? notags($_GET['dbegin']) : ''); @@ -132,19 +134,28 @@ function channel_content(&$a, $update = 0, $load = false) { if(($update) && (! $load)) { - - $r = q("SELECT distinct parent AS `item_id` from item - left join abook on item.author_xchan = abook.abook_xchan - WHERE uid = %d AND item_restrict = 0 - AND (item_flags & %d) AND ( item_flags & %d ) - AND ((abook.abook_flags & %d) = 0 or abook.abook_flags is null) - $sql_extra - ORDER BY created DESC", - intval($a->profile['profile_uid']), - intval(ITEM_WALL), - intval(ITEM_UNSEEN), - intval(ABOOK_FLAG_BLOCKED) - ); + if ($mid) { + $r = q("SELECT parent AS item_id from item where mid = '%s' and uid = %d AND item_restrict = 0 + AND (item_flags & %d) AND (item_flags & %d) $sql_extra limit 1", + dbesc($mid), + intval($a->profile['profile_uid']), + intval(ITEM_WALL), + intval(ITEM_UNSEEN) + ); + } else { + $r = q("SELECT distinct parent AS `item_id` from item + left join abook on item.author_xchan = abook.abook_xchan + WHERE uid = %d AND item_restrict = 0 + AND (item_flags & %d) AND ( item_flags & %d ) + AND ((abook.abook_flags & %d) = 0 or abook.abook_flags is null) + $sql_extra + ORDER BY created DESC", + intval($a->profile['profile_uid']), + intval(ITEM_WALL), + intval(ITEM_UNSEEN), + intval(ABOOK_FLAG_BLOCKED) + ); + } } else { @@ -166,19 +177,31 @@ function channel_content(&$a, $update = 0, $load = false) { $pager_sql = sprintf(" LIMIT %d, %d ",intval($a->pager['start']), intval($a->pager['itemspage'])); if($load || ($_COOKIE['jsAvailable'] != 1)) { - $r = q("SELECT distinct id AS item_id FROM item - left join abook on item.author_xchan = abook.abook_xchan - WHERE uid = %d AND item_restrict = 0 - AND (item_flags & %d) and (item_flags & %d) - AND ((abook.abook_flags & %d) = 0 or abook.abook_flags is null) - $sql_extra $sql_extra2 - ORDER BY created DESC $pager_sql ", - intval($a->profile['profile_uid']), - intval(ITEM_WALL), - intval(ITEM_THREAD_TOP), - intval(ABOOK_FLAG_BLOCKED) - - ); + if ($mid) { + $r = q("SELECT parent AS item_id from item where mid = '%s' and uid = %d AND item_restrict = 0 + AND (item_flags & %d) $sql_extra limit 1", + dbesc($mid), + intval($a->profile['profile_uid']), + intval(ITEM_WALL) + ); + if (! $r) { + notice( t('Permission denied.') . EOL); + } + + } else { + $r = q("SELECT distinct id AS item_id FROM item + left join abook on item.author_xchan = abook.abook_xchan + WHERE uid = %d AND item_restrict = 0 + AND (item_flags & %d) and (item_flags & %d) + AND ((abook.abook_flags & %d) = 0 or abook.abook_flags is null) + $sql_extra $sql_extra2 + ORDER BY created DESC $pager_sql ", + intval($a->profile['profile_uid']), + intval(ITEM_WALL), + intval(ITEM_THREAD_TOP), + intval(ABOOK_FLAG_BLOCKED) + ); + } } else { $r = array(); @@ -202,6 +225,12 @@ function channel_content(&$a, $update = 0, $load = false) { $items = fetch_post_tags($items, true); $items = conv_sort($items,'created'); + if ($load && $mid && (! count($items))) { + // This will happen if we don't have sufficient permissions + // to view the parent item (or the item itself if it is toplevel) + notice( t('Permission denied.') . EOL); + } + } else { $items = array(); } @@ -233,9 +262,10 @@ function channel_content(&$a, $update = 0, $load = false) { '$page' => (($a->pager['page'] != 1) ? $a->pager['page'] : 1), '$search' => '', '$order' => '', + '$list' => ((x($_REQUEST,'list')) ? intval($_REQUEST['list']) : 0), '$file' => '', '$cats' => (($category) ? $category : ''), - '$mid' => '', + '$mid' => $mid, '$dend' => $datequery, '$dbegin' => $datequery2 )); @@ -266,5 +296,8 @@ function channel_content(&$a, $update = 0, $load = false) { if((! $update) || ($_COOKIE['jsAvailable'] != 1)) $o .= alt_pager($a,count($items)); + if($mid) + $o .= '<div id="content-complete"></div>'; + return $o; } diff --git a/mod/chanview.php b/mod/chanview.php index f183fbdf1..ca3410c8f 100644 --- a/mod/chanview.php +++ b/mod/chanview.php @@ -38,17 +38,16 @@ function chanview_content(&$a) { ); } if($r) { - $xchan = $r[0]; + $a->poi = $r[0]; } - // Here, let's see if we have an xchan. If we don't, how we proceed is determined by what // info we do have. If it's a URL, we can offer to visit it directly. If it's a webbie or // address, we can and should try to import it. If it's just a hash, we can't continue, but we // probably wouldn't have a hash if we don't already have an xchan for this channel. - if(! $xchan) { + if(! $a->poi) { logger('mod_chanview: fallback'); // This is hackish - construct a zot address from the url if($_REQUEST['url']) { @@ -68,31 +67,27 @@ function chanview_content(&$a) { dbesc($_REQUEST['address']) ); if($r) - $xchan = $r[0]; + $a->poi = $r[0]; } } } - if(! $xchan) { + if(! $a->poi) { notice( t('Channel not found.') . EOL); return; } - $url = (($observer) - ? z_root() . '/magic?f=&dest=' . $xchan['xchan_url'] . '&addr=' . $xchan['xchan_addr'] - : $xchan['xchan_url'] - ); + + $url = $a->poi['xchan_url']; + if($observer) + $url = zid($url); // let somebody over-ride the iframed viewport presentation - if(local_user() && get_pconfig(local_user(),'system','chanview_full')) + if((! local_user()) || (get_pconfig(local_user(),'system','chanview_full'))) goaway($url); - - if($xchan['xchan_hash']) - $a->set_widget('vcard',vcard_from_xchan($xchan,$observer,'chanview')); - $o = replace_macros(get_markup_template('chanview.tpl'),array( '$url' => $url, '$full' => t('toggle full screen mode') diff --git a/mod/chat.php b/mod/chat.php new file mode 100644 index 000000000..0f2b94b9d --- /dev/null +++ b/mod/chat.php @@ -0,0 +1,229 @@ +<?php /** @file */ + +require_once('include/chat.php'); +require_once('include/bookmarks.php'); + +function chat_init(&$a) { + + $which = null; + if(argc() > 1) + $which = argv(1); + if(! $which) { + if(local_user()) { + $channel = $a->get_channel(); + if($channel && $channel['channel_address']) + $which = $channel['channel_address']; + } + } + if(! $which) { + notice( t('You must be logged in to see this page.') . EOL ); + return; + } + + $profile = 0; + $channel = $a->get_channel(); + + if((local_user()) && (argc() > 2) && (argv(2) === 'view')) { + $which = $channel['channel_address']; + $profile = argv(1); + } + + $a->page['htmlhead'] .= '<link rel="alternate" type="application/atom+xml" href="' . $a->get_baseurl() . '/feed/' . $which .'" />' . "\r\n" ; + + // Run profile_load() here to make sure the theme is set before + // we start loading content + + profile_load($a,$which,$profile); + +} + +function chat_post(&$a) { + + if($_POST['room_name']) + $room = strip_tags(trim($_POST['room_name'])); + + if((! $room) || (! local_user())) + return; + + $channel = $a->get_channel(); + + + if($_POST['action'] === 'drop') { + chatroom_destroy($channel,array('cr_name' => $room)); + goaway(z_root() . '/chat/' . $channel['channel_address']); + } + + + $arr = array('name' => $room); + $arr['allow_gid'] = perms2str($_REQUEST['group_allow']); + $arr['allow_cid'] = perms2str($_REQUEST['contact_allow']); + $arr['deny_gid'] = perms2str($_REQUEST['group_deny']); + $arr['deny_cid'] = perms2str($_REQUEST['contact_deny']); + + chatroom_create($channel,$arr); + + $x = q("select cr_id from chatroom where cr_name = '%s' and cr_uid = %d limit 1", + dbesc($room), + intval(local_user()) + ); + + if($x) + goaway(z_root() . '/chat/' . $channel['channel_address'] . '/' . $x[0]['cr_id']); + + // that failed. Try again perhaps? + + goaway(z_root() . '/chat/' . $channel['channel_address'] . '/new'); + + +} + + +function chat_content(&$a) { + + if(local_user()) + $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) { + $private = ((($x[0]['allow_cid']) || ($x[0]['allow_gid']) || ($x[0]['deny_cid']) || ($x[0]['deny_gid'])) ? true : false); + $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( + '$room_name' => $room_name, + '$room_id' => $room_id, + '$baseurl' => z_root(), + '$nickname' => argv(1), + '$submit' => t('Submit'), + '$leave' => t('Leave 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_user() && argc() > 2 && argv(2) === 'new') { + + + + $channel_acl = array( + 'allow_cid' => $channel['channel_allow_cid'], + 'allow_gid' => $channel['channel_allow_gid'], + 'deny_cid' => $channel['channel_deny_cid'], + 'deny_gid' => $channel['channel_deny_gid'] + ); + + 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'),'', ''), + '$acl' => populate_acl($channel_acl), + '$submit' => t('Submit') + )); + return $o; + } + + + + + + + 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_user() && local_user() == $a->profile['profile_uid']) ? 1 : 0) + )); + + return $o; + +}
\ No newline at end of file diff --git a/mod/chatsvc.php b/mod/chatsvc.php new file mode 100644 index 000000000..e6590f57a --- /dev/null +++ b/mod/chatsvc.php @@ -0,0 +1,150 @@ +<?php /** @file */ + +require_once('include/security.php'); + +function chatsvc_init(&$a) { + +//logger('chatsvc'); + + $ret = array('success' => false); + + $a->data['chat']['room_id'] = intval($_REQUEST['room_id']); + $x = q("select cr_uid from chatroom where cr_id = %d and cr_id != 0 limit 1", + intval($a->data['chat']['room_id']) + ); + if(! $x) + json_return_and_die($ret); + + $a->data['chat']['uid'] = $x[0]['cr_uid']; + + if(! perm_is_allowed($a->data['chat']['uid'],get_observer_hash(),'chat')) { + json_return_and_die($ret); + } + +} + +function chatsvc_post(&$a) { + + $ret = array('success' => false); + + $room_id = $a->data['chat']['room_id']; + $text = escape_tags($_REQUEST['chat_text']); + if(! $text) + return; + + $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); + + $x = q("insert into chat ( chat_room, chat_xchan, created, chat_text ) + values( %d, '%s', '%s', '%s' )", + intval($a->data['chat']['room_id']), + dbesc(get_observer_hash()), + dbesc(datetime_convert()), + dbesc($text) + ); + $ret['success'] = true; + json_return_and_die($ret); +} + +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", + 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); + +} +
\ No newline at end of file diff --git a/mod/cloud.php b/mod/cloud.php index cdd926444..3606325bd 100644 --- a/mod/cloud.php +++ b/mod/cloud.php @@ -1,23 +1,5 @@ <?php - // This module is currently !!!HIGHLY EXPERIMENTAL!!! - // You should think twice before running this on a production server - // as security mechanisms are not yet implemented and those that - // are implemented probably don't work. - - // DAV mounts will probably fail if you don't use SSL, because some platforms refuse to send - // basic auth over non-encrypted connections. - // One could use digest auth - but then one has to calculate the A1 digest and store it for - // all acounts. We aren't doing that. We have a stored password already. We don't need another - // one. The login unfortunately is the channel nickname (webbie) as we have no way of passing - // the destination channel to DAV. You should be able to login with your account credentials - // and be directed to your default channel. - - // This interface does not yet support Red stored files. Consider any content in your "store" - // directory to be throw-away until advised otherwise. - - - use Sabre\DAV; require_once('vendor/autoload.php'); @@ -44,64 +26,109 @@ -class RedBasicAuth extends Sabre\DAV\Auth\Backend\AbstractBasic { - protected function validateUserPass($username, $password) { - require_once('include/auth.php'); - $record = account_verify_password($email,$pass); - if($record && $record['account_default_channel']) { - $r = q("select * from channel where channel_account_id = %d and channel_id = %d limit 1", - intval($record['account_id']), - intval($record['account_default_channel']) - ); - if($r) { - $this->currentUser = $r[0]['channel_address']; - return true; - } - } - $r = q("select channel_account_id from channel where channel_address = '%s' limit 1", - dbesc($username) - ); - if($r) { - $x = q("select * from account where account_id = %d limit 1", - intval($r[0]['channel_account_id']) - ); - if($x) { - foreach($x as $record) { - if(($record['account_flags'] == ACCOUNT_OK) || ($record['account_flags'] == ACCOUNT_UNVERIFIED) - && (hash('whirlpool',$record['account_salt'] . $password) === $record['account_password'])) { - logger('(DAV) RedBasicAuth: password verified for ' . $username); - return true; - } - } - } - } - logger('(DAV) RedBasicAuth: password failed for ' . $username); - return false; - } -} +function cloud_init(&$a) { + + require_once('include/reddav.php'); + + if(! is_dir('store')) + mkdir('store',STORAGE_DEFAULT_PERMISSIONS,false); + + $which = null; + if(argc() > 1) + $which = argv(1); + + $profile = 0; + $channel = $a->get_channel(); + + $a->page['htmlhead'] .= '<link rel="alternate" type="application/atom+xml" href="' . $a->get_baseurl() . '/feed/' . $which .'" />' . "\r\n" ; + + if($which) + profile_load($a,$which,$profile); + + + + + $auth = new RedBasicAuth(); + + $ob_hash = get_observer_hash(); -function cloud_init() { + if($ob_hash) { + if(local_user()) { + $channel = $a->get_channel(); + $auth->setCurrentUser($channel['channel_address']); + $auth->channel_name = $channel['channel_address']; + $auth->channel_id = $channel['channel_id']; + $auth->channel_hash = $channel['channel_hash']; + if($channel['channel_timezone']) + $auth->timezone = $channel['channel_timezone']; + } + $auth->observer = $ob_hash; + } - if(! get_config('system','enable_cloud')) - killme(); + if($_GET['davguest']) + $_SESSION['davguest'] = true; - $rootDirectory = new DAV\FS\Directory('store'); + + + $_SERVER['QUERY_STRING'] = str_replace(array('?f=','&f='),array('',''),$_SERVER['QUERY_STRING']); + $_SERVER['QUERY_STRING'] = strip_zids($_SERVER['QUERY_STRING']); + $_SERVER['QUERY_STRING'] = preg_replace('/[\?&]davguest=(.*?)([\?&]|$)/ism','',$_SERVER['QUERY_STRING']); + + $_SERVER['REQUEST_URI'] = str_replace(array('?f=','&f='),array('',''),$_SERVER['REQUEST_URI']); + $_SERVER['REQUEST_URI'] = strip_zids($_SERVER['REQUEST_URI']); + $_SERVER['REQUEST_URI'] = preg_replace('/[\?&]davguest=(.*?)([\?&]|$)/ism','',$_SERVER['REQUEST_URI']); + + $rootDirectory = new RedDirectory('/',$auth); $server = new DAV\Server($rootDirectory); - $lockBackend = new DAV\Locks\Backend\File('store/data/locks'); + $lockBackend = new DAV\Locks\Backend\File('store/[data]/locks'); $lockPlugin = new DAV\Locks\Plugin($lockBackend); $server->addPlugin($lockPlugin); - $auth = new RedBasicAuth(); + // The next section of code allows us to bypass prompting for http-auth if a FILE is being accessed anonymously and permissions + // allow this. This way one can create hotlinks to public media files in their cloud and anonymous viewers won't get asked to login. + // If a DIRECTORY is accessed or there are permission issues accessing the file and we aren't previously authenticated via zot, + // prompt for HTTP-auth. This will be the default case for mounting a DAV directory. + // In order to avoid prompting for passwords for viewing a DIRECTORY, add the URL query parameter 'davguest=1' - $auth->Authenticate($server,'Red Matrix'); + $isapublic_file = false; + $davguest = ((x($_SESSION,'davguest')) ? true : false); + + if((! $auth->observer) && ($_SERVER['REQUEST_METHOD'] === 'GET')) { + try { + $x = RedFileData('/' . $a->cmd,$auth); + if($x instanceof RedFile) + $isapublic_file = true; + } + catch ( Exception $e ) { + $isapublic_file = false; + } + } + + if((! $auth->observer) && (! $isapublic_file) && (! $davguest)) { + try { + $auth->Authenticate($server, t('Red Matrix - Guests: Username: {your email address}, Password: +++')); + } + catch ( Exception $e) { + logger('mod_cloud: auth exception' . $e->getMessage()); + http_status_exit($e->getHTTPCode(),$e->getMessage()); + } + } + +// $browser = new DAV\Browser\Plugin(); + + $browser = new RedBrowser($auth); + + $auth->setBrowserPlugin($browser); + + + $server->addPlugin($browser); // All we need to do now, is to fire up the server $server->exec(); - exit; - + killme(); }
\ No newline at end of file diff --git a/mod/common.php b/mod/common.php index 4afaf37eb..e19a9d3a9 100644 --- a/mod/common.php +++ b/mod/common.php @@ -21,14 +21,6 @@ function common_init(&$a) { } -function common_aside(&$a) { - if(! $a->profile['profile_uid']) - return; - - profile_create_sidebar($a); -} - - function common_content(&$a) { $o = ''; diff --git a/mod/connect.php b/mod/connect.php index 93f994af5..f7748bcaf 100644 --- a/mod/connect.php +++ b/mod/connect.php @@ -23,10 +23,6 @@ function connect_init(&$a) { $a->data['channel'] = $r[0]; profile_load($a,$which,''); - - profile_create_sidebar($a,false); - - } function connect_post(&$a) { diff --git a/mod/connections.php b/mod/connections.php index d1bb33748..e36cb5fc7 100644 --- a/mod/connections.php +++ b/mod/connections.php @@ -13,46 +13,12 @@ function connections_init(&$a) { if(! local_user()) return; - if((argc() == 2) && intval(argv(1))) { - $r = q("SELECT abook.*, xchan.* - FROM abook left join xchan on abook_xchan = xchan_hash - WHERE abook_channel = %d and abook_id = %d LIMIT 1", - intval(local_user()), - intval(argv(1)) - ); - if($r) { - $a->data['abook'] = $r[0]; - } - } - $channel = $a->get_channel(); if($channel) head_set_icon($channel['xchan_photo_s']); } -function connections_aside(&$a) { - - - if (! local_user()) - return; - - if(x($a->data,'abook')) { - $a->set_widget('vcard',vcard_from_xchan($a->data['abook'],$a->get_observer())); - } - else { - $a->set_widget('follow', widget_follow(array())); - $a->set_widget('collections', group_side('connections','group',false,0,((array_key_exists('abook',$a->data)) ? $a->data['abook']['abook_xchan'] : ''))); - } - - - $a->set_widget('suggest',widget_suggestions(array())); - $a->set_widget('findpeople',findpeople_widget()); - -} - - - function connections_post(&$a) { if(! local_user()) @@ -75,7 +41,7 @@ function connections_post(&$a) { call_hooks('contact_edit_post', $_POST); - $profile_id = $_POST['profile-assign']; + $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), @@ -108,6 +74,7 @@ function connections_post(&$a) { $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; @@ -122,6 +89,7 @@ function connections_post(&$a) { intval($contact_id), intval(local_user()) ); + if($r) info( t('Connection updated.') . EOL); else @@ -202,319 +170,6 @@ function connections_content(&$a) { return login(); } - if(argc() == 3) { - - $contact_id = intval(argv(1)); - if(! $contact_id) - return; - - $cmd = argv(2); - - $orig_record = q("SELECT abook.*, xchan.* FROM abook left join xchan on abook_xchan = xchan_hash - WHERE abook_id = %d AND abook_channel = %d AND NOT ( abook_flags & %d ) and not ( abook_flags & %d ) LIMIT 1", - intval($contact_id), - intval(local_user()), - intval(ABOOK_FLAG_SELF), - // allow drop even if pending, just duplicate the self query - intval(($cmd === 'drop') ? ABOOK_FLAG_SELF : ABOOK_FLAG_PENDING) - ); - - if(! count($orig_record)) { - notice( t('Could not access address book record.') . EOL); - goaway($a->get_baseurl(true) . '/connections'); - } - - if($cmd === 'update') { - - // pull feed and consume it, which should subscribe to the hub. - proc_run('php',"include/poller.php","$contact_id"); - goaway($a->get_baseurl(true) . '/connections/' . $contact_id); - - } - - if($cmd === 'refresh') { - if(! zot_refresh($orig_record[0],get_app()->get_channel())) - notice( t('Refresh failed - channel is currently unavailable.') ); - goaway($a->get_baseurl(true) . '/connections/' . $contact_id); - } - - if($cmd === 'block') { - if(abook_toggle_flag($orig_record[0],ABOOK_FLAG_BLOCKED)) { - info((($orig_record[0]['abook_flags'] & ABOOK_FLAG_BLOCKED) - ? t('Channel has been unblocked') - : t('Channel has been blocked')) . EOL ); - connections_clone($a); - } - else - notice(t('Unable to set address book parameters.') . EOL); - goaway($a->get_baseurl(true) . '/connections/' . $contact_id); - } - - if($cmd === 'ignore') { - if(abook_toggle_flag($orig_record[0],ABOOK_FLAG_IGNORED)) { - info((($orig_record[0]['abook_flags'] & ABOOK_FLAG_IGNORED) - ? t('Channel has been unignored') - : t('Channel has been ignored')) . EOL ); - connections_clone($a); - } - else - notice(t('Unable to set address book parameters.') . EOL); - goaway($a->get_baseurl(true) . '/connections/' . $contact_id); - } - - if($cmd === 'archive') { - if(abook_toggle_flag($orig_record[0],ABOOK_FLAG_ARCHIVED)) { - info((($orig_record[0]['abook_flags'] & ABOOK_FLAG_ARCHIVED) - ? t('Channel has been unarchived') - : t('Channel has been archived')) . EOL ); - connections_clone($a); - } - else - notice(t('Unable to set address book parameters.') . EOL); - goaway($a->get_baseurl(true) . '/connections/' . $contact_id); - } - - if($cmd === 'hide') { - if(abook_toggle_flag($orig_record[0],ABOOK_FLAG_HIDDEN)) { - info((($orig_record[0]['abook_flags'] & ABOOK_FLAG_HIDDEN) - ? t('Channel has been unhidden') - : t('Channel has been hidden')) . EOL ); - connections_clone($a); - } - else - notice(t('Unable to set address book parameters.') . EOL); - goaway($a->get_baseurl(true) . '/connections/' . $contact_id); - } - - // We'll prevent somebody from unapproving a contact. - - if($cmd === 'approve') { - if($orig_record[0]['abook_flags'] & ABOOK_FLAG_PENDING) { - if(abook_toggle_flag($orig_record[0],ABOOK_FLAG_PENDING)) { - info((($orig_record[0]['abook_flags'] & ABOOK_FLAG_PENDING) - ? t('Channel has been approved') - : t('Channel has been unapproved')) . EOL ); - connections_clone($a); - } - else - notice(t('Unable to set address book parameters.') . EOL); - } - goaway($a->get_baseurl(true) . '/connections/' . $contact_id); - } - - - if($cmd === 'drop') { - - require_once('include/Contact.php'); -// FIXME -// terminate_friendship($a->get_channel(),$orig_record[0]); - - contact_remove(local_user(), $orig_record[0]['abook_id']); -// FIXME - send to clones - info( t('Contact has been removed.') . EOL ); - if(x($_SESSION,'return_url')) - goaway($a->get_baseurl(true) . '/' . $_SESSION['return_url']); - goaway($a->get_baseurl(true) . '/contacts'); - - } - } - - if((x($a->data,'abook')) && (is_array($a->data['abook']))) { - - $contact_id = $a->data['abook']['abook_id']; - $contact = $a->data['abook']; - - - $tabs = array( - - array( - 'label' => t('View Profile'), - 'url' => $a->get_baseurl(true) . '/chanview/?f=&cid=' . $contact['abook_id'], - 'sel' => '', - 'title' => sprintf( t('View %s\'s profile'), $contact['xchan_name']), - ), - - array( - 'label' => t('Refresh Permissions'), - 'url' => $a->get_baseurl(true) . '/connections/' . $contact['abook_id'] . '/refresh', - 'sel' => '', - 'title' => t('Fetch updated permissions'), - ), - - array( - 'label' => t('Recent Activity'), - 'url' => $a->get_baseurl(true) . '/network/?f=&cid=' . $contact['abook_id'], - 'sel' => '', - 'title' => t('View recent posts and comments'), - ), - - array( - 'label' => (($contact['abook_flags'] & ABOOK_FLAG_BLOCKED) ? t('Unblock') : t('Block')), - 'url' => $a->get_baseurl(true) . '/connections/' . $contact['abook_id'] . '/block', - 'sel' => (($contact['abook_flags'] & ABOOK_FLAG_BLOCKED) ? 'active' : ''), - 'title' => t('Block or Unblock this connection'), - ), - - array( - 'label' => (($contact['abook_flags'] & ABOOK_FLAG_IGNORED) ? t('Unignore') : t('Ignore')), - 'url' => $a->get_baseurl(true) . '/connections/' . $contact['abook_id'] . '/ignore', - 'sel' => (($contact['abook_flags'] & ABOOK_FLAG_IGNORED) ? 'active' : ''), - 'title' => t('Ignore or Unignore this connection'), - ), - array( - 'label' => (($contact['abook_flags'] & ABOOK_FLAG_ARCHIVED) ? t('Unarchive') : t('Archive')), - 'url' => $a->get_baseurl(true) . '/connections/' . $contact['abook_id'] . '/archive', - 'sel' => (($contact['abook_flags'] & ABOOK_FLAG_ARCHIVED) ? 'active' : ''), - 'title' => t('Archive or Unarchive this connection'), - ), - array( - 'label' => (($contact['abook_flags'] & ABOOK_FLAG_HIDDEN) ? t('Unhide') : t('Hide')), - 'url' => $a->get_baseurl(true) . '/connections/' . $contact['abook_id'] . '/hide', - 'sel' => (($contact['abook_flags'] & ABOOK_FLAG_HIDDEN) ? 'active' : ''), - 'title' => t('Hide or Unhide this connection'), - ), - - array( - 'label' => t('Delete'), - 'url' => $a->get_baseurl(true) . '/connections/' . $contact['abook_id'] . '/drop', - 'sel' => '', - 'title' => t('Delete this connection'), - ), - - ); - - $self = false; - - if(! ($contact['abook_flags'] & ABOOK_FLAG_SELF)) { - $tab_tpl = get_markup_template('common_tabs.tpl'); - $t = replace_macros($tab_tpl, array('$tabs'=>$tabs)); - } - else - $self = true; - - $a->page['htmlhead'] .= replace_macros(get_markup_template('contact_head.tpl'), array( - '$baseurl' => $a->get_baseurl(true), - '$editselect' => $editselect - )); - - require_once('include/contact_selectors.php'); - - $tpl = get_markup_template("abook_edit.tpl"); - - if(feature_enabled(local_user(),'affinity')) { - - $slider_tpl = get_markup_template('contact_slider.tpl'); - $slide = replace_macros($slider_tpl,array( - '$me' => t('Me'), - '$val' => (($contact['abook_closeness']) ? $contact['abook_closeness'] : 99), - '$intimate' => t('Best Friends'), - '$friends' => t('Friends'), - '$oldfriends' => t('Former Friends'), - '$acquaintances' => t('Acquaintances'), - '$world' => t('Unknown') - )); - } - - $perms = array(); - $channel = $a->get_channel(); - - $global_perms = get_perms(); - $existing = get_all_perms(local_user(),$contact['abook_xchan']); - - $unapproved = array('pending', t('Approve this connection'), '', t('Accept connection to allow communication')); - - foreach($global_perms as $k => $v) { - $thisperm = (($contact['abook_my_perms'] & $v[1]) ? "1" : ''); - - // For auto permissions (when $self is true) we don't want to look at existing - // permissions because they are enabled for the channel owner - - if((! $self) && ($existing[$k])) - $thisperm = "1"; - - $perms[] = array('perms_' . $k, $v[3], (($contact['abook_their_perms'] & $v[1]) ? "1" : ""),$thisperm, $v[1], (($channel[$v[0]] == PERMS_SPECIFIC) ? '' : '1'), $v[4]); - } - - $o .= replace_macros($tpl,array( - - '$header' => (($self) ? t('Automatic Permissions Settings') : sprintf( t('Connections: settings for %s'),$contact['xchan_name'])), - '$addr' => $contact['xchan_addr'], - '$notself' => (($self) ? '' : '1'), - '$self' => (($self) ? '1' : ''), - '$autolbl' => t('When receiving a channel introduction, any permissions provided here will be applied to the new connection automatically and the introduction approved. Leave this page if you do not wish to use this feature.'), - '$viewprof' => t('View Profile'), - '$lbl_slider' => t('Slide to adjust your degree of friendship'), - '$slide' => $slide, - '$tabs' => $t, - '$tab_str' => $tab_str, - '$is_pending' => (($contact['abook_flags'] & ABOOK_FLAG_PENDING) ? 1 : ''), - '$unapproved' => $unapproved, - '$inherited' => t('inherited'), - '$approve' => t('Approve this connection'), - '$noperms' => (((! $self) && (! $contact['abook_my_perms'])) ? t('Connection has no individual permissions!') : ''), - '$noperm_desc' => (((! $self) && (! $contact['abook_my_perms'])) ? t('This may be appropriate based on your <a href="settings">privacy settings</a>, though you may wish to review the "Advanced Permissions".') : ''), - '$submit' => t('Submit'), - '$lbl_vis1' => t('Profile Visibility'), - '$lbl_vis2' => sprintf( t('Please choose the profile you would like to display to %s when viewing your profile securely.'), $contact['xchan_name']), - '$lbl_info1' => t('Contact Information / Notes'), - '$infedit' => t('Edit contact notes'), - '$close' => $contact['abook_closeness'], - '$them' => t('Their Settings'), - '$me' => t('My Settings'), - '$perms' => $perms, - '$forum' => t('Forum Members'), - '$soapbox' => t('Soapbox'), - '$full' => t('Full Sharing'), - '$cautious' => t('Cautious Sharing'), - '$follow' => t('Follow Only'), - '$permlbl' => t('Individual Permissions'), - '$permnote' => t('Some permissions may be inherited from your channel <a href="settings">privacy settings</a>, which have higher priority. Changing those inherited settings on this page will have no effect.'), - '$advanced' => t('Advanced Permissions'), - '$quick' => t('Quick Links'), - '$common_link' => $a->get_baseurl(true) . '/common/loc/' . local_user() . '/' . $contact['id'], - '$all_friends' => $all_friends, - '$relation_text' => $relation_text, - '$visit' => sprintf( t('Visit %s\'s profile - %s'),$contact['xchan_name'],$contact['xchan_url']), - '$blockunblock' => t('Block/Unblock contact'), - '$ignorecont' => t('Ignore contact'), - '$lblcrepair' => t("Repair URL settings"), - '$lblrecent' => t('View conversations'), - '$lblsuggest' => $lblsuggest, - '$delete' => t('Delete contact'), - '$poll_interval' => contact_poll_interval($contact['priority'],(! $poll_enabled)), - '$poll_enabled' => $poll_enabled, - '$lastupdtext' => t('Last update:'), - '$lost_contact' => $lost_contact, - '$updpub' => t('Update public posts'), - '$last_update' => $last_update, - '$udnow' => t('Update now'), - '$profile_select' => contact_profile_assign($contact['abook_profile']), - '$multiprofs' => feature_enabled(local_user(),'multi_profiles'), - '$contact_id' => $contact['abook_id'], - '$block_text' => (($contact['blocked']) ? t('Unblock') : t('Block') ), - '$ignore_text' => (($contact['readonly']) ? t('Unignore') : t('Ignore') ), - '$blocked' => (($contact['blocked']) ? t('Currently blocked') : ''), - '$ignored' => (($contact['readonly']) ? t('Currently ignored') : ''), - '$archived' => (($contact['archive']) ? t('Currently archived') : ''), - '$pending' => (($contact['archive']) ? t('Currently pending') : ''), - '$hidden' => array('hidden', t('Hide this contact from others'), ($contact['hidden'] == 1), t('Replies/likes to your public posts <strong>may</strong> still be visible')), - '$photo' => $contact['photo'], - '$name' => $contact['name'], - '$dir_icon' => $dir_icon, - '$alt_text' => $alt_text, - '$sparkle' => $sparkle, - '$url' => $url - - )); - - $arr = array('contact' => $contact,'output' => $o); - - call_hooks('contact_edit', $arr); - - return $arr['output']; - - } - $blocked = false; $hidden = false; $ignored = false; @@ -647,9 +302,10 @@ function connections_content(&$a) { $r = q("SELECT COUNT(abook.abook_id) AS total FROM abook left join xchan on abook.abook_xchan = xchan.xchan_hash - where abook_channel = %d and not (abook_flags & %d) $sql_extra $sql_extra2 ", + where abook_channel = %d and not (abook_flags & %d) and not (xchan_flags & %d ) $sql_extra $sql_extra2 ", intval(local_user()), - intval(ABOOK_FLAG_SELF) + intval(ABOOK_FLAG_SELF), + intval(XCHAN_FLAGS_DELETED) ); if(count($r)) { $a->set_pager_total($r[0]['total']); @@ -657,9 +313,10 @@ function connections_content(&$a) { } $r = q("SELECT abook.*, xchan.* FROM abook left join xchan on abook.abook_xchan = xchan.xchan_hash - WHERE abook_channel = %d and not (abook_flags & %d) $sql_extra $sql_extra2 ORDER BY xchan_name LIMIT %d , %d ", + WHERE abook_channel = %d and not (abook_flags & %d) and not ( xchan_flags & %d) $sql_extra $sql_extra2 ORDER BY xchan_name LIMIT %d , %d ", intval(local_user()), intval(ABOOK_FLAG_SELF), + intval(XCHAN_FLAGS_DELETED), intval($a->pager['start']), intval($a->pager['itemspage']) ); @@ -680,7 +337,7 @@ function connections_content(&$a) { 'name' => $rr['xchan_name'], 'username' => $rr['xchan_name'], 'sparkle' => $sparkle, - 'link' => z_root() . '/connections/' . $rr['abook_id'], + 'link' => z_root() . '/connedit/' . $rr['abook_id'], 'url' => $rr['xchan_url'], 'network' => network_to_name($rr['network']), ); diff --git a/mod/connedit.php b/mod/connedit.php new file mode 100644 index 000000000..c6f64ccfc --- /dev/null +++ b/mod/connedit.php @@ -0,0 +1,500 @@ +<?php + +require_once('include/Contact.php'); +require_once('include/socgraph.php'); +require_once('include/contact_selectors.php'); +require_once('include/group.php'); +require_once('include/contact_widgets.php'); +require_once('include/zot.php'); +require_once('include/widgets.php'); + +function connedit_init(&$a) { + + if(! local_user()) + return; + + if((argc() == 2) && intval(argv(1))) { + $r = q("SELECT abook.*, xchan.* + FROM abook left join xchan on abook_xchan = xchan_hash + WHERE abook_channel = %d and abook_id = %d LIMIT 1", + intval(local_user()), + intval(argv(1)) + ); + if($r) { + $a->poi = $r[0]; + } + } + + $channel = $a->get_channel(); + if($channel) + head_set_icon($channel['xchan_photo_s']); + +} + +function connedit_post(&$a) { + + if(! local_user()) + 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_user()) + ); + + if(! $orig_record) { + notice( t('Could not access contact record.') . EOL); + goaway($a->get_baseurl(true) . '/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_user()) + ); + 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 + where abook_id = %d AND abook_channel = %d LIMIT 1", + dbesc($profile_id), + intval($abook_my_perms), + intval($closeness), + intval($abook_flags), + intval($contact_id), + intval(local_user()) + ); + + if($r) + info( t('Connection updated.') . EOL); + else + notice( t('Failed to update connection record.') . EOL); + + if($a->poi && $a->poi['abook_my_perms'] != $abook_my_perms + && (! ($a->poi['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_user(),$default_group); + if($g) + group_add_member(local_user(),'',$a->poi['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.* + FROM abook left join xchan on abook_xchan = xchan_hash + WHERE abook_channel = %d and abook_id = %d LIMIT 1", + intval(local_user()), + intval($contact_id) + ); + if($r) { + $a->poi = $r[0]; + } + + if($new_friend) { + $arr = array('channel_id' => local_user(), 'abook' => $a->poi); + call_hooks('accept_follow', $arr); + } + + connedit_clone($a); + + return; + +} + +function connedit_clone(&$a) { + + if(! $a->poi) + return; + $clone = $a->poi; + + unset($clone['abook_id']); + unset($clone['abook_account']); + unset($clone['abook_channel']); + + build_sync_packet(0 /* use the current local_user */, array('abook' => array($clone))); +} + + +function connedit_content(&$a) { + + $sort_type = 0; + $o = ''; + + + if(! local_user()) { + notice( t('Permission denied.') . EOL); + return login(); + } + + if(argc() == 3) { + + $contact_id = intval(argv(1)); + if(! $contact_id) + return; + + $cmd = argv(2); + + $orig_record = q("SELECT abook.*, xchan.* FROM abook left join xchan on abook_xchan = xchan_hash + WHERE abook_id = %d AND abook_channel = %d AND NOT ( abook_flags & %d ) and not ( abook_flags & %d ) LIMIT 1", + intval($contact_id), + intval(local_user()), + intval(ABOOK_FLAG_SELF), + // allow drop even if pending, just duplicate the self query + intval(($cmd === 'drop') ? ABOOK_FLAG_SELF : ABOOK_FLAG_PENDING) + ); + + if(! count($orig_record)) { + notice( t('Could not access address book record.') . EOL); + goaway($a->get_baseurl(true) . '/connections'); + } + + if($cmd === 'update') { + + // pull feed and consume it, which should subscribe to the hub. + proc_run('php',"include/poller.php","$contact_id"); + goaway($a->get_baseurl(true) . '/connedit/' . $contact_id); + + } + + if($cmd === 'refresh') { + if(! zot_refresh($orig_record[0],get_app()->get_channel())) + notice( t('Refresh failed - channel is currently unavailable.') ); + goaway($a->get_baseurl(true) . '/connedit/' . $contact_id); + } + + if($cmd === 'block') { + if(abook_toggle_flag($orig_record[0],ABOOK_FLAG_BLOCKED)) { + info((($orig_record[0]['abook_flags'] & ABOOK_FLAG_BLOCKED) + ? t('Channel has been unblocked') + : t('Channel has been blocked')) . EOL ); + connedit_clone($a); + } + else + notice(t('Unable to set address book parameters.') . EOL); + goaway($a->get_baseurl(true) . '/connedit/' . $contact_id); + } + + if($cmd === 'ignore') { + if(abook_toggle_flag($orig_record[0],ABOOK_FLAG_IGNORED)) { + info((($orig_record[0]['abook_flags'] & ABOOK_FLAG_IGNORED) + ? t('Channel has been unignored') + : t('Channel has been ignored')) . EOL ); + connedit_clone($a); + } + else + notice(t('Unable to set address book parameters.') . EOL); + goaway($a->get_baseurl(true) . '/connedit/' . $contact_id); + } + + if($cmd === 'archive') { + if(abook_toggle_flag($orig_record[0],ABOOK_FLAG_ARCHIVED)) { + info((($orig_record[0]['abook_flags'] & ABOOK_FLAG_ARCHIVED) + ? t('Channel has been unarchived') + : t('Channel has been archived')) . EOL ); + connedit_clone($a); + } + else + notice(t('Unable to set address book parameters.') . EOL); + goaway($a->get_baseurl(true) . '/connedit/' . $contact_id); + } + + if($cmd === 'hide') { + if(abook_toggle_flag($orig_record[0],ABOOK_FLAG_HIDDEN)) { + info((($orig_record[0]['abook_flags'] & ABOOK_FLAG_HIDDEN) + ? t('Channel has been unhidden') + : t('Channel has been hidden')) . EOL ); + connedit_clone($a); + } + else + notice(t('Unable to set address book parameters.') . EOL); + goaway($a->get_baseurl(true) . '/connedit/' . $contact_id); + } + + // We'll prevent somebody from unapproving a contact. + + if($cmd === 'approve') { + if($orig_record[0]['abook_flags'] & ABOOK_FLAG_PENDING) { + if(abook_toggle_flag($orig_record[0],ABOOK_FLAG_PENDING)) { + info((($orig_record[0]['abook_flags'] & ABOOK_FLAG_PENDING) + ? t('Channel has been approved') + : t('Channel has been unapproved')) . EOL ); + connedit_clone($a); + } + else + notice(t('Unable to set address book parameters.') . EOL); + } + goaway($a->get_baseurl(true) . '/connedit/' . $contact_id); + } + + + if($cmd === 'drop') { + + require_once('include/Contact.php'); +// FIXME +// terminate_friendship($a->get_channel(),$orig_record[0]); + + contact_remove(local_user(), $orig_record[0]['abook_id']); +// FIXME - send to clones + info( t('Contact has been removed.') . EOL ); + if(x($_SESSION,'return_url')) + goaway($a->get_baseurl(true) . '/' . $_SESSION['return_url']); + goaway($a->get_baseurl(true) . '/contacts'); + + } + } + + if($a->poi) { + + $contact_id = $a->poi['abook_id']; + $contact = $a->poi; + + + $tabs = array( + + array( + 'label' => t('View Profile'), + 'url' => $a->get_baseurl(true) . '/chanview/?f=&cid=' . $contact['abook_id'], + 'sel' => '', + 'title' => sprintf( t('View %s\'s profile'), $contact['xchan_name']), + ), + + array( + 'label' => t('Refresh Permissions'), + 'url' => $a->get_baseurl(true) . '/connedit/' . $contact['abook_id'] . '/refresh', + 'sel' => '', + 'title' => t('Fetch updated permissions'), + ), + + array( + 'label' => t('Recent Activity'), + 'url' => $a->get_baseurl(true) . '/network/?f=&cid=' . $contact['abook_id'], + 'sel' => '', + 'title' => t('View recent posts and comments'), + ), + + array( + 'label' => (($contact['abook_flags'] & ABOOK_FLAG_BLOCKED) ? t('Unblock') : t('Block')), + 'url' => $a->get_baseurl(true) . '/connedit/' . $contact['abook_id'] . '/block', + 'sel' => (($contact['abook_flags'] & ABOOK_FLAG_BLOCKED) ? 'active' : ''), + 'title' => t('Block or Unblock this connection'), + ), + + array( + 'label' => (($contact['abook_flags'] & ABOOK_FLAG_IGNORED) ? t('Unignore') : t('Ignore')), + 'url' => $a->get_baseurl(true) . '/connedit/' . $contact['abook_id'] . '/ignore', + 'sel' => (($contact['abook_flags'] & ABOOK_FLAG_IGNORED) ? 'active' : ''), + 'title' => t('Ignore or Unignore this connection'), + ), + array( + 'label' => (($contact['abook_flags'] & ABOOK_FLAG_ARCHIVED) ? t('Unarchive') : t('Archive')), + 'url' => $a->get_baseurl(true) . '/connedit/' . $contact['abook_id'] . '/archive', + 'sel' => (($contact['abook_flags'] & ABOOK_FLAG_ARCHIVED) ? 'active' : ''), + 'title' => t('Archive or Unarchive this connection'), + ), + array( + 'label' => (($contact['abook_flags'] & ABOOK_FLAG_HIDDEN) ? t('Unhide') : t('Hide')), + 'url' => $a->get_baseurl(true) . '/connedit/' . $contact['abook_id'] . '/hide', + 'sel' => (($contact['abook_flags'] & ABOOK_FLAG_HIDDEN) ? 'active' : ''), + 'title' => t('Hide or Unhide this connection'), + ), + + array( + 'label' => t('Delete'), + 'url' => $a->get_baseurl(true) . '/connedit/' . $contact['abook_id'] . '/drop', + 'sel' => '', + 'title' => t('Delete this connection'), + ), + + ); + + $self = false; + + if(! ($contact['abook_flags'] & ABOOK_FLAG_SELF)) { + $tab_tpl = get_markup_template('common_tabs.tpl'); + $t = replace_macros($tab_tpl, array('$tabs'=>$tabs)); + } + else + $self = true; + + $a->page['htmlhead'] .= replace_macros(get_markup_template('contact_head.tpl'), array( + '$baseurl' => $a->get_baseurl(true), + '$editselect' => $editselect + )); + + require_once('include/contact_selectors.php'); + + $tpl = get_markup_template("abook_edit.tpl"); + + if(feature_enabled(local_user(),'affinity')) { + + $slider_tpl = get_markup_template('contact_slider.tpl'); + $slide = replace_macros($slider_tpl,array( + '$me' => t('Me'), + '$val' => (($contact['abook_closeness']) ? $contact['abook_closeness'] : 99), + '$intimate' => t('Best Friends'), + '$friends' => t('Friends'), + '$oldfriends' => t('Former Friends'), + '$acquaintances' => t('Acquaintances'), + '$world' => t('Unknown') + )); + } + + $perms = array(); + $channel = $a->get_channel(); + + $global_perms = get_perms(); + $existing = get_all_perms(local_user(),$contact['abook_xchan']); + + $unapproved = array('pending', t('Approve this connection'), '', t('Accept connection to allow communication')); + + foreach($global_perms as $k => $v) { + $thisperm = (($contact['abook_my_perms'] & $v[1]) ? "1" : ''); + + // For auto permissions (when $self is true) we don't want to look at existing + // permissions because they are enabled for the channel owner + + if((! $self) && ($existing[$k])) + $thisperm = "1"; + + $perms[] = array('perms_' . $k, $v[3], (($contact['abook_their_perms'] & $v[1]) ? "1" : ""),$thisperm, $v[1], (($channel[$v[0]] == PERMS_SPECIFIC) ? '' : '1'), $v[4]); + } + + $o .= replace_macros($tpl,array( + + '$header' => (($self) ? t('Automatic Permissions Settings') : sprintf( t('Connections: settings for %s'),$contact['xchan_name'])), + '$addr' => $contact['xchan_addr'], + '$notself' => (($self) ? '' : '1'), + '$self' => (($self) ? '1' : ''), + '$autolbl' => t('When receiving a channel introduction, any permissions provided here will be applied to the new connection automatically and the introduction approved. Leave this page if you do not wish to use this feature.'), + '$viewprof' => t('View Profile'), + '$lbl_slider' => t('Slide to adjust your degree of friendship'), + '$slide' => $slide, + '$tabs' => $t, + '$tab_str' => $tab_str, + '$is_pending' => (($contact['abook_flags'] & ABOOK_FLAG_PENDING) ? 1 : ''), + '$unapproved' => $unapproved, + '$inherited' => t('inherited'), + '$approve' => t('Approve this connection'), + '$noperms' => (((! $self) && (! $contact['abook_my_perms'])) ? t('Connection has no individual permissions!') : ''), + '$noperm_desc' => (((! $self) && (! $contact['abook_my_perms'])) ? t('This may be appropriate based on your <a href="settings">privacy settings</a>, though you may wish to review the "Advanced Permissions".') : ''), + '$submit' => t('Submit'), + '$lbl_vis1' => t('Profile Visibility'), + '$lbl_vis2' => sprintf( t('Please choose the profile you would like to display to %s when viewing your profile securely.'), $contact['xchan_name']), + '$lbl_info1' => t('Contact Information / Notes'), + '$infedit' => t('Edit contact notes'), + '$close' => $contact['abook_closeness'], + '$them' => t('Their Settings'), + '$me' => t('My Settings'), + '$perms' => $perms, + '$forum' => t('Forum Members'), + '$soapbox' => t('Soapbox'), + '$full' => t('Full Sharing (typical social network permissions)'), + '$cautious' => t('Cautious Sharing '), + '$follow' => t('Follow Only'), + '$permlbl' => t('Individual Permissions'), + '$permnote' => t('Some permissions may be inherited from your channel <a href="settings">privacy settings</a>, which have higher priority than individual settings. Changing those inherited settings on this page will have no effect.'), + '$advanced' => t('Advanced Permissions'), + '$quick' => t('Simple Permissions (select one and submit)'), + '$common_link' => $a->get_baseurl(true) . '/common/loc/' . local_user() . '/' . $contact['id'], + '$all_friends' => $all_friends, + '$relation_text' => $relation_text, + '$visit' => sprintf( t('Visit %s\'s profile - %s'),$contact['xchan_name'],$contact['xchan_url']), + '$blockunblock' => t('Block/Unblock contact'), + '$ignorecont' => t('Ignore contact'), + '$lblcrepair' => t("Repair URL settings"), + '$lblrecent' => t('View conversations'), + '$lblsuggest' => $lblsuggest, + '$delete' => t('Delete contact'), + '$poll_interval' => contact_poll_interval($contact['priority'],(! $poll_enabled)), + '$poll_enabled' => $poll_enabled, + '$lastupdtext' => t('Last update:'), + '$lost_contact' => $lost_contact, + '$updpub' => t('Update public posts'), + '$last_update' => relative_date($contact['abook_connected']), + '$udnow' => t('Update now'), + '$profile_select' => contact_profile_assign($contact['abook_profile']), + '$multiprofs' => feature_enabled(local_user(),'multi_profiles'), + '$contact_id' => $contact['abook_id'], + '$block_text' => (($contact['blocked']) ? t('Unblock') : t('Block') ), + '$ignore_text' => (($contact['readonly']) ? t('Unignore') : t('Ignore') ), + '$blocked' => (($contact['blocked']) ? t('Currently blocked') : ''), + '$ignored' => (($contact['readonly']) ? t('Currently ignored') : ''), + '$archived' => (($contact['archive']) ? t('Currently archived') : ''), + '$pending' => (($contact['archive']) ? t('Currently pending') : ''), + '$hidden' => array('hidden', t('Hide this contact from others'), ($contact['hidden'] == 1), t('Replies/likes to your public posts <strong>may</strong> still be visible')), + '$photo' => $contact['photo'], + '$name' => $contact['name'], + '$dir_icon' => $dir_icon, + '$alt_text' => $alt_text, + '$sparkle' => $sparkle, + '$url' => $url + + )); + + $arr = array('contact' => $contact,'output' => $o); + + call_hooks('contact_edit', $arr); + + return $arr['output']; + + } + + +} diff --git a/mod/contactgroup.php b/mod/contactgroup.php index 4b46605a6..8b23f9f10 100644 --- a/mod/contactgroup.php +++ b/mod/contactgroup.php @@ -20,7 +20,7 @@ function contactgroup_content(&$a) { if((argc() > 1) && (intval(argv(1)))) { - $r = q("SELECT * FROM `group` WHERE `id` = %d AND `uid` = %d AND `deleted` = 0 LIMIT 1", + $r = q("SELECT * FROM `groups` WHERE `id` = %d AND `uid` = %d AND `deleted` = 0 LIMIT 1", intval(argv(1)), intval(local_user()) ); diff --git a/mod/crepair.php b/mod/crepair.php deleted file mode 100644 index f749fac0e..000000000 --- a/mod/crepair.php +++ /dev/null @@ -1,171 +0,0 @@ -<?php - -function crepair_init(&$a) { - if(! local_user()) - return; - - $contact_id = 0; - - if(($a->argc == 2) && intval($a->argv[1])) { - $contact_id = intval($a->argv[1]); - $r = q("SELECT * FROM `contact` WHERE `uid` = %d and `id` = %d LIMIT 1", - intval(local_user()), - intval($contact_id) - ); - if(! count($r)) { - $contact_id = 0; - } - } - - if(! x($a->page,'aside')) - $a->page['aside'] = ''; - - if($contact_id) { - $a->data['contact'] = $r[0]; - $o .= '<div class="vcard">'; - $o .= '<div class="fn">' . $a->data['contact']['name'] . '</div>'; - $o .= '<div id="profile-photo-wrapper"><img class="photo" style="width: 175px; height: 175px;" src="' . $a->data['contact']['photo'] . '" alt="' . $a->data['contact']['name'] . '" /></div>'; - $o .= '</div>'; - $a->page['aside'] .= $o; - - } -} - - -function crepair_post(&$a) { - if(! local_user()) - return; - - $cid = (($a->argc > 1) ? intval($a->argv[1]) : 0); - - if($cid) { - $r = q("SELECT * FROM `contact` WHERE `id` = %d AND `uid` = %d LIMIT 1", - intval($cid), - intval(local_user()) - ); - } - - if(! count($r)) - return; - - $contact = $r[0]; - - $name = ((x($_POST,'name')) ? $_POST['name'] : $contact['name']); - $nick = ((x($_POST,'nick')) ? $_POST['nick'] : ''); - $url = ((x($_POST,'url')) ? $_POST['url'] : ''); - $request = ((x($_POST,'request')) ? $_POST['request'] : ''); - $confirm = ((x($_POST,'confirm')) ? $_POST['confirm'] : ''); - $notify = ((x($_POST,'notify')) ? $_POST['notify'] : ''); - $poll = ((x($_POST,'poll')) ? $_POST['poll'] : ''); - $attag = ((x($_POST,'attag')) ? $_POST['attag'] : ''); - $photo = ((x($_POST,'photo')) ? $_POST['photo'] : ''); - - $r = q("UPDATE `contact` SET `name` = '%s', `nick` = '%s', `url` = '%s', `request` = '%s', `confirm` = '%s', `notify` = '%s', `poll` = '%s', `attag` = '%s' - WHERE `id` = %d AND `uid` = %d LIMIT 1", - dbesc($name), - dbesc($nick), - dbesc($url), - dbesc($request), - dbesc($confirm), - dbesc($notify), - dbesc($poll), - dbesc($attag), - intval($contact['id']), - local_user() - ); - - if($photo) { - logger('mod-crepair: updating photo from ' . $photo); - require_once('include/photo/photo_driver.php'); - - $photos = import_profile_photo($photo,local_user(),$contact['id']); - - $x = q("UPDATE `contact` SET `photo` = '%s', - `thumb` = '%s', - `micro` = '%s', - `name_date` = '%s', - `uri_date` = '%s', - `avatar_date` = '%s' - WHERE `id` = %d LIMIT 1 - ", - dbesc($photos[0]), - dbesc($photos[1]), - dbesc($photos[2]), - dbesc(datetime_convert()), - dbesc(datetime_convert()), - dbesc(datetime_convert()), - intval($contact['id']) - ); - } - - if($r) - info( t('Contact settings applied.') . EOL); - else - notice( t('Contact update failed.') . EOL); - - - return; -} - - - -function crepair_content(&$a) { - - if(! local_user()) { - notice( t('Permission denied.') . EOL); - return; - } - - $cid = (($a->argc > 1) ? intval($a->argv[1]) : 0); - - if($cid) { - $r = q("SELECT * FROM `contact` WHERE `id` = %d AND `uid` = %d LIMIT 1", - intval($cid), - intval(local_user()) - ); - } - - if(! count($r)) { - notice( t('Contact not found.') . EOL); - return; - } - - $contact = $r[0]; - - $msg1 = t('Repair Contact Settings'); - - $msg2 = t('<strong>WARNING: This is highly advanced</strong> and if you enter incorrect information your communications with this contact may stop working.'); - $msg3 = t('Please use your browser \'Back\' button <strong>now</strong> if you are uncertain what to do on this page.'); - - $o .= '<h2>' . $msg1 . '</h2>'; - - $o .= '<div class="error-message">' . $msg2 . EOL . EOL. $msg3 . '</div>'; - - $o .= EOL . '<a href="contacts/' . $cid . '">' . t('Return to contact editor') . '</a>' . EOL; - - $tpl = get_markup_template('crepair.tpl'); - $o .= replace_macros($tpl, array( - '$label_name' => t('Name'), - '$label_nick' => t('Account Nickname'), - '$label_attag' => t('@Tagname - overrides Name/Nickname'), - '$label_url' => t('Account URL'), - '$label_request' => t('Friend Request URL'), - '$label_confirm' => t('Friend Confirm URL'), - '$label_notify' => t('Notification Endpoint URL'), - '$label_poll' => t('Poll/Feed URL'), - '$label_photo' => t('New photo from this URL'), - '$contact_name' => $contact['name'], - '$contact_nick' => $contact['nick'], - '$contact_id' => $contact['id'], - '$contact_url' => $contact['url'], - '$request' => $contact['request'], - '$confirm' => $contact['confirm'], - '$notify' => $contact['notify'], - '$poll' => $contact['poll'], - '$contact_attag' => $contact['attag'], - '$lbl_submit' => t('Submit') - )); - - return $o; - -} diff --git a/mod/directory.php b/mod/directory.php index 616035339..8fc62e95b 100644 --- a/mod/directory.php +++ b/mod/directory.php @@ -9,24 +9,6 @@ function directory_init(&$a) { } -function directory_aside(&$a) { - - if(local_user()) { - require_once('include/contact_widgets.php'); - $a->set_widget('find_people',findpeople_widget()); - } - - if((get_config('system','block_public')) && (! local_user()) && (! remote_user())) { - return; - } - - $a->set_widget('safe_search',dir_safe_mode()); - - $a->set_widget('dir_sort_order',dir_sort_links()); - -} - - function directory_content(&$a) { if((get_config('system','block_public')) && (! local_user()) && (! remote_user())) { @@ -64,6 +46,7 @@ function directory_content(&$a) { $tpl = get_markup_template('directory_header.tpl'); + $dirmode = intval(get_config('system','directory_mode')); @@ -186,10 +169,12 @@ function directory_content(&$a) { 'id' => ++$t, 'profile_link' => $profile_link, 'photo' => $rr['photo'], + 'hash' => $rr['hash'], 'alttext' => $rr['name'] . ' ' . $rr['address'], 'name' => $rr['name'], 'details' => $pdesc . $details, 'profile' => $profile, + 'address' => $rr['address'], 'location' => $location, 'gender' => $gender, 'pdesc' => $pdesc, @@ -204,7 +189,7 @@ function directory_content(&$a) { call_hooks('directory_item', $arr); - $entries[] = $entry; + $entries[] = $arr['entry']; unset($profile); unset($location); @@ -212,10 +197,8 @@ function directory_content(&$a) { } if($j['keywords']) { - $a->set_widget('dirtagblock',dir_tagblock(z_root() . '/directory',$j['keywords'])); + $a->data['directory_keywords'] = $j['keywords']; } - $a->set_widget('suggest',widget_suggestions(array())); - // logger('mod_directory: entries: ' . print_r($entries,true), LOGGER_DATA); diff --git a/mod/dirprofile.php b/mod/dirprofile.php new file mode 100644 index 000000000..d88144f52 --- /dev/null +++ b/mod/dirprofile.php @@ -0,0 +1,190 @@ +<?php + +require_once('include/dir_fns.php'); +require_once('include/bbcode.php'); + +function dirprofile_init(&$a) { + + if((get_config('system','block_public')) && (! local_user()) && (! remote_user())) { + notice( t('Public access denied.') . EOL); + return; + } + + $hash = $_REQUEST['hash']; + if(! $hash) + return ''; + + $o = ''; + + $dirmode = intval(get_config('system','directory_mode')); + + if(($dirmode == DIRECTORY_MODE_PRIMARY) || ($dirmode == DIRECTORY_MODE_STANDALONE)) { + $url = z_root() . '/dirsearch'; + } + if(! $url) { + $directory = find_upstream_directory($dirmode); + + if($directory) { + $url = $directory['url'] . '/dirsearch'; + } + else { + $url = DIRECTORY_FALLBACK_MASTER . '/dirsearch'; + } + } + logger('mod_directory: URL = ' . $url, LOGGER_DEBUG); + + $contacts = array(); + + if(local_user()) { + $x = q("select abook_xchan from abook where abook_channel = %d", + intval(local_user()) + ); + if($x) { + foreach($x as $xx) + $contacts[] = $xx['abook_xchan']; + } + } + + + + if($url) { + + $query = $url . '?f=&hash=' . $hash; + + $x = z_fetch_url($query); + logger('dirprofile: return from upstream: ' . print_r($x,true), LOGGER_DATA); + + if($x['success']) { + $t = 0; + $j = json_decode($x['body'],true); + if($j) { + + if($j['results']) { + + $entries = array(); + + $photo = 'thumb'; + + foreach($j['results'] as $rr) { + + $profile_link = chanlink_url($rr['url']); + + $pdesc = (($rr['description']) ? $rr['description'] . '<br />' : ''); + + $qrlink = zid($rr['url']); + $connect_link = ((local_user()) ? z_root() . '/follow?f=&url=' . urlencode($rr['address']) : ''); + + $online = remote_online_status($rr['address']); + + + if(in_array($rr['hash'],$contacts)) + $connect_link = ''; + + $details = ''; + if(strlen($rr['locale'])) + $details .= $rr['locale']; + if(strlen($rr['region'])) { + if(strlen($rr['locale'])) + $details .= ', '; + $details .= $rr['region']; + } + if(strlen($rr['country'])) { + if(strlen($details)) + $details .= ', '; + $details .= $rr['country']; + } + if(strlen($rr['birthday'])) { + if(($years = age($rr['birthday'],'UTC','')) != 0) + $details .= '<br />' . t('Age: ') . $years ; + } + if(strlen($rr['gender'])) + $details .= '<br />' . t('Gender: ') . $rr['gender']; + + $page_type = ''; + + $profile = $rr; + + if ((x($profile,'locale') == 1) + || (x($profile,'region') == 1) + || (x($profile,'postcode') == 1) + || (x($profile,'country') == 1)) + $location = t('Location:'); + + + $marital = ((x($profile,'marital') == 1) ? t('Status: ') . $profile['marital'] : False); + $sexual = ((x($profile,'sexual') == 1) ? t('Sexual Preference: ') . $profile['sexual'] : False); + + $homepage = ((x($profile,'homepage') == 1) ? t('Homepage: ') . linkify($profile['homepage']) : False); + $hometown = ((x($profile,'hometown') == 1) ? t('Hometown: ') . $profile['hometown'] : False); + + $about = ((x($profile,'about') == 1) ? t('About: ') . bbcode($profile['about']) : False); + + $keywords = ((x($profile,'keywords')) ? $profile['keywords'] : ''); + if($keywords) { + $keywords = str_replace(',',' ', $keywords); + $keywords = str_replace(' ',' ', $keywords); + $karr = explode(' ', $keywords); + $out = ''; + if($karr) { + if(local_user()) { + $r = q("select keywords from profile where uid = %d and is_default = 1 limit 1", + intval(local_user()) + ); + if($r) { + $keywords = str_replace(',',' ', $r[0]['keywords']); + $keywords = str_replace(' ',' ', $keywords); + $marr = explode(' ', $keywords); + } + } + foreach($karr as $k) { + if(strlen($out)) + $out .= ', '; + if($marr && in_arrayi($k,$marr)) + $out .= '<strong>' . $k . '</strong>'; + else + $out .= $k; + } + } + + } + $entry = replace_macros(get_markup_template('direntry_large.tpl'), array( + '$id' => ++$t, + '$profile_link' => $profile_link, + '$qrlink' => $qrlink, + '$photo' => $rr['photo_l'], + '$alttext' => $rr['name'] . ' ' . $rr['address'], + '$name' => $rr['name'], + '$online' => (($online) ? t('Online Now') : ''), + '$details' => $pdesc . $details, + '$profile' => $profile, + '$address' => $rr['address'], + '$location' => $location, + '$gender' => $gender, + '$pdesc' => $pdesc, + '$marital' => $marital, + '$homepage' => $homepage, + '$hometown' => $hometown, + '$about' => $about, + '$kw' => (($out) ? t('Keywords: ') : ''), + '$keywords' => $out, + '$conn_label' => t('Connect'), + '$connect' => $connect_link, + )); + + + echo $entry; + killme(); + + } + } + else { + info( t("Not found.") . EOL); + } + } + } + } + + + + +}
\ No newline at end of file diff --git a/mod/dirsearch.php b/mod/dirsearch.php index 6315cae31..59a1d448d 100644 --- a/mod/dirsearch.php +++ b/mod/dirsearch.php @@ -27,9 +27,10 @@ function dirsearch_content(&$a) { json_return_and_die($ret); } + $hash = ((x($_REQUEST['hash'])) ? $_REQUEST['hash'] : ''); $name = ((x($_REQUEST,'name')) ? $_REQUEST['name'] : ''); - $hub = ((x($_REQUEST,'hub')) ? $_REQUEST['hub'] : ''); + $hub = ((x($_REQUEST,'hub')) ? $_REQUEST['hub'] : ''); $address = ((x($_REQUEST,'address')) ? $_REQUEST['address'] : ''); $locale = ((x($_REQUEST,'locale')) ? $_REQUEST['locale'] : ''); $region = ((x($_REQUEST,'region')) ? $_REQUEST['region'] : ''); @@ -91,6 +92,13 @@ function dirsearch_content(&$a) { $sql_extra .= " AND xprof_age >= " . intval($agege) . ") "; } + + if($hash) { + $sql_extra = " AND xchan_hash = '" . dbesc($hash) . "' "; + } + + + $perpage = (($_REQUEST['n']) ? $_REQUEST['n'] : 80); $page = (($_REQUEST['p']) ? intval($_REQUEST['p'] - 1) : 0); $startrec = (($page+1) * $perpage) - $perpage; @@ -112,6 +120,9 @@ function dirsearch_content(&$a) { $logic = ((strlen($sql_extra)) ? 0 : 1); + if($hash) + $logic = 1; + $safesql = (($safe > 0) ? " and not ( xchan_flags & " . intval(XCHAN_FLAGS_CENSORED|XCHAN_FLAGS_SELFCENSORED) . " ) " : ''); if($safe < 0) $safesql = " and ( xchan_flags & " . intval(XCHAN_FLAGS_CENSORED|XCHAN_FLAGS_SELFCENSORED) . " ) "; @@ -161,13 +172,11 @@ function dirsearch_content(&$a) { json_return_and_die($spkt); } else { - $r = q("SELECT xchan.*, xprof.* from xchan left join xprof on xchan_hash = xprof_hash where ( $logic $sql_extra ) and not ( xchan_flags & %d ) and not ( xchan_flags & %d ) and not ( xchan_flags & %d ) $safesql $order $qlimit ", intval(XCHAN_FLAGS_HIDDEN), intval(XCHAN_FLAGS_ORPHAN), intval(XCHAN_FLAGS_DELETED) ); - } $ret['page'] = $page + 1; @@ -184,9 +193,8 @@ function dirsearch_content(&$a) { $entry['name'] = $rr['xchan_name']; $entry['hash'] = $rr['xchan_hash']; -// $entry['updated'] = (($rr['ud_date']) ? $rr['ud_date'] : '0000-00-00 00:00:00'); -// $entry['update_guid'] = (($rr['ud_guid']) ? $rr['ud_guid'] : ''); $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']; @@ -198,6 +206,10 @@ function dirsearch_content(&$a) { $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; @@ -221,7 +233,7 @@ function dirsearch_content(&$a) { function list_public_sites() { - $r = q("select * from site where site_access != 0 order by rand()"); + $r = q("select * from site where site_access != 0 and site_register !=0 order by rand()"); $ret = array('success' => false); if($r) { @@ -257,4 +269,4 @@ function list_public_sites() { } } return $ret; -}
\ No newline at end of file +} diff --git a/mod/display.php b/mod/display.php index 9aafec8c3..b20eb3e4f 100644 --- a/mod/display.php +++ b/mod/display.php @@ -125,6 +125,7 @@ function display_content(&$a, $update = 0, $load = false) { '$nouveau' => '0', '$wall' => '0', '$page' => (($a->pager['page'] != 1) ? $a->pager['page'] : 1), + '$list' => ((x($_REQUEST,'list')) ? intval($_REQUEST['list']) : 0), '$search' => '', '$order' => '', '$file' => '', @@ -139,13 +140,13 @@ function display_content(&$a, $update = 0, $load = false) { $sql_extra = public_permissions_sql(get_observer_hash()); - if($update && $load) { + if(($update && $load) || ($_COOKIE['jsAvailable'] != 1)) { $updateable = false; $pager_sql = sprintf(" LIMIT %d, %d ",intval($a->pager['start']), intval($a->pager['itemspage'])); - if($load) { + if($load || ($_COOKIE['jsAvailable'] != 1)) { $r = null; if(local_user()) { $r = q("SELECT * from item @@ -202,8 +203,11 @@ function display_content(&$a, $update = 0, $load = false) { } - - $o .= conversation($a, $items, 'display', $update, 'client'); + if ($_COOKIE['jsAvailable'] == 1) { + $o .= conversation($a, $items, 'display', $update, 'client'); + } else { + $o .= conversation($a, $items, 'display', $update, 'traditional'); + } if($updateable) { $x = q("UPDATE item SET item_flags = ( item_flags ^ %d ) diff --git a/mod/editblock.php b/mod/editblock.php index 9c691640b..dcb4b42a7 100644 --- a/mod/editblock.php +++ b/mod/editblock.php @@ -56,7 +56,11 @@ function editblock_content(&$a) { intval($post_id), intval($owner) ); - + $item_id = q("select * from item_id where service = 'BUILDBLOCK' and iid = %d limit 1", + $itm[0]['id'] + ); + if($item_id) + $block_title = $item_id[0]['sid']; $plaintext = true; @@ -88,7 +92,8 @@ function editblock_content(&$a) { '$editselect' => (($plaintext) ? 'none' : '/(profile-jot-text|prvmail-text)/'), '$ispublic' => ' ', // t('Visible to <strong>everybody</strong>'), '$geotag' => $geotag, - '$nickname' => $a->user['nickname'] + '$nickname' => $a->user['nickname'], + '$confirmdelete' => t('Delete block?') )); @@ -111,6 +116,7 @@ function editblock_content(&$a) { $o .= replace_macros($tpl,array( '$return_path' => $rp, '$action' => 'item', + '$webpage' => ITEM_BUILDBLOCK, '$share' => t('Edit'), '$upload' => t('Upload photo'), '$attach' => t('Attach file'), @@ -132,8 +138,9 @@ function editblock_content(&$a) { '$pvisit' => 'none', '$public' => t('Public post'), '$jotnets' => $jotnets, - '$title' => htmlspecialchars($itm[0]['title']), + '$title' => htmlspecialchars($itm[0]['title'],ENT_COMPAT,'UTF-8'), '$placeholdertitle' => t('Set title'), + '$pagetitle' => $block_title, '$category' => '', '$placeholdercategory' => t('Categories (comma-separated list)'), '$emtitle' => t('Example: bob@example.com, mary@example.com'), @@ -153,7 +160,7 @@ function editblock_content(&$a) { $ob = get_observer_hash(); if(($itm[0]['author_xchan'] === $ob) || ($itm[0]['owner_xchan'] === $ob)) - $o .= '<br /><br /><a href="item/drop/' . $itm[0]['id'] . '" >' . t('Delete Block') . '</a><br />'; + $o .= '<br /><br /><a class="block-delete-link" href="item/drop/' . $itm[0]['id'] . '" >' . t('Delete Block') . '</a><br />'; return $o; diff --git a/mod/editlayout.php b/mod/editlayout.php index f8906d981..838a219c9 100644 --- a/mod/editlayout.php +++ b/mod/editlayout.php @@ -57,7 +57,11 @@ function editlayout_content(&$a) { intval($owner) ); - + $item_id = q("select * from item_id where service = 'PDL' and iid = %d limit 1", + $itm[0]['id'] + ); + if($item_id) + $layout_title = $item_id[0]['sid']; $plaintext = true; // You may or may not be a local user. This won't work, @@ -74,7 +78,8 @@ function editlayout_content(&$a) { '$editselect' => (($plaintext) ? 'none' : '/(profile-jot-text|prvmail-text)/'), '$ispublic' => ' ', // t('Visible to <strong>everybody</strong>'), '$geotag' => $geotag, - '$nickname' => $a->user['nickname'] + '$nickname' => $a->user['nickname'], + '$confirmdelete' => t('Delete layout?') )); @@ -97,6 +102,7 @@ function editlayout_content(&$a) { $o .= replace_macros($tpl,array( '$return_path' => $rp, '$action' => 'item', + '$webpage' => ITEM_PDL, '$share' => t('Edit'), '$upload' => t('Upload photo'), '$attach' => t('Attach file'), @@ -117,8 +123,9 @@ function editlayout_content(&$a) { '$pvisit' => 'none', '$public' => t('Public post'), '$jotnets' => $jotnets, - '$title' => htmlspecialchars($itm[0]['title']), + '$title' => htmlspecialchars($itm[0]['title'],ENT_COMPAT,'UTF-8'), '$placeholdertitle' => t('Set title'), + '$pagetitle' => $layout_title, '$category' => '', '$placeholdercategory' => t('Categories (comma-separated list)'), '$emtitle' => t('Example: bob@example.com, mary@example.com'), @@ -133,11 +140,11 @@ function editlayout_content(&$a) { '$feature_expire' => 'none', '$expires' => t('Set expiration date'), )); - + $ob = get_observer_hash(); if(($itm[0]['author_xchan'] === $ob) || ($itm[0]['owner_xchan'] === $ob)) - $o .= '<br /><br /><a href="item/drop/' . $itm[0]['id'] . '" >' . t('Delete Layout') . '</a><br />'; + $o .= '<br /><br /><a class="layout-delete-link" href="item/drop/' . $itm[0]['id'] . '" >' . t('Delete Layout') . '</a><br />'; return $o; diff --git a/mod/editpost.php b/mod/editpost.php index f25d6d21d..8c4117e7a 100644 --- a/mod/editpost.php +++ b/mod/editpost.php @@ -50,6 +50,7 @@ function editpost_content(&$a) { '$geotag' => $geotag, '$nickname' => $channel['channel_address'], '$expireswhen' => t('Expires YYYY-MM-DD HH:MM'), + '$confirmdelete' => t('Delete item?'), )); @@ -91,6 +92,20 @@ function editpost_content(&$a) { } + if($itm[0]['attach']) { + $j = json_decode($itm[0]['attach'],true); + if($j) { + foreach($j as $jj) { + $itm[0]['body'] .= "\n" . '[attachment]' . basename($jj['href']) . ',' . $jj['revision'] . '[/attachment]' . "\n"; + } + } + } + + $cipher = get_pconfig(get_app()->profile['profile_uid'],'system','default_cipher'); + if(! $cipher) + $cipher = 'aes256'; + + $o .= replace_macros($tpl,array( '$return_path' => $_SESSION['return_url'], '$action' => 'item', @@ -114,7 +129,7 @@ function editpost_content(&$a) { '$pvisit' => 'none', '$public' => t('Public post'), '$jotnets' => $jotnets, - '$title' => htmlspecialchars($itm[0]['title']), + '$title' => htmlspecialchars($itm[0]['title'],ENT_COMPAT,'UTF-8'), '$placeholdertitle' => t('Set title'), '$category' => $category, '$placeholdercategory' => t('Categories (comma-separated list)'), @@ -127,11 +142,14 @@ function editpost_content(&$a) { '$jotplugins' => $jotplugins, '$sourceapp' => t($a->sourcename), '$catsenabled' => $catsenabled, - '$defexpire' => $itm[0]['expires'], - '$feature_expire' => 'none', + '$defexpire' => datetime_convert('UTC', date_default_timezone_get(),$itm[0]['expires']), + '$feature_expire' => ((feature_enabled(get_app()->profile['profile_uid'],'content_expire') && (! $webpage)) ? 'block' : 'none'), '$expires' => t('Set expiration date'), - '$feature_encrypt' => 'none', + '$feature_encrypt' => ((feature_enabled(get_app()->profile['profile_uid'],'content_encrypt') && (! $webpage)) ? 'block' : 'none'), '$encrypt' => t('Encrypt text'), + '$cipher' => $cipher, + '$expiryModalOK' => t('OK'), + '$expiryModalCANCEL' => t('Cancel'), )); return $o; diff --git a/mod/editwebpage.php b/mod/editwebpage.php index 840bda336..f11210eea 100644 --- a/mod/editwebpage.php +++ b/mod/editwebpage.php @@ -99,8 +99,8 @@ function editwebpage_content(&$a) { if($layout) $layoutselect = '<input type="hidden" name="layout_mid" value="' . $layout . '" />'; else - $layoutselect = layout_select($itm[0]['uid']); - + $layoutselect = layout_select($itm[0]['uid'],$itm[0]['layout_mid']); + $o .= replace_macros(get_markup_template('edpost_head.tpl'), array( '$title' => t('Edit Webpage') @@ -112,7 +112,8 @@ function editwebpage_content(&$a) { '$editselect' => (($plaintext) ? 'none' : '/(profile-jot-text|prvmail-text)/'), '$ispublic' => ' ', // t('Visible to <strong>everybody</strong>'), '$geotag' => $geotag, - '$nickname' => $a->user['nickname'] + '$nickname' => $a->user['nickname'], + '$confirmdelete' => t('Delete webpage?') )); @@ -135,7 +136,7 @@ function editwebpage_content(&$a) { $o .= replace_macros($tpl,array( '$return_path' => $rp, - '$webpage' => true, + '$webpage' => ITEM_WEBPAGE, '$placeholdpagetitle' => t('Page link title'), '$pagetitle' => $page_title, @@ -164,7 +165,7 @@ function editwebpage_content(&$a) { '$jotnets' => $jotnets, '$mimeselect' => $mimeselect, '$layoutselect' => $layoutselect, - '$title' => htmlspecialchars($itm[0]['title']), + '$title' => htmlspecialchars($itm[0]['title'],ENT_COMPAT,'UTF-8'), '$placeholdertitle' => t('Set title'), '$category' => '', '$placeholdercategory' => t('Categories (comma-separated list)'), @@ -185,7 +186,7 @@ function editwebpage_content(&$a) { $ob = get_observer_hash(); if(($itm[0]['author_xchan'] === $ob) || ($itm[0]['owner_xchan'] === $ob)) - $o .= '<br /><br /><a href="item/drop/' . $itm[0]['id'] . '" >' . t('Delete Webpage') . '</a><br />'; + $o .= '<br /><br /><a class="page-delete-link" href="item/drop/' . $itm[0]['id'] . '" >' . t('Delete Webpage') . '</a><br />'; return $o; diff --git a/mod/events.php b/mod/events.php index 265c74fce..2a6067e65 100755 --- a/mod/events.php +++ b/mod/events.php @@ -108,7 +108,7 @@ function events_post(&$a) { $datarray['start'] = $start; $datarray['finish'] = $finish; $datarray['summary'] = $summary; - $datarray['desc'] = $desc; + $datarray['description'] = $desc; $datarray['location'] = $location; $datarray['type'] = $type; $datarray['adjust'] = $adjust; @@ -355,8 +355,7 @@ function events_content(&$a) { '$new_event'=> array($a->get_baseurl().'/events/new',t('Create New Event'),'',''), '$previus' => array($a->get_baseurl()."/events/$prevyear/$prevmonth",t('Previous'),'',''), '$next' => array($a->get_baseurl()."/events/$nextyear/$nextmonth",t('Next'),'',''), - '$calendar' => cal($y,$m,$links, ' eventcal'), - + '$calendar' => cal($y,$m,$links, ' eventcal'), '$events' => $events, diff --git a/mod/fbrowser.php b/mod/fbrowser.php index baacfe56b..19bd77914 100644 --- a/mod/fbrowser.php +++ b/mod/fbrowser.php @@ -45,7 +45,7 @@ function fbrowser_content($a){ $path[]=array($a->get_baseurl()."/fbrowser/image/".$a->argv[2]."/", $album); } - $r = q("SELECT `resource_id`, `id`, `filename`, type, min(`scale`) AS `hiq`,max(`scale`) AS `loq`, `desc` + $r = q("SELECT `resource_id`, `id`, `filename`, type, min(`scale`) AS `hiq`,max(`scale`) AS `loq`, `description` FROM `photo` WHERE `uid` = %d $sql_extra GROUP BY `resource_id` $sql_extra2", intval(local_user()) diff --git a/mod/filestorage.php b/mod/filestorage.php index 5e1e61f42..3e53a1e93 100644 --- a/mod/filestorage.php +++ b/mod/filestorage.php @@ -1,5 +1,37 @@ <?php +require_once('include/attach.php'); + +function filestorage_post(&$a) { + + $channel_id = ((x($_POST,'uid')) ? intval($_POST['uid']) : 0); + + if((! $channel_id) || (! local_user()) || ($channel_id != local_user())) { + notice( t('Permission denied.') . EOL); + return; + } + + $recurse = ((x($_POST,'recurse')) ? intval($_POST['recurse']) : 0); + $resource = ((x($_POST,'filehash')) ? notags($_POST['filehash']) : ''); + + if(! $resource) { + notice(t('Item not found.') . EOL); + return; + } + + $str_group_allow = perms2str($_REQUEST['group_allow']); + $str_contact_allow = perms2str($_REQUEST['contact_allow']); + $str_group_deny = perms2str($_REQUEST['group_deny']); + $str_contact_deny = perms2str($_REQUEST['contact_deny']); + + attach_change_permissions($channel_id,$resource,$str_contact_allow,$str_group_allow,$str_contact_deny,$str_group_deny,$recurse = false); + +} + + + + + function filestorage_content(&$a) { if(argc() > 1) @@ -10,81 +42,138 @@ function filestorage_content(&$a) { return; } - $r = q("select channel_id from channel where channel_address = '%s'", - dbesc($which) - ); - if($r) { - $owner = intval($r[0]['channel_id']); + $r = q("select * from channel where channel_address = '%s'", + dbesc($which) + ); + if($r) { + $channel = $r[0]; + $owner = intval($r[0]['channel_id']); } - $observer = $a->get_observer(); - $ob_hash = (($observer) ? $observer['xchan_hash'] : ''); + $observer = $a->get_observer(); + $ob_hash = (($observer) ? $observer['xchan_hash'] : ''); - $perms = get_all_perms($owner,$ob_hash); + $perms = get_all_perms($owner,$ob_hash); - if(! $perms['view_storage']) { - notice( t('Permission denied.') . EOL); - return; - } + if(! $perms['view_storage']) { + notice( t('Permission denied.') . EOL); + return; + } -// Since we have ACL'd files in the wild, but don't have ACL here yet, we -// need to return for anoyne other than the owner, despite the perms check for now. + // Since we have ACL'd files in the wild, but don't have ACL here yet, we + // need to return for anyone other than the owner, despite the perms check for now. $is_owner = (((local_user()) && ($owner == local_user())) ? true : false); - if (! $is_owner) { - info( t('Permission Denied.') . EOL ); - return; + if(! $is_owner) { + info( t('Permission Denied.') . EOL ); + return; } -// TODO This will also need to check for files on disk and delete them from there as well as the DB. - if ((argc() > 3 && argv(3) === 'delete') ? true : false);{ - if(! $perms['write_storage']) { - notice( t('Permission denied. VS.') . EOL); - return; + + if(argc() > 3 && argv(3) === 'delete') { + if(! $perms['write_storage']) { + notice( t('Permission denied.') . EOL); + return; } - $file = argv(2); - $r = q("delete from attach where id = '%s' and uid = '%s' limit 1", + $file = intval(argv(2)); + $r = q("select hash from attach where id = %d and uid = %d limit 1", dbesc($file), intval($owner) ); + if(! $r) { + notice( t('File not found.') . EOL); + goaway(z_root() . '/filestorage/' . $which); + } - + attach_delete($owner,$r[0]['hash']); + + goaway(z_root() . '/filestorage/' . $which); } -$r = q("select * from attach where uid = %d order by filename asc", - intval($owner) -); + if(argc() > 3 && argv(3) === 'edit') { + require_once('include/acl_selectors.php'); + if(! $perms['write_storage']) { + notice( t('Permission denied.') . EOL); + return; + } + $file = intval(argv(2)); - $files = null; + $r = q("select id, uid, folder, filename, revision, flags, hash, allow_cid, allow_gid, deny_cid, deny_gid from attach where id = %d and uid = %d limit 1", + intval($file), + intval($owner) + ); - if($r) { - $files = array(); - foreach($r as $rr) { - $files[$rr['id']][] = array('id' => $rr['id'],'download' => $rr['hash'], 'title' => $rr['filename'], 'size' => $rr['filesize']); - } - } + $f = $r[0]; + $channel = $a->get_channel(); - $limit = service_class_fetch ($owner,'attach_upload_limit'); - $r = q("select sum(filesize) as total from attach where uid = %d ", + $cloudpath = get_cloudpath($f) . (($f['flags'] & ATTACH_FLAG_DIR) ? '?f=&davguest=1' : ''); + + $aclselect_e = populate_acl($f); + $is_a_dir = (($f['flags'] & ATTACH_FLAG_DIR) ? true : false); + + + $o = replace_macros(get_markup_template('attach_edit.tpl'), array( + '$header' => t('Edit file permissions'), + '$file' => $f, + '$cloudpath' => z_root() . '/' . $cloudpath, + '$uid' => $channel['channel_id'], + '$channelnick' => $channel['channel_address'], + '$permissions' => t('Permissions'), + '$aclselect' => $aclselect_e, + '$recurse' => t('Include all files and sub folders'), + '$backlink' => t('Return to file list'), + '$isadir' => $is_a_dir, + '$cpdesc' => t('Copy/paste this code to attach file to a post'), + '$cpldesc' => t('Copy/paste this URL to link file from a web page'), + '$submit' => t('Submit') + + )); + + return $o; + } + + $r = q("select * from attach where uid = %d order by edited desc", intval($owner) ); + + $files = null; + + if($r) { + $files = array(); + foreach($r as $rr) { + $files[$rr['id']][] = array( + 'id' => $rr['id'], + 'download' => $rr['hash'], + 'title' => $rr['filename'], + 'size' => $rr['filesize'], + 'rev' => $rr['revision'], + 'dir' => (($rr['flags'] & ATTACH_FLAG_DIR) ? true : false) + ); + } + } + + $limit = service_class_fetch ($owner,'attach_upload_limit'); + $r = q("select sum(filesize) as total from attach where aid = %d ", + intval($channel['channel_account_id']) + ); $used = $r[0]['total']; - $url = z_root() . "/filestorage/" . $which; - return $o . replace_macros(get_markup_template("filestorage.tpl"), array( + $url = z_root() . "/filestorage/" . $which; + return $o . replace_macros(get_markup_template("filestorage.tpl"), array( '$baseurl' => $url, '$download' => t('Download'), '$files' => $files, '$channel' => $which, + '$edit' => t('Edit'), '$delete' => t('Delete'), '$used' => $used, '$usedlabel' => t('Used: '), + '$directory' => t('[directory]'), '$limit' => $limit, '$limitlabel' => t('Limit: '), - )); + )); - } diff --git a/mod/follow.php b/mod/follow.php index 364fe76b9..962bb71a7 100644 --- a/mod/follow.php +++ b/mod/follow.php @@ -30,7 +30,7 @@ function follow_init(&$a) { proc_run('php','include/onepoll.php',$result['abook']['abook_id']); - goaway(z_root() . '/connections/' . $result['abook']['abook_id']); + goaway(z_root() . '/connedit/' . $result['abook']['abook_id']); } diff --git a/mod/group.php b/mod/group.php index 5a34ab6fb..15e4ff2a3 100644 --- a/mod/group.php +++ b/mod/group.php @@ -2,12 +2,6 @@ require_once('include/group.php'); -function group_aside(&$a) { - if(local_user()) { - $a->set_widget('groups_edit',group_side('connections','group',false,(($a->argc > 1) ? intval($a->argv[1]) : 0))); - } -} - function group_post(&$a) { @@ -36,7 +30,7 @@ function group_post(&$a) { if((argc() == 2) && (intval(argv(1)))) { check_form_security_token_redirectOnErr('/group', 'group_edit'); - $r = q("SELECT * FROM `group` WHERE `id` = %d AND `uid` = %d LIMIT 1", + $r = q("SELECT * FROM `groups` WHERE `id` = %d AND `uid` = %d LIMIT 1", intval(argv(1)), intval(local_user()) ); @@ -50,7 +44,7 @@ function group_post(&$a) { $public = intval($_POST['public']); if((strlen($groupname)) && (($groupname != $group['name']) || ($public != $group['visible']))) { - $r = q("UPDATE `group` SET `name` = '%s', visible = %d WHERE `uid` = %d AND `id` = %d LIMIT 1", + $r = q("UPDATE `groups` SET `name` = '%s', visible = %d WHERE `uid` = %d AND `id` = %d LIMIT 1", dbesc($groupname), intval($public), intval(local_user()), @@ -103,7 +97,7 @@ function group_content(&$a) { check_form_security_token_redirectOnErr('/group', 'group_drop', 't'); if(intval(argv(2))) { - $r = q("SELECT `name` FROM `group` WHERE `id` = %d AND `uid` = %d LIMIT 1", + $r = q("SELECT `name` FROM `groups` WHERE `id` = %d AND `uid` = %d LIMIT 1", intval(argv(2)), intval(local_user()) ); @@ -123,10 +117,10 @@ function group_content(&$a) { check_form_security_token_ForbiddenOnErr('group_member_change', 't'); - $r = q("SELECT abook_xchan from abook where abook_xchan = '%s' and abook_channel = %d and not (abook_flags & %d) and not (abook_flags & %d) and not (abook_flags & %d) limit 1", + $r = q("SELECT abook_xchan from abook where abook_xchan = '%s' and abook_channel = %d and not (xchan_flags & %d) and not (abook_flags & %d) and not (abook_flags & %d) limit 1", dbesc(argv(2)), intval(local_user()), - intval(ABOOK_FLAG_SELF), + intval(XCHAN_FLAGS_DELETED), intval(ABOOK_FLAG_BLOCKED), intval(ABOOK_FLAG_PENDING) ); @@ -138,7 +132,7 @@ function group_content(&$a) { if((argc() > 1) && (intval(argv(1)))) { require_once('include/acl_selectors.php'); - $r = q("SELECT * FROM `group` WHERE `id` = %d AND `uid` = %d AND `deleted` = 0 LIMIT 1", + $r = q("SELECT * FROM `groups` WHERE `id` = %d AND `uid` = %d AND `deleted` = 0 LIMIT 1", intval(argv(1)), intval(local_user()) ); @@ -216,10 +210,10 @@ function group_content(&$a) { group_rmv_member(local_user(),$group['name'],$member['xchan_hash']); } - $r = q("SELECT abook.*, xchan.* FROM `abook` left join xchan on abook_xchan = xchan_hash WHERE `abook_channel` = %d AND not (abook_flags & %d) and not (abook_flags & %d) and not (abook_flags & %d) order by xchan_name asc", + $r = q("SELECT abook.*, xchan.* FROM `abook` left join xchan on abook_xchan = xchan_hash WHERE `abook_channel` = %d AND not (abook_flags & %d) and not (xchan_flags & %d) and not (abook_flags & %d) order by xchan_name asc", intval(local_user()), intval(ABOOK_FLAG_BLOCKED), - intval(ABOOK_FLAG_SELF), + intval(XCHAN_FLAGS_DELETED), intval(ABOOK_FLAG_PENDING) ); diff --git a/mod/hcard.php b/mod/hcard.php deleted file mode 100644 index ab2fa88a1..000000000 --- a/mod/hcard.php +++ /dev/null @@ -1,53 +0,0 @@ -<?php - -function hcard_init(&$a) { - - $blocked = (((get_config('system','block_public')) && (! local_user()) && (! remote_user())) ? true : false); - - if($a->argc > 1) - $which = $a->argv[1]; - else { - notice( t('No profile') . EOL ); - $a->error = 404; - return; - } - - $profile = 0; - if((local_user()) && ($a->argc > 2) && ($a->argv[2] === 'view')) { - $which = $a->user['nickname']; - $profile = $a->argv[1]; - } - - profile_load($a,$which,$profile); - - if((x($a->profile,'page-flags')) && ($a->profile['page-flags'] == PAGE_COMMUNITY)) { - $a->page['htmlhead'] .= '<meta name="friendica.community" content="true" />'; - } - if(x($a->profile,'openidserver')) - $a->page['htmlhead'] .= '<link rel="openid.server" href="' . $a->profile['openidserver'] . '" />' . "\r\n"; - if(x($a->profile,'openid')) { - $delegate = ((strstr($a->profile['openid'],'://')) ? $a->profile['openid'] : 'http://' . $a->profile['openid']); - $a->page['htmlhead'] .= '<link rel="openid.delegate" href="' . $delegate . '" />' . "\r\n"; - } - - if(! $blocked) { - $keywords = ((x($a->profile,'keywords')) ? $a->profile['keywords'] : ''); - $keywords = str_replace(array(',',' ',',,'),array(' ',',',','),$keywords); - if(strlen($keywords)) - $a->page['htmlhead'] .= '<meta name="keywords" content="' . $keywords . '" />' . "\r\n" ; - } - - $a->page['htmlhead'] .= '<link rel="alternate" type="application/atom+xml" href="' . $a->get_baseurl() . '/dfrn_poll/' . $which .'" />' . "\r\n" ; - $uri = urlencode('acct:' . $a->profile['nickname'] . '@' . $a->get_hostname() . (($a->path) ? '/' . $a->path : '')); - $a->page['htmlhead'] .= '<link rel="lrdd" type="application/xrd+xml" href="' . $a->get_baseurl() . '/xrd/?uri=' . $uri . '" />' . "\r\n"; - header('Link: <' . $a->get_baseurl() . '/xrd/?uri=' . $uri . '>; rel="lrdd"; type="application/xrd+xml"', false); - - $dfrn_pages = array('request', 'confirm', 'notify', 'poll'); - foreach($dfrn_pages as $dfrn) - $a->page['htmlhead'] .= "<link rel=\"dfrn-{$dfrn}\" href=\"".$a->get_baseurl()."/dfrn_{$dfrn}/{$which}\" />\r\n"; - -} - -function hcard_aside(&$a) { - profile_create_sidebar($a); -} diff --git a/mod/help.php b/mod/help.php index e78f9e61c..bbfeb9a6c 100644 --- a/mod/help.php +++ b/mod/help.php @@ -32,6 +32,8 @@ function help_content(&$a) { global $lang; + $doctype = 'markdown'; + require_once('library/markdown.php'); $text = ''; @@ -41,11 +43,25 @@ function help_content(&$a) { $a->page['title'] = t('Help:') . ' ' . str_replace('-',' ',notags(argv(1))); } if(! $text) { + $text = load_doc_file('doc/' . $a->argv[1] . '.bb'); + if($text) + $doctype = 'bbcode'; + $a->page['title'] = t('Help:') . ' ' . str_replace('-',' ',notags(argv(1))); + } + if(! $text) { + $text = load_doc_file('doc/' . $a->argv[1] . '.html'); + if($text) + $doctype = 'html'; + $a->page['title'] = t('Help:') . ' ' . str_replace('-',' ',notags(argv(1))); + } + + if(! $text) { $text = load_doc_file('doc/Site.md'); $a->page['title'] = t('Help'); } if(! $text) { - $text = load_doc_file('doc/Home.md'); + $doctype = 'bbcode'; + $text = load_doc_file('doc/main.bb'); $a->page['title'] = t('Help'); } @@ -58,15 +74,20 @@ function help_content(&$a) { } $text = preg_replace_callback("/#include (.*?)\;/ism", 'preg_callback_help_include', $text); - - - return Markdown($text); + + if($doctype === 'html') + return $text; + if($doctype === 'markdown') + return Markdown($text); + if($doctype === 'bbcode') { + require_once('include/bbcode.php'); + return bbcode($text); + } } function preg_callback_help_include($matches) { - print_r($matches); if($matches[1]) return str_replace($matches[0],load_doc_file($matches[1]),$matches[0]); diff --git a/mod/home.php b/mod/home.php index edcaa938d..05626dcb5 100644 --- a/mod/home.php +++ b/mod/home.php @@ -1,6 +1,9 @@ <?php -if(! function_exists('home_init')) { +require_once('include/items.php'); +require_once('include/conversation.php'); + + function home_init(&$a) { $ret = array(); @@ -20,10 +23,9 @@ function home_init(&$a) { goaway(z_root() . '/new_channel'); } -}} +} -if(! function_exists('home_content')) { function home_content(&$a) { $o = ''; @@ -33,56 +35,62 @@ function home_content(&$a) { if(x($_SESSION,'mobile_theme')) unset($_SESSION['mobile_theme']); -$channel_address = get_config("system", "site_channel" ); + $channel_address = get_config("system", "site_channel" ); if ($channel_address){ -require_once('include/items.php'); -require_once('include/conversation.php'); - - -//We can do better, but until we figure out auto-linkification, let's keep things simple - $page_id = 'home'; - - $u = q("select channel_id from channel where channel_address = '%s' limit 1", - dbesc($channel_address) - ); + // We can do better, but until we figure out auto-linkification, let's keep things simple + + $page_id = 'home'; + + $u = q("select channel_id from channel where channel_address = '%s' limit 1", + dbesc($channel_address) + ); + + if(! $u) { + notice( t('Channel not found.') . EOL); + return; + } + + $r = q("select item.* from item left join item_id on item.id = item_id.iid + where item.uid = %d and sid = '%s' and service = 'WEBPAGE' and + item_restrict = %d limit 1", + intval($u[0]['channel_id']), + dbesc($page_id), + intval(ITEM_WEBPAGE) + ); + + if(! $r) { + notice( t('Item not found.') . EOL); + return; + } + + xchan_query($r); + $r = fetch_post_tags($r,true); + $a->profile = array('profile_uid' => $u[0]['channel_id']); + $o .= prepare_page($r[0]); + return $o; + } - if(! $u) { - notice( t('Channel not found.') . EOL); - return; + if(get_config('system','projecthome')) { + $o .= file_get_contents('assets/home.html'); + $a->page['template'] = 'full'; + return $o; } - $r = q("select item.* from item left join item_id on item.id = item_id.iid - where item.uid = %d and sid = '%s' and service = 'WEBPAGE' and - item_restrict = %d limit 1", - intval($u[0]['channel_id']), - dbesc($page_id), - intval(ITEM_WEBPAGE) - ); - - if(! $r) { - notice( t('Item not found.') . EOL); - return; + if(file_exists('home.html')) { + $o .= file_get_contents('home.html'); } + else { - xchan_query($r); - $r = fetch_post_tags($r,true); - $a->profile = array('profile_uid' => $u[0]['channel_id']); - $o .= prepare_page($r[0]); + // If there's no site channel or home contents configured, fallback to the old behaviour -} - -// If there's no site channel specified, fallback to the old behaviour - else { $o .= '<h1>' . ((x($a->config,'sitename')) ? sprintf( t("Welcome to %s") ,$a->config['sitename']) : "" ) . '</h1>'; - if(file_exists('home.html')) - $o .= file_get_contents('home.html'); -} - - if (!$a->config['system']['no_login_on_homepage']) - $o .= login(($a->config['system']['register_policy'] == REGISTER_CLOSED) ? 0 : 1); - - call_hooks("home_content",$o); - return $o; -} + $sitename = get_config('system','sitename'); + if($sitename) + $o .= '<h1>' . sprintf( t("Welcome to %s") ,$sitename) . '</h1>'; + if (! $a->config['system']['no_login_on_homepage']) + $o .= login(($a->config['system']['register_policy'] == REGISTER_CLOSED) ? 0 : 1); + } + call_hooks('home_content',$o); + return $o; } diff --git a/mod/import.php b/mod/import.php index 94d41455d..5b3b53156 100644 --- a/mod/import.php +++ b/mod/import.php @@ -314,7 +314,7 @@ function import_post(&$a) { . implode("', '", array_values($group)) . "')" ); } - $r = q("select * from `group` where uid = %d", + $r = q("select * from `groups` where uid = %d", intval($channel['channel_id']) ); if($r) { diff --git a/mod/invite.php b/mod/invite.php index e23ed7d2a..9e37d1e6d 100644 --- a/mod/invite.php +++ b/mod/invite.php @@ -42,6 +42,8 @@ function invite_post(&$a) { foreach($recips as $recip) { $recip = trim($recip); + if(! $recip) + continue; if(! valid_email($recip)) { notice( sprintf( t('%s : Not a valid email address.'), $recip) . EOL); diff --git a/mod/item.php b/mod/item.php index 7f881d28d..2feb64a37 100644 --- a/mod/item.php +++ b/mod/item.php @@ -44,7 +44,7 @@ function item_post(&$a) { call_hooks('post_local_start', $_REQUEST); -// logger('postvars ' . print_r($_REQUEST,true), LOGGER_DATA); +// logger('postvars ' . print_r($_REQUEST,true), LOGGER_DATA); $api_source = ((x($_REQUEST,'api_source') && $_REQUEST['api_source']) ? true : false); @@ -66,8 +66,8 @@ function item_post(&$a) { $owner_hash = null; - $message_id = ((x($_REQUEST,'message_id') && $api_source) ? strip_tags($_REQUEST['message_id']) : ''); - + $message_id = ((x($_REQUEST,'message_id') && $api_source) ? strip_tags($_REQUEST['message_id']) : ''); + $created = ((x($_REQUEST,'created')) ? datetime_convert('UTC','UTC',$_REQUEST['created']) : datetime_convert()); $profile_uid = ((x($_REQUEST,'profile_uid')) ? intval($_REQUEST['profile_uid']) : 0); $post_id = ((x($_REQUEST,'post_id')) ? intval($_REQUEST['post_id']) : 0); $app = ((x($_REQUEST,'source')) ? strip_tags($_REQUEST['source']) : ''); @@ -79,6 +79,7 @@ function item_post(&$a) { $layout_mid = ((x($_REQUEST,'layout_mid')) ? escape_tags($_REQUEST['layout_mid']): ''); $plink = ((x($_REQUEST,'permalink')) ? escape_tags($_REQUEST['permalink']) : ''); + /* Check service class limits */ @@ -268,12 +269,16 @@ function item_post(&$a) { $coord = $orig_post['coord']; $verb = $orig_post['verb']; $app = $orig_post['app']; - $title = escape_tags(trim($_REQUEST['title'])); + $title = $_REQUEST['title']; $body = $_REQUEST['body']; $private = $orig_post['item_private']; $item_flags = $orig_post['item_flags']; $item_restrict = $orig_post['item_restrict']; $postopts = $orig_post['postopts']; + $created = $orig_post['created']; + $mid = $orig_post['mid']; + $parent_mid = $orig_post['parent_mid']; + $plink = $orig_post['plink']; } else { @@ -417,10 +422,20 @@ function item_post(&$a) { /** * fix naked links by passing through a callback to see if this is a red site - * (already known to us) which will get a zrl, otherwise link with url + * (already known to us) which will get a zrl, otherwise link with url, add bookmark tag to both. + * First protect any url inside certain bbcode tags so we don't double link it. */ - $body = preg_replace_callback("/([^\]\='".'"'."]|^)(https?\:\/\/[a-zA-Z0-9\:\/\-\?\&\;\.\=\@\_\~\#\%\$\!\+\,]+)/ism", 'red_zrl_callback', $body); + $body = preg_replace_callback('/\[code(.*?)\[\/(code)\]/ism','red_escape_codeblock',$body); + $body = preg_replace_callback('/\[url(.*?)\[\/(url)\]/ism','red_escape_codeblock',$body); + $body = preg_replace_callback('/\[zrl(.*?)\[\/(zrl)\]/ism','red_escape_codeblock',$body); + + $body = preg_replace_callback("/([^\]\='".'"'."]|^|\#\^)(https?\:\/\/[a-zA-Z0-9\:\/\-\?\&\;\.\=\@\_\~\#\%\$\!\+\,]+)/ism", 'red_zrl_callback', $body); + + $body = preg_replace_callback('/\[\$b64zrl(.*?)\[\/(zrl)\]/ism','red_unescape_codeblock',$body); + $body = preg_replace_callback('/\[\$b64url(.*?)\[\/(url)\]/ism','red_unescape_codeblock',$body); + $body = preg_replace_callback('/\[\$b64code(.*?)\[\/(code)\]/ism','red_unescape_codeblock',$body); + /** * @@ -438,6 +453,16 @@ function item_post(&$a) { * the post and we should keep it private. If it's encrypted we have no way of knowing * so we'll set the permissions regardless and realise that the media may not be * referenced in the post. + * + * What is preventing us from being able to upload photos into comments is dealing with + * the photo and attachment permissions, since we don't always know who was in the + * distribution for the top level post. + * + * We might be able to provide this functionality with a lot of fiddling: + * - if the top level post is public (make the photo public) + * - if the top level post was written by us or a wall post that belongs to us (match the top level post) + * - if the top level post has privacy mentions, add those to the permissions. + * - otherwise disallow the photo *or* make the photo public. This is the part that gets messy. */ if(! $preview) { @@ -474,6 +499,7 @@ function item_post(&$a) { $private_forum = false; if(count($tags)) { + $first_access_tag = true; foreach($tags as $tag) { // If we already tagged 'Robert Johnson', don't try and tag 'Robert'. @@ -489,8 +515,24 @@ function item_post(&$a) { if($fullnametagged) continue; - $success = handle_tag($a, $body, $inform, $str_tags, (local_user()) ? local_user() : $profile_uid , $tag); - logger('handle_tag: ' . print_r($success,tue)); + $success = handle_tag($a, $body, $access_tag, $str_tags, (local_user()) ? local_user() : $profile_uid , $tag); + logger('handle_tag: ' . print_r($success,tue), LOGGER_DEBUG); + if(($access_tag) && (! $parent_item)) { + logger('access_tag: ' . $tag . ' ' . print_r($access_tag,true), LOGGER_DEBUG); + if ($first_access_tag) { + $str_contact_allow = ''; + $str_group_allow = ''; + $first_access_tag = false; + } + if(strpos($access_tag,'cid:') === 0) { + $str_contact_allow .= '<' . substr($access_tag,4) . '>'; + $access_tag = ''; + } + elseif(strpos($access_tag,'gid:') === 0) { + $str_group_allow .= '<' . substr($access_tag,4) . '>'; + $access_tag = ''; + } + } if($success['replaced']) { $tagged[] = $tag; @@ -502,10 +544,10 @@ function item_post(&$a) { 'url' => $success['url'] ); } - if(is_array($success['contact']) && intval($success['contact']['prv'])) { - $private_forum = true; - $private_id = $success['contact']['id']; - } +// if(is_array($success['contact']) && intval($success['contact']['prv'])) { +// $private_forum = true; +// $private_id = $success['contact']['id']; +// } } } @@ -559,7 +601,7 @@ function item_post(&$a) { } $item_flags |= ITEM_UNSEEN; - $item_restrict |= ITEM_VISIBLE; +// $item_restrict |= ITEM_VISIBLE; if($post_type === 'wall' || $post_type === 'wall-comment') $item_flags = $item_flags | ITEM_WALL; @@ -579,9 +621,13 @@ function item_post(&$a) { $notify_type = (($parent) ? 'comment-new' : 'wall-new' ); - $mid = (($message_id) ? $message_id : item_message_id()); + if(! $mid) { + $mid = (($message_id) ? $message_id : item_message_id()); + } + if(! $parent_mid) { + $parent_mid = $mid; + } - $parent_mid = $mid; if($parent_item) $parent_mid = $parent_item['mid']; @@ -593,16 +639,19 @@ function item_post(&$a) { $datarray = array(); if(! $parent) { - $datarray['parent_mid'] = $mid; $item_flags = $item_flags | ITEM_THREAD_TOP; } + + if ((! $plink) && ($item_flags & ITEM_THREAD_TOP)) { + $plink = z_root() . '/channel/' . $channel['channel_address'] . '/?f=&mid=' . $mid; + } $datarray['aid'] = $channel['channel_account_id']; $datarray['uid'] = $profile_uid; $datarray['owner_xchan'] = (($owner_hash) ? $owner_hash : $owner_xchan['xchan_hash']); $datarray['author_xchan'] = $observer['xchan_hash']; - $datarray['created'] = datetime_convert(); + $datarray['created'] = $created; $datarray['edited'] = datetime_convert(); $datarray['expires'] = $expires; $datarray['commented'] = datetime_convert(); @@ -639,6 +688,7 @@ function item_post(&$a) { $datarray['owner'] = $owner_xchan; $datarray['author'] = $observer; + $datarray['attach'] = json_encode($datarray['attach']); $o = conversation($a,array($datarray),'search',false,'preview'); logger('preview: ' . $o, LOGGER_DEBUG); echo json_encode(array('preview' => $o)); @@ -692,6 +742,8 @@ function item_post(&$a) { item_store_update($datarray,$execflag); + update_remote_id($channel,$post_id,$webpage,$pagetitle,$namespace,$remote_id,$mid); + proc_run('php', "include/notifier.php", 'edit_post', $post_id); if((x($_REQUEST,'return')) && strlen($return_path)) { logger('return: ' . $return_path); @@ -795,34 +847,8 @@ function item_post(&$a) { // NOTREACHED } - $page_type = ''; - - if($webpage & ITEM_WEBPAGE) - $page_type = 'WEBPAGE'; - elseif($webpage & ITEM_BUILDBLOCK) - $page_type = 'BUILDBLOCK'; - elseif($webpage & ITEM_PDL) - $page_type = 'PDL'; - elseif($namespace && $remote_id) { - $page_type = $namespace; - $pagetitle = $remote_id; - } - - if($page_type) { - // store page info as an alternate message_id so we can access it via - // https://sitename/page/$channelname/$pagetitle - // if no pagetitle was given or it couldn't be transliterated into a url, use the first - // sixteen bytes of the mid - which makes the link portable and not quite as daunting - // as the entire mid. If it were the post_id the link would be less portable. - - q("insert into item_id ( iid, uid, sid, service ) values ( %d, %d, '%s','%s' )", - intval($post_id), - intval($channel['channel_id']), - dbesc(($pagetitle) ? $pagetitle : substr($mid,0,16)), - dbesc($page_type) - ); - } + update_remote_id($channel,$post_id,$webpage,$pagetitle,$namespace,$remote_id,$mid); $datarray['id'] = $post_id; $datarray['llink'] = $a->get_baseurl() . '/display/' . $channel['channel_address'] . '/' . $post_id; @@ -875,35 +901,47 @@ function item_content(&$a) { * the appropiate link. * * @param unknown_type $body the text to replace the tag in - * @param unknown_type $inform a comma-seperated string containing everybody to inform + * @param unknown_type $access_tag - used to return tag ACL exclusions e.g. @!foo * @param unknown_type $str_tags string to add the tag to * @param unknown_type $profile_uid * @param unknown_type $tag the tag to replace * * @return boolean true if replaced, false if not replaced */ -function handle_tag($a, &$body, &$inform, &$str_tags, $profile_uid, $tag) { +function handle_tag($a, &$body, &$access_tag, &$str_tags, $profile_uid, $tag) { $replaced = false; $r = null; - $termtype = ((strpos($tag,'#') === 0) ? TERM_HASHTAG : TERM_UNKNOWN); - $termtype = ((strpos($tag,'@') === 0) ? TERM_MENTION : $termtype); + + $termtype = ((strpos($tag,'#') === 0) ? TERM_HASHTAG : TERM_UNKNOWN); + $termtype = ((strpos($tag,'@') === 0) ? TERM_MENTION : $termtype); + $termtype = ((strpos($tag,'#^[') === 0) ? TERM_BOOKMARK : $termtype); + //is it a hash tag? if(strpos($tag,'#') === 0) { - //if the tag is replaced... - if(strpos($tag,'[zrl=')) + if(strpos($tag,'#^[') === 0) { + if(preg_match('/#\^\[(url|zrl)(.*?)\](.*?)\[\/(url|zrl)\]/',$tag,$match)) { + $basetag = $match[3]; + $url = ((substr($match[2],0,1) === '=') ? substr($match[2],1) : $match[3]); + $replaced = true; + + } + } + // if the tag is already replaced... + elseif(strpos($tag,'[zrl=')) { //...do nothing return $replaced; + } if($tag == '#getzot') { - $basetag = 'getzot'; - $url = 'http://getzot.com'; + $basetag = 'getzot'; + $url = 'https://redmatrix.me'; $newtag = '#[zrl=' . $url . ']' . $basetag . '[/zrl]'; $body = str_replace($tag,$newtag,$body); $replaced = true; } - else { + if(! $replaced) { //base tag has the tags name only $basetag = str_replace('_',' ',substr($tag,1)); //create text for link @@ -922,107 +960,105 @@ function handle_tag($a, &$body, &$inform, &$str_tags, $profile_uid, $tag) { } return array('replaced' => $replaced, 'termtype' => $termtype, 'term' => $basetag, 'url' => $url, 'contact' => $r[0]); } + //is it a person tag? if(strpos($tag,'@') === 0) { + $exclusive = ((strpos($tag,'!') === 1) ? true : false); //is it already replaced? if(strpos($tag,'[zrl=')) return $replaced; $stat = false; //get the person's name - $name = substr($tag,1); - //is it a link or a full dfrn address? - if((strpos($name,'@')) || (strpos($name,'http://'))) { - $newname = $name; - //get the profile links - $links = @lrdd($name); - if(count($links)) { - //for all links, collect how is to inform and how's profile is to link - foreach($links as $link) { - if($link['@attributes']['rel'] === 'http://webfinger.net/rel/profile-page') - $profile = $link['@attributes']['href']; - if($link['@attributes']['rel'] === 'salmon') { - if(strlen($inform)) - $inform .= ','; - $inform .= 'url:' . str_replace(',','%2c',$link['@attributes']['href']); - } - } - } - } else { //if it is a name rather than an address - $newname = $name; - $alias = ''; - $tagcid = 0; - //is it some generated name? - if(strrpos($newname,'+')) { - //get the id - $tagcid = intval(substr($newname,strrpos($newname,'+') + 1)); - //remove the next word from tag's name - if(strpos($name,' ')) { - $name = substr($name,0,strpos($name,' ')); - } + $name = substr($tag,(($exclusive) ? 2 : 1)); + $newname = $name; + $alias = ''; + $tagcid = 0; + + // is it some generated name? + + if(strrpos($newname,'+')) { + //get the id + $tagcid = intval(substr($newname,strrpos($newname,'+') + 1)); + //remove the next word from tag's name + if(strpos($name,' ')) { + $name = substr($name,0,strpos($name,' ')); } - if($tagcid) { //if there was an id - //select contact with that id from the logged in user's contact list + if($tagcid) { // if there was an id + // select channel with that id from the logged in user's address book $r = q("SELECT * FROM abook left join xchan on abook_xchan = xchan_hash WHERE abook_id = %d AND abook_channel = %d LIMIT 1", intval($tagcid), intval($profile_uid) ); - } - else { - $newname = str_replace('_',' ',$name); + } - //select someone from this user's contacts by name - $r = q("SELECT * FROM abook left join xchan on abook_xchan - xchan_hash - WHERE xchan_name = '%s' AND abook_channel = %d LIMIT 1", - dbesc($newname), - intval($profile_uid) - ); + else { + $newname = str_replace('_',' ',$name); - if(! $r) { - //select someone by attag or nick and the name passed in -/* $r = q("SELECT * FROM `contact` WHERE `attag` = '%s' OR `nick` = '%s' AND `uid` = %d ORDER BY `attag` DESC LIMIT 1", - dbesc($name), - dbesc($name), - intval($profile_uid) - ); -*/ } - } -/* } elseif(strstr($name,'_') || strstr($name,' ')) { //no id - //get the real name - $newname = str_replace('_',' ',$name); - //select someone from this user's contacts by name - $r = q("SELECT * FROM `contact` WHERE `name` = '%s' AND `uid` = %d LIMIT 1", - dbesc($newname), - intval($profile_uid) - ); - } else { + //select someone from this user's contacts by name + $r = q("SELECT * FROM abook left join xchan on abook_xchan = xchan_hash + WHERE xchan_name = '%s' AND abook_channel = %d LIMIT 1", + dbesc($newname), + intval($profile_uid) + ); + + if(! $r) { //select someone by attag or nick and the name passed in - $r = q("SELECT * FROM `contact` WHERE `attag` = '%s' OR `nick` = '%s' AND `uid` = %d ORDER BY `attag` DESC LIMIT 1", - dbesc($name), - dbesc($name), + $r = q("SELECT * FROM abook left join xchan on abook_xchan = xchan_hash + WHERE xchan_addr like ('%s') AND abook_channel = %d LIMIT 1", + dbesc($newname . '@%'), intval($profile_uid) ); - }*/ - //$r is set, if someone could be selected - if($r) { - $profile = $r[0]['xchan_url']; - $newname = $r[0]['xchan_name']; - //add person's id to $inform - if(strlen($inform)) - $inform .= ','; - $inform .= 'cid:' . $r[0]['id']; } } + + // $r is set, if someone could be selected + + if($r) { + $profile = $r[0]['xchan_url']; + $newname = $r[0]['xchan_name']; + //add person's id to $access_tag if exclusive + if($exclusive) { + $access_tag .= 'cid:' . $r[0]['xchan_hash']; + } + } + else { + // check for a group/collection exclusion tag + + // note that we aren't setting $replaced even though we're replacing text. + // This tag isn't going to get a term attached to it. It's only used for + // access control. The link points to out own channel just so it doesn't look + // weird - as all the other tags are linked to something. + + if(local_user() && local_user() == $profile_uid) { + require_once('include/group.php'); + $grp = group_byname($profile_uid,$name); + if($grp) { + $g = q("select hash from groups where id = %d and visible = 1 limit 1", + intval($grp[0]['id']) + ); + if($g && $exclusive) { + $access_tag .= 'gid:' . $g[0]['hash']; + } + $channel = get_app()->get_channel(); + if($channel) { + $newtag = '@' . (($exclusive) ? '!' : '') . '[zrl=' . z_root() . '/channel/' . $channel['channel_address'] . ']' . $newname . '[/zrl]'; + $body = str_replace('@' . (($exclusive) ? '!' : '') . $name, $newtag, $body); + } + } + } + } + //if there is an url for this persons profile if(isset($profile)) { $replaced = true; //create profile link $profile = str_replace(',','%2c',$profile); $url = $profile; - $newtag = '@[zrl=' . $profile . ']' . $newname . '[/zrl]'; - $body = str_replace('@' . $name, $newtag, $body); + $newtag = '@' . (($exclusive) ? '!' : '') . '[zrl=' . $profile . ']' . $newname . '[/zrl]'; + $body = str_replace('@' . (($exclusive) ? '!' : '') . $name, $newtag, $body); //append tag to str_tags if(! stristr($str_tags,$newtag)) { if(strlen($str_tags)) @@ -1031,8 +1067,7 @@ function handle_tag($a, &$body, &$inform, &$str_tags, $profile_uid, $tag) { } } } - - return array('replaced' => $replaced, 'termtype' => $termtype, 'term' => $newname, 'url' => $url, 'contact' => $r[0]); + return array('replaced' => $replaced, 'termtype' => $termtype, 'term' => $newname, 'url' => $url, 'contact' => $r[0]); } @@ -1135,8 +1170,9 @@ function item_check_service_class($channel_id,$iswebpage) { if ($iswebpage) { $r = q("select count(i.id) as total from item i right join channel c on (i.author_xchan=c.channel_hash and i.uid=c.channel_id ) - and i.parent=i.id and (i.item_restrict & %d) and i.uid= %d ", + and i.parent=i.id and (i.item_restrict & %d) and not (i.item_restrict & %d) and i.uid= %d ", intval(ITEM_WEBPAGE), + intval(ITEM_DELETED), intval($channel_id) ); } diff --git a/mod/layouts.php b/mod/layouts.php index b1f53d4d8..9ed349850 100644 --- a/mod/layouts.php +++ b/mod/layouts.php @@ -43,9 +43,9 @@ function layouts_content(&$a) { return; } - if(local_user() && local_user() == $owner) { - $a->set_widget('design',design_tools()); - } +// if(local_user() && local_user() == $owner) { + // $a->set_widget('design',design_tools()); + // } $tabs = array( array( diff --git a/mod/like.php b/mod/like.php index 84b0a6592..007d1aee1 100755 --- a/mod/like.php +++ b/mod/like.php @@ -171,6 +171,7 @@ function like_content(&$a) { $arr['deny_cid'] = $item['deny_cid']; $arr['deny_gid'] = $item['deny_gid']; + $post = item_store($arr); $post_id = $post['item_id']; diff --git a/mod/lockview.php b/mod/lockview.php index 7dda85623..32e7a3afb 100644 --- a/mod/lockview.php +++ b/mod/lockview.php @@ -49,7 +49,7 @@ function lockview_content(&$a) { stringify_array_elms($deny_users,true); if(count($allowed_groups)) { - $r = q("SELECT name FROM `group` WHERE hash IN ( " . implode(', ', $allowed_groups) . " )"); + $r = q("SELECT name FROM `groups` WHERE hash IN ( " . implode(', ', $allowed_groups) . " )"); if($r) foreach($r as $rr) $l[] = '<b>' . $rr['name'] . '</b>'; @@ -61,7 +61,7 @@ function lockview_content(&$a) { $l[] = $rr['xchan_name']; } if(count($deny_groups)) { - $r = q("SELECT name FROM `group` WHERE hash IN ( " . implode(', ', $deny_groups) . " )"); + $r = q("SELECT name FROM `groups` WHERE hash IN ( " . implode(', ', $deny_groups) . " )"); if($r) foreach($r as $rr) $l[] = '<b><strike>' . $rr['name'] . '</strike></b>'; diff --git a/mod/magic.php b/mod/magic.php index 03d09e70d..aead559a7 100644 --- a/mod/magic.php +++ b/mod/magic.php @@ -33,21 +33,28 @@ function magic_init(&$a) { if(! $x) { - // Somebody new? Finger them if they've never been seen here before - - if($addr) { - $ret = zot_finger($addr,null); - if($ret['success']) { - $j = json_decode($ret['body'],true); - if($j) - import_xchan($j); - - // Now try again - - $x = q("select * from hubloc where hubloc_url = '%s' order by hubloc_connected desc limit 1", - dbesc($basepath) - ); - } + /* + * We have no records for, or prior communications with this hub. + * If an address was supplied, let's finger them to create a hub record. + * Otherwise we'll use the special address '[system]' which will return + * either a system channel or the first available normal channel. We don't + * really care about what channel is returned - we need the hub information + * from that response so that we can create signed auth packets destined + * for that hub. + * + */ + + $ret = zot_finger((($addr) ? $addr : '[system]@' . $parsed['host']),null); + if($ret['success']) { + $j = json_decode($ret['body'],true); + if($j) + import_xchan($j); + + // Now try again + + $x = q("select * from hubloc where hubloc_url = '%s' order by hubloc_connected desc limit 1", + dbesc($basepath) + ); } } diff --git a/mod/mail.php b/mod/mail.php new file mode 100644 index 000000000..eb1b0ddc0 --- /dev/null +++ b/mod/mail.php @@ -0,0 +1,349 @@ +<?php + +require_once('include/acl_selectors.php'); +require_once('include/message.php'); +require_once('include/zot.php'); +require_once("include/bbcode.php"); +require_once('include/Contact.php'); + + +function mail_post(&$a) { + + if(! local_user()) + return; + + $replyto = ((x($_REQUEST,'replyto')) ? notags(trim($_REQUEST['replyto'])) : ''); + $subject = ((x($_REQUEST,'subject')) ? notags(trim($_REQUEST['subject'])) : ''); + $body = ((x($_REQUEST,'body')) ? escape_tags(trim($_REQUEST['body'])) : ''); + $recipient = ((x($_REQUEST,'messageto')) ? notags(trim($_REQUEST['messageto'])) : ''); + $rstr = ((x($_REQUEST,'messagerecip')) ? notags(trim($_REQUEST['messagerecip'])) : ''); + $expires = ((x($_REQUEST,'expires')) ? datetime_convert(date_default_timezone_get(),'UTC', $_REQUEST['expires']) : '0000-00-00 00:00:00'); + + // If we have a raw string for a recipient which hasn't been auto-filled, + // it means they probably aren't in our address book, hence we don't know + // if we have permission to send them private messages. + // finger them and find out before we try and send it. + + if(! $recipient) { + $channel = $a->get_channel(); + + $ret = zot_finger($rstr,$channel); + + if(! $ret['success']) { + notice( t('Unable to lookup recipient.') . EOL); + return; + } + $j = json_decode($ret['body'],true); + + logger('message_post: lookup: ' . $url . ' ' . print_r($j,true)); + + if(! ($j['success'] && $j['guid'])) { + notice( t('Unable to communicate with requested channel.')); + return; + } + + $x = import_xchan($j); + + if(! $x['success']) { + notice( t('Cannot verify requested channel.')); + return; + } + + $recipient = $x['hash']; + + $their_perms = 0; + + $global_perms = get_perms(); + + if($j['permissions']['data']) { + $permissions = crypto_unencapsulate($j['permissions'],$channel['channel_prvkey']); + if($permissions) + $permissions = json_decode($permissions); + logger('decrypted permissions: ' . print_r($permissions,true), LOGGER_DATA); + } + else + $permissions = $j['permissions']; + + foreach($permissions as $k => $v) { + if($v) { + $their_perms = $their_perms | intval($global_perms[$k][1]); + } + } + + if(! ($their_perms & PERMS_W_MAIL)) { + notice( t('Selected channel has private message restrictions. Send failed.')); + return; + } + } + + if(feature_enabled(local_user(),'richtext')) { + $body = fix_mce_lf($body); + } + + if(! $recipient) { + notice('No recipient found.'); + $a->argc = 2; + $a->argv[1] = 'new'; + return; + } + + // We have a local_user, let send_message use the session channel and save a lookup + + $ret = send_message(0, $recipient, $body, $subject, $replyto, $expires); + + if(! $ret['success']) { + notice($ret['message']); + } + + goaway(z_root() . '/message'); + +} + +function mail_content(&$a) { + + $o = ''; + nav_set_selected('messages'); + + if(! local_user()) { + notice( t('Permission denied.') . EOL); + return login(); + } + + $channel = $a->get_channel(); + head_set_icon($channel['xchan_photo_s']); + + $cipher = get_pconfig(local_user(),'system','default_cipher'); + if(! $cipher) + $cipher = 'aes256'; + + $tpl = get_markup_template('mail_head.tpl'); + $header = replace_macros($tpl, array( + '$messages' => t('Messages'), + '$tab_content' => $tab_content + )); + + if((argc() == 3) && (argv(1) === 'drop')) { + if(! intval(argv(2))) + return; + $cmd = argv(1); + + $r = private_messages_drop(local_user(), argv(2)); + if($r) { + info( t('Message deleted.') . EOL ); + } + goaway($a->get_baseurl(true) . '/message' ); + } + + if((argc() == 3) && (argv(1) === 'recall')) { + if(! intval(argv(2))) + return; + $cmd = argv(1); + $r = q("update mail set mail_flags = mail_flags | %d where id = %d and channel_id = %d limit 1", + intval(MAIL_RECALLED), + intval(argv(2)), + intval(local_user()) + ); + proc_run('php','include/notifier.php','mail',intval(argv(2))); + + if($r) { + info( t('Message recalled.') . EOL ); + } + goaway($a->get_baseurl(true) . '/message' ); + + } + + if((argc() > 1) && (argv(1) === 'new')) { + + $o .= $header; + + $plaintext = false; + if(intval(get_pconfig(local_user(),'system','plaintext'))) + $plaintext = true; + if(! feature_enabled(local_user(),'richtext')) + $plaintext = true; + + $tpl = get_markup_template('msg-header.tpl'); + + $a->page['htmlhead'] .= replace_macros($tpl, array( + '$baseurl' => $a->get_baseurl(true), + '$editselect' => (($plaintext) ? 'none' : '/(profile-jot-text|prvmail-text)/'), + '$nickname' => $channel['channel_address'], + '$linkurl' => t('Please enter a link URL:'), + '$expireswhen' => t('Expires YYYY-MM-DD HH:MM') + )); + + $preselect = (isset($a->argv[2])?array($a->argv[2]):false); + + + $prename = $preurl = $preid = ''; + + if($preselect) { + $r = q("select abook.*, xchan.* from abook left join xchan on abook_xchan = xchan_hash + where abook_channel = %d and abook_id = %d limit 1", + intval(local_user()), + intval(argv(2)) + ); + if($r) { + $prename = $r[0]['xchan_name']; + $preurl = $r[0]['xchan_url']; + $preid = $r[0]['abook_id']; + } + } + + $prefill = (($preselect) ? $prename : ''); + + if(! $prefill) { + if(array_key_exists('to',$_REQUEST)) + $prefill = $_REQUEST['to']; + } + + // the ugly select box + + $select = contact_select('messageto','message-to-select', $preselect, 4, true, false, false, 10); + + $tpl = get_markup_template('prv_message.tpl'); + $o .= replace_macros($tpl,array( + '$header' => t('Send Private Message'), + '$to' => t('To:'), + '$showinputs' => 'true', + '$prefill' => $prefill, + '$autocomp' => $autocomp, + '$preid' => $preid, + '$subject' => t('Subject:'), + '$subjtxt' => ((x($_REQUEST,'subject')) ? strip_tags($_REQUEST['subject']) : ''), + '$text' => ((x($_REQUEST,'body')) ? htmlspecialchars($_REQUEST['body'], ENT_COMPAT, 'UTF-8') : ''), + '$readonly' => '', + '$yourmessage' => t('Your message:'), + '$select' => $select, + '$parent' => '', + '$upload' => t('Upload photo'), + '$attach' => t('Attach file'), + '$insert' => t('Insert web link'), + '$wait' => t('Please wait'), + '$submit' => t('Submit'), + '$defexpire' => '', + '$feature_expire' => ((feature_enabled(local_user(),'content_expire')) ? 'block' : 'none'), + '$expires' => t('Set expiration date'), + '$feature_encrypt' => ((feature_enabled(local_user(),'content_encrypt')) ? 'block' : 'none'), + '$encrypt' => t('Encrypt text'), + '$cipher' => $cipher, + + + )); + + return $o; + } + + + if((argc() > 1) && (intval(argv(1)))) { + + $o .= $header; + + $plaintext = true; + if( local_user() && feature_enabled(local_user(),'richtext') ) + $plaintext = false; + + $messages = private_messages_fetch_conversation(local_user(), argv(1), true); + + if(! $messages) { + info( t('Message not found.') . EOL); + return $o; + } + + if($messages[0]['to_xchan'] === $channel['channel_hash']) + $a->poi = $messages[0]['from']; + else + $a->poi = $messages[0]['to']; + +// require_once('include/Contact.php'); + +// $a->set_widget('mail_conversant',vcard_from_xchan($a->poi,$get_observer_hash,'mail')); + + + $tpl = get_markup_template('msg-header.tpl'); + + $a->page['htmlhead'] .= replace_macros($tpl, array( + '$nickname' => $channel['channel_addr'], + '$baseurl' => $a->get_baseurl(true), + '$editselect' => (($plaintext) ? 'none' : '/(profile-jot-text|prvmail-text)/'), + '$linkurl' => t('Please enter a link URL:'), + '$expireswhen' => t('Expires YYYY-MM-DD HH:MM') + )); + + + $mails = array(); + $seen = 0; + $unknown = false; + + foreach($messages as $message) { + + $s = theme_attachments($message); + + $mails[] = array( + 'id' => $message['id'], + 'from_name' => $message['from']['xchan_name'], + 'from_url' => chanlink_hash($message['from_xchan']), + 'from_photo' => $message['from']['xchan_photo_m'], + 'to_name' => $message['to']['xchan_name'], + 'to_url' => chanlink_hash($message['to_xchan']), + 'to_photo' => $message['to']['xchan_photo_m'], + 'subject' => $message['title'], + 'body' => smilies(bbcode($message['body']) . $s), + 'delete' => t('Delete message'), + 'recall' => t('Recall message'), + 'can_recall' => (($channel['channel_hash'] == $message['from_xchan']) ? true : false), + 'is_recalled' => (($message['mail_flags'] & MAIL_RECALLED) ? t('Message has been recalled.') : ''), + 'date' => datetime_convert('UTC',date_default_timezone_get(),$message['created'],'D, d M Y - g:i A'), + ); + + $seen = $message['seen']; + + } + + $recp = (($message['from_xchan'] === $channel['channel_hash']) ? 'to' : 'from'); + +// FIXME - move this HTML to template + + $select = $message[$recp]['xchan_name'] . '<input type="hidden" name="messageto" value="' . $message[$recp]['xchan_hash'] . '" />'; + $parent = '<input type="hidden" name="replyto" value="' . $message['parent_mid'] . '" />'; + + $tpl = get_markup_template('mail_display.tpl'); + $o = replace_macros($tpl, array( + '$prvmsg_header' => t('Private Conversation'), + '$thread_id' => $a->argv[1], + '$thread_subject' => $message['title'], + '$thread_seen' => $seen, + '$delete' => t('Delete conversation'), + '$canreply' => (($unknown) ? false : '1'), + '$unknown_text' => t("No secure communications available. You <strong>may</strong> be able to respond from the sender's profile page."), + '$mails' => $mails, + + // reply + '$header' => t('Send Reply'), + '$to' => t('To:'), + '$showinputs' => '', + '$subject' => t('Subject:'), + '$subjtxt' => $message['title'], + '$readonly' => ' readonly="readonly" style="background: #BBBBBB;" ', + '$yourmessage' => t('Your message:'), + '$text' => '', + '$select' => $select, + '$parent' => $parent, + '$upload' => t('Upload photo'), + '$attach' => t('Attach file'), + '$insert' => t('Insert web link'), + '$submit' => t('Submit'), + '$wait' => t('Please wait'), + '$defexpire' => '', + '$feature_expire' => ((feature_enabled(local_user(),'content_expire')) ? 'block' : 'none'), + '$expires' => t('Set expiration date'), + '$feature_encrypt' => ((feature_enabled(local_user(),'content_encrypt')) ? 'block' : 'none'), + '$encrypt' => t('Encrypt text'), + '$cipher' => $cipher, + + )); + + return $o; + } + +} diff --git a/mod/manage.php b/mod/manage.php index a2f65b271..0772e2d61 100644 --- a/mod/manage.php +++ b/mod/manage.php @@ -55,8 +55,9 @@ function manage_content(&$a) { } } - $r = q("select count(channel_id) as total from channel where channel_account_id = %d ", - intval(get_account_id()) + $r = q("select count(channel_id) as total from channel where channel_account_id = %d and not ( channel_pageflags & %d )", + intval(get_account_id()), + intval(PAGE_REMOVED) ); $limit = service_class_fetch(local_user(),'total_identities'); if($limit !== false) { diff --git a/mod/menu.php b/mod/menu.php index 1ec3c7996..a2d0c2385 100644 --- a/mod/menu.php +++ b/mod/menu.php @@ -8,6 +8,10 @@ function menu_post(&$a) { return; $_REQUEST['menu_channel_id'] = local_user(); + if($_REQUEST['menu_bookmark']) + $_REQUEST['menu_flags'] |= MENU_BOOKMARK; + if($_REQUEST['menu_system']) + $_REQUEST['menu_flags'] |= MENU_SYSTEM; $menu_id = ((argc() > 1) ? intval(argv(1)) : 0); if($menu_id) { @@ -42,7 +46,7 @@ function menu_content(&$a) { } - $a->set_widget('design',design_tools()); +// $a->set_widget('design',design_tools()); if(argc() == 1) { @@ -76,6 +80,7 @@ function menu_content(&$a) { '$header' => t('New Menu'), '$menu_name' => array('menu_name', t('Menu name'), '', t('Must be unique, only seen by you'), '*'), '$menu_desc' => array('menu_desc', t('Menu title'), '', t('Menu title as seen by others'), ''), + '$menu_bookmark' => array('menu_bookmark', t('Allow bookmarks'), 0 , t('Menu may be used to store saved bookmarks'), ''), '$submit' => t('Create') )); return $o; @@ -104,6 +109,8 @@ function menu_content(&$a) { '$editcontents' => t('Edit menu contents'), '$menu_name' => array('menu_name', t('Menu name'), $m['menu_name'], t('Must be unique, only seen by you'), '*'), '$menu_desc' => array('menu_desc', t('Menu title'), $m['menu_desc'], t('Menu title as seen by others'), ''), + '$menu_bookmark' => array('menu_bookmark', t('Allow bookmarks'), (($m['menu_flags'] & MENU_BOOKMARK) ? 1 : 0), t('Menu may be used to store saved bookmarks'), ''), + '$menu_system' => (($m['menu_flags'] & MENU_SYSTEM) ? 1 : 0), '$submit' => t('Modify') )); return $o; diff --git a/mod/message.php b/mod/message.php index a0382f63d..c14bf2161 100644 --- a/mod/message.php +++ b/mod/message.php @@ -7,198 +7,6 @@ require_once("include/bbcode.php"); require_once('include/Contact.php'); -function message_aside(&$a) { - - if (! local_user()) - return; - - $a->set_widget('msgaside',replace_macros(get_markup_template('message_side.tpl'), array( - '$tabs'=> array(), - - '$check'=>array( - 'label' => t('Check Mail'), - 'url' => $a->get_baseurl(true) . '/message', - 'sel' => (argv(1) == ''), - ), - '$new'=>array( - 'label' => t('New Message'), - 'url' => $a->get_baseurl(true) . '/message/new', - 'sel'=> (argv(1) == 'new'), - ) - - ))); - -} - -function message_post(&$a) { - - if(! local_user()) - return; - - $replyto = ((x($_REQUEST,'replyto')) ? notags(trim($_REQUEST['replyto'])) : ''); - $subject = ((x($_REQUEST,'subject')) ? notags(trim($_REQUEST['subject'])) : ''); - $body = ((x($_REQUEST,'body')) ? escape_tags(trim($_REQUEST['body'])) : ''); - $recipient = ((x($_REQUEST,'messageto')) ? notags(trim($_REQUEST['messageto'])) : ''); - $rstr = ((x($_REQUEST,'messagerecip')) ? notags(trim($_REQUEST['messagerecip'])) : ''); - $expires = ((x($_REQUEST,'expires')) ? datetime_convert(date_default_timezone_get(),'UTC', $_REQUEST['expires']) : '0000-00-00 00:00:00'); - - // If we have a raw string for a recipient which hasn't been auto-filled, - // it means they probably aren't in our address book, hence we don't know - // if we have permission to send them private messages. - // finger them and find out before we try and send it. - - if(! $recipient) { - $channel = $a->get_channel(); - - $ret = zot_finger($rstr,$channel); - - if(! $ret['success']) { - notice( t('Unable to lookup recipient.') . EOL); - return; - } - $j = json_decode($ret['body'],true); - - logger('message_post: lookup: ' . $url . ' ' . print_r($j,true)); - - if(! ($j['success'] && $j['guid'])) { - notice( t('Unable to communicate with requested channel.')); - return; - } - - $x = import_xchan($j); - - if(! $x['success']) { - notice( t('Cannot verify requested channel.')); - return; - } - - $recipient = $x['hash']; - - $their_perms = 0; - - $global_perms = get_perms(); - - if($j['permissions']['data']) { - $permissions = crypto_unencapsulate($j['permissions'],$channel['channel_prvkey']); - if($permissions) - $permissions = json_decode($permissions); - logger('decrypted permissions: ' . print_r($permissions,true), LOGGER_DATA); - } - else - $permissions = $j['permissions']; - - foreach($permissions as $k => $v) { - if($v) { - $their_perms = $their_perms | intval($global_perms[$k][1]); - } - } - - if(! ($their_perms & PERMS_W_MAIL)) { - notice( t('Selected channel has private message restrictions. Send failed.')); - return; - } - } - - if(feature_enabled(local_user(),'richtext')) { - $body = fix_mce_lf($body); - } - - if(! $recipient) { - notice('No recipient found.'); - $a->argc = 2; - $a->argv[1] = 'new'; - return; - } - - // We have a local_user, let send_message use the session channel and save a lookup - - $ret = send_message(0, $recipient, $body, $subject, $replyto, $expires); - - if(! $ret['success']) { - notice($ret['message']); - } - -} - -// Note: the code in 'item_extract_images' and 'item_redir_and_replace_images' -// is identical to the code in include/conversation.php -if(! function_exists('item_extract_images')) { -function item_extract_images($body) { - - $saved_image = array(); - $orig_body = $body; - $new_body = ''; - - $cnt = 0; - $img_start = strpos($orig_body, '[img'); - $img_st_close = ($img_start !== false ? strpos(substr($orig_body, $img_start), ']') : false); - $img_end = ($img_start !== false ? strpos(substr($orig_body, $img_start), '[/img]') : false); - while(($img_st_close !== false) && ($img_end !== false)) { - - $img_st_close++; // make it point to AFTER the closing bracket - $img_end += $img_start; - - if(! strcmp(substr($orig_body, $img_start + $img_st_close, 5), 'data:')) { - // This is an embedded image - - $saved_image[$cnt] = substr($orig_body, $img_start + $img_st_close, $img_end - ($img_start + $img_st_close)); - $new_body = $new_body . substr($orig_body, 0, $img_start) . '[!#saved_image' . $cnt . '#!]'; - - $cnt++; - } - else - $new_body = $new_body . substr($orig_body, 0, $img_end + strlen('[/img]')); - - $orig_body = substr($orig_body, $img_end + strlen('[/img]')); - - if($orig_body === false) // in case the body ends on a closing image tag - $orig_body = ''; - - $img_start = strpos($orig_body, '[img'); - $img_st_close = ($img_start !== false ? strpos(substr($orig_body, $img_start), ']') : false); - $img_end = ($img_start !== false ? strpos(substr($orig_body, $img_start), '[/img]') : false); - } - - $new_body = $new_body . $orig_body; - - return array('body' => $new_body, 'images' => $saved_image); -}} - -if(! function_exists('item_redir_and_replace_images')) { -function item_redir_and_replace_images($body, $images, $cid) { - - $origbody = $body; - $newbody = ''; - - for($i = 0; $i < count($images); $i++) { - $search = '/\[zrl\=(.*?)\]\[!#saved_image' . $i . '#!\]\[\/zrl\]' . '/is'; -//FIXME - $replace = '[zrl=' . z_path() . '/redir/' . $cid - . '?f=1&url=' . '$1' . '][!#saved_image' . $i . '#!][/zrl]' ; - - $img_end = strpos($origbody, '[!#saved_image' . $i . '#!][/url]') + strlen('[!#saved_image' . $i . '#!][/url]'); - $process_part = substr($origbody, 0, $img_end); - $origbody = substr($origbody, $img_end); - - $process_part = preg_replace($search, $replace, $process_part); - $newbody = $newbody . $process_part; - } - $newbody = $newbody . $origbody; - - $cnt = 0; - foreach($images as $image) { - // We're depending on the property of 'foreach' (specified on the PHP website) that - // it loops over the array starting from the first element and going sequentially - // to the last element - $newbody = str_replace('[!#saved_image' . $cnt . '#!]', '[img]' . $image . '[/img]', $newbody); - $cnt++; - } - - return $newbody; -}} - - - function message_content(&$a) { $o = ''; @@ -224,126 +32,15 @@ function message_content(&$a) { '$tab_content' => $tab_content )); - if((argc() == 3) && (argv(1) === 'drop' || argv(1) === 'dropconv')) { - if(! intval(argv(2))) - return; - $cmd = argv(1); - if($cmd === 'drop') { - $r = private_messages_drop(local_user(), argv(2)); - if($r) { - info( t('Message deleted.') . EOL ); - } - goaway($a->get_baseurl(true) . '/message' ); - } - else { - $r = private_messages_drop(local_user(), argv(2), true); - if($r) - info( t('Conversation removed.') . EOL ); - goaway($a->get_baseurl(true) . '/message' ); - } - } - - if((argc() == 3) && (argv(1) === 'recall')) { + if((argc() == 3) && (argv(1) === 'dropconv')) { if(! intval(argv(2))) return; $cmd = argv(1); - $r = q("update mail set mail_flags = mail_flags | %d where id = %d and channel_id = %d limit 1", - intval(MAIL_RECALLED), - intval(argv(2)), - intval(local_user()) - ); - proc_run('php','include/notifier.php','mail',intval(argv(2))); - - if($r) { - info( t('Message recalled.') . EOL ); - } + $r = private_messages_drop(local_user(), argv(2), true); + if($r) + info( t('Conversation removed.') . EOL ); goaway($a->get_baseurl(true) . '/message' ); - - } - - - if((argc() > 1) && ($a->argv[1] === 'new')) { - - $o .= $header; - - $plaintext = false; - if(intval(get_pconfig(local_user(),'system','plaintext'))) - $plaintext = true; - if(! feature_enabled(local_user(),'richtext')) - $plaintext = true; - - $tpl = get_markup_template('msg-header.tpl'); - - $a->page['htmlhead'] .= replace_macros($tpl, array( - '$baseurl' => $a->get_baseurl(true), - '$editselect' => (($plaintext) ? 'none' : '/(profile-jot-text|prvmail-text)/'), - '$nickname' => $channel['channel_address'], - '$linkurl' => t('Please enter a link URL:'), - '$expireswhen' => t('Expires YYYY-MM-DD HH:MM') - )); - - $preselect = (isset($a->argv[2])?array($a->argv[2]):false); - - - $prename = $preurl = $preid = ''; - - if($preselect) { - $r = q("select abook.*, xchan.* from abook left join xchan on abook_xchan = xchan_hash - where abook_channel = %d and abook_id = %d limit 1", - intval(local_user()), - intval(argv(2)) - ); - if($r) { - $prename = $r[0]['xchan_name']; - $preurl = $r[0]['xchan_url']; - $preid = $r[0]['abook_id']; - } - } - - $prefill = (($preselect) ? $prename : ''); - - if(! $prefill) { - if(array_key_exists('to',$_REQUEST)) - $prefill = $_REQUEST['to']; - } - - // the ugly select box - - $select = contact_select('messageto','message-to-select', $preselect, 4, true, false, false, 10); - - $tpl = get_markup_template('prv_message.tpl'); - $o .= replace_macros($tpl,array( - '$header' => t('Send Private Message'), - '$to' => t('To:'), - '$showinputs' => 'true', - '$prefill' => $prefill, - '$autocomp' => $autocomp, - '$preid' => $preid, - '$subject' => t('Subject:'), - '$subjtxt' => ((x($_REQUEST,'subject')) ? strip_tags($_REQUEST['subject']) : ''), - '$text' => ((x($_REQUEST,'body')) ? escape_tags(htmlspecialchars($_REQUEST['body'])) : ''), - '$readonly' => '', - '$yourmessage' => t('Your message:'), - '$select' => $select, - '$parent' => '', - '$upload' => t('Upload photo'), - '$attach' => t('Attach file'), - '$insert' => t('Insert web link'), - '$wait' => t('Please wait'), - '$submit' => t('Submit'), - '$defexpire' => '', - '$feature_expire' => ((feature_enabled(local_user(),'content_expire')) ? 'block' : 'none'), - '$expires' => t('Set expiration date'), - '$feature_encrypt' => ((feature_enabled(local_user(),'content_encrypt')) ? 'block' : 'none'), - '$encrypt' => t('Encrypt text'), - '$cipher' => $cipher, - - - )); - - return $o; } - if(argc() == 1) { // list messages @@ -382,148 +79,5 @@ function message_content(&$a) { return $o; } - if((argc() > 1) && (intval(argv(1)))) { - - $o .= $header; - - $plaintext = true; - if( local_user() && feature_enabled(local_user(),'richtext') ) - $plaintext = false; - - $messages = private_messages_fetch_conversation(local_user(), argv(1), true); - - if(! $messages) { - info( t('Message not found.') . EOL); - return $o; - } - - $other_channel = null; - if($messages[0]['to_xchan'] === $channel['channel_hash']) - $other_channel = $messages[0]['from']; - else - $other_channel = $messages[0]['to']; - - require_once('include/Contact.php'); - - $a->set_widget('mail_conversant',vcard_from_xchan($other_channel,$get_observer_hash,'mail')); - - - $tpl = get_markup_template('msg-header.tpl'); - - $a->page['htmlhead'] .= replace_macros($tpl, array( - '$nickname' => $channel['channel_addr'], - '$baseurl' => $a->get_baseurl(true), - '$editselect' => (($plaintext) ? 'none' : '/(profile-jot-text|prvmail-text)/'), - '$linkurl' => t('Please enter a link URL:'), - '$expireswhen' => t('Expires YYYY-MM-DD HH:MM') - )); - - - $mails = array(); - $seen = 0; - $unknown = false; - - foreach($messages as $message) { - - $s = $arr = ''; - - if($message['attach']) - $arr = json_decode_plus($message['attach']); - if($arr) { - $s .= '<div class="body-attach">'; - foreach($arr as $r) { - $matches = false; - $icon = ''; - $icontype = substr($r['type'],0,strpos($r['type'],'/')); - - switch($icontype) { - case 'video': - case 'audio': - case 'image': - case 'text': - $icon = '<div class="attachtype icon s22 type-' . $icontype . '"></div>'; - break; - default: - $icon = '<div class="attachtype icon s22 type-unkn"></div>'; - break; - } - - $title = htmlentities($r['title'], ENT_COMPAT,'UTF-8'); - if(! $title) - $title = t('unknown.???'); - $title .= ' ' . $r['length'] . ' ' . t('bytes'); - - $url = $a->get_baseurl() . '/magic?f=&hash=' . $message['from_xchan'] . '&dest=' . $r['href'] . '/' . $r['revision']; - $s .= '<a href="' . $url . '" title="' . $title . '" class="attachlink" >' . $icon . '</a>'; - } - $s .= '<div class="clear"></div></div>'; - } - - $mails[] = array( - 'id' => $message['id'], - 'from_name' => $message['from']['xchan_name'], - 'from_url' => chanlink_hash($message['from_xchan']), - 'from_photo' => $message['from']['xchan_photo_m'], - 'to_name' => $message['to']['xchan_name'], - 'to_url' => chanlink_hash($message['to_xchan']), - 'to_photo' => $message['to']['xchan_photo_m'], - 'subject' => $message['title'], - 'body' => smilies(bbcode($message['body']) . $s), - 'delete' => t('Delete message'), - 'recall' => t('Recall message'), - 'can_recall' => (($channel['channel_hash'] == $message['from_xchan']) ? true : false), - 'is_recalled' => (($message['mail_flags'] & MAIL_RECALLED) ? t('Message has been recalled.') : ''), - 'date' => datetime_convert('UTC',date_default_timezone_get(),$message['created'],'D, d M Y - g:i A'), - ); - - $seen = $message['seen']; - - } - - $recp = (($message['from_xchan'] === $channel['channel_hash']) ? 'to' : 'from'); - -// FIXME - move this HTML to template - - $select = $message[$recp]['xchan_name'] . '<input type="hidden" name="messageto" value="' . $message[$recp]['xchan_hash'] . '" />'; - $parent = '<input type="hidden" name="replyto" value="' . $message['parent_mid'] . '" />'; - - $tpl = get_markup_template('mail_display.tpl'); - $o = replace_macros($tpl, array( - '$prvmsg_header' => t('Private Conversation'), - '$thread_id' => $a->argv[1], - '$thread_subject' => $message['title'], - '$thread_seen' => $seen, - '$delete' => t('Delete conversation'), - '$canreply' => (($unknown) ? false : '1'), - '$unknown_text' => t("No secure communications available. You <strong>may</strong> be able to respond from the sender's profile page."), - '$mails' => $mails, - - // reply - '$header' => t('Send Reply'), - '$to' => t('To:'), - '$showinputs' => '', - '$subject' => t('Subject:'), - '$subjtxt' => $message['title'], - '$readonly' => ' readonly="readonly" style="background: #BBBBBB;" ', - '$yourmessage' => t('Your message:'), - '$text' => '', - '$select' => $select, - '$parent' => $parent, - '$upload' => t('Upload photo'), - '$attach' => t('Attach file'), - '$insert' => t('Insert web link'), - '$submit' => t('Submit'), - '$wait' => t('Please wait'), - '$defexpire' => '', - '$feature_expire' => ((feature_enabled(local_user(),'content_expire')) ? 'block' : 'none'), - '$expires' => t('Set expiration date'), - '$feature_encrypt' => ((feature_enabled(local_user(),'content_encrypt')) ? 'block' : 'none'), - '$encrypt' => t('Encrypt text'), - '$cipher' => $cipher, - - )); - - return $o; - } } diff --git a/mod/mitem.php b/mod/mitem.php index 8e60e2d65..e0aa1b87a 100644 --- a/mod/mitem.php +++ b/mod/mitem.php @@ -81,11 +81,8 @@ function mitem_content(&$a) { $channel = $a->get_channel(); - $a->set_widget('design',design_tools()); - - $m = menu_fetch($a->data['menu']['menu_name'],local_user(), get_observer_hash()); - $a->set_widget('menu_preview',menu_render($m)); + $a->data['menu_item'] = $m; if(argc() == 2) { diff --git a/mod/mood.php b/mod/mood.php index 83b8bfb57..5075f622d 100755 --- a/mod/mood.php +++ b/mod/mood.php @@ -11,6 +11,7 @@ function mood_init(&$a) { return; $uid = local_user(); + $channel = $a->get_channel(); $verb = notags(trim($_GET['verb'])); if(! $verb) @@ -48,7 +49,6 @@ function mood_init(&$a) { else { $private = 0; - $channel = $a->get_channel(); $allow_cid = $channel['channel_allow_cid']; $allow_gid = $channel['channel_allow_gid']; @@ -84,6 +84,11 @@ function mood_init(&$a) { $arr['verb'] = $activity; $arr['body'] = $action; + if ((! $arr['plink']) && ($arr['item_flags'] & ITEM_THREAD_TOP)) { + $arr['plink'] = z_root() . '/channel/' . $channel['channel_address'] . '/?f=&mid=' . $arr['mid']; + } + + $post = item_store($arr); $item_id = $post['item_id']; diff --git a/mod/network.php b/mod/network.php index 754978949..191fe55ed 100644 --- a/mod/network.php +++ b/mod/network.php @@ -69,7 +69,7 @@ function network_content(&$a, $update = 0, $load = false) { $_GET['order'] = 'post'; if($gid) { - $r = q("SELECT * FROM `group` WHERE id = %d AND uid = %d LIMIT 1", + $r = q("SELECT * FROM `groups` WHERE id = %d AND uid = %d LIMIT 1", intval($gid), intval(local_user()) ); @@ -111,36 +111,11 @@ function network_content(&$a, $update = 0, $load = false) { if(! $update) { - - if(feature_enabled(local_user(),'affinity')) { - $tpl = get_markup_template('main_slider.tpl'); - $x = replace_macros($tpl,array( - '$val' => intval($cmin) . ';' . intval($cmax), - '$refresh' => t('Refresh'), - '$me' => t('Me'), - '$intimate' => t('Best Friends'), - '$friends' => t('Friends'), - '$coworkers' => t('Co-workers'), - '$oldfriends' => t('Former Friends'), - '$acquaintances' => t('Acquaintances'), - '$world' => t('Everybody') - )); - $arr = array('html' => $x); - call_hooks('main_slider',$arr); - $o .= $arr['html']; - } - - $o .= network_tabs(); - // --- end item filter tabs - - - - // search terms header if($search) - $o .= '<h2>' . t('Search Results For:') . ' ' . htmlspecialchars($search) . '</h2>'; + $o .= '<h2>' . t('Search Results For:') . ' ' . htmlspecialchars($search, ENT_COMPAT,'UTF-8') . '</h2>'; nav_set_selected('network'); @@ -262,6 +237,7 @@ function network_content(&$a, $update = 0, $load = false) { '$spam' => (($spam) ? $spam : '0'), '$nouveau' => (($nouveau) ? $nouveau : '0'), '$wall' => '0', + '$list' => ((x($_REQUEST,'list')) ? intval($_REQUEST['list']) : 0), '$page' => (($a->pager['page'] != 1) ? $a->pager['page'] : 1), '$search' => (($search) ? $search : ''), '$order' => $order, diff --git a/mod/notes.php b/mod/notes.php index ce3460aa4..468b4ef26 100644 --- a/mod/notes.php +++ b/mod/notes.php @@ -6,11 +6,11 @@ function notes_init(&$a) { logger('mod_notes: ' . print_r($_REQUEST,true)); $ret = array('success' => true); - if($_REQUEST['note_text']) { + if($_REQUEST['note_text'] || $_REQUEST['note_text'] == '') { $body = escape_tags($_REQUEST['note_text']); set_pconfig(local_user(),'notes','text',$body); } logger('notes saved.'); json_return_and_die($ret); -}
\ No newline at end of file +} diff --git a/mod/online.php b/mod/online.php new file mode 100644 index 000000000..c6500347a --- /dev/null +++ b/mod/online.php @@ -0,0 +1,11 @@ +<?php /** @file */ + +function online_init(&$a) { + + $ret = array('result' => false); + if(argc() != 2) + json_return_and_die($ret); + + $ret = get_online_status(argv(1)); + json_return_and_die($ret); +} diff --git a/mod/openid.php b/mod/openid.php new file mode 100644 index 000000000..b0d4008d4 --- /dev/null +++ b/mod/openid.php @@ -0,0 +1,189 @@ +<?php + + +require_once('library/openid/openid.php'); +require_once('include/auth.php'); + +function openid_content(&$a) { + + $noid = get_config('system','disable_openid'); + if($noid) + goaway(z_root()); + + logger('mod_openid ' . print_r($_REQUEST,true), LOGGER_DATA); + + if(x($_REQUEST,'openid_mode')) { + + $openid = new LightOpenID(z_root()); + + if($openid->validate()) { + + logger('openid: validate'); + + $authid = normalise_openid($_REQUEST['openid_identity']); + + if(! strlen($authid)) { + logger( t('OpenID protocol error. No ID returned.') . EOL); + goaway(z_root()); + } + + $x = match_openid($authid); + if($x) { + + $r = q("select * from channel where channel_id = %d limit 1", + intval($x) + ); + if($r) { + $y = q("select * from account where account_id = %d limit 1", + intval($r[0]['channel_account_id']) + ); + if($y) { + foreach($y as $record) { + if(($record['account_flags'] == ACCOUNT_OK) || ($record['account_flags'] == ACCOUNT_UNVERIFIED)) { + logger('mod_openid: openid success for ' . $x[0]['channel_name']); + $_SESSION['uid'] = $r[0]['channel_id']; + $_SESSION['account_id'] = $r[0]['channel_account_id']; + $_SESSION['authenticated'] = true; + authenticate_success($record,true,true,true,true); + goaway(z_root()); + } + } + } + } + } + + // Successful OpenID login - but we can't match it to an existing account. + // See if they've got an xchan + + $r = q("select * from xconfig left join xchan on xchan_hash = xconfig.xchan where cat = 'system' and k = 'openid' and v = '%s' limit 1", + dbesc($authid) + ); + + if($r) { + $_SESSION['authenticated'] = 1; + $_SESSION['visitor_id'] = $r[0]['xchan_hash']; + $_SESSION['my_address'] = $r[0]['xchan_addr']; + $arr = array('xchan' => $r[0], 'session' => $_SESSION); + call_hooks('magic_auth_openid_success',$arr); + $a->set_observer($r[0]); + require_once('include/security.php'); + $a->set_groups(init_groups_visitor($_SESSION['visitor_id'])); + info(sprintf( t('Welcome %s. Remote authentication successful.'),$r[0]['xchan_name'])); + logger('mod_openid: remote auth success from ' . $r[0]['xchan_addr']); + if($_SESSION['return_url']) + goaway($_SESSION['return_url']); + goaway(z_root()); + } + + // no xchan... + // create one. + // We should probably probe the openid url and figure out if they have any kind of social presence we might be able to + // scrape some identifying info from. + + $name = $authid; + $url = trim($_REQUEST['openid_identity'],'/'); + if(strpos($url,'http') === false) + $url = 'https://' . $url; + $pphoto = get_default_profile_photo(); + $parsed = @parse_url($url); + if($parsed) { + $host = $parsed['host']; + } + + $attr = $openid->getAttributes(); + + if(is_array($attr) && count($attr)) { + foreach($attr as $k => $v) { + if($k === 'namePerson/friendly') + $nick = notags(trim($v)); + if($k === 'namePerson/first') + $first = notags(trim($v)); + if($k === 'namePerson') + $name = notags(trim($v)); + if($k === 'contact/email') + $addr = notags(trim($v)); + if($k === 'media/image/aspect11') + $photosq = trim($v); + if($k === 'media/image/default') + $photo_other = trim($v); + } + } + if(! $nick) { + if($first) + $nick = $first; + else + $nick = $name; + } + + require_once('library/urlify/URLify.php'); + $x = strtolower(URLify::transliterate($nick)); + if($nick & $host) + $addr = $nick . '@' . $host; + $network = 'unknown'; + + if($photosq) + $pphoto = $photosq; + elseif($photo_other) + $pphoto = $photo_other; + + $x = q("insert into xchan ( xchan_hash, xchan_guid, xchan_guid_sig, xchan_pubkey, xchan_photo_mimetype, + xchan_photo_l, xchan_addr, xchan_url, xchan_connurl, xchan_follow, xchan_connpage, xchan_name, xchan_network, xchan_photo_date, + xchan_name_date, xchan_flags) + values ( '%s', '%s', '%s', '%s' , '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d) ", + dbesc($url), + dbesc(''), + dbesc(''), + dbesc(''), + dbesc('image/jpeg'), + dbesc($pphoto), + dbesc($addr), + dbesc($url), + dbesc(''), + dbesc(''), + dbesc(''), + dbesc($name), + dbesc($network), + dbesc(datetime_convert()), + dbesc(datetime_convert()), + intval(XCHAN_FLAGS_HIDDEN) + ); + if($x) { + $r = q("select * from xchan where xchan_hash = '%s' limit 1", + dbesc($url) + ); + if($r) { + + $photos = import_profile_photo($pphoto,$url); + if($photos) { + $z = q("update xchan set xchan_photo_date = '%s', xchan_photo_l = '%s', xchan_photo_m = '%s', + xchan_photo_s = '%s', xchan_photo_mimetype = '%s' where xchan_hash = '%s' limit 1", + dbesc(datetime_convert()), + dbesc($photos[0]), + dbesc($photos[1]), + dbesc($photos[2]), + dbesc($photos[3]), + dbesc($url) + ); + } + + set_xconfig($url,'system','openid',$authid); + $_SESSION['authenticated'] = 1; + $_SESSION['visitor_id'] = $r[0]['xchan_hash']; + $_SESSION['my_address'] = $r[0]['xchan_addr']; + $arr = array('xchan' => $r[0], 'session' => $_SESSION); + call_hooks('magic_auth_openid_success',$arr); + $a->set_observer($r[0]); + info(sprintf( t('Welcome %s. Remote authentication successful.'),$r[0]['xchan_name'])); + logger('mod_openid: remote auth success from ' . $r[0]['xchan_addr']); + if($_SESSION['return_url']) + goaway($_SESSION['return_url']); + goaway(z_root()); + } + } + + } + } + notice( t('Login failed.') . EOL); + goaway(z_root()); + // NOTREACHED +} diff --git a/mod/parse_url.php b/mod/parse_url.php index c206c24ec..340e1a67e 100644 --- a/mod/parse_url.php +++ b/mod/parse_url.php @@ -252,7 +252,7 @@ function parse_url_content(&$a) { logger('parse_url: ' . $url); - $template = $br . '[url=%s]%s[/url]%s' . $br; + $template = $br . '#^[url=%s]%s[/url]%s' . $br; $arr = array('url' => $url, 'text' => ''); diff --git a/mod/photo.php b/mod/photo.php index 591d7198a..1319f9569 100644 --- a/mod/photo.php +++ b/mod/photo.php @@ -22,9 +22,17 @@ function photo_init(&$a) { // NOTREACHED } + if($photo === 'qr') { + $t = $_GET['qr']; + require_once('library/phpqrcode/phpqrcode.php'); + header("Content-type: image/png"); + QRcode::png(($t) ? $t : '.'); + killme(); + } + $observer_xchan = get_observer_hash(); - $default = 'images/default_profile_photos/rainbow_man/175.jpg'; + $default = get_default_profile_photo(); if(isset($type)) { @@ -38,11 +46,11 @@ function photo_init(&$a) { case 'm': $resolution = 5; - $default = 'images/default_profile_photos/rainbow_man/80.jpg'; + $default = get_default_profile_photo(80); break; case 's': $resolution = 6; - $default = 'images/default_profile_photos/rainbow_man/48.jpg'; + $default = get_default_profile_photo(48); break; case 'l': default: @@ -135,15 +143,15 @@ function photo_init(&$a) { switch($resolution) { case 4: - $data = file_get_contents('images/default_profile_photos/rainbow_man/175.jpg'); + $data = file_get_contents(get_default_profile_photo()); $mimetype = 'image/jpeg'; break; case 5: - $data = file_get_contents('images/default_profile_photos/rainbow_man/80.jpg'); + $data = file_get_contents(get_default_profile_photo(80)); $mimetype = 'image/jpeg'; break; case 6: - $data = file_get_contents('images/default_profile_photos/rainbow_man/48.jpg'); + $data = file_get_contents(get_default_profile_photo(48)); $mimetype = 'image/jpeg'; break; default: diff --git a/mod/photos.php b/mod/photos.php index 64ca86941..e2279188a 100644 --- a/mod/photos.php +++ b/mod/photos.php @@ -19,28 +19,22 @@ function photos_init(&$a) { if(argc() > 1) { $nick = argv(1); + + profile_load($a,$nick); + $channelx = channelx_by_nick($nick); if(! $channelx) return; - $a->data['channel'] = $channelx[0]; + $a->data['channel'] = $channelx; $observer = $a->get_observer(); $a->data['observer'] = $observer; $observer_xchan = (($observer) ? $observer['xchan_hash'] : ''); - $a->data['perms'] = get_all_perms($channelx[0]['channel_id'],$observer_xchan); - - - - $a->set_widget('vcard',vcard_from_xchan($a->data['channel'],$observer)); head_set_icon($a->data['channel']['xchan_photo_s']); - if($a->data['perms']['view_photos']) { - $a->data['albums'] = photos_albums_list($a->data['channel'],$observer); - $a->set_widget('photo_albums',photos_album_widget($a->data['channel'],$observer,$a->data['albums'])); - } $a->page['htmlhead'] .= "<script> var ispublic = '" . t('everybody') . "'; var profile_uid = " . (($a->data['channel']) ? $a->data['channel']['channel_id'] : 0) . "; </script>" ; @@ -163,23 +157,20 @@ function photos_post(&$a) { } if((argc() > 2) && (x($_REQUEST,'delete')) && ($_REQUEST['delete'] === t('Delete Photo'))) { -// FIXME + // same as above but remove single photo - if($visitor) { - $r = q("SELECT `id`, `resource_id` FROM `photo` WHERE `contact-id` = %d AND `uid` = %d AND `resource_id` = '%s' LIMIT 1", - intval($visitor), - intval($page_owner_uid), - dbesc($a->argv[2]) - ); - } - else { - $r = q("SELECT `id`, `resource_id` FROM `photo` WHERE `uid` = %d AND `resource_id` = '%s' LIMIT 1", - intval(local_user()), - dbesc($a->argv[2]) - ); - } - if(count($r)) { + $ob_hash = get_observer_hash(); + if(! $ob_hash) + goaway($a->get_baseurl() . '/' . $_SESSION['photo_return']); + + $r = q("SELECT `id`, `resource_id` FROM `photo` WHERE ( xchan = '%s' or `uid` = %d ) AND `resource_id` = '%s' LIMIT 1", + dbesc($ob_hash), + intval(local_user()), + dbesc($a->argv[2]) + ); + + if($r) { q("DELETE FROM `photo` WHERE `uid` = %d AND `resource_id` = '%s'", intval($page_owner_uid), dbesc($r[0]['resource_id']) @@ -189,7 +180,7 @@ function photos_post(&$a) { intval($page_owner_uid) ); if(count($i)) { - q("UPDATE `item` SET item_restrict = (item_restrict & %d), `edited` = '%s', `changed` = '%s' WHERE `parent_mid` = '%s' AND `uid` = %d", + q("UPDATE `item` SET item_restrict = (item_restrict | %d), `edited` = '%s', `changed` = '%s' WHERE `parent_mid` = '%s' AND `uid` = %d", intval(ITEM_DELETED), dbesc(datetime_convert()), dbesc(datetime_convert()), @@ -206,7 +197,6 @@ function photos_post(&$a) { } goaway($a->get_baseurl() . '/' . $_SESSION['photo_return']); - return; // NOTREACHED } if(($a->argc > 2) && ((x($_POST,'desc') !== false) || (x($_POST,'newtag') !== false)) || (x($_POST,'albname') !== false)) { @@ -291,7 +281,8 @@ function photos_post(&$a) { ); if(count($p)) { $ext = $phototypes[$p[0]['type']]; - $r = q("UPDATE `photo` SET `desc` = '%s', `album` = '%s', `allow_cid` = '%s', `allow_gid` = '%s', `deny_cid` = '%s', `deny_gid` = '%s' WHERE `resource_id` = '%s' AND `uid` = %d", + + $r = q("UPDATE `photo` SET `description` = '%s', `album` = '%s', `allow_cid` = '%s', `allow_gid` = '%s', `deny_cid` = '%s', `deny_gid` = '%s' WHERE `resource_id` = '%s' AND `uid` = %d", dbesc($desc), dbesc($albname), dbesc($str_contact_allow), @@ -309,7 +300,7 @@ function photos_post(&$a) { /* Don't make the item visible if the only change was the album name */ $visibility = 0; - if($p[0]['desc'] !== $desc || strlen($rawtags)) + if($p[0]['description'] !== $desc || strlen($rawtags)) $visibility = 1; if(! $item_id) { @@ -345,201 +336,77 @@ function photos_post(&$a) { $str_tags = ''; $inform = ''; - // if the new tag doesn't have a namespace specifier (@foo or #foo) give it a hashtag + // if the new tag doesn't have a namespace specifier (@foo or #foo) give it a mention $x = substr($rawtags,0,1); if($x !== '@' && $x !== '#') - $rawtags = '#' . $rawtags; + $rawtags = '@' . $rawtags; $taginfo = array(); $tags = get_tags($rawtags); if(count($tags)) { foreach($tags as $tag) { - if(isset($profile)) - unset($profile); - if(strpos($tag,'@') === 0) { - $name = substr($tag,1); - if((strpos($name,'@')) || (strpos($name,'http://'))) { - $newname = $name; - $links = @lrdd($name); - if(count($links)) { - foreach($links as $link) { - if($link['@attributes']['rel'] === 'http://webfinger.net/rel/profile-page') - $profile = $link['@attributes']['href']; - if($link['@attributes']['rel'] === 'salmon') { - $salmon = '$url:' . str_replace(',','%sc',$link['@attributes']['href']); - if(strlen($inform)) - $inform .= ','; - $inform .= $salmon; - } - } - } - $taginfo[] = array($newname,$profile,$salmon); + + // If we already tagged 'Robert Johnson', don't try and tag 'Robert'. + // Robert Johnson should be first in the $tags array + + $fullnametagged = false; + for($x = 0; $x < count($tagged); $x ++) { + if(stristr($tagged[$x],$tag . ' ')) { + $fullnametagged = true; + break; } - else { - $newname = $name; - $alias = ''; - $tagcid = 0; - if(strrpos($newname,'+')) - $tagcid = intval(substr($newname,strrpos($newname,'+') + 1)); - - if($tagcid) { - $r = q("SELECT * FROM `contact` WHERE `id` = %d AND `uid` = %d LIMIT 1", - intval($tagcid), - intval($profile_uid) - ); - } - else { - $newname = str_replace('_',' ',$name); - - //select someone from this user's contacts by name - $r = q("SELECT * FROM `contact` WHERE `name` = '%s' AND `uid` = %d LIMIT 1", - dbesc($newname), - intval($page_owner_uid) - ); - - if(! $r) { - //select someone by attag or nick and the name passed in - $r = q("SELECT * FROM `contact` WHERE `attag` = '%s' OR `nick` = '%s' AND `uid` = %d ORDER BY `attag` DESC LIMIT 1", - dbesc($name), - dbesc($name), - intval($page_owner_uid) - ); - } - } -/* elseif(strstr($name,'_') || strstr($name,' ')) { - $newname = str_replace('_',' ',$name); - $r = q("SELECT * FROM `contact` WHERE `name` = '%s' AND `uid` = %d LIMIT 1", - dbesc($newname), - intval($page_owner_uid) - ); - } - else { - $r = q("SELECT * FROM `contact` WHERE `attag` = '%s' OR `nick` = '%s' AND `uid` = %d ORDER BY `attag` DESC LIMIT 1", - dbesc($name), - dbesc($name), - intval($page_owner_uid) - ); - }*/ - if(count($r)) { - $newname = $r[0]['name']; - $profile = $r[0]['url']; - $notify = 'cid:' . $r[0]['id']; - if(strlen($inform)) - $inform .= ','; - $inform .= $notify; - } + } + if($fullnametagged) + continue; + + require_once('mod/item.php'); + $body = $access_tag = ''; + + $success = handle_tag($a, $body, $access_tag, $str_tags, (local_user()) ? local_user() : $a->profile['profile_uid'] , $tag); + logger('handle_tag: ' . print_r($success,tue), LOGGER_DEBUG); + if($access_tag) { + logger('access_tag: ' . $tag . ' ' . print_r($access_tag,true), LOGGER_DEBUG); + if(strpos($access_tag,'cid:') === 0) { + $str_contact_allow .= '<' . substr($access_tag,4) . '>'; + $access_tag = ''; } - if($profile) { - if(substr($notify,0,4) === 'cid:') - $taginfo[] = array($newname,$profile,$notify,$r[0],'@[zrl=' . str_replace(',','%2c',$profile) . ']' . $newname . '[/zrl]'); - else - $taginfo[] = array($newname,$profile,$notify,null,$str_tags .= '@[url=' . $profile . ']' . $newname . '[/url]'); - if(strlen($str_tags)) - $str_tags .= ','; - $profile = str_replace(',','%2c',$profile); - $str_tags .= '@[zrl=' . $profile . ']' . $newname . '[/zrl]'; + elseif(strpos($access_tag,'gid:') === 0) { + $str_group_allow .= '<' . substr($access_tag,4) . '>'; + $access_tag = ''; } } + + if($success['replaced']) { + $tagged[] = $tag; + $post_tags[] = array( + 'uid' => $a->profile['profile_uid'], + 'type' => $success['termtype'], + 'otype' => TERM_OBJ_POST, + 'term' => $success['term'], + 'url' => $success['url'] + ); + } } } - - $newtag = $old_tag; - if(strlen($newtag) && strlen($str_tags)) - $newtag .= ','; - $newtag .= $str_tags; - - $newinform = $old_inform; - if(strlen($newinform) && strlen($inform)) - $newinform .= ','; - $newinform .= $inform; -//FIXME - inform is gone -// $r = q("UPDATE `item` SET `tag` = '%s', `inform` = '%s', `edited` = '%s', `changed` = '%s' WHERE `id` = %d AND `uid` = %d LIMIT 1", -// dbesc($newtag), -// dbesc($newinform), -// dbesc(datetime_convert()), -// dbesc(datetime_convert()), -// intval($item_id), -// intval($page_owner_uid) -// ); - - $best = 0; - foreach($p as $scales) { - if(intval($scales['scale']) == 2) { - $best = 2; - break; - } - if(intval($scales['scale']) == 4) { - $best = 4; - break; - } - } - - if(count($taginfo)) { - foreach($taginfo as $tagged) { - $mid = item_message_id(); - - $arr = array(); - - $arr['uid'] = $page_owner_uid; - $arr['mid'] = $mid; - $arr['parent_mid'] = $mid; - $arr['type'] = 'activity'; - $arr['wall'] = 1; - $arr['contact-id'] = $owner_record['id']; - $arr['owner-name'] = $owner_record['name']; - $arr['owner-link'] = $owner_record['url']; - $arr['owner-avatar'] = $owner_record['thumb']; - $arr['author-name'] = $owner_record['name']; - $arr['author-link'] = $owner_record['url']; - $arr['author-avatar'] = $owner_record['thumb']; - $arr['title'] = ''; - $arr['allow_cid'] = $p[0]['allow_cid']; - $arr['allow_gid'] = $p[0]['allow_gid']; - $arr['deny_cid'] = $p[0]['deny_cid']; - $arr['deny_gid'] = $p[0]['deny_gid']; - $arr['visible'] = 1; - $arr['verb'] = ACTIVITY_TAG; - $arr['obj_type'] = ACTIVITY_OBJ_PERSON; - $arr['tgt_type'] = ACTIVITY_OBJ_PHOTO; - $arr['tag'] = $tagged[4]; - $arr['inform'] = $tagged[2]; - $arr['origin'] = 1; - $arr['body'] = sprintf( t('%1$s was tagged in %2$s by %3$s'), '[zrl=' . $tagged[1] . ']' . $tagged[0] . '[/zrl]', '[zrl=' . $a->get_baseurl() . '/photos/' . $owner_record['nickname'] . '/image/' . $p[0]['resource-id'] . ']' . t('a photo') . '[/zrl]', '[zrl=' . $owner_record['url'] . ']' . $owner_record['name'] . '[/zrl]') ; - - $arr['body'] .= "\n\n" . '[zrl=' . $a->get_baseurl() . '/photos/' . $owner_record['nickname'] . '/image/' . $p[0]['resource_id'] . ']' . '[zmg]' . $a->get_baseurl() . "/photo/" . $p[0]['resource_id'] . '-' . $best . '.' . $ext . '[/zmg][/zrl]' . "\n" ; - - $arr['object'] = '<object><type>' . ACTIVITY_OBJ_PERSON . '</type><title>' . $tagged[0] . '</title><id>' . $tagged[1] . '/' . $tagged[0] . '</id>'; - $arr['object'] .= '<link>' . xmlify('<link rel="alternate" type="text/html" href="' . $tagged[1] . '" />' . "\n"); - if($tagged[3]) - $arr['object'] .= xmlify('<link rel="photo" type="'.$p[0]['type'].'" href="' . $tagged[3]['photo'] . '" />' . "\n"); - $arr['object'] .= '</link></object>' . "\n"; - - $arr['target'] = '<target><type>' . ACTIVITY_OBJ_PHOTO . '</type><title>' . $p[0]['desc'] . '</title><id>' - . $a->get_baseurl() . '/photos/' . $owner_record['nickname'] . '/image/' . $p[0]['resource_id'] . '</id>'; - $arr['target'] .= '<link>' . xmlify('<link rel="alternate" type="text/html" href="' . $a->get_baseurl() . '/photos/' . $owner_record['nickname'] . '/image/' . $p[0]['resource_id'] . '" />' . "\n" . '<link rel="preview" type="'.$p[0]['type'].'" href="' . $a->get_baseurl() . "/photo/" . $p[0]['resource_id'] . '-' . $best . '.' . $ext . '" />') . '</link></target>'; - - $post = item_store($arr); - $item_id = $post['item_id']; - - if($item_id) { - q("UPDATE `item` SET `plink` = '%s' WHERE `uid` = %d AND `id` = %d LIMIT 1", - dbesc($a->get_baseurl() . '/display/' . $owner_record['nickname'] . '/' . $item_id), - intval($page_owner_uid), - intval($item_id) - ); - - proc_run('php',"include/notifier.php","tag","$item_id"); - } - } + $r = q("select * from item where id = %d and uid = %d limit 1", + intval($item_id), + intval($page_owner_uid) + ); + if($r) { + $datarray = $r[0]; + $datarray['term'] = $post_tags; + item_store_update($datarray,$execflag); } } + goaway($a->get_baseurl() . '/' . $_SESSION['photo_return']); return; // NOTREACHED + } @@ -596,6 +463,8 @@ function photos_content(&$a) { // Parse arguments // + $can_comment = perm_is_allowed($a->profile['profile_uid'],get_observer_hash(),'post_comments'); + if(argc() > 3) { $datatype = argv(2); $datum = argv(3); @@ -636,6 +505,9 @@ function photos_content(&$a) { $o = ""; + $o .= "<script> var profile_uid = " . $a->profile['profile_uid'] + . "; var netargs = '?f='; var profile_page = " . $a->pager['page'] . "; </script>\r\n"; + // tabs $_is_owner = (local_user() && (local_user() == $owner_uid)); @@ -655,12 +527,21 @@ function photos_content(&$a) { return; } + + + if(array_key_exists('albums', $a->data)) + $albums = get_app()->data['albums']; + else + $albums = photos_albums_list($a->data['channel'],$a->data['observer']); + + + $selname = (($datum) ? hex2bin($datum) : ''); $albumselect = '<select id="photos-upload-album-select" name="album" size="4">'; $albumselect .= '<option value="" ' . ((! $selname) ? ' selected="selected" ' : '') . '> </option>'; - if(count($a->data['albums'])) { - foreach($a->data['albums'] as $album) { + if(count($albums)) { + foreach($albums as $album) { if($album['text'] === '') continue; $selected = (($selname === $album['text']) ? ' selected="selected" ' : ''); @@ -686,8 +567,8 @@ function photos_content(&$a) { /* Show space usage */ - $r = q("select sum(size) as total from photo where uid = %d and scale = 0 ", - intval($a->data['channel']['channel_id']) + $r = q("select sum(size) as total from photo where aid = %d and scale = 0 ", + intval($a->data['channel']['channel_account_id']) ); @@ -759,7 +640,7 @@ function photos_content(&$a) { else $order = 'DESC'; - $r = q("SELECT `resource_id`, `id`, `filename`, type, max(`scale`) AS `scale`, `desc` FROM `photo` WHERE `uid` = %d AND `album` = '%s' + $r = q("SELECT `resource_id`, `id`, `filename`, type, max(`scale`) AS `scale`, `description` FROM `photo` WHERE `uid` = %d AND `album` = '%s' AND `scale` <= 4 and (photo_flags = %d or photo_flags = %d ) $sql_extra GROUP BY `resource_id` ORDER BY `created` $order LIMIT %d , %d", intval($owner_uid), dbesc($album), @@ -825,25 +706,24 @@ function photos_content(&$a) { $ext = $phototypes[$rr['type']]; - if($a->get_template_engine() === 'internal') { - $imgalt_e = template_escape($rr['filename']); - $desc_e = template_escape($rr['desc']); - } - else { - $imgalt_e = $rr['filename']; - $desc_e = $rr['desc']; - } + $imgalt_e = $rr['filename']; + $desc_e = $rr['description']; + +// prettyphoto has potential license issues, so we can no longer include it in core +// The following lines would need to be modified so that they are provided in theme specific files +// instead of core modules for themes that wish to make use of prettyphoto. I would suggest +// the feature as a per-theme display option and putting the rel line inside a template. - if(feature_enabled($a->data['channel']['channel_id'],'prettyphoto')){ - $imagelink = ($a->get_baseurl() . '/photo/' . $rr['resource_id'] . '.' . $ext ); - $rel=("prettyPhoto[pp_gal]"); - } - else { +// if(feature_enabled($a->data['channel']['channel_id'],'prettyphoto')){ +// $imagelink = ($a->get_baseurl() . '/photo/' . $rr['resource_id'] . '.' . $ext ); +// $rel=("prettyPhoto[pp_gal]"); +// } +// else { $imagelink = ($a->get_baseurl() . '/photos/' . $a->data['channel']['channel_address'] . '/image/' . $rr['resource_id'] . (($_GET['order'] === 'posted') ? '?f=&order=posted' : '')); $rel=("photo"); - } +// } $o .= replace_macros($tpl,array( '$id' => $rr['id'], @@ -854,6 +734,8 @@ function photos_content(&$a) { '$imgsrc' => $a->get_baseurl() . '/photo/' . $rr['resource_id'] . '-' . $rr['scale'] . '.' .$ext, '$imgalt' => $imgalt_e, '$desc'=> $desc_e, + '$ext' => $ext, + '$hash'=> $rr['resource_id'], )); } @@ -872,7 +754,7 @@ function photos_content(&$a) { // fetch image, item containing image, then comments - $ph = q("SELECT aid,uid,xchan,resource_id,created,edited,title,`desc`,album,filename,`type`,height,width,`size`,scale,profile,photo_flags,allow_cid,allow_gid,deny_cid,deny_gid FROM `photo` WHERE `uid` = %d AND `resource_id` = '%s' + $ph = q("SELECT aid,uid,xchan,resource_id,created,edited,title,`description`,album,filename,`type`,height,width,`size`,scale,profile,photo_flags,allow_cid,allow_gid,deny_cid,deny_gid FROM `photo` WHERE `uid` = %d AND `resource_id` = '%s' and (photo_flags = %d or photo_flags = %d ) $sql_extra ORDER BY `scale` ASC ", intval($owner_uid), dbesc($datum), @@ -885,7 +767,7 @@ function photos_content(&$a) { /* Check again - this time without specifying permissions */ - $ph = q("SELECT `id` FROM `photo` WHERE `uid` = %d AND `resource_id` = '%s' + $ph = q("SELECT id FROM photo WHERE uid = %d AND resource_id = '%s' and ( photo_flags = %d or photo_flags = %d ) LIMIT 1", intval($owner_uid), @@ -900,6 +782,8 @@ function photos_content(&$a) { return; } + + $prevlink = ''; $nextlink = ''; @@ -995,6 +879,9 @@ function photos_content(&$a) { if($linked_items) { + xchan_query($linked_items); + $linked_items = fetch_post_tags($linked_items,true); + $link_item = $linked_items[0]; $r = q("select * from item where parent_mid = '%s' @@ -1010,6 +897,21 @@ function photos_content(&$a) { $r = conv_sort($r,'commented'); } + + + $tags = array(); + if($link_item['term']) { + $cnt = 0; + foreach($link_item['term'] as $t) + $tags[$cnt] = array(0 => format_term_for_display($t)); + if($can_post && ($ph[0]['uid'] == $owner_uid)) { + $tags[$cnt][1] = 'tagrm?f=&item=' . $link_item['id']; + $tags[$cnt][2] = t('Remove'); + } + $cnt ++; + } + + if((local_user()) && (local_user() == $link_item['uid'])) { q("UPDATE `item` SET item_flags = (item_flags ^ %d) WHERE parent = %d and uid = %d and (item_flags & %d)", intval(ITEM_UNSEEN), @@ -1020,6 +922,8 @@ function photos_content(&$a) { } } +// logger('mod_photo: link_item' . print_r($link_item,true)); + // FIXME - remove this when we move to conversation module $r = $r[0]['children']; @@ -1028,7 +932,7 @@ function photos_content(&$a) { if($can_post) { $album_e = $ph[0]['album']; - $caption_e = $ph[0]['desc']; + $caption_e = $ph[0]['description']; $aclselect_e = populate_acl($ph[0]); $edit = array( @@ -1043,7 +947,6 @@ function photos_content(&$a) { 'capt_label' => t('Caption'), 'caption' => $caption_e, 'tag_label' => t('Add a Tag'), - 'tags' => $link_item['tag'], 'permissions' => t('Permissions'), 'aclselect' => $aclselect_e, 'help_tags' => t('Example: @bob, @Barbara_Jensen, @jim@example.com, #California, #camping'), @@ -1063,7 +966,7 @@ function photos_content(&$a) { $likebuttons = ''; - if($can_post || $a->data['perms']['post_comments']) { + if($can_post || $can_comment) { $likebuttons = replace_macros($like_tpl,array( '$id' => $link_item['id'], '$likethis' => t("I like this \x28toggle\x29"), @@ -1075,7 +978,7 @@ function photos_content(&$a) { $comments = ''; if(! count($r)) { - if($can_post || $a->data['perms']['post_comments']) { + if($can_post || $can_comment) { $comments .= replace_macros($cmnt_tpl,array( '$return_path' => '', '$mode' => 'photos', @@ -1163,7 +1066,7 @@ function photos_content(&$a) { } - if($can_post || $a->data['perms']['post_comments']) { + if($can_post || $can_comment) { $comments .= replace_macros($cmnt_tpl,array( '$return_path' => '', '$jsreload' => $return_url, @@ -1185,10 +1088,10 @@ function photos_content(&$a) { } $album_e = array($album_link,$ph[0]['album']); - $tags_e = $tags; $like_e = $like; $dislike_e = $dislike; + $photo_tpl = get_markup_template('photo_view.tpl'); $o .= replace_macros($photo_tpl, array( '$id' => $ph[0]['id'], @@ -1198,8 +1101,9 @@ function photos_content(&$a) { '$photo' => $photo, '$prevlink' => $prevlink, '$nextlink' => $nextlink, - '$desc' => $ph[0]['desc'], - '$tags' => $tags_e, + '$desc' => $ph[0]['description'], + '$tag_hdr' => t('In This Photo:'), + '$tags' => $tags, '$edit' => $edit, '$likebuttons' => $likebuttons, '$like' => $like_e, diff --git a/mod/ping.php b/mod/ping.php index 414f06e53..b9d9a9c77 100644 --- a/mod/ping.php +++ b/mod/ping.php @@ -43,6 +43,38 @@ function ping_init(&$a) { unset($_SESSION['sysmsg_info']); } + if($a->install) { + echo json_encode($result); + killme(); + } + + + if(get_observer_hash() && (! $result['invalid'])) { + $r = q("select cp_id, cp_room from chatpresence where cp_xchan = '%s' and cp_client = '%s' and cp_room = 0 limit 1", + dbesc(get_observer_hash()), + dbesc($_SERVER['REMOTE_ADDR']) + ); + $basic_presence = false; + if($r) { + $basic_presence = true; + q("update chatpresence set cp_last = '%s' where cp_id = %d limit 1", + dbesc(datetime_convert()), + intval($r[0]['cp_id']) + ); + } + if(! $basic_presence) { + q("insert into chatpresence ( cp_xchan, cp_last, cp_status, cp_client) + values( '%s', '%s', '%s', '%s' ) ", + dbesc(get_observer_hash()), + dbesc(datetime_convert()), + dbesc('online'), + dbesc($_SERVER['REMOTE_ADDR']) + ); + } + } + + q("delete from chatpresence where cp_last < UTC_TIMESTAMP() - INTERVAL 3 MINUTE"); + if((! local_user()) || ($result['invalid'])) { echo json_encode($result); killme(); @@ -151,7 +183,7 @@ function ping_init(&$a) { foreach($t as $zz) { // $msg = sprintf( t('sent you a private message.'), $zz['xchan_name']); $notifs[] = array( - 'notify_link' => $a->get_baseurl() . '/message/' . $zz['id'], + 'notify_link' => $a->get_baseurl() . '/mail/' . $zz['id'], 'name' => $zz['xchan_name'], 'url' => $zz['xchan_url'], 'photo' => $zz['xchan_photo_s'], @@ -209,7 +241,7 @@ function ping_init(&$a) { if($r) { foreach($r as $rr) { $result[] = array( - 'notify_link' => $a->get_baseurl() . '/connections/' . $rr['abook_id'], + 'notify_link' => $a->get_baseurl() . '/connedit/' . $rr['abook_id'], 'name' => $rr['xchan_name'], 'url' => $rr['xchan_url'], 'photo' => $rr['xchan_photo_s'], diff --git a/mod/post.php b/mod/post.php index 73345c4e9..6c57bfa0d 100644 --- a/mod/post.php +++ b/mod/post.php @@ -69,6 +69,7 @@ function post_init(&$a) { * "success":1, * "confirm":"q0Ysovd1u..." * "service_class":(optional) + * "level":(optional) * } * * 'confirm' in this case is the base64url encoded RSA signature of the concatenation of 'secret' with the @@ -150,6 +151,7 @@ function post_init(&$a) { $remote = remote_user(); $result = null; $remote_service_class = ''; + $remote_level = 0; $remote_hub = $x[0]['hubloc_url']; // Also check that they are coming from the same site as they authenticated with originally. @@ -210,6 +212,8 @@ function post_init(&$a) { } if(array_key_exists('service_class',$j)) $remote_service_class = $j['service_class']; + if(array_key_exists('level',$j)) + $remote_level = $j['level']; } // everything is good... maybe if(local_user()) { @@ -232,7 +236,7 @@ function post_init(&$a) { if($test) { $ret['success'] = true; - $ret['message'] .= 'Success' . EOL; + $ret['message'] .= 'Authentication Success!' . EOL; json_return_and_die($ret); } @@ -241,6 +245,7 @@ function post_init(&$a) { $_SESSION['visitor_id'] = $x[0]['xchan_hash']; $_SESSION['my_address'] = $address; $_SESSION['remote_service_class'] = $remote_service_class; + $_SESSION['remote_level'] = $remote_level; $_SESSION['remote_hub'] = $remote_hub; $arr = array('xchan' => $x[0], 'url' => $desturl, 'session' => $_SESSION); @@ -250,6 +255,11 @@ function post_init(&$a) { $a->set_groups(init_groups_visitor($_SESSION['visitor_id'])); info(sprintf( t('Welcome %s. Remote authentication successful.'),$x[0]['xchan_name'])); logger('mod_zot: auth success from ' . $x[0]['xchan_addr']); + q("update hubloc set hubloc_status = (hubloc_status | %d ) where hubloc_id = %d ", + intval(HUBLOC_WORKS), + intval($x[0]['hubloc_id']) + ); + } else { if($test) { @@ -294,9 +304,9 @@ function post_init(&$a) { * * Once decrypted, one will find the normal json_encoded zot message packet. * - * Defined packet types are: notify, purge, refresh, auth_check, ping, and pickup + * Defined packet types are: notify, purge, refresh, force_refresh, auth_check, ping, and pickup * - * Standard packet: (used by notify, purge, refresh, and auth_check) + * Standard packet: (used by notify, purge, refresh, force_refresh, and auth_check) * * { * "type": "notify", @@ -440,14 +450,12 @@ function post_init(&$a) { function post_post(&$a) { - logger('mod_zot: ' . print_r($_REQUEST,true), LOGGER_DEBUG); $encrypted_packet = false; $ret = array('success' => false); $data = json_decode($_REQUEST['data'],true); - logger('mod_zot: data: ' . print_r($data,true), LOGGER_DATA); /** * Many message packets will arrive encrypted. The existence of an 'iv' element @@ -476,7 +484,6 @@ function post_post(&$a) { $data = array('type' => 'bogus'); } - logger('mod_zot: decoded data: ' . print_r($data,true), LOGGER_DATA); $msgtype = ((array_key_exists('type',$data)) ? $data['type'] : ''); @@ -485,6 +492,7 @@ function post_post(&$a) { // Useful to get a health check on a remote site. // This will let us know if any important communication details // that we may have stored are no longer valid, regardless of xchan details. + logger('POST: got ping send pong now back: ' . z_root() , LOGGER_DEBUG ); $ret['success'] = true; $ret['site'] = array(); @@ -785,10 +793,13 @@ function post_post(&$a) { } } - if($msgtype === 'refresh') { + if(($msgtype === 'refresh') || ($msgtype === 'force_refresh')) { // remote channel info (such as permissions or photo or something) // has been updated. Grab a fresh copy and sync it. + // The difference between refresh and force_refresh is that + // force_refresh unconditionally creates a directory update record, + // even if no changes were detected upon processing. if($recipients) { @@ -806,7 +817,7 @@ function post_post(&$a) { 'xchan_guid' => $sender['guid'], 'xchan_guid_sig' => $sender['guid_sig'], 'hubloc_url' => $sender['url'] - ),$r[0]); + ),$r[0], (($msgtype === 'force_refresh') ? true : false)); } } else { @@ -817,7 +828,7 @@ function post_post(&$a) { 'xchan_guid' => $sender['guid'], 'xchan_guid_sig' => $sender['guid_sig'], 'hubloc_url' => $sender['url'] - ),null); + ),null,(($msgtype === 'force_refresh') ? true : false)); } $ret['success'] = true; json_return_and_die($ret); diff --git a/mod/profile_photo.php b/mod/profile_photo.php index e86e2a828..876e3a931 100644 --- a/mod/profile_photo.php +++ b/mod/profile_photo.php @@ -14,16 +14,6 @@ function profile_photo_init(&$a) { } -function profile_photo_aside(&$a) { - - if(! local_user()) { - return; - } - - profile_create_sidebar($a); -} - - function profile_photo_post(&$a) { if(! local_user()) { diff --git a/mod/profiles.php b/mod/profiles.php index 173d97138..c71ad9733 100644 --- a/mod/profiles.php +++ b/mod/profiles.php @@ -146,17 +146,6 @@ function profiles_init(&$a) { } } -function profiles_aside(&$a) { - - if(! local_user()) { - return; - } - - if((argc() > 1) && (intval(argv(1)))) { - profile_create_sidebar($a); - } -} - function profiles_post(&$a) { if(! local_user()) { @@ -267,35 +256,23 @@ function profiles_post(&$a) { if(strpos($lookup,'@') === 0) $lookup = substr($lookup,1); $lookup = str_replace('_',' ', $lookup); - if(strpos($lookup,'@') || (strpos($lookup,'http://'))) { - $newname = $lookup; - $links = @lrdd($lookup); - if(count($links)) { - foreach($links as $link) { - if($link['@attributes']['rel'] === 'http://webfinger.net/rel/profile-page') { - $prf = $link['@attributes']['href']; - } - } - } - } - else { - $newname = $lookup; - - $r = q("SELECT * FROM `contact` WHERE `name` = '%s' AND `uid` = %d LIMIT 1", - dbesc($newname), + $newname = $lookup; + + $r = q("SELECT * FROM abook left join xchan on abook_xchan = xchan_hash WHERE xchan_name = '%s' AND abook_channel = %d LIMIT 1", + dbesc($newname), + intval(local_user()) + ); + if(! $r) { + $r = q("SELECT * FROM abook left join xchan on abook_xchan = xchan_hash WHERE xchan_addr = '%s' AND abook_channel = %d LIMIT 1", + dbesc($lookup . '@%'), intval(local_user()) ); - if(! $r) { - $r = q("SELECT * FROM `contact` WHERE `nick` = '%s' AND `uid` = %d LIMIT 1", - dbesc($lookup), - intval(local_user()) - ); - } - if(count($r)) { - $prf = $r[0]['url']; - $newname = $r[0]['name']; - } } + if($r) { + $prf = $r[0]['xchan_url']; + $newname = $r[0]['xchan_name']; + } + if($prf) { $with = str_replace($lookup,'<a href="' . $prf . '">' . $newname . '</a>', $with); @@ -621,6 +598,8 @@ function profiles_content(&$a) { $tpl_header = get_markup_template('profile_listing_header.tpl'); $o .= replace_macros($tpl_header,array( '$header' => t('Edit/Manage Profiles'), + '$addstuff' => t('Add profile things'), + '$stuff_desc' => t('Include desirable objects in your profile'), '$chg_photo' => t('Change profile photo'), '$cr_new' => t('Create New Profile'), '$cr_new_link' => 'profiles/new?t=' . get_form_security_token("profile_new") diff --git a/mod/profperm.php b/mod/profperm.php index 8054851e8..08838831b 100644 --- a/mod/profperm.php +++ b/mod/profperm.php @@ -1,11 +1,15 @@ <?php +require_once('include/Contact.php'); + function profperm_init(&$a) { if(! local_user()) return; - $which = $a->user['nickname']; + $channel = $a->get_channel(); + $which = $channel['channel_address']; + $profile = $a->argv[1]; profile_load($a,$which,$profile); @@ -13,15 +17,6 @@ function profperm_init(&$a) { } -function profperm_aside(&$a) { - - if(! local_user()) - return; - - profile_create_sidebar($a); -} - - function profperm_content(&$a) { if(! local_user()) { @@ -30,7 +25,7 @@ function profperm_content(&$a) { } - if($a->argc < 2) { + if(argc() < 2) { notice( t('Invalid profile identifier.') . EOL ); return; } @@ -44,59 +39,59 @@ function profperm_content(&$a) { $switchtotext = 400; - if(($a->argc > 2) && intval($a->argv[1]) && intval($a->argv[2])) { - $r = q("SELECT `id` FROM `contact` WHERE `blocked` = 0 AND `pending` = 0 AND `self` = 0 - AND `network` = 'dfrn' AND `id` = %d AND `uid` = %d LIMIT 1", - intval($a->argv[2]), + if((argc() > 2) && intval(argv(1)) && intval(argv(2))) { + $r = q("SELECT abook_id FROM abook WHERE abook_id = %d and abook_channel = %d limit 1", + intval(argv(2)), intval(local_user()) ); - if(count($r)) - $change = intval($a->argv[2]); + if($r) + $change = intval(argv(2)); } - if(($a->argc > 1) && (intval($a->argv[1]))) { + if((argc() > 1) && (intval(argv(1)))) { $r = q("SELECT * FROM `profile` WHERE `id` = %d AND `uid` = %d AND `is_default` = 0 LIMIT 1", - intval($a->argv[1]), + intval(argv(1)), intval(local_user()) ); - if(! count($r)) { + if(! $r) { notice( t('Invalid profile identifier.') . EOL ); return; } + $profile = $r[0]; - $r = q("SELECT * FROM `contact` WHERE `uid` = %d AND `profile_id` = %d", + $r = q("SELECT * FROM abook left join xchan on abook_xchan = xchan_hash WHERE abook_channel = %d AND abook_profile = %d", intval(local_user()), - intval($a->argv[1]) + intval(argv(1)) ); $ingroup = array(); - if(count($r)) + if($r) foreach($r as $member) - $ingroup[] = $member['id']; + $ingroup[] = $member['abook_id']; $members = $r; if($change) { if(in_array($change,$ingroup)) { - q("UPDATE `contact` SET `profile_id` = 0 WHERE `id` = %d AND `uid` = %d LIMIT 1", + q("UPDATE abook SET abook_profile = 0 WHERE abook_id = %d AND abook_channel = %d LIMIT 1", intval($change), intval(local_user()) ); } else { - q("UPDATE `contact` SET `profile_id` = %d WHERE `id` = %d AND `uid` = %d LIMIT 1", - intval($a->argv[1]), + q("UPDATE abook SET abook_profile = %d WHERE abook_id = %d AND abook_channel = %d LIMIT 1", + intval(argv(1)), intval($change), intval(local_user()) ); } - $r = q("SELECT * FROM `contact` WHERE `uid` = %d AND `profile_id` = %d", + $r = q("SELECT * FROM abook left join xchan on abook_xchan = xchan_hash WHERE abook_channel = %d AND abook_profile = %d", intval(local_user()), - intval($a->argv[1]) + intval(argv(1)) ); $members = $r; @@ -104,7 +99,7 @@ function profperm_content(&$a) { $ingroup = array(); if(count($r)) foreach($r as $member) - $ingroup[] = $member['id']; + $ingroup[] = $member['abook_id']; } $o .= '<h2>' . t('Profile Visibility Editor') . '</h2>'; @@ -127,8 +122,8 @@ function profperm_content(&$a) { $textmode = (($switchtotext && (count($members) > $switchtotext)) ? true : false); foreach($members as $member) { - if($member['url']) { - $member['click'] = 'profChangeMember(' . $profile['id'] . ',' . $member['id'] . '); return true;'; + if($member['xchan_url']) { + $member['click'] = 'profChangeMember(' . $profile['id'] . ',' . $member['abook_id'] . '); return false;'; $o .= micropro($member,true,'mpprof', $textmode); } } @@ -136,20 +131,17 @@ function profperm_content(&$a) { $o .= '<hr id="prof-separator" />'; $o .= '<div id="prof-all-contcts-title">'; - $o .= '<h3>' . t("All Contacts \x28with secure profile access\x29") . '</h3>'; + $o .= '<h3>' . t("All Connections") . '</h3>'; $o .= '</div>'; $o .= '<div id="prof-all-contacts">'; - $r = q("SELECT * FROM `contact` WHERE `uid` = %d AND `blocked` = 0 and `pending` = 0 and `self` = 0 - AND `network` = 'dfrn' ORDER BY `name` ASC", - intval(local_user()) - ); + $r = abook_connections(local_user()); - if(count($r)) { + if($r) { $textmode = (($switchtotext && (count($r) > $switchtotext)) ? true : false); foreach($r as $member) { - if(! in_array($member['id'],$ingroup)) { - $member['click'] = 'profChangeMember(' . $profile['id'] . ',' . $member['id'] . '); return true;'; + if(! in_array($member['abook_id'],$ingroup)) { + $member['click'] = 'profChangeMember(' . $profile['id'] . ',' . $member['abook_id'] . '); return false;'; $o .= micropro($member,true,'mpprof',$textmode); } } diff --git a/mod/pubsites.php b/mod/pubsites.php index c15ba31ac..c08ca2ae5 100644 --- a/mod/pubsites.php +++ b/mod/pubsites.php @@ -29,8 +29,10 @@ function pubsites_content(&$a) { $j = json_decode($ret['body'],true); if($j) { $o .= '<table border="1"><tr><td>' . t('Site URL') . '</td><td>' . t('Access Type') . '</td><td>' . t('Registration Policy') . '</td><td>' . t('Location') . '</td></tr>'; - foreach($j['sites'] as $jj) { - $o .= '<tr><td>' . '<a href="'. (($jj['sellpage']) ? $jj['sellpage'] : $jj['url'] . '/register' ) . '" >' . $jj['url'] . '</a>' . '</td><td>' . $jj['access'] . '</td><td>' . $jj['register'] . '</td><td>' . $jj['location'] . '</td></tr>'; + if($j['sites']) { + foreach($j['sites'] as $jj) { + $o .= '<tr><td>' . '<a href="'. (($jj['sellpage']) ? $jj['sellpage'] : $jj['url'] . '/register' ) . '" >' . $jj['url'] . '</a>' . '</td><td>' . $jj['access'] . '</td><td>' . $jj['register'] . '</td><td>' . $jj['location'] . '</td></tr>'; + } } $o .= '</table>'; diff --git a/mod/qsearch.php b/mod/qsearch.php deleted file mode 100644 index c35e253b6..000000000 --- a/mod/qsearch.php +++ /dev/null @@ -1,50 +0,0 @@ -<?php - -function qsearch_init(&$a) { - - if(! local_user()) - killme(); - - $limit = (get_config('system','qsearch_limit') ? intval(get_config('system','qsearch_limit')) : 100); - - $search = ((x($_GET,'s')) ? notags(trim(urldecode($_GET['s']))) : ''); - - if(! strlen($search)) - killme(); - - - if($search) - $search = dbesc($search); - - $results = array(); - - $r = q("SELECT * FROM `group` WHERE `name` REGEXP '$search' AND `deleted` = 0 AND `uid` = %d LIMIT 0, %d ", - intval(local_user()), - intval($limit) - ); - - if(count($r)) { - - foreach($r as $rr) - $results[] = array( 0, (int) $rr['id'], $rr['name'], '', ''); - } - - $sql_extra = ((strlen($search)) ? " AND (`name` REGEXP '$search' OR `nick` REGEXP '$search') " : ""); - - - $r = q("SELECT * FROM `contact` WHERE `uid` = %d $sql_extra ORDER BY `name` ASC LIMIT 0, %d ", - intval(local_user()), - intval($limit) - ); - - - if(count($r)) { - - foreach($r as $rr) - $results[] = array( (int) $rr['id'], 0, $rr['name'],$rr['url'],$rr['photo']); - } - - echo json_encode((object) $results); - killme(); -} - diff --git a/mod/rbmark.php b/mod/rbmark.php new file mode 100644 index 000000000..1c962152c --- /dev/null +++ b/mod/rbmark.php @@ -0,0 +1,112 @@ +<?php /** @file */ + +require_once('acl_selectors.php'); +require_once('include/crypto.php'); +require_once('include/items.php'); +require_once('include/taxonomy.php'); +require_once('include/conversation.php'); +require_once('include/zot.php'); +require_once('include/bookmarks.php'); + +/** + * remote bookmark + * + * https://yoursite/rbmark?f=&title=&url=&private=&remote_return= + * + * This can be called via either GET or POST, use POST for long body content as suhosin often limits GET parameter length + * + * f= placeholder, often required + * title= link text + * url= URL to bookmark + * ischat=1 if this bookmark is a chatroom + * private= Don't share this link + * remote_return= absolute URL to return after posting is finished + * + */ + +function rbmark_post(&$a) { + if($_POST['submit'] !== t('Save')) + return; + + logger('rbmark_post: ' . print_r($_REQUEST,true)); + + $channel = $a->get_channel(); + + $t = array('url' => escape_tags($_REQUEST['url']),'term' => escape_tags($_REQUEST['title'])); + bookmark_add($channel,$channel,$t,((x($_REQUEST,'private')) ? intval($_REQUEST['private']) : 0), + array('menu_id' => ((x($_REQUEST,'menu_id')) ? intval($_REQUEST['menu_id']) : 0), + 'menu_name' => ((x($_REQUEST,'menu_name')) ? escape_tags($_REQUEST['menu_name']) : '') + )); + + goaway(z_root() . '/bookmarks'); + +} + + +function rbmark_content(&$a) { + + $o = ''; + + if(! local_user()) { + + // The login procedure is going to bugger our $_REQUEST variables + // so save them in the session. + + if(array_key_exists('url',$_REQUEST)) { + $_SESSION['bookmark'] = $_REQUEST; + } + return login(); + } + + // If we have saved rbmark session variables, but nothing in the current $_REQUEST, recover the saved variables + + if((! array_key_exists('url',$_REQUEST)) && (array_key_exists('bookmark',$_SESSION))) { + $_REQUEST = $_SESSION['bookmark']; + unset($_SESSION['bookmark']); + } + + if($_REQUEST['remote_return']) { + $_SESSION['remote_return'] = $_REQUEST['remote_return']; + } + if(argc() > 1 && argv(1) === 'return') { + if($_SESSION['remote_return']) + goaway($_SESSION['remote_return']); + goaway(z_root() . '/bookmarks'); + } + + $channel = $a->get_channel(); + + $m = menu_list($channel,'',MENU_BOOKMARK); + $menus = array(); + if($m) { + $menus = array(0 => ''); + foreach($m as $n) { + $menus[$n['menu_id']] = $n['menu_name']; + } + } + $menu_select = array('menu_id',t('Select a bookmark folder'),false,'',$menus); + + + $o .= replace_macros(get_markup_template('rbmark.tpl'), array( + + '$header' => t('Save Bookmark'), + '$url' => array('url',t('URL of bookmark'),escape_tags($_REQUEST['url'])), + '$title' => array('title',t('Description'),escape_tags($_REQUEST['title'])), + '$ischat' => (($ischat) ? 1 : 0), + '$private' => (($private) ? 1 : 0), + '$submit' => t('Save'), + '$menu_name' => array('menu_name',t('Or enter new bookmark folder name'),'',''), + '$menus' => $menu_select + + )); + + + + + + + return $o; + +} + + diff --git a/mod/redir.php b/mod/redir.php deleted file mode 100644 index 113f6c200..000000000 --- a/mod/redir.php +++ /dev/null @@ -1,60 +0,0 @@ -<?php - -function redir_init(&$a) { - - $url = ((x($_GET,'url')) ? $_GET['url'] : ''); - - // traditional DFRN - - if(local_user() && $a->argc > 1 && intval($a->argv[1])) { - - $cid = $a->argv[1]; - - $r = q("SELECT * FROM `contact` WHERE `id` = %d AND `uid` = %d LIMIT 1", - intval($cid), - intval(local_user()) - ); - - if((! count($r)) || ($r[0]['network'] !== NETWORK_DFRN)) - goaway(z_root()); - - $dfrn_id = $orig_id = (($r[0]['issued_id']) ? $r[0]['issued_id'] : $r[0]['dfrn_id']); - - if($r[0]['duplex'] && $r[0]['issued_id']) { - $orig_id = $r[0]['issued_id']; - $dfrn_id = '1:' . $orig_id; - } - if($r[0]['duplex'] && $r[0]['dfrn_id']) { - $orig_id = $r[0]['dfrn_id']; - $dfrn_id = '0:' . $orig_id; - } - - $sec = random_string(); - - q("INSERT INTO `profile_check` ( `uid`, `cid`, `dfrn_id`, `sec`, `expire`) - VALUES( %d, %s, '%s', '%s', %d )", - intval(local_user()), - intval($cid), - dbesc($dfrn_id), - dbesc($sec), - intval(time() + 45) - ); - - logger('mod_redir: ' . $r[0]['name'] . ' ' . $sec, LOGGER_DEBUG); - $dest = (($url) ? '&destination_url=' . $url : ''); - goaway ($r[0]['poll'] . '?dfrn_id=' . $dfrn_id - . '&dfrn_version=' . DFRN_PROTOCOL_VERSION . '&type=profile&sec=' . $sec . $dest ); - } - - if(local_user()) - $handle = $a->user['nickname'] . '@' . substr($a->get_baseurl(),strpos($a->get_baseurl(),'://')+3); - if(remote_user()) - $handle = $_SESSION['handle']; - - if($url) { - $url = str_replace('{zid}','&zid=' . $handle,$url); - goaway($url); - } - - goaway(z_root()); -} diff --git a/mod/register.php b/mod/register.php index 2040732ff..990cce2ed 100644 --- a/mod/register.php +++ b/mod/register.php @@ -135,10 +135,17 @@ function register_post(&$a) { function register_content(&$a) { + $registration_is = ''; + $other_sites = ''; if(get_config('system','register_policy') == REGISTER_CLOSED) { - notice("Permission denied." . EOL); - return; + require_once('mod/pubsites.php'); + return pubsites_content($a); + } + + if(get_config('system','register_policy') == REGISTER_APPROVE) { + $registration_is = t('Registration on this site/hub is by approval only.'); + $other_sites = t('<a href="pubsites">Register at another affiliated site/hub</a>'); } $max_dailies = intval(get_config('system','max_daily_registrations')); @@ -175,10 +182,14 @@ function register_content(&$a) { $invite_code = ((x($_REQUEST,'invite_code')) ? strip_tags(trim($_REQUEST['invite_code'])) : "" ); + + $o = replace_macros(get_markup_template('register.tpl'), array( '$title' => t('Registration'), + '$reg_is' => $registration_is, '$registertext' => get_config('system','register_text'), + '$other_sites' => $other_sites, '$invitations' => get_config('system','invitation_only'), '$invite_desc' => t('Membership on this site is by invitation only.'), '$label_invite' => t('Please enter your invitation code'), diff --git a/mod/removeme.php b/mod/removeme.php index 7af4719bd..f0b4ae3c0 100644 --- a/mod/removeme.php +++ b/mod/removeme.php @@ -50,7 +50,7 @@ function removeme_content(&$a) { '$desc' => t('This will completely remove this channel from the network. Once this has been done it is not recoverable.'), '$passwd' => t('Please enter your password for verification:'), '$global' => array('global', t('Remove this channel and all its clones from the network'), false, t('By default only the instance of the channel located on this hub will be removed from the network')), - '$submit' => t('Remove My Account') + '$submit' => t('Remove Channel') )); return $o; diff --git a/mod/rmagic.php b/mod/rmagic.php index b8c1c6553..946277327 100644 --- a/mod/rmagic.php +++ b/mod/rmagic.php @@ -22,31 +22,53 @@ function rmagic_init(&$a) { function rmagic_post(&$a) { - $address = $_REQUEST['address']; + $address = trim($_REQUEST['address']); + if(strpos($address,'@') === false) { - notice('Invalid address.'); - return; - } + $arr = array('address' => $address); + call_hooks('reverse_magic_auth', $arr); - $r = null; - if($address) { - $r = q("select hubloc_url from hubloc where hubloc_addr = '%s' limit 1", - dbesc($address) - ); - } - if($r) { - $url = $r[0]['hubloc_url']; + try { + require_once('library/openid/openid.php'); + $openid = new LightOpenID(z_root()); + $openid->identity = $address; + $openid->returnUrl = z_root() . '/openid'; + goaway($openid->authUrl()); + } catch (Exception $e) { + notice( t('We encountered a problem while logging in with the OpenID you provided. Please check the correct spelling of the ID.').'<br /><br >'. t('The error message was:').' '.$e->getMessage()); + } + + // if they're still here... + notice( t('Authentication failed.') . EOL); + return; } else { - $url = 'https://' . substr($address,strpos($address,'@')+1); - } - if($url) { - $dest = z_root() . '/' . str_replace('zid=','zid_=',$a->query_string); - goaway($url . '/magic' . '?f=&dest=' . $dest); - } + // Presumed Red identity. Perform reverse magic auth + + if(strpos($address,'@') === false) { + notice('Invalid address.'); + return; + } + $r = null; + if($address) { + $r = q("select hubloc_url from hubloc where hubloc_addr = '%s' limit 1", + dbesc($address) + ); + } + if($r) { + $url = $r[0]['hubloc_url']; + } + else { + $url = 'https://' . substr($address,strpos($address,'@')+1); + } + if($url) { + $dest = z_root() . '/' . str_replace('zid=','zid_=',$a->query_string); + goaway($url . '/magic' . '?f=&dest=' . $dest); + } + } } diff --git a/mod/rpost.php b/mod/rpost.php index 8e01ef5d4..18d4c86cd 100644 --- a/mod/rpost.php +++ b/mod/rpost.php @@ -33,7 +33,7 @@ function rpost_content(&$a) { if(remote_user()) { // redirect to your own site. // We can only do this with a GET request so you'll need to keep the text short or risk getting truncated - // by the wretched beast called 'shusoin'. All the browsers now allow long GET requests, but suhosin + // by the wretched beast called 'suhosin'. All the browsers now allow long GET requests, but suhosin // blocks them. $url = get_rpost_path($a->get_observer()); @@ -65,8 +65,10 @@ function rpost_content(&$a) { if($_REQUEST['remote_return']) { $_SESSION['remote_return'] = $_REQUEST['remote_return']; } - if(argc() > 1 && argv(1) === 'return' && $_SESSION['remote_return']) { - goaway($_SESSION['remote_return']); + if(argc() > 1 && argv(1) === 'return') { + if($_SESSION['remote_return']) + goaway($_SESSION['remote_return']); + goaway(z_root() . '/network'); } $plaintext = true; diff --git a/mod/search.php b/mod/search.php index 7651b3a4e..22e521164 100644 --- a/mod/search.php +++ b/mod/search.php @@ -1,86 +1,19 @@ <?php -function search_saved_searches() { - - if(! feature_enabled(local_user(),'savedsearch')) - return ''; - - $o = ''; - - $r = q("select `tid`,`term` from `term` WHERE `uid` = %d and type = %d", - intval(local_user()), - intval(TERM_SAVEDSEARCH) - ); - - if(count($r)) { - $o .= '<div id="saved-search-list" class="widget">'; - $o .= '<h3>' . t('Saved Searches') . '</h3>' . "\r\n"; - $o .= '<ul id="saved-search-ul">' . "\r\n"; - foreach($r as $rr) { - $o .= '<li class="saved-search-li clear"><a href="search/?f=&remove=1&search=' . rawurlencode($rr['term']) . '" title="' . t('Remove term') . '" onclick="return confirmDelete();"><i class="icon-remove drop-icons"></i></a> <a href="search/?f=&search=' . $rr['term'] . '" class="savedsearchterm" >' . htmlspecialchars($rr['term']) . '</a></li>' . "\r\n"; - } - $o .= '</ul><div class="clear"></div></div>' . "\r\n"; - } - - return $o; - -} - - function search_init(&$a) { - - $search = ((x($_GET,'search')) ? trim(rawurldecode($_GET['search'])) : ''); - - if(local_user()) { - if(x($_GET,'save') && $search) { - $r = q("select `tid` from `term` where `uid` = %d and `type` = %d and `term` = '%s' limit 1", - intval(local_user()), - intval(TERM_SAVEDSEARCH), - dbesc($search) - ); - if(! count($r)) { - q("insert into `term` ( `uid`,`type`,`term` ) values ( %d, %d, '%s') ", - intval(local_user()), - intval(TERM_SAVEDSEARCH), - dbesc($search) - ); - } - } - if(x($_GET,'remove') && $search) { - q("delete from `term` where `uid` = %d and `type` = %d and `term` = '%s' limit 1", - intval(local_user()), - intval(TERM_SAVEDSEARCH), - dbesc($search) - ); - } - - $a->page['aside'] .= search_saved_searches(); - - } - else { - unset($_SESSION['theme']); - unset($_SESSION['mobile_theme']); - } - - - -} - - - -function search_post(&$a) { - if(x($_POST,'search')) - $a->data['search'] = $_POST['search']; + if(x($_REQUEST,'search')) + $a->data['search'] = $_REQUEST['search']; } function search_content(&$a,$update = 0, $load = false) { - if((get_config('system','block_public')) && (! local_user()) && (! remote_user())) { - notice( t('Public access denied.') . EOL); + if((get_config('system','block_public')) || (get_config('system','block_public_search'))) { + if ((! local_user()) && (! remote_user())) { + notice( t('Public access denied.') . EOL); return; + } } - nav_set_selected('search'); require_once("include/bbcode.php"); @@ -133,10 +66,7 @@ function search_content(&$a,$update = 0, $load = false) { ); } else { - if (get_config('system','use_fulltext_engine')) - $sql_extra = sprintf(" AND MATCH (`item`.`body`) AGAINST ('".'"%s"'."' in boolean mode) ", dbesc(protect_sprintf($search))); - else - $sql_extra = sprintf(" AND `item`.`body` REGEXP '%s' ", dbesc(protect_sprintf(preg_quote($search)))); + $sql_extra = sprintf(" AND `item`.`body` REGEXP '%s' ", dbesc(protect_sprintf(preg_quote($search)))); } // Here is the way permissions work in the search module... @@ -144,9 +74,6 @@ function search_content(&$a,$update = 0, $load = false) { // 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, @@ -170,6 +97,7 @@ function search_content(&$a,$update = 0, $load = false) { '$spam' => '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' => '', @@ -223,63 +151,19 @@ function search_content(&$a,$update = 0, $load = false) { } if($r) { - -// $parents_str = ids_to_querystr($r,'item_id'); - -// $items = q("SELECT `item`.*, `item`.`id` AS `item_id` -// FROM `item` -// WHERE item_restrict = 0 -// $sql_extra and parent in ( $parents_str ) " -// ); - xchan_query($r); $items = fetch_post_tags($r,true); -// $items = conv_sort($items,'created'); - } else { $items = array(); } -//logger('mod_search: items ' . count($items)); - -// $r = q("SELECT distinct(`item`.`mid`), `item`.*, `item`.`id` AS `item_id`, -// `contact`.`name`, `contact`.`photo`, `contact`.`url`, `contact`.`alias`, `contact`.`rel`, -// `contact`.`network`, `contact`.`thumb`, `contact`.`self`, `contact`.`writable`, -// `contact`.`id` AS `cid`, `contact`.`uid` AS `contact-uid`, -// `user`.`nickname` -// FROM `item` LEFT JOIN `contact` ON `contact`.`id` = `item`.`contact-id` -// LEFT JOIN `user` ON `user`.`uid` = `item`.`uid` -// WHERE `item`.`visible` = 1 AND `item`.`deleted` = 0 and `item`.`moderated` = 0 -// AND (( `item`.`allow_cid` = '' AND `item`.`allow_gid` = '' AND `item`.`deny_cid` = '' AND `item`.`deny_gid` = '' AND `item`.`private` = 0 AND `user`.`hidewall` = 0 ) -// OR `item`.`uid` = %d ) -// AND `contact`.`blocked` = 0 AND `contact`.`pending` = 0 -// $sql_extra -// group by `item`.`mid` -// ORDER BY `received` DESC LIMIT %d , %d ", -// intval(local_user()), -// intval($a->pager['start']), -// intval($a->pager['itemspage']) - -// ); - - -// $a = fetch_post_tags($a,true); - -// if(! $items) {// -// info( t('No results.') . EOL); -// return $o; -// } - - if($tag) - $o .= '<h2>Items tagged with: ' . htmlspecialchars($search) . '</h2>'; + $o .= '<h2>Items tagged with: ' . htmlspecialchars($search, ENT_COMPAT,'UTF-8') . '</h2>'; else - $o .= '<h2>Search results for: ' . htmlspecialchars($search) . '</h2>'; + $o .= '<h2>Search results for: ' . htmlspecialchars($search, ENT_COMPAT,'UTF-8') . '</h2>'; $o .= conversation($a,$items,'search',$update,'client'); -// $o .= alt_pager($a,count($r)); - return $o; } diff --git a/mod/settings.php b/mod/settings.php index 4d95f75b3..b88380ff0 100644 --- a/mod/settings.php +++ b/mod/settings.php @@ -16,14 +16,10 @@ function get_theme_config_file($theme){ } function settings_init(&$a) { - $a->profile_uid = local_user(); -} - - -function settings_aside(&$a) { + if(! local_user()) + return; -if (! local_user()) - return; + $a->profile_uid = local_user(); // default is channel settings in the absence of other arguments @@ -33,105 +29,7 @@ if (! local_user()) $a->argv[] = 'channel'; } - $channel = $a->get_channel(); - - $abook_self_id = 0; - - // Retrieve the 'self' address book entry for use in the auto-permissions link - if(local_user()) { - $abk = q("select abook_id from abook where abook_channel = %d and ( abook_flags & %d ) limit 1", - intval(local_user()), - intval(ABOOK_FLAG_SELF) - ); - if($abk) - $abook_self_id = $abk[0]['abook_id']; - } - - - $tabs = array( - array( - 'label' => t('Account settings'), - 'url' => $a->get_baseurl(true).'/settings/account', - 'selected' => ((argv(1) === 'account') ? 'active' : ''), - ), - - array( - 'label' => t('Channel settings'), - 'url' => $a->get_baseurl(true).'/settings/channel', - 'selected' => ((argv(1) === 'channel') ? 'active' : ''), - ), - - array( - 'label' => t('Additional features'), - 'url' => $a->get_baseurl(true).'/settings/features', - 'selected' => ((argv(1) === 'features') ? 'active' : ''), - ), - - array( - 'label' => t('Feature settings'), - 'url' => $a->get_baseurl(true).'/settings/featured', - 'selected' => ((argv(1) === 'featured') ? 'active' : ''), - ), - - array( - 'label' => t('Display settings'), - 'url' => $a->get_baseurl(true).'/settings/display', - 'selected' => ((argv(1) === 'display') ? 'active' : ''), - ), - - array( - 'label' => t('Connected apps'), - 'url' => $a->get_baseurl(true) . '/settings/oauth', - 'selected' => ((argv(1) === 'oauth') ? 'active' : ''), - ), - - array( - 'label' => t('Export channel'), - 'url' => $a->get_baseurl(true) . '/uexport/basic', - 'selected' => '' - ), - -// array( -// 'label' => t('Export account'), -// 'url' => $a->get_baseurl(true) . '/uexport/complete', -// 'selected' => '' -// ), - - array( - 'label' => t('Automatic Permissions (Advanced)'), - 'url' => $a->get_baseurl(true) . '/connections/' . $abook_self_id, - 'selected' => '' - ), - - - ); - - if(feature_enabled(local_user(),'premium_channel')) { - $tabs[] = array( - 'label' => t('Premium Channel Settings'), - 'url' => $a->get_baseurl(true) . '/connect/' . $channel['channel_address'], - 'selected' => '' - ); - - } - - if(feature_enabled(local_user(),'channel_sources')) { - $tabs[] = array( - 'label' => t('Channel Sources'), - 'url' => $a->get_baseurl(true) . '/sources', - 'selected' => '' - ); - } - - - - $tabtpl = get_markup_template("generic_links_widget.tpl"); - $a->page['aside'] = replace_macros($tabtpl, array( - '$title' => t('Settings'), - '$class' => 'settings-widget', - '$items' => $tabs, - )); } @@ -141,7 +39,7 @@ function settings_post(&$a) { if(! local_user()) return; -// logger('mod_settings: ' . print_r($_REQUEST,true)); + // logger('mod_settings: ' . print_r($_REQUEST,true)); if(x($_SESSION,'submanage') && intval($_SESSION['submanage'])) return; @@ -252,9 +150,12 @@ function settings_post(&$a) { set_pconfig(local_user(),'system','mobile_theme',$mobile_theme); } + $chanview_full = ((x($_POST,'chanview_full')) ? intval($_POST['chanview_full']) : 0); + set_pconfig(local_user(),'system','update_interval', $browser_update); set_pconfig(local_user(),'system','itemspage', $itemspage); set_pconfig(local_user(),'system','no_smilies',$nosmile); + set_pconfig(local_user(),'system','chanview_full',$chanview_full); if ($theme == $a->channel['channel_theme']){ @@ -360,7 +261,7 @@ function settings_post(&$a) { $maxreq = ((x($_POST,'maxreq')) ? intval($_POST['maxreq']) : 0); $expire = ((x($_POST,'expire')) ? intval($_POST['expire']) : 0); $def_group = ((x($_POST,'group-selection')) ? notags(trim($_POST['group-selection'])) : ''); - + $channel_menu = ((x($_POST['channel_menu'])) ? htmlspecialchars_decode(trim($_POST['channel_menu']),ENT_QUOTES) : ''); $expire_items = ((x($_POST,'expire_items')) ? intval($_POST['expire_items']) : 0); $expire_starred = ((x($_POST,'expire_starred')) ? intval($_POST['expire_starred']) : 0); @@ -368,6 +269,7 @@ function settings_post(&$a) { $expire_network_only = ((x($_POST,'expire_network_only'))? intval($_POST['expire_network_only']) : 0); $allow_location = (((x($_POST,'allow_location')) && (intval($_POST['allow_location']) == 1)) ? 1: 0); + $hide_presence = (((x($_POST,'hide_presence')) && (intval($_POST['hide_presence']) == 1)) ? 1: 0); $publish = (((x($_POST,'profile_in_directory')) && (intval($_POST['profile_in_directory']) == 1)) ? 1: 0); $page_flags = (((x($_POST,'page-flags')) && (intval($_POST['page-flags']))) ? intval($_POST['page-flags']) : 0); @@ -407,6 +309,7 @@ function settings_post(&$a) { $arr['channel_r_pages'] = (($_POST['view_pages']) ? $_POST['view_pages'] : 0); $arr['channel_w_pages'] = (($_POST['write_pages']) ? $_POST['write_pages'] : 0); $arr['channel_a_republish'] = (($_POST['republish']) ? $_POST['republish'] : 0); + $arr['channel_a_bookmark'] = (($_POST['bookmark']) ? $_POST['bookmark'] : 0); $defperms = 0; if(x($_POST['def_view_stream'])) @@ -443,6 +346,8 @@ function settings_post(&$a) { $defperms += $_POST['def_write_pages']; if(x($_POST['def_republish'])) $defperms += $_POST['def_republish']; + if(x($_POST['def_bookmark'])) + $defperms += $_POST['def_bookmark']; $notify = 0; @@ -497,9 +402,10 @@ function settings_post(&$a) { set_pconfig(local_user(),'system','post_joingroup', $post_joingroup); set_pconfig(local_user(),'system','post_profilechange', $post_profilechange); set_pconfig(local_user(),'system','blocktags',$blocktags); + set_pconfig(local_user(),'system','hide_online_status',$hide_presence); + set_pconfig(local_user(),'system','channel_menu',$channel_menu); - - $r = q("update channel set channel_name = '%s', channel_pageflags = %d, channel_timezone = '%s', channel_location = '%s', channel_notifyflags = %d, channel_max_anon_mail = %d, channel_max_friend_req = %d, channel_expire_days = %d, channel_default_group = '%s', channel_r_stream = %d, channel_r_profile = %d, channel_r_photos = %d, channel_r_abook = %d, channel_w_stream = %d, channel_w_wall = %d, channel_w_tagwall = %d, channel_w_comment = %d, channel_w_mail = %d, channel_w_photos = %d, channel_w_chat = %d, channel_a_delegate = %d, channel_r_storage = %d, channel_w_storage = %d, channel_r_pages = %d, channel_w_pages = %d, channel_a_republish = %d, channel_allow_cid = '%s', channel_allow_gid = '%s', channel_deny_cid = '%s', channel_deny_gid = '%s' where channel_id = %d limit 1", + $r = q("update channel set channel_name = '%s', channel_pageflags = %d, channel_timezone = '%s', channel_location = '%s', channel_notifyflags = %d, channel_max_anon_mail = %d, channel_max_friend_req = %d, channel_expire_days = %d, channel_default_group = '%s', channel_r_stream = %d, channel_r_profile = %d, channel_r_photos = %d, channel_r_abook = %d, channel_w_stream = %d, channel_w_wall = %d, channel_w_tagwall = %d, channel_w_comment = %d, channel_w_mail = %d, channel_w_photos = %d, channel_w_chat = %d, channel_a_delegate = %d, channel_r_storage = %d, channel_w_storage = %d, channel_r_pages = %d, channel_w_pages = %d, channel_a_republish = %d, channel_a_bookmark = %d, channel_allow_cid = '%s', channel_allow_gid = '%s', channel_deny_cid = '%s', channel_deny_gid = '%s' where channel_id = %d limit 1", dbesc($username), intval($pageflags), dbesc($timezone), @@ -526,6 +432,7 @@ function settings_post(&$a) { intval($arr['channel_r_pages']), intval($arr['channel_w_pages']), intval($arr['channel_a_republish']), + intval($arr['channel_a_bookmark']), dbesc($str_contact_allow), dbesc($str_group_allow), dbesc($str_contact_deny), @@ -737,7 +644,7 @@ function settings_content(&$a) { $arr[$fname] = array(); $arr[$fname][0] = $fdata[0]; foreach(array_slice($fdata,1) as $f) { - $arr[$fname][1][] = array('feature_' .$f[0],$f[1],((intval(get_pconfig(local_user(),'feature',$f[0]))) ? "1" : ''),$f[2],array(t('Off'),t('On'))); + $arr[$fname][1][] = array('feature_' .$f[0],$f[1],((intval(feature_enabled(local_user(),$f[0]))) ? "1" : ''),$f[2],array(t('Off'),t('On'))); } } @@ -830,6 +737,7 @@ function settings_content(&$a) { $nosmile = get_pconfig(local_user(),'system','no_smilies'); $nosmile = (($nosmile===false)? '0': $nosmile); // default if not set: 0 + $chanview = intval(get_pconfig(local_user(),'system','chanview_full')); $theme_config = ""; if( ($themeconfigfile = get_theme_config_file($theme_selected)) != null){ @@ -850,7 +758,7 @@ function settings_content(&$a) { '$ajaxint' => array('browser_update', t("Update browser every xx seconds"), $browser_update, t('Minimum of 10 seconds, no maximum')), '$itemspage' => array('itemspage', t("Maximum number of conversations to load at any time:"), $itemspage, t('Maximum of 100 items')), '$nosmile' => array('nosmile', t("Don't show emoticons"), $nosmile, ''), - + '$chanview_full' => array('chanview_full', t('Do not view remote profiles in frames'), $chanview, t('By default open in a sub-window of your own site')), '$theme_config' => $theme_config, )); @@ -890,6 +798,7 @@ function settings_content(&$a) { array( t('Anybody in your address book'), PERMS_CONTACTS), array( t('Anybody on this website'), PERMS_SITE), array( t('Anybody in this network'), PERMS_NETWORK), + array( t('Anybody authenticated'), PERMS_AUTHED), array( t('Anybody on the internet'), PERMS_PUBLIC) ); @@ -923,6 +832,9 @@ function settings_content(&$a) { $unkmail = $a->user['unkmail']; $cntunkmail = $a->user['cntunkmail']; + $hide_presence = intval(get_pconfig(local_user(), 'system','hide_online_status')); + + $expire_items = get_pconfig(local_user(), 'expire','items'); $expire_items = (($expire_items===false)? '1' : $expire_items); // default if not set: 1 @@ -999,6 +911,18 @@ function settings_content(&$a) { require_once('include/group.php'); $group_select = mini_group_select(local_user(),$channel['channel_default_group']); + require_once('include/menu.php'); + $m1 = menu_list(local_user()); + $menu = false; + if($m1) { + $menu = array(); + $current = get_pconfig(local_user(),'system','channel_menu'); + $menu[] = array('name' => '', 'selected' => ((! $current) ? true : false)); + foreach($m1 as $m) { + $menu[] = array('name' => htmlspecialchars($m['menu_name'],ENT_COMPAT,'UTF-8'), 'selected' => (($m['menu_name'] === $current) ? ' selected="selected" ' : false)); + } + } + $o .= replace_macros($stpl,array( '$ptitle' => t('Channel Settings'), @@ -1016,16 +940,21 @@ function settings_content(&$a) { '$defloc' => array('defloc', t('Default Post Location:'), $defloc, ''), '$allowloc' => array('allow_location', t('Use Browser Location:'), ((get_pconfig(local_user(),'system','use_browser_location')) ? 1 : ''), ''), - '$adult' => array('adult', t('Adult Content'), $adult_flag, t('This channel publishes adult content.')), + '$adult' => array('adult', t('Adult Content'), $adult_flag, t('This channel frequently or regularly publishes adult content. (Please tag any adult material and/or nudity with #NSFW)')), '$h_prv' => t('Security and Privacy Settings'), - '$lbl_pmacro' => t('Quick Privacy Settings:'), - '$pmacro3' => t('Very Public - extremely permissive'), - '$pmacro2' => t('Typical - default public, privacy when desired'), - '$pmacro1' => t('Private - default private, rarely open or public'), - '$pmacro0' => t('Blocked - default blocked to/from everybody'), + '$hide_presence' => array('hide_presence', t('Hide my online presence'),$hide_presence, t('Prevents displaying in your profile that you are online')), + + '$lbl_pmacro' => t('Simple Privacy Settings:'), + '$pmacro3' => t('Very Public - <em>extremely permissive (should be used with caution)</em>'), + '$pmacro2' => t('Typical - <em>default public, privacy when desired (similar to social network permissions but with improved privacy)</em>'), + '$pmacro1' => t('Private - <em>default private, never open or public</em>'), + '$pmacro0' => t('Blocked - <em>default blocked to/from everybody</em>'), '$permiss_arr' => $permiss, + '$blocktags' => array('blocktags',t('Allow others to tag your posts'), 1-$blocktags, t('Often used by the community to retro-actively flag inappropriate content'),array(t('No'),t('Yes'))), + + '$lbl_p2macro' => t('Advanced Privacy Settings'), '$maxreq' => array('maxreq', t('Maximum Friend Requests/Day:'), intval($channel['channel_max_friend_req']) , t('May reduce spam activity')), '$permissions' => t('Default Post Permissions'), @@ -1062,7 +991,11 @@ function settings_content(&$a) { '$h_advn' => t('Advanced Account/Page Type Settings'), '$h_descadvn' => t('Change the behaviour of this account for special situations'), '$pagetype' => $pagetype, - + '$expert' => feature_enabled(local_user(),'expert'), + '$hint' => t('Please enable expert mode (in <a href="settings/features">Settings > Additional features</a>) to adjust!'), + '$lbl_misc' => t('Miscellaneous Settings'), + '$menus' => $menu, + '$menu_desc' => t('Personal menu to display in your channel pages'), )); call_hooks('settings_form',$o); diff --git a/mod/setup.php b/mod/setup.php index 429be43af..14572699e 100755 --- a/mod/setup.php +++ b/mod/setup.php @@ -228,6 +228,8 @@ function setup_content(&$a) { check_smarty3($checks); + check_store($checks); + check_keys($checks); if(x($_POST,'phpath')) @@ -371,7 +373,10 @@ function check_php(&$phpath, &$checks) { if (strlen($phpath)){ $passed = file_exists($phpath); } else { - $phpath = trim(shell_exec('which php')); + if(is_windows()) + $phpath = trim(shell_exec('where php')); + else + $phpath = trim(shell_exec('which php')); $passed = strlen($phpath); } $help = ""; @@ -515,6 +520,24 @@ function check_smarty3(&$checks) { } +function check_store(&$checks) { + $status = true; + $help = ""; + + @mkdir('store',STORAGE_DEFAULT_PERMISSIONS); + + if( !is_writable('store') ) { + + $status=false; + $help = t('Red uses the store directory to save uploaded files. The web server needs to have write access to the store directory under the Red top level folder') . EOL; + $help .= t('Please ensure that the user that your web server runs as (e.g. www-data) has write access to this folder.').EOL; + } + + check_add($checks, t('store is writable'), $status, true, $help); + +} + + function check_htaccess(&$checks) { $a = get_app(); $status = true; @@ -543,7 +566,7 @@ function check_htaccess(&$checks) { function manual_config(&$a) { - $data = htmlentities($a->data['txt']); + $data = htmlspecialchars($a->data['txt'],ENT_COMPAT,'UTF-8'); $o = t('The database configuration file ".htconfig.php" could not be written. Please use the enclosed text to create a configuration file in your web server root.'); $o .= "<textarea rows=\"24\" cols=\"80\" >$data</textarea>"; return $o; @@ -577,6 +600,8 @@ function load_database($db) { function what_next() { $a = get_app(); + // install the standard theme + set_config('system','allowed_themes','redbasic'); $baseurl = $a->get_baseurl(); return t('<h1>What next</h1>') diff --git a/mod/siteinfo.php b/mod/siteinfo.php index a64b5df20..7fdb892d2 100644 --- a/mod/siteinfo.php +++ b/mod/siteinfo.php @@ -27,8 +27,14 @@ function siteinfo_init(&$a) { $visible_plugins[] = $rr['name']; } + if(@is_dir('.git') && function_exists('shell_exec')) + $commit = @shell_exec('git log -1 --format="%h"'); + if(! isset($commit) || strlen($commit) > 16) + $commit = ''; + $data = Array( 'version' => RED_VERSION, + 'commit' => $commit, 'url' => z_root(), 'plugins' => $visible_plugins, 'register_policy' => $register_policy[$a->config['system']['register_policy']], @@ -47,11 +53,16 @@ function siteinfo_init(&$a) { function siteinfo_content(&$a) { - if(! get_config('system','hidden_version_siteinfo')) + if(! get_config('system','hidden_version_siteinfo')) { $version = sprintf( t('Version %s'), RED_VERSION ); - else - $version = ""; - + if(@is_dir('.git') && function_exists('shell_exec')) + $commit = @shell_exec('git log -1 --format="%h"'); + if(! isset($commit) || strlen($commit) > 16) + $commit = ''; + } + else { + $version = $commit = ''; + } $visible_plugins = array(); if(is_array($a->plugins) && count($a->plugins)) { $r = q("select * from addon where hidden = 0"); @@ -77,16 +88,43 @@ function siteinfo_content(&$a) { else $plugins_text = t('No installed plugins/addons/apps'); + $admininfo = bbcode(get_config('system','admininfo')); + + $project_donate = t('Project Donations'); + $donate_text = t('<p>The Red Matrix is provided for you by volunteers working in their spare time. Your support will help us to build a better, freer, and privacy respecting web. Select the following option for a one-time donation of your choosing</p>'); + $alternatively = t('<p>or</p>'); + $recurring = t('Recurring Donation Options'); + + $donate = <<< EOT +<h3>{$project_donate}</h3> +$donate_text +<form action="https://www.paypal.com/cgi-bin/webscr" method="post"><input type="hidden" name="cmd" value="_donations" /><input type="hidden" name="business" value="mike@macgirvin.com" /><input type="hidden" name="lc" value="US" /><input type="hidden" name="item_name" value="Distributed Social Network Support Donation" /><input type="hidden" name="no_note" value="0" /><input type="hidden" name="currency_code" value="USD" /><input type="hidden" name="bn" value="PP-DonationsBF:btn_donate_LG.gif:NonHostedGuest" /><input style="border: none;" type="image" name="submit" src="https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif" alt="Donations gladly accepted to support our work" /></form><br /> +<strong>$alternatively</strong> +<form action="https://www.paypal.com/cgi-bin/webscr" method="post"><input type="hidden" name="cmd" value="_s-xclick" /><input type="hidden" name="hosted_button_id" value="FHV36KE28CYM8" /><br /> +<table><tbody><tr><td><input type="hidden" name="on0" value="$recurring" />$recurring</td> +</tr><tr><td> +<select name="os0"><option value="Option 1">Option 1 : $3.00USD - monthly</option><option value="Option 2">Option 2 : $5.00USD - monthly</option><option value="Option 3">Option 3 : $10.00USD - monthly</option><option value="Option 4">Option 4 : $20.00USD - monthly</option></select></td> +</tr></tbody></table><p><input type="hidden" name="currency_code" value="USD" /><input type="image" style="border: none;" border="0" name="submit" src="https://www.paypalobjects.com/en_US/i/btn/btn_subscribeCC_LG.gif" alt="PayPal - The safer, easier way to pay online!" /><img src="https://www.paypalobjects.com/en_US/i/scr/pixel.gif" alt="" width="1" height="1" border="0" /></p></form> +<p></p> +EOT; + + if(file_exists('doc/site_donate.html')) + $donate .= file_get_contents('doc/site_donate.html'); + $o = replace_macros(get_markup_template('siteinfo.tpl'), array( '$title' => t('Red'), '$description' => t('This is a hub of the Red Matrix - a global cooperative network of decentralised privacy enhanced websites.'), '$version' => $version, + '$commit' => $commit, '$web_location' => t('Running at web location') . ' ' . z_root(), '$visit' => t('Please visit <a href="http://getzot.com">GetZot.com</a> to learn more about the Red Matrix.'), '$bug_text' => t('Bug reports and issues: please visit'), '$bug_link_url' => 'https://github.com/friendica/red/issues', '$bug_link_text' => 'redmatrix issues', - '$contact' => t('Suggestions, praise, donations, etc. - please email "redmatrix" at librelist - dot com'), + '$contact' => t('Suggestions, praise, etc. - please email "redmatrix" at librelist - dot com'), + '$donate' => $donate, + '$adminlabel' => t('Site Administrators'), + '$admininfo' => $admininfo, '$plugins_text' => $plugins_text, '$plugins_list' => $plugins_list )); diff --git a/mod/sources.php b/mod/sources.php index 125184d47..f4b36508f 100644 --- a/mod/sources.php +++ b/mod/sources.php @@ -9,11 +9,29 @@ function sources_post(&$a) { $source = intval($_REQUEST['source']); $xchan = $_REQUEST['xchan']; + $abook = intval($_REQUEST['abook']); $words = $_REQUEST['words']; $frequency = $_REQUEST['frequency']; + $name = $_REQUEST['name']; $channel = $a->get_channel(); + if($name == '*') + $xchan = '*'; + + if($abook) { + $r = q("select abook_xchan from abook where abook_id = %d and abook_channel = %d limit 1", + intval($abook), + intval(local_user()) + ); + if($r) + $xchan = $r[0]['abook_xchan']; + } + + if(! $xchan) { + notice ( t('Failed to create source. No channel selected.') . EOL); + return; + } if(! $source) { $r = q("insert into source ( src_channel_id, src_channel_xchan, src_xchan, src_patt ) @@ -60,6 +78,9 @@ function sources_content(&$a) { ); if($r) { for($x = 0; $x < count($r); $x ++) { + if($r[$x]['src_xchan'] == '*') { + $r[$x]['xchan_name'] = t('*'); + } $r[$x]['src_patt'] = htmlspecialchars($r[$x]['src_patt'], ENT_COMPAT,'UTF-8'); } } @@ -92,6 +113,12 @@ function sources_content(&$a) { intval(argv(1)), intval(local_user()) ); + if($r) { + $x = q("select abook_id from abook where abook_xchan = '%s' and abook_channel = %d limit 1", + dbesc($r[0]['src_xchan']), + intval(local_user()) + ); + } if(! $r) { notice( t('Source not found.') . EOL); return ''; @@ -106,6 +133,7 @@ function sources_content(&$a) { '$desc' => t('Import all or selected content from the following channel into this channel and distribute it according to your channel settings.'), '$words' => array( 'words', t('Only import content with these words (one per line)'),$r[0]['src_patt'],t('Leave blank to import all public content')), '$xchan' => $r[0]['src_xchan'], + '$abook' => $x[0]['abook_id'], '$name' => array( 'name', t('Channel Name'), $r[0]['xchan_name'], ''), '$submit' => t('Submit') )); diff --git a/mod/sslify.php b/mod/sslify.php new file mode 100644 index 000000000..ed06d87c1 --- /dev/null +++ b/mod/sslify.php @@ -0,0 +1,24 @@ +<?php + +function sslify_init(&$a) { + $x = z_fetch_url($_REQUEST['url']); + if($x['success']) { + $h = explode("\n",$x['headers']); + foreach ($h as $l) { + list($k,$v) = array_map("trim", explode(":", trim($l), 2)); + $hdrs[$k] = $v; + } + if (array_key_exists('Content-Type', $hdrs)) + $type = $hdrs['Content-Type']; + + header('Content-Type: ' . $type); + echo $x['body']; + killme(); + } + killme(); + // for some reason when this fallback is in place - it gets triggered + // often, (creating mixed content exceptions) even though there is + // nothing obvious missing on the page when we bypass it. + goaway($_REQUEST['url']); +} + diff --git a/mod/suggest.php b/mod/suggest.php index baccbd38f..8a6b50b22 100644 --- a/mod/suggest.php +++ b/mod/suggest.php @@ -19,13 +19,6 @@ function suggest_init(&$a) { } -function suggest_aside(&$a) { - - $a->set_widget('follow', widget_follow(array())); - $a->set_widget('findpeople', findpeople_widget()); -} - - function suggest_content(&$a) { $o = ''; diff --git a/mod/thing.php b/mod/thing.php index 91bdca78a..cbf83fdf8 100644 --- a/mod/thing.php +++ b/mod/thing.php @@ -1,6 +1,7 @@ <?php /** @file */ require_once('include/items.php'); +require_once('include/contact_selectors.php'); function thing_init(&$a) { @@ -8,15 +9,20 @@ function thing_init(&$a) { if(! local_user()) return; + + + $account_id = $a->get_account(); $channel = $a->get_channel(); + $term_hash = (($_REQUEST['term_hash']) ? $_REQUEST['term_hash'] : ''); $name = escape_tags($_REQUEST['term']); $verb = escape_tags($_REQUEST['verb']); - $profile_guid = escape_tags($_REQUEST['profile']); + $activity = intval($_REQUEST['activity']); + $profile_guid = escape_tags($_REQUEST['profile_assign']); $url = $_REQUEST['link']; - $photo = $_REQUEST['photo']; + $photo = $_REQUEST['img']; $hash = random_string(); @@ -59,15 +65,58 @@ function thing_init(&$a) { if((! $name) || (! $translated_verb)) return; + + + + + if($term_hash) { + $t = q("select * from obj left join term on obj_obj = term_hash where term_hash != '' and obj_type = %d and term_hash = '%s' limit 1", + intval(TERM_OBJ_THING), + dbesc($term_hash) + ); + if(! $t) { + notice( t('Item not found.') . EOL); + return; + } + $orig_record = $t[0]; + if($photo != $orig_record['imgurl']) { + $arr = import_profile_photo($photo,get_observer_hash(),true); + $local_photo = $arr[0]; + $local_photo_type = $arr[3]; + } + else + $local_photo = $orig_record['imgurl']; + + $r = q("update term set term = '%s', url = '%s', imgurl = '%s' where term_hash = '%s' and uid = %d limit 1", + dbesc($name), + dbesc(($url) ? $url : z_root() . '/thing/' . $term_hash), + dbesc($local_photo), + dbesc($term_hash), + intval(local_user()) + ); + + info( t('Thing updated') . EOL); + return; + } + $sql = (($profile_guid) ? " and profile_guid = '" . dbesc($profile_guid) . "' " : " and is_default = 1 "); $p = q("select profile_guid, is_default from profile where uid = %d $sql limit 1", intval(local_user()) ); + if($p) $profile = $p[0]; else return; + $local_photo = null; + + if($photo) { + $arr = import_profile_photo($photo,get_observer_hash(),true); + $local_photo = $arr[0]; + $local_photo_type = $arr[3]; + } + $r = q("select * from term where uid = %d and otype = %d and type = %d and term = '%s' limit 1", intval(local_user()), @@ -85,7 +134,7 @@ function thing_init(&$a) { intval(TERM_THING), dbesc($name), dbesc(($url) ? $url : z_root() . '/thing/' . $hash), - dbesc(($photo) ? $photo : ''), + dbesc(($photo) ? $local_photo : ''), dbesc($hash) ); $r = q("select * from term where uid = %d and otype = %d and type = %d and term = '%s' limit 1", @@ -110,83 +159,170 @@ function thing_init(&$a) { return; } - info( t('thing/stuff added')); + info( t('Thing added')); - $arr = array(); - $links = array(array('rel' => 'alternate','type' => 'text/html', - 'href' => $term['url'])); - $objtype = ACTIVITY_OBJ_THING; + if($activity) { + $arr = array(); + $links = array(array('rel' => 'alternate','type' => 'text/html', 'href' => $term['url'])); + if($local_photo) + $links[] = array('rel' => 'photo', 'type' => $local_photo_type, 'href' => $local_photo); - $obj = json_encode(array( - 'type' => $objtype, - 'id' => $term['url'], - 'link' => $links, - 'title' => $term['term'], - 'content' => $term['term'] - )); - $bodyverb = str_replace('OBJ: ', '',t('OBJ: %1$s %2$s %3$s')); + $objtype = ACTIVITY_OBJ_THING; - $arr['owner_xchan'] = $channel['channel_hash']; - $arr['author_xchan'] = $channel['channel_hash']; + $obj = json_encode(array( + 'type' => $objtype, + 'id' => $term['url'], + 'link' => $links, + 'title' => $term['term'], + 'content' => $term['term'] + )); + $bodyverb = str_replace('OBJ: ', '',t('OBJ: %1$s %2$s %3$s')); - $arr['item_flags'] = ITEM_ORIGIN|ITEM_WALL|ITEM_THREAD_TOP; + $arr['owner_xchan'] = $channel['channel_hash']; + $arr['author_xchan'] = $channel['channel_hash']; + + + $arr['item_flags'] = ITEM_ORIGIN|ITEM_WALL|ITEM_THREAD_TOP; + + $ulink = '[zrl=' . $channel['xchan_url'] . ']' . $channel['channel_name'] . '[/zrl]'; + $plink = '[zrl=' . $term['url'] . ']' . $term['term'] . '[/zrl]'; + + $arr['body'] = sprintf( $bodyverb, $ulink, $translated_verb, $plink ); + + if($local_photo) + $arr['body'] .= "\n\n[zmg]" . $local_photo . "[/zmg]"; + + $arr['verb'] = $verb; + $arr['obj_type'] = $objtype; + $arr['object'] = $obj; + + if(! $profile['is_default']) { + $arr['item_private'] = true; + $str = ''; + $r = q("select abook_xchan from abook where abook_channel = %d and abook_profile = '%s'", + intval(local_user()), + dbesc($profile_guid) + ); + if($r) { + $arr['allow_cid'] = ''; + foreach($r as $rr) + $arr['allow_cid'] .= '<' . $rr['abook_xchan'] . '>'; + } + else + $arr['allow_cid'] = '<' . get_observer_hash() . '>'; + } - $ulink = '[zrl=' . $channel['xchan_url'] . ']' . $channel['channel_name'] . '[/zrl]'; - $plink = '[zrl=' . $term['url'] . ']' . $term['term'] . '[/zrl]'; + $ret = post_activity_item($arr); + } +} - $arr['body'] = sprintf( $bodyverb, $ulink, $translated_verb, $plink ); - $arr['verb'] = $verb; - $arr['obj_type'] = $objtype; - $arr['object'] = $obj; +function thing_content(&$a) { + + if(argc() == 2) { - if(! $profile['is_default']) { - $arr['item_private'] = true; - $str = ''; - $r = q("select abook_hash from abook where abook_channel = %d and abook_profile = '%s'", - intval(local_user()), - dbesc($profile_guid) + $r = q("select * from obj left join term on obj_obj = term_hash where term_hash != '' and obj_type = %d and term_hash = '%s' limit 1", + intval(TERM_OBJ_THING), + dbesc(argv(1)) ); + if($r) { - $arr['allow_cid'] = ''; - foreach($r as $rr) - $arr['allow_cid'] .= '<' . $rr['abook_hash'] . '>'; + return replace_macros(get_markup_template('show_thing.tpl'), array( + '$header' => t('Show Thing'), + '$edit' => t('Edit'), + '$delete' => t('Delete'), + '$canedit' => ((local_user() && local_user() == $r[0]['obj_channel']) ? true : false), + '$thing' => $r[0] )); + } + else { + notice( t('item not found.') . EOL); + return; } - else - $arr['allow_cid'] = '<' . get_observer_hash() . '>'; } - - $ret = post_activity_item($arr); - if($ret['success']) - proc_run('php','include/notifier.php','tag',$ret['activity']['id']); - -} + if(! local_user()) { + notice( t('Permission denied.') . EOL); + return; + } + $thing_hash = ''; + + if(argc() == 3 && argv(1) === 'edit') { + $thing_hash = argv(2); -function thing_content(&$a) { - - /* placeholders */ - if(argc() > 1) { - return t('not yet implemented.'); + $r = q("select * from obj left join term on obj_obj = term_hash where term_hash != '' and obj_type = %d and term_hash = '%s' limit 1", + intval(TERM_OBJ_THING), + dbesc($thing_hash) + ); + + if((! $r) || ($r[0]['obj_channel'] != local_user())) { + notice( t('Permission denied.') . EOL); + return ''; + } + + + $o .= replace_macros(get_markup_template('thing_edit.tpl'),array( + '$thing_hdr' => t('Edit Thing'), + '$multiprof' => feature_enabled(local_user(),'multi_profiles'), + '$profile_lbl' => t('Select a profile'), + '$profile_select' => contact_profile_assign($r[0]['obj_page']), + '$verb_lbl' => t('Select a category of stuff. e.g. I ______ something'), + '$verb_select' => obj_verb_selector($r[0]['obj_verb']), + '$activity' => array('activity',t('Post an activity'),true,t('Only sends to viewers of the applicable profile')), + '$thing_hash' => $thing_hash, + '$thing_lbl' => t('Name of thing e.g. something'), + '$thething' => $r[0]['term'], + '$url_lbl' => t('URL of thing (optional)'), + '$theurl' => $r[0]['url'], + '$img_lbl' => t('URL for photo of thing (optional)'), + '$imgurl' => $r[0]['imgurl'], + '$submit' => t('Submit') + )); + + return $o; } - require_once('include/contact_selectors.php'); + if(argc() == 3 && argv(1) === 'drop') { + $thing_hash = argv(2); + + $r = q("select * from obj left join term on obj_obj = term_hash where term_hash != '' and obj_type = %d and term_hash = '%s' limit 1", + intval(TERM_OBJ_THING), + dbesc($thing_hash) + ); + + if((! $r) || ($r[0]['obj_channel'] != local_user())) { + notice( t('Permission denied.') . EOL); + return ''; + } + + + $x = q("delete from obj where obj_obj = '%s' and obj_type = %d and obj_channel = %d limit 1", + dbesc($thing_hash), + intval(TERM_OBJ_THING), + intval(local_user()) + ); + $x = q("delete from term where term_hash = '%s' and uid = %d limit 1", + dbesc($thing_hash), + intval(local_user()) + ); + return $o; + } $o .= replace_macros(get_markup_template('thing_input.tpl'),array( - '$thing_hdr' => t('Add Stuff to your Profile'), + '$thing_hdr' => t('Add Thing to your Profile'), '$multiprof' => feature_enabled(local_user(),'multi_profiles'), '$profile_lbl' => t('Select a profile'), '$profile_select' => contact_profile_assign(''), '$verb_lbl' => t('Select a category of stuff. e.g. I ______ something'), + '$activity' => array('activity',t('Post an activity'),true,t('Only sends to viewers of the applicable profile')), '$verb_select' => obj_verb_selector(), - '$thing_lbl' => t('Name of thing or stuff e.g. something'), - '$url_lbl' => t('URL of thing or stuff (optional)'), - '$img_lbl' => t('URL for photo of thing or stuff (optional)'), + '$thing_lbl' => t('Name of thing e.g. something'), + '$url_lbl' => t('URL of thing (optional)'), + '$img_lbl' => t('URL for photo of thing (optional)'), '$submit' => t('Submit') )); diff --git a/mod/toggle_safesearch.php b/mod/toggle_safesearch.php index 5fb18f694..3c800c4f3 100644 --- a/mod/toggle_safesearch.php +++ b/mod/toggle_safesearch.php @@ -3,6 +3,8 @@ function toggle_safesearch_init(&$a) { $observer = get_observer_hash(); +if (! $observer) + return; if($observer) $safe_mode = get_xconfig($observer,'directory','safe_mode'); diff --git a/mod/viewconnections.php b/mod/viewconnections.php index 9c85d63b6..4f6f81d82 100644 --- a/mod/viewconnections.php +++ b/mod/viewconnections.php @@ -11,17 +11,6 @@ function viewconnections_init(&$a) { profile_load($a,argv(1)); } - -function viewconnections_aside(&$a) { - - if((get_config('system','block_public')) && (! local_user()) && (! remote_user())) { - return; - } - - profile_create_sidebar($a); -} - - function viewconnections_content(&$a) { if((get_config('system','block_public')) && (! local_user()) && (! remote_user())) { @@ -41,14 +30,11 @@ function viewconnections_content(&$a) { - $r = q("SELECT COUNT(abook_id) as total FROM abook WHERE abook_channel = %d AND abook_flags = 0 ", - intval($a->profile['uid']) - ); - if($r) - $a->set_pager_total($r[0]['total']); - - $r = q("SELECT * FROM abook left join xchan on abook_xchan = xchan_hash where abook_channel = %d and abook_flags = 0 order by xchan_name LIMIT %d , %d ", + $r = q("SELECT * FROM abook left join xchan on abook_xchan = xchan_hash where abook_channel = %d and abook_flags = 0 and not ( xchan_flags & %d ) and not ( xchan_flags & %d ) and not ( xchan_flags & %d ) order by xchan_name LIMIT %d , %d ", intval($a->profile['uid']), + intval(XCHAN_FLAGS_HIDDEN), + intval(XCHAN_FLAGS_ORPHAN), + intval(XCHAN_FLAGS_DELETED), intval($a->pager['start']), intval($a->pager['itemspage']) ); diff --git a/mod/wall_attach.php b/mod/wall_attach.php index 6e9443f12..47c097416 100644 --- a/mod/wall_attach.php +++ b/mod/wall_attach.php @@ -1,23 +1,12 @@ <?php require_once('include/attach.php'); -require_once('include/datetime.php'); +require_once('include/identity.php'); function wall_attach_post(&$a) { - // Figure out who owns the page and if they allow attachments - - if(argc() > 1) { - $nick = argv(1); - $r = q("SELECT channel.* from channel where channel_address = '%s' limit 1", - dbesc($nick) - ); - if(! $r) - killme(); - $channel = $r[0]; - - } - + if(argc() > 1) + $channel = get_channel_by_nick(argv(1)); else killme(); diff --git a/mod/wall_upload.php b/mod/wall_upload.php index dd5d760b3..2939cf0d1 100644 --- a/mod/wall_upload.php +++ b/mod/wall_upload.php @@ -1,6 +1,7 @@ <?php require_once('include/photo/photo_driver.php'); +require_once('include/identity.php'); require_once('include/photos.php'); @@ -19,15 +20,7 @@ function wall_upload_post(&$a) { $nick = argv(1); } - $channel = null; - - if($nick) { - $r = q("SELECT channel.* from channel where channel_address = '%s' limit 1", - dbesc($nick) - ); - if($r) - $channel = $r[0]; - } + $channel = (($nick) ? get_channel_by_nick($nick) : false); if(! $channel) { if($using_api) diff --git a/mod/webpages.php b/mod/webpages.php index 90004faa1..7e1b32f36 100644 --- a/mod/webpages.php +++ b/mod/webpages.php @@ -41,9 +41,9 @@ function webpages_content(&$a) { return; } - if(local_user() && local_user() == $owner) { - $a->set_widget('design',design_tools()); - } +// if(local_user() && local_user() == $owner) { +// $a->set_widget('design',design_tools()); +// } $mimetype = get_config('system','page_mimetype'); diff --git a/mod/xchan.php b/mod/xchan.php index 984a62f95..9d4cdcc22 100644 --- a/mod/xchan.php +++ b/mod/xchan.php @@ -14,9 +14,11 @@ function xchan_content(&$a) { if(x($_GET,'addr')) { $addr = trim($_GET['addr']); + $r = q("select xchan_name from xchan where xchan_hash like '%s%%'", - dbesc(addr) + dbesc($addr) ); + if($r) { foreach($r as $rr) $o .= $rr['xchan_name'] . EOL; diff --git a/mod/xref.php b/mod/xref.php new file mode 100644 index 000000000..95cc22aa7 --- /dev/null +++ b/mod/xref.php @@ -0,0 +1,20 @@ +<?php + +function xref_init(&$a) { + // Sets a referral URL using an xchan directly + // Link format: example.com/xref/[xchan]/[TargetURL] + // Target URL is optional. + // Cookie lasts 24 hours to survive a browser restart. Contains no personal + // information at all - just somebody else's xchan. + $referrer = argv(1); + $expire=time()+60*60*2; + $path = 'xref'; + setcookie($path, $referrer, $expire, "/"); + $url = ''; + + if (argc() > 2) + $url = argv(2); + + goaway (z_root() . '/' . $url); + +} diff --git a/mod/zfinger.php b/mod/zfinger.php index 0827f3424..94671271b 100644 --- a/mod/zfinger.php +++ b/mod/zfinger.php @@ -52,11 +52,33 @@ function zfinger_init(&$a) { ); } elseif(strlen($zaddr)) { - $r = q("select channel.*, xchan.* from channel left join xchan on channel_hash = xchan_hash - where ( channel_address = '%s' or xchan_addr = '%s' ) limit 1", - dbesc($zaddr), - dbesc($zaddr) - ); + if(strpos($zaddr,'[system]') === false) { /* normal address lookup */ + $r = q("select channel.*, xchan.* from channel left join xchan on channel_hash = xchan_hash + where ( 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 + where (( channel_pageflags & %d ) or not ( channel_pageflags & %d )) order by channel_id limit 1", + intval(PAGE_SYSTEM), + intval(PAGE_REMOVED) + ); + } } else { $ret['message'] = 'Invalid request'; @@ -104,12 +126,16 @@ function zfinger_init(&$a) { $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)) { + if(trim($kk," \t\n\r\0\x0B,")) { $tags[] = trim($kk," \t\n\r\0\x0B,"); } } |