diff options
Diffstat (limited to 'mod')
67 files changed, 2216 insertions, 1185 deletions
diff --git a/mod/_well_known.php b/mod/_well_known.php index 5c5f6585f..6e77336c3 100644 --- a/mod/_well_known.php +++ b/mod/_well_known.php @@ -4,11 +4,6 @@ function _well_known_init(&$a){ if(argc() > 1) {
switch(argv(1)) {
- case "host-meta":
- require_once('mod/hostxrd.php');
- hostxrd_init($a);
- break;
-
case 'zot-info':
$a->argc -= 1;
array_shift($a->argv);
@@ -17,6 +12,14 @@ function _well_known_init(&$a){ zfinger_init($a);
break;
+ case 'webfinger':
+ $a->argc -= 1;
+ array_shift($a->argv);
+ $a->argv[0] = 'wfinger';
+ require_once('mod/wfinger.php');
+ wfinger_init($a);
+ break;
+
}
}
diff --git a/mod/acl.php b/mod/acl.php index 2f1866f85..143b8098e 100644 --- a/mod/acl.php +++ b/mod/acl.php @@ -60,16 +60,17 @@ function acl_init(&$a){ // autocomplete for Private Messages - $r = q("SELECT COUNT(`id`) AS c FROM `contact` - WHERE `uid` = %d AND `self` = 0 - AND `blocked` = 0 AND `pending` = 0 AND `archive` = 0 - AND `network` IN ('%s','%s','%s') $sql_extra2" , + + $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 )) + $sql_extra2 ", intval(local_user()), - dbesc(NETWORK_DFRN), - dbesc(NETWORK_ZOT), - dbesc(NETWORK_DIASPORA) + intval(PERMS_W_MAIL) ); - $contact_count = (int)$r[0]['c']; + + if($r) + $contact_count = (int)$r[0]['c']; } elseif ($type == 'a') { @@ -123,7 +124,7 @@ 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 + $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 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" , intval(local_user()), @@ -142,7 +143,7 @@ function acl_init(&$a){ ); } elseif($type == 'a') { - $r = q("SELECT abook_id as id, xchan_name as name, xchan_addr as nick, xchan_photo_s as micro, xchan_network as network, xchan_url as url, xchan_addr as attag FROM abook left join xchan on abook_xchan = xchan_hash + $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 $sql_extra3 ORDER BY xchan_name ASC ", @@ -196,13 +197,15 @@ function acl_init(&$a){ if(count($r)) { foreach($r as $g){ $contacts[] = array( - "type" => "c", - "photo" => $g['micro'], - "name" => $g['name'], - "id" => $g['id'], - "xid" => $g['hash'], - "link" => $g['nick'], - "nick" => substr($g['nick'],0,strpos($g['nick'],'@')) + "type" => "c", + "photo" => $g['micro'], + "name" => $g['name'], + "id" => $g['id'], + "xid" => $g['hash'], + "link" => $g['nick'], + "nick" => substr($g['nick'],0,strpos($g['nick'],'@')), + "network" => '', + "taggable" => (($g['abook_their_perms'] & PERMS_W_TAGWALL) ? 'taggable' : '') ); } } @@ -251,10 +254,11 @@ function navbar_complete(&$a) { } if(! $url) { + require_once("include/dir_fns.php"); $directory = find_upstream_directory($dirmode); if($directory) { - $url = $directory['url']; + $url = $directory['url'] . '/dirsearch'; } else { $url = DIRECTORY_FALLBACK_MASTER . '/dirsearch'; diff --git a/mod/admin.php b/mod/admin.php index aa3d7b294..f3e44afb8 100644 --- a/mod/admin.php +++ b/mod/admin.php @@ -1,7 +1,7 @@ <?php /** - * Friendica admin + * Red admin */ @@ -188,7 +188,7 @@ function admin_page_summary(&$a) { '$users' => Array( t('Registered users'), $users), '$accounts' => $accounts, '$pending' => Array( t('Pending registrations'), $pending), - '$version' => Array( t('Version'), FRIENDICA_VERSION), + '$version' => Array( t('Version'), RED_VERSION), '$build' => get_config('system','db_version'), '$plugins' => Array( t('Active plugins'), $a->plugins ) )); @@ -210,6 +210,9 @@ function admin_page_site_post(&$a){ $banner = ((x($_POST,'banner')) ? trim($_POST['banner']) : 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); @@ -278,7 +281,7 @@ function admin_page_site_post(&$a){ set_config('system','delivery_interval',$delivery_interval); set_config('system','poll_interval',$poll_interval); set_config('system','maxloadavg',$maxloadavg); - set_config('config','sitename',$sitename); + set_config('system','sitename',$sitename); if ($banner=="") { del_config('system','banner'); @@ -289,6 +292,18 @@ function admin_page_site_post(&$a){ set_config('system','language', $language); set_config('system','theme', $theme); + if ( $theme_mobile === '---' ) { + del_config('system','mobile-theme'); + } else { + set_config('system','mobile-theme', $theme_mobile); + } + if ( $theme_accessibility === '---' ) { + del_config('system','accessibility-theme'); + } else { + set_config('system','accessibility-theme', $theme_accessibility); + } + + set_config('system','site-channel', $site_channel); set_config('system','maximagesize', $maximagesize); set_config('system','register_policy', $register_policy); @@ -337,14 +352,24 @@ function admin_page_site(&$a) { $lang_choices[$t[1]] = $t[1]; } } - + /* Installed themes */ $theme_choices = array(); + $theme_choices_mobile = array(); + $theme_choices_mobile["---"] = t("No special theme for mobile devices"); + $theme_choices_accessibility = array(); + $theme_choices_accessibility["---"] =t("No special theme for accessibility"); $files = glob('view/theme/*'); if($files) { foreach($files as $file) { $f = basename($file); $theme_name = ((file_exists($file . '/.experimental')) ? sprintf("%s - Experimental", $f) : $f); + if (file_exists($file . '/.mobile')) { + $theme_choices_mobile[$f] = $theme_name; + } + if (file_exists($file . '/.accessibility')) { + $theme_choices_accessibility[$f] = $theme_name; + } $theme_choices[$f] = $theme_name; } } @@ -380,22 +405,23 @@ function admin_page_site(&$a) { '$baseurl' => $a->get_baseurl(true), // name, label, value, help string, extra data... - '$sitename' => array('sitename', t("Site name"), htmlentities($a->config['sitename'], ENT_QUOTES), ""), + '$sitename' => array('sitename', t("Site name"), htmlentities(get_config('system','sitename'), ENT_QUOTES), ""), '$banner' => array('banner', t("Banner/Logo"), $banner, ""), '$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), + '$theme_accessibility' => array('theme-accessibility', t("Accessibility system theme"), get_config('system','accessibility-theme'), t("Accessibility theme"), $theme_choices_accessibility), + '$site_channel' => array('site-channel', t("Channel to use for this website's static pages"), get_config('system','site-channel'), t("Site Channel")), '$ssl_policy' => array('ssl_policy', t("SSL link policy"), (string) intval(get_config('system','ssl_policy')), t("Determines whether generated links should be forced to use SSL"), $ssl_choices), '$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"), $a->config['system']['register_policy'], "", $register_choices), - '$register_text' => array('register_text', t("Register text"), htmlentities($a->config['register_text'], ENT_QUOTES, 'UTF-8'), t("Will be displayed prominently on the registration page.")), + '$register_policy' => array('register_policy', t("Register policy"), get_config('system','register_policy'), "", $register_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.")), '$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")), '$block_public' => array('block_public', t("Block public"), get_config('system','block_public'), t("Check to block public access to all otherwise public personal pages on this site unless you are currently logged in.")), '$force_publish' => array('publish_all', t("Force publish"), get_config('system','publish_all'), t("Check to force all profiles on this site to be listed in the site directory.")), - '$global_directory' => array('directory_submit_url', t("Global directory update URL"), get_config('system','directory_submit_url'), t("URL to update the global directory. If this is not set, the global directory is completely unavailable to the application.")), - '$no_community_page' => array('no_community_page', t("Show Community Page"), !get_config('system','no_community_page'), t("Display a Community page showing all recent public postings on this site.")), '$proxyuser' => array('proxyuser', t("Proxy user"), get_config('system','proxyuser'), ""), '$proxy' => array('proxy', t("Proxy URL"), get_config('system','proxy'), ""), '$timeout' => array('timeout', t("Network timeout"), (x(get_config('system','curl_timeout'))?get_config('system','curl_timeout'):60), t("Value is in seconds. Set to 0 for unlimited (not recommended).")), @@ -564,22 +590,10 @@ function admin_page_users(&$a){ $a->set_pager_itemspage(100); } -// FIXME this is borked since there is no more user table - - $users = q("SELECT `user` . * , `contact`.`name` , `contact`.`url` , `contact`.`micro`, `lastitem`.`lastitem_date` - FROM - (SELECT MAX(`item`.`changed`) as `lastitem_date`, `item`.`uid` - FROM `item` - WHERE `item`.`type` = 'wall' - GROUP BY `item`.`uid`) AS `lastitem` - RIGHT OUTER JOIN `user` ON `user`.`uid` = `lastitem`.`uid`, - `contact` - WHERE - `user`.`uid` = `contact`.`uid` - AND `user`.`verified` =1 - AND `contact`.`self` =1 - ORDER BY `contact`.`name` LIMIT %d, %d - ", + +// WEe'll still need to link email addresses to admin/users/channels or some such, but this bit doesn't exist yet. +// That's where we need to be doing last post/channel flags/etc, not here. + $users =q("SELECT `account_id` , `account_email`, `account_lastlog`, `account_created`, `account_service_class` FROM `account`", intval($a->pager['start']), intval($a->pager['itemspage']) ); @@ -591,6 +605,7 @@ function admin_page_users(&$a){ t('Community/Celebrity Account'), t('Automatic Friend Account') ); + $e['page_flags'] = $accounts[$e['page-flags']]; $e['register_date'] = relative_date($e['register_date']); $e['login_date'] = relative_date($e['login_date']); @@ -617,7 +632,7 @@ function admin_page_users(&$a){ '$unblock' => t('Unblock'), '$h_users' => t('Users'), - '$th_users' => array( t('Name'), t('Email'), t('Register date'), t('Last login'), t('Last item'), t('Account') ), + '$th_users' => array( t('Email'), t('Register date'), t('Last login'), t('Service Class')), '$confirm_delete_multi' => t('Selected users will be deleted!\n\nEverything these users had posted on this site will be permanently deleted!\n\nAre you sure?'), '$confirm_delete' => t('The user {0} will be deleted!\n\nEverything this user has posted on this site will be permanently deleted!\n\nAre you sure?'), @@ -1035,7 +1050,7 @@ readable."); // name, label, value, help string, extra data... '$debugging' => array('debugging', t("Debugging"),get_config('system','debugging'), ""), - '$logfile' => array('logfile', t("Log file"), get_config('system','logfile'), t("Must be writable by web server. Relative to your Friendica top-level directory.")), + '$logfile' => array('logfile', t("Log file"), get_config('system','logfile'), t("Must be writable by web server. Relative to your Red top-level directory.")), '$loglevel' => array('loglevel', t("Log level"), get_config('system','loglevel'), "", $log_choices), '$form_security_token' => get_form_security_token("admin_logs"), diff --git a/mod/channel.php b/mod/channel.php index 0a49b41eb..aa158d330 100644 --- a/mod/channel.php +++ b/mod/channel.php @@ -2,11 +2,18 @@ function channel_init(&$a) { + $which = null; if(argc() > 1) $which = argv(1); - else { - notice( t('Requested profile is not available.') . EOL ); - $a->error = 404; + 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; } @@ -47,6 +54,9 @@ function channel_aside(&$a) { $a->set_widget('archive',posted_date_widget($a->get_baseurl(true) . '/channel/' . $a->profile['channel_address'],$a->profile['profile_uid'],true)); $a->set_widget('categories',categories_widget($a->get_baseurl(true) . '/channel/' . $a->profile['channel_address'],$cat)); } + if(feature_enabled($a->profile['profile_uid'],'tagadelic')) + $a->set_widget('tagcloud',tagblock('search',$a->profile['profile_uid'],50,$a->profile['channel_hash'],ITEM_WALL)); + } @@ -118,12 +128,12 @@ function channel_content(&$a, $update = 0, $load = false) { $x = array( 'is_owner' => $is_owner, -// FIXME - 'allow_location' => ((($is_owner || $observer) && $a->profile['allow_location']) ? true : false), - 'default_location' => (($is_owner) ? $a->profile['default_location'] : ''), + 'allow_location' => ((($is_owner || $observer) && (intval(get_pconfig($a->profile['profile_uid'],'system','use_browser_location')))) ? true : false), + 'default_location' => (($is_owner) ? $a->profile['channel_location'] : ''), 'nickname' => $a->profile['channel_address'], 'lockstate' => (((strlen($a->profile['channel_allow_cid'])) || (strlen($a->profile['channel_allow_gid'])) || (strlen($a->profile['channel_deny_cid'])) || (strlen($a->profile['channel_deny_gid']))) ? 'lock' : 'unlock'), 'acl' => (($is_owner) ? populate_acl($channel, false) : ''), + 'showacl' => (($is_owner) ? 'yes' : ''), 'bang' => '', 'visitor' => (($is_owner || $observer) ? 'block' : 'none'), 'profile_uid' => $a->profile['profile_uid'] @@ -247,7 +257,7 @@ function channel_content(&$a, $update = 0, $load = false) { '$order' => '', '$file' => '', '$cats' => (($category) ? $category : ''), - '$uri' => '', + '$mid' => '', '$dend' => $datequery, '$dbegin' => $datequery2 )); diff --git a/mod/chanview.php b/mod/chanview.php index 8de59b92e..4f7638846 100644 --- a/mod/chanview.php +++ b/mod/chanview.php @@ -29,7 +29,11 @@ function chanview_content(&$a) { ); } elseif($_REQUEST['url']) { - $r = q("select * from xchan where xchan_url = '%s' limit 1", + + // if somebody re-installed they will have more than one xchan, use the most recent name date as this is + // the most useful consistently ascending table item we have. + + $r = q("select * from xchan where xchan_url = '%s' order by xchan_name_date desc limit 1", dbesc($_REQUEST['url']) ); } diff --git a/mod/community.php b/mod/community.php index 4f6c3d3c9..971ecca5c 100644 --- a/mod/community.php +++ b/mod/community.php @@ -47,7 +47,7 @@ function community_content(&$a, $update = 0) { // OR your own posts if you are a logged in member if(! get_pconfig(local_user(),'system','alt_pager')) { - $r = q("SELECT COUNT(distinct(`item`.`uri`)) AS `total` + $r = q("SELECT COUNT(distinct(`item`.`mid`)) AS `total` 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` = '' @@ -66,7 +66,7 @@ function community_content(&$a, $update = 0) { } - $r = q("SELECT distinct(`item`.`uri`), `item`.*, `item`.`id` AS `item_id`, + $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`, @@ -77,7 +77,7 @@ function community_content(&$a, $update = 0) { AND `item`.`allow_cid` = '' AND `item`.`allow_gid` = '' AND `item`.`deny_cid` = '' AND `item`.`deny_gid` = '' AND `item`.`private` = 0 AND `item`.`wall` = 1 AND `user`.`hidewall` = 0 - AND `contact`.`blocked` = 0 AND `contact`.`pending` = 0 group by `item`.`uri` + AND `contact`.`blocked` = 0 AND `contact`.`pending` = 0 group by `item`.`mid` ORDER BY `received` DESC LIMIT %d, %d ", intval($a->pager['start']), intval($a->pager['itemspage']) diff --git a/mod/connections.php b/mod/connections.php index 8e002d870..2ad9342b8 100644 --- a/mod/connections.php +++ b/mod/connections.php @@ -23,6 +23,11 @@ function connections_init(&$a) { $a->data['abook'] = $r[0]; } } + + $channel = $a->get_channel(); + if($channel) + head_set_icon($channel['xchan_photo_s']); + } function connections_aside(&$a) { @@ -63,10 +68,10 @@ function connections_post(&$a) { call_hooks('contact_edit_post', $_POST); - $profile_id = intval($_POST['profile-assign']); + $profile_id = $_POST['profile-assign']; if($profile_id) { - $r = q("SELECT `id` FROM `profile` WHERE `id` = %d AND `uid` = %d LIMIT 1", - intval($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)) { @@ -99,9 +104,9 @@ function connections_post(&$a) { $abook_flags = ( $abook_flags ^ ABOOK_FLAG_PENDING ); } - $r = q("UPDATE abook SET abook_profile = %d, abook_my_perms = %d , abook_closeness = %d, abook_flags = %d + $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", - intval($profile_id), + dbesc($profile_id), intval($abook_my_perms), intval($closeness), intval($abook_flags), @@ -126,20 +131,34 @@ function connections_post(&$a) { intval(local_user()), intval($contact_id) ); - if($r) + if($r) { $a->data['abook'] = $r[0]; + } + + connections_clone($a); return; } +function connections_clone(&$a) { + + if(! array_key_exists('abook',$a->data)) + return; + $clone = $a->data['abook']; + + 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 connections_content(&$a) { $sort_type = 0; $o = ''; - nav_set_selected('connections'); if(! local_user()) { @@ -183,40 +202,48 @@ function connections_content(&$a) { } if($cmd === 'block') { - if(abook_toggle_flag($orig_record[0],ABOOK_FLAG_BLOCKED)) + 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)) + 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)) + 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)) + 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); @@ -226,10 +253,12 @@ function connections_content(&$a) { if($cmd === 'approve') { if($orig_record[0]['abook_flags'] & ABOOK_FLAG_PENDING) { - if(abook_toggle_flag($orig_record[0],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); } @@ -244,6 +273,7 @@ function connections_content(&$a) { // 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']); @@ -332,7 +362,7 @@ function connections_content(&$a) { $slider_tpl = get_markup_template('contact_slider.tpl'); $slide = replace_macros($slider_tpl,array( '$me' => t('Me'), - '$val' => $contact['abook_closeness'], + '$val' => (($contact['abook_closeness']) ? $contact['abook_closeness'] : 99), '$intimate' => t('Best Friends'), '$friends' => t('Friends'), '$oldfriends' => t('Former Friends'), @@ -345,12 +375,20 @@ function connections_content(&$a) { $channel = $a->get_channel(); $global_perms = get_perms(); - $existing = get_all_perms(local_user(),$contact); + $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) { - $perms[] = array('perms_' . $k, $v[3], (($contact['abook_their_perms'] & $v[1]) ? "1" : ""),((($contact['abook_my_perms'] & $v[1]) || $existing[$k]) ? "1" : ""), $v[1], (($channel[$v[0]] == PERMS_SPECIFIC) ? '' : '1'), $v[4]); + $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( @@ -368,10 +406,11 @@ function connections_content(&$a) { '$is_pending' => (($contact['abook_flags'] & ABOOK_FLAG_PENDING) ? 1 : ''), '$unapproved' => $unapproved, '$approve' => t('Approve this connection'), - '$noperms' => (((! $self) && (! $contact['abook_my_perms'])) ? t('Connection has no permissions!') : ''), + '$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['name']), + '$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'], @@ -383,7 +422,8 @@ function connections_content(&$a) { '$full' => t('Full Sharing'), '$cautious' => t('Cautious Sharing'), '$follow' => t('Follow Only'), - '$permlbl' => t('Permissions'), + '$permlbl' => t('Individual Permissions'), + '$permnote' => t('Individual permissions are only enabled for <a href="settings">privacy settings</a> which are set to "Only those you specifically allow". Otherwise they are controlled by your privacy settings.'), '$advanced' => t('Advanced Permissions'), '$quick' => t('Quick Links'), '$common_link' => $a->get_baseurl(true) . '/common/loc/' . local_user() . '/' . $contact['id'], @@ -403,7 +443,8 @@ function connections_content(&$a) { '$updpub' => t('Update public posts'), '$last_update' => $last_update, '$udnow' => t('Update now'), -// '$profile_select' => contact_profile_assign($contact['profile_id'],(($contact['network'] !== NETWORK_DFRN) ? true : false)), + '$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') ), @@ -469,6 +510,7 @@ function connections_content(&$a) { $search_flags = ABOOK_FLAG_PENDING; $head = t('New'); $pending = true; + nav_set_selected('intros'); break; case 'all': @@ -582,26 +624,24 @@ function connections_content(&$a) { if(count($r)) { foreach($r as $rr) { - - $contacts[] = array( - 'img_hover' => sprintf( t('%1$s [%2$s]'),$rr['xchan_name'],$rr['xchan_url']), - 'edit_hover' => t('Edit contact'), - 'photo_menu' => contact_photo_menu($rr), - 'id' => $rr['abook_id'], - 'alt_text' => $alt_text, - 'dir_icon' => $dir_icon, - 'thumb' => $rr['xchan_photo_m'], - 'name' => $rr['xchan_name'], - 'username' => $rr['xchan_name'], - 'sparkle' => $sparkle, - 'edit' => z_root() . '/connections/' . $rr['abook_id'], - 'url' => $rr['xchan_url'], - 'network' => network_to_name($rr['network']), - ); + if($rr['xchan_url']) { + $contacts[] = array( + 'img_hover' => sprintf( t('%1$s [%2$s]'),$rr['xchan_name'],$rr['xchan_url']), + 'edit_hover' => t('Edit contact'), + 'photo_menu' => contact_photo_menu($rr), + 'id' => $rr['abook_id'], + 'alt_text' => $alt_text, + 'dir_icon' => $dir_icon, + 'thumb' => $rr['xchan_photo_m'], + 'name' => $rr['xchan_name'], + 'username' => $rr['xchan_name'], + 'sparkle' => $sparkle, + 'link' => z_root() . '/connections/' . $rr['abook_id'], + 'url' => $rr['xchan_url'], + 'network' => network_to_name($rr['network']), + ); + } } - - - } diff --git a/mod/crepair.php b/mod/crepair.php index e5ece0f98..f749fac0e 100644 --- a/mod/crepair.php +++ b/mod/crepair.php @@ -76,7 +76,7 @@ function crepair_post(&$a) { if($photo) { logger('mod-crepair: updating photo from ' . $photo); - require_once("Photo.php"); + require_once('include/photo/photo_driver.php'); $photos = import_profile_photo($photo,local_user(),$contact['id']); diff --git a/mod/directory.php b/mod/directory.php index 21fb14bfc..b7cdaffe7 100644 --- a/mod/directory.php +++ b/mod/directory.php @@ -4,7 +4,7 @@ require_once('include/dir_fns.php'); function directory_init(&$a) { - $a->set_pager_itemspage(60); + $a->set_pager_itemspage(80); } @@ -45,7 +45,7 @@ function directory_content(&$a) { $directory = find_upstream_directory($dirmode); if($directory) { - $url = $directory['url']; + $url = $directory['url'] . '/dirsearch'; } else { $url = DIRECTORY_FALLBACK_MASTER . '/dirsearch'; @@ -53,12 +53,30 @@ function directory_content(&$a) { } 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=' ; if($search) $query .= '&name=' . urlencode($search); if(strpos($search,'@')) $query .= '&address=' . urlencode($search); + + $sort_order = ((x($_REQUEST,'order')) ? $_REQUEST['order'] : ''); + if($sort_order) + $query .= '&order=' . urlencode($sort_order); if($a->pager['page'] != 1) $query .= '&p=' . $a->pager['page']; @@ -66,7 +84,7 @@ function directory_content(&$a) { logger('mod_directory: query: ' . $query); $x = z_fetch_url($query); - logger('directory: return from upstream: ' . print_r($x,true)); + logger('directory: return from upstream: ' . print_r($x,true), LOGGER_DATA); if($x['success']) { $t = 0; @@ -84,7 +102,11 @@ function directory_content(&$a) { $profile_link = chanlink_url($rr['url']); $pdesc = (($rr['description']) ? $rr['description'] . '<br />' : ''); - + $connect_link = ((local_user()) ? z_root() . '/follow?f=&url=' . urlencode($rr['address']) : ''); + + if(in_array($rr['hash'],$contacts)) + $connect_link = ''; + $details = ''; if(strlen($rr['locale'])) $details .= $rr['locale']; @@ -138,7 +160,8 @@ function directory_content(&$a) { 'marital' => $marital, 'homepage' => $homepage, 'about' => $about, - + 'conn_label' => t('Connect'), + 'connect' => $connect_link, ); $arr = array('contact' => $rr, 'entry' => $entry); @@ -146,14 +169,13 @@ function directory_content(&$a) { call_hooks('directory_item', $arr); $entries[] = $entry; - unset($profile); unset($location); } - logger('mod_directory: entries: ' . print_r($entries,true), LOGGER_DATA); +// logger('mod_directory: entries: ' . print_r($entries,true), LOGGER_DATA); $o .= replace_macros($tpl, array( '$search' => $search, @@ -166,7 +188,7 @@ function directory_content(&$a) { )); - $o .= alt_pager($a,$j['records'], t('more'), t('back')); + $o .= alt_pager($a,$j['records'], t('next page'), t('previous page')); } else { diff --git a/mod/dirsearch.php b/mod/dirsearch.php index 7e4323da9..6d6ef7434 100644 --- a/mod/dirsearch.php +++ b/mod/dirsearch.php @@ -22,15 +22,20 @@ function dirsearch_content(&$a) { json_return_and_die($ret); } - $name = ((x($_REQUEST,'name')) ? $_REQUEST['name'] : ''); - $address = ((x($_REQUEST,'address')) ? $_REQUEST['address'] : ''); - $locale = ((x($_REQUEST,'locale')) ? $_REQUEST['locale'] : ''); - $region = ((x($_REQUEST,'region')) ? $_REQUEST['region'] : ''); + $name = ((x($_REQUEST,'name')) ? $_REQUEST['name'] : ''); + $hub = ((x($_REQUEST,'hub')) ? $_REQUEST['hub'] : ''); + $address = ((x($_REQUEST,'address')) ? $_REQUEST['address'] : ''); + $locale = ((x($_REQUEST,'locale')) ? $_REQUEST['locale'] : ''); + $region = ((x($_REQUEST,'region')) ? $_REQUEST['region'] : ''); $postcode = ((x($_REQUEST,'postcode')) ? $_REQUEST['postcode'] : ''); - $country = ((x($_REQUEST,'country')) ? $_REQUEST['country'] : ''); - $gender = ((x($_REQUEST,'gender')) ? $_REQUEST['gender'] : ''); - $marital = ((x($_REQUEST,'marital')) ? $_REQUEST['marital'] : ''); + $country = ((x($_REQUEST,'country')) ? $_REQUEST['country'] : ''); + $gender = ((x($_REQUEST,'gender')) ? $_REQUEST['gender'] : ''); + $marital = ((x($_REQUEST,'marital')) ? $_REQUEST['marital'] : ''); $keywords = ((x($_REQUEST,'keywords')) ? $_REQUEST['keywords'] : ''); + $agege = ((x($_REQUEST,'agege')) ? intval($_REQUEST['agege']) : 0 ); + $agele = ((x($_REQUEST,'agele')) ? intval($_REQUEST['agele']) : 0 ); + + $sort_order = ((x($_REQUEST,'order')) ? $_REQUEST['order'] : ''); // TODO - a meta search which joins all of these things to one search string @@ -38,6 +43,8 @@ function dirsearch_content(&$a) { if($name) $sql_extra .= " OR xchan_name like '" . protect_sprintf( '%' . dbesc($name) . '%' ) . "' "; + if($hub) + $sql_extra .= " OR xchan_hash in (select hubloc_hash from hubloc where hubloc_host = '" . protect_sprintf(dbesc($hub)) . "') "; if($address) $sql_extra .= " OR xchan_addr like '" . protect_sprintf( '%' . dbesc($address) . '%' ) . "' "; if($city) @@ -55,12 +62,23 @@ function dirsearch_content(&$a) { if($keywords) $sql_extra .= " OR xprof_keywords like '" . protect_sprintf( '%' . dbesc($keywords) . '%' ) . "' "; - $perpage = (($_REQUEST['n']) ? $_REQUEST['n'] : 80); - $page = (($_REQUEST['p']) ? intval($_REQUEST['p'] - 1) : 0); - $startrec = (($page+1) * $perpage) - $perpage; - $limit = (($_REQUEST['limit']) ? intval($_REQUEST['limit']) : 0); + // we only support an age range currently. You must set both agege + // (greater than or equal) and agele (less than or equal) + + if($agele && $agege) { + $sql_extra .= " OR ( xprof_age <= " . intval($agele) . " "; + $sql_extra .= " AND xprof_age >= " . intval($agege) . ") "; + } + + $perpage = (($_REQUEST['n']) ? $_REQUEST['n'] : 80); + $page = (($_REQUEST['p']) ? intval($_REQUEST['p'] - 1) : 0); + $startrec = (($page+1) * $perpage) - $perpage; + $limit = (($_REQUEST['limit']) ? intval($_REQUEST['limit']) : 0); $return_total = ((x($_REQUEST,'return_total')) ? intval($_REQUEST['return_total']) : 0); + + $mtime = ((x($_REQUEST,'mtime')) ? datetime_convert('UTC','UTC',$_REQUEST['mtime']) : ''); + // ok a separate tag table won't work. // merge them into xprof @@ -86,9 +104,21 @@ function dirsearch_content(&$a) { } } - $order = " ORDER BY `xchan_name` ASC "; + if($mtime) { + $qlimit = ''; + $sql_extra .= " and xchan_hash in ( select ud_hash from updates where ud_date > '" . dbesc($mtime) . "' ) "; + } + + if($sort_order == 'date') + $order = " order by ud_date desc "; + elseif($sort_order == 'reverse') + $order = " order by xchan_name desc "; + else + $order = " order by xchan_name asc "; + - $r = q("SELECT xchan.*, xprof.* from xchan left join xprof on xchan_hash = xprof_hash where $logic $sql_extra and not ( xchan_flags & %d ) $order $qlimit ", + + $r = q("SELECT xchan.*, xprof.*, updates.* from xchan left join xprof on xchan_hash = xprof_hash left join updates on xchan_hash = ud_hash where $logic $sql_extra and not ( xchan_flags & %d ) $order $qlimit ", intval(XCHAN_FLAGS_HIDDEN) ); @@ -104,6 +134,9 @@ function dirsearch_content(&$a) { $entry = array(); $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['url'] = $rr['xchan_url']; $entry['photo'] = $rr['xchan_photo_m']; $entry['address'] = $rr['xchan_addr']; @@ -113,6 +146,7 @@ function dirsearch_content(&$a) { $entry['postcode'] = $rr['xprof_postcode']; $entry['country'] = $rr['xprof_country']; $entry['birthday'] = $rr['xprof_dob']; + $entry['age'] = $rr['xprof_age']; $entry['gender'] = $rr['xprof_gender']; $entry['marital'] = $rr['xprof_marital']; $entry['keywords'] = $rr['xprof_keywords']; diff --git a/mod/display.php b/mod/display.php index 3c2172c7d..110dd1807 100644 --- a/mod/display.php +++ b/mod/display.php @@ -3,6 +3,8 @@ function display_content(&$a, $update = 0, $load = false) { + logger("mod-display: update = $update load = $load"); + if(intval(get_config('system','block_public')) && (! local_user()) && (! remote_user())) { notice( t('Public access denied.') . EOL); return; @@ -20,8 +22,10 @@ function display_content(&$a, $update = 0, $load = false) { if(argc() > 1 && argv(1) !== 'load') $item_hash = argv(1); - if($_REQUEST['uri']) - $item_hash = $_REQUEST['uri']; + + + if($_REQUEST['mid']) + $item_hash = $_REQUEST['mid']; if(! $item_hash) { @@ -43,7 +47,7 @@ function display_content(&$a, $update = 0, $load = false) { $target_item = null; - $r = q("select uri, parent_uri from item where uri = '%s' limit 1", + $r = q("select mid, parent_mid from item where mid = '%s' limit 1", dbesc($item_hash) ); @@ -55,7 +59,7 @@ function display_content(&$a, $update = 0, $load = false) { $o .= '<div id="live-display"></div>' . "\r\n"; - $o .= "<script> var profile_uid = " . intval(local_user()) + $o .= "<script> var profile_uid = " . ((intval(local_user())) ? local_user() : (-1)) . "; var netargs = '?f='; var profile_page = " . $a->pager['page'] . "; </script>\r\n"; $a->page['htmlhead'] .= replace_macros(get_markup_template("build_query.tpl"),array( @@ -79,7 +83,7 @@ function display_content(&$a, $update = 0, $load = false) { '$cats' => '', '$dend' => '', '$dbegin' => '', - '$uri' => $item_hash + '$mid' => $item_hash )); @@ -90,20 +94,36 @@ function display_content(&$a, $update = 0, $load = false) { if($update && $load) { + $updateable = false; + $pager_sql = sprintf(" LIMIT %d, %d ",intval($a->pager['start']), intval($a->pager['itemspage'])); if($load) { - - $r = q("SELECT * from item - WHERE item_restrict = 0 - and uri = '%s' - AND ((( `item`.`allow_cid` = '' AND `item`.`allow_gid` = '' AND `item`.`deny_cid` = '' - AND `item`.`deny_gid` = '' AND item_private = 0 ) - and uid in ( " . stream_perms_api_uids() . " )) - $sql_extra ) - group by uri limit 1", - dbesc($target_item['parent_uri']) - ); + $r = null; + if(local_user()) { + $r = q("SELECT * from item + WHERE item_restrict = 0 + and uid = %d + and mid = '%s' + limit 1", + intval(local_user()), + dbesc($target_item['parent_mid']) + ); + if($r) + $updateable = true; + } + if($r === null) { + $r = q("SELECT * from item + WHERE item_restrict = 0 + and mid = '%s' + AND ((( `item`.`allow_cid` = '' AND `item`.`allow_gid` = '' AND `item`.`deny_cid` = '' + AND `item`.`deny_gid` = '' AND item_private = 0 ) + and uid in ( " . stream_perms_api_uids() . " )) + $sql_extra ) + group by mid limit 1", + dbesc($target_item['parent_mid']) + ); + } } else { @@ -131,14 +151,26 @@ function display_content(&$a, $update = 0, $load = false) { } - $o .= conversation($a,$items,'display', $update, 'client'); + + $o .= conversation($a, $items, 'display', $update, 'client'); + + if($updateable) { + $x = q("UPDATE item SET item_flags = ( item_flags ^ %d ) + WHERE (item_flags & %d) AND uid = %d and parent = %d ", + intval(ITEM_UNSEEN), + intval(ITEM_UNSEEN), + intval(local_user()), + intval($r[0]['parent']) + ); + } + return $o; /* elseif((! $update) && (! { - $r = q("SELECT `id`, item_flags FROM `item` WHERE `id` = '%s' OR `uri` = '%s' LIMIT 1", + $r = q("SELECT `id`, item_flags FROM `item` WHERE `id` = '%s' OR `mid` = '%s' LIMIT 1", dbesc($item_hash), dbesc($item_hash) ); diff --git a/mod/editpost.php b/mod/editpost.php index 43c71ca8a..583bae9eb 100644 --- a/mod/editpost.php +++ b/mod/editpost.php @@ -1,6 +1,7 @@ <?php require_once('acl_selectors.php'); +require_once('include/crypto.php'); function editpost_content(&$a) { @@ -18,13 +19,14 @@ function editpost_content(&$a) { return; } - $itm = q("SELECT * FROM `item` WHERE `id` = %d AND `uid` = %d LIMIT 1", + $itm = q("SELECT * FROM `item` WHERE `id` = %d AND `uid` = %d and author_xchan = '%s' LIMIT 1", intval($post_id), - intval(local_user()) + intval(local_user()), + dbesc(get_observer_hash()) ); if(! count($itm)) { - notice( t('Item not found') . EOL); + notice( t('Item is not editable') . EOL); return; } @@ -46,6 +48,15 @@ function editpost_content(&$a) { )); + + if($itm[0]['item_flags'] & ITEM_OBSCURED) { + $key = get_config('system','prvkey'); + if($itm[0]['title']) + $itm[0]['title'] = aes_unencapsulate(json_decode_plus($itm[0]['title']),$key); + if($itm[0]['body']) + $itm[0]['body'] = aes_unencapsulate(json_decode_plus($itm[0]['body']),$key); + } + $tpl = get_markup_template("jot.tpl"); $jotplugins = ''; @@ -82,9 +93,9 @@ function editpost_content(&$a) { '$pvisit' => 'none', '$public' => t('Public post'), '$jotnets' => $jotnets, - '$title' => $itm[0]['title'], + '$title' => htmlspecialchars($itm[0]['title']), '$placeholdertitle' => t('Set title'), - '$category' => file_tag_file_to_list($itm[0]['file'], 'category'), + '$category' => '', // FIXME '$placeholdercategory' => t('Categories (comma-separated list)'), '$emtitle' => t('Example: bob@example.com, mary@example.com'), '$lockstate' => $lockstate, diff --git a/mod/editwebpage.php b/mod/editwebpage.php new file mode 100644 index 000000000..c7323a7f7 --- /dev/null +++ b/mod/editwebpage.php @@ -0,0 +1,135 @@ + +<?php + +require_once('acl_selectors.php'); + +function editwebpage_content(&$a) { + +// We first need to figure out who owns the webpage, grab it from an argument + $which = argv(1); + +// $a->get_channel() and stuff don't work here, so we've got to find the owner for ourselves. + $owner = q("select channel_id from channel where channel_address = '%s'", + dbesc($which) + ); + + + if((local_user()) && (argc() > 2) && (argv(2) === 'view')) { + $which = $channel['channel_address']; + } + + + $o = ''; + + +// Figure out which post we're editing + $post_id = ((argc() > 2) ? intval(argv(2)) : 0); + + + if(! $post_id) { + notice( t('Item not found') . EOL); + return; + } + +// Now we've got a post and an owner, let's find out if we're allowed to edit it + + $observer = $a->get_observer(); + $ob_hash = (($observer) ? $observer['xchan_hash'] : ''); + + $perms = get_all_perms($owner,$ob_hash); + + if(! $perms['write_pages']) { + notice( t('Permission denied.') . EOL); + return; + } + + + +// We've already figured out which item we want and whose copy we need, so we don't need anything fancy here + $itm = q("SELECT * FROM `item` WHERE `id` = %d and uid = %s LIMIT 1", + intval($post_id), + intval($owner) + ); + + + + // All of the following is straight from editpost - but we'll need richer editing options for webpages eventually, so we may as well have it's own mod now. + + $plaintext = true; + if(feature_enabled(local_user(),'richtext')) + $plaintext = false; + + $o .= replace_macros(get_markup_template('edpost_head.tpl'), array( + '$title' => t('Edit post') + )); + + + $a->page['htmlhead'] .= replace_macros(get_markup_template('jot-header.tpl'), array( + '$baseurl' => $a->get_baseurl(), + '$editselect' => (($plaintext) ? 'none' : '/(profile-jot-text|prvmail-text)/'), + '$ispublic' => ' ', // t('Visible to <strong>everybody</strong>'), + '$geotag' => $geotag, + '$nickname' => $a->user['nickname'] + )); + + + $tpl = get_markup_template("jot.tpl"); + + $jotplugins = ''; + $jotnets = ''; + + call_hooks('jot_tool', $jotplugins); + call_hooks('jot_networks', $jotnets); + + $channel = $a->get_channel(); + + //$tpl = replace_macros($tpl,array('$jotplugins' => $jotplugins)); + +//FIXME A return path with $_SESSION doesn't work for observer (at least, not here it doesn't). It'll WSoD instead of loading a sensible page. So, send folk +//back to the channel address until somebody figures out how to fix it - we can't send them back to webpages, because that could leak private pages they can't see +//when ACL is done. + + $rp = 'channel' . '/' . $which; + + $o .= replace_macros($tpl,array( + '$return_path' => $rp, + '$action' => 'item', + '$share' => t('Edit'), + '$upload' => t('Upload photo'), + '$attach' => t('Attach file'), + '$weblink' => t('Insert web link'), + '$youtube' => t('Insert YouTube video'), + '$video' => t('Insert Vorbis [.ogg] video'), + '$audio' => t('Insert Vorbis [.ogg] audio'), + '$setloc' => t('Set your location'), + '$noloc' => t('Clear browser location'), + '$wait' => t('Please wait'), + '$permset' => t('Permission settings'), + '$ptyp' => $itm[0]['type'], + '$content' => undo_post_tagging($itm[0]['body']), + '$post_id' => $post_id, + '$baseurl' => $a->get_baseurl(), + '$defloc' => $channel['channel_location'], + '$visitor' => 'none', + '$pvisit' => 'none', + '$public' => t('Public post'), + '$jotnets' => $jotnets, + '$title' => htmlspecialchars($itm[0]['title']), + '$placeholdertitle' => t('Set title'), + '$category' => '', + '$placeholdercategory' => t('Categories (comma-separated list)'), + '$emtitle' => t('Example: bob@example.com, mary@example.com'), + '$lockstate' => $lockstate, + '$acl' => '', + '$bang' => '', + '$profile_uid' => (intval($owner)), + '$preview' => ((feature_enabled(local_user(),'preview')) ? t('Preview') : ''), + '$jotplugins' => $jotplugins, + '$sourceapp' => t($a->sourcename), + )); + + return $o; + +} + + diff --git a/mod/events.php b/mod/events.php index 8c509cfea..f43a99cba 100755 --- a/mod/events.php +++ b/mod/events.php @@ -135,6 +135,8 @@ function events_content(&$a) { return; } + nav_set_selected('all_events'); + if((argc() > 2) && (argv(1) === 'ignore') && intval(argv(2))) { $r = q("update event set ignore = 1 where id = %d and uid = %d limit 1", intval(argv(2)), @@ -229,9 +231,9 @@ function events_content(&$a) { $adjust_start = datetime_convert('UTC', date_default_timezone_get(), $start); $adjust_finish = datetime_convert('UTC', date_default_timezone_get(), $finish); - if (x($_GET,'id')){ - $r = q("SELECT * from event left join item on resource_id = event_hash where resource_type = 'event' and event.uid = %d and event.id = %d limit 1", + $r = q("SELECT event.*, item.plink, item.item_flags, item.author_xchan, item.owner_xchan + from event left join item on resource_id = event_hash where resource_type = 'event' and event.uid = %d and event.id = %d limit 1", intval(local_user()), intval($_GET['id']) ); @@ -242,8 +244,8 @@ function events_content(&$a) { // Noting this for now - it will need to be fixed here and in Friendica. // Ultimately the finish date shouldn't be involved in the query. - - $r = q("SELECT * from event left join item on event_hash = resource_id + $r = q("SELECT event.*, item.plink, item.item_flags, item.author_xchan, item.owner_xchan + from event left join item on event_hash = resource_id where resource_type = 'event' and event.uid = %d and event.ignore = %d AND (( `adjust` = 0 AND ( `finish` >= '%s' or nofinish ) AND `start` <= '%s' ) OR ( `adjust` = 1 AND ( `finish` >= '%s' or nofinish ) AND `start` <= '%s' )) ", @@ -339,6 +341,7 @@ function events_content(&$a) { else { $tpl = get_markup_template("events-js.tpl"); } + $o = replace_macros($tpl, array( '$baseurl' => $a->get_baseurl(), '$tabs' => $tabs, @@ -379,7 +382,7 @@ function events_content(&$a) { $l_orig = ((x($orig_event)) ? $orig_event['location'] : ''); $eid = ((x($orig_event)) ? $orig_event['id'] : 0); $event_xchan = ((x($orig_event)) ? $orig_event['event_xchan'] : $channel['channel_hash']); - $uri = ((x($orig_event)) ? $orig_event['uri'] : ''); + $mid = ((x($orig_event)) ? $orig_event['mid'] : ''); if(! x($orig_event)) $sh_checked = ''; @@ -427,7 +430,7 @@ function events_content(&$a) { '$post' => $a->get_baseurl() . '/events', '$eid' => $eid, '$xchan' => $event_xchan, - '$uri' => $uri, + '$mid' => $mid, '$title' => t('Event details'), '$desc' => sprintf( t('Format is %s %s. Starting date and Title are required.'),$dateformat,$timeformat), diff --git a/mod/fbrowser.php b/mod/fbrowser.php index d10d8021b..31004c0d8 100644 --- a/mod/fbrowser.php +++ b/mod/fbrowser.php @@ -5,7 +5,7 @@ * @author Fabio Comuni <fabrixxm@kirgroup.com> */ -require_once('include/Photo.php'); +require_once('include/photo/photo_driver.php'); /** * @param App $a diff --git a/mod/feed.php b/mod/feed.php index a6adc620e..104208875 100644 --- a/mod/feed.php +++ b/mod/feed.php @@ -13,7 +13,7 @@ function feed_init(&$a) { $channel = ''; if(argc() > 1) { - $r = q("select * from channel where channel_address = '%s' limit 1", + $r = q("select * from channel left join xchan on channel_hash = xchan_hash where channel_address = '%s' limit 1", dbesc(argv(1)) ); if(!($r && count($r))) @@ -21,11 +21,6 @@ function feed_init(&$a) { $channel = $r[0]; - // check site and channel permissions - - if(!($channel['channel_r_stream'] & PERMS_PUBLIC)) - killme(); - if((intval(get_config('system','block_public'))) && (! get_account_id())) killme(); diff --git a/mod/follow.php b/mod/follow.php index c07c210f6..d21c50df6 100644 --- a/mod/follow.php +++ b/mod/follow.php @@ -6,7 +6,6 @@ require_once('include/follow.php'); function follow_init(&$a) { if(! local_user()) { - notice( t('Permission denied.') . EOL); return; } @@ -22,8 +21,15 @@ function follow_init(&$a) { goaway($return_url); } - info( t('Channel added') . EOL); + info( t('Channel added.') . EOL); goaway(z_root() . '/connections/' . $result['abook']['abook_id']); } + +function follow_content(&$a) { + + if(! local_user()) { + return login(); + } +}
\ No newline at end of file diff --git a/mod/fsuggest.php b/mod/fsuggest.php index 9ef8f4c55..8b6f077d3 100644 --- a/mod/fsuggest.php +++ b/mod/fsuggest.php @@ -100,8 +100,9 @@ function fsuggest_content(&$a) { $o .= '<form id="fsuggest-form" action="fsuggest/' . $contact_id . '" method="post" >'; - $o .= contact_selector('suggest','suggest-select', false, - array('size' => 4, 'exclude' => $contact_id, 'networks' => 'DFRN_ONLY', 'single' => true)); +// FIXME contact_selector deprecated, removed +// $o .= contact_selector('suggest','suggest-select', false, +// array('size' => 4, 'exclude' => $contact_id, 'networks' => 'DFRN_ONLY', 'single' => true)); $o .= '<div id="fsuggest-submit-wrapper"><input id="fsuggest-submit" type="submit" name="submit" value="' . t('Submit') . '" /></div>'; diff --git a/mod/group.php b/mod/group.php index 778ecbded..c85cb2da3 100644 --- a/mod/group.php +++ b/mod/group.php @@ -143,12 +143,14 @@ function group_content(&$a) { } $group = $r[0]; + $members = group_get_members($group['id']); $preselected = array(); if(count($members)) { foreach($members as $member) - $preselected[] = $member['xchan_hash']; + if(! in_array($member['xchan_hash'],$preselected)) + $preselected[] = $member['xchan_hash']; } if($change) { diff --git a/mod/home.php b/mod/home.php index 1bb0148d2..86d489853 100644 --- a/mod/home.php +++ b/mod/home.php @@ -8,11 +8,16 @@ function home_init(&$a) { $channel = $a->get_channel(); - if(local_user() && $channel && $channel['xchan_url']) - goaway( $channel['xchan_url']); + if(local_user() && $channel && $channel['xchan_url']) { + $dest = get_pconfig(local_user(),'system','startpage'); + if(! $dest) + $dest = z_root() . '/network'; + + goaway($dest); + } if(get_account_id()) { - goaway('new_channel'); + goaway(z_root() . '/new_channel'); } }} @@ -28,15 +33,55 @@ function home_content(&$a) { if(x($_SESSION,'mobile-theme')) unset($_SESSION['mobile-theme']); - $o .= '<h1>' . ((x($a->config,'sitename')) ? sprintf( t("Welcome to %s") ,$a->config['sitename']) : "" ) . '</h1>'; +$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) + ); + + 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]); + +} + +// 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'); +} - $o .= login(($a->config['system']['register_policy'] == REGISTER_CLOSED) ? 0 : 1); + $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 f35ca149b..4c878f5c6 100644 --- a/mod/import.php +++ b/mod/import.php @@ -4,10 +4,14 @@ // connection to original server. require_once('include/Contact.php'); - +require_once('include/zot.php'); +require_once('include/identity.php'); function import_post(&$a) { + if(! get_account_id()) { + return; + } $data = null; $seize = ((x($_REQUEST,'make_primary')) ? intval($_REQUEST['make_primary']) : 0); @@ -22,6 +26,7 @@ function import_post(&$a) { if($filesize) { $data = @file_get_contents($src); } + unlink($src); } if(! $src) { @@ -39,7 +44,7 @@ function import_post(&$a) { $servername = substr($old_address,strpos($old_address,'@')+1); $scheme = 'https://'; - $api_path = '/api/export/basic?f=&channel=' . $channelname; + $api_path = '/api/red/channel/export/basic?f=&channel=' . $channelname; $binary = false; $redirects = 0; $opts = array('http_auth' => $email . ':' . $password); @@ -60,6 +65,7 @@ function import_post(&$a) { return; } + $data = json_decode($data,true); // logger('import: data: ' . print_r($data,true)); @@ -113,9 +119,11 @@ function import_post(&$a) { // reset $channel = $r[0]; + set_default_login_identity(get_account_id(),$channel['channel_id'],false); + if($data['photo']) { - require_once('include/Photo.php'); - import_channel_photo(base64url_decode($data['photo']['data']),$data['photo']['type'],get_account_id,$channel['channel_id']); + require_once('include/photo/photo_driver.php'); + import_channel_photo(base64url_decode($data['photo']['data']),$data['photo']['type'],get_account_id(),$channel['channel_id']); } $profiles = $data['profile']; @@ -217,7 +225,7 @@ function import_post(&$a) { . "')" ); - require_once("Photo.php"); + require_once('include/photo/photo_driver.php'); $photos = import_profile_photo($xchan['xchan_photo_l'],$xchan['xchan_hash']); $r = q("update xchan set xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s' where xchan_hash = '%s' limit 1", @@ -250,6 +258,63 @@ function import_post(&$a) { } } + + $configs = $data['config']; + if($configs) { + foreach($configs as $config) { + unset($config['id']); + $config['uid'] = $channel['channel_id']; + dbesc_array($config); + $r = dbq("INSERT INTO pconfig (`" + . implode("`, `", array_keys($config)) + . "`) VALUES ('" + . implode("', '", array_values($config)) + . "')" ); + } + } + + $groups = $data['group']; + if($groups) { + $saved = array(); + foreach($groups as $group) { + $saved[$group['hash']] = array('old' => $group['id']); + unset($group['id']); + $group['uid'] = $channel['channel_id']; + dbesc_array($group); + $r = dbq("INSERT INTO group (`" + . implode("`, `", array_keys($group)) + . "`) VALUES ('" + . implode("', '", array_values($group)) + . "')" ); + } + $r = q("select * from `group` where uid = %d", + intval($channel['channel_id']) + ); + if($r) { + foreach($r as $rr) { + $saved[$rr['hash']]['new'] = $rr['id']; + } + } + } + + $group_members = $data['group_member']; + if($groups_members) { + foreach($group_members as $group_member) { + unset($group_member['id']); + $group_member['uid'] = $channel['channel_id']; + foreach($saved as $x) { + if($x['old'] == $group_member['gid']) + $group_member['gid'] = $x['new']; + } + dbesc_array($group_member); + $r = dbq("INSERT INTO group_member (`" + . implode("`, `", array_keys($group_member)) + . "`) VALUES ('" + . implode("', '", array_values($group_member)) + . "')" ); + } + } + // FIXME - ensure we have a self entry if somebody is trying to pull a fast one if($seize) { @@ -261,11 +326,20 @@ function import_post(&$a) { notice( t('Import completed.') . EOL); + change_channel($channel['channel_id']); + + goaway(z_root() . '/network' ); + + } function import_content(&$a) { + if(! get_account_id()) { + notice( t('You must be logged in to use this feature.')); + return ''; + } $o = replace_macros(get_markup_template('channel_import.tpl'),array( '$title' => t('Import Channel'), @@ -284,4 +358,4 @@ function import_content(&$a) { return $o; -}
\ No newline at end of file +} diff --git a/mod/invite.php b/mod/invite.php index 336e20164..cb8cd1f63 100644 --- a/mod/invite.php +++ b/mod/invite.php @@ -68,9 +68,12 @@ function invite_post(&$a) { else $nmessage = $message; - $res = mail($recip, sprintf( t('Please join us on Friendica'), $a->config['sitename']), + $account = $a->get_account(); + + + $res = mail($recip, sprintf( t('Please join us on Red'), $a->config['sitename']), $nmessage, - "From: " . $a->user['email'] . "\n" + "From: " . $account['account_email'] . "\n" . 'Content-type: text/plain; charset=UTF-8' . "\n" . 'Content-transfer-encoding: 8bit' ); @@ -112,29 +115,41 @@ function invite_content(&$a) { } } - $dirloc = get_config('system','directory_submit_url'); - if(strlen($dirloc)) { - if($a->config['system']['register_policy'] == REGISTER_CLOSED) - $linktxt = sprintf( t('Visit %s for a list of public sites that you can join. Friendica members on other sites can all connect with each other, as well as with members of many other social networks.'), dirname($dirloc) . '/siteinfo'); - elseif($a->config['system']['register_policy'] != REGISTER_CLOSED) - $linktxt = sprintf( t('To accept this invitation, please visit and register at %s or any other public Friendica website.'), $a->get_baseurl()) - . "\r\n" . "\r\n" . sprintf( t('Friendica sites all inter-connect to create a huge privacy-enhanced social web that is owned and controlled by its members. They can also connect with many traditional social networks. See %s for a list of alternate Friendica sites you can join.'),dirname($dirloc) . '/siteinfo'); - } - else { - $o = t('Our apologies. This system is not currently configured to connect with other public sites or invite members.'); +// $dirloc = get_config('system','directory_submit_url'); +// if(strlen($dirloc)) { +// if($a->config['system']['register_policy'] == REGISTER_CLOSED) +// $linktxt = sprintf( t('Visit %s for a list of public sites that you can join. Friendica members on other sites can all connect with each other, as well as with members of many other social networks.'), dirname($dirloc) . '/siteinfo'); +// elseif($a->config['system']['register_policy'] != REGISTER_CLOSED) +// $linktxt = sprintf( t('To accept this invitation, please visit and register at %s or any other public Friendica website.'), $a->get_baseurl()) +// . "\r\n" . "\r\n" . sprintf( t('Friendica sites all inter-connect to create a huge privacy-enhanced social web that is owned and controlled by its members. They can also connect with many traditional social networks. See %s for a list of alternate Friendica sites you can join.'),dirname($dirloc) . '/siteinfo'); +// } +// else { +// $o = t('Our apologies. This system is not currently configured to connect with other public sites or invite members.'); +// return $o; +// } + + $ob = $a->get_observer(); + if(! $ob) return $o; - } + + $channel = $a->get_channel(); $o = replace_macros($tpl, array( '$form_security_token' => get_form_security_token("send_invite"), '$invite' => t('Send invitations'), '$addr_text' => t('Enter email addresses, one per line:'), '$msg_text' => t('Your message:'), - '$default_message' => t('You are cordially invited to join me and other close friends on Friendica - and help us to create a better social web.') . "\r\n" . "\r\n" + '$default_message' => t('You are cordially invited to join me and some other close friends on the Red Matrix - a revolutionary new decentralised social and information tool.') . "\r\n" . "\r\n" . $linktxt - . "\r\n" . "\r\n" . (($invonly) ? t('You will need to supply this invitation code: $invite_code') . "\r\n" . "\r\n" : '') .t('Once you have registered, please connect with me via my profile page at:') - . "\r\n" . "\r\n" . $a->get_baseurl() . '/channel/' . $a->user['nickname'] - . "\r\n" . "\r\n" . t('For more information about the Friendica project and why we feel it is important, please visit http://friendica.com') . "\r\n" . "\r\n" , + . (($invonly) ? "\r\n" . "\r\n" . t('You will need to supply this invitation code: $invite_code') . "\r\n" . "\r\n" : '') + + . t('Please visit my channel at') + . "\r\n" . "\r\n" + . z_root() . "/channel/" . $channel['channel_address'] + . "\r\n" . "\r\n" + . t('Once you have registered, please connect with my Red Matrix channel address:') + . "\r\n" . "\r\n" . $ob['xchan_addr'] + . "\r\n" . "\r\n" . t('For more information about the Red Matrix Project and why it has the potential to change the internet as we know it, please visit http://getzot.com') . "\r\n" . "\r\n" , '$submit' => t('Submit') )); diff --git a/mod/item.php b/mod/item.php index 8298d3dc0..dc8ee5015 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); @@ -60,6 +60,7 @@ function item_post(&$a) { $origin = (($api_source && array_key_exists('origin',$_REQUEST)) ? intval($_REQUEST['origin']) : 1); $owner_hash = null; + $message_id = ((x($_REQUEST,'message_id') && $api_source) ? strip_tags($_REQUEST['message_id']) : ''); $profile_uid = ((x($_REQUEST,'profile_uid')) ? intval($_REQUEST['profile_uid']) : 0); $post_id = ((x($_REQUEST,'post_id')) ? intval($_REQUEST['post_id']) : 0); @@ -80,7 +81,7 @@ function item_post(&$a) { */ $parent = ((x($_REQUEST,'parent')) ? intval($_REQUEST['parent']) : 0); - $parent_uri = ((x($_REQUEST,'parent_uri')) ? trim($_REQUEST['parent_uri']) : ''); + $parent_mid = ((x($_REQUEST,'parent_mid')) ? trim($_REQUEST['parent_mid']) : ''); $parent_item = null; $parent_contact = null; @@ -88,7 +89,7 @@ function item_post(&$a) { $parid = 0; $r = false; - if($parent || $parent_uri) { + if($parent || $parent_mid) { if(! x($_REQUEST,'type')) $_REQUEST['type'] = 'net-comment'; @@ -98,17 +99,17 @@ function item_post(&$a) { intval($parent) ); } - elseif($parent_uri && local_user()) { + elseif($parent_mid && local_user()) { // This is coming from an API source, and we are logged in - $r = q("SELECT * FROM `item` WHERE `uri` = '%s' AND `uid` = %d LIMIT 1", - dbesc($parent_uri), + $r = q("SELECT * FROM `item` WHERE `mid` = '%s' AND `uid` = %d LIMIT 1", + dbesc($parent_mid), intval(local_user()) ); } // if this isn't the real parent of the conversation, find it if($r !== false && count($r)) { $parid = $r[0]['parent']; - $parent_uri = $r[0]['uri']; + $parent_mid = $r[0]['mid']; if($r[0]['id'] != $r[0]['parent']) { $r = q("SELECT * FROM `item` WHERE `id` = `parent` AND `parent` = %d LIMIT 1", intval($parid) @@ -127,19 +128,22 @@ function item_post(&$a) { // multi-level threading - preserve the info but re-parent to our single level threading //if(($parid) && ($parid != $parent)) - $thr_parent = $parent_uri; + $thr_parent = $parent_mid; + +// if($parent_item['contact-id'] && $uid) { +// $r = q("SELECT * FROM `contact` WHERE `id` = %d AND `uid` = %d LIMIT 1", +// intval($parent_item['contact-id']), +// intval($uid) +// ); +// if(count($r)) +// $parent_contact = $r[0]; +// } - if($parent_item['contact-id'] && $uid) { - $r = q("SELECT * FROM `contact` WHERE `id` = %d AND `uid` = %d LIMIT 1", - intval($parent_item['contact-id']), - intval($uid) - ); - if(count($r)) - $parent_contact = $r[0]; - } } - if($parent) logger('mod_item: item_post parent=' . $parent); + if($parent) { + logger('mod_item: item_post parent=' . $parent); + } $observer = $a->get_observer(); @@ -200,6 +204,10 @@ function item_post(&$a) { goaway($a->get_baseurl() . "/" . $return_path ); killme(); } + + if($observer) { + logger('mod_item: post accepted from ' . $observer['xchan_name'] . ' for ' . $owner_xchan['xchan_name'], LOGGER_DEBUG); + } if($orig_post) { @@ -242,10 +250,10 @@ function item_post(&$a) { $str_contact_deny = perms2str($_REQUEST['contact_deny']); } - $title = escape_tags(trim($_REQUEST['title'])); $location = notags(trim($_REQUEST['location'])); $coord = notags(trim($_REQUEST['coord'])); $verb = notags(trim($_REQUEST['verb'])); + $title = escape_tags(trim($_REQUEST['title'])); $body = escape_tags(trim($_REQUEST['body'])); $private = ( @@ -291,13 +299,25 @@ function item_post(&$a) { // expire_quantity, e.g. '3' // expire_units, e.g. days, weeks, months if(x($_REQUEST,'expire_quantity') && (x($_REQUEST,'expire_units'))) { - $expire = datetime_convert(date_default_timezone_get(),'UTC', 'now + ' . $_REQUEST['expire_quantity'] . ' ' . $_REQUEST['expire_units']); + $expire = datetime_convert('UTC','UTC', 'now + ' . $_REQUEST['expire_quantity'] . ' ' . $_REQUEST['expire_units']); if($expires <= datetime_convert()) $expires = '0000-00-00 00:00:00'; } } + + $post_type = notags(trim($_REQUEST['type'])); + + $content_type = notags(trim($_REQUEST['content_type'])); + if(! $content_type) + $content_type = 'text/bbcode'; + + +// BBCODE alert: the following functions assume bbcode input +// and will require alternatives for alternative content-types (text/html, text/markdown, text/plain, etc.) +// we may need virtual or template classes to implement the possible alternatives + // Work around doubled linefeeds in Tinymce 3.5b2 // First figure out if it's a status post that would've been // created using tinymce. Otherwise leave it alone. @@ -307,60 +327,23 @@ function item_post(&$a) { $body = fix_mce_lf($body); } + // If we're sending a private top-level message with a single @-taggable channel as a recipient, @-tag it. - // get contact info for poster - - -/* - $author = null; - $self = false; - $contact_id = 0; - - if((local_user()) && (local_user() == $profile_uid)) { - $self = true; - $r = q("SELECT * FROM `contact` WHERE `uid` = %d AND `self` = 1 LIMIT 1", - intval($_SESSION['uid']) - ); - } - elseif(remote_user()) { - if(is_array($_SESSION['remote'])) { - foreach($_SESSION['remote'] as $v) { - if($v['uid'] == $profile_uid) { - $contact_id = $v['cid']; - break; - } - } - } - if($contact_id) { - $r = q("SELECT * FROM `contact` WHERE `id` = %d LIMIT 1", - intval($contact_id) - ); - } - } - - if(count($r)) { - // FIXME - $author = $r[0]; - $contact_id = $author['id']; - } - - // get contact info for owner - - if($profile_uid == local_user()) { - $contact_record = $author; - } - else { - $r = q("SELECT * FROM `contact` WHERE `uid` = %d AND `self` = 1 LIMIT 1", + if((! $parent) && (substr_count($str_contact_allow,'<') == 1) && ($str_group_allow == '') && ($str_contact_deny == '') && ($str_group_deny == '')) { + $x = q("select abook_id, abook_their_perms from abook where abook_xchan = '%s' and abook_channel = %d limit 1", + dbesc(str_replace(array('<','>'),array('',''),$str_contact_allow)), intval($profile_uid) ); - if(count($r)) - $contact_record = $r[0]; + if($x && ($x[0]['abook_their_perms'] & PERMS_W_TAGWALL)) + $body .= "\n\n@group+" . $x[0]['abook_id'] . "\n"; } -*/ - - $post_type = notags(trim($_REQUEST['type'])); + /** + * 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 + */ + $body = preg_replace_callback("/([^\]\='".'"'."]|^)(https?\:\/\/[a-zA-Z0-9\:\/\-\?\&\;\.\=\@\_\~\#\%\$\!\+\,]+)/ism", 'red_zrl_callback', $body); /** * @@ -445,18 +428,6 @@ function item_post(&$a) { } } - if(strlen($categories)) { - $cats = explode(',',$categories); - foreach($cats as $cat) { - $post_tags[] = array( - 'uid' => $profile_uid, - 'type' => TERM_CATEGORY, - 'otype' => TERM_OBJ_POST, - 'term' => trim($cat), - 'url' => '' - ); - } - } // logger('post_tags: ' . print_r($post_tags,true)); @@ -489,6 +460,23 @@ function item_post(&$a) { } } +// BBCODE end alert + + + if(strlen($categories)) { + $cats = explode(',',$categories); + foreach($cats as $cat) { + $post_tags[] = array( + 'uid' => $profile_uid, + 'type' => TERM_CATEGORY, + 'otype' => TERM_OBJ_POST, + 'term' => trim($cat), + 'url' => '' + ); + } + } + + $item_flags = ITEM_UNSEEN; $item_restrict = ITEM_VISIBLE; @@ -504,7 +492,6 @@ function item_post(&$a) { if($webpage) $item_restrict = $item_restrict | ITEM_WEBPAGE; - if(! strlen($verb)) @@ -512,20 +499,21 @@ function item_post(&$a) { $notify_type = (($parent) ? 'comment-new' : 'wall-new' ); - $uri = item_message_id(); - $parent_uri = $uri; + $mid = (($message_id) ? $message_id : item_message_id()); + + $parent_mid = $mid; if($parent_item) - $parent_uri = $parent_item['uri']; + $parent_mid = $parent_item['mid']; // Fallback so that we alway have a thr_parent if(!$thr_parent) - $thr_parent = $uri; + $thr_parent = $mid; $datarray = array(); if(! $parent) { - $datarray['parent_uri'] = $uri; + $datarray['parent_mid'] = $mid; $item_flags = $item_flags | ITEM_THREAD_TOP; } @@ -540,8 +528,9 @@ function item_post(&$a) { $datarray['commented'] = datetime_convert(); $datarray['received'] = datetime_convert(); $datarray['changed'] = datetime_convert(); - $datarray['uri'] = $uri; - $datarray['parent_uri'] = $parent_uri; + $datarray['mid'] = $mid; + $datarray['parent_mid'] = $parent_mid; + $datarray['mimetype'] = $content_type; $datarray['title'] = $title; $datarray['body'] = $body; $datarray['app'] = $app; @@ -560,6 +549,7 @@ function item_post(&$a) { $datarray['item_restrict'] = $item_restrict; $datarray['item_flags'] = $item_flags; + $datarray['comment_policy'] = map_scope($channel['channel_w_comment']); // preview mode - prepare the body for display and send it via json @@ -573,6 +563,8 @@ function item_post(&$a) { echo json_encode(array('preview' => $o)); killme(); } + if($orig_post) + $datarray['edit'] = true; call_hooks('post_local',$datarray); @@ -591,6 +583,22 @@ function item_post(&$a) { } + if(mb_strlen($datarray['title']) > 255) + $datarray['title'] = mb_substr($datarray['title'],0,255); + + if(array_key_exists('item_private',$datarray) && $datarray['item_private']) { + logger('Encrypting local storage'); + $key = get_config('system','pubkey'); + $datarray['item_flags'] = $datarray['item_flags'] | ITEM_OBSCURED; + if($datarray['title']) + $datarray['title'] = json_encode(aes_encapsulate($datarray['title'],$key)); + if($datarray['body']) + $datarray['body'] = json_encode(aes_encapsulate($datarray['body'],$key)); + } + + + + if($orig_post) { $r = q("UPDATE `item` SET `title` = '%s', `body` = '%s', `attach` = '%s', `edited` = '%s' WHERE `id` = %d AND `uid` = %d LIMIT 1", dbesc($datarray['title']), @@ -613,6 +621,23 @@ function item_post(&$a) { ); + if(count($post_tags)) { + foreach($post_tags as $tag) { + if(strlen(trim($tag['term']))) { + q("insert into term (uid,oid,otype,type,term,url) values (%d,%d,%d,%d,'%s','%s')", + intval($tag['uid']), + intval($post_id), + intval($tag['otype']), + intval($tag['type']), + dbesc(trim($tag['term'])), + dbesc(trim($tag['url'])) + ); + } + } + } + + + proc_run('php', "include/notifier.php", 'edit_post', $post_id); if((x($_REQUEST,'return')) && strlen($return_path)) { logger('return: ' . $return_path); @@ -659,7 +684,7 @@ function item_post(&$a) { dbesc($parent_item['allow_gid']), dbesc($parent_item['deny_cid']), dbesc($parent_item['deny_gid']), - intval($parent_item['private']), + intval($parent_item['item_private']), intval($post_id) ); @@ -669,11 +694,11 @@ function item_post(&$a) { 'from_xchan' => $datarray['author_xchan'], 'to_xchan' => $datarray['owner_xchan'], 'item' => $datarray, - 'link' => $a->get_baseurl() . '/display/' . $datarray['uri'], + 'link' => $a->get_baseurl() . '/display/' . $datarray['mid'], 'verb' => ACTIVITY_POST, 'otype' => 'item', 'parent' => $parent, - 'parent_uri' => $parent_item['uri'] + 'parent_mid' => $parent_item['mid'] )); } @@ -688,7 +713,7 @@ function item_post(&$a) { 'from_xchan' => $datarray['author_xchan'], 'to_xchan' => $datarray['owner_xchan'], 'item' => $datarray, - 'link' => $a->get_baseurl() . '/display/' . $datarray['uri'], + 'link' => $a->get_baseurl() . '/display/' . $datarray['mid'], 'verb' => ACTIVITY_POST, 'otype' => 'item' )); @@ -700,10 +725,10 @@ function item_post(&$a) { if(! $parent) $parent = $post_id; - $r = q("UPDATE `item` SET `parent` = %d, `parent_uri` = '%s', `changed` = '%s' + $r = q("UPDATE `item` SET `parent` = %d, `parent_mid` = '%s', `changed` = '%s' WHERE `id` = %d LIMIT 1", intval($parent), - dbesc(($parent == $post_id) ? $uri : $parent_item['uri']), + dbesc(($parent == $post_id) ? $mid : $parent_item['mid']), dbesc(datetime_convert()), intval($post_id) ); @@ -741,14 +766,14 @@ function item_post(&$a) { // 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 uri - which makes the link portable and not quite as daunting - // as the entire uri. If it were the post_id the link would be less portable. + // 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. // We should have the ability to edit this and arrange pages into menus via the pages module 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($uri,0,16)), + dbesc(($pagetitle) ? $pagetitle : substr($mid,0,16)), dbesc('WEBPAGE') ); } @@ -822,18 +847,26 @@ function handle_tag($a, &$body, &$inform, &$str_tags, $profile_uid, $tag) { //is it a hash tag? if(strpos($tag,'#') === 0) { //if the tag is replaced... - if(strpos($tag,'[url=')) + if(strpos($tag,'[zrl=')) //...do nothing return $replaced; - //base tag has the tags name only - $basetag = str_replace('_',' ',substr($tag,1)); - //create text for link - $url = $a->get_baseurl() . '/search?tag=' . rawurlencode($basetag); - $newtag = '#[url=' . $a->get_baseurl() . '/search?tag=' . rawurlencode($basetag) . ']' . $basetag . '[/url]'; - //replace tag by the link - $body = str_replace($tag, $newtag, $body); - $replaced = true; - + if($tag == '#getzot') { + $basetag = 'getzot'; + $url = 'http://getzot.com'; + $newtag = '#[zrl=' . $url . ']' . $basetag . '[/zrl]'; + $body = str_replace($tag,$newtag,$body); + $replace = true; + } + else { + //base tag has the tags name only + $basetag = str_replace('_',' ',substr($tag,1)); + //create text for link + $url = $a->get_baseurl() . '/search?tag=' . rawurlencode($basetag); + $newtag = '#[zrl=' . $a->get_baseurl() . '/search?tag=' . rawurlencode($basetag) . ']' . $basetag . '[/zrl]'; + //replace tag by the link + $body = str_replace($tag, $newtag, $body); + $replaced = true; + } //is the link already in str_tags? if(! stristr($str_tags,$newtag)) { //append or set str_tags @@ -846,7 +879,7 @@ function handle_tag($a, &$body, &$inform, &$str_tags, $profile_uid, $tag) { //is it a person tag? if(strpos($tag,'@') === 0) { //is it already replaced? - if(strpos($tag,'[url=')) + if(strpos($tag,'[zrl=')) return $replaced; $stat = false; //get the person's name @@ -942,7 +975,7 @@ function handle_tag($a, &$body, &$inform, &$str_tags, $profile_uid, $tag) { //create profile link $profile = str_replace(',','%2c',$profile); $url = $profile; - $newtag = '@[url=' . $profile . ']' . $newname . '[/url]'; + $newtag = '@[zrl=' . $profile . ']' . $newname . '[/zrl]'; $body = str_replace('@' . $name, $newtag, $body); //append tag to str_tags if(! stristr($str_tags,$newtag)) { @@ -962,8 +995,8 @@ function fix_attached_photo_permissions($uid,$xchan_hash,$body, $str_contact_allow,$str_group_allow,$str_contact_deny,$str_group_deny) { $match = null; - - if(preg_match_all("/\[img\](.*?)\[\/img\]/",$body,$match)) { + // match img and zmg image links + if(preg_match_all("/\[[zi]mg\](.*?)\[\/[zi]mg\]/",$body,$match)) { $images = $match[1]; if($images) { foreach($images as $image) { diff --git a/mod/like.php b/mod/like.php index 7c3df98ba..f617391a1 100755 --- a/mod/like.php +++ b/mod/like.php @@ -49,6 +49,7 @@ function like_content(&$a) { $item = $r[0]; $owner_uid = $item['uid']; + $owner_aid = $item['aid']; if(! perm_is_allowed($owner_uid,$observer['xchan_hash'],'post_comments')) { notice( t('Permission denied') . EOL); @@ -78,7 +79,7 @@ function like_content(&$a) { dbesc($activity), dbesc($observer['xchan_hash']), intval($item_id), - dbesc($item['uri']) + dbesc($item['mid']) ); if($r) { $like_item = $r[0]; @@ -97,22 +98,23 @@ function like_content(&$a) { - $uri = item_message_id(); + $mid = item_message_id(); $post_type = (($item['resource_type'] === 'photo') ? $t('photo') : t('status')); - $links = array(array('rel' => 'alternate','type' => 'text/html', - 'href' => z_root() . '/display/' . $item['uri'])); + $links = array(array('rel' => 'alternate','type' => 'text/html', 'href' => $item['plink'])); $objtype = (($item['resource_type'] === 'photo') ? ACTIVITY_OBJ_PHOTO : ACTIVITY_OBJ_NOTE ); $body = $item['body']; $obj = json_encode(array( 'type' => $objtype, - 'id' => $item['uri'], + 'id' => $item['mid'], 'link' => $links, 'title' => $item['title'], 'content' => $item['body'], + 'created' => $item['created'], + 'edited' => $item['edited'], 'author' => array( 'name' => $item_author['xchan_name'], 'address' => $item_author['xchan_addr'], @@ -124,6 +126,9 @@ function like_content(&$a) { ), )); + if(! ($item['item_flags'] & ITEM_THREAD_TOP)) + $post_type = 'comment'; + if($verb === 'like') $bodyverb = t('%1$s likes %2$s\'s %3$s'); if($verb === 'dislike') @@ -132,28 +137,29 @@ function like_content(&$a) { if(! isset($bodyverb)) return; - $item_flags = ITEM_ORIGIN; + $item_flags = ITEM_ORIGIN | ITEM_NOTSHOWN; if($item['item_flags'] & ITEM_WALL) $item_flags |= ITEM_WALL; $arr = array(); - $arr['uri'] = $uri; + $arr['mid'] = $mid; + $arr['aid'] = $owner_aid; $arr['uid'] = $owner_uid; $arr['item_flags'] = $item_flags; $arr['parent'] = $item['id']; - $arr['parent_uri'] = $item['uri']; - $arr['thr_parent'] = $item['uri']; + $arr['parent_mid'] = $item['mid']; + $arr['thr_parent'] = $item['mid']; $arr['owner_xchan'] = $thread_owner['xchan_hash']; $arr['author_xchan'] = $observer['xchan_hash']; - $ulink = '[url=' . $item_owner['xchan_url'] . ']' . $item_owner['xchan_name'] . '[/url]'; - $alink = '[url=' . $observer['xchan_url'] . ']' . $observer['xchan_name'] . '[/url]'; - $plink = '[url=' . $a->get_baseurl() . '/display/' . $item['uri'] . ']' . $post_type . '[/url]'; + $ulink = '[zrl=' . $item_author['xchan_url'] . ']' . $item_author['xchan_name'] . '[/zrl]'; + $alink = '[zrl=' . $observer['xchan_url'] . ']' . $observer['xchan_name'] . '[/zrl]'; + $plink = '[zrl=' . $a->get_baseurl() . '/display/' . $item['mid'] . ']' . $post_type . '[/zrl]'; - $arr['body'] = sprintf( $bodyverb, $ulink, $alink, $plink ); + $arr['body'] = sprintf( $bodyverb, $alink, $ulink, $plink ); $arr['verb'] = $activity; $arr['obj_type'] = $objtype; diff --git a/mod/lockview.php b/mod/lockview.php index 01a6997ee..7dda85623 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 `group` 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 `group` 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 ba9e69a49..09a2e8a51 100644 --- a/mod/magic.php +++ b/mod/magic.php @@ -7,17 +7,18 @@ function magic_init(&$a) { $addr = ((x($_REQUEST,'addr')) ? $_REQUEST['addr'] : ''); $hash = ((x($_REQUEST,'hash')) ? $_REQUEST['hash'] : ''); $dest = ((x($_REQUEST,'dest')) ? $_REQUEST['dest'] : ''); + $rev = ((x($_REQUEST,'rev')) ? intval($_REQUEST['rev']) : 0); if($hash) { $x = q("select xchan.xchan_url, hubloc.* from xchan left join hubloc on xchan_hash = hubloc_hash - where hubloc_hash = '%s' and (hubloc_flags & %d) limit 1", + where hubloc_hash = '%s' and (hubloc_flags & %d) order by hubloc_id desc limit 1", dbesc($hash), intval(HUBLOC_FLAGS_PRIMARY) ); } elseif($addr) { $x = q("select hubloc.* from xchan left join hubloc on xchan_hash = hubloc_hash - where xchan_addr = '%s' and (hubloc_flags & %d) limit 1", + where xchan_addr = '%s' and (hubloc_flags & %d) order by hubloc_id desc limit 1", dbesc($addr), intval(HUBLOC_FLAGS_PRIMARY) ); @@ -25,17 +26,16 @@ function magic_init(&$a) { else { // See if we know anybody at the dest site that will unlock the door for us $b = explode('/',$dest); - if(count($b) >= 2) - $u = $b[0] . '//' . $b[2]; - - $x = q("select xchan.xchan_url, hubloc.* from xchan left join hubloc on xchan_hash = hubloc_hash - where hubloc_url = '%s' limit 1", - dbesc($u) - ); + if(count($b) >= 2) { + $u = $b[0] . '//' . $b[2]; + $x = q("select xchan.xchan_url, hubloc.* from xchan left join hubloc on xchan_hash = hubloc_hash + where hubloc_url = '%s' order by hubloc_id desc limit 1", + dbesc($u) + ); + } } - if(! $x) { // Finger them if they've never been seen here before @@ -47,7 +47,7 @@ function magic_init(&$a) { if($j) import_xchan($j); $x = q("select hubloc.* from xchan left join hubloc on xchan_hash = hubloc_hash - where xchan_addr = '%s' and (hubloc_flags & %d) limit 1", + where xchan_addr = '%s' and (hubloc_flags & %d) order by hubloc_id desc limit 1", dbesc($addr), intval(HUBLOC_FLAGS_PRIMARY) ); @@ -56,10 +56,30 @@ function magic_init(&$a) { } if(! $x) { - notice( t('Channel not found.') . EOL); - return; + if($rev) + goaway($dest); + else { + logger('mod_magic: channel not found.' . print_r($_REQUEST,true)); + notice( t('Channel not found.') . EOL); + return; + } } + // This is ready-made for a plugin that provides a blacklist or "ask me" before blindly authenticating. + // By default, we'll proceed without asking. + + $arr = array( + 'channel_id' => local_user(), + 'xchan' => $x[0], + 'destination' => $dest, + 'proceed' => true + ); + + call_hooks('magic_auth',$arr); + $dest = $arr['destination']; + if(! $arr['proceed']) + goaway($dest); + if($x[0]['hubloc_url'] === z_root()) { $webbie = substr($x[0]['hubloc_addr'],0,strpos('@',$x[0]['hubloc_addr'])); switch($dest) { @@ -105,7 +125,7 @@ function magic_init(&$a) { goaway($x[0]['hubloc_callback'] . '/' . substr($x[0]['hubloc_addr'],0,strpos($x[0]['hubloc_addr'],'@')) . '/?f=&auth=' . $channel['channel_address'] . '@' . $a->get_hostname() - . '&sec=' . $token . '&dest=' . $dest . '&version=' . ZOT_REVISION); + . '&sec=' . $token . '&dest=' . urlencode($dest) . '&version=' . ZOT_REVISION); } if(strpos($dest,'/')) diff --git a/mod/message.php b/mod/message.php index 98a1067ed..9c6cf75a6 100644 --- a/mod/message.php +++ b/mod/message.php @@ -9,13 +9,20 @@ require_once('include/Contact.php'); function message_aside(&$a) { - $a->set_widget('newmessage',replace_macros(get_markup_template('message_side.tpl'), array( + $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'), ) + ))); } @@ -41,7 +48,7 @@ function message_post(&$a) { $ret = zot_finger($rstr,$channel); - if(! $ret) { + if(! $ret['success']) { notice( t('Unable to lookup recipient.') . EOL); return; } @@ -160,9 +167,10 @@ function item_redir_and_replace_images($body, $images, $cid) { $newbody = ''; for($i = 0; $i < count($images); $i++) { - $search = '/\[url\=(.*?)\]\[!#saved_image' . $i . '#!\]\[\/url\]' . '/is'; - $replace = '[url=' . z_path() . '/redir/' . $cid - . '?f=1&url=' . '$1' . '][!#saved_image' . $i . '#!][/url]' ; + $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); @@ -198,6 +206,7 @@ function message_content(&$a) { } $channel = $a->get_channel(); + head_set_icon($channel['xchan_photo_s']); $tpl = get_markup_template('mail_head.tpl'); $header = replace_macros($tpl, array( @@ -392,7 +401,7 @@ function message_content(&$a) { // 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_uri'] . '" />'; + $parent = '<input type="hidden" name="replyto" value="' . $message['parent_mid'] . '" />'; $tpl = get_markup_template('mail_display.tpl'); $o = replace_macros($tpl, array( diff --git a/mod/mood.php b/mod/mood.php index 98064beab..7b6a0c392 100755 --- a/mod/mood.php +++ b/mod/mood.php @@ -30,15 +30,15 @@ function mood_init(&$a) { if($parent) { - $r = q("select uri, owner_xchan, private, allow_cid, allow_gid, deny_cid, deny_gid + $r = q("select mid, owner_xchan, private, allow_cid, allow_gid, deny_cid, deny_gid from item where id = %d and parent = %d and uid = %d limit 1", intval($parent), intval($parent), intval($uid) ); if(count($r)) { - $parent_uri = $r[0]['uri']; - $private = $r[0]['private']; + $parent_mid = $r[0]['mid']; + $private = $r[0]['item_private']; $allow_cid = $r[0]['allow_cid']; $allow_gid = $r[0]['allow_gid']; $deny_cid = $r[0]['deny_cid']; @@ -58,11 +58,11 @@ function mood_init(&$a) { $poster = $a->get_observer(); - $uri = item_message_id(); + $mid = item_message_id(); - $action = sprintf( t('%1$s is currently %2$s'), '[url=' . $poster['xchan_url'] . ']' . $poster['xchan_name'] . '[/url]' , $verbs[$verb]); + $action = sprintf( t('%1$s is currently %2$s'), '[zrl=' . $poster['xchan_url'] . ']' . $poster['xchan_name'] . '[/zrl]' , $verbs[$verb]); $item_flags = ITEM_WALL|ITEM_ORIGIN|ITEM_UNSEEN; - if(! $parent_uri) + if(! $parent_mid) $item_flags |= ITEM_THREAD_TOP; @@ -70,16 +70,17 @@ function mood_init(&$a) { $arr['aid'] = get_account_id(); $arr['uid'] = $uid; - $arr['uri'] = $uri; - $arr['parent_uri'] = (($parent_uri) ? $parent_uri : $uri); + $arr['mid'] = $mid; + $arr['parent_mid'] = (($parent_mid) ? $parent_mid : $mid); $arr['item_flags'] = $item_flags; $arr['author_xchan'] = $poster['xchan_hash']; - $arr['owner_xchan'] = (($parent_uri) ? $r[0]['owner_xchan'] : $poster['xchan_hash']); + $arr['owner_xchan'] = (($parent_mid) ? $r[0]['owner_xchan'] : $poster['xchan_hash']); $arr['title'] = ''; $arr['allow_cid'] = $allow_cid; $arr['allow_gid'] = $allow_gid; $arr['deny_cid'] = $deny_cid; $arr['deny_gid'] = $deny_gid; + $arr['item_private'] = $private; $arr['verb'] = $activity; $arr['body'] = $action; diff --git a/mod/network.php b/mod/network.php index dae9fa6be..413990ce2 100644 --- a/mod/network.php +++ b/mod/network.php @@ -7,6 +7,10 @@ function network_init(&$a) { notice( t('Permission denied.') . EOL); return; } + + $channel = $a->get_channel(); + $a->profile_uid = local_user(); + head_set_icon($channel['xchan_photo_s']); $is_a_date_query = false; @@ -369,7 +373,7 @@ function network_content(&$a, $update = 0, $load = false) { if(feature_enabled(local_user(),'affinity')) { $tpl = get_markup_template('main_slider.tpl'); - $o .= replace_macros($tpl,array( + $x = replace_macros($tpl,array( '$val' => intval($cmin) . ';' . intval($cmax), '$refresh' => t('Refresh'), '$me' => t('Me'), @@ -380,6 +384,9 @@ function network_content(&$a, $update = 0, $load = false) { '$acquaintances' => t('Acquaintances'), '$world' => t('Everybody') )); + $arr = array('html' => $x); + call_hooks('main_slider',$arr); + $o .= $arr['html']; } $arr = array('tabs' => $tabs); @@ -400,7 +407,7 @@ function network_content(&$a, $update = 0, $load = false) { $x = array( 'is_owner' => true, - 'allow_location' => $a->user['allow_location'], // FIXME + 'allow_location' => ((intval(get_pconfig($channel['channel_id'],'system','use_browser_location'))) ? '1' : ''), 'default_location' => $channel['channel_location'], 'nickname' => $channel['channel_address'], 'lockstate' => (($group || $cid || $channel['channel_allow_cid'] || $channel['channel_allow_gid'] || $channel['channel_deny_cid'] || $channel['channel_deny_gid']) ? 'lock' : 'unlock'), @@ -430,11 +437,11 @@ function network_content(&$a, $update = 0, $load = false) { $sql_extra = " AND `item`.`parent` IN ( SELECT `parent` FROM `item` WHERE (item_flags & " . intval(ITEM_THREAD_TOP) . ") $sql_options ) "; if($group) { - $r = q("SELECT `name`, `id` FROM `group` WHERE `id` = %d AND `uid` = %d LIMIT 1", - intval($group), - intval($_SESSION['uid']) - ); - if(! count($r)) { + $r = q("SELECT * FROM `group` WHERE id = %d AND uid = %d LIMIT 1", + intval($group), + intval(local_user()) + ); + if(! $r) { if($update) killme(); notice( t('No such group') . EOL ); @@ -442,33 +449,33 @@ function network_content(&$a, $update = 0, $load = false) { // NOTREACHED } - $contacts = expand_groups(array($group)); - if((is_array($contacts)) && count($contacts)) { - $contact_str = implode(',',$contacts); - } - else { - $contact_str = ' 0 '; - info( t('Group is empty')); - } + $contacts = expand_groups(array($arr['group'])); + if((is_array($contacts)) && count($contacts)) { + $contact_str = implode(',',$contacts); + } + else { + $contact_str = ' 0 '; + info( t('Group is empty')); + } + + $sql_extra = " AND item.parent IN ( SELECT DISTINCT parent FROM item WHERE true $sql_options AND ( author_xchan IN ( $contact_str ) OR owner_xchan in ( $contact_str) or allow_gid like '" . protect_sprintf('%<' . dbesc($r[0]['hash']) . '>%') . "' ) and item_restrict = 0 ) "; + + } - $sql_extra = " AND `item`.`parent` IN ( SELECT DISTINCT(`parent`) FROM `item` WHERE 1 $sql_options AND ( `contact-id` IN ( $contact_str ) OR `allow_gid` like '" . protect_sprintf('%<' . intval($group) . '>%') . "' ) and deleted = 0 ) "; - $o = '<h2>' . t('Group: ') . $r[0]['name'] . '</h2>' . $o; - } elseif($cid) { - $r = q("SELECT `id`,`name`,`network`,`writable`,`nurl` FROM `contact` WHERE `id` = %d - AND `blocked` = 0 AND `pending` = 0 LIMIT 1", - intval($cid) - ); - if(count($r)) { - $sql_extra = " AND `item`.`parent` IN ( SELECT DISTINCT(`parent`) FROM `item` WHERE 1 $sql_options AND `contact-id` = " . intval($cid) . " and deleted = 0 ) "; + $r = q("SELECT * from abook where abook_id = %d and abook_channel = %d and not ( abook_flags & " . intval(ABOOK_FLAG_BLOCKED) . ") limit 1", + intval($cid), + intval(local_user()) + ); + if($r) { + $sql_extra = " AND item.parent IN ( SELECT DISTINCT parent FROM item WHERE true $sql_options AND uid = " . intval(local_user()) . " AND ( author_xchan = '" . dbesc($r[0]['abook_xchan']) . "' or owner_xchan = '" . dbesc($r[0]['abook_xchan']) . "' ) and item_restrict = 0 ) "; $o = '<h2>' . t('Contact: ') . $r[0]['name'] . '</h2>' . $o; - } - else { + } + else { notice( t('Invalid contact.') . EOL); goaway($a->get_baseurl(true) . '/network'); - // NOTREACHED - } + } } @@ -515,7 +522,7 @@ function network_content(&$a, $update = 0, $load = false) { '$file' => $file, '$cats' => '', '$dend' => $datequery, - '$uri' => '', + '$mid' => '', '$dbegin' => $datequery2 )); } @@ -713,6 +720,8 @@ function network_content(&$a, $update = 0, $load = false) { $o .= alt_pager($a,count($items)); if($load) { + logger('mod_network: load: ' . count($items) . ' items', LOGGER_DATA); + profiler($start,$first,'network parents'); profiler($first,$second,'network children'); profiler($second,$third,'network authors'); diff --git a/mod/nogroup.php b/mod/nogroup.php index bd1ec82ed..31ccaadbf 100644 --- a/mod/nogroup.php +++ b/mod/nogroup.php @@ -48,7 +48,7 @@ function nogroup_content(&$a) { 'username' => $rr['name'], 'sparkle' => $sparkle, 'itemurl' => $rr['url'], - 'url' => $url, + 'link' => $url, 'network' => network_to_name($rr['network']), ); } diff --git a/mod/notifications.php b/mod/notifications.php index 7d861037c..397ed272b 100644 --- a/mod/notifications.php +++ b/mod/notifications.php @@ -70,30 +70,31 @@ function notifications_content(&$a) { nav_set_selected('notifications'); $o = ''; + $tabs = array( array( 'label' => t('System'), 'url'=>$a->get_baseurl(true) . '/notifications/system', 'sel'=> (($a->argv[1] == 'system') ? 'active' : ''), ), - array( - 'label' => t('Network'), - 'url'=>$a->get_baseurl(true) . '/notifications/network', - 'sel'=> (($a->argv[1] == 'network') ? 'active' : ''), - ), +// array( +// 'label' => t('Network'), +// 'url'=>$a->get_baseurl(true) . '/notifications/network', +// 'sel'=> (($a->argv[1] == 'network') ? 'active' : ''), +// ), array( 'label' => t('Personal'), 'url'=>$a->get_baseurl(true) . '/notifications/personal', 'sel'=> (($a->argv[1] == 'personal') ? 'active' : ''), ), - array( - 'label' => t('Home'), - 'url' => $a->get_baseurl(true) . '/notifications/home', - 'sel'=> (($a->argv[1] == 'home') ? 'active' : ''), - ), +// array( +// 'label' => t('Home'), +// 'url' => $a->get_baseurl(true) . '/notifications/home', +// 'sel'=> (($a->argv[1] == 'home') ? 'active' : ''), +// ), array( 'label' => t('Introductions'), - 'url' => $a->get_baseurl(true) . '/notifications/intros', + 'url' => $a->get_baseurl(true) . '/connections/pending', 'sel'=> (($a->argv[1] == 'intros') ? 'active' : ''), ), array( @@ -105,6 +106,7 @@ function notifications_content(&$a) { $o = ""; +//Disabled if( (($a->argc > 1) && ($a->argv[1] == 'intros')) || (($a->argc == 1))) { nav_set_selected('introductions'); @@ -221,7 +223,9 @@ function notifications_content(&$a) { $o .= paginate($a); return $o; - } else if (($a->argc > 1) && ($a->argv[1] == 'network')) { + } + + elseif (($a->argc > 1) && ($a->argv[1] == 'network')) { $notif_tpl = get_markup_template('notifications.tpl'); @@ -428,11 +432,7 @@ function notifications_content(&$a) { '$tabs' => $tabs, '$notif_content' => $notif_content, )); - - - - - + } else if (($a->argc > 1) && ($a->argv[1] == 'home')) { diff --git a/mod/oembed.php b/mod/oembed.php index 720a6d72b..adda63cf2 100644 --- a/mod/oembed.php +++ b/mod/oembed.php @@ -19,7 +19,7 @@ function oembed_init(&$a){ else { echo "<html><body>"; - $url = base64url_decode($argv(1)); + $url = base64url_decode(argv(1)); $j = oembed_fetch_url($url); echo $j->html; // logger('mod-oembed ' . $j->html, LOGGER_ALL); diff --git a/mod/oexchange.php b/mod/oexchange.php index 791a493ff..63b48751c 100644 --- a/mod/oexchange.php +++ b/mod/oexchange.php @@ -32,18 +32,19 @@ function oexchange_content(&$a) { $tags = (((x($_REQUEST,'tags')) && strlen($_REQUEST['tags'])) ? '&tags=' . urlencode(notags(trim($_REQUEST['tags']))) : ''); - $s = fetch_url($a->get_baseurl() . '/parse_url?f=&url=' . $url . $title . $description . $tags); + $ret = z_fetch_url($a->get_baseurl() . '/parse_url?f=&url=' . $url . $title . $description . $tags); + + if($ret['success']) + $s = $ret['body']; if(! strlen($s)) return; - require_once('include/html2bbcode.php'); - $post = array(); $post['profile_uid'] = local_user(); $post['return'] = '/oexchange/done' ; - $post['body'] = html2bbcode($s); + $post['body'] = $s; $post['type'] = 'wall'; $_REQUEST = $post; diff --git a/mod/page.php b/mod/page.php index 62f9d9204..51b292f37 100644 --- a/mod/page.php +++ b/mod/page.php @@ -2,9 +2,37 @@ require_once('include/items.php'); require_once('include/conversation.php'); +function page_init(&$a) { + // We need this to make sure the channel theme is always loaded. + $which = argv(1); + $profile = 0; + $channel = $a->get_channel(); + + if((local_user()) && (argc() > 2) && (argv(2) === 'view')) { + $which = $channel['channel_address']; + $profile = argv(1); + } + + profile_load($a,$which,$profile); + +} + + + function page_content(&$a) { + $observer = $a->get_observer(); + $ob_hash = (($observer) ? $observer['xchan_hash'] : ''); + + $perms = get_all_perms($a->profile['profile_uid'],$ob_hash); + + if(! $perms['view_pages']) { + notice( t('Permission denied.') . EOL); + return; + } + + if(argc() < 3) { notice( t('Invalid item.') . EOL); return; @@ -41,4 +69,4 @@ function page_content(&$a) { $o .= prepare_page($r[0]); return $o; -}
\ No newline at end of file +} diff --git a/mod/parse_url.php b/mod/parse_url.php index 600d3dc8b..c206c24ec 100644 --- a/mod/parse_url.php +++ b/mod/parse_url.php @@ -55,34 +55,18 @@ function completeurl($url, $scheme) { function parseurl_getsiteinfo($url) { $siteinfo = array(); - $ch = curl_init(); - curl_setopt($ch, CURLOPT_URL, $url); - curl_setopt($ch, CURLOPT_HEADER, 1); - curl_setopt($ch, CURLOPT_NOBODY, 0); - curl_setopt($ch, CURLOPT_TIMEOUT, 3); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - curl_setopt($ch,CURLOPT_USERAGENT,'Opera/9.64(Windows NT 5.1; U; de) Presto/2.1.1'); - - $header = curl_exec($ch); - curl_close($ch); - - // Fetch the first mentioned charset. Can be in body or header - if (preg_match('/charset=(.*?)['."'".'"\s\n]/', $header, $matches)) - $charset = trim(array_pop($matches)); - else - $charset = "utf-8"; - $pos = strpos($header, "\r\n\r\n"); + $result = z_fetch_url($url,false,0,array('novalidate' => true)); + if(! $result['success']) + return $siteinfo; - if ($pos) - $body = trim(substr($header, $pos)); - else - $body = $header; + $header = $result['header']; + $body = $result['body']; - $body = mb_convert_encoding($body, "UTF-8", $charset); - $body = mb_convert_encoding($body, 'HTML-ENTITIES', "UTF-8"); + $body = mb_convert_encoding($body, 'UTF-8', 'UTF-8'); + $body = mb_convert_encoding($body, 'HTML-ENTITIES', "UTF-8"); - $doc = new DOMDocument(); + $doc = new DOMDocument(); @$doc->loadHTML($body); deletenode($doc, 'style'); @@ -115,6 +99,9 @@ function parseurl_getsiteinfo($url) { $attr["content"] = html_entity_decode($attr["content"], ENT_QUOTES, "UTF-8"); switch (strtolower($attr["name"])) { + case 'generator': + $siteinfo['generator'] = $attr['content']; + break; case "fulltitle": $siteinfo["title"] = $attr["content"]; break; @@ -245,6 +232,10 @@ function parse_url_content(&$a) { else $url = trim($_GET['url']); + if((substr($url,0,1) != '/') && (substr($url,0,4) != 'http')) + $url = 'http://' . $url; + + if($_GET['title']) $title = strip_tags(trim($_GET['title'])); @@ -290,6 +281,11 @@ function parse_url_content(&$a) { $siteinfo = parseurl_getsiteinfo($url); + // If this is a Red site, use zrl rather than url so they get zids sent to them by default + + if( x($siteinfo,'generator') && (strpos($siteinfo['generator'],RED_PLATFORM . ' ') === 0)) + $template = str_replace('url','zrl',$template); + if($siteinfo["title"] == "") { echo sprintf($template,$url,$url,'') . $str_tags; killme(); diff --git a/mod/photo.php b/mod/photo.php index aff4dc895..fffc15e53 100644 --- a/mod/photo.php +++ b/mod/photo.php @@ -1,7 +1,7 @@ <?php require_once('include/security.php'); -require_once('include/Photo.php'); +require_once('include/photo/photo_driver.php'); function photo_init(&$a) { @@ -118,7 +118,10 @@ function photo_init(&$a) { intval($resolution) ); if($r) { - $data = file_get_contents('images/nosign.jpg'); + logger('mod_photo: forbidden. ' . $a->query_string()); + $observer = $a->get_observer(); + logger('mod_photo: observer = ' . (($observer) ? $observer['xchan_addr'] : '(not authenticated)')); + $data = file_get_contents('images/nosign.png'); $mimetype = 'image/jpeg'; $prvcachecontrol = true; } @@ -151,7 +154,7 @@ function photo_init(&$a) { } if(isset($res) && intval($res) && $res < 500) { - $ph = new Photo($data, $mimetype); + $ph = photo_factory($data, $mimetype); if($ph->is_valid()) { $ph->scaleImageSquare($res); $data = $ph->imageString(); diff --git a/mod/photos.php b/mod/photos.php index 90b2990aa..789e26949 100644 --- a/mod/photos.php +++ b/mod/photos.php @@ -1,5 +1,5 @@ <?php -require_once('include/Photo.php'); +require_once('include/photo/photo_driver.php'); require_once('include/photos.php'); require_once('include/items.php'); require_once('include/acl_selectors.php'); @@ -59,7 +59,9 @@ function photos_post(&$a) { logger('mod_photos: REQUEST ' . print_r($_REQUEST,true), LOGGER_DATA); logger('mod_photos: FILES ' . print_r($_FILES,true), LOGGER_DATA); - $phototypes = Photo::supportedTypes(); + $ph = photo_factory(''); + + $phototypes = $ph->supportedTypes(); $can_post = false; @@ -187,10 +189,10 @@ function photos_post(&$a) { intval($page_owner_uid) ); if(count($i)) { - q("UPDATE `item` SET `deleted` = 1, `edited` = '%s', `changed` = '%s' WHERE `parent_uri` = '%s' AND `uid` = %d", + q("UPDATE `item` SET `deleted` = 1, `edited` = '%s', `changed` = '%s' WHERE `parent_mid` = '%s' AND `uid` = %d", dbesc(datetime_convert()), dbesc(datetime_convert()), - dbesc($i[0]['uri']), + dbesc($i[0]['mid']), intval($page_owner_uid) ); @@ -233,7 +235,7 @@ function photos_post(&$a) { intval($page_owner_uid) ); if(count($r)) { - $ph = new Photo($r[0]['data'], $r[0]['type']); + $ph = photo_factory($r[0]['data'], $r[0]['type']); if($ph->is_valid()) { $rotate_deg = ( (intval($_POST['rotate']) == 1) ? 270 : 90 ); $ph->rotate($rotate_deg); @@ -280,9 +282,11 @@ function photos_post(&$a) { } } - $p = q("SELECT * FROM `photo` WHERE `resource_id` = '%s' AND `uid` = %d ORDER BY `scale` DESC", + $p = q("SELECT * FROM `photo` WHERE `resource_id` = '%s' AND `uid` = %d and ( photo_flags = %d or photo_flags = %d ) ORDER BY `scale` DESC", dbesc($resource_id), - intval($page_owner_uid) + intval($page_owner_uid), + intval(PHOTO_NORMAL), + intval(PHOTO_PROFILE) ); if(count($p)) { $ext = $phototypes[$p[0]['type']]; @@ -413,13 +417,13 @@ function photos_post(&$a) { } if($profile) { if(substr($notify,0,4) === 'cid:') - $taginfo[] = array($newname,$profile,$notify,$r[0],'@[url=' . str_replace(',','%2c',$profile) . ']' . $newname . '[/url]'); + $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 .= '@[url=' . $profile . ']' . $newname . '[/url]'; + $str_tags .= '@[zrl=' . $profile . ']' . $newname . '[/zrl]'; } } } @@ -459,13 +463,13 @@ function photos_post(&$a) { if(count($taginfo)) { foreach($taginfo as $tagged) { - $uri = item_message_id(); + $mid = item_message_id(); $arr = array(); $arr['uid'] = $page_owner_uid; - $arr['uri'] = $uri; - $arr['parent_uri'] = $uri; + $arr['mid'] = $mid; + $arr['parent_mid'] = $mid; $arr['type'] = 'activity'; $arr['wall'] = 1; $arr['contact-id'] = $owner_record['id']; @@ -487,9 +491,9 @@ function photos_post(&$a) { $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'), '[url=' . $tagged[1] . ']' . $tagged[0] . '[/url]', '[url=' . $a->get_baseurl() . '/photos/' . $owner_record['nickname'] . '/image/' . $p[0]['resource-id'] . ']' . t('a photo') . '[/url]', '[url=' . $owner_record['url'] . ']' . $owner_record['name'] . '[/url]') ; + $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" . '[url=' . $a->get_baseurl() . '/photos/' . $owner_record['nickname'] . '/image/' . $p[0]['resource_id'] . ']' . '[img]' . $a->get_baseurl() . "/photo/" . $p[0]['resource_id'] . '-' . $best . '.' . $ext . '[/img][/url]' . "\n" ; + $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"); @@ -565,7 +569,8 @@ function photos_content(&$a) { return; } - $phototypes = Photo::supportedTypes(); + $ph = photo_factory(''); + $phototypes = $ph->supportedTypes(); $_SESSION['photo_return'] = $a->cmd; @@ -604,57 +609,8 @@ function photos_content(&$a) { if((local_user()) && (local_user() == $owner_uid)) $can_post = true; - else { - if($community_page && remote_user()) { - if(is_array($_SESSION['remote'])) { - foreach($_SESSION['remote'] as $v) { - if($v['uid'] == $owner_uid) { - $contact_id = $v['cid']; - break; - } - } - } - if($contact_id) { - - $r = q("SELECT `uid` FROM `contact` WHERE `blocked` = 0 AND `pending` = 0 AND `id` = %d AND `uid` = %d LIMIT 1", - intval($contact_id), - intval($owner_uid) - ); - if(count($r)) { - $can_post = true; - $contact = $r[0]; - $remote_contact = true; - $visitor = $cid; - } - } - } - } - - // perhaps they're visiting - but not a community page, so they wouldn't have write access - - if(remote_user() && (! $visitor)) { - $contact_id = 0; - if(is_array($_SESSION['remote'])) { - foreach($_SESSION['remote'] as $v) { - if($v['uid'] == $owner_uid) { - $contact_id = $v['cid']; - break; - } - } - } - if($contact_id) { - $groups = init_groups_visitor($contact_id); - $r = q("SELECT * FROM `contact` WHERE `blocked` = 0 AND `pending` = 0 AND `id` = %d AND `uid` = %d LIMIT 1", - intval($contact_id), - intval($owner_uid) - ); - if(count($r)) { - $contact = $r[0]; - $remote_contact = true; - } - } - } +// FIXME if(! $remote_contact) { if(local_user()) { $contact_id = $_SESSION['cid']; @@ -679,6 +635,9 @@ function photos_content(&$a) { // dispatch request // + /** + * Display upload form + */ if($datatype === 'upload') { if(! ($can_post)) { @@ -686,20 +645,16 @@ function photos_content(&$a) { return; } - $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(($album['album'] === '') || ($album['album'] === 'Contact Photos') || ($album['album'] === t('Contact Photos'))) + if($album['text'] === '') continue; - $selected = (($selname === $album['album']) ? ' selected="selected" ' : ''); - $albumselect .= '<option value="' . $album['album'] . '"' . $selected . '>' . $album['album'] . '</option>'; + $selected = (($selname === $album['text']) ? ' selected="selected" ' : ''); + $albumselect .= '<option value="' . $album['text'] . '"' . $selected . '>' . $album['text'] . '</option>'; } } @@ -719,6 +674,7 @@ function photos_content(&$a) { $default_upload = '<input id="photos-upload-choose" type="file" name="userfile" /> <div class="photos-upload-submit-wrapper" > <input type="submit" name="submit" value="' . t('Submit') . '" id="photos-upload-submit" /> </div>'; + /* Show space usage */ $r = q("select sum(size) as total from photo where uid = %d and scale = 0 ", intval($a->data['channel']['channel_id']) @@ -733,15 +689,8 @@ function photos_content(&$a) { $usage_message = sprintf( t('You have used %1$.2f Mbytes of photo storage.'), $r[0]['total'] / 1024000 ); } - - if($a->get_template_engine() === 'internal') { - $albumselect_e = template_escape($albumselect); - $aclselect_e = (($visitor) ? '' : template_escape(populate_acl($a->user, $celeb))); - } - else { - $albumselect_e = $albumselect; - $aclselect_e = (($visitor) ? '' : populate_acl($a->user, $celeb)); - } + $albumselect_e = $albumselect; + $aclselect_e = (($visitor) ? '' : populate_acl($a->user, $celeb)); $tpl = get_markup_template('photos_upload.tpl'); $o .= replace_macros($tpl,array( @@ -764,18 +713,24 @@ function photos_content(&$a) { return $o; } + /* + * Display a single photo album + */ + if($datatype === 'album') { $album = hex2bin($datum); $r = q("SELECT `resource_id`, max(`scale`) AS `scale` FROM `photo` WHERE `uid` = %d AND `album` = '%s' - AND `scale` <= 4 $sql_extra GROUP BY `resource_id`", + AND `scale` <= 4 and (photo_flags = %d or photo_flags = %d ) $sql_extra GROUP BY `resource_id`", intval($owner_uid), - dbesc($album) + dbesc($album), + intval(PHOTO_NORMAL), + intval(PHOTO_PROFILE) ); if(count($r)) { $a->set_pager_total(count($r)); - $a->set_pager_itemspage(20); + $a->set_pager_itemspage(40); } if($_GET['order'] === 'posted') @@ -784,9 +739,11 @@ function photos_content(&$a) { $order = 'DESC'; $r = q("SELECT `resource_id`, `id`, `filename`, type, max(`scale`) AS `scale`, `desc` FROM `photo` WHERE `uid` = %d AND `album` = '%s' - AND `scale` <= 4 $sql_extra GROUP BY `resource_id` ORDER BY `created` $order LIMIT %d , %d", + 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), + intvaL(PHOTO_NORMAL), + intval(PHOTO_PROFILE), intval($a->pager['start']), intval($a->pager['itemspage']) ); @@ -835,11 +792,11 @@ function photos_content(&$a) { $o .= '<div class="photos-upload-link" ><a href="' . $a->get_baseurl() . '/photos/' . $a->data['channel']['channel_address'] . '/upload/' . bin2hex($album) . '" >' . t('Upload New Photos') . '</a></div>'; } - $tpl = get_markup_template('photo_album.tpl'); if(count($r)) $twist = 'rotright'; foreach($r as $rr) { + if($twist == 'rotright') $twist = 'rotleft'; else @@ -856,15 +813,26 @@ function photos_content(&$a) { $desc_e = $rr['desc']; } + + 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'], '$twist' => ' ' . $twist . rand(2,4), - '$photolink' => $a->get_baseurl() . '/photos/' . $a->data['channel']['channel_address'] . '/image/' . $rr['resource_id'] - . (($_GET['order'] === 'posted') ? '?f=&order=posted' : ''), + '$photolink' => $imagelink, + '$rel' => $rel, '$phototitle' => t('View Photo'), '$imgsrc' => $a->get_baseurl() . '/photo/' . $rr['resource_id'] . '-' . $rr['scale'] . '.' .$ext, '$imgalt' => $imgalt_e, - '$desc'=> $desc_e + '$desc'=> $desc_e, )); } @@ -875,27 +843,36 @@ function photos_content(&$a) { } + /** + * Display one photo + */ if($datatype === 'image') { - - - //$o = ''; // fetch image, item containing image, then comments $ph = q("SELECT * FROM `photo` WHERE `uid` = %d AND `resource_id` = '%s' - $sql_extra ORDER BY `scale` ASC ", + and (photo_flags = %d or photo_flags = %d ) $sql_extra ORDER BY `scale` ASC ", intval($owner_uid), - dbesc($datum) + dbesc($datum), + intval(PHOTO_NORMAL), + intval(PHOTO_PROFILE) + ); - if(! count($ph)) { + if(! $ph) { + + /* Check again - this time without specifying permissions */ + $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), - dbesc($datum) + dbesc($datum), + intval(PHOTO_NORMAL), + intval(PHOTO_PROFILE) ); - if(count($ph)) + if($ph) notice( t('Permission denied. Access to this item may be restricted.')); else notice( t('Photo not available') . EOL ); @@ -912,9 +889,11 @@ function photos_content(&$a) { $prvnxt = q("SELECT `resource_id` FROM `photo` WHERE `album` = '%s' AND `uid` = %d AND `scale` = 0 - $sql_extra ORDER BY `created` $order ", + and ( photo_flags = %d or photo_flags = %d ) $sql_extra ORDER BY `created` $order ", dbesc($ph[0]['album']), - intval($owner_uid) + intval($owner_uid), + intval(PHOTO_NORMAL), + intval(PHOTO_PROFILE) ); if(count($prvnxt)) { @@ -929,9 +908,9 @@ function photos_content(&$a) { break; } } - $edit_suffix = ((($cmd === 'edit') && ($can_post)) ? '/edit' : ''); - $prevlink = $a->get_baseurl() . '/photos/' . $a->data['channel']['channel_address'] . '/image/' . $prvnxt[$prv]['resource_id'] . $edit_suffix . (($_GET['order'] === 'posted') ? '?f=&order=posted' : ''); - $nextlink = $a->get_baseurl() . '/photos/' . $a->data['channel']['channel_address'] . '/image/' . $prvnxt[$nxt]['resource_id'] . $edit_suffix . (($_GET['order'] === 'posted') ? '?f=&order=posted' : ''); + + $prevlink = $a->get_baseurl() . '/photos/' . $a->data['channel']['channel_address'] . '/image/' . $prvnxt[$prv]['resource_id'] . (($_GET['order'] === 'posted') ? '?f=&order=posted' : ''); + $nextlink = $a->get_baseurl() . '/photos/' . $a->data['channel']['channel_address'] . '/image/' . $prvnxt[$nxt]['resource_id'] . (($_GET['order'] === 'posted') ? '?f=&order=posted' : ''); } @@ -954,7 +933,6 @@ function photos_content(&$a) { if($can_post && ($ph[0]['uid'] == $owner_uid)) { $tools = array( - 'edit' => array($a->get_baseurl() . '/photos/' . $a->data['channel']['channel_address'] . '/image/' . $datum . (($cmd === 'edit') ? '' : '/edit'), (($cmd === 'edit') ? t('View photo') : t('Edit photo'))), 'profile'=>array($a->get_baseurl() . '/profile_photo/use/'.$ph[0]['resource_id'], t('Use as profile photo')), ); @@ -967,7 +945,7 @@ function photos_content(&$a) { } - if(! $cmd !== 'edit') { + if(! $can_post) { $a->page['htmlhead'] .= '<script> $(document).keydown(function(event) {' . "\n"; @@ -993,105 +971,66 @@ function photos_content(&$a) { // Do we have an item for this photo? - $linked_items = q("SELECT * FROM `item` WHERE `resource_id` = '%s' $sql_extra LIMIT 1", + $linked_items = q("SELECT * FROM item WHERE resource_id = '%s' and resource_type = 'photo' + $sql_extra LIMIT 1", dbesc($datum) ); - if(count($linked_items)) { + if($linked_items) { + $link_item = $linked_items[0]; - $r = q("SELECT COUNT(*) AS `total` - FROM `item` LEFT JOIN `contact` ON `contact`.`id` = `item`.`contact-id` - WHERE `parent_uri` = '%s' AND `uri` != '%s' AND `item`.`deleted` = 0 and `item`.`moderated` = 0 - AND `contact`.`blocked` = 0 AND `contact`.`pending` = 0 - AND `item`.`uid` = %d - $sql_extra ", - dbesc($link_item['uri']), - dbesc($link_item['uri']), + + $r = q("select * from item where parent_mid = '%s' and mid != '%s' + and item_restrict = 0 and uid = %d $sql_extra ", + dbesc($link_item['mid']), + dbesc($link_item['mid']), intval($link_item['uid']) ); - if(count($r)) - $a->set_pager_total($r[0]['total']); - - - $r = q("SELECT `item`.*, `item`.`id` AS `item_id`, - `contact`.`name`, `contact`.`photo`, `contact`.`url`, `contact`.`network`, - `contact`.`rel`, `contact`.`thumb`, `contact`.`self`, - `contact`.`id` AS `cid`, `contact`.`uid` AS `contact-uid` - FROM `item` LEFT JOIN `contact` ON `contact`.`id` = `item`.`contact-id` - WHERE `parent_uri` = '%s' AND `uri` != '%s' AND `item`.`deleted` = 0 and `item`.`moderated` = 0 - AND `contact`.`blocked` = 0 AND `contact`.`pending` = 0 - AND `item`.`uid` = %d - $sql_extra - ORDER BY `parent` DESC, `id` ASC LIMIT %d ,%d ", - dbesc($link_item['uri']), - dbesc($link_item['uri']), - intval($link_item['uid']), - intval($a->pager['start']), - intval($a->pager['itemspage']) + if($r) { + xchan_query($r); + $r = fetch_post_tags($r,true); + $r = conv_sort($r,'commented'); + } - ); - if((local_user()) && (local_user() == $link_item['uid'])) { - q("UPDATE `item` SET `unseen` = 0 WHERE `parent` = %d and `uid` = %d", + q("UPDATE `item` SET item_flags = (item_flags ^ %d) WHERE parent = %d and uid = %d and (item_flags & %d)", + intval(ITEM_UNSEEN), intval($link_item['parent']), - intval(local_user()) + intval(local_user()), + intval(ITEM_UNSEEN) ); } } - $tags=Null; - - if(count($linked_items) && strlen($link_item['tag'])) { - $arr = explode(',',$link_item['tag']); - // parse tags and add links - $tag_str = ''; - foreach($arr as $t) { - if(strlen($tag_str)) - $tag_str .= ', '; - $tag_str .= bbcode($t); - } - $tags = array(t('Tags: '), $tag_str); - if($cmd === 'edit') { - $tags[] = $a->get_baseurl() . '/tagrm/' . $link_item['id']; - $tags[] = t('[Remove any tag]'); - } - } - - $edit = Null; - if(($cmd === 'edit') && ($can_post)) { - if($a->get_template_engine() === 'internal') { - $album_e = template_escape($ph[0]['album']); - $caption_e = template_escape($ph[0]['desc']); - $aclselect_e = template_escape(populate_acl($ph[0])); - } - else { - $album_e = $ph[0]['album']; - $caption_e = $ph[0]['desc']; - $aclselect_e = populate_acl($ph[0]); - } + $edit = null; + if($can_post) { - $edit_tpl = get_markup_template('photo_edit.tpl'); - $edit = replace_macros($edit_tpl, array( - '$id' => $ph[0]['id'], - '$rotatecw' => t('Rotate CW (right)'), - '$rotateccw' => t('Rotate CCW (left)'), - '$album' => $album_e, - '$newalbum' => t('New album name'), - '$nickname' => $a->data['channel']['channel_address'], - '$resource_id' => $ph[0]['resource_id'], - '$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'), - '$item_id' => ((count($linked_items)) ? $link_item['id'] : 0), - '$submit' => t('Submit'), - '$delete' => t('Delete Photo') - )); + $album_e = $ph[0]['album']; + $caption_e = $ph[0]['desc']; + $aclselect_e = populate_acl($ph[0]); + + $edit = array( + 'edit' => t('Edit photo'), + 'id' => $ph[0]['id'], + 'rotatecw' => t('Rotate CW (right)'), + 'rotateccw' => t('Rotate CCW (left)'), + 'album' => $album_e, + 'newalbum' => t('New album name'), + 'nickname' => $a->data['channel']['channel_address'], + 'resource_id' => $ph[0]['resource_id'], + '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'), + 'item_id' => ((count($linked_items)) ? $link_item['id'] : 0), + 'submit' => t('Submit'), + 'delete' => t('Delete Photo') + ); } if(count($linked_items)) { @@ -1142,7 +1081,7 @@ function photos_content(&$a) { $dislike = ''; // display comments - if(count($r)) { + if($r) { foreach($r as $item) { like_puller($a,$item,$alike,'like'); @@ -1223,16 +1162,10 @@ function photos_content(&$a) { $drop = replace_macros(get_markup_template('photo_drop.tpl'), array('$id' => $item['id'], '$delete' => t('Delete'))); - if($a->get_template_engine() === 'internal') { - $name_e = template_escape($profile_name); - $title_e = template_escape($item['title']); - $body_e = template_escape(bbcode($item['body'])); - } - else { - $name_e = $profile_name; - $title_e = $item['title']; - $body_e = bbcode($item['body']); - } + $name_e = $profile_name; + $title_e = $item['title']; + $body_e = bbcode($item['body']); + $comments .= replace_macros($template,array( '$id' => $item['item_id'], @@ -1253,18 +1186,10 @@ function photos_content(&$a) { $paginate = paginate($a); } - if($a->get_template_engine() === 'internal') { - $album_e = array($album_link,template_escape($ph[0]['album'])); - $tags_e = template_escape($tags); - $like_e = template_escape($like); - $dislike_e = template_escape($dislike); - } - else { - $album_e = array($album_link,$ph[0]['album']); - $tags_e = $tags; - $like_e = $like; - $dislike_e = $dislike; - } + $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( @@ -1292,10 +1217,12 @@ function photos_content(&$a) { //$o = ''; $r = q("SELECT `resource_id`, max(`scale`) AS `scale` FROM `photo` WHERE `uid` = %d AND `album` != '%s' AND `album` != '%s' - $sql_extra GROUP BY `resource_id`", + and ( photo_flags = %d or photo_flags = %d ) $sql_extra GROUP BY `resource_id`", intval($a->data['channel']['channel_id']), dbesc('Contact Photos'), - dbesc( t('Contact Photos')) + dbesc( t('Contact Photos')), + intval(PHOTO_NORMAL), + intval(PHOTO_PROFILE) ); if(count($r)) { $a->set_pager_total(count($r)); @@ -1303,11 +1230,14 @@ function photos_content(&$a) { } $r = q("SELECT `resource_id`, `id`, `filename`, type, `album`, max(`scale`) AS `scale` FROM `photo` - WHERE `uid` = %d AND `album` != '%s' AND `album` != '%s' + WHERE `uid` = %d AND `album` != '%s' AND `album` != '%s' + and ( photo_flags = %d or photo_flags = %d ) $sql_extra GROUP BY `resource_id` ORDER BY `created` DESC LIMIT %d , %d", intval($a->data['channel']['channel_id']), dbesc('Contact Photos'), dbesc( t('Contact Photos')), + intval(PHOTO_NORMAL), + intval(PHOTO_PROFILE), intval($a->pager['start']), intval($a->pager['itemspage']) ); diff --git a/mod/ping.php b/mod/ping.php index 827992c65..76d84d0e4 100644 --- a/mod/ping.php +++ b/mod/ping.php @@ -75,7 +75,7 @@ function ping_init(&$a) { ); break; case 'all_events': - $r = q("update event set ignore = 1 where ignore = 0 and uid = %d", + $r = q("update event set `ignore` = 1 where `ignore` = 0 and uid = %d", intval(local_user()) ); break; @@ -209,7 +209,7 @@ function ping_init(&$a) { if($r) { foreach($r as $rr) { $result[] = array( - 'notify_link' => $a->get_baseurl() . '/intro/' . $rr['abook_id'], + 'notify_link' => $a->get_baseurl() . '/connections/' . $rr['abook_id'], 'name' => $rr['xchan_name'], 'url' => $rr['xchan_url'], 'photo' => $rr['xchan_photo_s'], diff --git a/mod/poke.php b/mod/poke.php index 163ef0cd8..b22f7d9d5 100755 --- a/mod/poke.php +++ b/mod/poke.php @@ -1,17 +1,30 @@ -<?php +<?php /** @file */ + +/** + * + * Poke, prod, finger, or otherwise do unspeakable things to somebody - who must be a connection in your address book + * This function can be invoked with the required arguments (verb and cid and private and possibly parent) silently via ajax or + * other web request. You must be logged in and connected to a channel. + * If the required arguments aren't present, we'll display a simple form to choose a recipient and a verb. + * parent is a special argument which let's you attach this activity as a comment to an existing conversation, which + * may have started with somebody else poking (etc.) somebody, but this isn't necessary. This can be used in the adult + * plugin version to have entire conversations where Alice poked Bob, Bob fingered Alice, Alice hugged Bob, etc. + * + * private creates a private conversation with the recipient. Otherwise your channel's default post privacy is used. + * + */ -require_once('include/security.php'); -require_once('include/bbcode.php'); require_once('include/items.php'); - function poke_init(&$a) { if(! local_user()) return; $uid = local_user(); - $verb = notags(trim($_GET['verb'])); + $channel = $a->get_channel(); + + $verb = notags(trim($_REQUEST['verb'])); if(! $verb) return; @@ -23,109 +36,86 @@ function poke_init(&$a) { $activity = ACTIVITY_POKE . '#' . urlencode($verbs[$verb][0]); - $contact_id = intval($_GET['cid']); + $contact_id = intval($_REQUEST['cid']); if(! $contact_id) return; - $parent = ((x($_GET,'parent')) ? intval($_GET['parent']) : 0); - + $parent = ((x($_REQUEST,'parent')) ? intval($_REQUEST['parent']) : 0); logger('poke: verb ' . $verb . ' contact ' . $contact_id, LOGGER_DEBUG); - $r = q("SELECT * FROM `contact` WHERE `id` = %d and `uid` = %d LIMIT 1", + $r = q("SELECT * FROM abook left join xchan on xchan_hash = abook_xchan where abook_id = %d and abook_channel = %d LIMIT 1", intval($contact_id), intval($uid) ); - if(! count($r)) { - logger('poke: no contact ' . $contact_id); + if(! $r) { + logger('poke: no target ' . $contact_id); return; } $target = $r[0]; + $parent_item = null; if($parent) { - $r = q("select uri, private, allow_cid, allow_gid, deny_cid, deny_gid + $r = q("select mid, item_private, owner_xchan, allow_cid, allow_gid, deny_cid, deny_gid from item where id = %d and parent = %d and uid = %d limit 1", intval($parent), intval($parent), intval($uid) ); - if(count($r)) { - $parent_uri = $r[0]['uri']; - $private = $r[0]['private']; - $allow_cid = $r[0]['allow_cid']; - $allow_gid = $r[0]['allow_gid']; - $deny_cid = $r[0]['deny_cid']; - $deny_gid = $r[0]['deny_gid']; + if($r) { + $parent_item = $r[0]; + $parent_mid = $r[0]['mid']; + $item_private = $r[0]['item_private']; + $allow_cid = $r[0]['allow_cid']; + $allow_gid = $r[0]['allow_gid']; + $deny_cid = $r[0]['deny_cid']; + $deny_gid = $r[0]['deny_gid']; } } else { - $private = ((x($_GET,'private')) ? intval($_GET['private']) : 0); + $item_private = ((x($_GET,'private')) ? intval($_GET['private']) : 0); - $allow_cid = (($private) ? '<' . $target['id']. '>' : $a->user['allow_cid']); - $allow_gid = (($private) ? '' : $a->user['allow_gid']); - $deny_cid = (($private) ? '' : $a->user['deny_cid']); - $deny_gid = (($private) ? '' : $a->user['deny_gid']); + $allow_cid = (($item_private) ? '<' . $target['abook_xchan']. '>' : $channel['channel_allow_cid']); + $allow_gid = (($item_private) ? '' : $channel['channel_allow_gid']); + $deny_cid = (($item_private) ? '' : $channel['channel_deny_cid']); + $deny_gid = (($item_private) ? '' : $channel['channel_deny_gid']); } - - - $poster = $a->contact; - - $uri = item_message_id(); - $arr = array(); + $arr['item_flags'] = ITEM_WALL | ITEM_ORIGIN; + if($parent_item) + $arr['item_flags'] |= ITEM_THREAD_TOP; - $arr['uid'] = $uid; - $arr['uri'] = $uri; - $arr['parent_uri'] = (($parent_uri) ? $parent_uri : $uri); - $arr['type'] = 'activity'; - $arr['wall'] = 1; - $arr['contact-id'] = $poster['id']; - $arr['owner-name'] = $poster['name']; - $arr['owner-link'] = $poster['url']; - $arr['owner-avatar'] = $poster['thumb']; - $arr['author-name'] = $poster['name']; - $arr['author-link'] = $poster['url']; - $arr['author-avatar'] = $poster['thumb']; + $arr['owner_xchan'] = (($parent_item) ? $parent_item['owner_xchan'] : $channel['channel_hash']); + $arr['parent_mid'] = (($parent_mid) ? $parent_mid : $mid); $arr['title'] = ''; $arr['allow_cid'] = $allow_cid; $arr['allow_gid'] = $allow_gid; $arr['deny_cid'] = $deny_cid; $arr['deny_gid'] = $deny_gid; - $arr['last-child'] = 1; - $arr['visible'] = 1; $arr['verb'] = $activity; - $arr['private'] = $private; - $arr['obj_type'] = ACTIVITY_OBJ_PERSON; - - $arr['origin'] = 1; - $arr['body'] = '[url=' . $poster['url'] . ']' . $poster['name'] . '[/url]' . ' ' . t($verbs[$verb][0]) . ' ' . '[url=' . $target['url'] . ']' . $target['name'] . '[/url]'; - - $arr['object'] = '<object><type>' . ACTIVITY_OBJ_PERSON . '</type><title>' . $target['name'] . '</title><id>' . $a->get_baseurl() . '/contact/' . $target['id'] . '</id>'; - $arr['object'] .= '<link>' . xmlify('<link rel="alternate" type="text/html" href="' . $target['url'] . '" />' . "\n"); - - $arr['object'] .= xmlify('<link rel="photo" type="image/jpeg" href="' . $target['photo'] . '" />' . "\n"); - $arr['object'] .= '</link></object>' . "\n"; - - $item_id = item_store($arr); - if($item_id) { - q("UPDATE `item` SET `plink` = '%s' WHERE `uid` = %d AND `id` = %d LIMIT 1", - dbesc($a->get_baseurl() . '/display/' . $poster['nickname'] . '/' . $item_id), - intval($uid), - intval($item_id) - ); - proc_run('php',"include/notifier.php","tag","$item_id"); - } - + $arr['item_private'] = $item_private; + $arr['obj_type'] = ACTIVITY_OBJ_PERSON; + $arr['body'] = '[zrl=' . $channel['xchan_url'] . ']' . $channel['xchan_name'] . '[/zrl]' . ' ' . t($verbs[$verb][0]) . ' ' . '[zrl=' . $target['xchan_url'] . ']' . $target['xchan_name'] . '[/zrl]'; + + $obj = array( + 'type' => ACTIVITY_OBJ_PERSON, + 'title' => $target['xchan_name'], + 'id' => $target['xchan_hash'], + 'link' => array( + array('rel' => 'alternate', 'type' => 'text/html', 'href' => $target['xchan_url']), + array('rel' => 'photo', 'type' => $target['xchan_photo_mimetype'], 'href' => $target['xchan_photo_l']) + ), + ); - call_hooks('post_local_end', $arr); + $arr['object'] = json_encode($obj); - proc_run('php',"include/notifier.php","like","$post_id"); + post_activity_item($arr); return; } @@ -142,43 +132,19 @@ function poke_content(&$a) { $name = ''; $id = ''; - if(intval($_GET['c'])) { - $r = q("select id,name from contact where id = %d and uid = %d limit 1", - intval($_GET['c']), + if(intval($_REQUEST['c'])) { + $r = q("select abook_id, xchan_name from abook left join xchan on abook_xchan = xchan_hash + where abook_id = %d and abook_channel = %d limit 1", + intval($_REQUEST['c']), intval(local_user()) ); - if(count($r)) { - $name = $r[0]['name']; - $id = $r[0]['id']; + if($r) { + $name = $r[0]['xchan_name']; + $id = $r[0]['abook_id']; } } - - $base = $a->get_baseurl(); - - $a->page['htmlhead'] .= <<< EOT - -<script>$(document).ready(function() { - var a; - a = $("#poke-recip").autocomplete({ - serviceUrl: '$base/acl', - minChars: 2, - width: 350, - onSelect: function(value,data) { - $("#poke-recip-complete").val(data); - } - }); - a.setOptions({ params: { type: 'a' }}); - - -}); - -</script> -EOT; - - $parent = ((x($_GET,'parent')) ? intval($_GET['parent']) : '0'); - - + $parent = ((x($_REQUEST,'parent')) ? intval($_REQUEST['parent']) : '0'); $verbs = get_poke_verbs(); diff --git a/mod/post.php b/mod/post.php index e5fa1a418..07f2cd083 100644 --- a/mod/post.php +++ b/mod/post.php @@ -1,4 +1,4 @@ -<?php +<?php /** @file */ /** * Zot endpoint @@ -10,16 +10,16 @@ require_once('include/zot.php'); function post_init(&$a) { - // All other access to this endpoint is via the post method. + // Most access to this endpoint is via the post method. // Here we will pick out the magic auth params which arrive - // as a get request. + // as a get request, and the only communications to arrive this way. if(argc() > 1) { $webbie = argv(1); if(array_key_exists('auth',$_REQUEST)) { - + logger('mod_zot: auth request received.'); $address = $_REQUEST['auth']; $dest = $_REQUEST['dest']; $sec = $_REQUEST['sec']; @@ -49,7 +49,7 @@ function post_init(&$a) { } // Try and find a hubloc for the person attempting to auth - $x = q("select * from hubloc left join xchan on xchan_hash = hubloc_hash where hubloc_addr = '%s' limit 1", + $x = q("select * from hubloc left join xchan on xchan_hash = hubloc_hash where hubloc_addr = '%s' order by hubloc_id desc limit 1", dbesc($address) ); @@ -60,7 +60,7 @@ function post_init(&$a) { $j = json_decode($ret['body'],true); if($j) import_xchan($j); - $x = q("select * from hubloc left join xchan on xchan_hash = hubloc_hash where hubloc_addr = '%s' limit 1", + $x = q("select * from hubloc left join xchan on xchan_hash = hubloc_hash where hubloc_addr = '%s' order by hubloc_id desc limit 1", dbesc($address) ); } @@ -95,15 +95,32 @@ function post_init(&$a) { $j = json_decode($result['body'],true); } - if($already_authed || $j['result']) { + if($already_authed || $j['success']) { + if($j['success']) { + // legit response, but we do need to check that this wasn't answered by a man-in-middle + if(! rsa_verify($sec . $x[0]['xchan_hash'],base64url_decode($j['confirm']),$x[0]['xchan_pubkey'])) { + logger('mod_zot: auth: final confirmation failed.'); + goaway($desturl); + } + } // everything is good... maybe if(local_user()) { - notice( t('Remote authentication blocked. You are logged into this site locally. Please logout and retry.') . EOL); + + // tell them to logout if they're logged in locally as anything but the target remote account + // in which case just shut up because they don't need to be doing this at all. + + if($a->channel['channel_hash'] != $x[0]['xchan_hash']) { + logger('mod_zot: auth: already authenticated locally as somebody else.'); + notice( t('Remote authentication blocked. You are logged into this site locally. Please logout and retry.') . EOL); + } goaway($desturl); } // log them in $_SESSION['authenticated'] = 1; $_SESSION['visitor_id'] = $x[0]['xchan_hash']; + $_SESSION['my_address'] = $address; + $arr = array('xchan' => $x[0], 'url' => $desturl, 'channel_address' => $webbie); + call_hooks('magic_auth_success',$arr); $a->set_observer($x[0]); require_once('include/security.php'); $a->set_groups(init_groups_visitor($_SESSION['visitor_id'])); @@ -137,12 +154,17 @@ function post_post(&$a) { logger('mod_zot: ' . print_r($_REQUEST,true), LOGGER_DEBUG); - $ret = array('result' => 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 + * tells us we need to unencapsulate the AES-256-CBC content using the site private key + */ + if(array_key_exists('iv',$data)) { $data = aes_unencapsulate($data,get_config('system','prvkey')); logger('mod_zot: decrypt1: ' . $data, LOGGER_DATA); @@ -156,12 +178,20 @@ function post_post(&$a) { if($msgtype === 'pickup') { + /** + * The 'pickup' message arrives with a tracking ID which is associated with a particular outq_hash + * First verify that that the returned signatures verify, then check that we have an outbound queue item + * with the correct hash. + * If everything verifies, find any/all outbound messages in the queue for this hubloc and send them back + * + */ + if((! $data['secret']) || (! $data['secret_sig'])) { $ret['message'] = 'no verification signature'; logger('mod_zot: pickup: ' . $ret['message'], LOGGER_DEBUG); json_return_and_die($ret); } - $r = q("select hubloc_sitekey from hubloc where hubloc_url = '%s' and hubloc_callback = '%s' and hubloc_sitekey != '' limit 1", + $r = q("select distinct hubloc_sitekey from hubloc where hubloc_url = '%s' and hubloc_callback = '%s' and hubloc_sitekey != '' group by hubloc_sitekey ", dbesc($data['url']), dbesc($data['callback']) ); @@ -170,23 +200,46 @@ function post_post(&$a) { logger('mod_zot: pickup: ' . $ret['message']); json_return_and_die($ret); } - // verify the url_sig - $sitekey = $r[0]['hubloc_sitekey']; - logger('sitekey: ' . $sitekey); - if(! rsa_verify($data['callback'],base64url_decode($data['callback_sig']),$sitekey)) { + foreach ($r as $hubsite) { + + // verify the url_sig + // If the server was re-installed at some point, there could be multiple hubs with the same url and callback. + // Only one will have a valid key. + + $forgery = true; + $secret_fail = true; + + $sitekey = $hubsite['hubloc_sitekey']; + + logger('mod_zot: Checking sitekey: ' . $sitekey); + + if(rsa_verify($data['callback'],base64url_decode($data['callback_sig']),$sitekey)) { + $forgery = false; + } + if(rsa_verify($data['secret'],base64url_decode($data['secret_sig']),$sitekey)) { + $secret_fail = false; + } + if((! $forgery) && (! $secret_fail)) + break; + } + if($forgery) { $ret['message'] = 'possible site forgery'; logger('mod_zot: pickup: ' . $ret['message']); json_return_and_die($ret); } - if(! rsa_verify($data['secret'],base64url_decode($data['secret_sig']),$sitekey)) { + if($secret_fail) { $ret['message'] = 'secret validation failed'; logger('mod_zot: pickup: ' . $ret['message']); json_return_and_die($ret); } - // If we made it to here, we've got a valid pickup. Grab everything for this host and send it. + /** + * If we made it to here, the signatures verify, but we still don't know if the tracking ID is valid. + * It wouldn't be an error if the tracking ID isn't found, because we may have sent this particular + * queue item with another pickup (after the tracking ID for the other pickup was verified). + */ $r = q("select outq_posturl from outq where outq_hash = '%s' and outq_posturl = '%s' limit 1", dbesc($data['secret']), @@ -198,6 +251,11 @@ function post_post(&$a) { json_return_and_die($ret); } + /** + * Everything is good if we made it here, so find all messages that are going to this location + * and send them all. + */ + $r = q("select * from outq where outq_posturl = '%s'", dbesc($data['callback']) ); @@ -214,16 +272,31 @@ function post_post(&$a) { } $encrypted = aes_encapsulate(json_encode($ret),$sitekey); json_return_and_die($encrypted); + + /** pickup: end */ } + + /** + * All other message types require us to verify the sender. This is a generic check, so we + * will do it once here and bail if anything goes wrong. + */ + if(array_key_exists('sender',$data)) { $sender = $data['sender']; } + /** Check if the sender is already verified here */ + $hub = zot_gethub($sender); + if(! $hub) { + + /** Have never seen this guid or this guid coming from this location. Check it and register it. */ + // (!!) this will validate the sender $result = zot_register_hub($sender); + if((! $result['success']) || (! zot_gethub($sender))) { $ret['message'] = 'Hub not available.'; logger('mod_zot: no hub'); @@ -236,31 +309,41 @@ function post_post(&$a) { if(array_key_exists('recipients',$data)) $recipients = $data['recipients']; - if($msgtype === 'purge') { if($recipients) { // basically this means "unfriend" foreach($recipients as $recip) { - - - + $r = q("select channel.*,xchan.* from channel + left join xchan on channel_hash = xchan_hash + where channel_guid = '%s' and channel_guid_sig = '%s' limit 1", + dbesc($recip['guid']), + dbesc($recip['guid_sig']) + ); + if($r) { + $r = q("select abook_id from abook where uid = %d and abook_xchan = '%s' limit 1", + intval($r[0]['channel_id']), + dbesc(base64url_encode(hash('whirlpool',$sender['guid'] . $sender['guid_sig'], true))) + ); + if($r) { + contact_remove($r[0]['channel_id'],$r[0]['abook_id']); + } + } } - - } else { - // basically this means the channel has committed suicide + // Unfriend everybody - basically this means the channel has committed suicide $arr = $data['sender']; $sender_hash = base64url_encode(hash('whirlpool',$arr['guid'] . $arr['guid_sig'], true)); require_once('include/Contact.php'); remove_all_xchan_resources($sender_hash); - $ret['result'] = true; + $ret['success'] = true; json_return_and_die($ret); } } + if($msgtype === 'refresh') { // remote channel info (such as permissions or photo or something) @@ -295,7 +378,7 @@ function post_post(&$a) { 'hubloc_url' => $sender['url'] ),null); } - $ret['result'] = true; + $ret['success'] = true; json_return_and_die($ret); } @@ -311,12 +394,13 @@ function post_post(&$a) { $ret['delivery_report'] = $x; } - $ret['result'] = true; + $ret['success'] = true; json_return_and_die($ret); } if($msgtype === 'auth_check') { + logger('mod_zot: auth_check'); $arr = $data['sender']; $sender_hash = base64url_encode(hash('whirlpool',$arr['guid'] . $arr['guid_sig'], true)); @@ -340,7 +424,7 @@ function post_post(&$a) { $arr = $data['recipients'][0]; $recip_hash = base64url_encode(hash('whirlpool',$arr['guid'] . $arr['guid_sig'], true)); - $c = q("select channel_id from channel where channel_hash = '%s' limit 1", + $c = q("select channel_id, channel_prvkey from channel where channel_hash = '%s' limit 1", dbesc($recip_hash) ); if(! $c) { @@ -348,6 +432,8 @@ function post_post(&$a) { json_return_and_die($ret); } + $confirm = base64url_encode(rsa_sign($data['secret'] . $recip_hash,$c[0]['channel_prvkey'])); + // This additionally checks for forged senders since we already stored the expected result in meta // and we've already verified that this is them via zot_gethub() and that their key signed our token @@ -365,7 +451,8 @@ function post_post(&$a) { ); logger('mod_zot: auth_check: success', LOGGER_DEBUG); - $ret['result'] = true; + $ret['success'] = true; + $ret['confirm'] = $confirm; json_return_and_die($ret); } diff --git a/mod/probe.php b/mod/probe.php index f90728df2..397f571c5 100644 --- a/mod/probe.php +++ b/mod/probe.php @@ -1,6 +1,5 @@ <?php -require_once('include/Scrape.php'); require_once('include/zot.php'); function probe_content(&$a) { diff --git a/mod/profile.php b/mod/profile.php index 2f869a533..d59602ba0 100644 --- a/mod/profile.php +++ b/mod/profile.php @@ -10,25 +10,35 @@ function profile_init(&$a) { return; } - $profile = 0; + $profile = ''; $channel = $a->get_channel(); if((local_user()) && (argc() > 2) && (argv(2) === 'view')) { $which = $channel['channel_address']; $profile = argv(1); + $r = q("select profile_guid from profile where id = %d and uid = %d limit 1", + intval($profile), + intval(local_user()) + ); + if(! $r) + $profile = ''; + $profile = $r[0]['profile_guid']; } $a->page['htmlhead'] .= '<link rel="alternate" type="application/atom+xml" href="' . $a->get_baseurl() . '/feed/' . $which .'" />' . "\r\n" ; - $x = q("select channel_id as profile_uid from channel where channel_address = '%s' limit 1", - dbesc(argv(1)) - ); - if($x) { - $a->profile = $x[0]; + if(! $profile) { + $x = q("select channel_id as profile_uid from channel where channel_address = '%s' limit 1", + dbesc(argv(1)) + ); + if($x) { + $a->profile = $x[0]; + } + } // $channel_display = get_pconfig($a->profile['profile_uid'],'system','channel_format'); // if(! $channel_display) - profile_load($a,$which,$profile); - } + profile_load($a,$which,$profile); + } diff --git a/mod/profile_photo.php b/mod/profile_photo.php index ea7a01bc9..64dfc0e83 100644 --- a/mod/profile_photo.php +++ b/mod/profile_photo.php @@ -1,6 +1,6 @@ <?php -require_once("Photo.php"); +require_once('include/photo/photo_driver.php'); function profile_photo_init(&$a) { @@ -77,7 +77,7 @@ function profile_photo_post(&$a) { $base_image = $r[0]; - $im = new Photo($base_image['data'], $base_image['type']); + $im = photo_factory($base_image['data'], $base_image['type']); if($im->is_valid()) { $im->cropImage(175,$srcX,$srcY,$srcW,$srcH); @@ -164,7 +164,7 @@ function profile_photo_post(&$a) { } $imagedata = @file_get_contents($src); - $ph = new Photo($imagedata, $filetype); + $ph = photo_factory($imagedata, $filetype); if(! $ph->is_valid()) { notice( t('Unable to process image.') . EOL ); @@ -251,7 +251,7 @@ function profile_photo_content(&$a) { return; } - $ph = new Photo($r[0]['data'], $r[0]['type']); + $ph = photo_factory($r[0]['data'], $r[0]['type']); // go ahead as if we have just uploaded a new photo to crop profile_photo_crop_ui_head($a, $ph); } diff --git a/mod/profiles.php b/mod/profiles.php index e857c4216..173d97138 100644 --- a/mod/profiles.php +++ b/mod/profiles.php @@ -47,7 +47,7 @@ function profiles_init(&$a) { if((argc() > 1) && (argv(1) === 'new')) { - check_form_security_token_redirectOnErr('/profiles', 'profile_new', 't'); +// check_form_security_token_redirectOnErr('/profiles', 'profile_new', 't'); $r0 = q("SELECT `id` FROM `profile` WHERE `uid` = %d", intval(local_user())); @@ -59,7 +59,7 @@ function profiles_init(&$a) { intval(local_user())); $r2 = q("INSERT INTO `profile` (`aid`, `uid` , `profile_guid`, `profile_name` , `name`, `photo`, `thumb`) - VALUES ( %d, '%s', '%s', '%s', '%s' )", + VALUES ( %d, '%s', '%s', '%s', '%s', '%s', '%s' )", intval(get_account_id()), intval(local_user()), dbesc(random_string()), @@ -200,6 +200,11 @@ function profiles_post(&$a) { $day = intval($_POST['day']); if(($day > $mtab[$month]) || ($day < 0)) $day = 0; + + if($year && (! ($month && $day))) { + $month = 1; $day = 1; + } + $dob = '0000-00-00'; $dob = sprintf('%04d-%02d-%02d',$year,$month,$day); @@ -232,6 +237,7 @@ function profiles_post(&$a) { $about = fix_mce_lf(escape_tags(trim($_POST['about']))); $interest = fix_mce_lf(escape_tags(trim($_POST['interest']))); $contact = fix_mce_lf(escape_tags(trim($_POST['contact']))); + $channels = fix_mce_lf(escape_tags(trim($_POST['channels']))); $music = fix_mce_lf(escape_tags(trim($_POST['music']))); $book = fix_mce_lf(escape_tags(trim($_POST['book']))); $tv = fix_mce_lf(escape_tags(trim($_POST['tv']))); @@ -393,6 +399,7 @@ function profiles_post(&$a) { `about` = '%s', `interest` = '%s', `contact` = '%s', + `channels` = '%s', `music` = '%s', `book` = '%s', `tv` = '%s', @@ -426,6 +433,7 @@ function profiles_post(&$a) { dbesc($about), dbesc($interest), dbesc($contact), + dbesc($channels), dbesc($music), dbesc($book), dbesc($tv), @@ -444,7 +452,7 @@ function profiles_post(&$a) { $channel = $a->get_channel(); if($namechanged && $is_default) { - $r = q("UPDATE xchan SET xchan_name = '%s', xchan_name_date` = '%s' WHERE xchan_hash = '%s' limit 1", + $r = q("UPDATE xchan SET xchan_name = '%s', xchan_name_date = '%s' WHERE xchan_hash = '%s' limit 1", dbesc($name), dbesc(datetime_convert()), dbesc($channel['xchan_hash']) @@ -516,6 +524,7 @@ function profiles_content(&$a) { '$profile_drop_link' => 'profiles/drop/' . $r[0]['id'] . '?t=' . get_form_security_token("profile_drop"), + '$guid' => $r[0]['profile_guid'], '$banner' => t('Edit Profile Details'), '$submit' => t('Submit'), '$viewprof' => t('View this profile'), @@ -550,6 +559,7 @@ function profiles_content(&$a) { '$lbl_about' => t('Tell us about yourself...'), '$lbl_hobbies' => t('Hobbies/Interests'), '$lbl_social' => t('Contact information and Social Networks'), + '$lbl_channels' => t('My other channels'), '$lbl_music' => t('Musical interests'), '$lbl_book' => t('Books, literature'), '$lbl_tv' => t('Television'), @@ -593,7 +603,8 @@ function profiles_content(&$a) { '$romance' => $r[0]['romance'], '$work' => $r[0]['work'], '$education' => $r[0]['education'], - '$contact' => $r[0]['contact'] + '$contact' => $r[0]['contact'], + '$channels' => $r[0]['channels'], )); $arr = array('profile' => $r[0], 'entry' => $o); diff --git a/mod/randprof.php b/mod/randprof.php index 0726b231a..bddb3251a 100644 --- a/mod/randprof.php +++ b/mod/randprof.php @@ -5,6 +5,7 @@ function randprof_init(&$a) { require_once('include/Contact.php'); $x = random_profile(); if($x) - goaway(zid($x)); + goaway(chanlink_url($x)); + // FIXME this doesn't work at the moment as a fallback goaway($a->get_baseurl() . '/profile'); } diff --git a/mod/search.php b/mod/search.php index 1bea720a6..1335ea508 100644 --- a/mod/search.php +++ b/mod/search.php @@ -74,7 +74,7 @@ function search_post(&$a) { } -function search_content(&$a) { +function search_content(&$a,$update = 0, $load = false) { if((get_config('system','block_public')) && (! local_user()) && (! remote_user())) { notice( t('Public access denied.') . EOL); @@ -153,7 +153,7 @@ function search_content(&$a) { // because browser prefetching might change it on us. We have to deliver it with the page. $o .= '<div id="live-search"></div>' . "\r\n"; - $o .= "<script> var profile_uid = " . $a->profile['profile_uid'] + $o .= "<script> var profile_uid = " . ((intval(local_user())) ? local_user() : (-1)) . "; var netargs = '?f='; var profile_page = " . $a->pager['page'] . "; </script>\r\n"; $a->page['htmlhead'] .= replace_macros(get_markup_template("build_query.tpl"),array( @@ -171,11 +171,11 @@ function search_content(&$a) { '$nouveau' => '0', '$wall' => '0', '$page' => (($a->pager['page'] != 1) ? $a->pager['page'] : 1), - '$search' => (($tag) ? '#' : '') . $search, + '$search' => (($tag) ? urlencode('#') : '') . $search, '$order' => '', '$file' => '', '$cats' => '', - '$uri' => '', + '$mid' => '', '$dend' => '', '$dbegin' => '' )); @@ -186,20 +186,20 @@ function search_content(&$a) { if(($update) && ($load)) { - $pager_sql = sprintf(" LIMIT %d, %d ",intval($a->pager['start']), intval($a->pager['itemspage'])); - +dbg(1); if($load) { - $r = q("SELECT distinct(uri), item.* from item + $r = q("SELECT distinct mid, id as item_id from item WHERE item_restrict = 0 AND (( `item`.`allow_cid` = '' AND `item`.`allow_gid` = '' AND `item`.`deny_cid` = '' AND `item`.`deny_gid` = '' AND item_private = 0 ) OR ( `item`.`uid` = %d )) $sql_extra - group by uri ORDER BY created DESC $pager_sql ", + group by mid ORDER BY created DESC $pager_sql ", intval(local_user()), intval(ABOOK_FLAG_BLOCKED) ); +dbg(0); } else { $r = array(); @@ -209,15 +209,15 @@ function search_content(&$a) { if($r) { $parents_str = ids_to_querystr($r,'item_id'); - +dbg(1); $items = q("SELECT `item`.*, `item`.`id` AS `item_id` FROM `item` - WHERE item_restrict = 0 and - $sql_extra ", - intval($a->profile['profile_uid']), - dbesc($parents_str) + WHERE item_restrict = 0 + $sql_extra and parent in ( $parents_str ) " +// intval($a->profile['profile_uid']), +// dbesc($parents_str) ); - +dbg(0); xchan_query($items); $items = fetch_post_tags($items,true); $items = conv_sort($items,'created'); @@ -228,33 +228,33 @@ function search_content(&$a) { - $r = q("SELECT distinct(`item`.`uri`), `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`.`uri` - ORDER BY `received` DESC LIMIT %d , %d ", - intval(local_user()), - intval($a->pager['start']), - intval($a->pager['itemspage']) +// $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(! count($r)) { - info( t('No results.') . EOL); - return $o; - } +// if(! $items) {// +// info( t('No results.') . EOL); +// return $o; +// } if($tag) @@ -262,9 +262,9 @@ function search_content(&$a) { else $o .= '<h2>Search results for: ' . htmlspecialchars($search) . '</h2>'; - $o .= conversation($a,$r,'search',false); + $o .= conversation($a,$items,'search',$update,'client'); - $o .= alt_pager($a,count($r)); +// $o .= alt_pager($a,count($r)); return $o; } diff --git a/mod/settings.php b/mod/settings.php index da6cf709c..0cca41810 100644 --- a/mod/settings.php +++ b/mod/settings.php @@ -1,5 +1,6 @@ -<?php +<?php /** @file */ +require_once('include/zot.php'); function get_theme_config_file($theme){ @@ -14,6 +15,11 @@ function get_theme_config_file($theme){ return null; } +function settings_init(&$a) { + $a->profile_uid = local_user(); +} + + function settings_aside(&$a) { @@ -115,13 +121,6 @@ function settings_post(&$a) { return; -// if(count($a->user) && x($a->user,'uid') && $a->user['uid'] != local_user()) { -// notice( t('Permission denied.') . EOL); -// return; -// } - - $old_page_flags = $a->user['page-flags']; - if((argc() > 1) && (argv(1) === 'oauth') && x($_POST,'remove')){ check_form_security_token_redirectOnErr('/settings/oauth', 'settings_oauth'); @@ -182,6 +181,7 @@ function settings_post(&$a) { check_form_security_token_redirectOnErr('/settings/featured', 'settings_featured'); call_hooks('feature_settings_post', $_POST); + build_sync_packet(); return; } @@ -194,6 +194,7 @@ function settings_post(&$a) { set_pconfig(local_user(),'feature',substr($k,8),((intval($v)) ? 1 : 0)); } } + build_sync_packet(); return; } @@ -237,6 +238,7 @@ function settings_post(&$a) { ); call_hooks('display_settings_post', $_POST); + build_sync_packet(); goaway($a->get_baseurl(true) . '/settings/display' ); return; // NOTREACHED } @@ -292,7 +294,7 @@ function settings_post(&$a) { $errs[] = t('Not valid email.'); $adm = trim(get_config('system','admin_email')); if(($adm) && (strcasecmp($email,$adm) == 0)) { - $errs[] = t('Protected email. Cannot change to that email.'); + $errs[] = t('Protected email address. Cannot change to that email.'); $email = $a->user['email']; } if(! $errs) { @@ -334,6 +336,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); + $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); $blockwall = (((x($_POST,'blockwall')) && (intval($_POST['blockwall']) == 1)) ? 0: 1); // this setting is inverted! @@ -456,6 +459,8 @@ function settings_post(&$a) { set_pconfig(local_user(),'system','post_newfriend', $post_newfriend); 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); + /* if($page_flags == PAGE_PRVGROUP) { @@ -500,9 +505,11 @@ function settings_post(&$a) { ); */ - $r = q("update channel set channel_name = '%s', channel_timezone = '%s', channel_max_anon_mail = %d, channel_max_friend_req = %d, channel_expire_days = %d, 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 where channel_id = %d limit 1", + $r = q("update channel set channel_name = '%s', channel_timezone = '%s', channel_location = '%s', channel_notifyflags = %d, channel_max_anon_mail = %d, channel_max_friend_req = %d, channel_expire_days = %d, 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 where channel_id = %d limit 1", dbesc($username), dbesc($timezone), + dbesc($defloc), + intval($notify), intval($unkmail), intval($maxreq), intval($expire), @@ -547,11 +554,12 @@ function settings_post(&$a) { dbesc($username), intval($channel['channel_id']) ); - // we really need to send out notifications to all our friends } proc_run('php','include/directory.php',local_user()); + build_sync_packet(); + //$_SESSION['theme'] = $theme; if($email_changed && $a->config['system']['register_policy'] == REGISTER_VERIFY) { @@ -578,6 +586,11 @@ function settings_content(&$a) { return; } + + $channel = $a->get_channel(); + if($channel) + head_set_icon($channel['xchan_photo_s']); + // if(x($_SESSION,'submanage') && intval($_SESSION['submanage'])) { // notice( t('Permission denied.') . EOL ); // return; @@ -716,7 +729,6 @@ function settings_content(&$a) { if((argc() > 1) && (argv(1) === 'features')) { - $arr = array(); $features = get_features(); @@ -736,6 +748,7 @@ function settings_content(&$a) { '$submit' => t('Submit'), '$field_yesno' => 'field_yesno.tpl', )); + return $o; } @@ -905,7 +918,6 @@ function settings_content(&$a) { $expire = $channel['channel_expire_days']; $blockwall = $a->user['blockwall']; - $blocktags = $a->user['blocktags']; $unkmail = $a->user['unkmail']; $cntunkmail = $a->user['cntunkmail']; @@ -937,6 +949,8 @@ function settings_content(&$a) { $post_profilechange = get_pconfig(local_user(), 'system','post_profilechange'); $post_profilechange = (($post_profilechange===false)? '0': $post_profilechange); // default if not set: 0 + $blocktags = get_pconfig(local_user(),'system','blocktags'); + $blocktags = (($blocktags===false) ? '0' : $blocktags); $timezone = date_default_timezone_get(); @@ -1005,11 +1019,16 @@ function settings_content(&$a) { '$email' => array('email', t('Email Address:'), $email, ''), '$timezone' => array('timezone_select' , t('Your Timezone:'), select_timezone($timezone), ''), '$defloc' => array('defloc', t('Default Post Location:'), $defloc, ''), - '$allowloc' => array('allow_location', t('Use Browser Location:'), (intval(get_pconfig(local_user(),'system','use_browser_location')) == 1), ''), + '$allowloc' => array('allow_location', t('Use Browser Location:'), ((get_pconfig(local_user(),'system','use_browser_location')) ? 1 : ''), ''), '$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'), '$permiss_arr' => $permiss, '$maxreq' => array('maxreq', t('Maximum Friend Requests/Day:'), intval($channel['channel_max_friend_req']) , t('May reduce spam activity')), diff --git a/mod/setup.php b/mod/setup.php index b05b0cec3..3c0a133b7 100755 --- a/mod/setup.php +++ b/mod/setup.php @@ -27,6 +27,7 @@ function setup_post(&$a) { case 3: $urlpath = $a->get_path(); $dbhost = notags(trim($_POST['dbhost'])); + $dbport = intval(notags(trim($_POST['dbport']))); $dbuser = notags(trim($_POST['dbuser'])); $dbpass = notags(trim($_POST['dbpass'])); $dbdata = notags(trim($_POST['dbdata'])); @@ -34,12 +35,16 @@ function setup_post(&$a) { $adminmail = notags(trim($_POST['adminmail'])); $siteurl = notags(trim($_POST['siteurl'])); - require_once("dba.php"); + require_once('include/dba/dba_driver.php'); unset($db); - $db = new dba($dbhost, $dbuser, $dbpass, $dbdata, true); + $db = dba_factory($dbhost, $dbport, $dbuser, $dbpass, $dbdata, true); + if(! $db->connected) { + echo "Database Connect failed: " . $db->error; + killme(); + } /*if(get_db_errno()) { unset($db); - $db = new dba($dbhost, $dbuser, $dbpass, '', true); + $db = dba_factory($dbhost, $dbport, $dbuser, $dbpass, '', true); if(! get_db_errno()) { $r = q("CREATE DATABASE '%s'", @@ -47,7 +52,7 @@ function setup_post(&$a) { ); if($r) { unset($db); - $db = new dba($dbhost, $dbuser, $dbpass, $dbdata, true); + $db = new dba($dbhost, $dbport, $dbuser, $dbpass, $dbdata, true); } else { $a->data['db_create_failed']=true; } @@ -65,6 +70,7 @@ function setup_post(&$a) { case 4: $urlpath = $a->get_path(); $dbhost = notags(trim($_POST['dbhost'])); + $dbport = intval(notags(trim($_POST['dbport']))); $dbuser = notags(trim($_POST['dbuser'])); $dbpass = notags(trim($_POST['dbpass'])); $dbdata = notags(trim($_POST['dbdata'])); @@ -74,13 +80,26 @@ function setup_post(&$a) { $siteurl = notags(trim($_POST['siteurl'])); + if($siteurl != z_root()) { + $test = z_fetch_url($siteurl."/setup/testrewrite"); + if((! $test['success']) || ($test['body'] != 'ok')) { + $a->data['url_fail'] = true; + return; + } + } // connect to db - $db = new dba($dbhost, $dbuser, $dbpass, $dbdata, true); + $db = dba_factory($dbhost, $dbport, $dbuser, $dbpass, $dbdata, true); + + if(! $db->connected) { + echo 'CRITICAL: DB not connected.'; + killme(); + } $tpl = get_intltext_template('htconfig.tpl'); $txt = replace_macros($tpl,array( '$dbhost' => $dbhost, + '$dbport' => $dbport, '$dbuser' => $dbuser, '$dbpass' => $dbpass, '$dbdata' => $dbdata, @@ -120,7 +139,7 @@ function setup_content(&$a) { global $install_wizard_pass, $db; $o = ''; $wizard_status = ""; - $install_title = t('Friendica Red Communications Server - Setup'); + $install_title = t('Red Matrix Server - Setup'); @@ -128,6 +147,11 @@ function setup_content(&$a) { $install_wizard_pass = 2; $wizard_status = t('Could not connect to database.'); } + if(x($a->data,'url_fail')) { + $install_wizard_pass = 3; + $wizard_status = t('Could not connect to specified site URL. Possible SSL certificate or DNS issue.'); + } + if(x($a->data,'db_create_failed')) { $install_wizard_pass = 2; $wizard_status = t('Could not create table.'); @@ -136,7 +160,7 @@ function setup_content(&$a) { $db_return_text=""; if(x($a->data,'db_installed')) { $txt = '<p style="font-size: 130%;">'; - $txt .= t('Your Friendica site database has been installed.') . EOL; + $txt .= t('Your site database has been installed.') . EOL; $db_return_text .= $txt; } @@ -148,7 +172,7 @@ function setup_content(&$a) { } if($db && $db->connected) { - $r = q("SELECT COUNT(*) as `total` FROM `user`"); + $r = q("SELECT COUNT(*) as `total` FROM `account`"); if($r && count($r) && $r[0]['total']) { $tpl = get_markup_template('install.tpl'); return replace_macros($tpl, array( @@ -222,6 +246,7 @@ function setup_content(&$a) { $dbhost = ((x($_POST,'dbhost')) ? notags(trim($_POST['dbhost'])) : 'localhost'); $dbuser = notags(trim($_POST['dbuser'])); + $dbport = intval(notags(trim($_POST['dbport']))); $dbpass = notags(trim($_POST['dbpass'])); $dbdata = notags(trim($_POST['dbdata'])); $phpath = notags(trim($_POST['phpath'])); @@ -233,13 +258,14 @@ function setup_content(&$a) { $o .= replace_macros($tpl, array( '$title' => $install_title, '$pass' => t('Database connection'), - '$info_01' => t('In order to install Friendica we need to know how to connect to your database.'), + '$info_01' => t('In order to install Red Matrix we need to know how to connect to your database.'), '$info_02' => t('Please contact your hosting provider or site administrator if you have questions about these settings.'), '$info_03' => t('The database you specify below should already exist. If it does not, please create it before continuing.'), '$status' => $wizard_status, - '$dbhost' => array('dbhost', t('Database Server Name'), $dbhost, ''), + '$dbhost' => array('dbhost', t('Database Server Name'), $dbhost, t('Default is localhost')), + '$dbport' => array('dbport', t('Database Port'), $dbport, t('Communication port number - use 0 for default')), '$dbuser' => array('dbuser', t('Database Login Name'), $dbuser, ''), '$dbpass' => array('dbpass', t('Database Login Password'), $dbpass, ''), '$dbdata' => array('dbdata', t('Database Name'), $dbdata, ''), @@ -262,6 +288,7 @@ function setup_content(&$a) { case 3: { // Site settings require_once('datetime.php'); $dbhost = ((x($_POST,'dbhost')) ? notags(trim($_POST['dbhost'])) : 'localhost'); + $dbport = intval(notags(trim($_POST['dbuser']))); $dbuser = notags(trim($_POST['dbuser'])); $dbpass = notags(trim($_POST['dbpass'])); $dbdata = notags(trim($_POST['dbdata'])); @@ -279,6 +306,7 @@ function setup_content(&$a) { '$status' => $wizard_status, '$dbhost' => $dbhost, + '$dbport' => $dbport, '$dbuser' => $dbuser, '$dbpass' => $dbpass, '$dbdata' => $dbdata, @@ -330,7 +358,7 @@ function check_php(&$phpath, &$checks) { $help = ""; if(!$passed) { $help .= t('Could not find a command line version of PHP in the web server PATH.'). EOL; - $help .= t("If you don't have a command line version of PHP installed on server, you will not be able to run background polling via cron. See <a href='http://friendica.com/node/27'>'Activating scheduled tasks'</a>") . EOL ; + $help .= t("If you don't have a command line version of PHP installed on server, you will not be able to run background polling via cron.") . EOL; $help .= EOL . EOL ; $tpl = get_markup_template('field_input.tpl'); $help .= replace_macros($tpl, array( @@ -397,6 +425,12 @@ function check_funcs(&$checks) { check_add($ck_funcs, t('Apache mod_rewrite module'), true, true, ""); } } + if((! function_exists('proc_open')) || strstr(ini_get('disable_functions'),'proc_open')) { + check_add($ck_funcs, t('proc_open'), false, true, t('Error: proc_open is required but is either not installed or has been disabled in php.ini')); + } + else { + check_add($ck_funcs, t('proc_open'), true, true, ""); + } if(! function_exists('curl_init')){ $ck_funcs[0]['status']= false; @@ -438,7 +472,7 @@ function check_htconfig(&$checks) { $status=false; $help = t('The web installer needs to be able to create a file called ".htconfig.php" in the top folder of your web server and it is unable to do so.') .EOL; $help .= t('This is most often a permission setting, as the web server may not be able to write files in your folder - even if you can.').EOL; - $help .= t('At the end of this procedure, we will give you a text to save in a file named .htconfig.php in your Friendica top folder.').EOL; + $help .= t('At the end of this procedure, we will give you a text to save in a file named .htconfig.php in your Red top folder.').EOL; $help .= t('You can alternatively skip this procedure and perform a manual installation. Please see the file "install/INSTALL.txt" for instructions.').EOL; } @@ -452,8 +486,8 @@ function check_smarty3(&$checks) { if( !is_writable('view/tpl/smarty3') ) { $status=false; - $help = t('Friendica uses the Smarty3 template engine to render its web views. Smarty3 compiles templates to PHP to speed up rendering.') .EOL; - $help .= t('In order to store these compiled templates, the web server needs to have write access to the directory view/tpl/smarty3/ under the Friendica top level folder.').EOL; + $help = t('Red uses the Smarty3 template engine to render its web views. Smarty3 compiles templates to PHP to speed up rendering.') .EOL; + $help .= t('In order to store these compiled templates, the web server needs to have write access to the directory view/tpl/smarty3/ 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; $help .= t('Note: as a security measure, you should give the web server write access to view/tpl/smarty3/ only--not the template files (.tpl) that it contains.').EOL; } @@ -467,8 +501,17 @@ function check_htaccess(&$checks) { $status = true; $help = ""; if (function_exists('curl_init')){ - $test = fetch_url($a->get_baseurl()."/setup/testrewrite"); - if ($test!="ok") { + $test = z_fetch_url($a->get_baseurl()."/setup/testrewrite"); + if(! $test['success']) { + if(strstr($a->get_baseurl(),'https://')) { + $test = z_fetch_url($a->get_baseurl() . "/setup/testrewrite",false,0,array('novalidate' => true)); + if($test['success']) { + check_add($checks, t('SSL certificate validation'),false,true, t('SSL certificate cannot be validated. Fix certificate or disable https access to this site.')); + } + } + } + + if ((! $test['success']) || ($test['body'] != "ok")) { $status = false; $help = t('Url rewrite in .htaccess is not working. Check your server configuration.'); } @@ -521,7 +564,7 @@ function what_next() { ."<p>".t('IMPORTANT: You will need to [manually] setup a scheduled task for the poller.') .t('Please see the file "install/INSTALL.txt".') ."</p><p>" - .t("Go to your new Friendica node <a href='$baseurl/register'>registration page</a> and register as new user. Remember to use the same email you have entered as administrator email. This will allow you to enter the site admin panel.") + .t("Go to your new Red node <a href='$baseurl/register'>registration page</a> and register as new user. Remember to use the same email you have entered as administrator email. This will allow you to enter the site admin panel.") ."</p>"; } diff --git a/mod/share.php b/mod/share.php index 33aa9eede..f0b14541f 100644 --- a/mod/share.php +++ b/mod/share.php @@ -17,15 +17,22 @@ function share_init(&$a) { xchan_query($r); - $o = '[share]' . "\n"; - - $o .= "\xE2\x99\xb2" . ' [url=' . $r[0]['author']['xchan_url'] . ']' . $r[0]['author']['xchan_name'] . '[/url]' . "\n"; - if($r[0]['title']) - $o .= '[b]' . $r[0]['title'] . '[/b]' . "\n"; - $o .= $r[0]['body'] . "\n" ; - - $o .= (($r[0]['plink']) ? '[url=' . $r[0]['plink'] . ']' . t('link') . '[/url]' . "\n" : '') . '[/share]'; + if (strpos($r[0]['body'], "[/share]") !== false) { + $pos = strpos($r[0]['body'], "[share"); + $o = substr($r[0]['body'], $pos); + } else { + $o = "[share author='".str_replace("'", "'",$r[0]['author']['xchan_name']). + "' profile='".$r[0]['author']['xchan_url'] . + "' avatar='".$r[0]['author']['xchan_photo_s']. + "' link='".$r[0]['plink']. + "' posted='".$r[0]['created']."']\n"; + if($r[0]['title']) + $o .= '[b]'.$r[0]['title'].'[/b]'."\n"; + $o .= $r[0]['body']; + $o.= "[/share]"; + } echo $o; - killme(); + killme(); + } diff --git a/mod/siteinfo.php b/mod/siteinfo.php index 0cd569d20..f2f444fac 100644 --- a/mod/siteinfo.php +++ b/mod/siteinfo.php @@ -28,13 +28,13 @@ function siteinfo_init(&$a) { } $data = Array( - 'version' => FRIENDICA_VERSION, + 'version' => RED_VERSION, 'url' => z_root(), 'plugins' => $visible_plugins, 'register_policy' => $register_policy[$a->config['system']['register_policy']], 'admin' => $admin, 'site_name' => $a->config['sitename'], - 'platform' => FRIENDICA_PLATFORM, + 'platform' => RED_PLATFORM, 'info' => ((x($a->config,'info')) ? $a->config['info'] : '') ); @@ -47,26 +47,10 @@ function siteinfo_init(&$a) { function siteinfo_content(&$a) { - // FIXME Gak - this needs to be a template. - - $o = ''; - $o .= '<h3>' . t('Red') . '</h3>'; - - - $o .= '<p></p><p>'; - - $o .= t('This is Red - another decentralized, distributed communications project by the folks at Friendica.'); if(! get_config('system','hidden_version_siteinfo')) - $o .= '</p><p>' . sprintf( t('Version %s'), FRIENDICA_VERSION ) . '</p><p>'; - $o .= '</p><p>'; - $o .= t('Running at web location') . ' ' . z_root() . '</p><p>'; - - $o .= t('Please visit <a href="http://friendica.com">Friendica.com</a> to learn more about the Friendica and/or Red project.') . '</p><p>'; - - $o .= t('Bug reports and issues: please visit') . ' ' . '<a href="http://bugs.friendica.com">Bugs.Friendica.com</a></p><p>'; - $o .= t('Suggestions, praise, donations, etc. - please email "Info" at Friendica - dot com') . '</p>'; - - $o .= '<p></p>'; + $version = sprintf( t('Version %s'), RED_VERSION ); + else + $version = ""; $visible_plugins = array(); if(is_array($a->plugins) && count($a->plugins)) { @@ -76,9 +60,9 @@ function siteinfo_content(&$a) { $visible_plugins[] = $rr['name']; } - + $plugins_list = ''; if(count($visible_plugins)) { - $o .= '<p>' . t('Installed plugins/addons/apps:') . '</p>'; + $plugins_text = t('Installed plugins/addons/apps:'); $sorted = $visible_plugins; $s = ''; sort($sorted); @@ -88,10 +72,24 @@ function siteinfo_content(&$a) { $s .= $p; } } - $o .= '<div style="margin-left: 25px; margin-right: 25px;">' . $s . '</div>'; + $plugins_list .= $s; } else - $o .= '<p>' . t('No installed plugins/addons/apps') . '</p>'; + $plugins_text = t('No installed plugins/addons/apps'); + + $o = replace_macros(get_markup_template('siteinfo.tpl'), array( + '$title' => t('Red'), + '$description' => t('This is Red - another decentralized, distributed communications project by the folks at Friendica.'), + '$version' => $version, + '$web_location' => t('Running at web location') . ' ' . z_root(), + '$visit' => t('Please visit <a href="http://friendica.com">Friendica.com</a> to learn more about the Friendica and/or Red project.'), + '$bug_text' => t('Bug reports and issues: please visit'), + '$bug_link_url' => 'http://bugs.friendica.com', + '$bug_link_text' => 'Bugs.Friendica.com', + '$contact' => t('Suggestions, praise, donations, etc. - please email "Info" at Friendica - dot com'), + '$plugins_text' => $plugins_text, + '$plugins_list' => $plugins_list + )); call_hooks('about_hook', $o); diff --git a/mod/sitelist.php b/mod/sitelist.php new file mode 100644 index 000000000..1e6d0fcfb --- /dev/null +++ b/mod/sitelist.php @@ -0,0 +1,51 @@ +<?php /** @file */ + +function sitelist_init(&$a) { + + $start = (($_REQUEST['start']) ? intval($_REQUEST['start']) : 0); + $limit = ((intval($_REQUEST['limit'])) ? intval($_REQUEST['limit']) : 30); + $order = (($_REQUEST['order']) ? $_REQUEST['order'] : 'random'); + $open = (($_REQUEST['open']) ? intval($_REQUEST['open']) : false); + + + $sql_order = " order by site_url "; + if($order == 'random') + $sql_order = " order by rand() "; + + $sql_limit = " limit $start, $limit "; + + $sql_extra = ""; + if($open) + $sql_extra = " and site_register = " . intval(REGISTER_OPEN) . " "; + + + $result = array('success' => false); + + $r = q("select count(site_url) as total from site where 1 $sql_extra "); + + if($r) + $result['total'] = intval($r[0]['total']); + + $result['start'] = $start; + $result['limit'] = $limit; + + $r = q("select * from site where true $sql_extra $sql_order $sql_limit"); + + $result['results'] = 0; + $result['entries'] = array(); + + if($r) { + $result['success'] = true; + $result['results'] = count($r); + + foreach($r as $rr) { + $result['entries'][] = array('url' => $rr['site_url']); + } + + } + + echo json_encode($result); + killme(); + + +}
\ No newline at end of file diff --git a/mod/starred.php b/mod/starred.php index 530c5c7e0..ca7621b0f 100644 --- a/mod/starred.php +++ b/mod/starred.php @@ -19,13 +19,7 @@ function starred_init(&$a) { if(! count($r)) killme(); - $item_flags = $r[0]['item_flags']; - - if($item_flags & ITEM_STARRED) - $item_flags -= ITEM_STARRED; - else - $item_flags += ITEM_STARRED; - + $item_flags = ( $r[0]['item_flags'] ^ ITEM_STARRED ); $r = q("UPDATE item SET item_flags = %d WHERE uid = %d and id = %d LIMIT 1", intval($item_flags), diff --git a/mod/subthread.php b/mod/subthread.php index f8918e25d..66dc86eb2 100755 --- a/mod/subthread.php +++ b/mod/subthread.php @@ -7,15 +7,15 @@ require_once('include/items.php'); function subthread_content(&$a) { - if(! local_user() && ! remote_user()) { + if((! local_user()) && (! remote_user())) { return; } $activity = ACTIVITY_FOLLOW; - $item_id = (($a->argc > 1) ? notags(trim($a->argv[1])) : 0); + $item_id = ((argc() > 1) ? notags(trim(argv(1))) : 0); - $r = q("SELECT * FROM `item` WHERE `parent` = '%s' OR `parent-uri` = '%s' and parent = id LIMIT 1", + $r = q("SELECT * FROM `item` WHERE `parent` = '%s' OR `parent_mid` = '%s' and parent = id LIMIT 1", dbesc($item_id), dbesc($item_id) ); @@ -84,7 +84,7 @@ function subthread_content(&$a) { return; } - $uri = item_message_id(); + $mid = item_message_id(); $post_type = (($item['resource_id']) ? t('photo') : t('status')); $objtype = (($item['resource_id']) ? ACTIVITY_OBJ_PHOTO : ACTIVITY_OBJ_NOTE ); @@ -96,7 +96,7 @@ function subthread_content(&$a) { <object> <type>$objtype</type> <local>1</local> - <id>{$item['uri']}</id> + <id>{$item['mid']}</id> <link>$link</link> <title></title> <content>$body</content> @@ -109,7 +109,7 @@ EOT; $arr = array(); - $arr['uri'] = $uri; + $arr['mid'] = $mid; $arr['uid'] = $owner_uid; $arr['contact-id'] = $contact['id']; $arr['type'] = 'activity'; @@ -117,8 +117,8 @@ EOT; $arr['origin'] = 1; $arr['gravity'] = GRAVITY_LIKE; $arr['parent'] = $item['id']; - $arr['parent-uri'] = $item['uri']; - $arr['thr_parent'] = $item['uri']; + $arr['parent-mid'] = $item['mid']; + $arr['thr_parent'] = $item['mid']; $arr['owner-name'] = $remote_owner['name']; $arr['owner-link'] = $remote_owner['url']; $arr['owner-avatar'] = $remote_owner['thumb']; @@ -126,9 +126,9 @@ EOT; $arr['author-link'] = $contact['url']; $arr['author-avatar'] = $contact['thumb']; - $ulink = '[url=' . $contact['url'] . ']' . $contact['name'] . '[/url]'; - $alink = '[url=' . $item['author-link'] . ']' . $item['author-name'] . '[/url]'; - $plink = '[url=' . $a->get_baseurl() . '/display/' . $owner['nickname'] . '/' . $item['id'] . ']' . $post_type . '[/url]'; + $ulink = '[zrl=' . $contact['url'] . ']' . $contact['name'] . '[/zrl]'; + $alink = '[zrl=' . $item['author-link'] . ']' . $item['author-name'] . '[/zrl]'; + $plink = '[zrl=' . $a->get_baseurl() . '/display/' . $owner['nickname'] . '/' . $item['id'] . ']' . $post_type . '[/zrl]'; $arr['body'] = sprintf( $bodyverb, $ulink, $alink, $plink ); $arr['verb'] = $activity; diff --git a/mod/suggest.php b/mod/suggest.php index 4aed2e61a..f891ebefc 100644 --- a/mod/suggest.php +++ b/mod/suggest.php @@ -8,17 +8,21 @@ function suggest_init(&$a) { if(! local_user()) return; - if(x($_GET,'ignore') && intval($_GET['ignore'])) { - q("insert into gcign ( uid, gcid ) values ( %d, %d ) ", + if(x($_GET,'ignore')) { + q("insert into xign ( uid, xchan ) values ( %d, '%s' ) ", intval(local_user()), - intval($_GET['ignore']) + dbesc($_GET['ignore']) ); } } +function suggest_aside(&$a) { + $a->set_widget('follow', follow_widget()); + $a->set_widget('findpeople', findpeople_widget()); +} function suggest_content(&$a) { @@ -31,38 +35,36 @@ function suggest_content(&$a) { $_SESSION['return_url'] = $a->get_baseurl() . '/' . $a->cmd; - $a->page['aside'] .= follow_widget(); - $a->page['aside'] .= findpeople_widget(); + $r = suggestion_query(local_user(),get_observer_hash()); + if(! $r) { + info( t('No suggestions available. If this is a new site, please try again in 24 hours.')); + return; + } - $o .= '<h2>' . t('Friend Suggestions') . '</h2>'; + $arr = array(); + foreach($r as $rr) { - $r = suggestion_query(local_user()); + $connlnk = $a->get_baseurl() . '/follow/?url=' . $rr['xchan_addr']; - if(! count($r)) { - $o .= t('No suggestions available. If this is a new site, please try again in 24 hours.'); - return $o; + $arr[] = array( + 'url' => chanlink_url($rr['xchan_url']), + 'name' => $rr['xchan_name'], + 'photo' => $rr['xchan_photo_m'], + 'ignlnk' => $a->get_baseurl() . '/suggest?ignore=' . $rr['xchan_hash'], + 'conntxt' => t('Connect'), + 'connlnk' => $connlnk, + 'ignore' => t('Ignore/Hide') + ); } - $tpl = get_markup_template('suggest_friends.tpl'); - foreach($r as $rr) { - - $connlnk = $a->get_baseurl() . '/follow/?url=' . (($rr['connect']) ? $rr['connect'] : $rr['url']); - - $o .= replace_macros($tpl,array( - '$url' => zid($rr['url']), - '$name' => $rr['name'], - '$photo' => $rr['photo'], - '$ignlnk' => $a->get_baseurl() . '/suggest?ignore=' . $rr['id'], - '$conntxt' => t('Connect'), - '$connlnk' => $connlnk, - '$ignore' => t('Ignore/Hide') - )); - } + $o = replace_macros(get_markup_template('suggest_page.tpl'),array( + '$title' => t('Channel Suggestions'), + '$entries' => $arr + )); - $o .= cleardiv(); -// $o .= paginate($a); return $o; + } diff --git a/mod/tagger.php b/mod/tagger.php index 9c36a8b09..ec5c92184 100644 --- a/mod/tagger.php +++ b/mod/tagger.php @@ -11,6 +11,8 @@ function tagger_content(&$a) { return; } + $observer_hash = get_observer_hash(); + $term = notags(trim($_GET['term'])); // no commas allowed $term = str_replace(array(',',' '),array('','_'),$term); @@ -23,11 +25,12 @@ function tagger_content(&$a) { logger('tagger: tag ' . $term . ' item ' . $item_id); - $r = q("SELECT * FROM `item` WHERE `id` = '%s' LIMIT 1", - dbesc($item_id) + $r = q("SELECT * FROM item left join xchan on xchan_hash = author_xchan WHERE id = '%s' and uid = %d LIMIT 1", + dbesc($item_id), + intval(local_user()) ); - if(! $item_id || (! count($r))) { + if((! $item_id) || (! $r)) { logger('tagger: no item ' . $item_id); return; } @@ -36,89 +39,82 @@ function tagger_content(&$a) { $owner_uid = $item['uid']; - $r = q("select `nickname`,`blocktags` from user where uid = %d limit 1", - intval($owner_uid) - ); - if(count($r)) { - $owner_nick = $r[0]['nickname']; - $blocktags = $r[0]['blocktags']; + switch($item['resource_type']) { + case 'photo': + $targettype = ACTIVITY_OBJ_PHOTO; + $post_type = t('photo'); + break; + case 'event': + $targgettype = ACTIVITY_OBJ_EVENT; + $post_type = t('event'); + break; + default: + $targettype = ACTIVITY_OBJ_NOTE; + $post_type = t('status'); + if($item['mid'] != $item['parent_mid']) + $post_type = t('comment'); + break; } - if(local_user() != $owner_uid) - return; - $r = q("select * from contact where self = 1 and uid = %d limit 1", - intval(local_user()) - ); - if(count($r)) - $contact = $r[0]; - else { - logger('tagger: no contact_id'); - return; - } + $links = array(array('rel' => 'alternate','type' => 'text/html', + 'href' => z_root() . '/display/' . $item['mid'])); - $uri = item_message_id(); - $xterm = xmlify($term); - $post_type = (($item['resource_id']) ? t('photo') : t('status')); - $targettype = (($item['resource_id']) ? ACTIVITY_OBJ_PHOTO : ACTIVITY_OBJ_NOTE ); + $target = json_encode(array( + 'type' => $targettype, + 'id' => $item['mid'], + 'link' => $links, + 'title' => $item['title'], + 'content' => $item['body'], + 'created' => $item['created'], + 'edited' => $item['edited'], + 'author' => array( + 'name' => $item['xchan_name'], + 'address' => $item['xchan_addr'], + 'guid' => $item['xchan_guid'], + 'guid_sig' => $item['xchan_guid_sig'], + 'link' => array( + array('rel' => 'alternate', 'type' => 'text/html', 'href' => $item['xchan_url']), + array('rel' => 'photo', 'type' => $item['xchan_photo_mimetype'], 'href' => $item['xchan_photo_m'])), + ), + )); - $link = xmlify('<link rel="alternate" type="text/html" href="' - . $a->get_baseurl() . '/display/' . $owner['nickname'] . '/' . $item['id'] . '" />' . "\n") ; - $body = xmlify($item['body']); - $target = <<< EOT - <target> - <type>$targettype</type> - <local>1</local> - <id>{$item['uri']}</id> - <link>$link</link> - <title></title> - <content>$body</content> - </target> -EOT; + $link = xmlify('<link rel="alternate" type="text/html" href="' + . $a->get_baseurl() . '/display/' . $owner['nickname'] . '/' . $item['id'] . '" />' . "\n") ; $tagid = $a->get_baseurl() . '/search?tag=' . $term; $objtype = ACTIVITY_OBJ_TAGTERM; - $obj = <<< EOT - <object> - <type>$objtype</type> - <local>1</local> - <id>$tagid</id> - <link>$tagid</link> - <title>$xterm</title> - <content>$xterm</content> - </object> -EOT; + $obj = json_encode(array( + 'type' => $objtype, + 'id' => $tagid, + 'link' => array(array('rel' => 'alternate','type' => 'text/html', 'href' => $tagid)), + 'title' => $term, + 'content' => $term + )); $bodyverb = t('%1$s tagged %2$s\'s %3$s with %4$s'); - if(! isset($bodyverb)) - return; + $termlink = html_entity_decode('⌗') . '[zrl=' . $a->get_baseurl() . '/search?tag=' . urlencode($term) . ']'. $term . '[/zrl]'; - $termlink = html_entity_decode('⌗') . '[url=' . $a->get_baseurl() . '/search?tag=' . urlencode($term) . ']'. $term . '[/url]'; + $channel = $a->get_channel(); $arr = array(); - $arr['uri'] = $uri; - $arr['uid'] = $owner_uid; - $arr['contact-id'] = $contact['id']; - $arr['type'] = 'activity'; - $arr['wall'] = $item['wall']; - $arr['gravity'] = GRAVITY_COMMENT; - $arr['parent'] = $item['id']; - $arr['parent_uri'] = $item['uri']; - $arr['owner-name'] = $item['author-name']; - $arr['owner-link'] = $item['author-link']; - $arr['owner-avatar'] = $item['author-avatar']; - $arr['author-name'] = $contact['name']; - $arr['author-link'] = $contact['url']; - $arr['author-avatar'] = $contact['thumb']; + $arr['owner_xchan'] = $item['owner_xchan']; + $arr['author_xchan'] = $channel['channel_hash']; + + + $arr['item_flags'] = ITEM_ORIGIN; + if($item['item_flags'] & ITEM_WALL) + $arr['item_flags'] |= ITEM_WALL; - $ulink = '[url=' . $contact['url'] . ']' . $contact['name'] . '[/url]'; - $alink = '[url=' . $item['author-link'] . ']' . $item['author-name'] . '[/url]'; - $plink = '[url=' . $item['plink'] . ']' . $post_type . '[/url]'; + $ulink = '[zrl=' . $channel['xchan_url'] . ']' . $channel['channel_name'] . '[/zrl]'; + $alink = '[zrl=' . $item['xchan_url'] . ']' . $item['xchan_name'] . '[/zrl]'; + $plink = '[zrl=' . $item['plink'] . ']' . $post_type . '[/zrl]'; + $arr['body'] = sprintf( $bodyverb, $ulink, $alink, $plink, $termlink ); $arr['verb'] = ACTIVITY_TAG; @@ -126,65 +122,14 @@ EOT; $arr['target'] = $target; $arr['obj_type'] = $objtype; $arr['object'] = $obj; - $arr['private'] = $item['private']; - $arr['allow_cid'] = $item['allow_cid']; - $arr['allow_gid'] = $item['allow_gid']; - $arr['deny_cid'] = $item['deny_cid']; - $arr['deny_gid'] = $item['deny_gid']; - $arr['visible'] = 1; - $arr['unseen'] = 1; - $arr['origin'] = 1; - - $post_id = item_store($arr); - - q("UPDATE `item` set plink = '%s' where id = %d limit 1", - dbesc($a->get_baseurl() . '/display/' . $owner_nick . '/' . $post_id), - intval($post_id) - ); - - - if(! $item['visible']) { - $r = q("UPDATE `item` SET `visible` = 1 WHERE `id` = %d AND `uid` = %d LIMIT 1", - intval($item['id']), - intval($owner_uid) - ); - } - - if((! $blocktags) && (! stristr($item['tag'], ']' . $term . '[' ))) { - q("update item set tag = '%s' where id = %d limit 1", - dbesc($item['tag'] . (strlen($item['tag']) ? ',' : '') . '#[url=' . $a->get_baseurl() . '/search?tag=' . $term . ']'. $term . '[/url]'), - intval($item['id']) - ); - } - - // if the original post is on this site, update it. - - $r = q("select `tag`,`id`,`uid` from item where `origin` = 1 AND `uri` = '%s' LIMIT 1", - dbesc($item['uri']) - ); - if(count($r)) { - $x = q("SELECT `blocktags` FROM `user` WHERE `uid` = %d limit 1", - intval($r[0]['uid']) - ); - if(count($x) && !$x[0]['blocktags'] && (! stristr($r[0]['tag'], ']' . $term . '['))) { - q("update item set tag = '%s' where id = %d limit 1", - dbesc($r[0]['tag'] . (strlen($r[0]['tag']) ? ',' : '') . '#[url=' . $a->get_baseurl() . '/search?tag=' . $term . ']'. $term . '[/url]'), - intval($r[0]['id']) - ); - } - - } - - - $arr['id'] = $post_id; - - call_hooks('post_local_end', $arr); + $arr['parent_mid'] = $item['mid']; + + store_item_tag($item['uid'],$item['id'],TERM_OBJ_POST,TERM_HASHTAG,$term,$tagid); + $ret = post_activity_item($arr); - proc_run('php',"include/notifier.php","tag","$post_id"); + if($ret['success']) + proc_run('php','include/notifier.php','tag',$ret['activity']['id']); killme(); - return; // NOTREACHED - - }
\ No newline at end of file diff --git a/mod/thing.php b/mod/thing.php new file mode 100644 index 000000000..91bdca78a --- /dev/null +++ b/mod/thing.php @@ -0,0 +1,196 @@ +<?php /** @file */ + +require_once('include/items.php'); + + +function thing_init(&$a) { + + if(! local_user()) + return; + + $account_id = $a->get_account(); + $channel = $a->get_channel(); + + + $name = escape_tags($_REQUEST['term']); + $verb = escape_tags($_REQUEST['verb']); + $profile_guid = escape_tags($_REQUEST['profile']); + $url = $_REQUEST['link']; + $photo = $_REQUEST['photo']; + + $hash = random_string(); + + + $verbs = obj_verbs(); + + /** + * verbs: [0] = first person singular, e.g. "I want", [1] = 3rd person singular, e.g. "Bill wants" + * We use the first person form when creating an activity, but the third person for use in activities + * FIXME: There is no accounting for verb gender for languages where this is significant. We may eventually + * require obj_verbs() to provide full conjugations and specify which form to use in the $_REQUEST params to this module. + */ + + $translated_verb = $verbs[$verb][1]; + + /** + * The site administrator can do things that normals cannot. + * This is restricted because it will likely cause + * an activitystreams protocol violation and the activity might + * choke in some other network and result in unnecessary + * support requests. It isn't because we're trying to be heavy-handed + * about what you can and can't do. + */ + + if(! $translated_verb) { + if(is_site_admin()) + $translated_verb = $verb; + } + + /** + * Things, objects: We do not provide definite (a, an) or indefinite (the) articles or singular/plural designators + * That needs to be specified in your thing. e.g. Mike has "a carrot", Greg wants "balls", Bob likes "the Boston Red Sox". + */ + + /** + * Future work on this module might produce more complex activities with targets, e.g. Phillip likes Karen's moustache + * and to describe other non-thing objects like channels, such as Karl wants Susan - where Susan represents a channel profile. + */ + + if((! $name) || (! $translated_verb)) + 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; + + + $r = q("select * from term where uid = %d and otype = %d and type = %d and term = '%s' limit 1", + intval(local_user()), + intval(TERM_OBJ_THING), + intval(TERM_THING), + dbesc($name) + ); + if(! $r) { + $r = q("insert into term ( aid, uid, oid, otype, type, term, url, imgurl, term_hash ) + values( %d, %d, %d, %d, %d, '%s', '%s', '%s', '%s' ) ", + intval($account_id), + intval(local_user()), + 0, + intval(TERM_OBJ_THING), + intval(TERM_THING), + dbesc($name), + dbesc(($url) ? $url : z_root() . '/thing/' . $hash), + dbesc(($photo) ? $photo : ''), + dbesc($hash) + ); + $r = q("select * from term where uid = %d and otype = %d and type = %d and term = '%s' limit 1", + intval(local_user()), + intval(TERM_OBJ_THING), + intval(TERM_THING), + dbesc($name) + ); + } + $term = $r[0]; + + $r = q("insert into obj ( obj_page, obj_verb, obj_type, obj_channel, obj_obj) values ('%s','%s', %d, %d, '%s') ", + dbesc($profile['profile_guid']), + dbesc($verb), + intval(TERM_OBJ_THING), + intval(local_user()), + dbesc($term['term_hash']) + ); + + if(! $r) { + notice( t('Object store: failed')); + return; + } + + info( t('thing/stuff added')); + + $arr = array(); + $links = array(array('rel' => 'alternate','type' => 'text/html', + 'href' => $term['url'])); + + $objtype = ACTIVITY_OBJ_THING; + + $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['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 ); + + $arr['verb'] = $verb; + $arr['obj_type'] = $objtype; + $arr['object'] = $obj; + + 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) + ); + if($r) { + $arr['allow_cid'] = ''; + foreach($r as $rr) + $arr['allow_cid'] .= '<' . $rr['abook_hash'] . '>'; + } + 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']); + +} + + +function thing_content(&$a) { + + /* placeholders */ + + if(argc() > 1) { + return t('not yet implemented.'); + } + + require_once('include/contact_selectors.php'); + + $o .= replace_macros(get_markup_template('thing_input.tpl'),array( + '$thing_hdr' => t('Add Stuff 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'), + '$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)'), + '$submit' => t('Submit') + )); + + return $o; + + +} diff --git a/mod/update_channel.php b/mod/update_channel.php index 19226297b..bdde0a3be 100644 --- a/mod/update_channel.php +++ b/mod/update_channel.php @@ -39,15 +39,17 @@ function update_channel_content(&$a) { $replace = "<img\${1} dst=\"\${2}\""; $text = preg_replace($pattern, $replace, $text); - $replace = '<br />' . t('[Embedded content - reload page to view]') . '<br />'; - $pattern = "/<\s*audio[^>]*>(.*?)<\s*\/\s*audio>/i"; - $text = preg_replace($pattern, $replace, $text); - $pattern = "/<\s*video[^>]*>(.*?)<\s*\/\s*video>/i"; - $text = preg_replace($pattern, $replace, $text); - $pattern = "/<\s*embed[^>]*>(.*?)<\s*\/\s*embed>/i"; - $text = preg_replace($pattern, $replace, $text); - $pattern = "/<\s*iframe[^>]*>(.*?)<\s*\/\s*iframe>/i"; - $text = preg_replace($pattern, $replace, $text); + if(! $load) { + $replace = '<br />' . t('[Embedded content - reload page to view]') . '<br />'; + $pattern = "/<\s*audio[^>]*>(.*?)<\s*\/\s*audio>/i"; + $text = preg_replace($pattern, $replace, $text); + $pattern = "/<\s*video[^>]*>(.*?)<\s*\/\s*video>/i"; + $text = preg_replace($pattern, $replace, $text); + $pattern = "/<\s*embed[^>]*>(.*?)<\s*\/\s*embed>/i"; + $text = preg_replace($pattern, $replace, $text); + $pattern = "/<\s*iframe[^>]*>(.*?)<\s*\/\s*iframe>/i"; + $text = preg_replace($pattern, $replace, $text); + } /** * reportedly some versions of MSIE don't handle tabs in XMLHttpRequest documents very well diff --git a/mod/update_display.php b/mod/update_display.php index c8eb9c3a3..5802852bb 100644 --- a/mod/update_display.php +++ b/mod/update_display.php @@ -16,11 +16,12 @@ function update_display_content(&$a) { echo (($_GET['msie'] == 1) ? '<div>' : '<section>'); - $text = display_content($a,$profile_uid, $load); - $pattern = "/<img([^>]*) src=\"([^\"]*)\"/"; - $replace = "<img\${1} dst=\"\${2}\""; - $text = preg_replace($pattern, $replace, $text); + $text = display_content($a,$profile_uid, $load); + $pattern = "/<img([^>]*) src=\"([^\"]*)\"/"; + $replace = "<img\${1} dst=\"\${2}\""; + $text = preg_replace($pattern, $replace, $text); + if(! $load) { $replace = '<br />' . t('[Embedded content - reload page to view]') . '<br />'; $pattern = "/<\s*audio[^>]*>(.*?)<\s*\/\s*audio>/i"; $text = preg_replace($pattern, $replace, $text); @@ -30,9 +31,9 @@ function update_display_content(&$a) { $text = preg_replace($pattern, $replace, $text); $pattern = "/<\s*iframe[^>]*>(.*?)<\s*\/\s*iframe>/i"; $text = preg_replace($pattern, $replace, $text); + } - - echo str_replace("\t",' ',$text); + echo str_replace("\t",' ',$text); echo (($_GET['msie'] == 1) ? '</div>' : '</section>'); echo "</body></html>\r\n"; // logger('update_display: ' . $text); diff --git a/mod/update_network.php b/mod/update_network.php index 16de19365..bb6245f65 100644 --- a/mod/update_network.php +++ b/mod/update_network.php @@ -19,16 +19,17 @@ function update_network_content(&$a) { $replace = "<img\${1} dst=\"\${2}\""; $text = preg_replace($pattern, $replace, $text); - $replace = '<br />' . t('[Embedded content - reload page to view]') . '<br />'; - $pattern = "/<\s*audio[^>]*>(.*?)<\s*\/\s*audio>/i"; - $text = preg_replace($pattern, $replace, $text); - $pattern = "/<\s*video[^>]*>(.*?)<\s*\/\s*video>/i"; - $text = preg_replace($pattern, $replace, $text); - $pattern = "/<\s*embed[^>]*>(.*?)<\s*\/\s*embed>/i"; - $text = preg_replace($pattern, $replace, $text); - $pattern = "/<\s*iframe[^>]*>(.*?)<\s*\/\s*iframe>/i"; - $text = preg_replace($pattern, $replace, $text); - + if(! $load) { + $replace = '<br />' . t('[Embedded content - reload page to view]') . '<br />'; + $pattern = "/<\s*audio[^>]*>(.*?)<\s*\/\s*audio>/i"; + $text = preg_replace($pattern, $replace, $text); + $pattern = "/<\s*video[^>]*>(.*?)<\s*\/\s*video>/i"; + $text = preg_replace($pattern, $replace, $text); + $pattern = "/<\s*embed[^>]*>(.*?)<\s*\/\s*embed>/i"; + $text = preg_replace($pattern, $replace, $text); + $pattern = "/<\s*iframe[^>]*>(.*?)<\s*\/\s*iframe>/i"; + $text = preg_replace($pattern, $replace, $text); + } echo str_replace("\t",' ',$text); echo (($_GET['msie'] == 1) ? '</div>' : '</section>'); diff --git a/mod/update_search.php b/mod/update_search.php new file mode 100644 index 000000000..ec7599b79 --- /dev/null +++ b/mod/update_search.php @@ -0,0 +1,66 @@ +<?php + +/** + * Module: update_profile + * Purpose: AJAX synchronisation of search page + * + */ + + +require_once('mod/search.php'); + +function update_search_content(&$a) { + + $profile_uid = intval($_GET['p']); + if(! $profile_uid) + $profile_uid = (-1); + + $load = (((argc() > 1) && (argv(1) == 'load')) ? 1 : 0); + + header("Content-type: text/html"); + echo "<!DOCTYPE html><html><body>\r\n"; + + /** + * We can remove this hack once Internet Explorer recognises HTML5 natively + */ + + echo (($_GET['msie'] == 1) ? '<div>' : '<section>'); + + /** + * + * Grab the page inner contents by calling the content function from the profile module directly, + * but move any image src attributes to another attribute name. This is because + * some browsers will prefetch all the images for the page even if we don't need them. + * The only ones we need to fetch are those for new page additions, which we'll discover + * on the client side and then swap the image back. + * + */ + + $text = search_content($a,$profile_uid,$load); + + $pattern = "/<img([^>]*) src=\"([^\"]*)\"/"; + $replace = "<img\${1} dst=\"\${2}\""; + $text = preg_replace($pattern, $replace, $text); + + if(! $load) { + $replace = '<br />' . t('[Embedded content - reload page to view]') . '<br />'; + $pattern = "/<\s*audio[^>]*>(.*?)<\s*\/\s*audio>/i"; + $text = preg_replace($pattern, $replace, $text); + $pattern = "/<\s*video[^>]*>(.*?)<\s*\/\s*video>/i"; + $text = preg_replace($pattern, $replace, $text); + $pattern = "/<\s*embed[^>]*>(.*?)<\s*\/\s*embed>/i"; + $text = preg_replace($pattern, $replace, $text); + $pattern = "/<\s*iframe[^>]*>(.*?)<\s*\/\s*iframe>/i"; + $text = preg_replace($pattern, $replace, $text); + } + + /** + * reportedly some versions of MSIE don't handle tabs in XMLHttpRequest documents very well + */ + + echo str_replace("\t",' ',$text); + echo (($_GET['msie'] == 1) ? '</div>' : '</section>'); + echo "</body></html>\r\n"; + killme(); + +}
\ No newline at end of file diff --git a/mod/viewconnections.php b/mod/viewconnections.php index e6c739562..9c85d63b6 100644 --- a/mod/viewconnections.php +++ b/mod/viewconnections.php @@ -63,18 +63,19 @@ function viewconnections_content(&$a) { foreach($r as $rr) { $url = zid($rr['xchan_url']); - - $contacts[] = array( - 'id' => $rr['abook_id'], - 'img_hover' => sprintf( t('Visit %s\'s profile [%s]'), $rr['xchan_name'], $rr['xchan_url']), - 'thumb' => $rr['xchan_photo_m'], - 'name' => substr($rr['xchan_name'],0,20), - 'username' => $rr['xchan_addr'], - 'url' => $url, - 'sparkle' => '', - 'itemurl' => $rr['url'], - 'network' => '', - ); + if($url) { + $contacts[] = array( + 'id' => $rr['abook_id'], + 'img_hover' => sprintf( t('Visit %s\'s profile [%s]'), $rr['xchan_name'], $rr['xchan_url']), + 'thumb' => $rr['xchan_photo_m'], + 'name' => substr($rr['xchan_name'],0,20), + 'username' => $rr['xchan_addr'], + 'link' => $url, + 'sparkle' => '', + 'itemurl' => $rr['url'], + 'network' => '', + ); + } } diff --git a/mod/wall_upload.php b/mod/wall_upload.php index cee40744f..dd5d760b3 100644 --- a/mod/wall_upload.php +++ b/mod/wall_upload.php @@ -1,6 +1,6 @@ <?php -require_once('Photo.php'); +require_once('include/photo/photo_driver.php'); require_once('include/photos.php'); @@ -52,8 +52,11 @@ function wall_upload_post(&$a) { $m = $ret['body']; + // This might make Friendica for Android uploads work again, as it won't have any knowledge of zrl and zmg tags + // and these tags probably aren't useful with other client apps. + if($using_api) - return($ret['body']); + return(str_replace(array('zrl','zmg'),array('url','img'),$ret['body'])); else echo "\n\n" . $ret['body'] . "\n\n"; killme(); diff --git a/mod/webpages.php b/mod/webpages.php new file mode 100644 index 000000000..f2026ea0b --- /dev/null +++ b/mod/webpages.php @@ -0,0 +1,76 @@ +<?php + +function webpages_init(&$a) { + + if(argc() > 1) + $which = argv(1); + else { + notice( t('Requested profile is not available.') . EOL ); + $a->error = 404; + return; + } + + $profile = 0; + $channel = $a->get_channel(); + + if((local_user()) && (argc() > 2) && (argv(2) === 'view')) { + $which = $channel['channel_address']; + $profile = argv(1); + } + + profile_load($a,$which,$profile); + +} + +function webpages_content(&$a) { + +// We can do better, but since editing only works for local users and all posts are webpages, return anyone else for now. + +if (!local_user()) return; + + +// Create a status editor (for now - we'll need a WYSIWYG eventually) to create pages +require_once ('include/conversation.php'); + $x = array( + 'webpage' => 1, + 'is_owner' => true, + 'nickname' => $a->profile['channel_address'], + 'lockstate' => (($group || $cid || $channel['channel_allow_cid'] || $channel['channel_allow_gid'] || $channel['channel_deny_cid'] || $channel['channel_deny_gid']) ? 'lock' : 'unlock'), + 'bang' => (($group || $cid) ? '!' : ''), + 'visitor' => 'block', + 'profile_uid' => local_user() + ); + + $o .= status_editor($a,$x); + +//Get a list of webpages. We can't display all them because endless scroll makes that unusable, so just list titles and an edit link. +// FIXME - we should sort these results, but it's not obvious what order yet. Alphabetical? Created order? + +$r = q("select * from item_id where uid = %d and service = 'WEBPAGE'", + intval(local_user()) +); + + $pages = null; + + if($r) { + $pages = array(); + foreach($r as $rr) { + $pages[$rr['iid']][] = array('url' => $rr['iid'],'title' => $rr['sid']); + } + } + + +//Build the base URL for edit links + $url = z_root() . "/editwebpage/" . $a->profile['channel_address']; +// This isn't pretty, but it works. Until I figure out what to do with the UI, it's Good Enough(TM). + return $o . replace_macros(get_markup_template("webpagelist.tpl"), array( + '$baseurl' => $url, + '$edit' => t('Edit'), + '$pages' => $pages, + '$channel' => $a->profile['channel_address'], + '$view' => t('View'), + + )); + + +} diff --git a/mod/wfinger.php b/mod/wfinger.php new file mode 100644 index 000000000..33d2fe478 --- /dev/null +++ b/mod/wfinger.php @@ -0,0 +1,99 @@ +<?php + +function wfinger_init(&$a) { + + $result = array(); + + $scheme = ''; + + if(x($_SERVER,'HTTPS') && $_SERVER['HTTPS']) + $scheme = 'https'; + elseif(x($_SERVER,'SERVER_PORT') && (intval($_SERVER['SERVER_PORT']) == 443)) + $scheme = 'https'; + + // Don't complain to me - I'm just implementing the spec. + + if($scheme !== 'https') { + header($_SERVER["SERVER_PROTOCOL"] . ' ' . 500 . ' ' . 'Webfinger requires HTTPS'); + killme(); + } + + $resource = $_REQUEST['resource']; + + header('Access-Control-Allow-Origin: *'); + + header('Content-type: application/jrd+json'); + + $r = null; + + if($resource) { + + if(strpos($resource,'acct:') === 0) { + $channel = str_replace('acct:','',$resource); + $channel = substr($channel,0,strpos($channel,'@')); + } + if(strpos($resource,'http') === 0) { + $channel = str_replace('~','',basename($resource)); + } + + $r = q("select * from channel left join xchan on channel_hash = xchan_hash + where channel_address = '%s' limit 1", + dbesc($channel) + ); + + } + + if($resource && $r) { + + $result['subject'] = $resource; + + $aliases = array( + 'acct:' . $r[0]['channel_address'] . '@' . $a->get_hostname(), + z_root() . '/channel/' . $r[0]['channel_address'], + z_root() . '/~' . $r[0]['channel_address'] + ); + + $result['aliases'] = array(); + + foreach($aliases as $alias) + if($alias != $resource) + $result['aliases'][] = $alias; + + + $result['links'] = array( + + array( + 'rel' => 'http://webfinger.example/rel/avatar', + 'type' => $r[0]['xchan_photo_mimetype'], + 'href' => $r[0]['xchan_photo_l'] + ), + + array( + 'rel' => 'http://webfinger.example/rel/profile-page', + 'href' => z_root() . '/profile/' . $r[0]['channel_address'], + ), + + array( + 'rel' => 'http://webfinger.example/rel/blog', + 'href' => z_root() . '/channel/' . $r[0]['channel_address'], + ), + + array( + 'rel' => 'http://purl.org/zot/protocol', + 'href' => z_root() . '/.well-known/zot-info' . '?zaddr=' . $r[0]['xchan_addr'], + ) + ); + + } + else { + header($_SERVER["SERVER_PROTOCOL"] . ' ' . 400 . ' ' . 'Bad Request'); + killme(); + } + + $arr = array('channel' => $r[0], 'request' => $_REQUEST, 'result' => $result); + call_hooks('webfinger',$arr); + + echo json_encode($arr['result']); + killme(); + +}
\ No newline at end of file diff --git a/mod/zfinger.php b/mod/zfinger.php index 74353e8f9..a3da62162 100644 --- a/mod/zfinger.php +++ b/mod/zfinger.php @@ -91,6 +91,9 @@ function zfinger_init(&$a) { $profile['birthday'] = $p[0]['dob']; if($profile['birthday'] != '0000-00-00') $profile['next_birthday'] = z_birthday($p[0]['dob'],$e['channel_timezone']); + + if($age = age($p[0]['dob'],$e['channel_timezone'],'')) + $profile['age'] = $age; $profile['gender'] = $p[0]['gender']; $profile['marital'] = $p[0]['marital']; $profile['sexual'] = $p[0]['sexual']; @@ -145,6 +148,12 @@ function zfinger_init(&$a) { // array of (verified) hubs this channel uses $ret['locations'] = array(); + + + + + + $x = zot_get_hubloc(array($e['channel_hash'])); if($x && count($x)) { foreach($x as $hub) { @@ -164,6 +173,8 @@ function zfinger_init(&$a) { $ret['site'] = array(); $ret['site']['url'] = z_root(); + $ret['site']['url_sig'] = base64url_encode(rsa_sign(z_root(),$e['channel_prvkey'])); + $dirmode = get_config('system','directory_mode'); if(($dirmode === false) || ($dirmode == DIRECTORY_MODE_NORMAL)) $ret['site']['directory_mode'] = 'normal'; @@ -175,7 +186,46 @@ function zfinger_init(&$a) { $ret['site']['directory_mode'] = 'standalone'; if($dirmode != DIRECTORY_MODE_NORMAL) $ret['site']['directory_url'] = z_root() . '/dirsearch'; - + + + // hide detailed site information if you're off the grid + + if($dirmode != DIRECTORY_MODE_STANDALONE) { + + $register_policy = intval(get_config('system','register_policy')); + + + if($register_policy == REGISTER_CLOSED) + $ret['site']['register_policy'] = 'closed'; + if($register_policy == REGISTER_APPROVE) + $ret['site']['register_policy'] = 'approve'; + if($register_policy == REGISTER_OPEN) + $ret['site']['register_policy'] = 'open'; + + require_once('include/account.php'); + $ret['site']['accounts'] = account_total(); + + require_once('include/identity.php'); + $ret['site']['channels'] = channel_total(); + + + $ret['site']['version'] = RED_PLATFORM . ' ' . RED_VERSION . '[' . DB_UPDATE_VERSION . ']'; + + $ret['site']['admin'] = get_config('system','admin_email'); + + $visible_plugins = array(); + if(is_array($a->plugins) && count($a->plugins)) { + $r = q("select * from addon where hidden = 0"); + if($r) + foreach($r as $rr) + $visible_plugins[] = $rr['name']; + } + + $ret['site']['plugins'] = $visible_plugins; + $ret['site']['sitehash'] = get_config('system','location_hash'); + $ret['site']['sitename'] = get_config('system','sitename'); + + } json_return_and_die($ret); }
\ No newline at end of file diff --git a/mod/zotfeed.php b/mod/zotfeed.php index 76a860139..2ca049563 100644 --- a/mod/zotfeed.php +++ b/mod/zotfeed.php @@ -9,7 +9,7 @@ function zotfeed_init(&$a) { $mindate = (($_REQUEST['mindate']) ? datetime_convert('UTC','UTC',$_REQUEST['mindate']) : ''); if(! $mindate) - $mindate = '0000-00-00 00:00:00'; + $mindate = datetime_convert('UTC','UTC', 'now - 1 month'); if(get_config('system','block_public') && (! get_account_id()) && (! remote_user())) { $result['message'] = 'Public access denied'; diff --git a/mod/zperms.php b/mod/zperms.php deleted file mode 100644 index 6a7097cd6..000000000 --- a/mod/zperms.php +++ /dev/null @@ -1,84 +0,0 @@ -<?php - -function zperms_init(&$a) { - - require_once('include/zot.php'); - require_once('include/Contact.php'); - require_once('include/crypto.php'); - - $ret = array('success' => false); - - $zguid = ((x($_REQUEST,'guid')) ? $_REQUEST['guid'] : ''); - $zaddr = ((x($_REQUEST,'address')) ? $_REQUEST['address'] : ''); - $ztarget = ((x($_REQUEST,'target')) ? $_REQUEST['target'] : ''); - $zsig = ((x($_REQUEST,'target_sig')) ? $_REQUEST['target_sig'] : ''); - - $r = null; - - if(strlen($zguid)) { - $r = q("select * from channel where channel_guid = '%s' limit 1", - dbesc($zguid) - ); - } - elseif(strlen($zaddr)) { - $r = q("select * from channel where channel_address = '%s' limit 1", - dbesc($zaddr) - ); - } - else { - $ret['message'] = 'Invalid request'; - json_return_and_die($ret); - } - - if(! ($r && count($r))) { - $ret['message'] = 'Item not found.'; - json_return_and_die($ret); - } - $e = $r[0]; - - $id = $e['channel_id']; - $r = q("select contact.*, profile.* - from contact left join profile on contact.uid = profile.uid - where contact.uid = %d && contact.self = 1 and profile.is_default = 1 limit 1", - intval($id) - ); - if($r && count($r)) { - $profile = $r[0]; - } - - - - $ret['success'] = true; - $ret['guid'] = $e['channel_guid']; - $ret['guid_sig'] = base64url_encode(rsa_sign($e['channel_guid'],$e['channel_prvkey'])); - $ret['key'] = $e['channel_pubkey']; - $ret['name'] = $e['channel_name']; - $ret['address'] = $e['channel_address']; - $ret['target'] = $ztarget; - $ret['target_sig'] = $zsig; - $ret['permissions'] = map_perms($r[0],$ztarget,$zsig); - - $ret['profile'] = $profile; - - // array of (verified) hubs this channel uses - - $ret['hubs'] = array(); - $x = zot_get_hubloc(array($e['channel_guid'])); - if($x && count($x)) { - foreach($x as $hub) { - if(! ($hub['hubloc_flags'] & HUBLOC_FLAGS_UNVERIFIED)) { - $ret['hubs'][] = array( - 'primary' => (($hub['hubloc_flags'] & HUBLOC_FLAGS_PRIMARY) ? true : false), - 'url' => $hub['hubloc_url'], - /// hmmm we probably shouldn't sign somebody else's hub. FIXME - 'url_sig' => base64url_encode(rsa_sign($hub['hubloc_url'],$e['channel_prvkey'])), - 'callback' => $hub['hubloc_callback'], - 'sitekey' => $hub['hubloc_sitekey'] - ); - } - } - } - - json_return_and_die($ret); - -} |