diff options
Diffstat (limited to 'mod')
49 files changed, 2009 insertions, 607 deletions
diff --git a/mod/acl.php b/mod/acl.php index 143b8098e..b886b7e58 100644 --- a/mod/acl.php +++ b/mod/acl.php @@ -51,7 +51,7 @@ function acl_init(&$a){ $r = q("SELECT COUNT(abook_id) AS c FROM abook left join xchan on abook_xchan = xchan_hash WHERE abook_channel = %d AND not ( abook_flags & %d ) $sql_extra2" , intval(local_user()), - intval(ABOOK_FLAG_SELF|ABOOK_FLAG_BLOCKED|ABOOK_FLAG_PENDING|ABOOK_FLAG_ARCHIVE) + intval(ABOOK_FLAG_SELF|ABOOK_FLAG_BLOCKED|ABOOK_FLAG_PENDING|ABOOK_FLAG_ARCHIVED) ); $contact_count = (int)$r[0]['c']; } @@ -77,9 +77,8 @@ function acl_init(&$a){ // autocomplete for Contacts - $r = q("SELECT COUNT(`id`) AS c FROM `contact` - WHERE `uid` = %d AND `self` = 0 - AND `pending` = 0 $sql_extra2" , + $r = q("SELECT COUNT(abook_id) AS c FROM abook left join xchan on abook_xchan = xchan_hash + WHERE abook_channel = %d $sql_extra2" , intval(local_user()) ); $contact_count = (int)$r[0]['c']; @@ -128,7 +127,7 @@ function acl_init(&$a){ 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()), - intval(ABOOK_FLAG_SELF|ABOOK_FLAG_BLOCKED|ABOOK_FLAG_PENDING|ABOOK_FLAG_ARCHIVE) + intval(ABOOK_FLAG_SELF|ABOOK_FLAG_BLOCKED|ABOOK_FLAG_PENDING|ABOOK_FLAG_ARCHIVED) ); } elseif($type == 'm') { diff --git a/mod/admin.php b/mod/admin.php index df1a40019..fad03e34a 100644 --- a/mod/admin.php +++ b/mod/admin.php @@ -49,11 +49,15 @@ function admin_post(&$a){ if(is_ajax()) return; goaway($a->get_baseurl(true) . '/admin/themes/' . $theme ); + return; break; case 'logs': admin_page_logs_post($a); break; + case 'hubloc': + admin_page_hubloc_post($a); + break; case 'dbsync': admin_page_dbsync_post($a); break; @@ -84,6 +88,7 @@ function admin_content(&$a) { 'users' => Array($a->get_baseurl(true)."/admin/users/", t("Users") , "users"), 'plugins'=> Array($a->get_baseurl(true)."/admin/plugins/", t("Plugins") , "plugins"), 'themes' => Array($a->get_baseurl(true)."/admin/themes/", t("Themes") , "themes"), + 'hubloc' => Array($a->get_baseurl(true)."/admin/hubloc/", t("Server") , "server"), 'dbsync' => Array($a->get_baseurl(true)."/admin/dbsync/", t('DB updates'), "dbsync") ); @@ -132,6 +137,9 @@ function admin_content(&$a) { case 'themes': $o = admin_page_themes($a); break; + case 'hubloc': + $o = admin_page_hubloc($a); + break; case 'logs': $o = admin_page_logs($a); break; @@ -235,7 +243,7 @@ function admin_page_site_post(&$a){ $timeout = ((x($_POST,'timeout')) ? intval(trim($_POST['timeout'])) : 60); $delivery_interval = ((x($_POST,'delivery_interval'))? intval(trim($_POST['delivery_interval'])) : 0); $poll_interval = ((x($_POST,'poll_interval'))? intval(trim($_POST['poll_interval'])) : 0); - $ssl_policy = ((x($_POST,'ssl_policy')) ? intval($_POST['ssl_policy']) : 0); +// $ssl_policy = ((x($_POST,'ssl_policy')) ? intval($_POST['ssl_policy']) : 0); /* if($ssl_policy != intval(get_config('system','ssl_policy'))) { if($ssl_policy == SSL_POLICY_FULL) { @@ -278,7 +286,7 @@ function admin_page_site_post(&$a){ } } */ - set_config('system','ssl_policy',$ssl_policy); +// set_config('system','ssl_policy',$ssl_policy); set_config('system','delivery_interval',$delivery_interval); set_config('system','poll_interval',$poll_interval); set_config('system','maxloadavg',$maxloadavg); @@ -365,11 +373,11 @@ function admin_page_site(&$a) { 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_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')) { + if (file_exists($file . '/accessibility')) { $theme_choices_accessibility[$f] = $theme_name; } $theme_choices[$f] = $theme_name; @@ -394,13 +402,14 @@ function admin_page_site(&$a) { $access_choices = Array( ACCESS_PRIVATE => t("Private"), ACCESS_PAID => t("Paid Access"), - ACCESS_FREE => t("Free Access") + ACCESS_FREE => t("Free Access"), + ACCESS_TIERED => t("Tiered Access") ); - $ssl_choices = array( - SSL_POLICY_NONE => t("No SSL policy, links will track page SSL state"), - SSL_POLICY_FULL => t("Force all links to use SSL") - ); +// $ssl_choices = array( +// SSL_POLICY_NONE => t("No SSL policy, links will track page SSL state"), +// SSL_POLICY_FULL => t("Force all links to use SSL") +// ); $t = get_markup_template("admin_site.tpl"); return replace_macros($t, array( @@ -421,7 +430,7 @@ function admin_page_site(&$a) { '$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), +// '$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"), get_config('system','register_policy'), "", $register_choices), '$access_policy' => array('access_policy', t("Access policy"), get_config('system','access_policy'), "", $access_choices), @@ -443,6 +452,34 @@ function admin_page_site(&$a) { )); } +function admin_page_hubloc_post(&$a){ + check_form_security_token_redirectOnErr('/admin/hubloc', 'hubloc'); + return; +} + +function admin_page_hubloc(&$a) { + $o = ''; + $hubloc = q("SELECT hubloc_id, hubloc_addr, hubloc_host, hubloc_status FROM hubloc"); + + + if(! $hubloc){ + notice( t('No server found') . EOL); + goaway($a->get_baseurl(true) . '/admin/hubloc'); + } + + $t = get_markup_template("admin_hubloc.tpl"); + return replace_macros($t, array( + '$hubloc' => $hubloc, + '$th_hubloc' => array(t('ID'), t('for channel'), t('on server'), t('Status')), + '$title' => t('Administration'), + '$page' => t('Server'), + '$queues' => $queues, + '$accounts' => $accounts, + '$pending' => Array( t('Pending registrations'), $pending), + '$plugins' => Array( t('Active plugins'), $a->plugins ) + )); + return $o; +} function admin_page_dbsync(&$a) { @@ -714,12 +751,16 @@ function admin_page_plugins(&$a){ } $admin_form=""; + if (is_array($a->plugins_admin) && in_array($plugin, $a->plugins_admin)){ @require_once("addon/$plugin/$plugin.php"); - $func = $plugin.'_plugin_admin'; - $func($a, $admin_form); + if(function_exists($plugin.'_plugin_admin')) { + $func = $plugin.'_plugin_admin'; + $func($a, $admin_form); + } } - + + $t = get_markup_template("admin_plugins_details.tpl"); return replace_macros($t, array( '$title' => t('Administration'), diff --git a/mod/blocks.php b/mod/blocks.php new file mode 100644 index 000000000..170d37256 --- /dev/null +++ b/mod/blocks.php @@ -0,0 +1,101 @@ +<?php + +function blocks_content(&$a) { + + + + if(argc() > 1) + $which = argv(1); + else { + notice( t('Requested profile is not available.') . EOL ); + $a->error = 404; + return; + } + + profile_load($a,$which,0); + + + // Figure out who the page owner is. + $r = q("select channel_id from channel where channel_address = '%s'", + dbesc($which) + ); + if($r) { + $owner = intval($r[0]['channel_id']); + } + + // Block design features from visitors + + if((! local_user()) || (local_user() != $owner)) { + notice( t('Permission denied.') . EOL); + return; + } + + + + +// Get the observer, check their permissions + + $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; + } + + if(local_user() && local_user() == $owner) { + $a->set_widget('design',design_tools()); + } + + + +// Create a status editor (for now - we'll need a WYSIWYG eventually) to create pages +// Nickname is set to the observers xchan, and profile_uid to the owners. This lets you post pages at other people's channels. +require_once ('include/conversation.php'); + $x = array( + 'webpage' => ITEM_BUILDBLOCK, + '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', + 'mimetype' => 'choose', + 'profile_uid' => intval($owner), + ); + + $o .= status_editor($a,$x); + + //Get a list of blocks. We can't display all them because endless scroll makes that unusable, so just list titles and an edit link. +//TODO - this should be replaced with pagelist_widget + +$r = q("select * from item_id where uid = %d and service = 'BUILDBLOCK' order by sid asc", + intval($owner) +); + + $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() . "/editblock/" . $which; +// 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' => $which, + '$view' => t('View'), + '$preview' => '1', + + )); + + +} diff --git a/mod/chanman.php b/mod/chanman.php new file mode 100644 index 000000000..7a89708d7 --- /dev/null +++ b/mod/chanman.php @@ -0,0 +1,31 @@ +<?php /** @file */ + + +/** + Placeholder file at present. This is going to involve a bit of work. + + This file will deal with the deletion of channels and management of hublocs. + + We need to provide the following functionality: + + - Delete my account and all channels from the entire network + + - Delete my account and all channels from this server + + - Delete a channel from the entire network + + - Delete a channel from this server + + - List all hub locations for this channel + + - Remove this/some hub location from this channel + + - promote this/some hub location to primary + + - Remove hub location 'xyz' from this channel, (this should possibly only be allowed if that hub has been down for a period of time) + + - Some of these actions should probably require email verification + +*/ + + diff --git a/mod/channel.php b/mod/channel.php index aa158d330..e5af91b53 100644 --- a/mod/channel.php +++ b/mod/channel.php @@ -64,17 +64,18 @@ function channel_content(&$a, $update = 0, $load = false) { $category = $datequery = $datequery2 = ''; - if(argc() > 2) { - for($x = 2; $x < argc(); $x ++) { - if(is_a_date_arg(argv($x))) { - if($datequery) - $datequery2 = escape_tags(argv($x)); - else - $datequery = escape_tags(argv($x)); - } - } - } - + // if(argc() > 2) { + // for($x = 2; $x < argc(); $x ++) { + // if(is_a_date_arg(argv($x))) { + // if($datequery) + // $datequery2 = escape_tags(argv($x)); + // else + // $datequery = escape_tags(argv($x)); + // } + // } + // } + $datequery = ((x($_GET,'dend') && is_a_date_arg($_GET['dend'])) ? notags($_GET['dend']) : ''); + $datequery2 = ((x($_GET,'dbegin') && is_a_date_arg($_GET['dbegin'])) ? notags($_GET['dbegin']) : ''); if(get_config('system','block_public') && (! get_account_id()) && (! remote_user())) { return login(); @@ -90,6 +91,8 @@ function channel_content(&$a, $update = 0, $load = false) { require_once('include/permissions.php'); + $category = ((x($_REQUEST,'cat')) ? $_REQUEST['cat'] : ''); + $groups = array(); $o = ''; @@ -112,6 +115,11 @@ function channel_content(&$a, $update = 0, $load = false) { $perms = get_all_perms($a->profile['profile_uid'],$ob_hash); if(! $perms['view_stream']) { + // We may want to make the target of this redirect configurable + if($perms['view_profile']) { + notice( t('Insufficient permissions. Request redirected to profile page.') . EOL); + goaway (z_root() . "/profile/" . $a->profile['channel_address']); + } notice( t('Permission denied.') . EOL); return; } @@ -171,8 +179,9 @@ function channel_content(&$a, $update = 0, $load = false) { } else { + if(x($category)) { - $sql_extra .= protect_sprintf(file_tag_file_query('item',$category,'category')); + $sql_extra .= protect_sprintf(term_query('item', $category, TERM_CATEGORY)); } if($datequery) { @@ -182,9 +191,8 @@ function channel_content(&$a, $update = 0, $load = false) { $sql_extra2 .= protect_sprintf(sprintf(" AND item.created >= '%s' ", dbesc(datetime_convert(date_default_timezone_get(),'',$datequery2)))); } - - $a->set_pager_itemspage(40); - + $itemspage = get_pconfig(local_user(),'system','itemspage'); + $a->set_pager_itemspage(((intval($itemspage)) ? $itemspage : 20)); $pager_sql = sprintf(" LIMIT %d, %d ",intval($a->pager['start']), intval($a->pager['itemspage'])); if($load) { diff --git a/mod/chanview.php b/mod/chanview.php index 4f7638846..f183fbdf1 100644 --- a/mod/chanview.php +++ b/mod/chanview.php @@ -79,16 +79,20 @@ function chanview_content(&$a) { return; } - if($xchan['xchan_hash']) - $a->set_widget('vcard',vcard_from_xchan($xchan,$observer,'chanview')); - $url = (($observer) ? z_root() . '/magic?f=&dest=' . $xchan['xchan_url'] . '&addr=' . $xchan['xchan_addr'] : $xchan['xchan_url'] ); - + // let somebody over-ride the iframed viewport presentation + + if(local_user() && get_pconfig(local_user(),'system','chanview_full')) + goaway($url); + + if($xchan['xchan_hash']) + $a->set_widget('vcard',vcard_from_xchan($xchan,$observer,'chanview')); + $o = replace_macros(get_markup_template('chanview.tpl'),array( '$url' => $url, '$full' => t('toggle full screen mode') diff --git a/mod/connect.php b/mod/connect.php new file mode 100644 index 000000000..93f994af5 --- /dev/null +++ b/mod/connect.php @@ -0,0 +1,128 @@ +<?php /** @file */ + + +require_once('include/Contact.php'); +require_once('include/contact_widgets.php'); +require_once('include/items.php'); + + +function connect_init(&$a) { + if(argc() > 1) + $which = argv(1); + else { + notice( t('Requested profile is not available.') . EOL ); + $a->error = 404; + return; + } + + $r = q("select * from channel where channel_address = '%s' limit 1", + dbesc($which) + ); + + if($r) + $a->data['channel'] = $r[0]; + + profile_load($a,$which,''); + + profile_create_sidebar($a,false); + + +} + +function connect_post(&$a) { + + if(! array_key_exists('channel', $a->data)) + return; + + $edit = ((local_user() && (local_user() == $a->data['channel']['channel_id'])) ? true : false); + + if($edit) { + $has_premium = (($a->data['channel']['channel_pageflags'] & PAGE_PREMIUM) ? 1 : 0); + $premium = (($_POST['premium']) ? intval($_POST['premium']) : 0); + $text = escape_tags($_POST['text']); + + if($has_premium != $premium) { + $r = q("update channel set channel_pageflags = ( channel_pageflags ^ %d ) where channel_id = %d limit 1", + intval(PAGE_PREMIUM), + intval(local_user()) + ); + proc_run('php','include/notifier.php','refresh_all',$a->data['channel']['channel_id']); + } + set_pconfig($a->data['channel']['channel_id'],'system','selltext',$text); + // reload the page completely to get fresh data + goaway(z_root() . '/' . $a->query_string); + + } + + $url = ''; + $observer = $a->get_observer(); + if(($observer) && ($_POST['submit'] === t('Continue'))) { + if($observer['xchan_follow']) + $url = sprintf($observer['xchan_follow'],urlencode($a->data['channel']['channel_address'] . '@' . $a->get_hostname())); + if(! $url) { + $r = q("select * from hubloc where hubloc_hash = '%s' order by hubloc_id desc limit 1", + dbesc($observer['xchan_hash']) + ); + if($r) + $url = $r[0]['hubloc_url'] . '/follow?f=&url=' . urlencode($a->data['channel']['channel_address'] . '@' . $a->get_hostname()); + } + } + if($url) + goaway($url . '&confirm=1'); + else + notice('Unable to connect to your home hub location.'); + +} + + + +function connect_content(&$a) { + + $edit = ((local_user() && (local_user() == $a->data['channel']['channel_id'])) ? true : false); + + $text = get_pconfig($a->data['channel']['channel_id'],'system','selltext'); + + if($edit) { + + $o = replace_macros(get_markup_template('sellpage_edit.tpl'),array( + '$header' => t('Premium Channel Setup'), + '$address' => $a->data['channel']['channel_address'], + '$premium' => array('premium', t('Enable premium channel connection restrictions'),(($a->data['channel']['channel_pageflags'] & PAGE_PREMIUM) ? '1' : ''),''), + '$lbl_about' => t('Please enter your restrictions or conditions, such as paypal receipt, usage guidelines, etc.'), + '$text' => $text, + '$desc' => t('This channel may require additional steps or acknowledgement of the following conditions prior to connecting:'), + '$lbl2' => t('Potential connections will then see the following text before proceeding:'), + '$desc2' => t('By continuing, I certify that I have complied with any instructions provided on this page.'), + '$submit' => t('Submit'), + + + )); + return $o; + } + else { + if(! $text) + $text = t('(No specific instructions have been provided by the channel owner.)'); + + $submit = replace_macros(get_markup_template('sellpage_submit.tpl'), array( + '$continue' => t('Continue'), + '$address' => $a->data['channel']['channel_address'] + )); + + $o = replace_macros(get_markup_template('sellpage_view.tpl'),array( + '$header' => t('Restricted or Premium Channel'), + '$desc' => t('This channel may require additional steps or acknowledgement of the following conditions prior to connecting:'), + '$text' => prepare_text($text), + + '$desc2' => t('By continuing, I certify that I have complied with any instructions provided on this page.'), + '$submit' => $submit, + + )); + + $arr = array('channel' => $a->data['channel'],'observer' => $a->get_observer(), 'sellpage' => $o, 'submit' => $submit); + call_hooks('connect_premium', $arr); + $o = $arr['sellpage']; + + } + + return $o; +}
\ No newline at end of file diff --git a/mod/connections.php b/mod/connections.php index 7c4d8acc1..95fc18174 100644 --- a/mod/connections.php +++ b/mod/connections.php @@ -99,9 +99,11 @@ function connections_post(&$a) { } $abook_flags = $orig_record[0]['abook_flags']; + $new_friend = false; if(($_REQUEST['pending']) && ($abook_flags & ABOOK_FLAG_PENDING)) { $abook_flags = ( $abook_flags ^ ABOOK_FLAG_PENDING ); + $new_friend = true; } $r = q("UPDATE abook SET abook_profile = '%s', abook_my_perms = %d , abook_closeness = %d, abook_flags = %d @@ -123,6 +125,13 @@ function connections_post(&$a) { proc_run('php', 'include/notifier.php', 'permission_update', $contact_id); } + if($new_friend) { + // Check if settings permit ("post new friend activity" is allowed, and + // friends in general or this friend in particular aren't hidden) + // and send out a new friend activity + // TODO + } + // Refresh the structure in memory with the new data $r = q("SELECT abook.*, xchan.* @@ -306,6 +315,13 @@ function connections_content(&$a) { ), array( + 'label' => t('Recent Activity'), + 'url' => $a->get_baseurl(true) . '/network/?f=&cid=' . $contact['abook_id'], + 'sel' => '', + 'title' => t('View recent posts and comments'), + ), + + array( 'label' => (($contact['abook_flags'] & ABOOK_FLAG_BLOCKED) ? t('Unblock') : t('Block')), 'url' => $a->get_baseurl(true) . '/connections/' . $contact['abook_id'] . '/block', 'sel' => (($contact['abook_flags'] & ABOOK_FLAG_BLOCKED) ? 'active' : ''), diff --git a/mod/directory.php b/mod/directory.php index b7cdaffe7..195ca993e 100644 --- a/mod/directory.php +++ b/mod/directory.php @@ -24,6 +24,19 @@ function directory_content(&$a) { return; } + $safe_mode = 1; + + if(local_user()) { + $safe_mode = get_pconfig(local_user(),'directory','safe_mode'); + } + if($safe_mode === false) + $safe_mode = 1; + else + $safe_mode = intval($safe_mode); + + if(x($_REQUEST,'safe')) + $safe_mode = intval($_REQUEST['safe']); + $o = ''; nav_set_selected('directory'); @@ -32,6 +45,7 @@ function directory_content(&$a) { else $search = ((x($_GET,'search')) ? notags(trim(rawurldecode($_GET['search']))) : ''); + $keywords = (($_GET['keywords']) ? $_GET['keywords'] : ''); $tpl = get_markup_template('directory_header.tpl'); @@ -68,11 +82,17 @@ function directory_content(&$a) { if($url) { - $query = $url . '?f=' ; + // We might want to make the tagadelic count (&kw=) configurable or turn it off completely. + $numtags = get_config('system','directorytags'); + + $kw = ((intval($numtags)) ? $numtags : 24); + $query = $url . '?f=&kw=' . $kw . (($safe_mode != 1) ? '&safe=' . $safe_mode : ''); if($search) - $query .= '&name=' . urlencode($search); + $query .= '&name=' . urlencode($search) . '&keywords=' . urlencode($search); if(strpos($search,'@')) $query .= '&address=' . urlencode($search); + if($keywords) + $query .= '&keywords=' . urlencode($keywords); $sort_order = ((x($_REQUEST,'order')) ? $_REQUEST['order'] : ''); if($sort_order) @@ -175,6 +195,10 @@ function directory_content(&$a) { } + if($j['keywords']) { + $a->set_widget('dirtagblock',dir_tagblock(z_root() . '/directory',$j['keywords'])); + } + // logger('mod_directory: entries: ' . print_r($entries,true), LOGGER_DATA); $o .= replace_macros($tpl, array( diff --git a/mod/dirfind.php b/mod/dirfind.php deleted file mode 100644 index 54bbf31af..000000000 --- a/mod/dirfind.php +++ /dev/null @@ -1,68 +0,0 @@ -<?php - -function dirfind_init(&$a) { - - require_once('include/contact_widgets.php'); - - if(! x($a->page,'aside')) - $a->page['aside'] = ''; - - $a->page['aside'] .= follow_widget(); - - $a->page['aside'] .= findpeople_widget(); -} - - - -function dirfind_content(&$a) { - - $search = notags(trim($_REQUEST['search'])); - - if(strpos($search,'@') === 0) - $search = substr($search,1); - - $o = ''; - - $o .= '<h2>' . t('People Search') . ' - ' . $search . '</h2>'; - - if($search) { - - $p = (($a->pager['page'] != 1) ? '&p=' . $a->pager['page'] : ''); - - if(strlen(get_config('system','directory_submit_url'))) - $x = fetch_url('http://dir.friendica.com/lsearch?f=' . $p . '&search=' . urlencode($search)); - -//TODO fallback local search if global dir not available. -// else -// $x = post_url($a->get_baseurl() . '/lsearch', $params); - - $j = json_decode($x); - - if($j->total) { - $a->set_pager_total($j->total); - $a->set_pager_itemspage($j->items_page); - } - - if(count($j->results)) { - - $tpl = get_markup_template('match.tpl'); - foreach($j->results as $jj) { - - $o .= replace_macros($tpl,array( - '$url' => zid($jj->url), - '$name' => $jj->name, - '$photo' => $jj->photo, - '$tags' => $jj->tags - )); - } - } - else { - info( t('No matches') . EOL); - } - - } - - $o .= '<div class="clear"></div>'; - $o .= paginate($a); - return $o; -} diff --git a/mod/dirsearch.php b/mod/dirsearch.php index 524f55cc1..14307f274 100644 --- a/mod/dirsearch.php +++ b/mod/dirsearch.php @@ -22,6 +22,12 @@ function dirsearch_content(&$a) { json_return_and_die($ret); } + if(argc() > 1 && argv(1) === 'sites') { + $ret = list_public_sites(); + json_return_and_die($ret); + } + + $name = ((x($_REQUEST,'name')) ? $_REQUEST['name'] : ''); $hub = ((x($_REQUEST,'hub')) ? $_REQUEST['hub'] : ''); $address = ((x($_REQUEST,'address')) ? $_REQUEST['address'] : ''); @@ -34,6 +40,20 @@ function dirsearch_content(&$a) { $keywords = ((x($_REQUEST,'keywords')) ? $_REQUEST['keywords'] : ''); $agege = ((x($_REQUEST,'agege')) ? intval($_REQUEST['agege']) : 0 ); $agele = ((x($_REQUEST,'agele')) ? intval($_REQUEST['agele']) : 0 ); + $kw = ((x($_REQUEST,'kw')) ? intval($_REQUEST['kw']) : 0 ); + + // by default use a safe search + $safe = ((x($_REQUEST,'safe')) ? intval($_REQUEST['safe']) : 1 ); + + + if(array_key_exists('sync',$_REQUEST)) { + if($_REQUEST['sync']) + $sync = datetime_convert('UTC','UTC',$_REQUEST['sync']); + else + $sync = datetime_convert('UTC','UTC','2010-01-01 01:01:00'); + } + else + $sync = false; $sort_order = ((x($_REQUEST,'order')) ? $_REQUEST['order'] : ''); @@ -76,6 +96,7 @@ function dirsearch_content(&$a) { $limit = (($_REQUEST['limit']) ? intval($_REQUEST['limit']) : 0); $return_total = ((x($_REQUEST,'return_total')) ? intval($_REQUEST['return_total']) : 0); + // mtime is not currently working $mtime = ((x($_REQUEST,'mtime')) ? datetime_convert('UTC','UTC',$_REQUEST['mtime']) : ''); @@ -90,12 +111,16 @@ function dirsearch_content(&$a) { $logic = ((strlen($sql_extra)) ? 0 : 1); + $safesql = (($safe > 0) ? " and not ( xchan_flags & " . intval(XCHAN_FLAGS_CENSORED|XCHAN_FLAGS_SELFCENSORED) . " ) " : ''); + if($safe < 0) + $safesql = " and ( xchan_flags & " . intval(XCHAN_FLAGS_CENSORED|XCHAN_FLAGS_SELFCENSORED) . " ) "; + if($limit) $qlimit = " LIMIT $limit "; else { $qlimit = " LIMIT " . intval($startrec) . " , " . intval($perpage); if($return_total) { - $r = q("SELECT COUNT(xchan_hash) AS `total` FROM xchan left join xprof on xchan_hash = xprof_hash where $logic $sql_extra and not ( xchan_flags & %d) and not ( xchan_flags & %d ) ", + $r = q("SELECT COUNT(xchan_hash) AS `total` FROM xchan left join xprof on xchan_hash = xprof_hash where $logic $sql_extra and not ( xchan_flags & %d) and not ( xchan_flags & %d ) $safesql ", intval(XCHAN_FLAGS_HIDDEN), intval(XCHAN_FLAGS_ORPHAN) ); @@ -105,24 +130,40 @@ function dirsearch_content(&$a) { } } - 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 "; + $order = ""; // Not currently implemented elseif($sort_order == 'reverse') $order = " order by xchan_name desc "; else $order = " order by xchan_name asc "; - - $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 ) and not ( xchan_flags & %d ) $order $qlimit ", - intval(XCHAN_FLAGS_HIDDEN), - intval(XCHAN_FLAGS_ORPHAN) - ); + if($sync) { + $spkt = array('transactions' => array()); + $r = q("select * from updates where ud_date >= '%s' and ud_guid != '' order by ud_date desc", + dbesc($sync) + ); + if($r) { + foreach($r as $rr) { + $flags = (($rr['ud_flags'] & UPDATE_FLAGS_DELETED) ? array('deleted') : array()); + $spkt['transactions'][] = array( + 'hash' => $rr['ud_hash'], + 'address' => $rr['ud_addr'], + 'transaction_id' => $rr['ud_guid'], + 'timestamp' => $rr['ud_date'], + 'flags' => $flags + ); + } + } + json_return_and_die($spkt); + } + else { + $r = q("SELECT xchan.*, xprof.* from xchan left join xprof on xchan_hash = xprof_hash where $logic $sql_extra and not ( xchan_flags & %d ) and not ( xchan_flags & %d ) $safesql $order $qlimit ", + intval(XCHAN_FLAGS_HIDDEN), + intval(XCHAN_FLAGS_ORPHAN) + ); + } $ret['page'] = $page + 1; $ret['records'] = count($r); @@ -139,6 +180,7 @@ function dirsearch_content(&$a) { $entry['hash'] = $rr['xchan_hash']; $entry['updated'] = (($rr['ud_date']) ? $rr['ud_date'] : '0000-00-00 00:00:00'); + $entry['update_guid'] = (($rr['ud_guid']) ? $rr['ud_guid'] : ''); $entry['url'] = $rr['xchan_url']; $entry['photo'] = $rr['xchan_photo_m']; $entry['address'] = $rr['xchan_addr']; @@ -158,8 +200,48 @@ function dirsearch_content(&$a) { } $ret['results'] = $entries; - + if($kw) { + $k = dir_tagadelic($kw); + if($k) { + $ret['keywords'] = array(); + foreach($k as $kv) { + $ret['keywords'][] = array('term' => $kv[0],'weight' => $kv[1], 'normalise' => $kv[2]); + } + } + } } json_return_and_die($ret); } + + +function list_public_sites() { + $r = q("select * from site where site_access != 0 order by rand()"); + $ret = array('success' => false); + + if($r) { + $ret['success'] = true; + $ret['sites'] = array(); + foreach($r as $rr) { + + if($rr['site_access'] == ACCESS_FREE) + $access = 'free'; + elseif($rr['site_access'] == ACCESS_PAID) + $access = 'paid'; + elseif($rr['site_access'] == ACCESS_TIERED) + $access = 'tiered'; + else + $access = 'private'; + + if($rr['site_register'] == REGISTER_OPEN) + $register = 'open'; + elseif($rr['site_register'] == REGISTER_APPROVE) + $register = 'approve'; + else + $register = 'closed'; + + $ret['sites'][] = array('url' => $rr['site_url'], 'access' => $access, 'register' => $register, 'sellpage' => $rr['site_sellpage']); + } + } + return $ret; +}
\ No newline at end of file diff --git a/mod/display.php b/mod/display.php index 110dd1807..c9f6595c6 100644 --- a/mod/display.php +++ b/mod/display.php @@ -3,7 +3,7 @@ function display_content(&$a, $update = 0, $load = false) { - logger("mod-display: update = $update load = $load"); +// logger("mod-display: update = $update load = $load"); if(intval(get_config('system','block_public')) && (! local_user()) && (! remote_user())) { notice( t('Public access denied.') . EOL); @@ -19,7 +19,6 @@ function display_content(&$a, $update = 0, $load = false) { $a->page['htmlhead'] .= replace_macros(get_markup_template('display-head.tpl'), array()); - if(argc() > 1 && argv(1) !== 'load') $item_hash = argv(1); @@ -91,7 +90,6 @@ function display_content(&$a, $update = 0, $load = false) { $sql_extra = public_permissions_sql(get_observer_hash()); - if($update && $load) { $updateable = false; @@ -109,20 +107,24 @@ function display_content(&$a, $update = 0, $load = false) { intval(local_user()), dbesc($target_item['parent_mid']) ); - if($r) + 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() . " )) + and owner_xchan in ( " . stream_perms_xchans(($observer) ? PERMS_NETWORK : PERMS_PUBLIC) . " )) $sql_extra ) group by mid limit 1", dbesc($target_item['parent_mid']) ); + } } diff --git a/mod/editblock.php b/mod/editblock.php new file mode 100644 index 000000000..a111f6666 --- /dev/null +++ b/mod/editblock.php @@ -0,0 +1,159 @@ +<?php + +// What is this here for? I think it's cruft, but comment out for now in case it's here for a reason +// require_once('acl_selectors.php'); + +function editblock_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. + $r = q("select channel_id from channel where channel_address = '%s'", + dbesc($which) + ); + if($r) { + $owner = intval($r[0]['channel_id']); + //logger('owner: ' . print_r($owner,true)); + } + + + + + 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) + ); + + + + $plaintext = true; +// You may or may not be a local user. This won't work, + if(feature_enabled(local_user(),'richtext')) + $plaintext = false; + + $mimeselect = ''; + + if($mimetype != 'text/bbcode') + $plaintext = true; + + if(get_config('system','page_mimetype')) + $mimeselect = '<input type="hidden" name="mimetype" value="' . $mimetype . '" />'; + else + $mimeselect = mimetype_select($itm[0]['uid'],$mimetype); + + + + + + $o .= replace_macros(get_markup_template('edpost_head.tpl'), array( + '$title' => t('Edit Block') + )); + + + $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 always work for observer - it may WSoD instead of loading a sensible page. So, send folk to the webpage list. + + $rp = '/blocks/' . $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'], + '$mimeselect' => $mimeselect, + '$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), + )); + + + $ob = get_observer_hash(); + + if(($itm[0]['author_xchan'] === $ob) || ($itm[0]['owner_xchan'] === $ob)) + $o .= '<br /><br /><a href="item/drop/' . $itm[0]['id'] . '" >' . t('Delete Block') . '</a><br />'; + + return $o; + +} + + diff --git a/mod/editlayout.php b/mod/editlayout.php new file mode 100644 index 000000000..7bcd02512 --- /dev/null +++ b/mod/editlayout.php @@ -0,0 +1,143 @@ +<?php + +// What is this here for? I think it's cruft, but comment out for now in case it's here for a reason +// require_once('acl_selectors.php'); + +function editlayout_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. + $r = q("select channel_id from channel where channel_address = '%s'", + dbesc($which) + ); + if($r) { + $owner = intval($r[0]['channel_id']); + //logger('owner: ' . print_r($owner,true)); + } + + + + + 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) + ); + + + + $plaintext = true; +// You may or may not be a local user. This won't work, + if(feature_enabled(local_user(),'richtext')) + $plaintext = false; + + $o .= replace_macros(get_markup_template('edpost_head.tpl'), array( + '$title' => t('Edit Layout') + )); + + + $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 always work for observer - it may WSoD instead of loading a sensible page. So, send folk to the webpage list. + + $rp = '/layouts/' . $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), + )); + + $ob = get_observer_hash(); + + if(($itm[0]['author_xchan'] === $ob) || ($itm[0]['owner_xchan'] === $ob)) + $o .= '<br /><br /><a href="item/drop/' . $itm[0]['id'] . '" >' . t('Delete Layout') . '</a><br />'; + + return $o; + +} + + diff --git a/mod/editpost.php b/mod/editpost.php index 583bae9eb..8d510ce05 100644 --- a/mod/editpost.php +++ b/mod/editpost.php @@ -2,6 +2,8 @@ require_once('acl_selectors.php'); require_once('include/crypto.php'); +require_once('include/items.php'); +require_once('include/taxonomy.php'); function editpost_content(&$a) { @@ -70,6 +72,22 @@ function editpost_content(&$a) { //$tpl = replace_macros($tpl,array('$jotplugins' => $jotplugins)); + $category = ''; + $catsenabled = ((feature_enabled(local_user(),'categories')) ? 'categories' : ''); + + if ($catsenabled){ + $itm = fetch_post_tags($itm); + + $cats = get_terms_oftype($itm[0]['term'], TERM_CATEGORY); + + foreach ($cats as $cat) { + if (strlen($category)) + $category .= ', '; + $category .= $cat['term']; + } + + } + $o .= replace_macros($tpl,array( '$return_path' => $_SESSION['return_url'], '$action' => 'item', @@ -95,7 +113,7 @@ function editpost_content(&$a) { '$jotnets' => $jotnets, '$title' => htmlspecialchars($itm[0]['title']), '$placeholdertitle' => t('Set title'), - '$category' => '', // FIXME + '$category' => $category, '$placeholdercategory' => t('Categories (comma-separated list)'), '$emtitle' => t('Example: bob@example.com, mary@example.com'), '$lockstate' => $lockstate, @@ -105,6 +123,7 @@ function editpost_content(&$a) { '$preview' => ((feature_enabled(local_user(),'preview')) ? t('Preview') : ''), '$jotplugins' => $jotplugins, '$sourceapp' => t($a->sourcename), + '$catsenabled' => $catsenabled, )); return $o; diff --git a/mod/editwebpage.php b/mod/editwebpage.php index f89be67c4..44ac0bc85 100644 --- a/mod/editwebpage.php +++ b/mod/editwebpage.php @@ -1,35 +1,28 @@ - <?php -// What is this here for? I think it's cruft, but comment out for now in case it's here for a reason -// require_once('acl_selectors.php'); +// Required for setting permissions. (FIXME) + +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); + // 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. + // $a->get_channel() and stuff don't work here, so we've got to find the owner for ourselves. + $r = q("select channel_id from channel where channel_address = '%s'", dbesc($which) - ); - if($r) { - $owner = intval($r[0]['channel_id']); - //logger('owner: ' . print_r($owner,true)); - } - - - - - if((local_user()) && (argc() > 2) && (argv(2) === 'view')) { - $which = $channel['channel_address']; - } - - + ); + if($r) { + $owner = intval($r[0]['channel_id']); + //logger('owner: ' . print_r($owner,true)); + } + $o = ''; - -// Figure out which post we're editing + // Figure out which post we're editing $post_id = ((argc() > 2) ? intval(argv(2)) : 0); @@ -38,35 +31,60 @@ function editwebpage_content(&$a) { return; } -// Now we've got a post and an owner, let's find out if we're allowed to edit it + // 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'] : ''); + $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; - } + $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) - ); + // 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) + ); $plaintext = true; -// You may or may not be a local user. This won't work, - if(feature_enabled(local_user(),'richtext')) + + if(feature_enabled($itm[0]['uid'],'richtext')) $plaintext = false; + $mimetype = $itm[0]['mimetype']; + + if($mimetype === 'application/x-php') { + if((! local_user()) || (local_user() != $itm[0]['uid'])) { + notice( t('Permission denied.') . EOL); + return; + } + } + + $mimeselect = ''; + + if($mimetype != 'text/bbcode') + $plaintext = true; + + if(get_config('system','page_mimetype')) + $mimeselect = '<input type="hidden" name="mimetype" value="' . $mimetype . '" />'; + else + $mimeselect = mimetype_select($itm[0]['uid'],$mimetype); + + $layout = get_config('system','page_layout'); + if($layout) + $layoutselect = '<input type="hidden" name="layout_mid" value="' . $layout . '" />'; + else + $layoutselect = layout_select($itm[0]['uid']); + + $o .= replace_macros(get_markup_template('edpost_head.tpl'), array( - '$title' => t('Edit post') + '$title' => t('Edit Webpage') )); @@ -78,7 +96,7 @@ function editwebpage_content(&$a) { '$nickname' => $a->user['nickname'] )); - + $tpl = get_markup_template("jot.tpl"); $jotplugins = ''; @@ -118,6 +136,8 @@ function editwebpage_content(&$a) { '$pvisit' => 'none', '$public' => t('Public post'), '$jotnets' => $jotnets, + '$mimeselect' => $mimeselect, + '$layoutselect' => $layoutselect, '$title' => htmlspecialchars($itm[0]['title']), '$placeholdertitle' => t('Set title'), '$category' => '', @@ -132,6 +152,11 @@ function editwebpage_content(&$a) { '$sourceapp' => t($a->sourcename), )); + $ob = get_observer_hash(); + + if(($itm[0]['author_xchan'] === $ob) || ($itm[0]['owner_xchan'] === $ob)) + $o .= '<br /><br /><a href="item/drop/' . $itm[0]['id'] . '" >' . t('Delete Webpage') . '</a><br />'; + return $o; } diff --git a/mod/fbrowser.php b/mod/fbrowser.php index 31004c0d8..baacfe56b 100644 --- a/mod/fbrowser.php +++ b/mod/fbrowser.php @@ -53,7 +53,8 @@ function fbrowser_content($a){ function files1($rr){ global $a; - $types = Photo::supportedTypes(); + $ph = photo_factory(''); + $types = $ph->supportedTypes(); $ext = $types[$rr['type']]; if($a->get_template_engine() === 'internal') { diff --git a/mod/feed.php b/mod/feed.php index 104208875..0f8296ed1 100644 --- a/mod/feed.php +++ b/mod/feed.php @@ -7,9 +7,10 @@ function feed_init(&$a) { $params = array(); - $params['begin'] = ((x($_REQUEST,'date_begin')) ? $_REQUEST['date_begin'] : '0000-00-00 00:00:00'); - $params['end'] = ((x($_REQUEST,'date_end')) ? $_REQUEST['date_end'] : ''); - $params['type'] = ((stristr(argv(0),'json')) ? 'json' : 'xml'); + $params['begin'] = ((x($_REQUEST,'date_begin')) ? $_REQUEST['date_begin'] : '0000-00-00 00:00:00'); + $params['end'] = ((x($_REQUEST,'date_end')) ? $_REQUEST['date_end'] : ''); + $params['type'] = ((stristr(argv(0),'json')) ? 'json' : 'xml'); + $params['pages'] = ((x($_REQUEST,'pages')) ? intval($_REQUEST['pages']) : 0); $channel = ''; if(argc() > 1) { diff --git a/mod/filestorage.php b/mod/filestorage.php new file mode 100644 index 000000000..5e1e61f42 --- /dev/null +++ b/mod/filestorage.php @@ -0,0 +1,90 @@ +<?php + +function filestorage_content(&$a) { + + if(argc() > 1) + $which = argv(1); + else { + notice( t('Requested profile is not available.') . EOL ); + $a->error = 404; + return; + } + + $r = q("select channel_id from channel where channel_address = '%s'", + dbesc($which) + ); + if($r) { + $owner = intval($r[0]['channel_id']); + } + + $observer = $a->get_observer(); + $ob_hash = (($observer) ? $observer['xchan_hash'] : ''); + + $perms = get_all_perms($owner,$ob_hash); + + if(! $perms['view_storage']) { + notice( t('Permission denied.') . EOL); + return; + } + +// Since we have ACL'd files in the wild, but don't have ACL here yet, we +// need to return for anoyne other than the owner, despite the perms check for now. + + $is_owner = (((local_user()) && ($owner == local_user())) ? true : false); + if (! $is_owner) { + info( t('Permission Denied.') . EOL ); + return; + } + +// TODO This will also need to check for files on disk and delete them from there as well as the DB. + if ((argc() > 3 && argv(3) === 'delete') ? true : false);{ + if(! $perms['write_storage']) { + notice( t('Permission denied. VS.') . EOL); + return; + } + + $file = argv(2); + $r = q("delete from attach where id = '%s' and uid = '%s' limit 1", + dbesc($file), + intval($owner) + ); + + + } + + +$r = q("select * from attach where uid = %d order by filename asc", + intval($owner) +); + + $files = null; + + if($r) { + $files = array(); + foreach($r as $rr) { + $files[$rr['id']][] = array('id' => $rr['id'],'download' => $rr['hash'], 'title' => $rr['filename'], 'size' => $rr['filesize']); + } + } + + + $limit = service_class_fetch ($owner,'attach_upload_limit'); + $r = q("select sum(filesize) as total from attach where uid = %d ", + intval($owner) + ); + $used = $r[0]['total']; + + $url = z_root() . "/filestorage/" . $which; + return $o . replace_macros(get_markup_template("filestorage.tpl"), array( + '$baseurl' => $url, + '$download' => t('Download'), + '$files' => $files, + '$channel' => $which, + '$delete' => t('Delete'), + '$used' => $used, + '$usedlabel' => t('Used: '), + '$limit' => $limit, + '$limitlabel' => t('Limit: '), + )); + + +} diff --git a/mod/follow.php b/mod/follow.php index d21c50df6..9f5a8183b 100644 --- a/mod/follow.php +++ b/mod/follow.php @@ -12,8 +12,9 @@ function follow_init(&$a) { $uid = local_user(); $url = notags(trim($_REQUEST['url'])); $return_url = $_SESSION['return_url']; + $confirm = intval($_REQUEST['confirm']); - $result = new_contact($uid,$url,$a->get_channel(),true); + $result = new_contact($uid,$url,$a->get_channel(),true,$confirm); if($result['success'] == false) { if($result['message']) diff --git a/mod/help.php b/mod/help.php index af05bd47c..770a0a8af 100644 --- a/mod/help.php +++ b/mod/help.php @@ -2,7 +2,7 @@ if(! function_exists('load_doc_file')) { function load_doc_file($s) { - global $lang; + $lang = get_app()->language; if(! isset($lang)) $lang = 'en'; $b = basename($s); diff --git a/mod/import.php b/mod/import.php index 08311013a..e2e54c0cd 100644 --- a/mod/import.php +++ b/mod/import.php @@ -347,6 +347,10 @@ function import_post(&$a) { } + // This will indirectly perform a refresh_all *and* update the directory + + proc_run('php', 'include/directory.php', $channel['channel_id']); + // send out refresh requests notice( t('Import completed.') . EOL); diff --git a/mod/item.php b/mod/item.php index 1893a6ef4..48a22bd3c 100644 --- a/mod/item.php +++ b/mod/item.php @@ -62,21 +62,35 @@ function item_post(&$a) { $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); - $app = ((x($_REQUEST,'source')) ? strip_tags($_REQUEST['source']) : ''); - $return_path = ((x($_REQUEST,'return')) ? $_REQUEST['return'] : ''); - $preview = ((x($_REQUEST,'preview')) ? intval($_REQUEST['preview']) : 0); - $categories = ((x($_REQUEST,'category')) ? escape_tags($_REQUEST['category']) : ''); - $webpage = ((x($_REQUEST,'webpage')) ? intval($_REQUEST['webpage']) : 0); - $pagetitle = ((x($_REQUEST,'pagetitle')) ? escape_tags($_REQUEST['pagetitle']): ''); - $buildblock = ((x($_REQUEST,'buildblock')) ? intval($_REQUEST['buildblock']) : 0); - + $profile_uid = ((x($_REQUEST,'profile_uid')) ? intval($_REQUEST['profile_uid']) : 0); + $post_id = ((x($_REQUEST,'post_id')) ? intval($_REQUEST['post_id']) : 0); + $app = ((x($_REQUEST,'source')) ? strip_tags($_REQUEST['source']) : ''); + $return_path = ((x($_REQUEST,'return')) ? $_REQUEST['return'] : ''); + $preview = ((x($_REQUEST,'preview')) ? intval($_REQUEST['preview']) : 0); + $categories = ((x($_REQUEST,'category')) ? escape_tags($_REQUEST['category']) : ''); + $webpage = ((x($_REQUEST,'webpage')) ? intval($_REQUEST['webpage']) : 0); + $pagetitle = ((x($_REQUEST,'pagetitle')) ? escape_tags($_REQUEST['pagetitle']) : ''); + $layout_mid = ((x($_REQUEST,'layout_mid')) ? escape_tags($_REQUEST['layout_mid']): ''); + /* + Check service class limits + */ + if (local_user() && !(x($_REQUEST,'parent')) && !(x($_REQUEST,'post_id'))) { + $ret=item_check_service_class(local_user(),x($_REQUEST,'webpage')); + if (!$ret['success']) { + notice( t($ret['message']) . EOL) ; + if(x($_REQUEST,'return')) + goaway($a->get_baseurl() . "/" . $return_path ); + killme(); + } + } if($pagetitle) { require_once('library/urlify/URLify.php'); $pagetitle = strtolower(URLify::transliterate($pagetitle)); } + + $item_flags = $item_restrict = 0; + /** * Is this a reply to something? */ @@ -124,6 +138,9 @@ function item_post(&$a) { goaway($a->get_baseurl() . "/" . $return_path ); killme(); } + + // can_comment_on_post() needs info from the following xchan_query + xchan_query($r); $parent_item = $r[0]; $parent = $r[0]['id']; @@ -142,17 +159,31 @@ function item_post(&$a) { } + $observer = $a->get_observer(); + + if($parent) { logger('mod_item: item_post parent=' . $parent); + $can_comment = false; + if((array_key_exists('owner',$parent_item)) && ($parent_item['owner']['abook_flags'] & ABOOK_FLAG_SELF)) + $can_comment = perm_is_allowed($profile_uid,$observer['xchan_hash'],'post_comments'); + else + $can_comment = can_comment_on_post($observer['xchan_hash'],$parent_item); + + if(! $can_comment) { + notice( t('Permission denied.') . EOL) ; + if(x($_REQUEST,'return')) + goaway($a->get_baseurl() . "/" . $return_path ); + killme(); + } } - - $observer = $a->get_observer(); - - if(! perm_is_allowed($profile_uid,$observer['xchan_hash'],(($parent) ? 'post_comments' : 'post_wall'))) { - notice( t('Permission denied.') . EOL) ; - if(x($_REQUEST,'return')) - goaway($a->get_baseurl() . "/" . $return_path ); - killme(); + else { + if(! perm_is_allowed($profile_uid,$observer['xchan_hash'],'post_wall')) { + notice( t('Permission denied.') . EOL) ; + if(x($_REQUEST,'return')) + goaway($a->get_baseurl() . "/" . $return_path ); + killme(); + } } @@ -219,11 +250,12 @@ function item_post(&$a) { $location = $orig_post['location']; $coord = $orig_post['coord']; $verb = $orig_post['verb']; - $app = $orig_post['app']; + $app = $orig_post['app']; $title = escape_tags(trim($_REQUEST['title'])); - $body = escape_tags(trim($_REQUEST['body'])); + $body = $_REQUEST['body']; $private = $orig_post['item_private']; - + $item_flags = $orig_post['item_flags']; + $item_restrict = $orig_post['item_restrict']; } else { @@ -255,7 +287,7 @@ function item_post(&$a) { $coord = notags(trim($_REQUEST['coord'])); $verb = notags(trim($_REQUEST['verb'])); $title = escape_tags(trim($_REQUEST['title'])); - $body = escape_tags(trim($_REQUEST['body'])); + $body = $_REQUEST['body']; $private = ( ( strlen($str_group_allow) @@ -310,154 +342,179 @@ function item_post(&$a) { $post_type = notags(trim($_REQUEST['type'])); - $content_type = notags(trim($_REQUEST['content_type'])); - if(! $content_type) - $content_type = 'text/bbcode'; - + $mimetype = notags(trim($_REQUEST['mimetype'])); + if(! $mimetype) + $mimetype = '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 + // Verify ability to use html or php!!! - // 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. - - $plaintext = ((feature_enabled($profile_uid,'richtext')) ? false : true); - if((! $parent) && (! $api_source) && (! $plaintext)) { - $body = fix_mce_lf($body); + if($preview) { + $body = z_input_filter($profile_uid,$body,$mimetype); } - // If we're sending a private top-level message with a single @-taggable channel as a recipient, @-tag it. + $execflag = false; - 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)), + if($mimetype === 'application/x-php') { + $z = q("select account_id, account_roles from account left join channel on channel_account_id = account_id where channel_id = %d limit 1", intval($profile_uid) ); - if($x && ($x[0]['abook_their_perms'] & PERMS_W_TAGWALL)) - $body .= "\n\n@group+" . $x[0]['abook_id'] . "\n"; + if($z && ($z[0]['account_roles'] & ACCOUNT_ROLE_ALLOWCODE)) { + if(local_user() && (get_account_id() == $z[0]['account_id'])) { + $execflag = true; + } + else { + notice( t('Executable content type not permitted to this channel.') . EOL); + if(x($_REQUEST,'return')) + goaway($a->get_baseurl() . "/" . $return_path ); + killme(); + } + } } - /** - * 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 - */ + if($mimetype === 'text/bbcode') { - $body = preg_replace_callback("/([^\]\='".'"'."]|^)(https?\:\/\/[a-zA-Z0-9\:\/\-\?\&\;\.\=\@\_\~\#\%\$\!\+\,]+)/ism", 'red_zrl_callback', $body); + // 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 - /** - * - * When a photo was uploaded into the message using the (profile wall) ajax - * uploader, The permissions are initially set to disallow anybody but the - * owner from seeing it. This is because the permissions may not yet have been - * set for the post. If it's private, the photo permissions should be set - * appropriately. But we didn't know the final permissions on the post until - * now. So now we'll look for links of uploaded messages that are in the - * post and set them to the same permissions as the post itself. - * - */ + // 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. - if(! $preview) { - fix_attached_photo_permissions($profile_uid,$owner_xchan['xchan_hash'],$body, - $str_contact_allow,$str_group_allow,$str_contact_deny,$str_group_deny); + $plaintext = ((feature_enabled($profile_uid,'richtext')) ? false : true); + if((! $parent) && (! $api_source) && (! $plaintext)) { + $body = fix_mce_lf($body); + } - fix_attached_file_permissions($channel,$observer['xchan_hash'],$body, - $str_contact_allow,$str_group_allow,$str_contact_deny,$str_group_deny); + // If we're sending a private top-level message with a single @-taggable channel as a recipient, @-tag it. - } + 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($x && ($x[0]['abook_their_perms'] & PERMS_W_TAGWALL)) + $body .= "\n\n@group+" . $x[0]['abook_id'] . "\n"; + } + /** + * 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); - $body = bb_translate_video($body); + /** + * + * When a photo was uploaded into the message using the (profile wall) ajax + * uploader, The permissions are initially set to disallow anybody but the + * owner from seeing it. This is because the permissions may not yet have been + * set for the post. If it's private, the photo permissions should be set + * appropriately. But we didn't know the final permissions on the post until + * now. So now we'll look for links of uploaded messages that are in the + * post and set them to the same permissions as the post itself. + * + */ - /** - * Fold multi-line [code] sequences - */ + if(! $preview) { + fix_attached_photo_permissions($profile_uid,$owner_xchan['xchan_hash'],$body,$str_contact_allow,$str_group_allow,$str_contact_deny,$str_group_deny); + + fix_attached_file_permissions($channel,$observer['xchan_hash'],$body,$str_contact_allow,$str_group_allow,$str_contact_deny,$str_group_deny); - $body = preg_replace('/\[\/code\]\s*\[code\]/ism',"\n",$body); + } - $body = scale_external_images($body,false); - /** - * Look for any tags and linkify them - */ - $str_tags = ''; - $inform = ''; - $post_tags = array(); + $body = bb_translate_video($body); + + /** + * Fold multi-line [code] sequences + */ + + $body = preg_replace('/\[\/code\]\s*\[code\]/ism',"\n",$body); + + $body = scale_external_images($body,false); + + /** + * Look for any tags and linkify them + */ + + $str_tags = ''; + $inform = ''; + $post_tags = array(); - $tags = get_tags($body); + $tags = get_tags($body); - $tagged = array(); + $tagged = array(); - $private_forum = false; + $private_forum = false; - if(count($tags)) { - foreach($tags as $tag) { + if(count($tags)) { + foreach($tags as $tag) { - // If we already tagged 'Robert Johnson', don't try and tag 'Robert'. - // Robert Johnson should be first in the $tags array + // If we already tagged 'Robert Johnson', don't try and tag 'Robert'. + // Robert Johnson should be first in the $tags array - $fullnametagged = false; - for($x = 0; $x < count($tagged); $x ++) { - if(stristr($tagged[$x],$tag . ' ')) { - $fullnametagged = true; - break; + $fullnametagged = false; + for($x = 0; $x < count($tagged); $x ++) { + if(stristr($tagged[$x],$tag . ' ')) { + $fullnametagged = true; + break; + } + } + if($fullnametagged) + continue; + + $success = handle_tag($a, $body, $inform, $str_tags, (local_user()) ? local_user() : $profile_uid , $tag); + logger('handle_tag: ' . print_r($success,tue)); + + if($success['replaced']) { + $tagged[] = $tag; + $post_tags[] = array( + 'uid' => $profile_uid, + 'type' => $success['termtype'], + 'otype' => TERM_OBJ_POST, + 'term' => $success['term'], + 'url' => $success['url'] + ); + } + if(is_array($success['contact']) && intval($success['contact']['prv'])) { + $private_forum = true; + $private_id = $success['contact']['id']; } - } - if($fullnametagged) - continue; - - $success = handle_tag($a, $body, $inform, $str_tags, (local_user()) ? local_user() : $profile_uid , $tag); - logger('handle_tag: ' . print_r($success,tue)); - - if($success['replaced']) { - $tagged[] = $tag; - $post_tags[] = array( - 'uid' => $profile_uid, - 'type' => $success['termtype'], - 'otype' => TERM_OBJ_POST, - 'term' => $success['term'], - 'url' => $success['url'] - ); - } - if(is_array($success['contact']) && intval($success['contact']['prv'])) { - $private_forum = true; - $private_id = $success['contact']['id']; } } - } // logger('post_tags: ' . print_r($post_tags,true)); - if(($private_forum) && (! $parent) && (! $private)) { - // we tagged a private forum in a top level post and the message was public. - // Restrict it. - $private = 1; - $str_contact_allow = '<' . $private_id . '>'; - } - - $attachments = ''; - $match = false; + if(($private_forum) && (! $parent) && (! $private)) { + // we tagged a private forum in a top level post and the message was public. + // Restrict it. + $private = 1; + $str_contact_allow = '<' . $private_id . '>'; + } - if(preg_match_all('/(\[attachment\](.*?)\[\/attachment\])/',$body,$match)) { - $attachments = array(); - foreach($match[2] as $mtch) { - $hash = substr($mtch,0,strpos($mtch,',')); - $rev = intval(substr($mtch,strpos($mtch,','))); - $r = attach_by_hash_nodata($hash,$rev); - if($r['success']) { - $attachments[] = array( - 'href' => $a->get_baseurl() . '/attach/' . $r['data']['hash'], - 'length' => $r['data']['filesize'], - 'type' => $r['data']['filetype'], - 'title' => urlencode($r['data']['filename']), - 'revision' => $r['data']['revision'] - ); + $attachments = ''; + $match = false; + + if(preg_match_all('/(\[attachment\](.*?)\[\/attachment\])/',$body,$match)) { + $attachments = array(); + foreach($match[2] as $mtch) { + $hash = substr($mtch,0,strpos($mtch,',')); + $rev = intval(substr($mtch,strpos($mtch,','))); + $r = attach_by_hash_nodata($hash,$rev); + if($r['success']) { + $attachments[] = array( + 'href' => $a->get_baseurl() . '/attach/' . $r['data']['hash'], + 'length' => $r['data']['filesize'], + 'type' => $r['data']['filetype'], + 'title' => urlencode($r['data']['filename']), + 'revision' => $r['data']['revision'] + ); + } + $body = str_replace($match[1],'',$body); } - $body = str_replace($match[1],'',$body); } } @@ -477,9 +534,8 @@ function item_post(&$a) { } } - - $item_flags = ITEM_UNSEEN; - $item_restrict = ITEM_VISIBLE; + $item_flags |= ITEM_UNSEEN; + $item_restrict |= ITEM_VISIBLE; if($post_type === 'wall' || $post_type === 'wall-comment') $item_flags = $item_flags | ITEM_WALL; @@ -491,10 +547,7 @@ function item_post(&$a) { $item_restrict = $item_restrict | ITEM_MODERATED; if($webpage) - $item_restrict = $item_restrict | ITEM_WEBPAGE; - - if($buildblock) - $item_restrict = $item_restrict | ITEM_BUILDBLOCK; + $item_restrict = $item_restrict | $webpage; if(! strlen($verb)) @@ -520,38 +573,37 @@ function item_post(&$a) { $item_flags = $item_flags | ITEM_THREAD_TOP; } - $datarray['aid'] = $channel['channel_account_id']; - $datarray['uid'] = $profile_uid; - - $datarray['owner_xchan'] = (($owner_hash) ? $owner_hash : $owner_xchan['xchan_hash']); - $datarray['author_xchan'] = $observer['xchan_hash']; - $datarray['created'] = datetime_convert(); - $datarray['edited'] = datetime_convert(); - $datarray['expires'] = $expires; - $datarray['commented'] = datetime_convert(); - $datarray['received'] = datetime_convert(); - $datarray['changed'] = datetime_convert(); - $datarray['mid'] = $mid; - $datarray['parent_mid'] = $parent_mid; - $datarray['mimetype'] = $content_type; - $datarray['title'] = $title; - $datarray['body'] = $body; - $datarray['app'] = $app; - $datarray['location'] = $location; - $datarray['coord'] = $coord; - $datarray['inform'] = $inform; - $datarray['verb'] = $verb; - $datarray['allow_cid'] = $str_contact_allow; - $datarray['allow_gid'] = $str_group_allow; - $datarray['deny_cid'] = $str_contact_deny; - $datarray['deny_gid'] = $str_group_deny; - $datarray['item_private'] = $private; - $datarray['attach'] = $attachments; - $datarray['thr_parent'] = $thr_parent; - $datarray['postopts'] = ''; - $datarray['item_restrict'] = $item_restrict; - $datarray['item_flags'] = $item_flags; - + $datarray['aid'] = $channel['channel_account_id']; + $datarray['uid'] = $profile_uid; + + $datarray['owner_xchan'] = (($owner_hash) ? $owner_hash : $owner_xchan['xchan_hash']); + $datarray['author_xchan'] = $observer['xchan_hash']; + $datarray['created'] = datetime_convert(); + $datarray['edited'] = datetime_convert(); + $datarray['expires'] = $expires; + $datarray['commented'] = datetime_convert(); + $datarray['received'] = datetime_convert(); + $datarray['changed'] = datetime_convert(); + $datarray['mid'] = $mid; + $datarray['parent_mid'] = $parent_mid; + $datarray['mimetype'] = $mimetype; + $datarray['title'] = $title; + $datarray['body'] = $body; + $datarray['app'] = $app; + $datarray['location'] = $location; + $datarray['coord'] = $coord; + $datarray['verb'] = $verb; + $datarray['allow_cid'] = $str_contact_allow; + $datarray['allow_gid'] = $str_group_allow; + $datarray['deny_cid'] = $str_contact_deny; + $datarray['deny_gid'] = $str_group_deny; + $datarray['item_private'] = $private; + $datarray['attach'] = $attachments; + $datarray['thr_parent'] = $thr_parent; + $datarray['postopts'] = ''; + $datarray['item_restrict'] = $item_restrict; + $datarray['item_flags'] = $item_flags; + $datarray['layout_mid'] = $layout_mid; $datarray['comment_policy'] = map_scope($channel['channel_w_comment']); // preview mode - prepare the body for display and send it via json @@ -590,6 +642,16 @@ function item_post(&$a) { $datarray['title'] = mb_substr($datarray['title'],0,255); if(array_key_exists('item_private',$datarray) && $datarray['item_private']) { + + $datarray['body'] = z_input_filter($datarray['uid'],$datarray['body'],$datarray['mimetype']); + + if(local_user()) { + if($channel['channel_hash'] === $datarray['author_xchan']) { + $datarray['sig'] = base64url_encode(rsa_sign($datarray['body'],$channel['channel_prvkey'])); + $datarray['item_flags'] = $datarray['item_flags'] | ITEM_VERIFIED; + } + } + logger('Encrypting local storage'); $key = get_config('system','pubkey'); $datarray['item_flags'] = $datarray['item_flags'] | ITEM_OBSCURED; @@ -599,47 +661,10 @@ function item_post(&$a) { $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']), - dbesc($datarray['body']), - dbesc($datarray['attach']), - dbesc(datetime_convert()), - intval($post_id), - intval($profile_uid) - ); - - // remove taxonomy items for this post - we'll recreate them - - q("delete from term where otype = %d and oid = %d and type in (%d, %d, %d, %d) ", - intval(TERM_OBJ_POST), - intval($post_id), - intval(TERM_UNKNOWN), - intval(TERM_HASHTAG), - intval(TERM_MENTION), - intval(TERM_CATEGORY) - ); - - - 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'])) - ); - } - } - } - + $datarray['id'] = $post_id; + item_store_update($datarray,$execflag); proc_run('php', "include/notifier.php", 'edit_post', $post_id); if((x($_REQUEST,'return')) && strlen($return_path)) { @@ -652,7 +677,10 @@ function item_post(&$a) { $post_id = 0; - $post_id = item_store($datarray); + $post = item_store($datarray,$execflag); + + + $post_id = $post['item_id']; if($post_id) { logger('mod_item: saved item ' . $post_id); @@ -764,20 +792,28 @@ function item_post(&$a) { intval($parent) ); - if($webpage) { + $page_type = ''; + + if($webpage & ITEM_WEBPAGE) + $page_type = 'WEBPAGE'; + elseif($webpage & ITEM_BUILDBLOCK) + $page_type = 'BUILDBLOCK'; + elseif($webpage & ITEM_PDL) + $page_type = 'PDL'; + + if($page_type) { // store page info as an alternate message_id so we can access it via // https://sitename/page/$channelname/$pagetitle // if no pagetitle was given or it couldn't be transliterated into a url, use the first // sixteen bytes of the mid - which makes the link portable and not quite as daunting // as the entire mid. If it were the post_id the link would be less portable. - // 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($mid,0,16)), - dbesc('WEBPAGE') + dbesc($page_type) ); } @@ -1041,12 +1077,15 @@ function fix_attached_photo_permissions($uid,$xchan_hash,$body, intval($uid) ); if($r) { - $r = q("UPDATE item SET allow_cid = '%s', allow_gid = '%s', deny_cid = '%s', deny_gid = '%s' + $private = (($str_contact_allow || $str_group_allow || $str_contact_deny || $str_group_deny) ? true : false); + + $r = q("UPDATE item SET allow_cid = '%s', allow_gid = '%s', deny_cid = '%s', deny_gid = '%s', item_private = %d WHERE id = %d AND uid = %d limit 1", dbesc($str_contact_allow), dbesc($str_group_allow), dbesc($str_contact_deny), dbesc($str_group_deny), + intval($private), intval($r[0]['id']), intval($uid) ); @@ -1081,3 +1120,40 @@ function fix_attached_file_permissions($channel,$observer_hash,$body, } } } +function item_check_service_class($channel_id,$iswebpage) { + $ret = array('success' => false, $message => ''); + if ($iswebpage) { + $r = q("select count(i.id) as total from item i + right join channel c on (i.author_xchan=c.channel_hash and i.uid=c.channel_id ) + and i.parent=i.id and (i.item_restrict & %d) and i.uid= %d ", + intval(ITEM_WEBPAGE), + intval($channel_id) + ); + } + else { + $r = q("select count(i.id) as total from item i + right join channel c on (i.author_xchan=c.channel_hash and i.uid=c.channel_id ) + and i.parent=i.id and (i.item_restrict=0) and i.uid= %d ", + intval($channel_id) + ); + } + if(! ($r && count($r))) { + $ret['message'] = t('Unable to obtain identity information from database'); + return $ret; + } + if (!$iswebpage) { + if(! service_class_allows($channel_id,'total_items',$r[0]['total'])) { + $result['message'] .= upgrade_message().sprintf(t("You have reached your limit of %1$.0f top level posts."),$r[0]['total']); + return $result; + } + } + else { + if(! service_class_allows($channel_id,'total_pages',$r[0]['total'])) { + $result['message'] .= upgrade_message().sprintf(t("You have reached your limit of %1$.0f webpages."),$r[0]['total']); + return $result; + } + } + + $ret['success'] = true; + return $ret; +} diff --git a/mod/layouts.php b/mod/layouts.php new file mode 100644 index 000000000..cd6e61f88 --- /dev/null +++ b/mod/layouts.php @@ -0,0 +1,98 @@ +<?php + +function layouts_content(&$a) { + + if(argc() > 1) + $which = argv(1); + else { + notice( t('Requested profile is not available.') . EOL ); + $a->error = 404; + return; + } + + profile_load($a,$which,0); + + + // Figure out who the page owner is. + $r = q("select channel_id from channel where channel_address = '%s'", + dbesc($which) + ); + if($r) { + $owner = intval($r[0]['channel_id']); + } + + // Block design features from visitors + + if((! local_user()) || (local_user() != $owner)) { + notice( t('Permission denied.') . EOL); + return; + } + + + + +// Get the observer, check their permissions + + $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; + } + + if(local_user() && local_user() == $owner) { + $a->set_widget('design',design_tools()); + } + + + +// Create a status editor (for now - we'll need a WYSIWYG eventually) to create pages +// Nickname is set to the observers xchan, and profile_uid to the owners. This lets you post pages at other people's channels. +require_once ('include/conversation.php'); + $x = array( + 'webpage' => ITEM_PDL, + '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' => intval($owner), + ); + + $o .= status_editor($a,$x); + + //Get a list of blocks. We can't display all them because endless scroll makes that unusable, so just list titles and an edit link. +//TODO - this should be replaced with pagelist_widget + +$r = q("select * from item_id where uid = %d and service = 'PDL' order by sid asc", + intval($owner) +); + + $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() . "/editlayout/" . $which; +// 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' => $which, + '$view' => t('View'), + '$preview' => '1', + + )); + + +} diff --git a/mod/like.php b/mod/like.php index 90005eca3..84b0a6592 100755 --- a/mod/like.php +++ b/mod/like.php @@ -100,7 +100,7 @@ function like_content(&$a) { $mid = item_message_id(); - $post_type = (($item['resource_type'] === 'photo') ? $t('photo') : t('status')); + $post_type = (($item['resource_type'] === 'photo') ? t('photo') : t('status')); $links = array(array('rel' => 'alternate','type' => 'text/html', 'href' => $item['plink'])); $objtype = (($item['resource_type'] === 'photo') ? ACTIVITY_OBJ_PHOTO : ACTIVITY_OBJ_NOTE ); @@ -171,7 +171,8 @@ function like_content(&$a) { $arr['deny_cid'] = $item['deny_cid']; $arr['deny_gid'] = $item['deny_gid']; - $post_id = item_store($arr); + $post = item_store($arr); + $post_id = $post['item_id']; $arr['id'] = $post_id; diff --git a/mod/magic.php b/mod/magic.php index 09a2e8a51..44aa19ead 100644 --- a/mod/magic.php +++ b/mod/magic.php @@ -4,6 +4,8 @@ function magic_init(&$a) { + logger('mod_magic: invoked', LOGGER_DEBUG); + $addr = ((x($_REQUEST,'addr')) ? $_REQUEST['addr'] : ''); $hash = ((x($_REQUEST,'hash')) ? $_REQUEST['hash'] : ''); $dest = ((x($_REQUEST,'dest')) ? $_REQUEST['dest'] : ''); diff --git a/mod/manage.php b/mod/manage.php index 2cdfce115..27e45aa47 100644 --- a/mod/manage.php +++ b/mod/manage.php @@ -53,6 +53,17 @@ function manage_content(&$a) { $channels[$x]['default_links'] = '1'; } } + + $r = q("select count(channel_id) as total from channel where channel_account_id = %d ", + intval(get_account_id()) + ); + $limit = service_class_fetch(local_user(),'total_identities'); + if($limit !== false) { + $channel_usage_message = sprintf( t("You have created %1$.0f of %2$.0f allowed channels."), $r[0]['total'], $limit); + } + else { + $channel_usage_message = ''; + } } $links = array( @@ -69,6 +80,7 @@ function manage_content(&$a) { '$msg_make_default' => t('Make Default'), '$links' => $links, '$all_channels' => $channels, + '$channel_usage_message' => $channel_usage_message, )); diff --git a/mod/menu.php b/mod/menu.php index c3302544e..1ec3c7996 100644 --- a/mod/menu.php +++ b/mod/menu.php @@ -42,6 +42,9 @@ function menu_content(&$a) { } + $a->set_widget('design',design_tools()); + + if(argc() == 1) { // list menus $x = menu_list(local_user()); diff --git a/mod/message.php b/mod/message.php index f5a60b73b..652481579 100644 --- a/mod/message.php +++ b/mod/message.php @@ -273,6 +273,11 @@ function message_content(&$a) { $prefill = (($preselect) ? $prename : ''); + if(! $prefill) { + if(array_key_exists('to',$_REQUEST)) + $prefill = $_REQUEST['to']; + } + // the ugly select box $select = contact_select('messageto','message-to-select', $preselect, 4, true, false, false, 10); diff --git a/mod/mitem.php b/mod/mitem.php index 2b890d5a1..6a5785114 100644 --- a/mod/mitem.php +++ b/mod/mitem.php @@ -98,6 +98,8 @@ function mitem_content(&$a) { return ''; } + $a->set_widget('design',design_tools()); + $m = menu_fetch($a->data['menu']['menu_name'],local_user(), get_observer_hash()); $a->set_widget('menu_preview',menu_render($m)); @@ -109,24 +111,23 @@ function mitem_content(&$a) { local_user() ); - if($r) { - $o = replace_macros(get_markup_template('mitemlist.tpl'),array( - '$title' => t('Manage Menu Elements'), - '$menuname' => $a->data['menu']['menu_name'], - '$menudesc' => $a->data['menu']['menu_desc'], - '$edmenu' => t('Edit menu'), - '$menu_id' => $a->data['menu']['menu_id'], - '$mlist' => $r, - '$edit' => t('Edit element'), - '$drop' => t('Drop element'), - '$new' => t('New element'), - '$hintmenu' => t('Edit this menu container'), - '$hintnew' => t('Add menu element'), - '$hintdrop' => t('Delete this menu item'), - '$hintedit' => t('Edit this menu item') - )); - } + $o .= replace_macros(get_markup_template('mitemlist.tpl'),array( + '$title' => t('Manage Menu Elements'), + '$menuname' => $a->data['menu']['menu_name'], + '$menudesc' => $a->data['menu']['menu_desc'], + '$edmenu' => t('Edit menu'), + '$menu_id' => $a->data['menu']['menu_id'], + '$mlist' => $r, + '$edit' => t('Edit element'), + '$drop' => t('Drop element'), + '$new' => t('New element'), + '$hintmenu' => t('Edit this menu container'), + '$hintnew' => t('Add menu element'), + '$hintdrop' => t('Delete this menu item'), + '$hintedit' => t('Edit this menu item') + )); + return $o; diff --git a/mod/mood.php b/mod/mood.php index 7b6a0c392..83b8bfb57 100755 --- a/mod/mood.php +++ b/mod/mood.php @@ -84,7 +84,9 @@ function mood_init(&$a) { $arr['verb'] = $activity; $arr['body'] = $action; - $item_id = item_store($arr); + $post = item_store($arr); + $item_id = $post['item_id']; + if($item_id) { // q("UPDATE `item` SET `plink` = '%s' WHERE `uid` = %d AND `id` = %d LIMIT 1", // dbesc($a->get_baseurl() . '/display/' . $poster['nickname'] . '/' . $item_id), diff --git a/mod/network.php b/mod/network.php index e44a604de..81b38a5ae 100644 --- a/mod/network.php +++ b/mod/network.php @@ -64,7 +64,6 @@ function network_init(&$a) { } } - $group_id = ((x($_GET,'gid')) ? intval($_GET['gid']) : 0); require_once('include/group.php'); require_once('include/contact_widgets.php'); @@ -74,8 +73,10 @@ function network_init(&$a) { $a->page['aside'] = ''; $search = ((x($_GET,'search')) ? $_GET['search'] : ''); + + - if(x($_GET,'save')) { + if(x($_GET,'save') && $search) { $r = q("select * from `term` where `uid` = %d and `type` = %d and `term` = '%s' limit 1", intval(local_user()), intval(TERM_SAVEDSEARCH), @@ -104,6 +105,28 @@ function network_init(&$a) { $a->page['aside'] .= saved_searches($search); $a->page['aside'] .= fileas_widget($a->get_baseurl(true) . '/network',(x($_GET, 'file') ? $_GET['file'] : '')); + + if($search) { + if(strpos($search,'@') === 0) { + $r = q("select abook_id from abook left join xchan on abook_xchan = xchan_hash where xchan_name = '%s' and abook_channel = %d limit 1", + dbesc(substr($search,1)), + intval(local_user()) + ); + if($r) { + $_GET['cid'] = $r[0]['abook_id']; + $search = $_GET['search'] = ''; + } + } + elseif(strpos($search,'#') === 0) { + $search = $_GET['search'] = substr($search,1); + } + } + + $group_id = ((x($_GET,'gid')) ? intval($_GET['gid']) : 0); + + + + } function saved_searches($search) { @@ -149,7 +172,7 @@ function saved_searches($search) { $o = replace_macros($tpl, array( '$title' => t('Saved Searches'), '$add' => t('add'), - '$searchbox' => search($search,'netsearch-box',$srchurl,true), + '$searchbox' => search('','netsearch-box',$srchurl,true), '$saved' => $saved, )); @@ -325,9 +348,9 @@ function network_content(&$a, $update = 0, $load = false) { // save selected tab, but only if not in search or file mode - if(!x($_GET,'search') && !x($_GET,'file')) { - set_pconfig( local_user(), 'network.view','tab.selected',array($all_active, $postord_active, $conv_active, $new_active, $starred_active, $bookmarked_active, $spam_active) ); - } +// if(!x($_GET,'search') && !x($_GET,'file')) { +// set_pconfig( local_user(), 'network.view','tab.selected',array($all_active, $postord_active, $conv_active, $new_active, $starred_active, $bookmarked_active, $spam_active) ); +// } $contact_id = $a->cid; @@ -379,14 +402,14 @@ function network_content(&$a, $update = 0, $load = false) { // --- end item filter tabs - + $search = (($_GET['search']) ? $_GET['search'] : ''); // search terms header if($search) $o .= '<h2>' . t('Search Results For:') . ' ' . htmlspecialchars($search) . '</h2>'; nav_set_selected('network'); - $celeb = ((($a->user['page-flags'] == PAGE_SOAPBOX) || ($a->user['page-flags'] == PAGE_COMMUNITY)) ? true : false); + $celeb = false; $x = array( 'is_owner' => true, @@ -432,31 +455,36 @@ function network_content(&$a, $update = 0, $load = false) { // NOTREACHED } - $contacts = expand_groups(array($arr['group'])); - if((is_array($contacts)) && count($contacts)) { - $contact_str = implode(',',$contacts); + $contact_str = ''; + $contacts = group_get_members($group); + if($contacts) { + foreach($contacts as $c) { + if($contact_str) + $contact_str .= ','; + $contact_str .= "'" . $c['xchan'] . "'"; + } } 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 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 id = parent and item_restrict = 0 ) "; } elseif($cid) { - $r = q("SELECT * from abook where abook_id = %d and abook_channel = %d and not ( abook_flags & " . intval(ABOOK_FLAG_BLOCKED) . ") limit 1", + $r = q("SELECT abook.*, xchan.* from abook left join xchan on abook_xchan = xchan_hash where abook_id = %d and abook_channel = %d and not ( abook_flags & " . 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; + $o = '<h2>' . t('Connection: ') . $r[0]['xchan_name'] . '</h2>' . $o; } else { - notice( t('Invalid contact.') . EOL); + notice( t('Invalid connection.') . EOL); goaway($a->get_baseurl(true) . '/network'); } } @@ -484,6 +512,7 @@ function network_content(&$a, $update = 0, $load = false) { . "'; var profile_page = " . $a->pager['page'] . ";</script>"; +logger('Search: ' . $search); $a->page['htmlhead'] .= replace_macros(get_markup_template("build_query.tpl"),array( '$baseurl' => z_root(), @@ -500,7 +529,7 @@ function network_content(&$a, $update = 0, $load = false) { '$nouveau' => (($nouveau) ? $nouveau : '0'), '$wall' => '0', '$page' => (($a->pager['page'] != 1) ? $a->pager['page'] : 1), - '$search' => $search, + '$search' => (($search) ? $search : ''), '$order' => $order, '$file' => $file, '$cats' => '', @@ -641,6 +670,8 @@ function network_content(&$a, $update = 0, $load = false) { $first = dba_timer(); // Then fetch all the children of the parents that are on this page + $parents_str = ''; + $update_unseen = ''; if($r) { @@ -699,7 +730,7 @@ function network_content(&$a, $update = 0, $load = false) { $sixth = dba_timer(); - if(! $update) + if(($items) && (! $update)) $o .= alt_pager($a,count($items)); if($load) { diff --git a/mod/page.php b/mod/page.php index 4b2b95b6a..452341cb1 100644 --- a/mod/page.php +++ b/mod/page.php @@ -6,16 +6,13 @@ require_once('include/page_widgets.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); - } + $which = argv(1); + $profile = 0; + profile_load($a,$which,$profile); - profile_load($a,$which,$profile); + if($a->profile['profile_uid']) + head_set_icon($a->profile['thumb']); } @@ -51,9 +48,15 @@ function page_content(&$a) { return; } + if($_REQUEST['rev']) + $revision = " and revision = " . intval($_REQUEST['rev']) . " "; + else + $revision = " order by revision desc "; + + $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", + item_restrict = %d $revision limit 1", intval($u[0]['channel_id']), dbesc($page_id), intval(ITEM_WEBPAGE) @@ -63,8 +66,25 @@ function page_content(&$a) { notice( t('Item not found.') . EOL); return; } +dbg(1); + if($r[0]['layout_mid']) { + $l = q("select body from item where mid = '%s' and uid = %d limit 1", + dbesc($r[0]['layout_mid']), + intval($u[0]['channel_id']) + ); + + if($l) { + require_once('include/comanche.php'); + comanche_parser(get_app(),$l[0]['body']); + } + } +dbg(0); + +logger('layout: ' . print_r($a->layout,true)); + + + // Use of widgets should be determined by Comanche, but we don't have it yet, so... -// Use of widgets should be determined by Comanchie, but we don't have it yet, so... if ($perms['write_pages']) { $chan = $a->channel['channel_id']; $who = $channel_address; @@ -74,7 +94,7 @@ function page_content(&$a) { xchan_query($r); $r = fetch_post_tags($r,true); - $a->profile = array('profile_uid' => $u[0]['channel_id']); + $o .= prepare_page($r[0]); return $o; diff --git a/mod/photos.php b/mod/photos.php index 789e26949..f751d7d4f 100644 --- a/mod/photos.php +++ b/mod/photos.php @@ -184,12 +184,13 @@ function photos_post(&$a) { intval($page_owner_uid), dbesc($r[0]['resource_id']) ); - $i = q("SELECT * FROM `item` WHERE `resource_id` = '%s' AND `uid` = %d LIMIT 1", + $i = q("SELECT * FROM `item` WHERE `resource_id` = '%s' AND resource_type = 'photo' and `uid` = %d LIMIT 1", dbesc($r[0]['resource_id']), intval($page_owner_uid) ); if(count($i)) { - q("UPDATE `item` SET `deleted` = 1, `edited` = '%s', `changed` = '%s' WHERE `parent_mid` = '%s' AND `uid` = %d", + q("UPDATE `item` SET item_restrict = (item_restrict & %d), `edited` = '%s', `changed` = '%s' WHERE `parent_mid` = '%s' AND `uid` = %d", + intval(ITEM_DELETED), dbesc(datetime_convert()), dbesc(datetime_convert()), dbesc($i[0]['mid']), @@ -302,6 +303,9 @@ function photos_post(&$a) { ); } + $item_private = (($str_contact_allow || $str_group_allow || $str_contact_deny || $str_group_deny) ? true : false); + + /* Don't make the item visible if the only change was the album name */ $visibility = 0; @@ -319,11 +323,23 @@ function photos_post(&$a) { intval($page_owner_uid) ); } - if(count($r)) { + if($r) { $old_tag = $r[0]['tag']; $old_inform = $r[0]['inform']; } + // make sure the linked item has the same permissions as the photo regardless of any other changes + $x = q("update item set allow_cid = '%s', allow_gid = '%s', deny_cid = '%s', deny_gid = '%s', item_private = %d + where id = %d limit 1", + dbesc($str_contact_allow), + dbesc($str_group_allow), + dbesc($str_contact_deny), + dbesc($str_group_deny), + intval($item_private), + intval($item_id) + ); + + if(strlen($rawtags)) { $str_tags = ''; @@ -438,15 +454,15 @@ function photos_post(&$a) { if(strlen($newinform) && strlen($inform)) $newinform .= ','; $newinform .= $inform; - - $r = q("UPDATE `item` SET `tag` = '%s', `inform` = '%s', `edited` = '%s', `changed` = '%s' WHERE `id` = %d AND `uid` = %d LIMIT 1", - dbesc($newtag), - dbesc($newinform), - dbesc(datetime_convert()), - dbesc(datetime_convert()), - intval($item_id), - intval($page_owner_uid) - ); +//FIXME - inform is gone +// $r = q("UPDATE `item` SET `tag` = '%s', `inform` = '%s', `edited` = '%s', `changed` = '%s' WHERE `id` = %d AND `uid` = %d LIMIT 1", +// dbesc($newtag), +// dbesc($newinform), +// dbesc(datetime_convert()), +// dbesc(datetime_convert()), +// intval($item_id), +// intval($page_owner_uid) +// ); $best = 0; foreach($p as $scales) { @@ -505,7 +521,9 @@ function photos_post(&$a) { . $a->get_baseurl() . '/photos/' . $owner_record['nickname'] . '/image/' . $p[0]['resource_id'] . '</id>'; $arr['target'] .= '<link>' . xmlify('<link rel="alternate" type="text/html" href="' . $a->get_baseurl() . '/photos/' . $owner_record['nickname'] . '/image/' . $p[0]['resource_id'] . '" />' . "\n" . '<link rel="preview" type="'.$p[0]['type'].'" href="' . $a->get_baseurl() . "/photo/" . $p[0]['resource_id'] . '-' . $best . '.' . $ext . '" />') . '</link></target>'; - $item_id = item_store($arr); + $post = item_store($arr); + $item_id = $post['item_id']; + if($item_id) { q("UPDATE `item` SET `plink` = '%s' WHERE `uid` = %d AND `id` = %d LIMIT 1", dbesc($a->get_baseurl() . '/display/' . $owner_record['nickname'] . '/' . $item_id), @@ -851,7 +869,7 @@ function photos_content(&$a) { // fetch image, item containing image, then comments - $ph = q("SELECT * FROM `photo` WHERE `uid` = %d AND `resource_id` = '%s' + $ph = q("SELECT aid,uid,xchan,resource_id,created,edited,title,`desc`,album,filename,`type`,height,width,`size`,scale,profile,photo_flags,allow_cid,allow_gid,deny_cid,deny_gid FROM `photo` WHERE `uid` = %d AND `resource_id` = '%s' and (photo_flags = %d or photo_flags = %d ) $sql_extra ORDER BY `scale` ASC ", intval($owner_uid), dbesc($datum), @@ -873,7 +891,7 @@ function photos_content(&$a) { intval(PHOTO_PROFILE) ); if($ph) - notice( t('Permission denied. Access to this item may be restricted.')); + notice( t('Permission denied. Access to this item may be restricted.') . EOL); else notice( t('Photo not available') . EOL ); return; @@ -957,7 +975,7 @@ function photos_content(&$a) { } if($prevlink) - $prevlink = array($prevlink, '<div class="icon prev"></div>') ; + $prevlink = array($prevlink, '<i class="icon-backward photo-icons""></i>') ; $photo = array( 'href' => $a->get_baseurl() . '/photo/' . $hires['resource_id'] . '-' . $hires['scale'] . '.' . $phototypes[$hires['type']], @@ -966,7 +984,7 @@ function photos_content(&$a) { ); if($nextlink) - $nextlink = array($nextlink, '<div class="icon next"></div>'); + $nextlink = array($nextlink, '<i class="icon-forward photo-icons"></i>'); // Do we have an item for this photo? @@ -975,14 +993,14 @@ function photos_content(&$a) { $sql_extra LIMIT 1", dbesc($datum) ); + if($linked_items) { $link_item = $linked_items[0]; - $r = q("select * from item where parent_mid = '%s' and mid != '%s' + $r = q("select * from item where parent_mid = '%s' and item_restrict = 0 and uid = %d $sql_extra ", dbesc($link_item['mid']), - dbesc($link_item['mid']), intval($link_item['uid']) ); @@ -1003,6 +1021,9 @@ function photos_content(&$a) { } } + // FIXME - remove this when we move to conversation module + + $r = $r[0]['children']; $edit = null; if($can_post) { @@ -1058,6 +1079,7 @@ function photos_content(&$a) { if($can_post || $a->data['perms']['post_comments']) { $comments .= replace_macros($cmnt_tpl,array( '$return_path' => '', + '$mode' => 'photos', '$jsreload' => $return_url, '$type' => 'wall-comment', '$id' => $link_item['id'], @@ -1093,23 +1115,6 @@ function photos_content(&$a) { - if($can_post || $a->data['perms']['post_comments']) { - $comments .= replace_macros($cmnt_tpl,array( - '$return_path' => '', - '$jsreload' => $return_url, - '$type' => 'wall-comment', - '$id' => $link_item['id'], - '$parent' => $link_item['id'], - '$profile_uid' => $owner_uid, - '$mylink' => $contact['url'], - '$mytitle' => t('This is you'), - '$myphoto' => $contact['thumb'], - '$comment' => t('Comment'), - '$submit' => t('Submit'), - '$ww' => '' - )); - } - foreach($r as $item) { $comment = ''; $template = $tpl; @@ -1120,39 +1125,13 @@ function photos_content(&$a) { $redirect_url = $a->get_baseurl() . '/redir/' . $item['cid'] ; - if($can_post || $a->data['perms']['post_comments']) { - $comments .= replace_macros($cmnt_tpl,array( - '$return_path' => '', - '$jsreload' => $return_url, - '$type' => 'wall-comment', - '$id' => $item['item_id'], - '$parent' => $item['parent'], - '$profile_uid' => $owner_uid, - '$mylink' => $contact['url'], - '$mytitle' => t('This is you'), - '$myphoto' => $contact['thumb'], - '$comment' => t('Comment'), - '$submit' => t('Submit'), - '$sourceapp' => t($a->sourcename), - '$ww' => '' - )); - } + $profile_url = zid($item['author']['xchan_url']); + $sparkle = ''; - if(local_user() && ($item['contact-uid'] == local_user()) - && ($item['network'] == 'dfrn') && (! $item['self'] )) { - $profile_url = $redirect_url; - $sparkle = ' sparkle'; - } - else { - $profile_url = $item['url']; - $sparkle = ''; - } - - $diff_author = (($item['url'] !== $item['author-link']) ? true : false); - $profile_name = (((strlen($item['author-name'])) && $diff_author) ? $item['author-name'] : $item['name']); - $profile_avatar = (((strlen($item['author-avatar'])) && $diff_author) ? $item['author-avatar'] : $item['thumb']); + $profile_name = $item['author']['xchan_name']; + $profile_avatar = $item['author']['xchan_photo_m']; $profile_link = $profile_url; @@ -1164,11 +1143,12 @@ function photos_content(&$a) { $name_e = $profile_name; $title_e = $item['title']; - $body_e = bbcode($item['body']); - + unobscure($item); + $body_e = prepare_text($item['body'],$item['mimetype']); $comments .= replace_macros($template,array( '$id' => $item['item_id'], + '$mode' => 'photos', '$profile_url' => $profile_link, '$name' => $name_e, '$thumb' => $profile_avatar, @@ -1180,9 +1160,27 @@ function photos_content(&$a) { '$drop' => $drop, '$comment' => $comment )); + + } + + if($can_post || $a->data['perms']['post_comments']) { + $comments .= replace_macros($cmnt_tpl,array( + '$return_path' => '', + '$jsreload' => $return_url, + '$type' => 'wall-comment', + '$id' => $link_item['id'], + '$parent' => $link_item['id'], + '$profile_uid' => $owner_uid, + '$mylink' => $contact['url'], + '$mytitle' => t('This is you'), + '$myphoto' => $contact['thumb'], + '$comment' => t('Comment'), + '$submit' => t('Submit'), + '$ww' => '' + )); } - } + } $paginate = paginate($a); } @@ -1209,6 +1207,8 @@ function photos_content(&$a) { '$comments' => $comments, '$paginate' => $paginate, )); + + $a->data['photo_html'] = $o; return $o; } diff --git a/mod/post.php b/mod/post.php index 07f2cd083..92d810356 100644 --- a/mod/post.php +++ b/mod/post.php @@ -127,6 +127,12 @@ function post_init(&$a) { info(sprintf( t('Welcome %s. Remote authentication successful.'),$x[0]['xchan_name'])); logger('mod_zot: auth success from ' . $x[0]['xchan_addr'] . ' for ' . $webbie); + } else { + logger('mod_zot: still not authenticated: ' . $x[0]['xchan_addr']); + q("update hubloc set hubloc_status = (hubloc_status | %d ) where hubloc_addr = '%s'", + intval(HUBLOC_RECEIVE_ERROR), + $x[0][xchan_addr] + ); } // FIXME - we really want to save the return_url in the session before we visit rmagic. @@ -168,13 +174,49 @@ function post_post(&$a) { if(array_key_exists('iv',$data)) { $data = aes_unencapsulate($data,get_config('system','prvkey')); logger('mod_zot: decrypt1: ' . $data, LOGGER_DATA); + +// susceptible to Bleichenbacher's attack +// if(! $data) { +// $ret['message'] = 'Decryption failed.'; +// json_return_and_die($ret); +// } + $data = json_decode($data,true); + + } + + if(! $data) { + + // possible Bleichenbacher's attack, just treat it as a + // message we have no handler for. It should fail a bit + // further along with "no hub". Our public key is public + // knowledge. There's no reason why anybody should get the + // encryption wrong unless they're fishing or hacking. If + // they're developing and made a goof, this can be discovered + // in the logs of the destination site. If they're fishing or + // hacking, the bottom line is we can't verify their hub. + // That's all we're going to tell them. + + $data = array('type' => 'bogus'); } logger('mod_zot: decoded data: ' . print_r($data,true), LOGGER_DATA); $msgtype = ((array_key_exists('type',$data)) ? $data['type'] : ''); + if($msgtype === 'ping') { + + // Useful to get a health check on a remote site. + // This will let us know if any important communication details + // that we may have stored are no longer valid, regardless of xchan details. + + $ret['success'] = true; + $ret['site'] = array(); + $ret['site']['url'] = z_root(); + $ret['site']['url_sig'] = base64url_encode(rsa_sign(z_root(),get_config('system','prvkey'))); + $ret['site']['sitekey'] = get_config('system','pubkey'); + json_return_and_die($ret); + } if($msgtype === 'pickup') { @@ -297,13 +339,23 @@ function post_post(&$a) { // (!!) this will validate the sender $result = zot_register_hub($sender); - if((! $result['success']) || (! zot_gethub($sender))) { + if((! $result['success']) || (! ($hub = zot_gethub($sender)))) { $ret['message'] = 'Hub not available.'; logger('mod_zot: no hub'); json_return_and_die($ret); } } + + // Update our DB to show when we last communicated successfully with this hub + // This will allow us to prune dead hubs from using up resources + + $r = q("update hubloc set hubloc_connected = '%s' where hubloc_id = %d limit 1", + dbesc(datetime_convert()), + intval($hub['hubloc_id']) + ); + + // TODO: check which hub is primary and take action if mismatched if(array_key_exists('recipients',$data)) diff --git a/mod/probe.php b/mod/probe.php index 397f571c5..bd792d52e 100644 --- a/mod/probe.php +++ b/mod/probe.php @@ -15,9 +15,16 @@ function probe_content(&$a) { if(x($_GET,'addr')) { $channel = $a->get_channel(); $addr = trim($_GET['addr']); - $res = zot_finger($addr,$channel); + $res = zot_finger($addr,$channel,false); $o .= '<pre>'; - $j = json_decode($res['body'],true); + if($res['success']) + $j = json_decode($res['body'],true); + else { + $o .= "<strong>https connection failed. Trying again with auto failover to http.</strong>\r\n\r\n"; + $res = zot_finger($addr,$channel,true); + if($res['success']) + $j = json_decode($res['body'],true); + } if($j && $j['permissions'] && $j['permissions']['iv']) $j['permissions'] = json_decode(aes_unencapsulate($j['permissions'],$channel['channel_prvkey']),true); $o .= str_replace("\n",'<br />',print_r($j,true)); diff --git a/mod/pubsites.php b/mod/pubsites.php new file mode 100644 index 000000000..9728d0704 --- /dev/null +++ b/mod/pubsites.php @@ -0,0 +1,37 @@ +<?php + +function pubsites_content(&$a) { + require_once('include/dir_fns.php'); + $dirmode = intval(get_config('system','directory_mode')); + + if(($dirmode == DIRECTORY_MODE_PRIMARY) || ($dirmode == DIRECTORY_MODE_STANDALONE)) { + $url = z_root() . '/dirsearch'; + } + if(! $url) { + $directory = find_upstream_directory($dirmode); + + if($directory) { + $url = $directory['url'] . '/dirsearch'; + } + else { + $url = DIRECTORY_FALLBACK_MASTER . '/dirsearch'; + } + } + $url .= '/sites'; + + $o .= '<h1>' . t('Public Sites') . '</h1>'; + + $ret = z_fetch_url($url); + if($ret['success']) { + $j = json_decode($ret['body'],true); + if($j) { + $o .= '<table border="1"><tr><td>' . t('Site URL') . '</td><td>' . t('Access Type') . '</td><td>' . t('Registration Policy') . '</td></tr>'; + foreach($j['sites'] as $jj) { + $o .= '<tr><td>' . '<a href="'. (($jj['sellpage']) ? $jj['sellpage'] : $jj['url']) . '" >' . $jj['url'] . '</a>' . '</td><td>' . $jj['access'] . '</td><td>' . $jj['register'] . '</td></tr>'; + } + + $o .= '</table>'; + } + } + return $o; +} diff --git a/mod/register.php b/mod/register.php index 3ba714c74..bc1603f25 100644 --- a/mod/register.php +++ b/mod/register.php @@ -64,6 +64,12 @@ function register_post(&$a) { break; } + + if((! $_POST['password']) || ($_POST['password'] !== $_POST['password2'])) { + notice( t('Passwords do not match.') . EOL); + return; + } + $arr = $_POST; $arr['account_flags'] = $flags; diff --git a/mod/search.php b/mod/search.php index 38131f63f..539241268 100644 --- a/mod/search.php +++ b/mod/search.php @@ -183,23 +183,37 @@ function search_content(&$a,$update = 0, $load = false) { } - + $pub_sql = public_permissions_sql(get_observer_hash()); 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 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 mid ORDER BY created DESC $pager_sql ", - intval(local_user()), - intval(ABOOK_FLAG_BLOCKED) + $r = null; + + if(local_user()) { + $r = q("SELECT distinct mid, item.id as item_id, item.* 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 mid ORDER BY created DESC $pager_sql ", + intval(local_user()), + intval(ABOOK_FLAG_BLOCKED) - ); -dbg(0); + ); + } + if($r === null) { + $r = q("SELECT distinct mid, item.id as item_id, item.* 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 ) + and owner_xchan in ( " . stream_perms_xchans(($observer) ? PERMS_NETWORK : PERMS_PUBLIC) . " )) + $pub_sql ) + $sql_extra + group by mid ORDER BY created DESC $pager_sql" + ); + } } else { $r = array(); @@ -208,25 +222,23 @@ dbg(0); 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 - $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'); +// $parents_str = ids_to_querystr($r,'item_id'); + +// $items = q("SELECT `item`.*, `item`.`id` AS `item_id` +// FROM `item` +// WHERE item_restrict = 0 +// $sql_extra and parent in ( $parents_str ) " +// ); + + xchan_query($r); + $items = fetch_post_tags($r,true); +// $items = conv_sort($items,'created'); } else { $items = array(); } - +//logger('mod_search: items ' . count($items)); // $r = q("SELECT distinct(`item`.`mid`), `item`.*, `item`.`id` AS `item_id`, // `contact`.`name`, `contact`.`photo`, `contact`.`url`, `contact`.`alias`, `contact`.`rel`, diff --git a/mod/search_ac.php b/mod/search_ac.php index 5bc3c1c0b..36da21376 100644 --- a/mod/search_ac.php +++ b/mod/search_ac.php @@ -27,43 +27,27 @@ function search_ac_init(&$a){ // Priority to people searches if ($search) { - $people_sql_extra = protect_sprintf(" AND `name` LIKE '%". dbesc($search) . "%' "); + $people_sql_extra = protect_sprintf(" AND `xchan_name` LIKE '%". dbesc($search) . "%' "); $tag_sql_extra = protect_sprintf(" AND term LIKE '%". dbesc($search) . "%' "); } - $r = q("SELECT `id`, `name`, `micro`, `url` FROM `contact` - WHERE `uid` = %d AND `pending` = 0 + + $r = q("SELECT `abook_id`, `xchan_name`, `xchan_photo_s`, `xchan_url` FROM `abook` left join xchan on abook_xchan = xchan_hash WHERE abook_channel = %d $people_sql_extra - ORDER BY `name` ASC ", + ORDER BY `xchan_name` ASC ", intval(local_user()) ); - if(count($r)) { + if($r) { foreach($r as $g) { - $x['photos'][] = $g['micro']; - $x['links'][] = $g['url']; - $x['suggestions'][] = '@' . $g['name']; - $x['data'][] = intval($g['id']); - } - } - else { - - $r = q("SELECT `id`, `name`, `photo`, `url` FROM `gcontact` where 1 - $people_sql_extra - ORDER BY `name` ASC " - ); - - if(count($r)) { - foreach($r as $g) { - $x['photos'][] = $g['photo']; - $x['links'][] = $g['url']; - $x['suggestions'][] = '@' . $g['name']; - $x['data'][] = intval($g['id']); - } + $x['photos'][] = $g['xchan_photo_s']; + $x['links'][] = $g['xchan_url']; + $x['suggestions'][] = '@' . $g['xchan_name']; + $x['data'][] = 'cid=' . intval($g['abook_id']); } } - $r = q("select tid, term, url from term where type = %d $tag_sql_extra order by term asc", + $r = q("select distinct term, tid, url from term where type = %d $tag_sql_extra group by term order by term asc", intval(TERM_HASHTAG) ); diff --git a/mod/settings.php b/mod/settings.php index 36befead1..5f1106be5 100644 --- a/mod/settings.php +++ b/mod/settings.php @@ -31,6 +31,8 @@ function settings_aside(&$a) { $a->argv[] = 'channel'; } + $channel = $a->get_channel(); + $abook_self_id = 0; // Retrieve the 'self' address book entry for use in the auto-permissions link @@ -101,6 +103,26 @@ function settings_aside(&$a) { ); + + if(feature_enabled(local_user(),'premium_channel')) { + $tabs[] = array( + 'label' => t('Premium Channel Settings'), + 'url' => $a->get_baseurl(true) . '/connect/' . $channel['channel_address'], + 'selected' => '' + ); + + } + + if(feature_enabled(local_user(),'channel_sources')) { + $tabs[] = array( + 'label' => t('Channel Sources'), + 'url' => $a->get_baseurl(true) . '/sources', + 'selected' => '' + ); + + } + + $tabtpl = get_markup_template("generic_links_widget.tpl"); $a->page['aside'] = replace_macros($tabtpl, array( @@ -141,10 +163,17 @@ function settings_post(&$a) { $secret = ((x($_POST,'secret')) ? $_POST['secret'] : ''); $redirect = ((x($_POST,'redirect')) ? $_POST['redirect'] : ''); $icon = ((x($_POST,'icon')) ? $_POST['icon'] : ''); - if ($name=="" || $key=="" || $secret==""){ - notice(t("Missing some important data!")); - - } else { + $ok = true; + if($name == '') { + $ok = false; + notice( t('Name is required') . EOL); + } + if($key == '' || $secret == '') { + $ok = false; + notice( t('Key and Secret are required') . EOL); + } + + if($ok) { if ($_POST['submit']==t("Update")){ $r = q("UPDATE clients SET client_id='%s', @@ -348,26 +377,33 @@ function settings_post(&$a) { $post_newfriend = (($_POST['post_newfriend'] == 1) ? 1: 0); $post_joingroup = (($_POST['post_joingroup'] == 1) ? 1: 0); $post_profilechange = (($_POST['post_profilechange'] == 1) ? 1: 0); + $adult = (($_POST['adult'] == 1) ? 1 : 0); + $channel = $a->get_channel(); + $pageflags = $channel['channel_pageflags']; + $existing_adult = (($pageflags & PAGE_ADULT) ? 1 : 0); + if($adult != $existing_adult) + $pageflags = ($pageflags ^ PAGE_ADULT); $arr = array(); - $arr['channel_r_stream'] = (($_POST['view_stream']) ? $_POST['view_stream'] : 0); - $arr['channel_r_profile'] = (($_POST['view_profile']) ? $_POST['view_profile'] : 0); - $arr['channel_r_photos'] = (($_POST['view_photos']) ? $_POST['view_photos'] : 0); - $arr['channel_r_abook'] = (($_POST['view_contacts']) ? $_POST['view_contacts'] : 0); - $arr['channel_w_stream'] = (($_POST['send_stream']) ? $_POST['send_stream'] : 0); - $arr['channel_w_wall'] = (($_POST['post_wall']) ? $_POST['post_wall'] : 0); - $arr['channel_w_tagwall'] = (($_POST['tag_deliver']) ? $_POST['tag_deliver'] : 0); - $arr['channel_w_comment'] = (($_POST['post_comments']) ? $_POST['post_comments'] : 0); - $arr['channel_w_mail'] = (($_POST['post_mail']) ? $_POST['post_mail'] : 0); - $arr['channel_w_photos'] = (($_POST['post_photos']) ? $_POST['post_photos'] : 0); - $arr['channel_w_chat'] = (($_POST['chat']) ? $_POST['chat'] : 0); - $arr['channel_a_delegate'] = (($_POST['delegate']) ? $_POST['delegate'] : 0); - $arr['channel_r_storage'] = (($_POST['view_storage']) ? $_POST['view_storage'] : 0); - $arr['channel_w_storage'] = (($_POST['write_storage']) ? $_POST['write_storage'] : 0); - $arr['channel_r_pages'] = (($_POST['view_pages']) ? $_POST['view_pages'] : 0); - $arr['channel_w_pages'] = (($_POST['write_pages']) ? $_POST['write_pages'] : 0); - + $arr['channel_r_stream'] = (($_POST['view_stream']) ? $_POST['view_stream'] : 0); + $arr['channel_r_profile'] = (($_POST['view_profile']) ? $_POST['view_profile'] : 0); + $arr['channel_r_photos'] = (($_POST['view_photos']) ? $_POST['view_photos'] : 0); + $arr['channel_r_abook'] = (($_POST['view_contacts']) ? $_POST['view_contacts'] : 0); + $arr['channel_w_stream'] = (($_POST['send_stream']) ? $_POST['send_stream'] : 0); + $arr['channel_w_wall'] = (($_POST['post_wall']) ? $_POST['post_wall'] : 0); + $arr['channel_w_tagwall'] = (($_POST['tag_deliver']) ? $_POST['tag_deliver'] : 0); + $arr['channel_w_comment'] = (($_POST['post_comments']) ? $_POST['post_comments'] : 0); + $arr['channel_w_mail'] = (($_POST['post_mail']) ? $_POST['post_mail'] : 0); + $arr['channel_w_photos'] = (($_POST['post_photos']) ? $_POST['post_photos'] : 0); + $arr['channel_w_chat'] = (($_POST['chat']) ? $_POST['chat'] : 0); + $arr['channel_a_delegate'] = (($_POST['delegate']) ? $_POST['delegate'] : 0); + $arr['channel_r_storage'] = (($_POST['view_storage']) ? $_POST['view_storage'] : 0); + $arr['channel_w_storage'] = (($_POST['write_storage']) ? $_POST['write_storage'] : 0); + $arr['channel_r_pages'] = (($_POST['view_pages']) ? $_POST['view_pages'] : 0); + $arr['channel_w_pages'] = (($_POST['write_pages']) ? $_POST['write_pages'] : 0); + $arr['channel_a_republish'] = (($_POST['republish']) ? $_POST['republish'] : 0); + $defperms = 0; if(x($_POST['def_view_stream'])) $defperms += $_POST['def_view_stream']; @@ -401,6 +437,8 @@ function settings_post(&$a) { $defperms += $_POST['def_view_pages']; if(x($_POST['def_write_pages'])) $defperms += $_POST['def_write_pages']; + if(x($_POST['def_republish'])) + $defperms += $_POST['def_republish']; $notify = 0; @@ -505,8 +543,9 @@ function settings_post(&$a) { ); */ - $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", + $r = q("update channel set channel_name = '%s', channel_pageflags = %d, channel_timezone = '%s', channel_location = '%s', channel_notifyflags = %d, channel_max_anon_mail = %d, channel_max_friend_req = %d, channel_expire_days = %d, channel_r_stream = %d, channel_r_profile = %d, channel_r_photos = %d, channel_r_abook = %d, channel_w_stream = %d, channel_w_wall = %d, channel_w_tagwall = %d, channel_w_comment = %d, channel_w_mail = %d, channel_w_photos = %d, channel_w_chat = %d, channel_a_delegate = %d, channel_r_storage = %d, channel_w_storage = %d, channel_r_pages = %d, channel_w_pages = %d, channel_a_republish = %d where channel_id = %d limit 1", dbesc($username), + intval($pageflags), dbesc($timezone), dbesc($defloc), intval($notify), @@ -529,6 +568,7 @@ function settings_post(&$a) { intval($arr['channel_w_storage']), intval($arr['channel_r_pages']), intval($arr['channel_w_pages']), + intval($arr['channel_a_republish']), intval(local_user()) ); @@ -607,11 +647,11 @@ function settings_content(&$a) { '$title' => t('Add application'), '$submit' => t('Submit'), '$cancel' => t('Cancel'), - '$name' => array('name', t('Name'), '', ''), - '$key' => array('key', t('Consumer Key'), '', ''), - '$secret' => array('secret', t('Consumer Secret'), '', ''), - '$redirect' => array('redirect', t('Redirect'), '', ''), - '$icon' => array('icon', t('Icon url'), '', ''), + '$name' => array('name', t('Name'), '', t('Name of application')), + '$key' => array('key', t('Consumer Key'), random_string(16), t('Automatically generated - change if desired. Max length 20')), + '$secret' => array('secret', t('Consumer Secret'), random_string(16), t('Automatically generated - change if desired. Max length 20')), + '$redirect' => array('redirect', t('Redirect'), '', t('Redirect URI - leave blank unless your application specifically requires this')), + '$icon' => array('icon', t('Icon url'), '', t('Optional')), )); return $o; } @@ -916,6 +956,7 @@ function settings_content(&$a) { $maxreq = $channel['channel_max_friend_req']; $expire = $channel['channel_expire_days']; + $adult_flag = intval($channel['channel_pageflags'] & PAGE_ADULT); $blockwall = $a->user['blockwall']; $unkmail = $a->user['unkmail']; @@ -984,7 +1025,7 @@ function settings_content(&$a) { $stpl = get_markup_template('settings.tpl'); - $celeb = ((($a->user['page-flags'] == PAGE_SOAPBOX) || ($a->user['page-flags'] == PAGE_COMMUNITY)) ? true : false); + $celeb = false; $expire_arr = array( 'days' => array('expire', t("Automatically expire posts after this many days:"), $expire, t('If empty, posts will not expire. Expired posts will be deleted')), @@ -1021,6 +1062,7 @@ function settings_content(&$a) { '$defloc' => array('defloc', t('Default Post Location:'), $defloc, ''), '$allowloc' => array('allow_location', t('Use Browser Location:'), ((get_pconfig(local_user(),'system','use_browser_location')) ? 1 : ''), ''), + '$adult' => array('adult', t('Adult Content'), $adult_flag, t('This channel publishes adult content.')), '$h_prv' => t('Security and Privacy Settings'), diff --git a/mod/setup.php b/mod/setup.php index 3c0a133b7..97bdba34e 100755 --- a/mod/setup.php +++ b/mod/setup.php @@ -286,7 +286,7 @@ function setup_content(&$a) { return $o; }; break; case 3: { // Site settings - require_once('datetime.php'); + require_once('include/datetime.php'); $dbhost = ((x($_POST,'dbhost')) ? notags(trim($_POST['dbhost'])) : 'localhost'); $dbport = intval(notags(trim($_POST['dbuser']))); $dbuser = notags(trim($_POST['dbuser'])); diff --git a/mod/share.php b/mod/share.php index f0b14541f..1f767578d 100644 --- a/mod/share.php +++ b/mod/share.php @@ -21,7 +21,7 @@ function share_init(&$a) { $pos = strpos($r[0]['body'], "[share"); $o = substr($r[0]['body'], $pos); } else { - $o = "[share author='".str_replace("'", "'",$r[0]['author']['xchan_name']). + $o = "[share author='".urlencode($r[0]['author']['xchan_name']). "' profile='".$r[0]['author']['xchan_url'] . "' avatar='".$r[0]['author']['xchan_photo_s']. "' link='".$r[0]['plink']. diff --git a/mod/sources.php b/mod/sources.php new file mode 100644 index 000000000..125184d47 --- /dev/null +++ b/mod/sources.php @@ -0,0 +1,140 @@ +<?php /** @file */ + +function sources_post(&$a) { + if(! local_user()) + return; + + if(! feature_enabled(local_user(),'channel_sources')) + return ''; + + $source = intval($_REQUEST['source']); + $xchan = $_REQUEST['xchan']; + $words = $_REQUEST['words']; + $frequency = $_REQUEST['frequency']; + + $channel = $a->get_channel(); + + + if(! $source) { + $r = q("insert into source ( src_channel_id, src_channel_xchan, src_xchan, src_patt ) + values ( %d, '%s', '%s', '%s' ) ", + intval(local_user()), + dbesc($channel['channel_hash']), + dbesc($xchan), + dbesc($words) + ); + if($r) { + info( t('Source created.') . EOL); + } + goaway(z_root() . '/sources'); + } + else { + $r = q("update source set src_xchan = '%s', src_patt = '%s' where src_channel_id = %d and src_id = %d limit 1", + dbesc($xchan), + dbesc($words), + intval(local_user()), + intval($source) + ); + if($r) { + info( t('Source updated.') . EOL); + } + + } +} + + +function sources_content(&$a) { + if(! local_user()) { + notice( t('Permission denied.') . EOL); + return ''; + } + + if(! feature_enabled(local_user(),'channel_sources')) { + return ''; + } + + // list sources + if(argc() == 1) { + $r = q("select source.*, xchan.* from source left join xchan on src_xchan = xchan_hash where src_channel_id = %d", + intval(local_user()) + ); + if($r) { + for($x = 0; $x < count($r); $x ++) { + $r[$x]['src_patt'] = htmlspecialchars($r[$x]['src_patt'], ENT_COMPAT,'UTF-8'); + } + } + $o = replace_macros(get_markup_template('sources_list.tpl'), array( + '$title' => t('Channel Sources'), + '$desc' => t('Manage remote sources of content for your channel.'), + '$new' => t('New Source'), + '$sources' => $r + )); + return $o; + } + + if(argc() == 2 && argv(1) === 'new') { + // TODO add the words 'or RSS feed' and corresponding code to manage feeds and frequency + + $o = replace_macros(get_markup_template('sources_new.tpl'), array( + '$title' => t('New Source'), + '$desc' => t('Import all or selected content from the following channel into this channel and distribute it according to your channel settings.'), + '$words' => array( 'words', t('Only import content with these words (one per line)'),'',t('Leave blank to import all public content')), + '$name' => array( 'name', t('Channel Name'), '', ''), + '$submit' => t('Submit') + )); + return $o; + + } + + if(argc() == 2 && intval(argv(1))) { + // edit source + $r = q("select source.*, xchan.* from source left join xchan on src_xchan = xchan_hash where src_id = %d and src_channel_id = %d limit 1", + intval(argv(1)), + intval(local_user()) + ); + if(! $r) { + notice( t('Source not found.') . EOL); + return ''; + } + + $r[0]['src_patt'] = htmlspecialchars($r[0]['src_patt'], ENT_QUOTES,'UTF-8'); + + $o = replace_macros(get_markup_template('sources_edit.tpl'), array( + '$title' => t('Edit Source'), + '$drop' => t('Delete Source'), + '$id' => $r[0]['src_id'], + '$desc' => t('Import all or selected content from the following channel into this channel and distribute it according to your channel settings.'), + '$words' => array( 'words', t('Only import content with these words (one per line)'),$r[0]['src_patt'],t('Leave blank to import all public content')), + '$xchan' => $r[0]['src_xchan'], + '$name' => array( 'name', t('Channel Name'), $r[0]['xchan_name'], ''), + '$submit' => t('Submit') + )); + return $o; + + } + + if(argc() == 3 && intval(argv(1)) && argv(2) === 'drop') { + $r = q("select * from source where src_id = %d and src_channel_id = %d limit 1", + intval(argv(1)), + intval(local_user()) + ); + if(! $r) { + notice( t('Source not found.') . EOL); + return ''; + } + $r = q("delete from source where src_id = %d and src_channel_id = %d limit 1", + intval(argv(1)), + intval(local_user()) + ); + if($r) + info( t('Source removed') . EOL); + else + notice( t('Unable to remove source.') . EOL); + + goaway(z_root() . '/sources'); + + } + + // shouldn't get here. + +}
\ No newline at end of file diff --git a/mod/subthread.php b/mod/subthread.php index 66dc86eb2..11b7236fb 100755 --- a/mod/subthread.php +++ b/mod/subthread.php @@ -142,7 +142,8 @@ EOT; $arr['unseen'] = 1; $arr['last-child'] = 0; - $post_id = item_store($arr); + $post = item_store($arr); + $post_id = $post['item_id']; if(! $item['visible']) { $r = q("UPDATE `item` SET `visible` = 1 WHERE `id` = %d AND `uid` = %d LIMIT 1", diff --git a/mod/update_network.php b/mod/update_network.php index bb6245f65..0021af876 100644 --- a/mod/update_network.php +++ b/mod/update_network.php @@ -11,7 +11,7 @@ function update_network_content(&$a) { $load = (((argc() > 1) && (argv(1) == 'load')) ? 1 : 0); header("Content-type: text/html"); echo "<!DOCTYPE html><html><body>\r\n"; - echo (($_GET['msie'] == 1) ? '<div>' : '<section>'); + echo ((array_key_exists('msie',$_GET) && $_GET['msie'] == 1) ? '<div>' : '<section>'); $text = network_content($a,$profile_uid, $load); @@ -32,7 +32,7 @@ function update_network_content(&$a) { } echo str_replace("\t",' ',$text); - echo (($_GET['msie'] == 1) ? '</div>' : '</section>'); + echo ((array_key_exists('msie',$_GET) && $_GET['msie'] == 1) ? '</div>' : '</section>'); echo "</body></html>\r\n"; // logger('update_network: ' . $text); killme(); diff --git a/mod/webpages.php b/mod/webpages.php index fb133eccf..04c2e07c5 100644 --- a/mod/webpages.php +++ b/mod/webpages.php @@ -41,21 +41,38 @@ function webpages_content(&$a) { return; } + if(local_user() && local_user() == $owner) { + $a->set_widget('design',design_tools()); + } + + + $mimetype = get_config('system','page_mimetype'); + if(! $mimetype) + $mimetype = 'choose'; + + $layout = get_config('system','page_layout'); + if(! $layout) + $layout = 'choose'; + + // Create a status editor (for now - we'll need a WYSIWYG eventually) to create pages // Nickname is set to the observers xchan, and profile_uid to the owners. This lets you post pages at other people's channels. require_once ('include/conversation.php'); $x = array( - 'webpage' => 1, + 'webpage' => ITEM_WEBPAGE, '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' => intval($owner), + 'mimetype' => $mimetype, + 'layout' => $layout, ); $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. //TODO - this should be replaced with pagelist_widget diff --git a/mod/zfinger.php b/mod/zfinger.php index cf61233ad..3671da56e 100644 --- a/mod/zfinger.php +++ b/mod/zfinger.php @@ -71,7 +71,9 @@ function zfinger_init(&$a) { $id = $e['channel_id']; - $searchable = (($e['channel_pageflags'] & PAGE_HIDDEN) ? false : true); + $special_channel = (($e['channel_pageflags'] & PAGE_PREMIUM) ? true : false); + $adult_channel = (($e['channel_pageflags'] & PAGE_ADULT) ? true : false); + $searchable = (($e['channel_pageflags'] & PAGE_HIDDEN) ? false : true); if($e['xchan_flags'] & XCHAN_FLAGS_HIDDEN) $searchable = false; @@ -104,10 +106,13 @@ function zfinger_init(&$a) { if($p[0]['keywords']) { $tags = array(); $k = explode(' ',$p[0]['keywords']); - if($k) - foreach($k as $kk) - if(trim($kk)) - $tags[] = trim($kk); + if($k) { + foreach($k as $kk) { + if(trim($kk)) { + $tags[] = trim($kk," \t\n\r\0\x0B,"); + } + } + } if($tags) $profile['keywords'] = $tags; } @@ -128,11 +133,21 @@ function zfinger_init(&$a) { $ret['photo_updated'] = $e['xchan_photo_date']; $ret['url'] = $e['xchan_url']; $ret['connections_url']= (($e['xchan_connurl']) ? $e['xchan_connurl'] : z_root() . '/poco/' . $e['channel_address']); - $ret['name_updated'] = $e['xchan_name_date']; $ret['target'] = $ztarget; $ret['target_sig'] = $zsig; $ret['searchable'] = $searchable; + $ret['adult_content'] = $adult_channel; + + + // premium or other channel desiring some contact with potential followers before connecting. + // This is a template - %s will be replaced with the follow_url we discover for the return channel. + + if($special_channel) + $ret['connect_url'] = z_root() . '/connect/' . $e['channel_address']; + + // This is a template for our follow url, %s will be replaced with a webbie + $ret['follow_url'] = z_root() . '/follow?f=&url=%s'; $permissions = get_all_perms($e['channel_id'],(($ztarget && $zsig) ? base64url_encode(hash('whirlpool',$ztarget . $zsig,true)) @@ -149,11 +164,6 @@ function zfinger_init(&$a) { $ret['locations'] = array(); - - - - - $x = zot_get_hubloc(array($e['channel_hash'])); if($x && count($x)) { foreach($x as $hub) { @@ -165,7 +175,8 @@ function zfinger_init(&$a) { 'url' => $hub['hubloc_url'], 'url_sig' => $hub['hubloc_url_sig'], 'callback' => $hub['hubloc_callback'], - 'sitekey' => $hub['hubloc_sitekey'] + 'sitekey' => $hub['hubloc_sitekey'], + 'deleted' => (($hub['hubloc_flags'] & HUBLOC_FLAGS_DELETED) ? true : false) ); } } @@ -211,6 +222,8 @@ function zfinger_init(&$a) { $ret['site']['access_policy'] = 'paid'; if($access_policy == ACCESS_FREE) $ret['site']['access_policy'] = 'free'; + if($access_policy == ACCESS_TIERED) + $ret['site']['access_policy'] = 'tiered'; require_once('include/account.php'); $ret['site']['accounts'] = account_total(); @@ -234,8 +247,9 @@ function zfinger_init(&$a) { $ret['site']['plugins'] = $visible_plugins; $ret['site']['sitehash'] = get_config('system','location_hash'); $ret['site']['sitename'] = get_config('system','sitename'); + $ret['site']['sellpage'] = get_config('system','sellpage'); } json_return_and_die($ret); -}
\ No newline at end of file +} diff --git a/mod/zping.php b/mod/zping.php new file mode 100644 index 000000000..76f4470c1 --- /dev/null +++ b/mod/zping.php @@ -0,0 +1,28 @@ +<?php /** @file */ + +require_once('include/zot.php'); + +function zping_content(&$a) { + + // This is just a test utility function and may go away once we build these tools into + // the address book and directory to do dead site discovery. + + // The response packet include the current URL and key so we can discover if the server + // has been re-installed and clean up (e.g. get rid of) any old hublocs and xchans. + + // Remember to add '/post' to the url + + if(! local_user()) + return; + + $url = $_REQUEST['url']; + + if(! $url) + return; + + + $m = zot_build_packet($a->get_channel(),'ping'); + $r = zot_zot($url,$m); + return print_r($r,true); + +}
\ No newline at end of file |