function search_content(&$a, $update = 0, $load = false) { if (get_config('system', 'block_public') || get_config('system', 'block_public_search')) { if (!local_channel() && !remote_channel()) { notice(t('Public access denied.') . EOL); return; } } if ($load) { $_SESSION['loadtime'] = datetime_convert(); } nav_set_selected('search'); require_once "include/bbcode.php"; require_once 'include/security.php'; require_once 'include/conversation.php'; require_once 'include/items.php'; $format = $_REQUEST['format'] ? $_REQUEST['format'] : ''; if ($format !== '') { $update = $load = 1; } $observer = $a->get_observer(); $observer_hash = $observer ? $observer['xchan_hash'] : ''; $o = '<div id="live-search"></div>' . "\r\n"; $o .= '<h3>' . t('Search') . '</h3>'; if (x($a->data, 'search')) { $search = trim($a->data['search']); } else { $search = x($_GET, 'search') ? trim(rawurldecode($_GET['search'])) : ''; } $tag = false; if (x($_GET, 'tag')) { $tag = true; $search = x($_GET, 'tag') ? trim(rawurldecode($_GET['tag'])) : ''; } if (!local_channel() || !feature_enabled(local_channel(), 'savedsearch')) { $o .= search($search, 'search-box', '/search', local_channel() ? true : false); } if (strpos($search, '#') === 0) { $tag = true; $search = substr($search, 1); } if (strpos($search, '@') === 0) { $search = substr($search, 1); goaway(z_root() . '/directory' . '?f=1&search=' . $search); } // look for a naked webbie if (strpos($search, '@') !== false) { goaway(z_root() . '/directory' . '?f=1&search=' . $search); } if (!$search) { return $o; } if ($tag) { $sql_extra = sprintf(" AND `item`.`id` IN (select `oid` from term where otype = %d and type = %d and term = '%s') ", intval(TERM_OBJ_POST), intval(TERM_HASHTAG), dbesc(protect_sprintf($search))); } else { $regstr = db_getfunc('REGEXP'); $sql_extra = sprintf(" AND `item`.`body` {$regstr} '%s' ", dbesc(protect_sprintf(preg_quote($search)))); } // Here is the way permissions work in the search module... // Only public posts can be shown // OR your own posts if you are a logged in member // No items will be shown if the member has a blocked profile wall. if (!$update && !$load) { // This is ugly, but we can't pass the profile_uid through the session to the ajax updater, // because browser prefetching might change it on us. We have to deliver it with the page. $o .= '<div id="live-search"></div>' . "\r\n"; $o .= "<script> var profile_uid = " . (intval(local_channel()) ? local_channel() : -1) . "; var netargs = '?f='; var profile_page = " . $a->pager['page'] . "; </script>\r\n"; $a->page['htmlhead'] .= replace_macros(get_markup_template("build_query.tpl"), array('$baseurl' => z_root(), '$pgtype' => 'search', '$uid' => $a->profile['profile_uid'] ? $a->profile['profile_uid'] : '0', '$gid' => '0', '$cid' => '0', '$cmin' => '0', '$cmax' => '0', '$star' => '0', '$liked' => '0', '$conv' => '0', '$spam' => '0', '$fh' => '0', '$nouveau' => '0', '$wall' => '0', '$list' => x($_REQUEST, 'list') ? intval($_REQUEST['list']) : 0, '$page' => $a->pager['page'] != 1 ? $a->pager['page'] : 1, '$search' => ($tag ? urlencode('#') : '') . $search, '$order' => '', '$file' => '', '$cats' => '', '$tags' => '', '$mid' => '', '$verb' => '', '$dend' => '', '$dbegin' => '')); } $pub_sql = public_permissions_sql($observer_hash); require_once 'include/identity.php'; $sys = get_sys_channel(); if ($update && $load) { $itemspage = get_pconfig(local_channel(), 'system', 'itemspage'); $a->set_pager_itemspage(intval($itemspage) ? $itemspage : 20); $pager_sql = sprintf(" LIMIT %d OFFSET %d ", intval($a->pager['itemspage']), intval($a->pager['start'])); // in case somebody turned off public access to sys channel content with permissions if (!perm_is_allowed($sys['channel_id'], $observer_hash, 'view_stream')) { $sys['xchan_hash'] .= 'disabled'; } if ($load) { $r = null; if (ACTIVE_DBTYPE == DBTYPE_POSTGRES) { $prefix = 'distinct on (created, mid)'; $suffix = 'ORDER BY created DESC, mid'; } else { $prefix = 'distinct'; $suffix = 'group by mid ORDER BY created DESC'; } if (local_channel()) { $r = q("SELECT {$prefix} mid, item.id as item_id, item.* from item\n\t\t\t\t\tWHERE item_restrict = 0\n\t\t\t\t\tAND ((( `item`.`allow_cid` = '' AND `item`.`allow_gid` = '' AND `item`.`deny_cid` = '' AND `item`.`deny_gid` = '' AND item_private = 0 ) \n\t\t\t\t\tOR ( `item`.`uid` = %d )) OR item.owner_xchan = '%s' )\n\t\t\t\t\t{$sql_extra}\n\t\t\t\t\t{$suffix} {$pager_sql} ", intval(local_channel()), dbesc($sys['xchan_hash'])); } if ($r === null) { $r = q("SELECT {$prefix} mid, item.id as item_id, item.* from item\n\t\t\t\t\tWHERE item_restrict = 0\n\t\t\t\t\tAND (((( `item`.`allow_cid` = '' AND `item`.`allow_gid` = '' AND `item`.`deny_cid` = ''\n\t\t\t\t\tAND `item`.`deny_gid` = '' AND item_private = 0 )\n\t\t\t\t\tand owner_xchan in ( " . stream_perms_xchans($observer ? PERMS_NETWORK | PERMS_PUBLIC : PERMS_PUBLIC) . " ))\n\t\t\t\t\t\t{$pub_sql} ) OR owner_xchan = '%s')\n\t\t\t\t\t{$sql_extra} \n\t\t\t\t\t{$suffix} {$pager_sql}", dbesc($sys['xchan_hash'])); } } else { $r = array(); } } if ($r) { xchan_query($r); $items = fetch_post_tags($r, true); } else { $items = array(); } if ($format == 'json') { $result = array(); require_once 'include/conversation.php'; foreach ($items as $item) { $item['html'] = bbcode($item['body']); $x = encode_item($item); $x['html'] = prepare_text($item['body'], $item['mimetype']); $result[] = $x; } json_return_and_die(array('success' => true, 'messages' => $result)); } if ($tag) { $o .= '<h2>Items tagged with: ' . htmlspecialchars($search, ENT_COMPAT, 'UTF-8') . '</h2>'; } else { $o .= '<h2>Search results for: ' . htmlspecialchars($search, ENT_COMPAT, 'UTF-8') . '</h2>'; } $o .= conversation($a, $items, 'search', $update, 'client'); return $o; }
function get($update = 0, $load = false) { $checkjs = new \Zotlabs\Web\CheckJS(1); if ($load) { $_SESSION['loadtime'] = datetime_convert(); } if (observer_prohibited()) { notice(t('Public access denied.') . EOL); return; } require_once "include/bbcode.php"; require_once 'include/security.php'; require_once 'include/conversation.php'; require_once 'include/acl_selectors.php'; require_once 'include/items.php'; \App::$page['htmlhead'] .= replace_macros(get_markup_template('display-head.tpl'), array()); if (argc() > 1 && argv(1) !== 'load') { $item_hash = argv(1); } if ($_REQUEST['mid']) { $item_hash = $_REQUEST['mid']; } if (!$item_hash) { \App::$error = 404; notice(t('Item not found.') . EOL); return; } $observer_is_owner = false; if (local_channel() && !$update) { $channel = \App::get_channel(); $channel_acl = array('allow_cid' => $channel['channel_allow_cid'], 'allow_gid' => $channel['channel_allow_gid'], 'deny_cid' => $channel['channel_deny_cid'], 'deny_gid' => $channel['channel_deny_gid']); $x = array('is_owner' => true, 'allow_location' => intval(get_pconfig($channel['channel_id'], 'system', 'use_browser_location')) ? '1' : '', 'default_location' => $channel['channel_location'], 'nickname' => $channel['channel_address'], 'lockstate' => $group || $cid || $channel['channel_allow_cid'] || $channel['channel_allow_gid'] || $channel['channel_deny_cid'] || $channel['channel_deny_gid'] ? 'lock' : 'unlock', 'acl' => populate_acl($channel_acl), 'permissions' => $channel_acl, 'bang' => '', 'visitor' => true, 'profile_uid' => local_channel(), 'return_path' => 'channel/' . $channel['channel_address'], 'expanded' => true, 'editor_autocomplete' => true, 'bbco_autocomplete' => 'bbcode', 'bbcode' => true); $o = '<div id="jot-popup">'; $o .= status_editor($a, $x); $o .= '</div>'; } // This page can be viewed by anybody so the query could be complicated // First we'll see if there is a copy of the item which is owned by us - if we're logged in locally. // If that fails (or we aren't logged in locally), // query an item in which the observer (if logged in remotely) has cid or gid rights // and if that fails, look for a copy of the post that has no privacy restrictions. // If we find the post, but we don't find a copy that we're allowed to look at, this fact needs to be reported. // find a copy of the item somewhere $target_item = null; $r = q("select id, uid, mid, parent_mid, item_type, item_deleted from item where mid like '%s' limit 1", dbesc($item_hash . '%')); if ($r) { $target_item = $r[0]; } $r = null; if ($target_item['item_type'] == ITEM_TYPE_WEBPAGE) { $x = q("select * from channel where channel_id = %d limit 1", intval($target_item['uid'])); $y = q("select * from iconfig left join item on iconfig.iid = item.id \n\t\t\t\twhere item.uid = %d and iconfig.cat = 'system' and iconfig.k = 'WEBPAGE' and item.id = %d limit 1", intval($target_item['uid']), intval($target_item['id'])); if ($x && $y) { goaway(z_root() . '/page/' . $x[0]['channel_address'] . '/' . $y[0]['v']); } else { notice(t('Page not found.') . EOL); return ''; } } $simple_update = $update ? " AND item_unseen = 1 " : ''; if ($update && $_SESSION['loadtime']) { $simple_update = " AND (( item_unseen = 1 AND item.changed > '" . datetime_convert('UTC', 'UTC', $_SESSION['loadtime']) . "' ) OR item.changed > '" . datetime_convert('UTC', 'UTC', $_SESSION['loadtime']) . "' ) "; } if ($load) { $simple_update = ''; } if (!$update && !$load) { $o .= '<div id="live-display"></div>' . "\r\n"; $o .= "<script> var profile_uid = " . (intval(local_channel()) ? local_channel() : -1) . "; var netargs = '?f='; var profile_page = " . \App::$pager['page'] . "; </script>\r\n"; \App::$page['htmlhead'] .= replace_macros(get_markup_template("build_query.tpl"), array('$baseurl' => z_root(), '$pgtype' => 'display', '$uid' => '0', '$gid' => '0', '$cid' => '0', '$cmin' => '0', '$cmax' => '99', '$star' => '0', '$liked' => '0', '$conv' => '0', '$spam' => '0', '$fh' => '0', '$nouveau' => '0', '$wall' => '0', '$page' => \App::$pager['page'] != 1 ? \App::$pager['page'] : 1, '$list' => x($_REQUEST, 'list') ? intval($_REQUEST['list']) : 0, '$search' => '', '$order' => '', '$file' => '', '$cats' => '', '$tags' => '', '$dend' => '', '$dbegin' => '', '$verb' => '', '$mid' => $item_hash)); } $observer_hash = get_observer_hash(); $item_normal = item_normal(); $sql_extra = public_permissions_sql($observer_hash); if ($update && $load || $checkjs->disabled()) { $updateable = false; $pager_sql = sprintf(" LIMIT %d OFFSET %d ", intval(\App::$pager['itemspage']), intval(\App::$pager['start'])); if ($load || $checkjs->disabled()) { $r = null; require_once 'include/channel.php'; $sys = get_sys_channel(); $sysid = $sys['channel_id']; if (local_channel()) { $r = q("SELECT * from item\n\t\t\t\t\t\tWHERE uid = %d\n\t\t\t\t\t\tand mid = '%s'\n\t\t\t\t\t\t{$item_normal}\n\t\t\t\t\t\tlimit 1", intval(local_channel()), dbesc($target_item['parent_mid'])); if ($r) { $updateable = true; } } if ($r === null) { // in case somebody turned off public access to sys channel content using permissions // make that content unsearchable by ensuring the owner_xchan can't match if (!perm_is_allowed($sysid, $observer_hash, 'view_stream')) { $sysid = 0; } $r = q("SELECT * from item\n\t\t\t\t\t\tWHERE mid = '%s'\n\t\t\t\t\t\tAND (((( `item`.`allow_cid` = '' AND `item`.`allow_gid` = '' AND `item`.`deny_cid` = '' \n\t\t\t\t\t\tAND `item`.`deny_gid` = '' AND item_private = 0 ) \n\t\t\t\t\t\tand owner_xchan in ( " . stream_perms_xchans($observer_hash ? PERMS_NETWORK | PERMS_PUBLIC : PERMS_PUBLIC) . " ))\n\t\t\t\t\t\tOR uid = %d )\n\t\t\t\t\t\t{$sql_extra} )\n\t\t\t\t\t\t{$item_normal}\n\t\t\t\t\t\tlimit 1", dbesc($target_item['parent_mid']), intval($sysid)); } } } elseif ($update && !$load) { $r = null; require_once 'include/channel.php'; $sys = get_sys_channel(); $sysid = $sys['channel_id']; if (local_channel()) { $r = q("SELECT * from item\n\t\t\t\t\tWHERE uid = %d\n\t\t\t\t\tand mid = '%s'\n\t\t\t\t\t{$item_normal}\n\t\t\t\t\t{$simple_update}\n\t\t\t\t\tlimit 1", intval(local_channel()), dbesc($target_item['parent_mid'])); if ($r) { $updateable = true; } } if ($r === null) { // in case somebody turned off public access to sys channel content using permissions // make that content unsearchable by ensuring the owner_xchan can't match if (!perm_is_allowed($sysid, $observer_hash, 'view_stream')) { $sysid = 0; } $r = q("SELECT * from item\n\t\t\t\t\tWHERE mid = '%s'\n\t\t\t\t\tAND (((( `item`.`allow_cid` = '' AND `item`.`allow_gid` = '' AND `item`.`deny_cid` = '' \n\t\t\t\t\tAND `item`.`deny_gid` = '' AND item_private = 0 ) \n\t\t\t\t\tand owner_xchan in ( " . stream_perms_xchans($observer_hash ? PERMS_NETWORK | PERMS_PUBLIC : PERMS_PUBLIC) . " ))\n\t\t\t\t\tOR uid = %d )\n\t\t\t\t\t{$sql_extra} )\n\t\t\t\t\t{$item_normal}\n\t\t\t\t\t{$simple_update}\n\t\t\t\t\tlimit 1", dbesc($target_item['parent_mid']), intval($sysid)); } $_SESSION['loadtime'] = datetime_convert(); } else { $r = array(); } if ($r) { $parents_str = ids_to_querystr($r, 'id'); if ($parents_str) { $items = q("SELECT `item`.*, `item`.`id` AS `item_id` \n\t\t\t\t\tFROM `item`\n\t\t\t\t\tWHERE parent in ( %s ) {$item_normal} ", dbesc($parents_str)); xchan_query($items); $items = fetch_post_tags($items, true); $items = conv_sort($items, 'created'); } } else { $items = array(); } if ($checkjs->disabled()) { $o .= conversation($a, $items, 'display', $update, 'traditional'); if ($items[0]['title']) { \App::$page['title'] = $items[0]['title'] . " - " . \App::$page['title']; } } else { $o .= conversation($a, $items, 'display', $update, 'client'); } if ($updateable) { $x = q("UPDATE item SET item_unseen = 0 where item_unseen = 1 AND uid = %d and parent = %d ", intval(local_channel()), intval($r[0]['parent'])); } $o .= '<div id="content-complete"></div>'; return $o; /* elseif((! $update) && (! { $r = q("SELECT `id`, item_flags FROM `item` WHERE `id` = '%s' OR `mid` = '%s' LIMIT 1", dbesc($item_hash), dbesc($item_hash) ); if($r) { if(intval($r[0]['item_deleted'])) { notice( t('Item has been removed.') . EOL ); } else { notice( t('Permission denied.') . EOL ); } } else { notice( t('Item not found.') . EOL ); } } */ }
function display_content(&$a, $update = 0, $load = false) { // logger("mod-display: update = $update load = $load"); if (intval(get_config('system', 'block_public')) && !local_user() && !remote_user()) { notice(t('Public access denied.') . EOL); return; } require_once "include/bbcode.php"; require_once 'include/security.php'; require_once 'include/conversation.php'; require_once 'include/acl_selectors.php'; require_once 'include/items.php'; $a->page['htmlhead'] .= replace_macros(get_markup_template('display-head.tpl'), array()); if (argc() > 1 && argv(1) !== 'load') { $item_hash = argv(1); } if ($_REQUEST['mid']) { $item_hash = $_REQUEST['mid']; } if (!$item_hash) { $a->error = 404; notice(t('Item not found.') . EOL); return; } $observer_is_owner = false; if (local_user() && !$update) { $channel = $a->get_channel(); $channel_acl = array('allow_cid' => $channel['channel_allow_cid'], 'allow_gid' => $channel['channel_allow_gid'], 'deny_cid' => $channel['channel_deny_cid'], 'deny_gid' => $channel['channel_deny_gid']); $x = array('is_owner' => true, 'allow_location' => intval(get_pconfig($channel['channel_id'], 'system', 'use_browser_location')) ? '1' : '', 'default_location' => $channel['channel_location'], 'nickname' => $channel['channel_address'], 'lockstate' => $group || $cid || $channel['channel_allow_cid'] || $channel['channel_allow_gid'] || $channel['channel_deny_cid'] || $channel['channel_deny_gid'] ? 'lock' : 'unlock', 'acl' => populate_acl($channel_acl), 'bang' => '', 'visitor' => true, 'profile_uid' => local_user(), 'return_path' => 'channel/' . $channel['channel_address']); $o .= status_editor($a, $x); } // This page can be viewed by anybody so the query could be complicated // First we'll see if there is a copy of the item which is owned by us - if we're logged in locally. // If that fails (or we aren't logged in locally), // query an item in which the observer (if logged in remotely) has cid or gid rights // and if that fails, look for a copy of the post that has no privacy restrictions. // If we find the post, but we don't find a copy that we're allowed to look at, this fact needs to be reported. // find a copy of the item somewhere $target_item = null; $r = q("select id, uid, mid, parent_mid, item_restrict from item where mid like '%s' limit 1", dbesc($item_hash . '%')); if ($r) { $target_item = $r[0]; } if ($target_item['item_restrict'] & ITEM_WEBPAGE) { $x = q("select * from channel where channel_id = %d limit 1", intval($target_item['uid'])); $y = q("select * from item_id where uid = %d and service = 'WEBPAGE' and iid = %d limit 1", intval($target_item['uid']), intval($target_item['id'])); if ($x && $y) { goaway(z_root() . '/page/' . $x[0]['channel_address'] . '/' . $y[0]['sid']); } else { notice(t('Page not found.') . EOL); return ''; } } if (!$update && !$load) { $o .= '<div id="live-display"></div>' . "\r\n"; $o .= "<script> var profile_uid = " . (intval(local_user()) ? local_user() : -1) . "; var netargs = '?f='; var profile_page = " . $a->pager['page'] . "; </script>\r\n"; $a->page['htmlhead'] .= replace_macros(get_markup_template("build_query.tpl"), array('$baseurl' => z_root(), '$pgtype' => 'display', '$uid' => '0', '$gid' => '0', '$cid' => '0', '$cmin' => '0', '$cmax' => '99', '$star' => '0', '$liked' => '0', '$conv' => '0', '$spam' => '0', '$fh' => '0', '$nouveau' => '0', '$wall' => '0', '$page' => $a->pager['page'] != 1 ? $a->pager['page'] : 1, '$list' => x($_REQUEST, 'list') ? intval($_REQUEST['list']) : 0, '$search' => '', '$order' => '', '$file' => '', '$cats' => '', '$dend' => '', '$dbegin' => '', '$mid' => $item_hash)); } $observer_hash = get_observer_hash(); $sql_extra = public_permissions_sql($observer_hash); if ($update && $load || $_COOKIE['jsAvailable'] != 1) { $updateable = false; $pager_sql = sprintf(" LIMIT %d, %d ", intval($a->pager['start']), intval($a->pager['itemspage'])); if ($load || $_COOKIE['jsAvailable'] != 1) { $r = null; require_once 'include/identity.php'; $sys = get_sys_channel(); if (local_user()) { $r = q("SELECT * from item\n\t\t\t\t\tWHERE item_restrict = 0\n\t\t\t\t\tand uid = %d\n\t\t\t\t\tand mid = '%s'\n\t\t\t\t\tlimit 1", intval(local_user()), dbesc($target_item['parent_mid'])); if ($r) { $updateable = true; } } if ($r === null) { // in case somebody turned off public access to sys channel content using permissions // make that content unsearchable by ensuring the owner_xchan can't match if (!perm_is_allowed($sys['channel_id'], $observer_hash, 'view_stream')) { $sys['xchan_hash'] .= 'disabled'; } $r = q("SELECT * from item\n\t\t\t\t\tWHERE item_restrict = 0\n\t\t\t\t\tand mid = '%s'\n\t\t\t\t\tAND (((( `item`.`allow_cid` = '' AND `item`.`allow_gid` = '' AND `item`.`deny_cid` = '' \n\t\t\t\t\tAND `item`.`deny_gid` = '' AND item_private = 0 ) \n\t\t\t\t\tand owner_xchan in ( " . stream_perms_xchans($observer_hash ? PERMS_NETWORK | PERMS_PUBLIC : PERMS_PUBLIC) . " ))\n\t\t\t\t\tOR owner_xchan = '%s')\n\t\t\t\t\t{$sql_extra} )\n\t\t\t\t\tgroup by mid limit 1", dbesc($target_item['parent_mid']), dbesc($sys['xchan_hash'])); } } else { $r = array(); } } if ($r) { $parents_str = ids_to_querystr($r, 'id'); if ($parents_str) { $items = q("SELECT `item`.*, `item`.`id` AS `item_id` \n\t\t\t\tFROM `item`\n\t\t\t\tWHERE item_restrict = 0 and parent in ( %s ) ", dbesc($parents_str)); xchan_query($items); $items = fetch_post_tags($items, true); $items = conv_sort($items, 'created'); } } else { $items = array(); } if ($_COOKIE['jsAvailable'] == 1) { $o .= conversation($a, $items, 'display', $update, 'client'); } else { $o .= conversation($a, $items, 'display', $update, 'traditional'); } if ($updateable) { $x = q("UPDATE item SET item_flags = ( item_flags ^ %d )\n\t\t\tWHERE (item_flags & %d) AND uid = %d and parent = %d ", intval(ITEM_UNSEEN), intval(ITEM_UNSEEN), intval(local_user()), intval($r[0]['parent'])); } $o .= '<div id="content-complete"></div>'; return $o; /* elseif((! $update) && (! { $r = q("SELECT `id`, item_flags FROM `item` WHERE `id` = '%s' OR `mid` = '%s' LIMIT 1", dbesc($item_hash), dbesc($item_hash) ); if($r) { if($r[0]['item_flags'] & ITEM_DELETED) { notice( t('Item has been removed.') . EOL ); } else { notice( t('Permission denied.') . EOL ); } } else { notice( t('Item not found.') . EOL ); } } */ return $o; }