diff options
Diffstat (limited to 'mod')
-rw-r--r-- | mod/admin.php | 6 | ||||
-rw-r--r-- | mod/babel.php | 56 | ||||
-rw-r--r-- | mod/content.php | 858 | ||||
-rw-r--r-- | mod/dfrn_confirm.php | 2 | ||||
-rw-r--r-- | mod/directory.php | 48 | ||||
-rwxr-xr-x | mod/events.php | 26 | ||||
-rw-r--r-- | mod/item.php | 68 | ||||
-rwxr-xr-x | mod/like.php | 187 | ||||
-rw-r--r-- | mod/lockview.php | 2 | ||||
-rw-r--r-- | mod/message.php | 4 | ||||
-rw-r--r-- | mod/parse_url.php | 4 | ||||
-rw-r--r-- | mod/photos.php | 45 | ||||
-rw-r--r-- | mod/profiles.php | 21 | ||||
-rw-r--r-- | mod/settings.php | 27 | ||||
-rw-r--r-- | mod/share.php | 29 | ||||
-rw-r--r-- | mod/wall_attach.php | 13 | ||||
-rw-r--r-- | mod/wall_upload.php | 13 |
17 files changed, 1255 insertions, 154 deletions
diff --git a/mod/admin.php b/mod/admin.php index 56f88a489..c8ed7a53b 100644 --- a/mod/admin.php +++ b/mod/admin.php @@ -183,13 +183,15 @@ function admin_page_summary(&$a) { Array( t('Normal Account'), 0), Array( t('Soapbox Account'), 0), Array( t('Community/Celebrity Account'), 0), - Array( t('Automatic Friend Account'), 0) + Array( t('Automatic Friend Account'), 0), + Array( t('Blog Account'), 0), + Array( t('Private Forum'), 0) ); $users=0; foreach ($r as $u){ $accounts[$u['page-flags']][1] = $u['count']; $users+= $u['count']; } - logger('accounts: ' . print_r($accounts,true)); + logger('accounts: ' . print_r($accounts,true),LOGGER_DATA); $r = q("SELECT COUNT(id) as `count` FROM `register`"); $pending = $r[0]['count']; diff --git a/mod/babel.php b/mod/babel.php new file mode 100644 index 000000000..1c881a5bd --- /dev/null +++ b/mod/babel.php @@ -0,0 +1,56 @@ +<?php + +require_once('include/bbcode.php'); +require_once('library/markdown.php'); +require_once('include/bb2diaspora.php'); +require_once('include/html2bbcode.php'); + +function visible_lf($s) { + return str_replace("\n",'<br />', $s); +} + +function babel_content(&$a) { + + $o .= '<h3>Babel Diagnostic</h3>'; + + $o .= '<form action="babel" method="post">'; + $o .= t('Source (bbcode) text:') . EOL . '<textarea name="text" >' . htmlspecialchars($_REQUEST['text']) .'</textarea>' . EOL; + $o .= '<input type="submit" name="submit" value="Submit" /></form>'; + + $o .= '<br /><br />'; + + if(x($_REQUEST,'text')) { + + $text = trim($_REQUEST['text']); + $o .= t("Source input: ") . EOL. EOL; + $o .= visible_lf($text) . EOL. EOL; + + $html = bbcode($text); + $o .= t("bb2html: ") . EOL. EOL; + $o .= $html. EOL. EOL; + + $bbcode = html2bbcode($html); + $o .= t("bb2html2bb: ") . EOL. EOL; + $o .= visible_lf($bbcode) . EOL. EOL; + + $diaspora = bb2diaspora($text); + $o .= t("bb2md: ") . EOL. EOL; + $o .= visible_lf($diaspora) . EOL. EOL; + + $html = Markdown($diaspora); + $o .= t("bb2md2html: ") . EOL. EOL; + $o .= $html. EOL. EOL; + + $bbcode = diaspora2bb($diaspora); + $o .= t("bb2dia2bb: ") . EOL. EOL; + $o .= visible_lf($bbcode) . EOL. EOL; + + $bbcode = html2bbcode($html); + $o .= t("bb2md2html2bb: ") . EOL. EOL; + $o .= visible_lf($bbcode) . EOL. EOL; + + + + } + return $o; +} diff --git a/mod/content.php b/mod/content.php new file mode 100644 index 000000000..5f3e954f6 --- /dev/null +++ b/mod/content.php @@ -0,0 +1,858 @@ +<?php + +// This is a purely experimental module and is not yet generally useful. + +// The eventual goal is to provide a json backend to fetch content and fill the current page. +// The page will be filled in on the frontend using javascript. +// At the present time this page is based on "network", but the hope is to extend to serving +// any content (wall, community, search, etc.). +// All search parameters, etc. will be managed in javascript and sent as request params. +// Security will be managed on the backend. +// There is no "pagination query", but we will manage the "current page" on the client +// and provide a link to fetch the next page - until there are no pages left to fetch. + +// With the exception of complex tag and text searches, this prototype is incredibly +// fast - e.g. one or two milliseconds to fetch parent items for the current content, +// and 10-20 milliseconds to fetch all the child items. + + +function content_content(&$a, $update = 0) { + + require_once('include/conversation.php'); + + + // Currently security is based on the logged in user + + if(! local_user()) { + return; + } + + $arr = array('query' => $a->query_string); + + call_hooks('content_content_init', $arr); + + + $datequery = $datequery2 = ''; + + $group = 0; + + $nouveau = false; + + if($a->argc > 1) { + for($x = 1; $x < $a->argc; $x ++) { + if(is_a_date_arg($a->argv[$x])) { + if($datequery) + $datequery2 = escape_tags($a->argv[$x]); + else { + $datequery = escape_tags($a->argv[$x]); + $_GET['order'] = 'post'; + } + } + elseif($a->argv[$x] === 'new') { + $nouveau = true; + } + elseif(intval($a->argv[$x])) { + $group = intval($a->argv[$x]); + $def_acl = array('allow_gid' => '<' . $group . '>'); + } + } + } + + + $o = ''; + + + + $contact_id = $a->cid; + + require_once('include/acl_selectors.php'); + + $cid = ((x($_GET,'cid')) ? intval($_GET['cid']) : 0); + $star = ((x($_GET,'star')) ? intval($_GET['star']) : 0); + $bmark = ((x($_GET,'bmark')) ? intval($_GET['bmark']) : 0); + $order = ((x($_GET,'order')) ? notags($_GET['order']) : 'comment'); + $liked = ((x($_GET,'liked')) ? intval($_GET['liked']) : 0); + $conv = ((x($_GET,'conv')) ? intval($_GET['conv']) : 0); + $spam = ((x($_GET,'spam')) ? intval($_GET['spam']) : 0); + $nets = ((x($_GET,'nets')) ? $_GET['nets'] : ''); + $cmin = ((x($_GET,'cmin')) ? intval($_GET['cmin']) : 0); + $cmax = ((x($_GET,'cmax')) ? intval($_GET['cmax']) : 99); + $file = ((x($_GET,'file')) ? $_GET['file'] : ''); + + + + if(x($_GET,'search') || x($_GET,'file')) + $nouveau = true; + if($cid) + $def_acl = array('allow_cid' => '<' . intval($cid) . '>'); + + if($nets) { + $r = q("select id from contact where uid = %d and network = '%s' and self = 0", + intval(local_user()), + dbesc($nets) + ); + + $str = ''; + if(count($r)) + foreach($r as $rr) + $str .= '<' . $rr['id'] . '>'; + if(strlen($str)) + $def_acl = array('allow_cid' => $str); + } + + + $sql_options = (($star) ? " and starred = 1 " : ''); + $sql_options .= (($bmark) ? " and bookmark = 1 " : ''); + + $sql_nets = (($nets) ? sprintf(" and `contact`.`network` = '%s' ", dbesc($nets)) : ''); + + $sql_extra = " AND `item`.`parent` IN ( SELECT `parent` FROM `item` WHERE `id` = `parent` $sql_options ) "; + + if($group) { + $r = q("SELECT `name`, `id` FROM `group` WHERE `id` = %d AND `uid` = %d LIMIT 1", + intval($group), + intval($_SESSION['uid']) + ); + if(! count($r)) { + if($update) + killme(); + notice( t('No such group') . EOL ); + goaway($a->get_baseurl(true) . '/network'); + // NOTREACHED + } + + $contacts = expand_groups(array($group)); + if((is_array($contacts)) && count($contacts)) { + $contact_str = implode(',',$contacts); + } + else { + $contact_str = ' 0 '; + info( t('Group is empty')); + } + + $sql_extra = " AND `item`.`parent` IN ( SELECT DISTINCT(`parent`) FROM `item` WHERE 1 $sql_options AND ( `contact-id` IN ( $contact_str ) OR `allow_gid` like '" . protect_sprintf('%<' . intval($group) . '>%') . "' ) and deleted = 0 ) "; + $o = '<h2>' . t('Group: ') . $r[0]['name'] . '</h2>' . $o; + } + elseif($cid) { + + $r = q("SELECT `id`,`name`,`network`,`writable`,`nurl` FROM `contact` WHERE `id` = %d + AND `blocked` = 0 AND `pending` = 0 LIMIT 1", + intval($cid) + ); + if(count($r)) { + $sql_extra = " AND `item`.`parent` IN ( SELECT DISTINCT(`parent`) FROM `item` WHERE 1 $sql_options AND `contact-id` = " . intval($cid) . " and deleted = 0 ) "; + + } + else { + killme(); + } + } + + + $sql_extra3 = ''; + + if($datequery) { + $sql_extra3 .= protect_sprintf(sprintf(" AND item.created <= '%s' ", dbesc(datetime_convert(date_default_timezone_get(),'',$datequery)))); + } + if($datequery2) { + $sql_extra3 .= protect_sprintf(sprintf(" AND item.created >= '%s' ", dbesc(datetime_convert(date_default_timezone_get(),'',$datequery2)))); + } + + $sql_extra2 = (($nouveau) ? '' : " AND `item`.`parent` = `item`.`id` "); + $sql_extra3 = (($nouveau) ? '' : $sql_extra3); + + if(x($_GET,'search')) { + $search = escape_tags($_GET['search']); + if (get_config('system','use_fulltext_engine')) { + if(strpos($search,'#') === 0) + $sql_extra .= sprintf(" AND (MATCH(tag) AGAINST ('".'"%s"'."' in boolean mode)) ", + dbesc(protect_sprintf($search)) + ); + else + $sql_extra .= sprintf(" AND (MATCH(`item`.`body`) AGAINST ('".'"%s"'."' in boolean mode) or MATCH(tag) AGAINST ('".'"%s"'."' in boolean mode)) ", + dbesc(protect_sprintf($search)), + dbesc(protect_sprintf($search)) + ); + } else { + $sql_extra .= sprintf(" AND ( `item`.`body` like '%s' OR `item`.`tag` like '%s' ) ", + dbesc(protect_sprintf('%' . $search . '%')), + dbesc(protect_sprintf('%]' . $search . '[%')) + ); + } + } + if(strlen($file)) { + $sql_extra .= file_tag_file_query('item',unxmlify($file)); + } + + if($conv) { + $myurl = $a->get_baseurl() . '/profile/'. $a->user['nickname']; + $myurl = substr($myurl,strpos($myurl,'://')+3); + $myurl = str_replace('www.','',$myurl); + $diasp_url = str_replace('/profile/','/u/',$myurl); + if (get_config('system','use_fulltext_engine')) + $sql_extra .= sprintf(" AND `item`.`parent` IN (SELECT distinct(`parent`) from item where (MATCH(`author-link`) AGAINST ('".'"%s"'."' in boolean mode) or MATCH(`tag`) AGAINST ('".'"%s"'."' in boolean mode) or MATCH(tag) AGAINST ('".'"%s"'."' in boolean mode))) ", + dbesc(protect_sprintf($myurl)), + dbesc(protect_sprintf($myurl)), + dbesc(protect_sprintf($diasp_url)) + ); + else + $sql_extra .= sprintf(" AND `item`.`parent` IN (SELECT distinct(`parent`) from item where ( `author-link` like '%s' or `tag` like '%s' or tag like '%s' )) ", + dbesc(protect_sprintf('%' . $myurl)), + dbesc(protect_sprintf('%' . $myurl . ']%')), + dbesc(protect_sprintf('%' . $diasp_url . ']%')) + ); + + } + + $pager_sql = sprintf(" LIMIT %d, %d ",intval($a->pager['start']), intval($a->pager['itemspage'])); + + + + + if($nouveau) { + // "New Item View" - show all items unthreaded in reverse created date order + + $items = q("SELECT `item`.*, `item`.`id` AS `item_id`, + `contact`.`name`, `contact`.`photo`, `contact`.`url`, `contact`.`rel`, `contact`.`writable`, + `contact`.`network`, `contact`.`thumb`, `contact`.`dfrn-id`, `contact`.`self`, + `contact`.`id` AS `cid`, `contact`.`uid` AS `contact-uid` + FROM `item`, `contact` + WHERE `item`.`uid` = %d AND `item`.`visible` = 1 + AND `item`.`deleted` = 0 and `item`.`moderated` = 0 + $simple_update + AND `contact`.`id` = `item`.`contact-id` + AND `contact`.`blocked` = 0 AND `contact`.`pending` = 0 + $sql_extra $sql_nets + ORDER BY `item`.`received` DESC $pager_sql ", + intval($_SESSION['uid']) + ); + + } + else { + + // Normal conversation view + + + if($order === 'post') + $ordering = "`created`"; + else + $ordering = "`commented`"; + + $start = dba_timer(); + + $r = q("SELECT `item`.`id` AS `item_id`, `contact`.`uid` AS `contact_uid` + FROM `item` LEFT JOIN `contact` ON `contact`.`id` = `item`.`contact-id` + WHERE `item`.`uid` = %d AND `item`.`visible` = 1 AND `item`.`deleted` = 0 + AND `item`.`moderated` = 0 AND `contact`.`blocked` = 0 AND `contact`.`pending` = 0 + AND `item`.`parent` = `item`.`id` + $sql_extra3 $sql_extra $sql_nets + ORDER BY `item`.$ordering DESC $pager_sql ", + intval(local_user()) + ); + + $first = dba_timer(); + + + // Then fetch all the children of the parents that are on this page + + $parents_arr = array(); + $parents_str = ''; + + if(count($r)) { + foreach($r as $rr) + if(! in_array($rr['item_id'],$parents_arr)) + $parents_arr[] = $rr['item_id']; + $parents_str = implode(', ', $parents_arr); + + $items = q("SELECT `item`.*, `item`.`id` AS `item_id`, + `contact`.`name`, `contact`.`photo`, `contact`.`url`, `contact`.`alias`, `contact`.`rel`, `contact`.`writable`, + `contact`.`network`, `contact`.`thumb`, `contact`.`dfrn-id`, `contact`.`self`, + `contact`.`id` AS `cid`, `contact`.`uid` AS `contact-uid` + FROM `item`, `contact` + WHERE `item`.`uid` = %d AND `item`.`visible` = 1 AND `item`.`deleted` = 0 + AND `item`.`moderated` = 0 AND `contact`.`id` = `item`.`contact-id` + AND `contact`.`blocked` = 0 AND `contact`.`pending` = 0 + AND `item`.`parent` IN ( %s ) + $sql_extra ", + intval(local_user()), + dbesc($parents_str) + ); + + $second = dba_timer(); + + $items = conv_sort($items,$ordering); + + } else { + $items = array(); + } + } + + + logger('parent dba_timer: ' . sprintf('%01.4f',$first - $start)); + logger('child dba_timer: ' . sprintf('%01.4f',$second - $first)); + + // Set this so that the conversation function can find out contact info for our wall-wall items + $a->page_contact = $a->contact; + + $mode = (($nouveau) ? 'network-new' : 'network'); + + $o = render_content($a,$items,$mode,false); + + + header('Content-type: application/json'); + echo json_encode($o); + killme(); +} + + + +function render_content(&$a, $items, $mode, $update, $preview = false) { + + + require_once('bbcode.php'); + + $ssl_state = ((local_user()) ? true : false); + + $profile_owner = 0; + $page_writeable = false; + + $previewing = (($preview) ? ' preview ' : ''); + + if($mode === 'network') { + $profile_owner = local_user(); + $page_writeable = true; + } + + if($mode === 'profile') { + $profile_owner = $a->profile['profile_uid']; + $page_writeable = can_write_wall($a,$profile_owner); + } + + if($mode === 'notes') { + $profile_owner = local_user(); + $page_writeable = true; + } + + if($mode === 'display') { + $profile_owner = $a->profile['uid']; + $page_writeable = can_write_wall($a,$profile_owner); + } + + if($mode === 'community') { + $profile_owner = 0; + $page_writeable = false; + } + + if($update) + $return_url = $_SESSION['return_url']; + else + $return_url = $_SESSION['return_url'] = $a->query_string; + + load_contact_links(local_user()); + + $cb = array('items' => $items, 'mode' => $mode, 'update' => $update, 'preview' => $preview); + call_hooks('conversation_start',$cb); + + $items = $cb['items']; + + $cmnt_tpl = get_markup_template('comment_item.tpl'); + $tpl = 'wall_item.tpl'; + $wallwall = 'wallwall_item.tpl'; + $hide_comments_tpl = get_markup_template('hide_comments.tpl'); + + $alike = array(); + $dlike = array(); + + + // array with html for each thread (parent+comments) + $threads = array(); + $threadsid = -1; + + if($items && count($items)) { + + if($mode === 'network-new' || $mode === 'search' || $mode === 'community') { + + // "New Item View" on network page or search page results + // - just loop through the items and format them minimally for display + + //$tpl = get_markup_template('search_item.tpl'); + $tpl = 'search_item.tpl'; + + foreach($items as $item) { + $threadsid++; + + $comment = ''; + $owner_url = ''; + $owner_photo = ''; + $owner_name = ''; + $sparkle = ''; + + if($mode === 'search' || $mode === 'community') { + if(((activity_match($item['verb'],ACTIVITY_LIKE)) || (activity_match($item['verb'],ACTIVITY_DISLIKE))) + && ($item['id'] != $item['parent'])) + continue; + $nickname = $item['nickname']; + } + else + $nickname = $a->user['nickname']; + + // prevent private email from leaking. + if($item['network'] === NETWORK_MAIL && local_user() != $item['uid']) + continue; + + $profile_name = ((strlen($item['author-name'])) ? $item['author-name'] : $item['name']); + if($item['author-link'] && (! $item['author-name'])) + $profile_name = $item['author-link']; + + + + $sp = false; + $profile_link = best_link_url($item,$sp); + if($profile_link === 'mailbox') + $profile_link = ''; + if($sp) + $sparkle = ' sparkle'; + else + $profile_link = zrl($profile_link); + + $normalised = normalise_link((strlen($item['author-link'])) ? $item['author-link'] : $item['url']); + if(($normalised != 'mailbox') && (x($a->contacts[$normalised]))) + $profile_avatar = $a->contacts[$normalised]['thumb']; + else + $profile_avatar = ((strlen($item['author-avatar'])) ? $a->get_cached_avatar_image($item['author-avatar']) : $item['thumb']); + + $locate = array('location' => $item['location'], 'coord' => $item['coord'], 'html' => ''); + call_hooks('render_location',$locate); + + $location = ((strlen($locate['html'])) ? $locate['html'] : render_location_google($locate)); + + localize_item($item); + if($mode === 'network-new') + $dropping = true; + else + $dropping = false; + + + $drop = array( + 'dropping' => $dropping, + 'select' => t('Select'), + 'delete' => t('Delete'), + ); + + $star = false; + $isstarred = "unstarred"; + + $lock = false; + $likebuttons = false; + $shareable = false; + + $body = prepare_body($item,true); + + //$tmp_item = replace_macros($tpl,array( + $tmp_item = array( + 'template' => $tpl, + 'id' => (($preview) ? 'P0' : $item['item_id']), + 'linktitle' => sprintf( t('View %s\'s profile @ %s'), $profile_name, ((strlen($item['author-link'])) ? $item['author-link'] : $item['url'])), + 'profile_url' => $profile_link, + 'item_photo_menu' => item_photo_menu($item), + 'name' => template_escape($profile_name), + 'sparkle' => $sparkle, + 'lock' => $lock, + 'thumb' => $profile_avatar, + 'title' => template_escape($item['title']), + 'body' => template_escape($body), + 'text' => strip_tags(template_escape($body)), + 'ago' => (($item['app']) ? sprintf( t('%s from %s'),relative_date($item['created']),$item['app']) : relative_date($item['created'])), + 'location' => template_escape($location), + 'indent' => '', + 'owner_name' => template_escape($owner_name), + 'owner_url' => $owner_url, + 'owner_photo' => $owner_photo, + 'plink' => get_plink($item), + 'edpost' => false, + 'isstarred' => $isstarred, + 'star' => $star, + 'drop' => $drop, + 'vote' => $likebuttons, + 'like' => '', + 'dislike' => '', + 'comment' => '', + 'conv' => (($preview) ? '' : array('href'=> $a->get_baseurl($ssl_state) . '/display/' . $nickname . '/' . $item['id'], 'title'=> t('View in context'))), + 'previewing' => $previewing, + 'wait' => t('Please wait'), + ); + + $arr = array('item' => $item, 'output' => $tmp_item); + call_hooks('display_item', $arr); + + $threads[$threadsid]['id'] = $item['item_id']; + $threads[$threadsid]['items'] = array($arr['output']); + + } + + } + else + { + // Normal View + + + // Figure out how many comments each parent has + // (Comments all have gravity of 6) + // Store the result in the $comments array + + $comments = array(); + foreach($items as $item) { + if((intval($item['gravity']) == 6) && ($item['id'] != $item['parent'])) { + if(! x($comments,$item['parent'])) + $comments[$item['parent']] = 1; + else + $comments[$item['parent']] += 1; + } elseif(! x($comments,$item['parent'])) + $comments[$item['parent']] = 0; // avoid notices later on + } + + // map all the like/dislike activities for each parent item + // Store these in the $alike and $dlike arrays + + foreach($items as $item) { + like_puller($a,$item,$alike,'like'); + like_puller($a,$item,$dlike,'dislike'); + } + + $comments_collapsed = false; + $comments_seen = 0; + $comment_lastcollapsed = false; + $comment_firstcollapsed = false; + $blowhard = 0; + $blowhard_count = 0; + + + foreach($items as $item) { + + $comment = ''; + $template = $tpl; + $commentww = ''; + $sparkle = ''; + $owner_url = $owner_photo = $owner_name = ''; + + // We've already parsed out like/dislike for special treatment. We can ignore them now + + if(((activity_match($item['verb'],ACTIVITY_LIKE)) + || (activity_match($item['verb'],ACTIVITY_DISLIKE))) + && ($item['id'] != $item['parent'])) + continue; + + $toplevelpost = (($item['id'] == $item['parent']) ? true : false); + + + // Take care of author collapsing and comment collapsing + // (author collapsing is currently disabled) + // If a single author has more than 3 consecutive top-level posts, squash the remaining ones. + // If there are more than two comments, squash all but the last 2. + + if($toplevelpost) { + + $item_writeable = (($item['writable'] || $item['self']) ? true : false); + + $comments_seen = 0; + $comments_collapsed = false; + $comment_lastcollapsed = false; + $comment_firstcollapsed = false; + + $threadsid++; + $threads[$threadsid]['id'] = $item['item_id']; + $threads[$threadsid]['private'] = $item['private']; + $threads[$threadsid]['items'] = array(); + + } + else { + + // prevent private email reply to public conversation from leaking. + if($item['network'] === NETWORK_MAIL && local_user() != $item['uid']) + continue; + + $comments_seen ++; + $comment_lastcollapsed = false; + $comment_firstcollapsed = false; + } + + $override_comment_box = ((($page_writeable) && ($item_writeable)) ? true : false); + $show_comment_box = ((($page_writeable) && ($item_writeable) && ($comments_seen == $comments[$item['parent']])) ? true : false); + + + if(($comments[$item['parent']] > 2) && ($comments_seen <= ($comments[$item['parent']] - 2)) && ($item['gravity'] == 6)) { + + if (!$comments_collapsed){ + $threads[$threadsid]['num_comments'] = sprintf( tt('%d comment','%d comments',$comments[$item['parent']]),$comments[$item['parent']] ); + $threads[$threadsid]['hide_text'] = t('show more'); + $comments_collapsed = true; + $comment_firstcollapsed = true; + } + } + if(($comments[$item['parent']] > 2) && ($comments_seen == ($comments[$item['parent']] - 1))) { + + $comment_lastcollapsed = true; + } + + $redirect_url = $a->get_baseurl($ssl_state) . '/redir/' . $item['cid'] ; + + $lock = ((($item['private'] == 1) || (($item['uid'] == local_user()) && (strlen($item['allow_cid']) || strlen($item['allow_gid']) + || strlen($item['deny_cid']) || strlen($item['deny_gid'])))) + ? t('Private Message') + : false); + + + // Top-level wall post not written by the wall owner (wall-to-wall) + // First figure out who owns it. + + $osparkle = ''; + + if(($toplevelpost) && (! $item['self']) && ($mode !== 'profile')) { + + if($item['wall']) { + + // On the network page, I am the owner. On the display page it will be the profile owner. + // This will have been stored in $a->page_contact by our calling page. + // Put this person as the wall owner of the wall-to-wall notice. + + $owner_url = zrl($a->page_contact['url']); + $owner_photo = $a->page_contact['thumb']; + $owner_name = $a->page_contact['name']; + $template = $wallwall; + $commentww = 'ww'; + } + + if((! $item['wall']) && $item['owner-link']) { + + $owner_linkmatch = (($item['owner-link']) && link_compare($item['owner-link'],$item['author-link'])); + $alias_linkmatch = (($item['alias']) && link_compare($item['alias'],$item['author-link'])); + $owner_namematch = (($item['owner-name']) && $item['owner-name'] == $item['author-name']); + if((! $owner_linkmatch) && (! $alias_linkmatch) && (! $owner_namematch)) { + + // The author url doesn't match the owner (typically the contact) + // and also doesn't match the contact alias. + // The name match is a hack to catch several weird cases where URLs are + // all over the park. It can be tricked, but this prevents you from + // seeing "Bob Smith to Bob Smith via Wall-to-wall" and you know darn + // well that it's the same Bob Smith. + + // But it could be somebody else with the same name. It just isn't highly likely. + + + $owner_url = $item['owner-link']; + $owner_photo = $item['owner-avatar']; + $owner_name = $item['owner-name']; + $template = $wallwall; + $commentww = 'ww'; + // If it is our contact, use a friendly redirect link + if((link_compare($item['owner-link'],$item['url'])) + && ($item['network'] === NETWORK_DFRN)) { + $owner_url = $redirect_url; + $osparkle = ' sparkle'; + } + else + $owner_url = zrl($owner_url); + } + } + } + + $likebuttons = ''; + $shareable = ((($profile_owner == local_user()) && ($item['private'] != 1)) ? true : false); + + if($page_writeable) { +/* if($toplevelpost) { */ + $likebuttons = array( + 'like' => array( t("I like this \x28toggle\x29"), t("like")), + 'dislike' => array( t("I don't like this \x28toggle\x29"), t("dislike")), + ); + if ($shareable) $likebuttons['share'] = array( t('Share this'), t('share')); +/* } */ + + $qc = $qcomment = null; + + if(in_array('qcomment',$a->plugins)) { + $qc = ((local_user()) ? get_pconfig(local_user(),'qcomment','words') : null); + $qcomment = (($qc) ? explode("\n",$qc) : null); + } + + if(($show_comment_box) || (($show_comment_box == false) && ($override_comment_box == false) && ($item['last-child']))) { + $comment = replace_macros($cmnt_tpl,array( + '$return_path' => '', + '$jsreload' => (($mode === 'display') ? $_SESSION['return_url'] : ''), + '$type' => (($mode === 'profile') ? 'wall-comment' : 'net-comment'), + '$id' => $item['item_id'], + '$parent' => $item['parent'], + '$qcomment' => $qcomment, + '$profile_uid' => $profile_owner, + '$mylink' => $a->contact['url'], + '$mytitle' => t('This is you'), + '$myphoto' => $a->contact['thumb'], + '$comment' => t('Comment'), + '$submit' => t('Submit'), + '$edbold' => t('Bold'), + '$editalic' => t('Italic'), + '$eduline' => t('Underline'), + '$edquote' => t('Quote'), + '$edcode' => t('Code'), + '$edimg' => t('Image'), + '$edurl' => t('Link'), + '$edvideo' => t('Video'), + '$preview' => t('Preview'), + '$ww' => (($mode === 'network') ? $commentww : '') + )); + } + } + + if(local_user() && link_compare($a->contact['url'],$item['author-link'])) + $edpost = array($a->get_baseurl($ssl_state)."/editpost/".$item['id'], t("Edit")); + else + $edpost = false; + + $drop = ''; + $dropping = false; + + if((intval($item['contact-id']) && $item['contact-id'] == remote_user()) || ($item['uid'] == local_user())) + $dropping = true; + + $drop = array( + 'dropping' => $dropping, + 'select' => t('Select'), + 'delete' => t('Delete'), + ); + + $star = false; + $filer = false; + + $isstarred = "unstarred"; + if ($profile_owner == local_user()) { + if($toplevelpost) { + $isstarred = (($item['starred']) ? "starred" : "unstarred"); + + $star = array( + 'do' => t("add star"), + 'undo' => t("remove star"), + 'toggle' => t("toggle star status"), + 'classdo' => (($item['starred']) ? "hidden" : ""), + 'classundo' => (($item['starred']) ? "" : "hidden"), + 'starred' => t('starred'), + 'tagger' => t("add tag"), + 'classtagger' => "", + ); + } + $filer = t("save to folder"); + } + + + $photo = $item['photo']; + $thumb = $item['thumb']; + + // Post was remotely authored. + + $diff_author = ((link_compare($item['url'],$item['author-link'])) ? false : true); + + $profile_name = (((strlen($item['author-name'])) && $diff_author) ? $item['author-name'] : $item['name']); + + if($item['author-link'] && (! $item['author-name'])) + $profile_name = $item['author-link']; + + $sp = false; + $profile_link = best_link_url($item,$sp); + if($profile_link === 'mailbox') + $profile_link = ''; + if($sp) + $sparkle = ' sparkle'; + else + $profile_link = zrl($profile_link); + + $normalised = normalise_link((strlen($item['author-link'])) ? $item['author-link'] : $item['url']); + if(($normalised != 'mailbox') && (x($a->contacts,$normalised))) + $profile_avatar = $a->contacts[$normalised]['thumb']; + else + $profile_avatar = (((strlen($item['author-avatar'])) && $diff_author) ? $item['author-avatar'] : $a->get_cached_avatar_image($thumb)); + + $like = ((x($alike,$item['uri'])) ? format_like($alike[$item['uri']],$alike[$item['uri'] . '-l'],'like',$item['uri']) : ''); + $dislike = ((x($dlike,$item['uri'])) ? format_like($dlike[$item['uri']],$dlike[$item['uri'] . '-l'],'dislike',$item['uri']) : ''); + + $locate = array('location' => $item['location'], 'coord' => $item['coord'], 'html' => ''); + call_hooks('render_location',$locate); + + $location = ((strlen($locate['html'])) ? $locate['html'] : render_location_google($locate)); + + $indent = (($toplevelpost) ? '' : ' comment'); + + if(strcmp(datetime_convert('UTC','UTC',$item['created']),datetime_convert('UTC','UTC','now - 12 hours')) > 0) + $indent .= ' shiny'; + + // + localize_item($item); + + + $tags=array(); + foreach(explode(',',$item['tag']) as $tag){ + $tag = trim($tag); + if ($tag!="") $tags[] = bbcode($tag); + } + + // Build the HTML + + $body = prepare_body($item,true); + //$tmp_item = replace_macros($template, + $tmp_item = array( + // collapse comments in template. I don't like this much... + 'comment_firstcollapsed' => $comment_firstcollapsed, + 'comment_lastcollapsed' => $comment_lastcollapsed, + // template to use to render item (wall, walltowall, search) + 'template' => $template, + + 'type' => implode("",array_slice(explode("/",$item['verb']),-1)), + 'tags' => $tags, + 'body' => template_escape($body), + 'text' => strip_tags(template_escape($body)), + 'id' => $item['item_id'], + 'linktitle' => sprintf( t('View %s\'s profile @ %s'), $profile_name, ((strlen($item['author-link'])) ? $item['author-link'] : $item['url'])), + 'olinktitle' => sprintf( t('View %s\'s profile @ %s'), $profile_name, ((strlen($item['owner-link'])) ? $item['owner-link'] : $item['url'])), + 'to' => t('to'), + 'wall' => t('Wall-to-Wall'), + 'vwall' => t('via Wall-To-Wall:'), + 'profile_url' => $profile_link, + 'item_photo_menu' => item_photo_menu($item), + 'name' => template_escape($profile_name), + 'thumb' => $profile_avatar, + 'osparkle' => $osparkle, + 'sparkle' => $sparkle, + 'title' => template_escape($item['title']), + 'ago' => (($item['app']) ? sprintf( t('%s from %s'),relative_date($item['created']),$item['app']) : relative_date($item['created'])), + 'lock' => $lock, + 'location' => template_escape($location), + 'indent' => $indent, + 'owner_url' => $owner_url, + 'owner_photo' => $owner_photo, + 'owner_name' => template_escape($owner_name), + 'plink' => get_plink($item), + 'edpost' => $edpost, + 'isstarred' => $isstarred, + 'star' => $star, + 'filer' => $filer, + 'drop' => $drop, + 'vote' => $likebuttons, + 'like' => $like, + 'dislike' => $dislike, + 'comment' => $comment, + 'previewing' => $previewing, + 'wait' => t('Please wait'), + + ); + + + $arr = array('item' => $item, 'output' => $tmp_item); + call_hooks('display_item', $arr); + + $threads[$threadsid]['items'][] = $arr['output']; + } + } + } + + + return $threads; + +} diff --git a/mod/dfrn_confirm.php b/mod/dfrn_confirm.php index 76b99cbca..8e39f5fd0 100644 --- a/mod/dfrn_confirm.php +++ b/mod/dfrn_confirm.php @@ -146,7 +146,7 @@ function dfrn_confirm_post(&$a,$handsfree = null) { */ require_once('include/crypto.php'); - $res = new_keypair(1024); + $res = new_keypair(4096); $private_key = $res['prvkey']; $public_key = $res['pubkey']; diff --git a/mod/directory.php b/mod/directory.php index 930a575b6..8a5685c9a 100644 --- a/mod/directory.php +++ b/mod/directory.php @@ -73,14 +73,12 @@ function directory_content(&$a) { $order = " ORDER BY `name` ASC "; - $r = q("SELECT `profile`.*, `profile`.`uid` AS `profile_uid`, `user`.`nickname`, `user`.`timezone` FROM `profile` LEFT JOIN `user` ON `user`.`uid` = `profile`.`uid` WHERE `is-default` = 1 $publish AND `user`.`blocked` = 0 $sql_extra $order LIMIT %d , %d ", + $r = q("SELECT `profile`.*, `profile`.`uid` AS `profile_uid`, `user`.`nickname`, `user`.`timezone` , `user`.`page-flags` FROM `profile` LEFT JOIN `user` ON `user`.`uid` = `profile`.`uid` WHERE `is-default` = 1 $publish AND `user`.`blocked` = 0 $sql_extra $order LIMIT %d , %d ", intval($a->pager['start']), intval($a->pager['itemspage']) ); if(count($r)) { - $tpl = get_markup_template('directory_item.tpl'); - if(in_array('small', $a->argv)) $photo = 'thumb'; else @@ -113,20 +111,60 @@ function directory_content(&$a) { if(strlen($rr['gender'])) $details .= '<br />' . t('Gender: ') . $rr['gender']; + if($rr['page-flags'] == PAGE_NORMAL) + $page_type = "Personal Profile"; + if($rr['page-flags'] == PAGE_SOAPBOX) + $page_type = "Fan Page"; + if($rr['page-flags'] == PAGE_COMMUNITY) + $page_type = "Community Forum"; + if($rr['page-flags'] == PAGE_FREELOVE) + $page_type = "Open Forum"; + if($rr['page-flags'] == PAGE_PRVGROUP) + $page_type = "Private Group"; + + $profile = $rr; + + if((x($profile,'address') == 1) + || (x($profile,'locality') == 1) + || (x($profile,'region') == 1) + || (x($profile,'postal-code') == 1) + || (x($profile,'country-name') == 1)) + $location = t('Location:'); + + $gender = ((x($profile,'gender') == 1) ? t('Gender:') : False); + + $marital = ((x($profile,'marital') == 1) ? t('Status:') : False); + + $homepage = ((x($profile,'homepage') == 1) ? t('Homepage:') : False); + + $about = ((x($profile,'about') == 1) ? t('About:') : False); + + $tpl = get_markup_template('directory_item.tpl'); + $entry = replace_macros($tpl,array( '$id' => $rr['id'], '$profile-link' => $profile_link, '$photo' => $a->get_cached_avatar_image($rr[$photo]), '$alt-text' => $rr['name'], '$name' => $rr['name'], - '$details' => $pdesc . $details - + '$details' => $pdesc . $details, + '$page-type' => $page_type, + '$profile' => $profile, + '$location' => template_escape($location), + '$gender' => $gender, + '$pdesc' => $pdesc, + '$marital' => $marital, + '$homepage' => $homepage, + '$about' => $about, )); $arr = array('contact' => $rr, 'entry' => $entry); call_hooks('directory_item', $arr); + + unset($profile); + unset($location); $o .= $entry; diff --git a/mod/events.php b/mod/events.php index 2a6fb692e..bf02f8309 100755 --- a/mod/events.php +++ b/mod/events.php @@ -57,12 +57,13 @@ function events_post(&$a) { if(strcmp($finish,$start) < 0) $finish = $start; + $summary = escape_tags(trim($_POST['summary'])); $desc = escape_tags(trim($_POST['desc'])); $location = escape_tags(trim($_POST['location'])); $type = 'event'; - if((! $desc) || (! $start)) { - notice( t('Event description and start time are required.') . EOL); + if((! $summary) || (! $start)) { + notice( t('Event title and start time are required.') . EOL); goaway($a->get_baseurl() . '/events/new'); } @@ -107,6 +108,7 @@ function events_post(&$a) { $datarray = array(); $datarray['start'] = $start; $datarray['finish'] = $finish; + $datarray['summary'] = $summary; $datarray['desc'] = $desc; $datarray['location'] = $location; $datarray['type'] = $type; @@ -118,7 +120,7 @@ function events_post(&$a) { $datarray['allow_gid'] = $str_group_allow; $datarray['deny_cid'] = $str_contact_deny; $datarray['deny_gid'] = $str_group_deny; - $datarray['private'] = $private_event; + $datarray['private'] = (($private_event) ? 1 : 0); $datarray['id'] = $event_id; $datarray['created'] = $created; $datarray['edited'] = $edited; @@ -278,9 +280,11 @@ function events_content(&$a) { $last_date = $d; $edit = ((! $rr['cid']) ? array($a->get_baseurl().'/events/event/'.$rr['id'],t('Edit event'),'','') : null); - - list($title, $_trash) = explode("<br",bbcode($rr['desc']),2); - $title = strip_tags($title); + $title = strip_tags(html_entity_decode(bbcode($rr['summary']),ENT_QUOTES,'UTF-8')); + if(! $title) { + list($title, $_trash) = explode("<br",bbcode($rr['desc']),2); + $title = strip_tags(html_entity_decode($title,ENT_QUOTES,'UTF-8')); + } $html = format_event_html($rr); $rr['desc'] = bbcode($rr['desc']); $rr['location'] = bbcode($rr['location']); @@ -351,6 +355,7 @@ function events_content(&$a) { $n_checked = ((x($orig_event) && $orig_event['nofinish']) ? ' checked="checked" ' : ''); $a_checked = ((x($orig_event) && $orig_event['adjust']) ? ' checked="checked" ' : ''); + $t_orig = ((x($orig_event)) ? $orig_event['summary'] : ''); $d_orig = ((x($orig_event)) ? $orig_event['desc'] : ''); $l_orig = ((x($orig_event)) ? $orig_event['location'] : ''); $eid = ((x($orig_event)) ? $orig_event['id'] : 0); @@ -405,10 +410,11 @@ function events_content(&$a) { '$eid' => $eid, '$cid' => $cid, '$uri' => $uri, + '$title' => t('Event details'), - '$desc' => sprintf( t('Format is %s %s. Starting date and Description are required.'),$dateformat,$timeformat), + '$desc' => sprintf( t('Format is %s %s. Starting date and Title are required.'),$dateformat,$timeformat), - '$s_text' => t('Event Starts:') . ' <span class="required">*</span> ', + '$s_text' => t('Event Starts:') . ' <span class="required" title="' . t('Required') . '">*</span>', '$s_dsel' => datesel($f,'start',$syear+5,$syear,false,$syear,$smonth,$sday), '$s_tsel' => timesel('start',$shour,$sminute), '$n_text' => t('Finish date/time is not known or not relevant'), @@ -418,10 +424,12 @@ function events_content(&$a) { '$f_tsel' => timesel('finish',$fhour,$fminute), '$a_text' => t('Adjust for viewer timezone'), '$a_checked' => $a_checked, - '$d_text' => t('Description:') . ' <span class="required">*</span>', + '$d_text' => t('Description:'), '$d_orig' => $d_orig, '$l_text' => t('Location:'), '$l_orig' => $l_orig, + '$t_text' => t('Title:') . ' <span class="required" title="' . t('Required') . '">*</span>', + '$t_orig' => $t_orig, '$sh_text' => t('Share this event'), '$sh_checked' => $sh_checked, '$acl' => (($cid) ? '' : populate_acl(((x($orig_event)) ? $orig_event : $a->user),false)), diff --git a/mod/item.php b/mod/item.php index c1c0b14ec..554e97fe4 100644 --- a/mod/item.php +++ b/mod/item.php @@ -108,7 +108,7 @@ function item_post(&$a) { } } - if($parent) logger('mod_post: parent=' . $parent); + if($parent) logger('mod_item: item_post parent=' . $parent); $profile_uid = ((x($_REQUEST,'profile_uid')) ? intval($_REQUEST['profile_uid']) : 0); $post_id = ((x($_REQUEST,'post_id')) ? intval($_REQUEST['post_id']) : 0); @@ -228,7 +228,7 @@ function item_post(&$a) { || strlen($parent_item['allow_gid']) || strlen($parent_item['deny_cid']) || strlen($parent_item['deny_gid'])) { - $private = 1; + $private = (($parent_item['private']) ? $parent_item['private'] : 1); } $str_contact_allow = $parent_item['allow_cid']; @@ -728,26 +728,10 @@ function item_post(&$a) { } - // We won't be able to sign Diaspora comments for authenticated visitors - we don't have their private key - if($self) { - require_once('include/bb2diaspora.php'); - $signed_body = html_entity_decode(bb2diaspora($datarray['body'])); - $myaddr = $a->user['nickname'] . '@' . substr($a->get_baseurl(), strpos($a->get_baseurl(),'://') + 3); - if($datarray['verb'] === ACTIVITY_LIKE) - $signed_text = $datarray['guid'] . ';' . 'Post' . ';' . $parent_item['guid'] . ';' . 'true' . ';' . $myaddr; - else - $signed_text = $datarray['guid'] . ';' . $parent_item['guid'] . ';' . $signed_body . ';' . $myaddr; - - $authorsig = base64_encode(rsa_sign($signed_text,$a->user['prvkey'],'sha256')); + // Store the comment signature information in case we need to relay to Diaspora + store_diaspora_comment_sig($datarray, $author, ($self ? $a->user['prvkey'] : false), $parent_item, $post_id); - q("insert into sign (`iid`,`signed_text`,`signature`,`signer`) values (%d,'%s','%s','%s') ", - intval($post_id), - dbesc($signed_text), - dbesc(base64_encode($authorsig)), - dbesc($myaddr) - ); - } } else { $parent = $post_id; @@ -1038,3 +1022,47 @@ function handle_tag($a, &$body, &$inform, &$str_tags, $profile_uid, $tag) { return array('replaced' => $replaced, 'contact' => $r[0]); } + + +function store_diaspora_comment_sig($datarray, $author, $uprvkey, $parent_item, $post_id) { + // We won't be able to sign Diaspora comments for authenticated visitors - we don't have their private key + + $enabled = intval(get_config('system','diaspora_enabled')); + if(! $enabled) { + logger('mod_item: diaspora support disabled, not storing comment signature', LOGGER_DEBUG); + return; + } + + + logger('mod_item: storing diaspora comment signature'); + + require_once('include/bb2diaspora.php'); + $signed_body = html_entity_decode(bb2diaspora($datarray['body'])); + +// $myaddr = $user['nickname'] . '@' . substr($baseurl, strpos($baseurl,'://') + 3); +// if( $author['network'] === NETWORK_DIASPORA) +// $diaspora_handle = $author['addr']; +// else { + // Only works for NETWORK_DFRN + $contact_baseurl_start = strpos($author['url'],'://') + 3; + $contact_baseurl_length = strpos($author['url'],'/profile') - $contact_baseurl_start; + $contact_baseurl = substr($author['url'], $contact_baseurl_start, $contact_baseurl_length); + $diaspora_handle = $author['nick'] . '@' . $contact_baseurl; +// } + + $signed_text = $datarray['guid'] . ';' . $parent_item['guid'] . ';' . $signed_body . ';' . $diaspora_handle; + + if( $uprvkey !== false ) + $authorsig = base64_encode(rsa_sign($signed_text,$uprvkey,'sha256')); + else + $authorsig = ''; + + q("insert into sign (`iid`,`signed_text`,`signature`,`signer`) values (%d,'%s','%s','%s') ", + intval($post_id), + dbesc($signed_text), + dbesc(base64_encode($authorsig)), + dbesc($diaspora_handle) + ); + + return; +} diff --git a/mod/like.php b/mod/like.php index 942a04fe7..1176c3110 100755 --- a/mod/like.php +++ b/mod/like.php @@ -37,7 +37,7 @@ function like_content(&$a) { logger('like: verb ' . $verb . ' item ' . $item_id); - $r = q("SELECT * FROM `item` WHERE ( `id` = '%s' OR `uri` = '%s') AND `id` = `parent` LIMIT 1", + $r = q("SELECT * FROM `item` WHERE `id` = '%s' OR `uri` = '%s' LIMIT 1", dbesc($item_id), dbesc($item_id) ); @@ -121,57 +121,16 @@ function like_content(&$a) { intval($like_item['id']) ); - // Clean up the `sign` table + + // Clean up the Diaspora signatures for this like + // Go ahead and do it even if Diaspora support is disabled. We still want to clean up + // if it had been enabled in the past $r = q("DELETE FROM `sign` WHERE `iid` = %d", intval($like_item['id']) ); // Save the author information for the unlike in case we need to relay to Diaspora - // Note that we can only create a signature for a user of the local server. We don't have - // a key for remote users. That is ok, because if a remote user is "unlike"ing a post, it - // means we are the relay, and for relayable_retractions, Diaspora - // only checks the parent_author_signature if it doesn't have to relay further - // - // If $item['resource-id'] exists, it means the item is a photo. Diaspora doesn't support - // likes on photos, so don't bother. - - if(($activity === ACTIVITY_LIKE) && (! $item['resource-id'])) { - $signed_text = $like_item['guid'] . ';' . 'Like'; - - if( $contact['network'] === NETWORK_DIASPORA) - $diaspora_handle = $contact['addr']; - else { // Only works for NETWORK_DFRN - $contact_baseurl_start = strpos($contact['url'],'://') + 3; - $contact_baseurl_length = strpos($contact['url'],'/profile') - $contact_baseurl_start; - $contact_baseurl = substr($contact['url'], $contact_baseurl_start, $contact_baseurl_length); - $diaspora_handle = $contact['nick'] . '@' . $contact_baseurl; - - // Get contact's private key if he's a user of the local Friendica server - $r = q("SELECT `contact`.`uid` FROM `contact` WHERE `url` = '%s' AND `self` = 1 LIMIT 1", - dbesc($contact['url']) - ); - - if( $r) { - $contact_uid = $r['uid']; - $r = q("SELECT prvkey FROM user WHERE uid = %d LIMIT 1", - intval($contact_uid) - ); - - if( $r) - $authorsig = base64_encode(rsa_sign($signed_text,$r['prvkey'],'sha256')); - } - } - - if(! isset($authorsig)) - $authorsig = ''; - - q("insert into sign (`retract_iid`,`signed_text`,`signature`,`signer`) values (%d,'%s','%s','%s') ", - intval($like_item['id']), - dbesc($signed_text), - dbesc($authorsig), - dbesc($diaspora_handle) - ); - } + store_diaspora_like_retract_sig($activity, $item, $like_item, $contact); // proc_run('php',"include/notifier.php","like","$post_id"); // $post_id isn't defined here! @@ -217,6 +176,7 @@ EOT; $arr['gravity'] = GRAVITY_LIKE; $arr['parent'] = $item['id']; $arr['parent-uri'] = $item['uri']; + $arr['thr-parent'] = $item['uri']; $arr['owner-name'] = $remote_owner['name']; $arr['owner-link'] = $remote_owner['url']; $arr['owner-avatar'] = $remote_owner['thumb']; @@ -251,35 +211,118 @@ EOT; // Save the author information for the like in case we need to relay to Diaspora + store_diaspora_like_sig($activity, $post_type, $contact, $post_id); + + + $arr['id'] = $post_id; + + call_hooks('post_local_end', $arr); + + proc_run('php',"include/notifier.php","like","$post_id"); + + killme(); +// return; // NOTREACHED +} + + +function store_diaspora_like_retract_sig($activity, $item, $like_item, $contact) { // Note that we can only create a signature for a user of the local server. We don't have // a key for remote users. That is ok, because if a remote user is "unlike"ing a post, it // means we are the relay, and for relayable_retractions, Diaspora // only checks the parent_author_signature if it doesn't have to relay further + // + // If $item['resource-id'] exists, it means the item is a photo. Diaspora doesn't support + // likes on photos, so don't bother. - if(($activity === ACTIVITY_LIKE) && ($post_type === t('status'))) { - if( $contact['network'] === NETWORK_DIASPORA) - $diaspora_handle = $contact['addr']; - else { // Only works for NETWORK_DFRN - $contact_baseurl_start = strpos($contact['url'],'://') + 3; - $contact_baseurl_length = strpos($contact['url'],'/profile') - $contact_baseurl_start; - $contact_baseurl = substr($contact['url'], $contact_baseurl_start, $contact_baseurl_length); - $diaspora_handle = $contact['nick'] . '@' . $contact_baseurl; - - // Get contact's private key if he's a user of the local Friendica server - $r = q("SELECT `contact`.`uid` FROM `contact` WHERE `url` = '%s' AND `self` = 1 LIMIT 1", - dbesc($contact['url']) + $enabled = intval(get_config('system','diaspora_enabled')); + if(! $enabled) { + logger('mod_like: diaspora support disabled, not storing like retraction signature', LOGGER_DEBUG); + return; + } + + logger('mod_like: storing diaspora like retraction signature'); + + if(($activity === ACTIVITY_LIKE) && (! $item['resource-id'])) { + $signed_text = $like_item['guid'] . ';' . 'Like'; + +// if( $contact['network'] === NETWORK_DIASPORA) +// $diaspora_handle = $contact['addr']; +// else { + // Only works for NETWORK_DFRN + $contact_baseurl_start = strpos($contact['url'],'://') + 3; + $contact_baseurl_length = strpos($contact['url'],'/profile') - $contact_baseurl_start; + $contact_baseurl = substr($contact['url'], $contact_baseurl_start, $contact_baseurl_length); + $diaspora_handle = $contact['nick'] . '@' . $contact_baseurl; + + // Get contact's private key if he's a user of the local Friendica server + $r = q("SELECT `contact`.`uid` FROM `contact` WHERE `url` = '%s' AND `self` = 1 LIMIT 1", + dbesc($contact['url']) + ); + + if( $r) { + $contact_uid = $r['uid']; + $r = q("SELECT prvkey FROM user WHERE uid = %d LIMIT 1", + intval($contact_uid) ); - if( $r) { - $contact_uid = $r['uid']; - $r = q("SELECT prvkey FROM user WHERE uid = %d LIMIT 1", - intval($contact_uid) - ); + if( $r) + $authorsig = base64_encode(rsa_sign($signed_text,$r['prvkey'],'sha256')); + } +// } - if( $r) - $contact_uprvkey = $r['prvkey']; - } + if(! isset($authorsig)) + $authorsig = ''; + + q("insert into sign (`retract_iid`,`signed_text`,`signature`,`signer`) values (%d,'%s','%s','%s') ", + intval($like_item['id']), + dbesc($signed_text), + dbesc($authorsig), + dbesc($diaspora_handle) + ); + } + + return; +} + +function store_diaspora_like_sig($activity, $post_type, $contact, $post_id) { + // Note that we can only create a signature for a user of the local server. We don't have + // a key for remote users. That is ok, because if a remote user is "unlike"ing a post, it + // means we are the relay, and for relayable_retractions, Diaspora + // only checks the parent_author_signature if it doesn't have to relay further + + $enabled = intval(get_config('system','diaspora_enabled')); + if(! $enabled) { + logger('mod_like: diaspora support disabled, not storing like signature', LOGGER_DEBUG); + return; + } + + logger('mod_like: storing diaspora like signature'); + + if(($activity === ACTIVITY_LIKE) && ($post_type === t('status'))) { +// if( $contact['network'] === NETWORK_DIASPORA) +// $diaspora_handle = $contact['addr']; +// else { + // Only works for NETWORK_DFRN + $contact_baseurl_start = strpos($contact['url'],'://') + 3; + $contact_baseurl_length = strpos($contact['url'],'/profile') - $contact_baseurl_start; + $contact_baseurl = substr($contact['url'], $contact_baseurl_start, $contact_baseurl_length); + $diaspora_handle = $contact['nick'] . '@' . $contact_baseurl; + + // Get contact's private key if he's a user of the local Friendica server + $r = q("SELECT `contact`.`uid` FROM `contact` WHERE `url` = '%s' AND `self` = 1 LIMIT 1", + dbesc($contact['url']) + ); + + if( $r) { + $contact_uid = $r['uid']; + $r = q("SELECT prvkey FROM user WHERE uid = %d LIMIT 1", + intval($contact_uid) + ); + + if( $r) + $contact_uprvkey = $r['prvkey']; } +// } $r = q("SELECT guid, parent FROM `item` WHERE id = %d LIMIT 1", intval($post_id) @@ -307,13 +350,5 @@ EOT; } } - - $arr['id'] = $post_id; - - call_hooks('post_local_end', $arr); - - proc_run('php',"include/notifier.php","like","$post_id"); - - killme(); -// return; // NOTREACHED + return; } diff --git a/mod/lockview.php b/mod/lockview.php index 9e64e2608..a832629f1 100644 --- a/mod/lockview.php +++ b/mod/lockview.php @@ -33,7 +33,7 @@ function lockview_content(&$a) { $deny_users = expand_acl($item['deny_cid']); $deny_groups = expand_acl($item['deny_gid']); - if(($item['private']) && (! strlen($item['allow_cid'])) && (! strlen($item['allow_gid'])) + if(($item['private'] == 1) && (! strlen($item['allow_cid'])) && (! strlen($item['allow_gid'])) && (! strlen($item['deny_cid'])) && (! strlen($item['deny_gid']))) { echo t('Remote privacy information not available.') . '<br />'; diff --git a/mod/message.php b/mod/message.php index 519634be5..80d2c6d99 100644 --- a/mod/message.php +++ b/mod/message.php @@ -224,6 +224,7 @@ function message_content(&$a) { // list messages $o .= $header; + $r = q("SELECT count(*) AS `total` FROM `mail` WHERE `mail`.`uid` = %d GROUP BY `parent-uri` ORDER BY `created` DESC", @@ -232,7 +233,7 @@ function message_content(&$a) { ); if(count($r)) $a->set_pager_total($r[0]['total']); - + $r = q("SELECT max(`mail`.`created`) AS `mailcreated`, min(`mail`.`seen`) AS `mailseen`, `mail`.* , `contact`.`name`, `contact`.`url`, `contact`.`thumb` , `contact`.`network`, count( * ) as count @@ -243,6 +244,7 @@ function message_content(&$a) { intval($a->pager['start']), intval($a->pager['itemspage']) ); + if(! count($r)) { info( t('No messages.') . EOL); return $o; diff --git a/mod/parse_url.php b/mod/parse_url.php index cdf2223a8..a38f7e270 100644 --- a/mod/parse_url.php +++ b/mod/parse_url.php @@ -215,10 +215,10 @@ function parse_url_content(&$a) { $i = fetch_url($image); if($i) { + require_once('include/Photo.php'); // guess mimetype from headers or filename $type = guess_image_type($image,true); - - require_once('include/Photo.php'); + $ph = new Photo($i, $type); if($ph->is_valid()) { if($ph->getWidth() > 300 || $ph->getHeight() > 300) { diff --git a/mod/photos.php b/mod/photos.php index d96bc135e..624f0bdca 100644 --- a/mod/photos.php +++ b/mod/photos.php @@ -38,8 +38,10 @@ function photos_init(&$a) { $o .= '<div class="fn">' . $a->data['user']['username'] . '</div>'; $o .= '<div id="profile-photo-wrapper"><img class="photo" style="width: 175px; height: 175px;" src="' . $a->get_cached_avatar_image($a->get_baseurl() . '/photo/profile/' . $a->data['user']['uid'] . '.jpg') . '" alt="' . $a->data['user']['username'] . '" /></div>'; $o .= '</div>'; - - if(! intval($a->data['user']['hidewall'])) { + + $albums_visible = ((intval($a->data['user']['hidewall']) && (! local_user()) && (! remote_user())) ? false : true); + + if($albums_visible) { $o .= '<div id="side-bar-photos-albums" class="widget">'; $o .= '<h3>' . '<a href="' . $a->get_baseurl() . '/photos/' . $a->data['user']['nickname'] . '">' . t('Photo Albums') . '</a></h3>'; @@ -709,6 +711,24 @@ function photos_post(&$a) { logger('mod/photos.php: photos_post(): loading the contents of ' . $src , LOGGER_DEBUG); $imagedata = @file_get_contents($src); + + + + $r = q("select sum(octet_length(data)) as total from photo where uid = %d and scale = 0 and album != 'Contact Photos' ", + intval($a->data['user']['uid']) + ); + + $limit = service_class_fetch($a->data['user']['uid'],'photo_upload_limit'); + + if(($limit !== false) && (($r[0]['total'] + strlen($imagedata)) > $limit)) { + notice( upgrade_message() . EOL ); + @unlink($src); + $foo = 0; + call_hooks('photo_post_end',$foo); + killme(); + } + + $ph = new Photo($imagedata, $type); if(! $ph->is_valid()) { @@ -723,6 +743,12 @@ function photos_post(&$a) { $ph->orient($src); @unlink($src); + $max_length = get_config('system','max_image_length'); + if(! $max_length) + $max_length = MAX_IMAGE_LENGTH; + if($max_length > 0) + $ph->scaleImage($max_length); + $width = $ph->getWidth(); $height = $ph->getHeight(); @@ -966,12 +992,25 @@ function photos_content(&$a) { <input type="submit" name="submit" value="' . t('Submit') . '" id="photos-upload-submit" /> </div>'; - + $r = q("select sum(octet_length(data)) as total from photo where uid = %d and scale = 0 and album != 'Contact Photos' ", + intval($a->data['user']['uid']) + ); + + + $limit = service_class_fetch($a->data['user']['uid'],'photo_upload_limit'); + if($limit !== false) { + $usage_message = sprintf( t("You have used %1$.2f Mbytes of %2$.2f Mbytes photo storage."), $r[0]['total'] / 1024000, $limit / 1024000 ); + } + else { + $usage_message = sprintf( t('You have used %1$.2f Mbytes of photo storage.'), $r[0]['total'] / 1024000 ); + } + $tpl = get_markup_template('photos_upload.tpl'); $o .= replace_macros($tpl,array( '$pagename' => t('Upload Photos'), '$sessid' => session_id(), + '$usage' => $usage_message, '$nickname' => $a->data['user']['nickname'], '$newalbum' => t('New album name: '), '$existalbumtext' => t('or existing album name: '), diff --git a/mod/profiles.php b/mod/profiles.php index a9da5454c..4df8a5af7 100644 --- a/mod/profiles.php +++ b/mod/profiles.php @@ -130,6 +130,9 @@ function profiles_post(&$a) { $politic = notags(trim($_POST['politic'])); $religion = notags(trim($_POST['religion'])); + $likes = fix_mce_lf(escape_tags(trim($_POST['likes']))); + $dislikes = fix_mce_lf(escape_tags(trim($_POST['dislikes']))); + $about = fix_mce_lf(escape_tags(trim($_POST['about']))); $interest = fix_mce_lf(escape_tags(trim($_POST['interest']))); $contact = fix_mce_lf(escape_tags(trim($_POST['contact']))); @@ -155,7 +158,15 @@ function profiles_post(&$a) { if($withchanged) { $changes[] = '[color=#ff0000]♥[/color] ' . t('Romantic Partner'); $value = strip_tags($with); - } + } + if($likes != $orig[0]['likes']) { + $changes[] = t('Likes'); + $value = $likes; + } + if($dislikes != $orig[0]['dislikes']) { + $changes[] = t('Dislikes'); + $value = $dislikes; + } if($work != $orig[0]['work']) { $changes[] = t('Work/Employment'); } @@ -222,6 +233,8 @@ function profiles_post(&$a) { `religion` = '%s', `pub_keywords` = '%s', `prv_keywords` = '%s', + `likes` = '%s', + `dislikes` = '%s', `about` = '%s', `interest` = '%s', `contact` = '%s', @@ -254,6 +267,8 @@ function profiles_post(&$a) { dbesc($religion), dbesc($pub_keywords), dbesc($prv_keywords), + dbesc($likes), + dbesc($dislikes), dbesc($about), dbesc($interest), dbesc($contact), @@ -577,6 +592,8 @@ function profiles_content(&$a) { '$lbl_religion' => t('Religious Views:'), '$lbl_pubkey' => t('Public Keywords:'), '$lbl_prvkey' => t('Private Keywords:'), + '$lbl_likes' => t('Likes:'), + '$lbl_dislikes' => t('Dislikes:'), '$lbl_ex2' => t('Example: fishing photography software'), '$lbl_pubdsc' => t("\x28Used for suggesting potential friends, can be seen by others\x29"), '$lbl_prvdsc' => t("\x28Used for searching profiles, never shown to others\x29"), @@ -617,6 +634,8 @@ function profiles_content(&$a) { '$religion' => $r[0]['religion'], '$pub_keywords' => $r[0]['pub_keywords'], '$prv_keywords' => $r[0]['prv_keywords'], + '$likes' => $r[0]['likes'], + '$dislikes' => $r[0]['dislikes'], '$music' => $r[0]['music'], '$book' => $r[0]['book'], '$tv' => $r[0]['tv'], diff --git a/mod/settings.php b/mod/settings.php index 92593d7a8..b1c3cf7d4 100644 --- a/mod/settings.php +++ b/mod/settings.php @@ -677,6 +677,14 @@ function settings_content(&$a) { $tpl = get_markup_template("settings_connectors.tpl"); + + if(! service_class_allows(local_user(),'email_connect')) { + $mail_disabled_message = upgrade_bool_message(); + } + else { + $mail_disabled_message = (($mail_disabled) ? t('Email access is disabled on this site.') : ''); + } + $o .= replace_macros($tpl, array( '$form_security_token' => get_form_security_token("settings_connectors"), @@ -688,7 +696,7 @@ function settings_content(&$a) { '$h_imap' => t('Email/Mailbox Setup'), '$imap_desc' => t("If you wish to communicate with email contacts using this service \x28optional\x29, please specify how to connect to your mailbox."), '$imap_lastcheck' => array('imap_lastcheck', t('Last successful email check:'), $mail_chk,''), - '$mail_disabled' => (($mail_disabled) ? t('Email access is disabled on this site.') : ''), + '$mail_disabled' => $mail_disabled_message, '$mail_server' => array('mail_server', t('IMAP server name:'), $mail_server, ''), '$mail_port' => array('mail_port', t('IMAP port:'), $mail_port, ''), '$mail_ssl' => array('mail_ssl', t('Security:'), strtoupper($mail_ssl), '', array( 'notls'=>t('None'), 'TLS'=>'TLS', 'SSL'=>'SSL')), @@ -921,18 +929,12 @@ function settings_content(&$a) { )); - - - $invisible = (((! $profile['publish']) && (! $profile['net-publish'])) ? true : false); if($invisible) info( t('Profile is <strong>not published</strong>.') . EOL ); - - - $subdir = ((strlen($a->get_path())) ? '<br />' . t('or') . ' ' . $a->get_baseurl(true) . '/profile/' . $nickname : ''); @@ -1029,17 +1031,6 @@ function settings_content(&$a) { '$h_descadvn' => t('Change the behaviour of this account for special situations'), '$pagetype' => $pagetype, - - - - - - - - - - - )); call_hooks('settings_form',$o); diff --git a/mod/share.php b/mod/share.php index c7525113e..761220ad7 100644 --- a/mod/share.php +++ b/mod/share.php @@ -8,26 +8,25 @@ function share_init(&$a) { if((! $post_id) || (! local_user())) killme(); - $r = q("SELECT item.*, contact.network FROM `item` left join contact on `item`.`contact-id` = `contact`.`id` WHERE `item`.`id` = %d LIMIT 1", - intval($post_id) + $r = q("SELECT item.*, contact.network FROM `item` + left join contact on `item`.`contact-id` = `contact`.`id` + WHERE `item`.`id` = %d AND `item`.`uid` = %d LIMIT 1", + + intval($post_id), + intval(local_user()) ); - if(! count($r) || ($r[0]['private'] && ($r[0]['network'] != NETWORK_FEED))) + if(! count($r) || ($r[0]['private'] == 1)) killme(); $o = ''; -// if(local_user() && intval(get_pconfig(local_user(),'system','plaintext'))) { - $o .= "\xE2\x99\xb2" . ' [url=' . $r[0]['author-link'] . ']' . $r[0]['author-name'] . '[/url]' . "\n"; - if($r[0]['title']) - $o .= '[b]' . $r[0]['title'] . '[/b]' . "\n"; - $o .= $r[0]['body'] . "\n"; -// } -// else { -// $o .= '♲ <a href="' . $r[0]['author-link'] . '">' . $r[0]['author-name'] . '</a><br />'; -// if($r[0]['title']) -// $o .= '<strong>' . $r[0]['title'] . '</strong><br />'; -// $o .= $r[0]['body'] . "\n"; -// } + $o .= "\xE2\x99\xb2" . ' [url=' . $r[0]['author-link'] . ']' . $r[0]['author-name'] . '[/url]' . "\n"; + if($r[0]['title']) + $o .= '[b]' . $r[0]['title'] . '[/b]' . "\n"; + $o .= $r[0]['body'] . "\n" ; + + $o .= (($r[0]['plink']) ? '[url=' . $r[0]['plink'] . ']' . t('link') . '[/url]' . "\n" : ''); + echo $o; killme(); } diff --git a/mod/wall_attach.php b/mod/wall_attach.php index 03d9f5105..f179b3ca5 100644 --- a/mod/wall_attach.php +++ b/mod/wall_attach.php @@ -60,6 +60,19 @@ function wall_attach_post(&$a) { return; } + $r = q("select sum(octet_length(data)) as total from attach where uid = %d ", + intval($page_owner_uid) + ); + + $limit = service_class_fetch($page_owner_uid,'attach_upload_limit'); + + if(($limit !== false) && (($r[0]['total'] + strlen($imagedata)) > $limit)) { + echo upgrade_message(true) . EOL ; + @unlink($src); + killme(); + } + + $filedata = @file_get_contents($src); $mimetype = z_mime_content_type($filename); $hash = random_string(); diff --git a/mod/wall_upload.php b/mod/wall_upload.php index 4b81f8d1c..5990f2834 100644 --- a/mod/wall_upload.php +++ b/mod/wall_upload.php @@ -79,6 +79,19 @@ function wall_upload_post(&$a) { killme(); } + $r = q("select sum(octet_length(data)) as total from photo where uid = %d and scale = 0 and album != 'Contact Photos' ", + intval($page_owner_uid) + ); + + $limit = service_class_fetch($page_owner_uid,'photo_upload_limit'); + + if(($limit !== false) && (($r[0]['total'] + strlen($imagedata)) > $limit)) { + echo upgrade_message(true) . EOL ; + @unlink($src); + killme(); + } + + $imagedata = @file_get_contents($src); $ph = new Photo($imagedata, $filetype); |