diff options
Diffstat (limited to 'Zotlabs/Module')
38 files changed, 904 insertions, 740 deletions
diff --git a/Zotlabs/Module/Acl.php b/Zotlabs/Module/Acl.php index 1de7a3d02..cf9278f5e 100644 --- a/Zotlabs/Module/Acl.php +++ b/Zotlabs/Module/Acl.php @@ -29,11 +29,11 @@ class Acl extends \Zotlabs\Web\Controller { // logger('mod_acl: ' . print_r($_GET,true),LOGGER_DATA); - $start = (x($_REQUEST,'start') ? $_REQUEST['start'] : 0); - $count = (x($_REQUEST,'count') ? $_REQUEST['count'] : 500); - $search = (x($_REQUEST,'search') ? $_REQUEST['search'] : ''); - $type = (x($_REQUEST,'type') ? $_REQUEST['type'] : ''); - $noforums = (x($_REQUEST,'n') ? $_REQUEST['n'] : false); + $start = (!empty($_REQUEST['start']) ? $_REQUEST['start'] : 0); + $count = (!empty($_REQUEST['count']) ? $_REQUEST['count'] : 500); + $search = (!empty($_REQUEST['search']) ? $_REQUEST['search'] : ''); + $type = (!empty($_REQUEST['type']) ? $_REQUEST['type'] : ''); + $noforums = (!empty($_REQUEST['n']) ? $_REQUEST['n'] : false); // $type = @@ -53,7 +53,7 @@ class Acl extends \Zotlabs\Web\Controller { // List of channels whose connections to also suggest, // e.g. currently viewed channel or channels mentioned in a post - $extra_channels = (x($_REQUEST,'extra_channels') ? $_REQUEST['extra_channels'] : array()); + $extra_channels = (!empty($_REQUEST['extra_channels']) ? $_REQUEST['extra_channels'] : []); // The different autocomplete libraries use different names for the search text // parameter. Internally we'll use $search to represent the search text no matter @@ -416,7 +416,7 @@ class Acl extends \Zotlabs\Web\Controller { } $dirmode = intval(Config::Get('system','directory_mode')); - $search = ((x($_REQUEST,'search')) ? htmlentities($_REQUEST['search'],ENT_COMPAT,'UTF-8',false) : ''); + $search = ((!empty($_REQUEST['search'])) ? htmlentities($_REQUEST['search'], ENT_COMPAT, 'UTF-8', false) : ''); if(! $search || mb_strlen($search) < 2) return array(); @@ -446,7 +446,7 @@ class Acl extends \Zotlabs\Web\Controller { $token = Config::Get('system','realm_token'); - $count = (x($_REQUEST,'count') ? $_REQUEST['count'] : 100); + $count = (!empty($_REQUEST['count']) ? $_REQUEST['count'] : 100); if($url) { $query = $url . '?f=' . (($token) ? '&t=' . urlencode($token) : ''); $query .= '&name=' . urlencode($search) . "&limit=$count" . (($address) ? '&address=' . urlencode(punify($search)) : ''); diff --git a/Zotlabs/Module/Activity.php b/Zotlabs/Module/Activity.php index 133312e28..64da2586b 100644 --- a/Zotlabs/Module/Activity.php +++ b/Zotlabs/Module/Activity.php @@ -23,14 +23,14 @@ class Activity extends Controller { if (! $item_id) http_status_exit(404, 'Not found'); - $portable_id = EMPTY_STR; + $portable_id = null; $item_normal_extra = sprintf(" and not verb in ('Follow', 'Ignore', '%s', '%s') ", dbesc(ACTIVITY_FOLLOW), dbesc(ACTIVITY_UNFOLLOW) ); - $item_normal = " and item.item_hidden = 0 and item.item_type = 0 and item.item_unpublished = 0 and item.item_delayed = 0 and item.item_blocked = 0 $item_normal_extra "; + $item_normal = " and item.item_hidden = 0 and item.item_type = 0 and item.item_unpublished = 0 and item.item_delayed = 0 and item.item_blocked = 0 and item.item_uplink = 0 $item_normal_extra "; $i = null; @@ -166,6 +166,7 @@ class Activity extends Controller { return; } + $portable_id = null; $ob_authorize = false; $item_uid = 0; @@ -191,7 +192,7 @@ class Activity extends Controller { dbesc(ACTIVITY_UNFOLLOW) ); - $item_normal = " and item.item_hidden = 0 and item.item_type = 0 and item.item_unpublished = 0 and item.item_delayed = 0 and item.item_blocked = 0 $item_normal_extra "; + $item_normal = " and item.item_hidden = 0 and item.item_type = 0 and item.item_unpublished = 0 and item.item_delayed = 0 and item.item_blocked = 0 and item.item_uplink = 0 $item_normal_extra "; $sigdata = HTTPSig::verify(EMPTY_STR); if ($sigdata['portable_id'] && $sigdata['header_valid']) { diff --git a/Zotlabs/Module/Admin/Accounts.php b/Zotlabs/Module/Admin/Accounts.php index 6f7cb0311..108231d7d 100644 --- a/Zotlabs/Module/Admin/Accounts.php +++ b/Zotlabs/Module/Admin/Accounts.php @@ -6,133 +6,33 @@ use Zotlabs\Lib\Config; class Accounts { - /** - * @brief Handle POST actions on accounts admin page. - * - * This function is called when on the admin user/account page the form was - * submitted to handle multiple operations at once. If one of the icons next - * to an entry are pressed the function admin_page_accounts() will handle this. - * - */ const MYP = 'ZAR'; // ZAR2x const VERSION = '2.0.0'; - function post() { + /** + * Handle POST actions on accounts admin page. + */ + public function post() { - $pending = ( x($_POST, 'pending') ? $_POST['pending'] : array() ); - $users = ( x($_POST, 'user') ? $_POST['user'] : array() ); - $blocked = ( x($_POST, 'blocked') ? $_POST['blocked'] : array() ); + $pending = x($_POST, 'pending') ? $_POST['pending'] : array(); check_form_security_token_redirectOnErr('/admin/accounts', 'admin_accounts'); - $isajax = is_ajax(); - $rc = 0; - - If (!is_site_admin()) { - if ($isajax) { - killme(); - exit; - } - goaway(z_root() . '/'); - } - - if ($isajax) { - //$debug = print_r($_SESSION[self::MYP],true); - $zarop = (x($_POST['zardo']) && preg_match('/^[ad]{1,1}$/', $_POST['zardo']) ) - ? $_POST['zardo'] : ''; - // zarat arrives with leading underscore _n - $zarat = (x($_POST['zarat']) && preg_match('/^_{1,1}[0-9]{1,6}$/', $_POST['zarat']) ) - ? substr($_POST['zarat'],1) : ''; - $zarse = (x($_POST['zarse']) && preg_match('/^[0-9a-f]{8,8}$/', $_POST['zarse']) ) - ? hex2bin($_POST['zarse']) : ''; - - if ($zarop && $zarat >= 0 && $zarse && $zarse == $_SESSION[self::MYP]['h'][$zarat]) { - - // - if ($zarop == 'd') { - $rd = q("UPDATE register SET reg_vital = 0 WHERE reg_id = %d AND SUBSTR(reg_hash,1,4) = '%s' ", - intval($_SESSION[self::MYP]['i'][$zarat]), - dbesc($_SESSION[self::MYP]['h'][$zarat]) - ); - $rc = '×'; - } - elseif ($zarop == 'a') { - // approval, REGISTER_DENIED by user 0x0040, REGISTER_AGREED by user 0x0020 @Regate - $rd = q("UPDATE register SET reg_flags = (reg_flags & ~ 16), " - . " reg_vital = (CASE (reg_flags & ~ 48) WHEN 0 THEN 0 ELSE 1 END) " - . " WHERE reg_vital = 1 AND reg_id = %d AND SUBSTR(reg_hash,1,4) = '%s' ", - intval($_SESSION[self::MYP]['i'][$zarat]), - dbesc($_SESSION[self::MYP]['h'][$zarat]) - ); - $rc = 0; - $rs = q("SELECT * from register WHERE reg_id = %d ", - intval($_SESSION[self::MYP]['i'][$zarat]) - ); - if ($rs && ($rs[0]['reg_flags'] & ~ 48) == 0) { - // create account - $rc = 'ok'.$rs[0]['reg_id']; - $ac = create_account_from_register($rs[0]); - if ( $ac['success'] ) { - $rc .= '✔'; - - $auto_create = Config::Get('system','auto_channel_create',1); - - if($auto_create) { - $reonar = json_decode($rs[0]['reg_stuff'], true); - // prepare channel creation - if($reonar['chan.name']) - set_aconfig($ac['account']['account_id'], 'register', 'channel_name', $reonar['chan.name']); - - if($reonar['chan.did1']) - set_aconfig($ac['account']['account_id'], 'register', 'channel_address', $reonar['chan.did1']); - - $permissions_role = Config::Get('system','default_permissions_role'); - if($permissions_role) - set_aconfig($ac['account']['account_id'], 'register', 'permissions_role', $permissions_role); - - // create channel - $new_channel = auto_channel_create($ac['account']['account_id']); - - if($new_channel['success']) { - $rc .= ' c,ok' . $new_channel['channel']['channel_id'] . '✔'; - } - else { - $rc .= ' c ×'; - } - } - - - } - } else { - $rc='oh ×'; - } - } - echo json_encode(array('re' => $zarop, 'at' => '_' . $zarat, 'rc' => $rc)); - } + if (is_ajax()) { + $this->handle_ajax_request(); killme(); - exit; } // change to switch structure? // account block/unblock button was submitted if (x($_POST, 'page_accounts_block')) { - for ($i = 0; $i < count($users); $i++) { - // if account is blocked remove blocked bit-flag, otherwise add blocked bit-flag - $op = ($blocked[$i]) ? '& ~' : '| '; - q("UPDATE account SET account_flags = (account_flags $op%d) WHERE account_id = %d", - intval(ACCOUNT_BLOCKED), - intval($users[$i]) - ); - } - notice( sprintf( tt("%s account blocked/unblocked", "%s account blocked/unblocked", count($users)), count($users)) ); + $this->block_unblock_accounts(); } + // account delete button was submitted if (x($_POST, 'page_accounts_delete')) { - foreach ($users as $uid){ - account_remove($uid, true, false); - } - notice( sprintf( tt("%s account deleted", "%s accounts deleted", count($users)), count($users)) ); + $this->delete_accounts(); } // registration approved button was submitted if (x($_POST, 'page_accounts_approve')) { @@ -351,5 +251,143 @@ class Accounts { return $o; } + private function handle_ajax_request(): void { + //$debug = print_r($_SESSION[self::MYP],true); + $zarop = (x($_POST['zardo']) && preg_match('/^[ad]{1,1}$/', $_POST['zardo']) ) + ? $_POST['zardo'] : ''; + // zarat arrives with leading underscore _n + $zarat = (x($_POST['zarat']) && preg_match('/^_{1,1}[0-9]{1,6}$/', $_POST['zarat']) ) + ? substr($_POST['zarat'],1) : ''; + $zarse = (x($_POST['zarse']) && preg_match('/^[0-9a-f]{8,8}$/', $_POST['zarse']) ) + ? hex2bin($_POST['zarse']) : ''; + + if ($zarop && $zarat >= 0 && $zarse && $zarse == $_SESSION[self::MYP]['h'][$zarat]) { + + // + if ($zarop == 'd') { + $rd = q("UPDATE register SET reg_vital = 0 WHERE reg_id = %d AND SUBSTR(reg_hash,1,4) = '%s' ", + intval($_SESSION[self::MYP]['i'][$zarat]), + dbesc($_SESSION[self::MYP]['h'][$zarat]) + ); + $rc = '×'; + } + elseif ($zarop == 'a') { + // approval, REGISTER_DENIED by user 0x0040, REGISTER_AGREED by user 0x0020 @Regate + $rd = q("UPDATE register SET reg_flags = (reg_flags & ~ 16), " + . " reg_vital = (CASE (reg_flags & ~ 48) WHEN 0 THEN 0 ELSE 1 END) " + . " WHERE reg_vital = 1 AND reg_id = %d AND SUBSTR(reg_hash,1,4) = '%s' ", + intval($_SESSION[self::MYP]['i'][$zarat]), + dbesc($_SESSION[self::MYP]['h'][$zarat]) + ); + $rc = 0; + $rs = q("SELECT * from register WHERE reg_id = %d ", + intval($_SESSION[self::MYP]['i'][$zarat]) + ); + if ($rs && ($rs[0]['reg_flags'] & ~ 48) == 0) { + // create account + $rc = 'ok'.$rs[0]['reg_id']; + $ac = create_account_from_register($rs[0]); + if ( $ac['success'] ) { + $rc .= '✔'; + + $auto_create = Config::Get('system','auto_channel_create',1); + + if($auto_create) { + $reonar = json_decode($rs[0]['reg_stuff'], true); + // prepare channel creation + if($reonar['chan.name']) + set_aconfig($ac['account']['account_id'], 'register', 'channel_name', $reonar['chan.name']); + + if($reonar['chan.did1']) + set_aconfig($ac['account']['account_id'], 'register', 'channel_address', $reonar['chan.did1']); + + $permissions_role = Config::Get('system','default_permissions_role'); + if($permissions_role) + set_aconfig($ac['account']['account_id'], 'register', 'permissions_role', $permissions_role); + + // create channel + $new_channel = auto_channel_create($ac['account']['account_id']); + + if($new_channel['success']) { + $rc .= ' c,ok' . $new_channel['channel']['channel_id'] . '✔'; + } + else { + $rc .= ' c ×'; + } + } + + + } + } else { + $rc='oh ×'; + } + } + echo json_encode(array('re' => $zarop, 'at' => '_' . $zarat, 'rc' => $rc)); + } + } + + /** + * Block or unblock accounts given by the `user` and `blocked` POST params. + * + * The post params `user` and `blocked` must be present and arrays of equal + * lengths. The `user` array should contain account id's or the accounts to + * process, and the `blocked` array holds a corresponding boolean value to + * indicate that the account at the same offset in the `user` array is or is + * not blocked. + * + * An account that is _not_ blocked will be blocked, and accounts that _are_ + * blocked will be unblocked. + * + * @SuppressWarnings(PHPMD.ShortVariable) + */ + private function block_unblock_accounts(): void { + if (!isset($_POST['user']) || !isset($_POST['blocked'])) { + return; + } + + $users = $_POST['user']; + $blocked = $_POST['blocked']; + + if (!is_array($users) || !is_array($blocked)) { + return; + } + + foreach($users as $i => $id) { + // if account is blocked remove blocked bit-flag, otherwise add blocked bit-flag + $op = $blocked[$i] ? '& ~' : '| '; + + q("UPDATE account SET account_flags = (account_flags $op%d) WHERE account_id = %d", + intval(ACCOUNT_BLOCKED), + intval($id) + ); + } + + $count = count($users); + $fmt = tt("%s account blocked/unblocked", "%s account blocked/unblocked", $count); + notice(sprintf($fmt, $count)); + } + + /** + * Delete multiple accounts given by the `user` POST param. + */ + private function delete_accounts(): void { + if (!isset($_POST['user'])) { + return; + } + + $users = $_POST['user']; + + if (!is_array($users)) { + return; + } + + foreach ($users as $uid){ + account_remove($uid, true, false); + } + + $count = count($users); + $fmt = tt("%s account deleted", "%s accounts deleted", $count); + notice(sprintf($fmt, $count)); + } } diff --git a/Zotlabs/Module/Attach_edit.php b/Zotlabs/Module/Attach_edit.php index 5880d8f13..4cde1c168 100644 --- a/Zotlabs/Module/Attach_edit.php +++ b/Zotlabs/Module/Attach_edit.php @@ -133,6 +133,11 @@ class Attach_edit extends Controller { } $x = attach_move($channel_id, $resource, $newfolder, (($single) ? $newfilename : '')); + if (!$x['success']) { + notice($x['message'] . EOL); + goaway($return_path); + } + $actions_done .= 'move,'; } diff --git a/Zotlabs/Module/Channel.php b/Zotlabs/Module/Channel.php index f3855b7e8..e35a611d0 100644 --- a/Zotlabs/Module/Channel.php +++ b/Zotlabs/Module/Channel.php @@ -85,7 +85,7 @@ class Channel extends Controller { $headers = [ 'Content-Type' => 'application/x-zot+json', 'Digest' => HTTPSig::generate_digest_header($data), - '(request-target)' => strtolower($_SERVER['REQUEST_METHOD']) . ' ' . $_SERVER['REQUEST_URI'] + 'Date' => datetime_convert('UTC','UTC', 'now', 'D, d M Y H:i:s \\G\\M\\T') ]; $h = HTTPSig::create_sig($headers, $channel['channel_prvkey'], channel_url($channel)); @@ -298,12 +298,15 @@ class Channel extends Controller { $item_normal = item_normal(); $item_normal_update = item_normal_update(); - $sql_extra = item_permissions_sql(App::$profile['profile_uid']); + $sql_extra = ''; + $permission_sql = item_permissions_sql(App::$profile['profile_uid']); - if (feature_enabled(App::$profile['profile_uid'], 'channel_list_mode') && (!$mid)) + $page_mode = 'client'; + + $blog_mode = feature_enabled(App::$profile['profile_uid'], 'channel_list_mode') && !$mid; + if ($blog_mode) { $page_mode = 'list'; - else - $page_mode = 'client'; + } $abook_uids = " and abook.abook_channel = " . intval(App::$profile['profile_uid']) . " "; @@ -334,8 +337,8 @@ class Channel extends Controller { if (($update) && (!$load)) { if ($mid) { - $r = q("SELECT parent AS item_id, uuid from item where $identifier = '%s' and uid = %d $item_normal_update - AND item_wall = 1 $simple_update $sql_extra limit 1", + $r = q("SELECT *, parent AS item_id from item where $identifier = '%s' and uid = %d $item_normal_update + AND item_wall = 1 $simple_update $permission_sql $sql_extra limit 1", dbesc($mid), intval(App::$profile['profile_uid']) ); @@ -346,6 +349,7 @@ class Channel extends Controller { WHERE uid = %d $item_normal_update AND item_wall = 1 $simple_update AND (abook.abook_blocked = 0 or abook.abook_flags is null) + $permission_sql $sql_extra ORDER BY created DESC", intval(App::$profile['profile_uid']) @@ -382,8 +386,8 @@ class Channel extends Controller { if ($noscript_content || $load) { if ($mid) { - $r = q("SELECT parent AS item_id, uuid from item where $identifier = '%s' and uid = %d $item_normal - AND item_wall = 1 $sql_extra limit 1", + $r = q("SELECT *, parent AS item_id from item where $identifier = '%s' and uid = %d $item_normal + AND item_wall = 1 $permission_sql $sql_extra limit 1", dbesc($mid), intval(App::$profile['profile_uid']) ); @@ -392,13 +396,18 @@ class Channel extends Controller { } } else { - $r = q("SELECT DISTINCT item.parent AS item_id, $ordering FROM item - left join abook on ( item.author_xchan = abook.abook_xchan $abook_uids ) - WHERE true and item.uid = %d $item_normal + $r = q("SELECT parent AS item_id, $ordering FROM item + LEFT JOIN abook ON (item.author_xchan = abook.abook_xchan $abook_uids) + WHERE item.uid = %d + AND item.id = item.parent AND (abook.abook_blocked = 0 or abook.abook_flags is null) - AND item.item_wall = 1 AND item.item_thread_top = 1 - $sql_extra $sql_extra2 - ORDER BY $ordering DESC, item_id $pager_sql ", + AND item.item_wall = 1 + $item_normal + $permission_sql + $sql_extra + $sql_extra2 + ORDER BY $ordering DESC, item_id + $pager_sql", intval(App::$profile['profile_uid']) ); } @@ -408,19 +417,15 @@ class Channel extends Controller { } } if ($r) { - $parents_str = ids_to_querystr($r, 'item_id'); - - $r = q("SELECT item.*, item.id AS item_id - FROM item - WHERE item.uid = %d $item_normal - AND item.parent IN ( %s ) - $sql_extra ", - intval(App::$profile['profile_uid']), - dbesc($parents_str) - ); + $thr_parents = null; + if ($mid) { + $thr_parents = get_recursive_thr_parents($r[0]); + } - xchan_query($r); - $items = fetch_post_tags($r, true); + $items = items_by_parent_ids($r, $thr_parents, $permission_sql, $blog_mode); + + xchan_query($items); + $items = fetch_post_tags($items, true); $items = conv_sort($items, $ordering); if ($load && $mid && (!count($items))) { @@ -434,11 +439,8 @@ class Channel extends Controller { $items = []; } - - $mode = (($search) ? 'search' : 'channel'); - if ((!$update) && (!$load)) { // This is ugly, but we can't pass the profile_uid through the session to the ajax updater, diff --git a/Zotlabs/Module/Cloud.php b/Zotlabs/Module/Cloud.php index 510f91c1e..f9abd767a 100644 --- a/Zotlabs/Module/Cloud.php +++ b/Zotlabs/Module/Cloud.php @@ -7,6 +7,7 @@ namespace Zotlabs\Module; * Module for accessing the DAV storage area. */ +use App; use Sabre\DAV as SDAV; use Zotlabs\Web\Controller; use Zotlabs\Storage\BasicAuth; @@ -32,6 +33,15 @@ class Cloud extends Controller { */ function init() { + // TODO: why is this required? + // if we arrived at this path with any query parameters in the url, build a clean url without + // them and redirect. + + $parsed = parse_url(App::$query_string); + if (!empty($parsed['query'])) { + goaway(z_root() . '/' . $parsed['path']); + } + if (! is_dir('store')) os_mkdir('store', STORAGE_DEFAULT_PERMISSIONS, false); @@ -44,15 +54,13 @@ class Cloud extends Controller { if ($which) profile_load( $which, $profile); - - $auth = new BasicAuth(); $ob_hash = get_observer_hash(); if ($ob_hash) { if (local_channel()) { - $channel = \App::get_channel(); + $channel = App::get_channel(); $auth->setCurrentUser($channel['channel_address']); $auth->channel_account_id = $channel['channel_account_id']; $auth->channel_id = $channel['channel_id']; @@ -63,19 +71,12 @@ class Cloud extends Controller { $auth->observer = $ob_hash; } - // if we arrived at this path with any query parameters in the url, build a clean url without - // them and redirect. - if(! array_key_exists('cloud_sort',$_SESSION)) { $_SESSION['cloud_sort'] = 'name'; } $_SESSION['cloud_sort'] = ((isset($_REQUEST['sort']) && $_REQUEST['sort']) ? trim(notags($_REQUEST['sort'])) : $_SESSION['cloud_sort']); - $x = clean_query_string(); - if($x !== \App::$query_string) - goaway(z_root() . '/' . $x); - $rootDirectory = new Directory('/', [], $auth); // A SabreDAV server-object @@ -116,16 +117,16 @@ class Cloud extends Controller { function DAVException($err) { if($err instanceof \Sabre\DAV\Exception\NotFound) { - \App::$page['content'] = '<h2>404 Not found</h2>'; + App::$page['content'] = '<h2>404 Not found</h2>'; } elseif($err instanceof \Sabre\DAV\Exception\Forbidden) { - \App::$page['content'] = '<h2>403 Forbidden</h2>'; + App::$page['content'] = '<h2>403 Forbidden</h2>'; } elseif($err instanceof \Sabre\DAV\Exception\NotImplemented) { - goaway(z_root() . '/' . \App::$query_string); + goaway(z_root() . '/' . App::$query_string); } else { - \App::$page['content'] = '<h2>Unknown error</h2>'; + App::$page['content'] = '<h2>Unknown error</h2>'; } construct_page(); diff --git a/Zotlabs/Module/Conversation.php b/Zotlabs/Module/Conversation.php index c3e6ae5ec..0a1ba87d1 100644 --- a/Zotlabs/Module/Conversation.php +++ b/Zotlabs/Module/Conversation.php @@ -30,14 +30,13 @@ class Conversation extends Controller { dbesc(ACTIVITY_UNFOLLOW) ); - $item_normal = " and item.item_hidden = 0 and item.item_type = 0 and item.item_unpublished = 0 and item.item_delayed = 0 and item.item_blocked = 0 $item_normal_extra "; + $item_normal = " and item.item_hidden = 0 and item.item_type = 0 and item.item_unpublished = 0 and item.item_delayed = 0 and item.item_blocked = 0 and item.item_uplink = 0 $item_normal_extra "; $i = null; // do we have the item (at all)? - $r = q("select parent_mid from item where mid = '%s' or uuid = '%s' $item_normal order by item_wall desc limit 1", - dbesc(z_root() . '/item/' . $item_id), + $r = q("select parent_mid from item where uuid = '%s' $item_normal order by item_wall desc limit 1", dbesc($item_id) ); @@ -84,9 +83,9 @@ class Conversation extends Controller { // if we don't have a parent id belonging to the signer see if we can obtain one as a visitor that we have permission to access // with a bias towards those items owned by channels on this site (item_wall = 1) - $sql_extra = item_permissions_sql(0); - if (!$i) { + $sql_extra = item_permissions_sql(0); + $i = q("select id as item_id from item where mid = '%s' $item_normal $sql_extra order by item_wall desc limit 1", dbesc($r[0]['parent_mid']) ); diff --git a/Zotlabs/Module/Display.php b/Zotlabs/Module/Display.php index 090e0c92e..094466665 100644 --- a/Zotlabs/Module/Display.php +++ b/Zotlabs/Module/Display.php @@ -212,7 +212,7 @@ class Display extends Controller { $observer_hash = get_observer_hash(); $item_normal = item_normal(); $item_normal_update = item_normal_update(); - $sql_extra = ''; + $permission_sql = ''; $r = []; if($noscript_content || $load) { @@ -231,7 +231,7 @@ class Display extends Controller { } if(!$r) { - $sql_extra = item_permissions_sql(0, $observer_hash); + $permission_sql = item_permissions_sql(0, $observer_hash); $r = q("SELECT item.id AS item_id FROM item WHERE ((mid = '%s' @@ -239,7 +239,7 @@ class Display extends Controller { AND item.deny_gid = '' AND item_private = 0 ) AND uid IN ( " . stream_perms_api_uids(($observer_hash) ? (PERMS_NETWORK|PERMS_PUBLIC) : PERMS_PUBLIC) . " )) OR uid = %d ))) OR - (mid = '%s' $sql_extra )) + (mid = '%s' $permission_sql )) $item_normal limit 1", dbesc($target_item['parent_mid']), @@ -269,7 +269,7 @@ class Display extends Controller { } if(!$r) { - $sql_extra = item_permissions_sql(0, $observer_hash); + $permission_sql = item_permissions_sql(0, $observer_hash); $r = q("SELECT item.id as item_id from item WHERE ((parent_mid = '%s' @@ -277,7 +277,7 @@ class Display extends Controller { AND item.deny_gid = '' AND item_private = 0 ) and uid in ( " . stream_perms_api_uids(($observer_hash) ? (PERMS_NETWORK|PERMS_PUBLIC) : PERMS_PUBLIC) . " )) OR uid = %d ))) OR - (parent_mid = '%s' $sql_extra )) + (parent_mid = '%s' $permission_sql )) $item_normal limit 1", dbesc($target_item['parent_mid']), @@ -288,17 +288,12 @@ class Display extends Controller { } if($r) { - $parents_str = ids_to_querystr($r,'item_id'); - if($parents_str) { - $items = q("SELECT item.*, item.id AS item_id - FROM item - WHERE parent in ( %s ) $sql_extra $item_normal ", - dbesc($parents_str) - ); - xchan_query($items); - $items = fetch_post_tags($items,true); - $items = conv_sort($items,'created'); - } + $thr_parents = get_recursive_thr_parents($target_item); + $items = items_by_parent_ids($r, $thr_parents, $permission_sql); + + xchan_query($items); + $items = fetch_post_tags($items,true); + $items = conv_sort($items,'created'); } else { $items = array(); diff --git a/Zotlabs/Module/Dreport.php b/Zotlabs/Module/Dreport.php index 5db607545..d1ffb8027 100644 --- a/Zotlabs/Module/Dreport.php +++ b/Zotlabs/Module/Dreport.php @@ -19,7 +19,7 @@ class Dreport extends \Zotlabs\Web\Controller { $table = 'push'; if($mid) { - $i = q("select id from item where mid = '%s' and uid = %d and ( author_xchan = '%s' or ( owner_xchan = '%s' and item_wall = 1 )) ", + $i = q("select * from item where mid = '%s' and uid = %d and ( author_xchan = '%s' or ( owner_xchan = '%s' and item_wall = 1 )) ", dbesc($mid), intval($channel['channel_id']), dbesc($channel['channel_hash']), @@ -27,6 +27,12 @@ class Dreport extends \Zotlabs\Web\Controller { ); if($i) { \Zotlabs\Daemon\Master::Summon([ 'Notifier', 'edit_post', $i[0]['id'] ]); + + $relatedItem = find_related($i[0]); + if (isset($relatedItem['id'])) { + \Zotlabs\Daemon\Master::Summon([ 'Notifier', 'edit_post', $relatedItem['id'] ]); + } + } } sleep(3); diff --git a/Zotlabs/Module/Editpost.php b/Zotlabs/Module/Editpost.php index 6f524cdb8..678ceb207 100644 --- a/Zotlabs/Module/Editpost.php +++ b/Zotlabs/Module/Editpost.php @@ -86,6 +86,7 @@ class Editpost extends \Zotlabs\Web\Controller { 'bbco_autocomplete'=> 'bbcode', 'return_path' => 'hq', 'button' => t('Submit'), + 'disable_comments' => (($itm[0]['item_thread_top']) ? false : true), 'hide_voting' => true, 'hide_future' => true, 'hide_location' => true, diff --git a/Zotlabs/Module/Embedphotos.php b/Zotlabs/Module/Embedphotos.php index ed5b24724..edf2d162a 100644 --- a/Zotlabs/Module/Embedphotos.php +++ b/Zotlabs/Module/Embedphotos.php @@ -43,7 +43,7 @@ class Embedphotos extends \Zotlabs\Web\Controller { $arr = explode('/', $href); $resource_id = array_pop($arr); $x = self::photolink($resource_id); - if($x) + if($x) json_return_and_die(array('status' => true, 'photolink' => $x, 'resource_id' => $resource_id)); json_return_and_die(array('errormsg' => 'Error retrieving resource ' . $resource_id, 'status' => false)); } @@ -55,7 +55,7 @@ class Embedphotos extends \Zotlabs\Web\Controller { $output = EMPTY_STR; if($channel) { $resolution = ((feature_enabled($channel['channel_id'],'large_photos')) ? 1 : 2); - $r = q("select mimetype, height, width from photo where resource_id = '%s' and $resolution = %d and uid = %d limit 1", + $r = q("select mimetype, filename from photo where resource_id = '%s' and $resolution = %d and uid = %d limit 1", dbesc($resource), intval($resolution), intval($channel['channel_id']) @@ -63,6 +63,8 @@ class Embedphotos extends \Zotlabs\Web\Controller { if(! $r) return $output; + $filename = $r[0]['filename']; + if($r[0]['mimetype'] === 'image/jpeg') $ext = '.jpg'; elseif($r[0]['mimetype'] === 'image/png') @@ -75,7 +77,7 @@ class Embedphotos extends \Zotlabs\Web\Controller { $ext = EMPTY_STR; $output = '[zrl=' . z_root() . '/photos/' . $channel['channel_address'] . '/image/' . $resource . ']' . - '[zmg=' . $r[0]['width'] . 'x' . $r[0]['height'] . ']' . z_root() . '/photo/' . $resource . '-' . $resolution . $ext . '[/zmg][/zrl]'; + '[zmg=' . z_root() . '/photo/' . $resource . '-' . $resolution . $ext . ']' . $filename . '[/zmg][/zrl]' . "\r\n"; return $output; } diff --git a/Zotlabs/Module/File_upload.php b/Zotlabs/Module/File_upload.php index 8956ce16f..2586265f8 100644 --- a/Zotlabs/Module/File_upload.php +++ b/Zotlabs/Module/File_upload.php @@ -11,39 +11,42 @@ require_once('include/photos.php'); class File_upload extends \Zotlabs\Web\Controller { function post() { - logger('file upload: ' . print_r($_REQUEST,true)); + logger('file upload: ' . print_r($_POST,true)); logger('file upload: ' . print_r($_FILES,true)); - $channel = (($_REQUEST['channick']) ? channelx_by_nick($_REQUEST['channick']) : null); + $channel = (($_POST['channick']) ? channelx_by_nick($_POST['channick']) : null); - if(! $channel) { + if (!$channel) { logger('channel not found'); - killme(); + is_ajax() ? killme() : goaway(z_root() . '/' . $_POST['return_url']); } - $_REQUEST['source'] = 'file_upload'; + $_POST['source'] = 'file_upload'; if($channel['channel_id'] != local_channel()) { - $_REQUEST['contact_allow'] = expand_acl($channel['channel_allow_cid']); - $_REQUEST['group_allow'] = expand_acl($channel['channel_allow_gid']); - $_REQUEST['contact_deny'] = expand_acl($channel['channel_deny_cid']); - $_REQUEST['group_deny'] = expand_acl($channel['channel_deny_gid']); + $_POST['contact_allow'] = expand_acl($channel['channel_allow_cid']); + $_POST['group_allow'] = expand_acl($channel['channel_allow_gid']); + $_POST['contact_deny'] = expand_acl($channel['channel_deny_cid']); + $_POST['group_deny'] = expand_acl($channel['channel_deny_gid']); } - $_REQUEST['allow_cid'] = ((isset($_REQUEST['contact_allow'])) ? perms2str($_REQUEST['contact_allow']) : ''); - $_REQUEST['allow_gid'] = ((isset($_REQUEST['group_allow'])) ? perms2str($_REQUEST['group_allow']) : ''); - $_REQUEST['deny_cid'] = ((isset($_REQUEST['contact_deny'])) ? perms2str($_REQUEST['contact_deny']) : ''); - $_REQUEST['deny_gid'] = ((isset($_REQUEST['group_deny'])) ? perms2str($_REQUEST['group_deny']) : ''); - - if(isset($_REQUEST['filename']) && strlen($_REQUEST['filename'])) { - $r = attach_mkdir($channel, get_observer_hash(), $_REQUEST); - if($r['success']) { - $hash = $r['data']['hash']; - $sync = attach_export_data($channel,$hash); - if($sync) { - Libsync::build_sync_packet($channel['channel_id'],array('file' => array($sync))); - } - goaway(z_root() . '/' . $_REQUEST['return_url']); + $_POST['allow_cid'] = ((isset($_POST['contact_allow'])) ? perms2str($_POST['contact_allow']) : ''); + $_POST['allow_gid'] = ((isset($_POST['group_allow'])) ? perms2str($_POST['group_allow']) : ''); + $_POST['deny_cid'] = ((isset($_POST['contact_deny'])) ? perms2str($_POST['contact_deny']) : ''); + $_POST['deny_gid'] = ((isset($_POST['group_deny'])) ? perms2str($_POST['group_deny']) : ''); + + if(isset($_POST['filename']) && strlen($_POST['filename'])) { + $r = attach_mkdir($channel, get_observer_hash(), $_POST); + + if (!$r['success']) { + notice($r['message'] . EOL); + is_ajax() ? killme() : goaway(z_root() . '/' . $_POST['return_url']); + } + + $hash = $r['data']['hash']; + $sync = attach_export_data($channel,$hash); + if ($sync) { + Libsync::build_sync_packet($channel['channel_id'], ['file' => [$sync]]); } } else { @@ -90,19 +93,19 @@ class File_upload extends \Zotlabs\Web\Controller { } } - $r = attach_store($channel, get_observer_hash(), '', $_REQUEST); - if($r['success']) { - $sync = attach_export_data($channel,$r['data']['hash']); - if($sync) - Libsync::build_sync_packet($channel['channel_id'],array('file' => array($sync))); + $r = attach_store($channel, get_observer_hash(), '', $_POST); + if (!$r['success']) { + notice($r['message'] . EOL); + is_ajax() ? killme() : goaway(z_root() . '/' . $_POST['return_url']); + } + $sync = attach_export_data($channel,$r['data']['hash']); + if ($sync) { + Libsync::build_sync_packet($channel['channel_id'], ['file' => [$sync]]); } } - if(is_ajax()) - killme(); - - goaway(z_root() . '/' . $_REQUEST['return_url']); + is_ajax() ? killme() : goaway(z_root() . '/' . $_POST['return_url']); } diff --git a/Zotlabs/Module/Help.php b/Zotlabs/Module/Help.php index fc0ef2708..52e23e4e0 100644 --- a/Zotlabs/Module/Help.php +++ b/Zotlabs/Module/Help.php @@ -30,7 +30,7 @@ class Help extends \Zotlabs\Web\Controller { $this->determine_help_language(); if (empty($_REQUEST['search']) && argc() === 1) { - goaway("/help/about/about"); + goaway("/help/about"); killme(); } } @@ -85,7 +85,7 @@ class Help extends \Zotlabs\Web\Controller { } - if(argc() > 2 && argv(argc()-2) === 'assets') { + if(argc() > 2 && argv(argc()-2) === 'pic') { $path = ''; for($x = 1; $x < argc(); $x ++) { if(strlen($path)) diff --git a/Zotlabs/Module/Home.php b/Zotlabs/Module/Home.php index 691ca1af9..0dec432d0 100644 --- a/Zotlabs/Module/Home.php +++ b/Zotlabs/Module/Home.php @@ -24,9 +24,13 @@ class Home extends Controller { $key = Config::Get('system', 'prvkey'); $ret = json_encode(Libzot::site_info()); - $headers = ['Content-Type' => 'application/x-zot+json', 'Digest' => HTTPSig::generate_digest_header($ret)]; - $headers['(request-target)'] = strtolower($_SERVER['REQUEST_METHOD']) . ' ' . $_SERVER['REQUEST_URI']; - $h = HTTPSig::create_sig($headers, $key, z_root()); + $headers = [ + 'Content-Type' => 'application/x-zot+json', + 'Digest' => HTTPSig::generate_digest_header($ret), + 'Date' => datetime_convert('UTC','UTC', 'now', 'D, d M Y H:i:s \\G\\M\\T') + ]; + + $h = HTTPSig::create_sig($headers, $key, z_root()); HTTPSig::set_headers($h); echo $ret; @@ -68,9 +72,9 @@ class Home extends Controller { $o = ''; - if (x($_SESSION, 'theme')) + if (isset($_SESSION['theme'])) unset($_SESSION['theme']); - if (x($_SESSION, 'mobile_theme')) + if (isset($_SESSION['mobile_theme'])) unset($_SESSION['mobile_theme']); $splash = ((argc() > 1 && argv(1) === 'splash') ? true : false); @@ -100,14 +104,25 @@ class Home extends Controller { goaway($frontpage); } + $o .= '<div class="generic-content-wrapper">'; + $sitename = Config::Get('system', 'sitename'); - if ($sitename) - $o .= '<h1 class="home-welcome">' . sprintf(t('Welcome to %s'), $sitename) . '</h1>'; + if ($sitename) { + $o .= '<div class="section-title-wrapper">'; + $o .= '<h2 class="">' . sprintf(t('Welcome to %s'), $sitename) . '</h2>'; + $o .= '</div>'; + + } + + $o .= '<div class="section-content-wrapper">'; $loginbox = Config::Get('system', 'login_on_homepage'); if (intval($loginbox) || $loginbox === false) $o .= login(true); + $o .= '</div>'; + $o .= '</div>'; + return $o; } diff --git a/Zotlabs/Module/Hq.php b/Zotlabs/Module/Hq.php index 51caa179c..241a5101a 100644 --- a/Zotlabs/Module/Hq.php +++ b/Zotlabs/Module/Hq.php @@ -3,6 +3,7 @@ namespace Zotlabs\Module; use App; use Zotlabs\Widget\Messages; +use Zotlabs\Lib\Config; class Hq extends \Zotlabs\Web\Controller { @@ -50,12 +51,13 @@ class Hq extends \Zotlabs\Web\Controller { // select the target item with a bias to our own item $sql_order = ((local_channel() > $sys['channel_id']) ? 'DESC' : 'ASC'); - $r = q("select id, uid, mid, parent_mid, thr_parent, verb, item_type, item_deleted, item_blocked from item where uid in (%d, %d) and $identifier = '%s' order by uid $sql_order limit 2", + $r = q("select id, uid, mid, parent, parent_mid, thr_parent, verb, item_type, item_deleted, item_blocked from item where uid in (%d, %d) and $identifier = '%s' order by uid $sql_order limit 2", intval(local_channel()), intval($sys['channel_id']), dbesc($item_hash) ); + if($r) { $target_item = $r[0]; if (intval($target_item['uid']) === intval($sys['channel_id'])) { @@ -129,7 +131,7 @@ class Hq extends \Zotlabs\Web\Controller { '$nouveau' => '0', '$wall' => '0', '$page' => '1', - '$list' => ((x($_REQUEST,'list')) ? intval($_REQUEST['list']) : 0), + '$list' => ((!empty($_REQUEST['list'])) ? intval($_REQUEST['list']) : 0), '$search' => '', '$xchan' => '', '$order' => '', @@ -145,7 +147,6 @@ class Hq extends \Zotlabs\Web\Controller { } if($load && $target_item) { - if (!$sys_item) { $r = q("SELECT item.id AS item_id FROM item WHERE uid = %d @@ -199,11 +200,8 @@ class Hq extends \Zotlabs\Web\Controller { } if($r) { - $items = q("SELECT item.*, item.id AS item_id - FROM item - WHERE parent = '%s' $item_normal $sql_extra", - dbesc($r[0]['item_id']) - ); + $thr_parents = get_recursive_thr_parents($target_item); + $items = items_by_parent_ids($r, $thr_parents); xchan_query($items,true,(($sys_item) ? local_channel() : 0)); $items = fetch_post_tags($items,true); diff --git a/Zotlabs/Module/Id.php b/Zotlabs/Module/Id.php index e08568d00..004cad6e7 100644 --- a/Zotlabs/Module/Id.php +++ b/Zotlabs/Module/Id.php @@ -6,8 +6,8 @@ namespace Zotlabs\Module; * * Controller for responding to x-zot: protocol requests * x-zot:_jkfRG85nJ-714zn-LW_VbTFW8jSjGAhAydOcJzHxqHkvEHWG2E0RbA_pbch-h4R63RG1YJZifaNzgccoLa3MQ/453c1678-1a79-4af7-ab65-6b012f6cab77 - * - */ + * + */ use Zotlabs\Lib\Activity; use Zotlabs\Lib\ActivityStreams; @@ -104,7 +104,7 @@ class Id extends Controller { $headers['Content-Type'] = 'application/x-zot+json' ; $ret = json_encode($x, JSON_UNESCAPED_SLASHES); $headers['Digest'] = HTTPSig::generate_digest_header($ret); - $headers['(request-target)'] = strtolower($_SERVER['REQUEST_METHOD']) . ' ' . $_SERVER['REQUEST_URI']; + $headers['Date'] = datetime_convert('UTC','UTC', 'now', 'D, d M Y H:i:s \\G\\M\\T'); $h = HTTPSig::create_sig($headers,$chan['channel_prvkey'],channel_url($chan)); HTTPSig::set_headers($h); echo $ret; diff --git a/Zotlabs/Module/Invite.php b/Zotlabs/Module/Invite.php index 3e1e98f89..aff0e9340 100644 --- a/Zotlabs/Module/Invite.php +++ b/Zotlabs/Module/Invite.php @@ -310,9 +310,9 @@ class Invite extends Controller { function get() { - // zai1 + $channel_id = local_channel(); - if(! local_channel()) { + if ($channel_id === false || $channel_id < 1) { notice( 'ZAI0101E,' . t('Permission denied.') . EOL); return; } @@ -330,15 +330,15 @@ class Invite extends Controller { return $o; } - // invitation_by_user may still not configured, the default 'na' will tell this - // if configured, 0 disables invitations by users, other numbers are how many invites a user may propagate - $invuser = Config::Get('system','invitation_by_user', 'na'); + $ihave = $this->count_invites_by_user($channel_id); - // if the mortal user drives the invitation - If (! is_site_admin()) { - - // when not configured, 4 is the default - $invuser = ($invuser === 'na') ? 4 : $invuser; + if (is_site_admin()) { + // Admins have unlimited invites + $invuser = '∞'; + } else { + // invitation_by_user may still not configured, the default 'na' will tell this + // if configured, 0 disables invitations by users, other numbers are how many invites a user may propagate + $invuser = Config::Get('system','invitation_by_user', 4); // a config value 0 disables invitation by users if (!$invuser) { @@ -350,12 +350,6 @@ class Invite extends Controller { notice( 'ZAI0105W,' . t('You have no more invitations available') . EOL); return ''; } - - } else { - // general deity admin invite limit infinite (theoretical) - if ($invuser === 'na') Config::Set('system','invitation_by_user', 4); - // for display only - $invuser = '∞'; } // xchan record of the page observer @@ -394,17 +388,6 @@ class Invite extends Controller { } } - if ($wehave > $invmaxau) { - if (! is_site_admin()) { - $feedbk .= 'ZAI0200E,' . t('All users invitation limit exceeded.') . $eol; - } - } - - // let see how many invites currently used by the user - $r = q("SELECT count(reg_id) AS n FROM register WHERE reg_vital = 1 AND reg_byc = %d", - intval(local_channel())); - $ihave = $r ? $r[0]['n'] : 0; - $tpl = get_markup_template('invite.tpl'); $inv_rabots = array( @@ -420,11 +403,11 @@ class Invite extends Controller { 'field' => array( 'name' => 'expire', 'title' => t('duration up from now'), - 'value' => ($invexpire_n ? $invexpire_n : 2), + 'value' => 2, 'min' => '1', 'max' => '99', 'size' => '2', - 'default' => ($invexpire_u ? $invexpire_u : 'd') + 'default' => 'd', ), 'rabot' => $inv_rabots ) @@ -583,5 +566,18 @@ class Invite extends Controller { } return false; } + + /** + * Find how many invites the given channel is currently using. + * + * @param int $channel_id The id of the channel + * + * @return int Number of invites this channel is currently using. + */ + private function count_invites_by_user(int $channel): int { + $r = q("SELECT count(reg_id) AS n FROM register WHERE reg_vital = 1 AND reg_byc = %d", $channel); + + return $r ? $r[0]['n'] : 0; + } } diff --git a/Zotlabs/Module/Item.php b/Zotlabs/Module/Item.php index 8ded7c1d7..83e8d609e 100644 --- a/Zotlabs/Module/Item.php +++ b/Zotlabs/Module/Item.php @@ -53,22 +53,21 @@ class Item extends Controller { if (argc() > 1 && argv(1) !== 'drop') { - $x = q("select uid, item_wall, llink, mid, uuid from item where mid = '%s' or mid = '%s' or uuid = '%s'", - dbesc(z_root() . '/item/' . argv(1)), - dbesc(z_root() . '/activity/' . argv(1)), + $x = q("select uid, item_wall, llink, uuid from item where uuid = '%s' order by item_wall desc", dbesc(argv(1)) ); + if ($x) { - foreach ($x as $xv) { - if (intval($xv['item_wall'])) { - $c = channelx_by_n($xv['uid']); - if ($c) { - goaway(z_root() . '/channel/' . $c['channel_address'] . '?mid=' . $xv['uuid']); - } + if ($x[0]['item_wall']) { + $c = channelx_by_n($x[0]['uid']); + if ($c) { + goaway(z_root() . '/channel/' . $c['channel_address'] . '?mid=' . $x[0]['uuid']); } } + goaway($x[0]['llink']); } + http_status_exit(404, 'Not found'); } @@ -79,7 +78,7 @@ class Item extends Controller { // This will change. Figure out who the observer is and whether or not // they have permission to post here. Else ignore the post. - if ((!local_channel()) && (!remote_channel()) && (!x($_REQUEST, 'anonname'))) + if ((!local_channel()) && (!remote_channel()) && (empty($_POST['anonname']))) return; $uid = local_channel(); @@ -101,7 +100,6 @@ class Item extends Controller { $item_deleted = false; $item_hidden = false; $item_unpublished = false; - $item_delayed = false; $item_pending_remove = false; $item_blocked = false; @@ -109,12 +107,13 @@ class Item extends Controller { * Is this a reply to something? */ - $parent = ((x($_REQUEST, 'parent')) ? intval($_REQUEST['parent']) : 0); - $parent_mid = ((x($_REQUEST, 'parent_mid')) ? trim($_REQUEST['parent_mid']) : ''); - $mode = ((isset($_REQUEST['conv_mode']) && $_REQUEST['conv_mode'] === 'channel') ? 'channel' : 'network'); + $parent = ((!empty($_POST['parent'])) ? intval($_POST['parent']) : 0); + $thr_parent_id = $parent; + $parent_mid = ((!empty($_POST['parent_mid'])) ? trim($_POST['parent_mid']) : ''); + $mode = ((isset($_POST['conv_mode']) && $_POST['conv_mode'] === 'channel') ? 'channel' : 'network'); - $remote_xchan = ((x($_REQUEST, 'remote_xchan')) ? trim($_REQUEST['remote_xchan']) : false); - $r = q("select * from xchan where xchan_hash = '%s' limit 1", + $remote_xchan = ((!empty($_POST['remote_xchan'])) ? trim($_POST['remote_xchan']) : false); + $r = q("select * from xchan where xchan_hash = '%s' limit 1", dbesc($remote_xchan) ); if ($r) @@ -122,7 +121,7 @@ class Item extends Controller { else $remote_xchan = $remote_observer = false; - $profile_uid = ((x($_REQUEST, 'profile_uid')) ? intval($_REQUEST['profile_uid']) : 0); + $profile_uid = ((!empty($_POST['profile_uid'])) ? intval($_POST['profile_uid']) : 0); require_once('include/channel.php'); $sys = get_sys_channel(); @@ -132,25 +131,25 @@ class Item extends Controller { $observer = $sys; } - if (x($_REQUEST, 'dropitems')) { + if (!empty($_POST['dropitems'])) { require_once('include/items.php'); - $arr_drop = explode(',', $_REQUEST['dropitems']); + $arr_drop = explode(',', $_POST['dropitems']); drop_items($arr_drop); $json = ['success' => 1]; echo json_encode($json); killme(); } - call_hooks('post_local_start', $_REQUEST); + call_hooks('post_local_start', $_POST); - // logger('postvars ' . print_r($_REQUEST,true), LOGGER_DATA); + // logger('postvars ' . print_r($_POST,true), LOGGER_DATA); - $api_source = ((x($_REQUEST, 'api_source') && $_REQUEST['api_source']) ? true : false); + $api_source = ((!empty($_POST['api_source'])) ? true : false); - $consensus = $_REQUEST['consensus'] ?? 0; - $nocomment = $_REQUEST['nocomment'] ?? 0; + $consensus = $_POST['consensus'] ?? 0; + $nocomment = $_POST['nocomment'] ?? 0; - $is_poll = ((isset($_REQUEST['poll_answers'][0]) && $_REQUEST['poll_answers'][0]) && (isset($_REQUEST['poll_answers'][1]) && $_REQUEST['poll_answers'][1])); + $is_poll = ((isset($_POST['poll_answers'][0]) && $_POST['poll_answers'][0]) && (isset($_POST['poll_answers'][1]) && $_POST['poll_answers'][1])); // 'origin' (if non-zero) indicates that this network is where the message originated, // for the purpose of relaying comments to other conversation members. @@ -161,42 +160,43 @@ class Item extends Controller { // If you are unsure, it is prudent (and important) to leave it unset. - $origin = (($api_source && array_key_exists('origin', $_REQUEST)) ? intval($_REQUEST['origin']) : 1); + $origin = (($api_source && array_key_exists('origin', $_POST)) ? intval($_REQU_POSTEST['origin']) : 1); // To represent message-ids on other networks - this will create an iconfig record - $namespace = (($api_source && array_key_exists('namespace', $_REQUEST)) ? strip_tags($_REQUEST['namespace']) : ''); - $remote_id = (($api_source && array_key_exists('remote_id', $_REQUEST)) ? strip_tags($_REQUEST['remote_id']) : ''); + $namespace = (($api_source && array_key_exists('namespace', $_POST)) ? strip_tags($_POST['namespace']) : ''); + $remote_id = (($api_source && array_key_exists('remote_id', $_POST)) ? strip_tags($_POST['remote_id']) : ''); $owner_hash = null; - $message_id = ((x($_REQUEST, 'message_id') && $api_source) ? strip_tags($_REQUEST['message_id']) : null); - $created = ((x($_REQUEST, 'created')) ? datetime_convert(date_default_timezone_get(), 'UTC', $_REQUEST['created']) : datetime_convert()); - $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); - $item_obscured = ((x($_REQUEST, 'obscured')) ? intval($_REQUEST['obscured']) : 0); - $pagetitle = ((x($_REQUEST, 'pagetitle')) ? escape_tags($_REQUEST['pagetitle']) : ''); - $layout_mid = ((x($_REQUEST, 'layout_mid')) ? escape_tags($_REQUEST['layout_mid']) : ''); - $plink = ((x($_REQUEST, 'permalink')) ? escape_tags($_REQUEST['permalink']) : ''); - $obj_type = ((x($_REQUEST, 'obj_type')) ? escape_tags($_REQUEST['obj_type']) : 'Note'); + $message_id = ((!empty($_POST['message_id']) && $api_source) ? strip_tags($_POST['message_id']) : null); + $created = ((!empty($_POST['created'])) ? datetime_convert(date_default_timezone_get(), 'UTC', $_POST['created']) : datetime_convert()); + $post_id = ((!empty($_POST['post_id'])) ? intval($_POST['post_id']) : 0); + $app = ((!empty($_POST['source'])) ? strip_tags($_POST['source']) : ''); + $return_path = ((!empty($_POST['return'])) ? $_POST['return'] : ''); + $preview = ((!empty($_POST['preview'])) ? intval($_POST['preview']) : 0); + $categories = ((!empty($_POST['category'])) ? escape_tags($_POST['category']) : ''); + $item_type = ((!empty($_POST['webpage'])) ? intval($_POST['webpage']) : ITEM_TYPE_POST); + $item_obscured = ((!empty($_POST['obscured'])) ? intval($_POST['obscured']) : 0); + $item_delayed = ((!empty($_POST['delayed'])) ? intval($_POST['delayed']) : 0); + $pagetitle = ((!empty($_POST['pagetitle'])) ? escape_tags($_POST['pagetitle']) : ''); + $layout_mid = ((!empty($_POST['layout_mid'])) ? escape_tags($_POST['layout_mid']) : ''); + $plink = ((!empty($_POST['permalink'])) ? escape_tags($_POST['permalink']) : null); + $obj_type = ((!empty($_POST['obj_type'])) ? escape_tags($_POST['obj_type']) : 'Note'); // allow API to bulk load a bunch of imported items with sending out a bunch of posts. - $nopush = ((x($_REQUEST, 'nopush')) ? intval($_REQUEST['nopush']) : 0); + $nopush = ((!empty($_POST['nopush'])) ? intval($_POST['nopush']) : 0); /* * Check service class limits */ - if ($uid && !(x($_REQUEST, 'parent')) && !(x($_REQUEST, 'post_id'))) { - $ret = $this->item_check_service_class($uid, (($_REQUEST['webpage'] == ITEM_TYPE_WEBPAGE) ? true : false)); + if ($uid && empty($_POST['parent']) && empty($_POST['post_id'])) { + $ret = $this->item_check_service_class($uid, (($_POST['webpage'] == ITEM_TYPE_WEBPAGE) ? true : false)); if (!$ret['success']) { notice(t($ret['message']) . EOL); if ($api_source) return (['success' => false, 'message' => 'service class exception']); - if (x($_REQUEST, 'return')) + if (!empty($_POST['return'])) goaway(z_root() . "/" . $return_path); killme(); } @@ -208,7 +208,6 @@ class Item extends Controller { $expires = NULL_DATE; - $comments_closed = NULL_DATE; $route = ''; $parent_item = null; @@ -218,8 +217,8 @@ class Item extends Controller { if ($parent || $parent_mid) { - if (!x($_REQUEST, 'type')) - $_REQUEST['type'] = 'net-comment'; + if (empty($_POST['type'])) + $_POST['type'] = 'net-comment'; if ($parent) { $r = q("SELECT * FROM item WHERE id = %d LIMIT 1", @@ -255,7 +254,7 @@ class Item extends Controller { notice(t('Unable to locate original post.') . EOL); if ($api_source) return (['success' => false, 'message' => 'invalid post id']); - if (x($_REQUEST, 'return')) + if (!empty($_POST['return'])) goaway(z_root() . "/" . $return_path); killme(); } @@ -278,7 +277,7 @@ class Item extends Controller { if (!$observer) { $observer = App::get_observer(); if (!$observer) { - $observer = anon_identity_init($_REQUEST); + $observer = anon_identity_init($_POST); if ($observer) { $moderated = true; $remote_xchan = $remote_observer = $observer; @@ -290,7 +289,7 @@ class Item extends Controller { notice(t('Permission denied.') . EOL); if ($api_source) return (['success' => false, 'message' => 'permission denied']); - if (x($_REQUEST, 'return')) + if (!empty($_POST['return'])) goaway(z_root() . "/" . $return_path); killme(); } @@ -309,17 +308,17 @@ class Item extends Controller { notice(t('Permission denied.') . EOL); if ($api_source) return (['success' => false, 'message' => 'permission denied']); - if (x($_REQUEST, 'return')) + if (!empty($_POST['return'])) goaway(z_root() . "/" . $return_path); killme(); } } else { - if (!perm_is_allowed($profile_uid, $observer['xchan_hash'], ($webpage) ? 'write_pages' : 'post_wall')) { + if (!perm_is_allowed($profile_uid, $observer['xchan_hash'], (intval($item_type) === ITEM_TYPE_POST) ? 'post_wall' : 'write_pages')) { notice(t('Permission denied.') . EOL); if ($api_source) return (['success' => false, 'message' => 'permission denied']); - if (x($_REQUEST, 'return')) + if (!empty($_POST['return'])) goaway(z_root() . "/" . $return_path); killme(); } @@ -375,7 +374,7 @@ class Item extends Controller { logger("mod_item: no channel."); if ($api_source) return (['success' => false, 'message' => 'no channel']); - if (x($_REQUEST, 'return')) + if (!empty($_POST['return'])) goaway(z_root() . "/" . $return_path); killme(); } @@ -385,6 +384,7 @@ class Item extends Controller { $r = q("select * from xchan where xchan_hash = '%s' limit 1", dbesc($channel['channel_hash']) ); + if ($r && count($r)) { $owner_xchan = $r[0]; } @@ -392,7 +392,7 @@ class Item extends Controller { logger("mod_item: no owner."); if ($api_source) return (['success' => false, 'message' => 'no owner']); - if (x($_REQUEST, 'return')) + if (!empty($_POST['return'])) goaway(z_root() . "/" . $return_path); killme(); } @@ -426,17 +426,21 @@ class Item extends Controller { $view_policy = \Zotlabs\Access\PermissionLimits::Get($channel['channel_id'], 'view_stream'); $comment_policy = \Zotlabs\Access\PermissionLimits::Get($channel['channel_id'], 'post_comments'); - $public_policy = ((x($_REQUEST, 'public_policy')) ? escape_tags($_REQUEST['public_policy']) : map_scope($view_policy, true)); - if ($webpage) - $public_policy = ''; - if ($public_policy) + $public_policy = ''; + + if (intval($item_type) === ITEM_TYPE_POST) { + $public_policy = ((!empty($_POST['public_policy'])) ? escape_tags($_POST['public_policy']) : map_scope($view_policy, true)); + } + + if ($public_policy) { $private = 1; + } if ($orig_post) { $private = 0; - // webpages are allowed to change ACLs after the fact. Normal conversation items aren't. - if ($webpage) { - $acl->set_from_array($_REQUEST); + // Normal conversation items are not allowed to change ACL. + if (intval($item_type) !== ITEM_TYPE_POST) { + $acl->set_from_array($_POST); } else { $acl->set($orig_post); @@ -452,10 +456,10 @@ class Item extends Controller { $coord = $orig_post['coord']; $verb = $orig_post['verb']; $app = $orig_post['app']; - $title = escape_tags(trim($_REQUEST['title'])); - $summary = escape_tags(trim($_REQUEST['summary'])); - $body = trim($_REQUEST['body']); - $item_flags = $orig_post['item_flags']; + $title = escape_tags(trim($_POST['title'])); + $summary = escape_tags(trim($_POST['summary'])); + $body = trim($_POST['body']); + $item_flags = $orig_post['item_flags']; $item_origin = $orig_post['item_origin']; $item_unseen = $orig_post['item_unseen']; $item_starred = $orig_post['item_starred']; @@ -469,7 +473,7 @@ class Item extends Controller { $item_mentionsme = $orig_post['item_mentionsme']; $item_nocomment = $orig_post['item_nocomment']; $item_obscured = $orig_post['item_obscured']; - $item_verified = $orig_post['item_verified']; + $item_verified = $orig_post['item_verified']; $item_retained = $orig_post['item_retained']; $item_rss = $orig_post['item_rss']; $item_deleted = $orig_post['item_deleted']; @@ -488,14 +492,15 @@ class Item extends Controller { $thr_parent = $orig_post['thr_parent']; $parent_mid = $orig_post['parent_mid']; $plink = $orig_post['plink']; + $owner_hash = $orig_post['owner_xchan']; } else { if (!$walltowall) { - if ((array_key_exists('contact_allow', $_REQUEST)) - || (array_key_exists('group_allow', $_REQUEST)) - || (array_key_exists('contact_deny', $_REQUEST)) - || (array_key_exists('group_deny', $_REQUEST))) { - $acl->set_from_array($_REQUEST); + if ((array_key_exists('contact_allow', $_POST)) + || (array_key_exists('group_allow', $_POST)) + || (array_key_exists('contact_deny', $_POST)) + || (array_key_exists('group_deny', $_POST))) { + $acl->set_from_array($_POST); } elseif (!$api_source) { @@ -510,16 +515,16 @@ class Item extends Controller { } - $location = ((isset($_REQUEST['location'])) ? notags(trim($_REQUEST['location'])) : ''); - $coord = ((isset($_REQUEST['coord'])) ? notags(trim($_REQUEST['coord'])) : ''); - $verb = ((isset($_REQUEST['verb'])) ? notags(trim($_REQUEST['verb'])) : ''); - $title = ((isset($_REQUEST['title'])) ? escape_tags(trim($_REQUEST['title'])) : ''); - $summary = ((isset($_REQUEST['summary'])) ? escape_tags(trim($_REQUEST['summary'])) : ''); - $body = ((isset($_REQUEST['body'])) ? trim($_REQUEST['body']) : ''); - $body .= ((isset($_REQUEST['attachment'])) ? trim($_REQUEST['attachment']) : ''); + $location = ((isset($_POST['location'])) ? notags(trim($_POST['location'])) : ''); + $coord = ((isset($_POST['coord'])) ? notags(trim($_POST['coord'])) : ''); + $verb = ((isset($_POST['verb'])) ? notags(trim($_POST['verb'])) : ''); + $title = ((isset($_POST['title'])) ? escape_tags(trim($_POST['title'])) : ''); + $summary = ((isset($_POST['summary'])) ? escape_tags(trim($_POST['summary'])) : ''); + $body = ((isset($_POST['body'])) ? trim($_POST['body']) : ''); + $body .= ((isset($_POST['attachment'])) ? trim($_POST['attachment']) : ''); $postopts = ''; - $allow_empty = ((array_key_exists('allow_empty', $_REQUEST)) ? intval($_REQUEST['allow_empty']) : 0); + $allow_empty = ((array_key_exists('allow_empty', $_POST)) ? intval($_POST['allow_empty']) : 0); $private = ((isset($private) && $private) ? $private : intval($acl->is_private() || ($public_policy))); @@ -530,7 +535,7 @@ class Item extends Controller { $private = intval($parent_item['item_private']); $public_policy = $parent_item['public_policy']; $owner_hash = $parent_item['owner_xchan']; - $webpage = $parent_item['item_type']; + $item_type = $parent_item['item_type']; } @@ -541,7 +546,7 @@ class Item extends Controller { info(t('Empty post discarded.') . EOL); if ($api_source) return (['success' => false, 'message' => 'no content']); - if (x($_REQUEST, 'return')) + if (!empty($_POST['return'])) goaway(z_root() . "/" . $return_path); killme(); } @@ -549,15 +554,15 @@ class Item extends Controller { if (feature_enabled($profile_uid, 'content_expire')) { - if (x($_REQUEST, 'expire')) { - $expires = datetime_convert(date_default_timezone_get(), 'UTC', $_REQUEST['expire']); + if (!empty($_POST['expire'])) { + $expires = datetime_convert(date_default_timezone_get(), 'UTC', $_POST['expire']); if ($expires <= datetime_convert()) $expires = NULL_DATE; } } - $mimetype = ((isset($_REQUEST['mimetype'])) ? notags(trim($_REQUEST['mimetype'])) : ''); + $mimetype = ((isset($_POST['mimetype'])) ? notags(trim($_POST['mimetype'])) : ''); if (!$mimetype) $mimetype = 'text/bbcode'; @@ -591,7 +596,7 @@ class Item extends Controller { $is_group = get_pconfig($profile_uid, 'system', 'group_actor'); - if ($is_group && $walltowall && !$walltowall_comment && !$webpage) { + if ($is_group && $walltowall && !$walltowall_comment && (intval($item_type) === ITEM_TYPE_POST)) { $groupww = true; $str_contact_allow = $owner_xchan['xchan_hash']; $str_group_allow = ''; @@ -790,22 +795,21 @@ class Item extends Controller { } $item_unseen = ((local_channel() != $profile_uid) ? 1 : 0); - $item_wall = ((isset($_REQUEST['type']) && ($_REQUEST['type'] === 'wall' || $_REQUEST['type'] === 'wall-comment')) ? 1 : 0); + $item_wall = ((isset($_POST['type']) && ($_POST['type'] === 'wall' || $_POST['type'] === 'wall-comment')) ? 1 : 0); $item_origin = (($origin) ? 1 : 0); $item_consensus = (($consensus) ? 1 : 0); $item_nocomment = (($nocomment) ? 1 : 0); + $comments_closed = (($nocomment) ? $comments_closed : NULL_DATE); // determine if this is a wall post + if (in_array($item_type, [ITEM_TYPE_POST, ITEM_TYPE_CARD, ITEM_TYPE_ARTICLE])) { + $item_wall = 1; + } + if ($parent) { $item_wall = $parent_item['item_wall']; } - else { - if (!$webpage) { - $item_wall = 1; - } - } - if ($moderated) { $item_blocked = ITEM_MODERATED; @@ -822,36 +826,34 @@ class Item extends Controller { $mid = $mid ?? z_root() . '/item/' . $uuid; - // Set the conversation target. - if (empty($owner_hash)) { - $owner_hash = $owner_xchan['xchan_hash']; - } - - if ($owner_hash === $channel['channel_hash']) { - $attributedTo = z_root() . '/channel/' . $channel['channel_address']; - - $conversation = isset($parent_item) ? $parent_item['mid'] : $mid; - $datarray['target'] = [ - 'id' => str_replace('/item/', '/conversation/', $conversation), - 'type' => 'Collection', - 'attributedTo' => $attributedTo, - ]; - $datarray['tgt_type'] = 'Collection'; - } - elseif (!empty($parent_item['target'])) { - $datarray['target'] = $parent_item['target']; - $datarray['tgt_type'] = $parent_item['tgt_type']; - } + if (empty($owner_hash)) { + $owner_hash = $owner_xchan['xchan_hash']; + } + // Set the conversation target. + if ($owner_hash === $channel['channel_hash']) { + $attributedTo = z_root() . '/channel/' . $channel['channel_address']; + $conversation = isset($parent_item) ? $parent_item['mid'] : $mid; + $datarray['target'] = [ + 'id' => str_replace('/item/', '/conversation/', $conversation), + 'type' => 'Collection', + 'attributedTo' => $attributedTo, + ]; + $datarray['tgt_type'] = 'Collection'; + } + elseif (!empty($parent_item['target'])) { + $datarray['target'] = $parent_item['target']; + $datarray['tgt_type'] = $parent_item['tgt_type']; + } if ($is_poll) { $poll = [ 'question' => $body, - 'answers' => $_REQUEST['poll_answers'], - 'multiple_answers' => $_REQUEST['poll_multiple_answers'], - 'expire_value' => $_REQUEST['poll_expire_value'], - 'expire_unit' => $_REQUEST['poll_expire_unit'] + 'answers' => $_POST['poll_answers'], + 'multiple_answers' => $_POST['poll_multiple_answers'], + 'expire_value' => $_POST['poll_expire_value'], + 'expire_unit' => $_POST['poll_expire_unit'] ]; $obj = $this->extract_poll_data($poll, ['item_private' => $private, 'allow_cid' => $str_contact_allow, 'allow_gid' => $str_contact_deny]); } @@ -886,19 +888,13 @@ class Item extends Controller { if ($parent_item) $parent_mid = $parent_item['mid']; - // Fallback so that we always have a thr_parent if (!$thr_parent) $thr_parent = $mid; - $item_thread_top = ((!$parent) ? 1 : 0); - if ((!$plink) && ($item_thread_top)) { - $plink = $mid; - } - if (isset($datarray['obj']) && $datarray['obj']) { $datarray['obj']['id'] = $mid; } @@ -936,7 +932,7 @@ class Item extends Controller { $datarray['item_unseen'] = intval($item_unseen); $datarray['item_wall'] = intval($item_wall); $datarray['item_origin'] = intval($item_origin); - $datarray['item_type'] = $webpage; + $datarray['item_type'] = $item_type; $datarray['item_private'] = intval($private); $datarray['item_thread_top'] = intval($item_thread_top); $datarray['item_starred'] = intval($item_starred); @@ -961,7 +957,7 @@ class Item extends Controller { $datarray['public_policy'] = $public_policy; $datarray['comment_policy'] = map_scope($comment_policy); $datarray['term'] = array_unique($post_tags, SORT_REGULAR); - $datarray['plink'] = $plink; + $datarray['plink'] = $plink ?? $mid; $datarray['route'] = $route; // A specific ACL over-rides public_policy completely @@ -1015,14 +1011,14 @@ class Item extends Controller { call_hooks('post_local', $datarray); - if (x($datarray, 'cancel')) { + if (!empty($datarray['cancel'])) { logger('mod_item: post cancelled by plugin or duplicate suppressed.'); if ($return_path) goaway(z_root() . "/" . $return_path); if ($api_source) return (['success' => false, 'message' => 'operation cancelled']); $json = ['cancel' => 1]; - $json['reload'] = z_root() . '/' . $_REQUEST['jsreload']; + $json['reload'] = z_root() . '/' . $_POST['jsreload']; echo json_encode($json); killme(); } @@ -1031,8 +1027,8 @@ class Item extends Controller { if (mb_strlen($datarray['title']) > 191) $datarray['title'] = mb_substr($datarray['title'], 0, 191); - if ($webpage) { - IConfig::Set($datarray, 'system', webpage_to_namespace($webpage), + if (intval($item_type) !== ITEM_TYPE_POST) { + IConfig::Set($datarray, 'system', item_type_to_namespace($item_type), (($pagetitle) ? $pagetitle : basename($datarray['mid'])), true); } elseif ($namespace) { @@ -1072,7 +1068,7 @@ class Item extends Controller { if ($api_source) return ($x); - if ((x($_REQUEST, 'return')) && strlen($return_path)) { + if ((!empty($_POST['return'])) && strlen($return_path)) { logger('return: ' . $return_path); if ($return_path === 'hq') { @@ -1225,11 +1221,12 @@ class Item extends Controller { $json = [ 'success' => 1, 'id' => $post_id, + 'thr_parent_id' => $thr_parent_id, 'html' => conversation($item, $mode, true, 'r_preview'), ]; - if (x($_REQUEST, 'jsreload') && strlen($_REQUEST['jsreload'])) - $json['reload'] = z_root() . '/' . $_REQUEST['jsreload']; + if (!empty($_POST['jsreload'])) + $json['reload'] = z_root() . '/' . $_POST['jsreload']; logger('post_json: ' . print_r($json, true), LOGGER_DEBUG); @@ -1246,8 +1243,6 @@ class Item extends Controller { if ((argc() == 3) && (argv(1) === 'drop') && intval(argv(2))) { - require_once('include/items.php'); - $i = q("select * from item where id = %d limit 1", intval(argv(2)) ); @@ -1506,7 +1501,7 @@ class Item extends Controller { dbesc(ACTIVITY_UNFOLLOW) ); - $item_normal = " and item.item_hidden = 0 and item.item_type = 0 and item.item_unpublished = 0 and item.item_delayed = 0 and item.item_blocked = 0 $item_normal_extra "; + $item_normal = " and item.item_hidden = 0 and item.item_type = 0 and item.item_unpublished = 0 and item.item_delayed = 0 and item.item_blocked = 0 and item.item_uplink = 0 $item_normal_extra "; $i = null; @@ -1622,7 +1617,7 @@ class Item extends Controller { dbesc(ACTIVITY_UNFOLLOW) ); - $item_normal = " and item.item_hidden = 0 and item.item_type = 0 and item.item_unpublished = 0 and item.item_delayed = 0 and item.item_blocked = 0 $item_normal_extra "; + $item_normal = " and item.item_hidden = 0 and item.item_type = 0 and item.item_unpublished = 0 and item.item_delayed = 0 and item.item_blocked = 0 and item.item_uplink = 0 $item_normal_extra "; $i = null; diff --git a/Zotlabs/Module/Lang.php b/Zotlabs/Module/Lang.php index fe185ebea..1eeb29363 100644 --- a/Zotlabs/Module/Lang.php +++ b/Zotlabs/Module/Lang.php @@ -65,8 +65,22 @@ class Lang extends Controller { } nav_set_selected('Language'); - return lang_selector(); + return $this->lang_selector(); } + private function lang_selector(): string + { + $lang_options = language_list(); + array_unshift($lang_options, t('default')); + + $tpl = get_markup_template('lang_selector.tpl'); + + return replace_macros($tpl, [ + '$title' => t('Select an alternate language'), + '$langs' => array($lang_options, App::$language), + + ]); + } + } diff --git a/Zotlabs/Module/Like.php b/Zotlabs/Module/Like.php index 2fb3fab83..52c559a17 100644 --- a/Zotlabs/Module/Like.php +++ b/Zotlabs/Module/Like.php @@ -22,9 +22,9 @@ class Like extends Controller { 'like' => 'Like', 'dislike' => 'Dislike', 'announce' => ACTIVITY_SHARE, - 'attendyes' => 'Accept', - 'attendno' => 'Reject', - 'attendmaybe' => 'TentativeAccept' + 'accept' => 'Accept', + 'reject' => 'Reject', + 'tentativeaccept' => 'TentativeAccept' ]; // unlike (etc.) reactions are an undo of positive reactions, rather than a negative action. @@ -52,43 +52,31 @@ class Like extends Controller { profile_load($parts[0]); } - $item_normal = item_normal(); - if ($page_mode === 'list') { + $item_normal = item_normal(); + $items = q("SELECT item.*, item.id AS item_id FROM item WHERE uid = %d $item_normal AND parent = %d", intval($arr['item']['uid']), intval($arr['item']['parent']) ); + xchan_query($items, true); $items = fetch_post_tags($items, true); $items = conv_sort($items, 'commented'); } else { - $activities = q("SELECT item.*, item.id AS item_id FROM item - WHERE uid = %d $item_normal - AND thr_parent = '%s' - AND verb IN ('%s', '%s', '%s', '%s', '%s', '%s', 'Accept', 'Reject', 'TentativeAccept')", - intval($arr['item']['uid']), - dbesc($arr['item']['mid']), - dbesc('Like'), - dbesc('Dislike'), - dbesc(ACTIVITY_SHARE), - dbesc(ACTIVITY_ATTEND), - dbesc(ACTIVITY_ATTENDNO), - dbesc(ACTIVITY_ATTENDMAYBE) - ); - xchan_query($activities, true); - $items = array_merge([$arr['item']], $activities); - $items = fetch_post_tags($items, true); + $item = item_by_item_id($arr['item']['id'], $arr['item']['parent']); + xchan_query($item, true); + $item = fetch_post_tags($item, true); } $ret = [ 'success' => 1, 'orig_id' => $arr['orig_item_id'], //this is required for pubstream items where $item_id != $item['id'] 'id' => $arr['item']['id'], - 'html' => conversation($items, $conv_mode, true, $page_mode), + 'html' => conversation($item, $conv_mode, true, $page_mode), ]; // mod photos @@ -486,11 +474,11 @@ class Like extends Controller { $bodyverb = t('%1$s likes %2$s\'s %3$s'); if ($verb === 'dislike') $bodyverb = t('%1$s doesn\'t like %2$s\'s %3$s'); - if ($verb === 'attendyes') + if ($verb === 'accept') $bodyverb = t('%1$s is attending %2$s\'s %3$s'); - if ($verb === 'attendno') + if ($verb === 'reject') $bodyverb = t('%1$s is not attending %2$s\'s %3$s'); - if ($verb === 'attendmaybe') + if ($verb === 'tentativeaccept') $bodyverb = t('%1$s may attend %2$s\'s %3$s'); if (!isset($bodyverb)) @@ -573,7 +561,7 @@ class Like extends Controller { call_hooks('post_local_end', $arr); - if ($is_rsvp && in_array($verb, ['attendyes', 'attendmaybe'])) { + if ($is_rsvp && in_array($verb, ['accept', 'tentativeaccept'])) { event_addtocal($item_id, local_channel()); } diff --git a/Zotlabs/Module/Login.php b/Zotlabs/Module/Login.php index 721ac15ac..f5a83a91a 100644 --- a/Zotlabs/Module/Login.php +++ b/Zotlabs/Module/Login.php @@ -5,12 +5,28 @@ namespace Zotlabs\Module; class Login extends \Zotlabs\Web\Controller { function get() { - if(local_channel()) + if (local_channel()) { goaway(z_root()); - if(remote_channel() && $_SESSION['atoken']) + } + + if (remote_channel() && $_SESSION['atoken']) { goaway(z_root()); + } + + if (!empty($_GET['retry'])) { + notice( t('Login failed.') . EOL ); + } + + $o = '<div class="generic-content-wrapper">'; + $o .= '<div class="section-title-wrapper">'; + $o .= '<h2 class="">' . t('Login') . '</h2>'; + $o .= '</div>'; + $o .= '<div class="section-content-wrapper">'; + $o .= login(true); + $o .= '</div>'; + $o .= '</div>'; - return login(true); + return $o; } } diff --git a/Zotlabs/Module/Magic.php b/Zotlabs/Module/Magic.php index e722a7161..122d90b1b 100644 --- a/Zotlabs/Module/Magic.php +++ b/Zotlabs/Module/Magic.php @@ -41,11 +41,7 @@ class Magic extends Controller { http_status_exit(400, 'Bad Request'); } - $basepath = unparse_url(array_filter( - $parsed, - fn (string $key) => in_array($key, ['scheme', 'host', 'port']), - ARRAY_FILTER_USE_KEY - )); + $basepath = unparse_url($parsed, ['scheme', 'host', 'port']); $owapath = SConfig::get($basepath, 'system', 'openwebauth', $basepath . '/owa'); @@ -134,11 +130,22 @@ class Magic extends Controller { $args = (($x) ? '&owt=' . $token : '?owt=' . $token) . (($delegate) ? '&delegate=1' : ''); goaway($dest . $args); } + else { + $o = '<h1>OWA ERROR</h1>'; + if (!empty($j['message'])) { + $o .= '<h2>' . $j['message'] . '</h2>'; + } + $o .= '<a href=' . $dest . '>' . $dest . '</a>'; + + echo $o; + killme(); + + } } } } - killme(); + goaway($dest); } diff --git a/Zotlabs/Module/Moderate.php b/Zotlabs/Module/Moderate.php index 2103684ab..1d8f65348 100644 --- a/Zotlabs/Module/Moderate.php +++ b/Zotlabs/Module/Moderate.php @@ -67,7 +67,7 @@ class Moderate extends \Zotlabs\Web\Controller { $item['item_blocked'] = 0; item_update_parent_commented($item); - notice( t('Item approved') . EOL); + info(t('Item approved') . EOL); } elseif($action === 'drop') { // TODO: not implemented @@ -75,7 +75,7 @@ class Moderate extends \Zotlabs\Web\Controller { // Activity::send_rejection_activity(App::get_channel(), $item['author_xchan'], $item); drop_item($post_id); - notice( t('Item deleted') . EOL); + info(t('Item deleted') . EOL); } // refetch the item after changes have been made diff --git a/Zotlabs/Module/Network.php b/Zotlabs/Module/Network.php index 3ea813547..f95d92fe2 100644 --- a/Zotlabs/Module/Network.php +++ b/Zotlabs/Module/Network.php @@ -70,17 +70,19 @@ class Network extends \Zotlabs\Web\Controller { $dm = ((x($_REQUEST,'dm')) ? $_REQUEST['dm'] : 0); - $order = get_pconfig(local_channel(), 'mod_network', 'order', 0); + $order = get_pconfig(local_channel(), 'mod_network', 'order', 'created'); switch($order) { - case 0: - $order = 'comment'; + case 'commented': + $ordering = 'commented'; break; - case 1: - $order = 'post'; + case 'created': + $ordering = 'created'; break; - case 2: + case 'unthreaded': $nouveau = true; break; + default: + $ordering = 'created'; } $search = $_GET['search'] ?? ''; @@ -92,7 +94,7 @@ class Network extends \Zotlabs\Web\Controller { } if($datequery) - $order = 'post'; + $order = 'created'; // filter by collection (e.g. group) @@ -274,36 +276,18 @@ class Network extends \Zotlabs\Web\Controller { elseif($pf && $unseen && $nouveau) { $vnotify = get_pconfig(local_channel(), 'system', 'vnotify'); - if(! ($vnotify & VNOTIFY_LIKE)) + $likes_sql = ''; + if (!($vnotify & VNOTIFY_LIKE)) { $likes_sql = " AND verb NOT IN ('Like', 'Dislike', '" . dbesc(ACTIVITY_LIKE) . "', '" . dbesc(ACTIVITY_DISLIKE) . "') "; + } // This is for nouveau view public forum cid queries (if a forum notification is clicked) - //$p = q("SELECT oid AS parent FROM term WHERE uid = %d AND ttype = %d AND term = '%s'", - //intval(local_channel()), - //intval(TERM_FORUM), - //dbesc($cid_r[0]['xchan_name']) - //); - - //$p_str = ids_to_querystr($p, 'parent'); + $sql_extra = " AND item.parent IN (SELECT DISTINCT parent FROM item WHERE uid = " . intval(local_channel()) . " AND ( author_xchan = '" . dbesc($cid_r[0]['abook_xchan']) . "' OR owner_xchan = '" . dbesc($cid_r[0]['abook_xchan']) . "' ) $item_normal) AND item_unseen = 1 AND verb != 'Announce' $likes_sql "; - $p_sql = ''; - //if($p_str) - //$p_sql = " OR item.parent IN ( $p_str ) "; - - $sql_extra = " AND ( owner_xchan = '" . protect_sprintf(dbesc($cid_r[0]['abook_xchan'])) . "' OR owner_xchan = '" . protect_sprintf(dbesc($cid_r[0]['abook_xchan'])) . "' $p_sql ) AND item_unseen = 1 $likes_sql "; } else { // This is for threaded view cid queries (e.g. if a forum is selected from the forum filter) - $ttype = (($pf) ? TERM_FORUM : TERM_MENTION); - - $p1 = dbq("SELECT DISTINCT parent FROM item WHERE uid = " . intval(local_channel()) . " AND ( author_xchan = '" . dbesc($cid_r[0]['abook_xchan']) . "' OR owner_xchan = '" . dbesc($cid_r[0]['abook_xchan']) . "' ) $item_normal "); - $p2 = dbq("SELECT oid AS parent FROM term WHERE uid = " . intval(local_channel()) . " AND ttype = $ttype AND term = '" . dbesc($cid_r[0]['xchan_name']) . "'"); - - $p_str = ids_to_querystr(array_merge($p1, $p2), 'parent'); - if(! $p_str) - killme(); - - $sql_extra = " AND item.parent IN ( $p_str ) "; + $sql_extra = " AND item.parent IN (SELECT DISTINCT parent FROM item WHERE uid = " . intval(local_channel()) . " AND ( author_xchan = '" . dbesc($cid_r[0]['abook_xchan']) . "' OR owner_xchan = '" . dbesc($cid_r[0]['abook_xchan']) . "' ) $item_normal) "; } } @@ -393,10 +377,10 @@ class Network extends \Zotlabs\Web\Controller { } if ($dm) { - $sql_extra .= ' AND item_private = 2 '; + $sql_extra .= ' AND item.item_private = 2 '; } else { - $sql_extra .= ' AND item_private IN (0, 1) '; + $sql_extra .= ' AND item.item_private IN (0, 1) '; } @@ -445,10 +429,12 @@ class Network extends \Zotlabs\Web\Controller { $abook_uids = ' and abook.abook_channel = ' . local_channel() . ' '; $uids = ' and item.uid = ' . local_channel() . ' '; - if(feature_enabled(local_channel(), 'network_list_mode')) + $page_mode = 'client'; + + $blog_mode = feature_enabled(local_channel(), 'network_list_mode'); + if ($blog_mode) { $page_mode = 'list'; - else - $page_mode = 'client'; + } $parents_str = ''; @@ -472,11 +458,12 @@ class Network extends \Zotlabs\Web\Controller { if($nouveau && $load) { // "New Item View" - show all items unthreaded in reverse created date order - $items = dbq("SELECT item.*, item.id AS item_id, created FROM item + $items = dbq("SELECT item.*, item.id AS item_id FROM item left join abook on ( item.owner_xchan = abook.abook_xchan $abook_uids ) $net_query WHERE true $uids $item_normal and (abook.abook_blocked = 0 or abook.abook_flags is null) + AND item.verb NOT IN ('Add', 'Remove') $sql_extra $sql_options $sql_nets $net_query2 ORDER BY item.created DESC $pager_sql " @@ -492,13 +479,6 @@ class Network extends \Zotlabs\Web\Controller { } elseif($update) { - // Normal conversation view - - if($order === 'post') - $ordering = 'created'; - else - $ordering = 'commented'; - if($load) { // Fetch a page full of parent items for this page $r = dbq("SELECT item.parent AS item_id FROM item @@ -527,12 +507,7 @@ class Network extends \Zotlabs\Web\Controller { // Then fetch all the children of the parents that are on this page if($r) { - $parents_str = ids_to_querystr($r, 'item_id'); - $items = dbq("SELECT item.*, item.id AS item_id FROM item - WHERE true $uids $item_normal - AND item.parent IN ( $parents_str ) - $sql_extra " - ); + $items = items_by_parent_ids($r, blog_mode: $blog_mode); xchan_query($items, true); $items = fetch_post_tags($items, true); diff --git a/Zotlabs/Module/Oep.php b/Zotlabs/Module/Oep.php index 37a46a23e..201e5a06f 100644 --- a/Zotlabs/Module/Oep.php +++ b/Zotlabs/Module/Oep.php @@ -23,6 +23,7 @@ class Oep extends \Zotlabs\Web\Controller { if(! $url) http_status_exit(404, 'Not found'); + $arr = []; $maxwidth = $_REQUEST['maxwidth'] ?? 0; $maxheight = $_REQUEST['maxheight'] ?? 0; $format = $_REQUEST['format'] ?? ''; diff --git a/Zotlabs/Module/Owa.php b/Zotlabs/Module/Owa.php index 85467d4f4..254b1c7d1 100644 --- a/Zotlabs/Module/Owa.php +++ b/Zotlabs/Module/Owa.php @@ -18,96 +18,97 @@ use Zotlabs\Web\Controller; class Owa extends Controller { - function init() { + public function init(): void + { $ret = [ 'success' => false ]; - if (array_key_exists('REDIRECT_REMOTE_USER',$_SERVER) && (! array_key_exists('HTTP_AUTHORIZATION',$_SERVER))) { - $_SERVER['HTTP_AUTHORIZATION'] = $_SERVER['REDIRECT_REMOTE_USER']; + if (!$this->validateAuthorizationHeader()) { + $this->error('Missing or invalid authorization header.'); } - if (array_key_exists('HTTP_AUTHORIZATION',$_SERVER) && substr(trim($_SERVER['HTTP_AUTHORIZATION']),0,9) === 'Signature') { - $sigblock = HTTPSig::parse_sigheader($_SERVER['HTTP_AUTHORIZATION']); - if ($sigblock) { - $keyId = $sigblock['keyId']; - $parsed = parse_url($keyId); - if (str_starts_with($parsed['scheme'],'http')) { - unset($parsed['fragment']); - unset($parsed['query']); - $keyId = unparse_url($parsed); - } - else { - $keyId = str_replace('acct:', '', $keyId); + $_SERVER['HTTP_AUTHORIZATION'] = $_SERVER['HTTP_AUTHORIZATION'] ?? $_SERVER['REDIRECT_REMOTE_USER']; + + $sigblock = HTTPSig::parse_sigheader($_SERVER['HTTP_AUTHORIZATION']); + if ($sigblock) { + $keyId = $sigblock['keyId']; + $parsed = parse_url($keyId); + if (str_starts_with($parsed['scheme'],'http')) { + unset($parsed['fragment']); + unset($parsed['query']); + $keyId = unparse_url($parsed); + } + else { + $keyId = str_replace('acct:', '', $keyId); + } + if ($keyId) { + $r = q("SELECT * FROM hubloc LEFT JOIN xchan ON hubloc_hash = xchan_hash + WHERE (hubloc_addr = '%s' OR hubloc_id_url = '%s' OR xchan_hash = '%s') + AND hubloc_deleted = 0 AND xchan_pubkey != '' + ORDER BY hubloc_id DESC", + dbesc($keyId), + dbesc($keyId), + dbesc($keyId) + ); + if (! $r) { + $found = discover_by_webbie($keyId); + logger('found = ' . print_r($found, true)); + if ($found) { + $r = q("SELECT * FROM hubloc LEFT JOIN xchan ON hubloc_hash = xchan_hash + WHERE (hubloc_addr = '%s' OR hubloc_id_url = '%s' OR xchan_hash = '%s') AND hubloc_deleted = 0 AND xchan_pubkey != '' ORDER BY hubloc_id DESC ", + dbesc($keyId), + dbesc($keyId), + dbesc($keyId) + ); + } } - if ($keyId) { - $r = q("SELECT * FROM hubloc LEFT JOIN xchan ON hubloc_hash = xchan_hash - WHERE (hubloc_addr = '%s' OR hubloc_id_url = '%s' OR xchan_hash = '%s') - AND hubloc_deleted = 0 AND xchan_pubkey != '' - ORDER BY hubloc_id DESC", - dbesc($keyId), - dbesc($keyId), - dbesc($keyId) - ); - if (! $r) { + + if ($r) { + foreach ($r as $hubloc) { + $verified = HTTPSig::verify(file_get_contents('php://input'), $hubloc['xchan_pubkey']); + if ($verified && $verified['header_signed'] && $verified['header_valid'] && ($verified['content_valid'] || (! $verified['content_signed']))) { + logger('OWA header: ' . print_r($verified,true),LOGGER_DATA); + logger('OWA success: ' . $hubloc['hubloc_id_url'],LOGGER_DATA); + $ret['success'] = true; + $token = random_string(32); + Verify::create('owt',0,$token,$hubloc['hubloc_id_url']); + $result = ''; + openssl_public_encrypt($token,$result,$hubloc['xchan_pubkey']); + $ret['encrypted_token'] = base64url_encode($result); + break; + } else { + logger('OWA fail: ' . $hubloc['hubloc_id'] . ' ' . $hubloc['hubloc_id_url']); + } + } + + if (!$ret['success']) { + + // Possible a reinstall? + // In this case we probably already have an old hubloc + // but not the new one yet. + $found = discover_by_webbie($keyId); - logger('found = ' . print_r($found, true)); + if ($found) { $r = q("SELECT * FROM hubloc LEFT JOIN xchan ON hubloc_hash = xchan_hash - WHERE (hubloc_addr = '%s' OR hubloc_id_url = '%s' OR xchan_hash = '%s') AND hubloc_deleted = 0 AND xchan_pubkey != '' ORDER BY hubloc_id DESC ", - dbesc($keyId), - dbesc($keyId), + WHERE (hubloc_addr = '%s' OR hubloc_id_url = '%s') AND hubloc_deleted = 0 ORDER BY hubloc_id DESC LIMIT 1", + dbesc(str_replace('acct:', '', $keyId)), dbesc($keyId) ); - } - } - - if ($r) { - foreach ($r as $hubloc) { - $verified = HTTPSig::verify(file_get_contents('php://input'), $hubloc['xchan_pubkey']); - if ($verified && $verified['header_signed'] && $verified['header_valid'] && ($verified['content_valid'] || (! $verified['content_signed']))) { - logger('OWA header: ' . print_r($verified,true),LOGGER_DATA); - logger('OWA success: ' . $hubloc['hubloc_id_url'],LOGGER_DATA); - $ret['success'] = true; - $token = random_string(32); - Verify::create('owt',0,$token,$hubloc['hubloc_id_url']); - $result = ''; - openssl_public_encrypt($token,$result,$hubloc['xchan_pubkey']); - $ret['encrypted_token'] = base64url_encode($result); - break; - } else { - logger('OWA fail: ' . $hubloc['hubloc_id'] . ' ' . $hubloc['hubloc_id_url']); - } - } - if (!$ret['success']) { - - // Possible a reinstall? - // In this case we probably already have an old hubloc - // but not the new one yet. - - $found = discover_by_webbie($keyId); - - if ($found) { - $r = q("SELECT * FROM hubloc LEFT JOIN xchan ON hubloc_hash = xchan_hash - WHERE (hubloc_addr = '%s' OR hubloc_id_url = '%s') AND hubloc_deleted = 0 ORDER BY hubloc_id DESC LIMIT 1", - dbesc(str_replace('acct:', '', $keyId)), - dbesc($keyId) - ); - - if ($r) { - $verified = HTTPSig::verify(file_get_contents('php://input'), $r[0]['xchan_pubkey']); - if ($verified && $verified['header_signed'] && $verified['header_valid'] && ($verified['content_valid'] || (! $verified['content_signed']))) { - logger('OWA header: ' . print_r($verified,true), LOGGER_DATA); - logger('OWA success: ' . $r[0]['hubloc_id_url'], LOGGER_DATA); - $ret['success'] = true; - $token = random_string(32); - Verify::create('owt', 0, $token, $r[0]['hubloc_id_url']); - $result = ''; - openssl_public_encrypt($token, $result, $r[0]['xchan_pubkey']); - $ret['encrypted_token'] = base64url_encode($result); - } else { - logger('OWA fail: ' . $hubloc['hubloc_id'] . ' ' . $hubloc['hubloc_id_url']); - } + if ($r) { + $verified = HTTPSig::verify(file_get_contents('php://input'), $r[0]['xchan_pubkey']); + if ($verified && $verified['header_signed'] && $verified['header_valid'] && ($verified['content_valid'] || (! $verified['content_signed']))) { + logger('OWA header: ' . print_r($verified,true), LOGGER_DATA); + logger('OWA success: ' . $r[0]['hubloc_id_url'], LOGGER_DATA); + $ret['success'] = true; + $token = random_string(32); + Verify::create('owt', 0, $token, $r[0]['hubloc_id_url']); + $result = ''; + openssl_public_encrypt($token, $result, $r[0]['xchan_pubkey']); + $ret['encrypted_token'] = base64url_encode($result); + } else { + logger('OWA fail: ' . $hubloc['hubloc_id'] . ' ' . $hubloc['hubloc_id_url']); } } } @@ -118,4 +119,33 @@ class Owa extends Controller { json_return_and_die($ret,'application/x-zot+json'); } + + private function validateAuthorizationHeader(): bool + { + if (!empty($_SERVER['HTTP_AUTHORIZATION'])) { + $auth = trim($_SERVER['HTTP_AUTHORIZATION']); + } else if (!empty($_SERVER['REDIRECT_REMOTE_USER'])) { + $auth = trim($_SERVER['REDIRECT_REMOTE_USER']); + } else { + return false; + } + + return strncmp($auth, 'Signature', 9) === 0; + } + + /** + * Terminates the request, and return a json error response. + * + * @Note This function does not return! + * + * @param string $msg The error message for the response. + */ + private function error(string $msg): void { + $ret = [ + 'success' => false, + 'message' => $msg + ]; + + json_return_and_die($ret,'application/x-zot+json'); + } } diff --git a/Zotlabs/Module/Photos.php b/Zotlabs/Module/Photos.php index e31aa9dc1..5f6162ba7 100644 --- a/Zotlabs/Module/Photos.php +++ b/Zotlabs/Module/Photos.php @@ -557,7 +557,9 @@ class Photos extends \Zotlabs\Web\Controller { $can_post = false; $visitor = 0; - + $link_item = null; + $like = null; + $dislike = null; $owner_uid = \App::$data['channel']['channel_id']; $owner_aid = \App::$data['channel']['channel_account_id']; @@ -965,7 +967,6 @@ class Photos extends \Zotlabs\Web\Controller { $map = null; if($linked_items) { - xchan_query($linked_items); $linked_items = fetch_post_tags($linked_items,true); @@ -1103,20 +1104,8 @@ class Photos extends \Zotlabs\Web\Controller { $alike = array(); $dlike = array(); - $like = ''; - $dislike = ''; - - $conv_responses = array( - 'like' => array('title' => t('Likes','title')),'dislike' => array('title' => t('Dislikes','title')), - 'attendyes' => array('title' => t('Attending','title')), 'attendno' => array('title' => t('Not attending','title')), 'attendmaybe' => array('title' => t('Might attend','title')) - ); - if($r) { - foreach($r as $item) { - builtin_activity_puller($item, $conv_responses); - } - $like_count = ((x($alike,$link_item['mid'])) ? $alike[$link_item['mid']] : ''); $like_list = ((x($alike,$link_item['mid'])) ? $alike[$link_item['mid'] . '-l'] : ''); @@ -1217,12 +1206,17 @@ class Photos extends \Zotlabs\Web\Controller { $like_e = $like; $dislike_e = $dislike; $paginate = paginate(); + $responses = []; - $response_verbs = array('like'); - if(feature_enabled($owner_uid,'dislike')) - $response_verbs[] = 'dislike'; + if ($link_item) { + $response_verbs = ['like']; - $responses = get_responses($conv_responses,$response_verbs,'',$link_item); + if(feature_enabled($owner_uid,'dislike')) { + $response_verbs[] = 'dislike'; + } + + $responses = get_responses($response_verbs, $link_item); + } $hookdata = [ 'onclick' => '$.colorbox({href: \'' . $photo['href'] . '\'}); return false;', diff --git a/Zotlabs/Module/Pin.php b/Zotlabs/Module/Pin.php index de3c75622..14a45c10d 100644 --- a/Zotlabs/Module/Pin.php +++ b/Zotlabs/Module/Pin.php @@ -29,8 +29,9 @@ class Pin extends \Zotlabs\Web\Controller { if(! $observer) http_status_exit(403, 'Forbidden'); - $r = q("SELECT * FROM item WHERE id = %d AND id = parent AND item_private = 0 LIMIT 1", - $item_id + $r = q("SELECT * FROM item WHERE id = %d AND uid = %d AND id = parent AND item_private = 0 LIMIT 1", + intval($item_id), + intval(local_channel()) ); if(! $r) { notice(t('Unable to locate original post.')); diff --git a/Zotlabs/Module/Pubstream.php b/Zotlabs/Module/Pubstream.php index 6d8edf4d8..99b8ab587 100644 --- a/Zotlabs/Module/Pubstream.php +++ b/Zotlabs/Module/Pubstream.php @@ -183,6 +183,7 @@ class Pubstream extends \Zotlabs\Web\Controller { $sql_extra .= protect_sprintf(term_query('item', $hashtags, TERM_HASHTAG, TERM_COMMUNITYTAG)); $sql_extra_order = " ORDER BY item.created DESC "; $thread_top = ''; + } $net_query2 = (($net) ? " and xchan_network = '" . protect_sprintf(dbesc($net)) . "' " : ''); @@ -196,17 +197,15 @@ class Pubstream extends \Zotlabs\Web\Controller { if($update) { - $ordering = Config::Get('system', 'pubstream_ordering', 'commented'); + $ordering = Config::Get('system', 'pubstream_ordering', 'created'); if($load) { if($mid) { $r = q("SELECT parent AS item_id FROM item left join abook on item.author_xchan = abook.abook_xchan - left join xchan on item.author_xchan = xchan.xchan_hash WHERE item.$identifier = '%s' and item.item_private = 0 $uids $site_firehose_sql $item_normal - and xchan.xchan_censored = 0 and (abook.abook_blocked = 0 or abook.abook_flags is null) $sql_extra $net_query2", dbesc($mid) @@ -216,11 +215,9 @@ class Pubstream extends \Zotlabs\Web\Controller { // Fetch a page full of parent items for this page $r = dbq("SELECT parent AS item_id FROM item left join abook on ( item.author_xchan = abook.abook_xchan $abook_uids ) - left join xchan on item.author_xchan = xchan.xchan_hash WHERE item.item_private = 0 $thread_top $uids $site_firehose_sql $item_normal - and xchan.xchan_censored = 0 and (abook.abook_blocked = 0 or abook.abook_flags is null) $sql_extra $net_query2 ORDER BY $ordering DESC $pager_sql " @@ -231,10 +228,8 @@ class Pubstream extends \Zotlabs\Web\Controller { if($mid) { $r = q("SELECT parent AS item_id FROM item left join abook on item.author_xchan = abook.abook_xchan - left join xchan on item.author_xchan = xchan.xchan_hash WHERE item.$identifier = '%s' and item.item_private = 0 $uids $site_firehose_sql $item_normal_update $simple_update - and xchan.xchan_censored = 0 and (abook.abook_blocked = 0 or abook.abook_flags is null) $sql_extra $net_query2", dbesc($mid) @@ -243,11 +238,9 @@ class Pubstream extends \Zotlabs\Web\Controller { else { $r = dbq("SELECT parent AS item_id FROM item left join abook on item.author_xchan = abook.abook_xchan - left join xchan on item.author_xchan = xchan.xchan_hash WHERE item.item_private = 0 $thread_top $uids $site_firehose_sql $item_normal_update $simple_update - and xchan.xchan_censored = 0 and (abook.abook_blocked = 0 or abook.abook_flags is null) $sql_extra $net_query2" ); @@ -258,15 +251,7 @@ class Pubstream extends \Zotlabs\Web\Controller { $parents_str = ''; if($r) { - - $parents_str = ids_to_querystr($r,'item_id'); - - $items = dbq("SELECT item.*, item.id AS item_id FROM item - WHERE true $uids $item_normal - AND item.parent IN ( $parents_str ) - $sql_extra $sql_extra_order" - ); - + $items = items_by_parent_ids($r); // use effective_uid param of xchan_query to help sort out comment permission // for sys_channel owned items. diff --git a/Zotlabs/Module/Regate.php b/Zotlabs/Module/Regate.php index c67f45a88..956c5e2ea 100644 --- a/Zotlabs/Module/Regate.php +++ b/Zotlabs/Module/Regate.php @@ -375,7 +375,7 @@ class Regate extends \Zotlabs\Web\Controller { ]); $reonar = json_decode( $r['reg_stuff'], true); - $reonar['deny'] = $now . ',' . $ip . ' ' . $did2 . ' ' . $msg; + $reonar['deny'] = $now . ',' . $ip . ' ' . $did2; $flags = ( $r['reg_flags'] &= ( $r['reg_flags'] ^ ACCOUNT_UNVERIFIED) ) | ( $r['reg_flags'] |= REGISTER_DENIED); $rd = q("UPDATE register SET reg_stuff='%s', reg_vital=0, reg_flags=%d WHERE reg_id = %d ", @@ -456,7 +456,7 @@ class Regate extends \Zotlabs\Web\Controller { // $log = ' from § ' . $ip . ' §' . ' (' . dbesc($did2) . ')'; zar_log($msg); $o = replace_macros(get_markup_template('plain.tpl'), [ - '$title' => $title, + '$title' => $msg, '$now' => $nowfmt, '$infos' => $msg ]); diff --git a/Zotlabs/Module/Request.php b/Zotlabs/Module/Request.php new file mode 100644 index 000000000..439f56282 --- /dev/null +++ b/Zotlabs/Module/Request.php @@ -0,0 +1,89 @@ +<?php +namespace Zotlabs\Module; + +use Zotlabs\Web\Controller; + +class Request extends Controller +{ + + private function mapVerb(string $verb) : string + { + $verbs = [ + 'like' => 'Like', + 'dislike' => 'Dislike', + 'announce' => 'Announce', + 'accept' => 'Accept', + 'reject' => 'Reject', + 'tentativeaccept' => 'TentativeAccept' + ]; + + if (array_key_exists($verb, $verbs)) { + return $verbs[$verb]; + } + + return EMPTY_STR; + } + + + private function processSubthreadRequest() : string + { + $mid = $_GET['mid']; + $parent = intval($_GET['parent']); + + $offset = null; + if ($_GET['verb'] === 'load') { + $offset = intval($_GET['offset']); + } + + $module = strip_tags($_GET['module']); + + $items = items_by_thr_parent($mid, $parent, $offset); + xchan_query($items); + + $items = fetch_post_tags($items,true); + + if ($module === 'channel') { + $parts = explode('@', $items[0]['owner']['xchan_addr']); + profile_load($parts[0]); + } + + $ret['html'] = conversation($items, $module, true, 'r_preview'); + + json_return_and_die($ret); + } + + public function get() : string + { + + if (in_array($_GET['verb'], ['comment', 'load'])) { + return self::processSubthreadRequest(); + } + + $verb = self::mapVerb($_GET['verb']); + + if (!$verb) { + killme(); + } + + $text = get_response_button_text($_GET['verb']); + $mid = strip_tags($_GET['mid']); + $parent = intval($_GET['parent']); + $observer_hash = get_observer_hash(); + + $ret['result'] = item_activity_xchans($mid, $parent, $verb); + + $commentable = $ret['result']['is_commentable']; + unset($ret['result']['is_commentable']); + + if ($commentable) { + $ret['action'] = (($verb === 'Announce') ? 'jotShare' : 'dolike'); + $ret['action_label'] = ((find_xchan_in_array($observer_hash, $ret['result'])) ? (($verb === 'Announce') ? t('+ Repeat again') : t('- Remove yours')) : t('+ Add yours')); + } + + $ret['title'] = $text['label']; + + json_return_and_die($ret); + + } + +} diff --git a/Zotlabs/Module/Settings/Display.php b/Zotlabs/Module/Settings/Display.php index a7fccea47..98c3d7543 100644 --- a/Zotlabs/Module/Settings/Display.php +++ b/Zotlabs/Module/Settings/Display.php @@ -24,7 +24,7 @@ class Display { $theme = 'redbasic'; - $preload_images = ((x($_POST,'preload_images')) ? intval($_POST['preload_images']) : 0); + $thread_allow = ((!empty($_POST['thread_allow'])) ? intval($_POST['thread_allow']) : 0); $user_scalable = ((x($_POST,'user_scalable')) ? intval($_POST['user_scalable']) : 0); $nosmile = ((x($_POST,'nosmile')) ? intval($_POST['nosmile']) : 0); $title_tosource = ((x($_POST,'title_tosource')) ? intval($_POST['title_tosource']) : 0); @@ -40,7 +40,7 @@ class Display { $itemspage = 30; - set_pconfig(local_channel(),'system','preload_images',$preload_images); + set_pconfig(local_channel(), 'system', 'thread_allow', $thread_allow); set_pconfig(local_channel(),'system','user_scalable',$user_scalable); set_pconfig(local_channel(),'system','update_interval', $browser_update); set_pconfig(local_channel(),'system','itemspage', $itemspage); @@ -146,8 +146,7 @@ class Display { $start_menu = get_pconfig(local_channel(), 'system', 'start_menu', 0); } - $preload_images = get_pconfig(local_channel(),'system','preload_images'); - $preload_images = (($preload_images===false)? '0': $preload_images); // default if not set: 0 + $thread_allow = get_pconfig(local_channel(), 'system', 'thread_allow', true); $user_scalable = get_pconfig(local_channel(),'system','user_scalable'); $user_scalable = (($user_scalable===false)? '0': $user_scalable); // default if not set: 0 @@ -192,7 +191,7 @@ class Display { '$theme' => (($themes) ? array('theme', t('Display Theme:'), $theme_selected, '', $themes, 'preview') : false), '$schema' => (($schemas) ? array('schema', t('Select scheme'), $existing_schema, '' , $schemas) : false), - '$preload_images' => array('preload_images', t("Preload images before rendering the page"), $preload_images, t("The subjective page load time will be longer but the page will be ready when displayed"), $yes_no), + '$thread_allow' => ['thread_allow', t('Threaded conversation view'), $thread_allow, t('Display replies below their parent message (default yes)'), $yes_no], '$user_scalable' => array('user_scalable', t("Enable user zoom on mobile devices"), $user_scalable, '', $yes_no), '$ajaxint' => array('browser_update', t("Update browser every xx seconds"), $browser_update, t('Minimum of 10 seconds, no maximum')), '$itemspage' => array('itemspage', t("Maximum number of conversations to load at any time:"), $itemspage, t('Maximum of 30 items')), diff --git a/Zotlabs/Module/Sse.php b/Zotlabs/Module/Sse.php index fda2f2be4..673457db1 100644 --- a/Zotlabs/Module/Sse.php +++ b/Zotlabs/Module/Sse.php @@ -207,10 +207,9 @@ class Sse extends Controller { if ($result) { XConfig::Set(self::$ob_hash, 'sse', 'notifications', []); - json_return_and_die($result); } - killme(); + json_return_and_die($result); } diff --git a/Zotlabs/Module/Sse_bs.php b/Zotlabs/Module/Sse_bs.php index 09c4ed614..c457363c0 100644 --- a/Zotlabs/Module/Sse_bs.php +++ b/Zotlabs/Module/Sse_bs.php @@ -22,7 +22,6 @@ class Sse_bs extends Controller { public static $xchans; function init() { - self::$uid = local_channel(); self::$ob_hash = get_observer_hash(); self::$sse_id = false; @@ -43,8 +42,9 @@ class Sse_bs extends Controller { self::$offset = 0; self::$xchans = ''; - if(isset($_REQUEST['sse_rmids'])) - self::mark_read($_REQUEST['sse_rmids']); + if (!empty($_REQUEST['sse_rmids'])) { + self::mark_read(explode(',', $_REQUEST['sse_rmids'])); + } if(!empty($_REQUEST['nquery']) && $_REQUEST['nquery'] !== '%') { $nquery = $_REQUEST['nquery']; @@ -118,7 +118,6 @@ class Sse_bs extends Controller { } function mark_read($arr) { - $mids = []; $str = ''; $slice = 0; @@ -142,24 +141,51 @@ class Sse_bs extends Controller { } } - $_SESSION['sse_mids_all'] = serialise($mids_all); + $str = implode(',', $mids); + + $sys = get_sys_channel(); + $sql_order = ((self::$uid > $sys['channel_id']) ? 'DESC' : 'ASC'); + + $r = q("SELECT uid, uuid FROM item + WHERE uid in (%d, %d) + AND verb IN ('Like', 'Dislike', 'Announce', 'Accept', 'Reject', 'TentativeAccept') + AND thr_parent IN ( + SELECT mid FROM item WHERE uid IN (%d, %d) AND uuid IN (%s) ORDER BY uid $sql_order + ) + GROUP BY uid, uuid + ORDER BY uid $sql_order", + intval(self::$uid), + intval($sys['channel_id']), + intval(self::$uid), + intval($sys['channel_id']), + $str // this is dbesc() in the above foreach loop + ); + + if ($r) { + $activities_str = ids_to_querystr($r, 'uuid', true); + $str .= ',' . $activities_str; + $activities_arr = explode(',', $activities_str); + $mids_all = array_merge($mids_all, $activities_arr); + } + + $_SESSION['sse_mids_all'] = serialise(array_unique($mids_all)); if(! self::$uid) { return; } - $str = implode(',', $mids); - $x = [ 'channel_id' => self::$uid, 'update' => 'unset' ]; call_hooks('update_unseen',$x); - if($x['update'] === 'unset' || intval($x['update'])) { - q("UPDATE item SET item_unseen = 0 WHERE uid = %d AND uuid in (%s) AND item_unseen = 1", + if ($x['update'] === 'unset' || intval($x['update'])) { + q("UPDATE item SET item_unseen = 0 + WHERE uid = %d + AND uuid in (%s) + AND item_unseen = 1", intval(self::$uid), $str // this is dbesc() in the above foreach loop ); } - } function bs_network($notifications) { @@ -182,32 +208,34 @@ class Sse_bs extends Controller { $sql_extra = ''; if (!(self::$vnotify & VNOTIFY_LIKE)) { - $sql_extra = " AND verb NOT IN ('Like', 'Dislike', '" . dbesc(ACTIVITY_LIKE) . "', '" . dbesc(ACTIVITY_DISLIKE) . "') "; + $sql_extra = " AND item.verb NOT IN ('Like', 'Dislike', '" . dbesc(ACTIVITY_LIKE) . "', '" . dbesc(ACTIVITY_DISLIKE) . "') "; } elseif (!feature_enabled(self::$uid, 'dislike')) { - $sql_extra = " AND verb NOT IN ('Dislike', '" . dbesc(ACTIVITY_DISLIKE) . "') "; + $sql_extra = " AND item.verb NOT IN ('Dislike', '" . dbesc(ACTIVITY_DISLIKE) . "') "; } $sql_extra2 = ''; if(self::$xchans) - $sql_extra2 = " AND CASE WHEN verb = '" . dbesc(ACTIVITY_SHARE) . "' THEN owner_xchan ELSE author_xchan END IN (" . self::$xchans . ") "; + $sql_extra2 = " AND CASE WHEN item.verb = '" . dbesc(ACTIVITY_SHARE) . "' THEN item.owner_xchan ELSE item.author_xchan END IN (" . self::$xchans . ") "; $item_normal = item_normal(); // Filter internal follow activities and strerams add/remove activities - $item_normal .= " AND verb NOT IN ('Add', 'Remove', 'Follow', 'Ignore', '" . dbesc(ACTIVITY_FOLLOW) . "') "; + $item_normal .= " AND item.verb NOT IN ('Add', 'Remove', 'Follow', 'Ignore', '" . dbesc(ACTIVITY_FOLLOW) . "') "; if ($notifications) { - $items = q("SELECT * FROM item - WHERE uid = %d - AND created <= '%s' - AND item_unseen = 1 AND item_wall = 0 AND item_private IN (0, 1) - AND obj_type NOT IN ('Document', 'Video', 'Audio', 'Image') - AND author_xchan != '%s' + $items = q("SELECT item.*, tp.uuid AS thr_parent_uuid FROM item + LEFT JOIN item tp ON item.thr_parent = tp.mid AND item.uid = tp.uid + WHERE item.uid = %d + AND item.created <= '%s' + AND item.item_unseen = 1 AND item.item_wall = 0 AND item.item_private IN (0, 1) + AND item.obj_type NOT IN ('Document', 'Video', 'Audio', 'Image') + AND NOT (item.verb = 'Announce' AND item.item_thread_top = 1) -- only show the announce activity and not the resulting item + AND NOT item.author_xchan = '%s' $item_normal $sql_extra $sql_extra2 - ORDER BY created DESC LIMIT $limit OFFSET $offset", + ORDER BY item.created DESC LIMIT $limit OFFSET $offset", intval(self::$uid), dbescdate($_SESSION['sse_loadtime']), dbesc(self::$ob_hash) @@ -265,28 +293,30 @@ class Sse_bs extends Controller { $sql_extra = ''; if (!(self::$vnotify & VNOTIFY_LIKE)) { - $sql_extra = " AND verb NOT IN ('Like', 'Dislike', '" . dbesc(ACTIVITY_LIKE) . "', '" . dbesc(ACTIVITY_DISLIKE) . "') "; + $sql_extra = " AND item.verb NOT IN ('Like', 'Dislike', '" . dbesc(ACTIVITY_LIKE) . "', '" . dbesc(ACTIVITY_DISLIKE) . "') "; } elseif (!feature_enabled(self::$uid, 'dislike')) { - $sql_extra = " AND verb NOT IN ('Dislike', '" . dbesc(ACTIVITY_DISLIKE) . "') "; + $sql_extra = " AND item.verb NOT IN ('Dislike', '" . dbesc(ACTIVITY_DISLIKE) . "') "; } $sql_extra2 = ''; if(self::$xchans) - $sql_extra2 = " AND CASE WHEN verb = '" . ACTIVITY_SHARE . "' THEN owner_xchan ELSE author_xchan END IN (" . self::$xchans . ") "; + $sql_extra2 = " AND CASE WHEN item.verb = '" . ACTIVITY_SHARE . "' THEN item.owner_xchan ELSE item.author_xchan END IN (" . self::$xchans . ") "; $item_normal = item_normal(); // Filter internal follow activities and strerams add/remove activities - $item_normal .= " AND verb NOT IN ('Add', 'Remove', 'Follow', 'Ignore', '" . dbesc(ACTIVITY_FOLLOW) . "') "; + $item_normal .= " AND item.verb NOT IN ('Add', 'Remove', 'Follow', 'Ignore', '" . dbesc(ACTIVITY_FOLLOW) . "') "; if ($notifications) { - $items = q("SELECT * FROM item - WHERE uid = %d - AND created <= '%s' - AND item_unseen = 1 AND item_private = 2 - AND obj_type NOT IN ('Document', 'Video', 'Audio', 'Image') - AND author_xchan != '%s' + $items = q("SELECT item.*, tp.uuid AS thr_parent_uuid FROM item + LEFT JOIN item tp ON item.thr_parent = tp.mid AND item.uid = tp.uid + WHERE item.uid = %d + AND item.created <= '%s' + AND item.item_unseen = 1 AND item.item_private = 2 + AND item.obj_type NOT IN ('Document', 'Video', 'Audio', 'Image') + AND NOT (item.verb = 'Announce' AND item.item_thread_top = 1) -- only show the announce activity and not the resulting item + AND NOT item.author_xchan = '%s' $item_normal $sql_extra $sql_extra2 @@ -347,33 +377,35 @@ class Sse_bs extends Controller { $sql_extra = ''; if (!(self::$vnotify & VNOTIFY_LIKE)) { - $sql_extra = " AND verb NOT IN ('Like', 'Dislike', '" . dbesc(ACTIVITY_LIKE) . "', '" . dbesc(ACTIVITY_DISLIKE) . "') "; + $sql_extra = " AND item.verb NOT IN ('Like', 'Dislike', '" . dbesc(ACTIVITY_LIKE) . "', '" . dbesc(ACTIVITY_DISLIKE) . "') "; } elseif (!feature_enabled(self::$uid, 'dislike')) { - $sql_extra = " AND verb NOT IN ('Dislike', '" . dbesc(ACTIVITY_DISLIKE) . "') "; + $sql_extra = " AND item.verb NOT IN ('Dislike', '" . dbesc(ACTIVITY_DISLIKE) . "') "; } $sql_extra2 = ''; if(self::$xchans) - $sql_extra2 = " AND CASE WHEN verb = '" . ACTIVITY_SHARE . "' THEN owner_xchan ELSE author_xchan END IN (" . self::$xchans . ") "; + $sql_extra2 = " AND CASE WHEN item.verb = '" . ACTIVITY_SHARE . "' THEN item.owner_xchan ELSE item.author_xchan END IN (" . self::$xchans . ") "; $item_normal = item_normal(); // Filter internal follow activities and strerams add/remove activities - $item_normal .= " AND verb NOT IN ('Add', 'Remove', 'Follow', 'Ignore', '" . dbesc(ACTIVITY_FOLLOW) . "') "; + $item_normal .= " AND item.verb NOT IN ('Add', 'Remove', 'Follow', 'Ignore', '" . dbesc(ACTIVITY_FOLLOW) . "') "; if ($notifications) { - $items = q("SELECT * FROM item - WHERE uid = %d - AND created <= '%s' - AND item_unseen = 1 AND item_wall = 1 AND item_private IN (0, 1) - AND obj_type NOT IN ('Document', 'Video', 'Audio', 'Image') - AND author_xchan != '%s' + $items = q("SELECT item.*, tp.uuid AS thr_parent_uuid FROM item + LEFT JOIN item tp ON item.thr_parent = tp.mid AND item.uid = tp.uid + WHERE item.uid = %d + AND item.created <= '%s' + AND item.item_unseen = 1 AND item.item_wall = 1 AND item.item_private IN (0, 1) + AND item.obj_type NOT IN ('Document', 'Video', 'Audio', 'Image') + AND NOT (item.verb = 'Announce' AND item.item_thread_top = 1) -- only show the announce activity and not the resulting item + AND NOT item.author_xchan = '%s' $item_normal $sql_extra $sql_extra2 - ORDER BY created DESC LIMIT $limit OFFSET $offset", + ORDER BY item.created DESC LIMIT $limit OFFSET $offset", intval(self::$uid), dbescdate($_SESSION['sse_loadtime']), dbesc(self::$ob_hash) @@ -442,49 +474,51 @@ class Sse_bs extends Controller { $sys = get_sys_channel(); $sql_extra = ''; if (!(self::$vnotify & VNOTIFY_LIKE)) { - $sql_extra = " AND verb NOT IN ('Like', 'Dislike', '" . dbesc(ACTIVITY_LIKE) . "', '" . dbesc(ACTIVITY_DISLIKE) . "') "; + $sql_extra = " AND item.verb NOT IN ('Like', 'Dislike', '" . dbesc(ACTIVITY_LIKE) . "', '" . dbesc(ACTIVITY_DISLIKE) . "') "; } elseif (!feature_enabled(self::$uid, 'dislike')) { - $sql_extra = " AND verb NOT IN ('Dislike', '" . dbesc(ACTIVITY_DISLIKE) . "') "; + $sql_extra = " AND item.verb NOT IN ('Dislike', '" . dbesc(ACTIVITY_DISLIKE) . "') "; } $sql_extra2 = ''; if(self::$xchans) - $sql_extra2 = " AND CASE WHEN verb = '" . ACTIVITY_SHARE . "' THEN owner_xchan ELSE author_xchan END IN (" . self::$xchans . ") "; + $sql_extra2 = " AND CASE WHEN item.verb = '" . ACTIVITY_SHARE . "' THEN item.owner_xchan ELSE item.author_xchan END IN (" . self::$xchans . ") "; $sql_extra3 = ''; - $sse_mids_all = unserialise($_SESSION['sse_mids_all']) ?? []; + $sse_mids_all = isset($_SESSION['sse_mids_all']) ? unserialise($_SESSION['sse_mids_all']) : []; if ($sse_mids_all) { - $sql_extra3 = " AND uuid NOT IN (" . protect_sprintf(implode(',', $sse_mids_all)) . ") "; + $sql_extra3 = " AND item.uuid NOT IN (" . protect_sprintf(implode(',', $sse_mids_all)) . ") "; } - $uids = " AND uid IN ( " . $sys['channel_id'] . " ) "; + $uids = " AND item.uid IN ( " . $sys['channel_id'] . " ) "; $site_firehose = Config::Get('system', 'site_firehose', 0); if($site_firehose) { - $uids = " AND uid IN ( " . stream_perms_api_uids(PERMS_PUBLIC) . " ) AND item_private = 0 AND item_wall = 1 "; + $uids = " AND item.uid IN ( " . stream_perms_api_uids(PERMS_PUBLIC) . " ) AND item.item_private = 0 AND item.item_wall = 1 "; } $item_normal = item_normal(); // Filter internal follow activities and strerams add/remove activities - $item_normal .= " AND verb NOT IN ('Add', 'Remove', 'Follow', 'Ignore', '" . dbesc(ACTIVITY_FOLLOW) . "') "; + $item_normal .= " AND item.verb NOT IN ('Add', 'Remove', 'Follow', 'Ignore', '" . dbesc(ACTIVITY_FOLLOW) . "') "; if ($notifications) { - $items = q("SELECT * FROM item + $items = q("SELECT item.*, tp.uuid AS thr_parent_uuid FROM item + LEFT JOIN item tp ON item.thr_parent = tp.mid AND item.uid = tp.uid WHERE true $uids - AND created <= '%s' - AND obj_type NOT IN ('Document', 'Video', 'Audio', 'Image') - AND author_xchan != '%s' - AND created > '%s' + AND item.created <= '%s' + AND item.created > '%s' + AND item.obj_type NOT IN ('Document', 'Video', 'Audio', 'Image') + AND NOT (item.verb = 'Announce' AND item.item_thread_top = 1) -- only show the announce activity not the resulting item + AND NOT item.author_xchan = '%s' $item_normal $sql_extra $sql_extra2 $sql_extra3 - ORDER BY created DESC LIMIT $limit OFFSET $offset", + ORDER BY item.created DESC LIMIT $limit OFFSET $offset", dbescdate($_SESSION['sse_loadtime']), - dbesc(self::$ob_hash), - dbescdate($_SESSION['last_login_date'] ?? $_SESSION['static_loadtime']) + dbescdate($_SESSION['last_login_date'] ?? $_SESSION['static_loadtime']), + dbesc(self::$ob_hash) ); if($items) { @@ -502,13 +536,15 @@ class Sse_bs extends Controller { } } - $r = q("SELECT id FROM item + $r = q("SELECT id, body FROM item WHERE true $uids + AND created <= '%s' AND created > '%s' $item_normal $sql_extra $sql_extra3 AND author_xchan != '%s' LIMIT 100", + dbescdate($_SESSION['sse_loadtime']), dbescdate($_SESSION['last_login_date'] ?? $_SESSION['static_loadtime']), dbesc(self::$ob_hash) ); @@ -600,25 +636,15 @@ class Sse_bs extends Controller { $i = 0; for($x = 0; $x < $fcount; $x ++) { - /* - $p = q("SELECT oid AS parent FROM term WHERE uid = %d AND ttype = %d AND term = '%s'", - intval(self::$uid), - intval(TERM_FORUM), - dbesc($forums[$x]['xchan_name']) - ); - - $p_str = ids_to_querystr($p, 'parent'); - $p_sql = (($p_str) ? "OR parent IN ( $p_str )" : ''); - */ $r = q("select count(*) as total from item - where uid = %d and ( owner_xchan = '%s' OR author_xchan = '%s' $p_sql ) and verb != 'Announce' and item_unseen = 1 $sql_extra $item_normal", + where uid = %d and (owner_xchan = '%s' or author_xchan = '%s') and author_xchan != '%s' and verb != 'Announce' and item_unseen = 1 $sql_extra $item_normal", intval(self::$uid), dbesc($forums[$x]['xchan_hash']), - dbesc($forums[$x]['xchan_hash']) + dbesc($forums[$x]['xchan_hash']), + dbesc(self::$ob_hash) ); - if($r[0]['total']) { $forums[$x]['notify_link'] = z_root() . '/network/?f=&pf=1&unseen=1&cid=' . $forums[$x]['abook_id']; diff --git a/Zotlabs/Module/Viewsrc.php b/Zotlabs/Module/Viewsrc.php index 3e49b9db4..cfc184a9d 100644 --- a/Zotlabs/Module/Viewsrc.php +++ b/Zotlabs/Module/Viewsrc.php @@ -6,34 +6,34 @@ namespace Zotlabs\Module; class Viewsrc extends \Zotlabs\Web\Controller { function get() { - + $o = ''; - + $sys = get_sys_channel(); - + $item_id = ((argc() > 1) ? intval(argv(1)) : 0); $json = ((argc() > 2 && argv(2) === 'json') ? true : false); $dload = ((argc() > 2 && argv(2) === 'download') ? true : false); - + if(! local_channel()) { notice( t('Permission denied.') . EOL); } - - + + if(! $item_id) { \App::$error = 404; notice( t('Item not found.') . EOL); } - + $item_normal = item_normal_search(); - + if(local_channel() && $item_id) { - $r = q("select id, mid, item_flags, mimetype, item_obscured, body, llink, plink from item where uid in (%d , %d) and id = %d $item_normal limit 1", + $r = q("select id, mid, uuid, item_flags, mimetype, item_obscured, body, llink, plink from item where uid in (%d , %d) and id = %d $item_normal limit 1", intval(local_channel()), intval($sys['channel_id']), intval($item_id) ); - + if($r) { if(intval($r[0]['item_obscured'])) $dload = true; @@ -50,18 +50,18 @@ class Viewsrc extends \Zotlabs\Web\Controller { $o = (($json) ? json_encode($content) : $content); } } - + if(is_ajax()) { echo '<div class="p-1">'; - echo '<div>id: ' . $r[0]['id'] . ' | <a href="' . $r[0]['plink'] . '" target="_blank">plink</a> | <a href="' . $r[0]['llink'] . '" target="_blank">llink</a><br>mid: ' . $r[0]['mid'] . '</div>'; + echo '<div>id: ' . $r[0]['id'] . ' | <a href="' . $r[0]['plink'] . '" target="_blank">plink</a> | <a href="' . $r[0]['llink'] . '" target="_blank">llink</a><br>mid: ' . $r[0]['mid'] . '<br>uuid: ' . $r[0]['uuid'] . '</div>'; echo '<hr>'; echo '<pre class="p-1">' . $o . '</pre>'; echo '</div>'; killme(); - } - + } + return $o; } - - + + } diff --git a/Zotlabs/Module/Wall_attach.php b/Zotlabs/Module/Wall_attach.php index e354f58f1..84c76f8dd 100644 --- a/Zotlabs/Module/Wall_attach.php +++ b/Zotlabs/Module/Wall_attach.php @@ -10,7 +10,7 @@ class Wall_attach extends \Zotlabs\Web\Controller { function init() { logger('request_method: ' . $_SERVER['REQUEST_METHOD'],LOGGER_DATA,LOG_INFO); - logger('wall_attach: ' . print_r($_REQUEST,true),LOGGER_DEBUG,LOG_INFO); + logger('wall_attach: ' . print_r($_POST,true),LOGGER_DEBUG,LOG_INFO); logger('wall_attach files: ' . print_r($_FILES,true),LOGGER_DEBUG,LOG_INFO); // for testing without actually storing anything // http_status_exit(200,'OK'); @@ -18,12 +18,11 @@ class Wall_attach extends \Zotlabs\Web\Controller { function post() { - $using_api = false; $result = []; - if($_REQUEST['api_source'] && array_key_exists('media',$_FILES)) { + if($_POST['api_source'] && array_key_exists('media',$_FILES)) { $using_api = true; } @@ -98,8 +97,8 @@ class Wall_attach extends \Zotlabs\Web\Controller { $r = attach_store($channel, get_observer_hash(), '', $data); - if(! $r['success']) { - notice( $r['message'] . EOL); + if (!$r['success']) { + notice($r['message'] . EOL); killme(); } diff --git a/Zotlabs/Module/Xref.php b/Zotlabs/Module/Xref.php deleted file mode 100644 index e9d494da4..000000000 --- a/Zotlabs/Module/Xref.php +++ /dev/null @@ -1,26 +0,0 @@ -<?php -namespace Zotlabs\Module; - - -class Xref extends \Zotlabs\Web\Controller { - - function init() { - // Sets a referral URL using an xchan directly - // Link format: example.com/xref/[xchan]/[TargetURL] - // Target URL is optional. - // Cookie lasts 24 hours to survive a browser restart. Contains no personal - // information at all - just somebody else's xchan. - $referrer = argv(1); - $expire=time()+60*60*2; - $path = 'xref'; - setcookie($path, $referrer, $expire, "/"); - $url = ''; - - if (argc() > 2) - $url = argv(2); - - goaway (z_root() . '/' . $url); - - } - -} diff --git a/Zotlabs/Module/Zot_probe.php b/Zotlabs/Module/Zot_probe.php index 3eaabdd92..feb51f071 100644 --- a/Zotlabs/Module/Zot_probe.php +++ b/Zotlabs/Module/Zot_probe.php @@ -9,19 +9,29 @@ class Zot_probe extends \Zotlabs\Web\Controller { function get() { + if (!local_channel()) { + return; + } + $addr = $_GET['addr'] ?? ''; $o = '<h3>Zot6 Probe Diagnostic</h3>'; $o .= '<form action="zot_probe" method="get">'; $o .= 'Lookup URI: <input type="text" style="width: 250px;" name="addr" value="' . $addr .'" /><br>'; + $o .= '<input type="checkbox" name="sign" /> Sign request <br>'; $o .= '<input type="submit" name="submit" value="Submit" /></form>'; $o .= '<br /><br />'; if($addr) { - $x = Zotfinger::exec($addr); + $channel = null; + if ($_GET['sign']) { + $channel = get_sys_channel(); + } + + $x = Zotfinger::exec($addr, $channel); $o .= '<pre>' . htmlspecialchars(print_array($x)) . '</pre>'; |