diff options
Diffstat (limited to 'Zotlabs/Module')
87 files changed, 1126 insertions, 1270 deletions
diff --git a/Zotlabs/Module/Achievements.php b/Zotlabs/Module/Achievements.php index 1529448d3..a16294039 100644 --- a/Zotlabs/Module/Achievements.php +++ b/Zotlabs/Module/Achievements.php @@ -8,25 +8,25 @@ class Achievements extends \Zotlabs\Web\Controller { // This doesn't work, so if (! is_developer()) return; - + if(argc() > 1) $which = argv(1); else { notice( t('Requested profile is not available.') . EOL ); return; } - + $profile = 0; - $profile = argv(1); + $profile = argv(1); profile_load($which,$profile); - + $r = q("select channel_id from channel where channel_address = '%s'", dbesc($which) ); if($r) { $owner = intval($r[0]['channel_id']); } - + $observer = \App::get_observer(); $ob_hash = (($observer) ? $observer['xchan_hash'] : ''); $perms = get_all_perms($owner,$ob_hash); @@ -34,60 +34,60 @@ class Achievements extends \Zotlabs\Web\Controller { notice( t('Permission denied.') . EOL); return; } - + $newmembertext = t('Some blurb about what to do when you\'re new here'); - - + + // By default, all badges are false $contactbadge = false; $profilebadge = false; $keywordsbadge = false; - + // Check number of contacts. Award a badge if over 10 - // We'll figure these out on each page load instead of + // We'll figure these out on each page load instead of // writing them to the DB because that will mean one needs // to retain their achievements - eg, you can't add // a bunch of channels just to get your badge, and then // delete them all again. If these become popular or // used in profiles or something, we may need to reconsider // and add a table for this - because this won't scale. - + $r = q("select * from abook where abook_channel = %d", intval($owner) ); - + if (count($r)) $contacts = count($r); // We're checking for 11 to adjust for the abook record for self if ($contacts >= 11) $contactbadge = true; - + // Check if an about field in the profile has been created. - + $r = q("select * from profile where uid = %d and about <> ''", intval($owner) ); - + if ($r) $profilebadge = 1; - + // Check if keywords have been set - + $r = q("select * from profile where uid = %d and keywords <> ''", intval($owner) ); - + if($r) $keywordsbadge = 1; - + return replace_macros(get_markup_template("achievements.tpl"), array( '$newmembertext' => $newmembertext, '$profilebadge' => $profilebadge, '$contactbadge' => $contactbadge, '$keywordsbadge' => $keywordsbadge, - '$channelsbadge' => $channelsbadge + '$channelsbadge' => null, )); - + } - + } diff --git a/Zotlabs/Module/Activity.php b/Zotlabs/Module/Activity.php index 133312e28..85b9f3e7c 100644 --- a/Zotlabs/Module/Activity.php +++ b/Zotlabs/Module/Activity.php @@ -30,7 +30,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 "; $i = null; @@ -191,7 +191,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/Account_edit.php b/Zotlabs/Module/Admin/Account_edit.php index 0300fb10c..35a15133f 100644 --- a/Zotlabs/Module/Admin/Account_edit.php +++ b/Zotlabs/Module/Admin/Account_edit.php @@ -8,6 +8,11 @@ class Account_edit { function post() { + // Validate CSRF token + // + // We terminate with a 403 Forbidden status if the check fails. + check_form_security_token_ForbiddenOnErr('admin_account_edit', 'security'); + $account_id = $_REQUEST['aid']; if(! $account_id) @@ -18,7 +23,7 @@ class Account_edit { if($pass1 && $pass2 && ($pass1 === $pass2)) { $salt = random_string(32); $password_encoded = hash('whirlpool', $salt . $pass1); - $r = q("update account set account_salt = '%s', account_password = '%s', + $r = q("update account set account_salt = '%s', account_password = '%s', account_password_changed = '%s' where account_id = %d", dbesc($salt), dbesc($password_encoded), @@ -34,7 +39,7 @@ class Account_edit { $account_level = 5; $account_language = trim($_REQUEST['account_language']); - $r = q("update account set account_service_class = '%s', account_level = %d, account_language = '%s' + $r = q("update account set account_service_class = '%s', account_level = %d, account_language = '%s' where account_id = %d", dbesc($service_class), intval($account_level), @@ -62,8 +67,8 @@ class Account_edit { return ''; } - $a = replace_macros(get_markup_template('admin_account_edit.tpl'), [ + '$security' => get_form_security_token('admin_account_edit'), '$account' => $x[0], '$title' => t('Account Edit'), '$pass1' => [ 'pass1', t('New Password'), ' ','' ], 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/Admin/Addons.php b/Zotlabs/Module/Admin/Addons.php index b7cfb651c..0cb173e7c 100644 --- a/Zotlabs/Module/Admin/Addons.php +++ b/Zotlabs/Module/Admin/Addons.php @@ -3,9 +3,8 @@ namespace Zotlabs\Module\Admin; use App; -use \Zotlabs\Lib\Config; -use \Zotlabs\Storage\GitRepo; -use \Michelf\MarkdownExtra; +use Zotlabs\Lib\Config; +use Michelf\MarkdownExtra; class Addons { @@ -24,227 +23,6 @@ class Addons { goaway(z_root() . '/admin/addons/' . argv(2) ); } - elseif(argc() > 2) { - switch(argv(2)) { - case 'updaterepo': - if (array_key_exists('repoName', $_REQUEST)) { - $repoName = $_REQUEST['repoName']; - } - else { - json_return_and_die(array('message' => 'No repo name provided.', 'success' => false)); - } - $extendDir = 'store/[data]/git/sys/extend'; - $addonDir = $extendDir . '/addon'; - if (!file_exists($extendDir)) { - if (!mkdir($extendDir, 0770, true)) { - logger('Error creating extend folder: ' . $extendDir); - json_return_and_die(array('message' => 'Error creating extend folder: ' . $extendDir, 'success' => false)); - } - else { - if (!symlink(realpath('extend/addon'), $addonDir)) { - logger('Error creating symlink to addon folder: ' . $addonDir); - json_return_and_die(array('message' => 'Error creating symlink to addon folder: ' . $addonDir, 'success' => false)); - } - } - } - $repoDir = 'store/[data]/git/sys/extend/addon/' . $repoName; - if (!is_dir($repoDir)) { - logger('Repo directory does not exist: ' . $repoDir); - json_return_and_die(array('message' => 'Invalid addon repo.', 'success' => false)); - } - if (!is_writable($repoDir)) { - logger('Repo directory not writable to web server: ' . $repoDir); - json_return_and_die(array('message' => 'Repo directory not writable to web server.', 'success' => false)); - } - $git = new GitRepo('sys', null, false, $repoName, $repoDir); - try { - if ($git->pull()) { - $files = array_diff(scandir($repoDir), array('.', '..')); - foreach ($files as $file) { - if (is_dir($repoDir . '/' . $file) && $file !== '.git') { - $source = '../extend/addon/' . $repoName . '/' . $file; - $target = realpath('addon/') . '/' . $file; - unlink($target); - if (!symlink($source, $target)) { - logger('Error linking addons to /addon'); - json_return_and_die(array('message' => 'Error linking addons to /addon', 'success' => false)); - } - } - } - json_return_and_die(array('message' => 'Repo updated.', 'success' => true)); - } else { - json_return_and_die(array('message' => 'Error updating addon repo.', 'success' => false)); - } - } catch (\PHPGit\Exception\GitException $e) { - json_return_and_die(array('message' => 'Error updating addon repo.', 'success' => false)); - } - break; - case 'removerepo': - if (array_key_exists('repoName', $_REQUEST)) { - $repoName = $_REQUEST['repoName']; - } else { - json_return_and_die(array('message' => 'No repo name provided.', 'success' => false)); - } - $extendDir = 'store/[data]/git/sys/extend'; - $addonDir = $extendDir . '/addon'; - if (!file_exists($extendDir)) { - if (!mkdir($extendDir, 0770, true)) { - logger('Error creating extend folder: ' . $extendDir); - json_return_and_die(array('message' => 'Error creating extend folder: ' . $extendDir, 'success' => false)); - } else { - if (!symlink(realpath('extend/addon'), $addonDir)) { - logger('Error creating symlink to addon folder: ' . $addonDir); - json_return_and_die(array('message' => 'Error creating symlink to addon folder: ' . $addonDir, 'success' => false)); - } - } - } - $repoDir = 'store/[data]/git/sys/extend/addon/' . $repoName; - if (!is_dir($repoDir)) { - logger('Repo directory does not exist: ' . $repoDir); - json_return_and_die(array('message' => 'Invalid addon repo.', 'success' => false)); - } - if (!is_writable($repoDir)) { - logger('Repo directory not writable to web server: ' . $repoDir); - json_return_and_die(array('message' => 'Repo directory not writable to web server.', 'success' => false)); - } - /// @TODO remove directory and unlink /addon/files - if (rrmdir($repoDir)) { - json_return_and_die(array('message' => 'Repo deleted.', 'success' => true)); - } else { - json_return_and_die(array('message' => 'Error deleting addon repo.', 'success' => false)); - } - break; - case 'installrepo': - if (array_key_exists('repoURL', $_REQUEST)) { - require_once('library/PHPGit.autoload.php'); // Load PHPGit dependencies - $repoURL = $_REQUEST['repoURL']; - $extendDir = 'store/[data]/git/sys/extend'; - $addonDir = $extendDir . '/addon'; - if (!file_exists($extendDir)) { - if (!mkdir($extendDir, 0770, true)) { - logger('Error creating extend folder: ' . $extendDir); - json_return_and_die(array('message' => 'Error creating extend folder: ' . $extendDir, 'success' => false)); - } else { - if (!symlink(realpath('extend/addon'), $addonDir)) { - logger('Error creating symlink to addon folder: ' . $addonDir); - json_return_and_die(array('message' => 'Error creating symlink to addon folder: ' . $addonDir, 'success' => false)); - } - } - } - if (!is_writable($extendDir)) { - logger('Directory not writable to web server: ' . $extendDir); - json_return_and_die(array('message' => 'Directory not writable to web server.', 'success' => false)); - } - $repoName = null; - if (array_key_exists('repoName', $_REQUEST) && $_REQUEST['repoName'] !== '') { - $repoName = $_REQUEST['repoName']; - } else { - $repoName = GitRepo::getRepoNameFromURL($repoURL); - } - if (!$repoName) { - logger('Invalid git repo'); - json_return_and_die(array('message' => 'Invalid git repo', 'success' => false)); - } - $repoDir = $addonDir . '/' . $repoName; - $tempRepoBaseDir = 'store/[data]/git/sys/temp/'; - $tempAddonDir = $tempRepoBaseDir . $repoName; - - if (!is_writable($addonDir) || !is_writable($tempAddonDir)) { - logger('Temp repo directory or /extend/addon not writable to web server: ' . $tempAddonDir); - json_return_and_die(array('message' => 'Temp repo directory not writable to web server.', 'success' => false)); - } - rename($tempAddonDir, $repoDir); - - if (!is_writable(realpath('addon/'))) { - logger('/addon directory not writable to web server: ' . $tempAddonDir); - json_return_and_die(array('message' => '/addon directory not writable to web server.', 'success' => false)); - } - $files = array_diff(scandir($repoDir), array('.', '..')); - foreach ($files as $file) { - if (is_dir($repoDir . '/' . $file) && $file !== '.git') { - $source = '../extend/addon/' . $repoName . '/' . $file; - $target = realpath('addon/') . '/' . $file; - unlink($target); - if (!symlink($source, $target)) { - logger('Error linking addons to /addon'); - json_return_and_die(array('message' => 'Error linking addons to /addon', 'success' => false)); - } - } - } - $git = new GitRepo('sys', $repoURL, false, $repoName, $repoDir); - $repo = $git->probeRepo(); - json_return_and_die(array('repo' => $repo, 'message' => '', 'success' => true)); - } - break; - case 'addrepo': - if (array_key_exists('repoURL', $_REQUEST)) { - require_once('library/PHPGit.autoload.php'); // Load PHPGit dependencies - $repoURL = $_REQUEST['repoURL']; - $extendDir = 'store/[data]/git/sys/extend'; - $addonDir = $extendDir . '/addon'; - $tempAddonDir = realpath('store/[data]') . '/git/sys/temp'; - if (!file_exists($extendDir)) { - if (!mkdir($extendDir, 0770, true)) { - logger('Error creating extend folder: ' . $extendDir); - json_return_and_die(array('message' => 'Error creating extend folder: ' . $extendDir, 'success' => false)); - } else { - if (!symlink(realpath('extend/addon'), $addonDir)) { - logger('Error creating symlink to addon folder: ' . $addonDir); - json_return_and_die(array('message' => 'Error creating symlink to addon folder: ' . $addonDir, 'success' => false)); - } - } - } - if (!is_dir($tempAddonDir)) { - if (!mkdir($tempAddonDir, 0770, true)) { - logger('Error creating temp plugin repo folder: ' . $tempAddonDir); - json_return_and_die(array('message' => 'Error creating temp plugin repo folder: ' . $tempAddonDir, 'success' => false)); - } - } - $repoName = null; - if (array_key_exists('repoName', $_REQUEST) && $_REQUEST['repoName'] !== '') { - $repoName = $_REQUEST['repoName']; - } else { - $repoName = GitRepo::getRepoNameFromURL($repoURL); - } - if (!$repoName) { - logger('Invalid git repo'); - json_return_and_die(array('message' => 'Invalid git repo: ' . $repoName, 'success' => false)); - } - $repoDir = $tempAddonDir . '/' . $repoName; - if (!is_writable($tempAddonDir)) { - logger('Temporary directory for new addon repo is not writable to web server: ' . $tempAddonDir); - json_return_and_die(array('message' => 'Temporary directory for new addon repo is not writable to web server.', 'success' => false)); - } - // clone the repo if new automatically - $git = new GitRepo('sys', $repoURL, true, $repoName, $repoDir); - - $remotes = $git->git->remote(); - $fetchURL = $remotes['origin']['fetch']; - if ($fetchURL !== $git->url) { - if (rrmdir($repoDir)) { - $git = new GitRepo('sys', $repoURL, true, $repoName, $repoDir); - } else { - json_return_and_die(array('message' => 'Error deleting existing addon repo.', 'success' => false)); - } - } - $repo = $git->probeRepo(); - $repo['readme'] = $repo['manifest'] = null; - foreach ($git->git->tree('master') as $object) { - if ($object['type'] == 'blob' && (strtolower($object['file']) === 'readme.md' || strtolower($object['file']) === 'readme')) { - $repo['readme'] = MarkdownExtra::defaultTransform($git->git->cat->blob($object['hash'])); - } else if ($object['type'] == 'blob' && strtolower($object['file']) === 'manifest.json') { - $repo['manifest'] = $git->git->cat->blob($object['hash']); - } - } - json_return_and_die(array('repo' => $repo, 'message' => '', 'success' => true)); - } else { - json_return_and_die(array('message' => 'No repo URL provided', 'success' => false)); - } - break; - default: - break; - } - } } /** @@ -408,37 +186,6 @@ class Addons { usort($plugins,'self::plugin_sort'); - $allowManageRepos = false; - if(is_writable('extend/addon') && is_writable('store/[data]')) { - $allowManageRepos = true; - } - - $admin_plugins_add_repo_form= replace_macros( - get_markup_template('admin_plugins_addrepo.tpl'), array( - '$post' => 'admin/addons/addrepo', - '$desc' => t('Enter the public git repository URL of the addon repo.'), - '$repoURL' => array('repoURL', t('Addon repo git URL'), '', ''), - '$repoName' => array('repoName', t('Custom repo name'), '', '', t('(optional)')), - '$submit' => t('Download Addon Repo') - ) - ); - $newRepoModalID = random_string(3); - $newRepoModal = replace_macros( - get_markup_template('generic_modal.tpl'), array( - '$id' => $newRepoModalID, - '$title' => t('Install new repo'), - '$ok' => t('Install'), - '$cancel' => t('Cancel') - ) - ); - - $reponames = $this->listAddonRepos(); - $addonrepos = []; - foreach($reponames as $repo) { - $addonrepos[] = array('name' => $repo, 'description' => ''); - /// @TODO Parse repo info to provide more information about repos - } - $t = get_markup_template('admin_plugins.tpl'); return replace_macros($t, array( '$title' => t('Administration'), @@ -449,37 +196,9 @@ class Addons { '$plugins' => $plugins, '$disabled' => t('Disabled - version incompatibility'), '$form_security_token' => get_form_security_token('admin_addons'), - '$allowManageRepos' => $allowManageRepos, - '$managerepos' => t('Manage Repos'), - '$installedtitle' => t('Installed Addon Repositories'), - '$addnewrepotitle' => t('Install a New Addon Repository'), - '$expandform' => false, - '$form' => $admin_plugins_add_repo_form, - '$newRepoModal' => $newRepoModal, - '$newRepoModalID' => $newRepoModalID, - '$addonrepos' => $addonrepos, - '$repoUpdateButton' => t('Update'), - '$repoBranchButton' => t('Switch branch'), - '$repoRemoveButton' => t('Remove') )); } - function listAddonRepos() { - $addonrepos = []; - $addonDir = 'extend/addon/'; - if(is_dir($addonDir)) { - if ($handle = opendir($addonDir)) { - while (false !== ($entry = readdir($handle))) { - if ($entry != "." && $entry != "..") { - $addonrepos[] = $entry; - } - } - closedir($handle); - } - } - return $addonrepos; - } - static public function plugin_sort($a,$b) { return(strcmp(strtolower($a[2]['name']),strtolower($b[2]['name']))); } diff --git a/Zotlabs/Module/Admin/Channels.php b/Zotlabs/Module/Admin/Channels.php index 52b661420..cd1d2b6fe 100644 --- a/Zotlabs/Module/Admin/Channels.php +++ b/Zotlabs/Module/Admin/Channels.php @@ -126,7 +126,7 @@ class Channels { goaway(z_root() . '/admin/channels' ); } - $key = (($_REQUEST['key']) ? dbesc($_REQUEST['key']) : 'channel_id'); + $key = ((isset($_REQUEST['key']) && $_REQUEST['key']) ? dbesc($_REQUEST['key']) : 'channel_id'); $dir = 'asc'; if(array_key_exists('dir',$_REQUEST)) $dir = ((intval($_REQUEST['dir'])) ? 'asc' : 'desc'); diff --git a/Zotlabs/Module/Admin/Features.php b/Zotlabs/Module/Admin/Features.php index e0b3a3fd4..eb82ae1ff 100644 --- a/Zotlabs/Module/Admin/Features.php +++ b/Zotlabs/Module/Admin/Features.php @@ -59,14 +59,13 @@ class Features { } $tpl = get_markup_template("admin_settings_features.tpl"); - $o .= replace_macros($tpl, array( + + return replace_macros($tpl, array( '$form_security_token' => get_form_security_token("admin_manage_features"), '$title' => t('Manage Additional Features'), '$features' => $arr, '$submit' => t('Submit'), )); - - return $o; } } diff --git a/Zotlabs/Module/Admin/Site.php b/Zotlabs/Module/Admin/Site.php index abc56d298..9ef5dc20f 100644 --- a/Zotlabs/Module/Admin/Site.php +++ b/Zotlabs/Module/Admin/Site.php @@ -6,6 +6,8 @@ use Zotlabs\Lib\Config; class Site { + private string $eol; + private string $joo; /** * @brief POST handler for Admin Site Page. @@ -208,7 +210,6 @@ class Site { //Config::Set('system','force_queue_threshold', $force_queue); Config::Set('system','no_community_page', $no_community_page); - Config::Set('system','no_utf', $no_utf); Config::Set('system','sse_enabled', $sse_enabled); diff --git a/Zotlabs/Module/Admin/Themes.php b/Zotlabs/Module/Admin/Themes.php index 6793f56b1..09fec9725 100644 --- a/Zotlabs/Module/Admin/Themes.php +++ b/Zotlabs/Module/Admin/Themes.php @@ -2,7 +2,7 @@ namespace Zotlabs\Module\Admin; -use \Michelf\MarkdownExtra; +use Michelf\MarkdownExtra; use Zotlabs\Lib\Config; /** diff --git a/Zotlabs/Module/Api.php b/Zotlabs/Module/Api.php index 8574ae1cd..c3337b501 100644 --- a/Zotlabs/Module/Api.php +++ b/Zotlabs/Module/Api.php @@ -108,6 +108,9 @@ class Api extends \Zotlabs\Web\Controller { echo api_call(); killme(); + + // not reached + return; } function oauth_get_client($request){ diff --git a/Zotlabs/Module/Appman.php b/Zotlabs/Module/Appman.php index 5f72d771b..8a842feda 100644 --- a/Zotlabs/Module/Appman.php +++ b/Zotlabs/Module/Appman.php @@ -16,21 +16,21 @@ class Appman extends \Zotlabs\Web\Controller { if(isset($_POST['url']) && $_POST['url']) { $arr = array( 'uid' => intval($_REQUEST['uid']), - 'url' => escape_tags($_REQUEST['url']), - 'guid' => escape_tags($_REQUEST['guid']), - 'author' => escape_tags($_REQUEST['author']), - 'addr' => escape_tags($_REQUEST['addr']), - 'name' => escape_tags($_REQUEST['name']), - 'desc' => escape_tags($_REQUEST['desc']), - 'photo' => escape_tags($_REQUEST['photo']), - 'version' => escape_tags($_REQUEST['version']), - 'price' => escape_tags($_REQUEST['price']), - 'page' => escape_tags($_REQUEST['page']), - 'requires' => escape_tags($_REQUEST['requires']), + 'url' => escape_tags($_REQUEST['url'] ?? ''), + 'guid' => escape_tags($_REQUEST['guid'] ?? ''), + 'author' => escape_tags($_REQUEST['author'] ?? ''), + 'addr' => escape_tags($_REQUEST['addr'] ?? ''), + 'name' => escape_tags($_REQUEST['name'] ?? ''), + 'desc' => escape_tags($_REQUEST['desc'] ?? ''), + 'photo' => escape_tags($_REQUEST['photo'] ?? ''), + 'version' => escape_tags($_REQUEST['version'] ?? ''), + 'price' => escape_tags($_REQUEST['price'] ?? ''), + 'page' => escape_tags($_REQUEST['page'] ?? ''), + 'requires' => escape_tags($_REQUEST['requires'] ?? ''), 'system' => intval($_REQUEST['system']), - 'plugin' => escape_tags($_REQUEST['plugin']), - 'sig' => escape_tags($_REQUEST['sig']), - 'categories' => escape_tags($_REQUEST['categories']) + 'plugin' => escape_tags($_REQUEST['plugin'] ?? ''), + 'sig' => escape_tags($_REQUEST['sig'] ?? ''), + 'categories' => escape_tags($_REQUEST['categories'] ?? '') ); $_REQUEST['appid'] = Apps::app_install(local_channel(),$arr); diff --git a/Zotlabs/Module/Apporder.php b/Zotlabs/Module/Apporder.php index 313c2df50..579ca738c 100644 --- a/Zotlabs/Module/Apporder.php +++ b/Zotlabs/Module/Apporder.php @@ -2,7 +2,7 @@ namespace Zotlabs\Module; -use \Zotlabs\Lib as Zlib; +use Zotlabs\Lib as Zlib; class Apporder extends \Zotlabs\Web\Controller { @@ -25,7 +25,7 @@ class Apporder extends \Zotlabs\Web\Controller { $syslist[] = Zlib\Apps::app_encode($li); } } - + Zlib\Apps::translate_system_apps($syslist); usort($syslist,'Zotlabs\\Lib\\Apps::app_name_compare'); diff --git a/Zotlabs/Module/Apps.php b/Zotlabs/Module/Apps.php index a8817111e..97e1b237f 100644 --- a/Zotlabs/Module/Apps.php +++ b/Zotlabs/Module/Apps.php @@ -1,8 +1,8 @@ <?php namespace Zotlabs\Module; -use \Zotlabs\Lib\Config; -use \Zotlabs\Lib as Zlib; +use Zotlabs\Lib\Config; +use Zotlabs\Lib as Zlib; class Apps extends \Zotlabs\Web\Controller { diff --git a/Zotlabs/Module/Authorize.php b/Zotlabs/Module/Authorize.php index c6709f602..b015c3284 100644 --- a/Zotlabs/Module/Authorize.php +++ b/Zotlabs/Module/Authorize.php @@ -9,7 +9,7 @@ class Authorize extends \Zotlabs\Web\Controller { function get() { if (! local_channel()) { return login(); - } + } else { $name = $_REQUEST['client_name']; @@ -25,7 +25,7 @@ class Authorize extends \Zotlabs\Web\Controller { $link = (($app['url']) ? '<a style="float: none;" href="' . $app['url'] . '">' . $app['name'] . '</a> ' : $app['name']); - $o .= replace_macros(get_markup_template('oauth_authorize.tpl'), [ + return replace_macros(get_markup_template('oauth_authorize.tpl'), [ '$title' => t('Authorize'), '$authorize' => sprintf( t('Do you authorize the app %s to access your channel data?'), $link ), '$app' => $app, @@ -35,7 +35,6 @@ class Authorize extends \Zotlabs\Web\Controller { '$redirect_uri' => (x($_REQUEST, 'redirect_uri') ? $_REQUEST['redirect_uri'] : ''), '$state' => (x($_REQUEST, 'state') ? $_REQUEST['state'] : ''), ]); - return $o; } } @@ -50,7 +49,7 @@ class Authorize extends \Zotlabs\Web\Controller { // TODO: The automatic client registration protocol below should adhere more // closely to "OAuth 2.0 Dynamic Client Registration Protocol" defined // at https://tools.ietf.org/html/rfc7591 - + // If no client_id was provided, generate a new one. if (x($_POST, 'client_id')) { $client_id = $_POST['client_id']; @@ -67,7 +66,7 @@ class Authorize extends \Zotlabs\Web\Controller { $request = \OAuth2\Request::createFromGlobals(); $response = new \OAuth2\Response(); - // Note, "sub" field must match type and content. $user_id is used to populate - make sure it's a string. + // Note, "sub" field must match type and content. $user_id is used to populate - make sure it's a string. $channel = channelx_by_n(local_channel()); $user_id = $channel['channel_id']; diff --git a/Zotlabs/Module/Authtest.php b/Zotlabs/Module/Authtest.php index d85af09dc..bf199ccf6 100644 --- a/Zotlabs/Module/Authtest.php +++ b/Zotlabs/Module/Authtest.php @@ -7,7 +7,7 @@ class Authtest extends \Zotlabs\Web\Controller { $auth_success = false; - $o .= '<h3>Magic-Auth Diagnostic</h3>'; + $o = '<h3>Magic-Auth Diagnostic</h3>'; if(! local_channel()) { notice( t('Permission denied.') . EOL); @@ -27,7 +27,7 @@ class Authtest extends \Zotlabs\Web\Controller { $_REQUEST['test'] = 1; $mod = new Magic(); - $x = $mod->init($a); + $x = $mod->init(); $o .= 'Local Setup returns: ' . print_r($x,true); diff --git a/Zotlabs/Module/Changeaddr.php b/Zotlabs/Module/Changeaddr.php index ed139c9f9..f8a045727 100644 --- a/Zotlabs/Module/Changeaddr.php +++ b/Zotlabs/Module/Changeaddr.php @@ -5,30 +5,30 @@ namespace Zotlabs\Module; class Changeaddr extends \Zotlabs\Web\Controller { function post() { - + if(! local_channel()) return; - + if($_SESSION['delegate']) return; - + if((! x($_POST,'qxz_password')) || (! strlen(trim($_POST['qxz_password'])))) return; - + if((! x($_POST,'verify')) || (! strlen(trim($_POST['verify'])))) return; - + if($_POST['verify'] !== $_SESSION['remove_account_verify']) return; - - + + $account = \App::get_account(); $channel = \App::get_channel(); - + $x = account_verify_password($account['account_email'],$_POST['qxz_password']); if(! ($x && $x['account'])) return; - + if($account['account_password_changed'] > NULL_DATE) { $d1 = datetime_convert('UTC','UTC','now - 48 hours'); if($account['account_password_changed'] > $d1) { @@ -36,7 +36,7 @@ class Changeaddr extends \Zotlabs\Web\Controller { return; } } - + $new_address = trim($_POST['newname']); if($new_address === $channel['channel_address']) @@ -55,23 +55,23 @@ class Changeaddr extends \Zotlabs\Web\Controller { channel_change_address($channel,$new_address); goaway(z_root() . '/changeaddr'); - + } - - + + function get() { - + if(! local_channel()) goaway(z_root()); - + $channel = \App::get_channel(); $hash = random_string(); - + $_SESSION['remove_account_verify'] = $hash; - + $tpl = get_markup_template('channel_rename.tpl'); - $o .= replace_macros($tpl, array( + return replace_macros($tpl, array( '$basedir' => z_root(), '$hash' => $hash, '$title' => t('Change channel nickname/address'), @@ -80,9 +80,5 @@ class Changeaddr extends \Zotlabs\Web\Controller { '$newname' => array('newname', t('New channel address'),$channel['channel_address'], ''), '$submit' => t('Rename Channel') )); - - return $o; - } - } diff --git a/Zotlabs/Module/Channel_calendar.php b/Zotlabs/Module/Channel_calendar.php index 289e3a734..30683404b 100644 --- a/Zotlabs/Module/Channel_calendar.php +++ b/Zotlabs/Module/Channel_calendar.php @@ -179,26 +179,14 @@ class Channel_calendar extends Controller { if ($post_tags) $datarray['term'] = $post_tags; - $item_id = event_store_item($datarray, $event); + $post = event_store_item($datarray, $event); - if ($item_id) { - $r = q("select * from item where id = %d", - intval($item_id) - ); - if ($r) { - xchan_query($r); - $sync_item = fetch_post_tags($r); - $z = q("select * from event where event_hash = '%s' and uid = %d limit 1", - dbesc($r[0]['resource_id']), - intval($channel['channel_id']) - ); - if ($z) { - Libsync::build_sync_packet($channel['channel_id'], array('event_item' => array(encode_item($sync_item[0], true)), 'event' => $z)); - } - } + if (!empty($post['item_id'])) { + Master::Summon(['Notifier', 'event', $post['item_id']]); + } + if (!empty($post['approval_id'])) { + Master::Summon(['Notifier', 'event', $post['approval_id']]); } - - Master::Summon(array('Notifier', 'event', $item_id)); killme(); @@ -470,13 +458,14 @@ class Channel_calendar extends Controller { } else { // complex deletion that needs to propagate and be performed in phases - drop_item($i[0]['id'], true, DROPITEM_PHASE1); + drop_item($i[0]['id'], DROPITEM_PHASE1); $complex = true; } $ii = q("select * from item where id = %d", intval($i[0]['id']) ); + if ($ii) { xchan_query($ii); $sync_item = fetch_post_tags($ii); @@ -485,6 +474,9 @@ class Channel_calendar extends Controller { if ($complex) { tag_deliver($i[0]['uid'], $i[0]['id']); + if (intval($i[0]['item_wall'])) { + Master::Summon(['Notifier', 'drop', $i[0]['id']]); + } } } } diff --git a/Zotlabs/Module/Chatsvc.php b/Zotlabs/Module/Chatsvc.php index 2f2784fc4..e9dfb2a4b 100644 --- a/Zotlabs/Module/Chatsvc.php +++ b/Zotlabs/Module/Chatsvc.php @@ -4,7 +4,7 @@ namespace Zotlabs\Module; require_once('include/security.php'); -use \Zotlabs\Lib as Zlib; +use Zotlabs\Lib as Zlib; class Chatsvc extends \Zotlabs\Web\Controller { diff --git a/Zotlabs/Module/Cloud.php b/Zotlabs/Module/Cloud.php index 527b06b3a..510f91c1e 100644 --- a/Zotlabs/Module/Cloud.php +++ b/Zotlabs/Module/Cloud.php @@ -8,10 +8,10 @@ namespace Zotlabs\Module; */ use Sabre\DAV as SDAV; -use \Zotlabs\Web\Controller; -use \Zotlabs\Storage\BasicAuth; -use \Zotlabs\Storage\Directory; -use \Zotlabs\Storage\Browser; +use Zotlabs\Web\Controller; +use Zotlabs\Storage\BasicAuth; +use Zotlabs\Storage\Directory; +use Zotlabs\Storage\Browser; // composer autoloader for SabreDAV diff --git a/Zotlabs/Module/Conversation.php b/Zotlabs/Module/Conversation.php index aa8349f55..0a1ba87d1 100644 --- a/Zotlabs/Module/Conversation.php +++ b/Zotlabs/Module/Conversation.php @@ -16,7 +16,7 @@ class Conversation extends Controller { public function init() { - if (ActivityStreams::is_as_request()) { + if (ActivityStreams::is_as_request() || Libzot::is_zot_request()) { $item_id = argv(1); if (!$item_id) { @@ -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) ); @@ -77,16 +76,16 @@ class Conversation extends Controller { } } } - elseif (Config::get('system', 'require_authenticated_fetch', false)) { + elseif (Config::Get('system', 'require_authenticated_fetch', false)) { http_status_exit(403, 'Permission denied'); } // 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/Cover_photo.php b/Zotlabs/Module/Cover_photo.php index aa2464ac2..2d2ffd52d 100644 --- a/Zotlabs/Module/Cover_photo.php +++ b/Zotlabs/Module/Cover_photo.php @@ -371,7 +371,7 @@ class Cover_photo extends \Zotlabs\Web\Controller { $tpl = get_markup_template('cover_photo.tpl'); - $o .= replace_macros($tpl,array( + $output = replace_macros($tpl,array( '$user' => \App::$channel['channel_address'], '$info' => t('Your cover photo may be visible to anybody on the internet'), '$existing' => get_cover_photo(local_channel(),'array',PHOTO_RES_COVER_850), @@ -397,15 +397,15 @@ class Cover_photo extends \Zotlabs\Web\Controller { )); - call_hooks('cover_photo_content_end', $o); + call_hooks('cover_photo_content_end', $output); - return $o; + return $output; } else { $filename = \App::$data['imagecrop'] . '-3'; $resolution = 3; $tpl = get_markup_template("cropcover.tpl"); - $o .= replace_macros($tpl,array( + return replace_macros($tpl,array( '$filename' => $filename, '$profile' => intval($_REQUEST['profile']), '$resource' => \App::$data['imagecrop'] . '-3', @@ -415,7 +415,6 @@ class Cover_photo extends \Zotlabs\Web\Controller { '$form_security_token' => get_form_security_token("cover_photo"), '$done' => t('Done Editing') )); - return $o; } } diff --git a/Zotlabs/Module/Dav.php b/Zotlabs/Module/Dav.php index 96fe2c898..5254d436d 100644 --- a/Zotlabs/Module/Dav.php +++ b/Zotlabs/Module/Dav.php @@ -9,6 +9,7 @@ namespace Zotlabs\Module; use Sabre\DAV as SDAV; +use Zotlabs\Lib\Libzot; use Zotlabs\Storage; use Zotlabs\Web\HTTPSig; diff --git a/Zotlabs/Module/Display.php b/Zotlabs/Module/Display.php index 451ddeb1f..090e0c92e 100644 --- a/Zotlabs/Module/Display.php +++ b/Zotlabs/Module/Display.php @@ -344,7 +344,12 @@ class Display extends Controller { '$profile_page' => xmlify(z_root() . '/display/' . gen_link_id($target_item['mid'])), )); - $x = [ 'xml' => $atom, 'channel' => $channel, 'observer_hash' => $observer_hash, 'params' => $params ]; + $x = [ + 'xml' => $atom, + 'channel' => $channel, + 'observer_hash' => $observer_hash, + 'params' => [], + ]; call_hooks('atom_feed_top',$x); $atom = $x['xml']; 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/Fbrowser.php b/Zotlabs/Module/Fbrowser.php index 3bac81c5a..e8517e095 100644 --- a/Zotlabs/Module/Fbrowser.php +++ b/Zotlabs/Module/Fbrowser.php @@ -6,6 +6,8 @@ namespace Zotlabs\Module; * @author Fabio Comuni <fabrixxm@kirgroup.com> */ +use function Zotlabs\Render\template_escape; + require_once('include/photo/photo_driver.php'); /** diff --git a/Zotlabs/Module/Filer.php b/Zotlabs/Module/Filer.php index c2747e6c2..bf472eb67 100644 --- a/Zotlabs/Module/Filer.php +++ b/Zotlabs/Module/Filer.php @@ -1,43 +1,54 @@ <?php namespace Zotlabs\Module; -require_once('include/security.php'); -require_once('include/bbcode.php'); -require_once('include/items.php'); - - +use App; class Filer extends \Zotlabs\Web\Controller { function get() { - - if(! local_channel()) { + + if(!local_channel()) { killme(); } - - $term = unxmlify(trim($_GET['term'])); - $item_id = ((\App::$argc > 1) ? intval(\App::$argv[1]) : 0); - + + $term = unxmlify(trim($_GET['term'] ?? '')); + $item_id = ((App::$argc > 1) ? intval(App::$argv[1]) : 0); + logger('filer: tag ' . $term . ' item ' . $item_id); - + if($item_id && strlen($term)){ + + $sys = get_sys_channel(); + + $r = q("SELECT * FROM item WHERE (uid = %d OR uid = %d) AND id = %d + and item_type in (0,6,7) and item_deleted = 0 and item_unpublished = 0 + and item_delayed = 0 and item_pending_remove = 0 and item_blocked = 0 LIMIT 1", + intval(local_channel()), + intval($sys['channel_id']), + intval($item_id) + ); + + if ($r && $r[0]['uid'] === $sys['channel_id']) { + $r = [copy_of_pubitem(App::get_channel(), $r[0]['mid'])]; + } + + if(!$r) { + killme(); + } + + $item_id = $r[0]['id']; + // file item store_item_tag(local_channel(),$item_id,TERM_OBJ_POST,TERM_FILE,$term,''); - + // protect the entire conversation from periodic expiration - - $r = q("select parent from item where id = %d and uid = %d limit 1", - intval($item_id), + + q("update item set item_retained = 1, changed = '%s' where id = %d and uid = %d", + dbesc(datetime_convert()), + intval($r[0]['parent']), intval(local_channel()) ); - if($r) { - $x = q("update item set item_retained = 1, changed = '%s' where id = %d and uid = %d", - dbesc(datetime_convert()), - intval($r[0]['parent']), - intval(local_channel()) - ); - } - } + } else { $filetags = array(); $r = q("select distinct(term) from term where uid = %d and ttype = %d order by term asc", @@ -55,10 +66,10 @@ class Filer extends \Zotlabs\Web\Controller { '$title' => t('Save to Folder'), '$cancel' => t('Cancel') )); - + echo $o; } killme(); } - + } diff --git a/Zotlabs/Module/Go.php b/Zotlabs/Module/Go.php index ec528fb1a..77a3ffac6 100644 --- a/Zotlabs/Module/Go.php +++ b/Zotlabs/Module/Go.php @@ -2,7 +2,7 @@ namespace Zotlabs\Module; -use Zorlabs\Lib\Config; +use Zotlabs\Lib\Config; class Go extends \Zotlabs\Web\Controller { @@ -19,7 +19,7 @@ class Go extends \Zotlabs\Web\Controller { function get() { if(! local_channel()) { - notify( t('This page is available only to site members') . EOL); + notice( t('This page is available only to site members') . EOL); } $channel = \App::get_channel(); diff --git a/Zotlabs/Module/Help.php b/Zotlabs/Module/Help.php index fd5cacee6..fc0ef2708 100644 --- a/Zotlabs/Module/Help.php +++ b/Zotlabs/Module/Help.php @@ -6,6 +6,7 @@ use Michelf\MarkdownExtra; /** * You can create local site resources in doc/Site.md and either link to doc/Home.md for the standard resources * or use our include mechanism to include it on your local page. + * *@code * #include doc/Home.md; *@endcode @@ -19,14 +20,6 @@ class Help extends \Zotlabs\Web\Controller { private string $heading_slug = ''; /** - * Associative array containing the detected language. - */ - public array $lang = [ - 'language' => 'en', //! Detected language, 2-letter ISO 639-1 code ("en") - 'from_url' => false, //! true if language from URL overrides browser default - ]; - - /** * Pre-check before processing request. * * Determine language requested, and ensure that a topic was requested. @@ -36,8 +29,8 @@ class Help extends \Zotlabs\Web\Controller { public function init() { $this->determine_help_language(); - if (argc() === 1) { - goaway("/help/{$this->lang['language']}/about/about"); + if (empty($_REQUEST['search']) && argc() === 1) { + goaway("/help/about/about"); killme(); } } @@ -69,6 +62,7 @@ class Help extends \Zotlabs\Web\Controller { $o .= '</div>'; $o .= '<div class="section-content-wrapper">'; + require_once('include/help.php'); $r = search_doc_files($_REQUEST['search']); if($r) { $o .= '<ul class="help-searchlist">'; @@ -160,6 +154,10 @@ class Help extends \Zotlabs\Web\Controller { array_shift($args); } + if (empty($args)) { + goaway("/help/about/about"); + } + // Keep the first remaining arg as the heading slug $this->heading_slug = $args[0]; diff --git a/Zotlabs/Module/Home.php b/Zotlabs/Module/Home.php index 691ca1af9..3ac445f9f 100644 --- a/Zotlabs/Module/Home.php +++ b/Zotlabs/Module/Home.php @@ -100,14 +100,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 c8e6efe38..51caa179c 100644 --- a/Zotlabs/Module/Hq.php +++ b/Zotlabs/Module/Hq.php @@ -230,6 +230,7 @@ class Hq extends \Zotlabs\Web\Controller { $options['offset'] = $_REQUEST['offset'] ?? 0; $options['type'] = $_REQUEST['type'] ?? ''; $options['author'] = ((isset($_REQUEST['author'])) ? urldecode($_REQUEST['author']) : ''); + $options['file'] = ((isset($_REQUEST['file'])) ? urldecode($_REQUEST['file']) : ''); $ret = Messages::get_messages_page($options); diff --git a/Zotlabs/Module/Impel.php b/Zotlabs/Module/Impel.php index 869de2669..0e07ab71c 100644 --- a/Zotlabs/Module/Impel.php +++ b/Zotlabs/Module/Impel.php @@ -164,7 +164,7 @@ class Impel extends \Zotlabs\Web\Controller { $arr['id'] = $i[0]['id']; // don't update if it has the same timestamp as the original if($arr['edited'] > $i[0]['edited']) - $x = item_store_update($arr,$execflag); + $x = item_store_update($arr, $execflag , deliver: false, addAndSync: false); } else { if(($i) && (intval($i[0]['item_deleted']))) { @@ -175,7 +175,7 @@ class Impel extends \Zotlabs\Web\Controller { ); } else - $x = item_store($arr,$execflag); + $x = item_store($arr, $execflag, deliver: false, addAndSync: false); } if($x && $x['success']) { diff --git a/Zotlabs/Module/Import.php b/Zotlabs/Module/Import.php index 5ace4e72d..7aed6469e 100644 --- a/Zotlabs/Module/Import.php +++ b/Zotlabs/Module/Import.php @@ -534,6 +534,7 @@ class Import extends Controller { if ($api_path) { $parsed = parse_url($api_path); unset($parsed['path']); + unset($parsed['query']); // store the import host so we can manually kick off item/file sync later in case anything did not work out set_pconfig($channel['channel_id'], 'import', 'host', $parsed['host']); @@ -551,7 +552,7 @@ class Import extends Controller { $until = datetime_convert(date_default_timezone_get(), date_default_timezone_get(), 'now + 1 day'); //$poll_interval = Config::Get('system', 'poll_interval', 3); - $page = 0; + $page = 0; Master::Summon(['Content_importer', sprintf('%d', $page), $since, $until, $channel['channel_address'], urlencode($hz_server)]); Master::Summon(['File_importer', sprintf('%d', $page), $channel['channel_address'], urlencode($hz_server)]); diff --git a/Zotlabs/Module/Import_progress.php b/Zotlabs/Module/Import_progress.php index d9b13e8a8..0afb6faed 100644 --- a/Zotlabs/Module/Import_progress.php +++ b/Zotlabs/Module/Import_progress.php @@ -29,14 +29,14 @@ class Import_progress extends \Zotlabs\Web\Controller { $c = PConfig::Get(local_channel(), 'import', 'content_progress'); if ($c) { - $total_cpages = floor(intval($c['items_total']) / intval($c['items_page'])); + $total_cpages = round(intval($c['items_total']) / intval($c['items_page'])); if(!$total_cpages) { - $total_cpages = 1; // because of floor + $total_cpages = 1; // because of round } $cpage = $c['last_page'] + 1; // because page count start at 0 - $cprogress = intval(floor((intval($cpage) * 100) / $total_cpages)); + $cprogress = intval(round((intval($cpage) * 100) / $total_cpages)); $ccompleted_str = t('Item sync completed!'); if(argv(1) === 'resume_itemsync' && $cprogress < 100) { @@ -50,6 +50,7 @@ class Import_progress extends \Zotlabs\Web\Controller { if ($alive) { $parsed = parse_url($alive); unset($parsed['path']); + unset($parsed['query']); $hz_server = unparse_url($parsed); $since = datetime_convert(date_default_timezone_get(), date_default_timezone_get(), '0001-01-01 00:00'); @@ -79,14 +80,14 @@ class Import_progress extends \Zotlabs\Web\Controller { $f = PConfig::Get(local_channel(), 'import', 'files_progress'); if ($f) { - $total_fpages = floor(intval($f['files_total']) / intval($f['files_page'])); + $total_fpages = round(intval($f['files_total']) / intval($f['files_page'])); if(!$total_fpages) { $total_fpages = 1; } $fpage = $f['last_page'] + 1; - $fprogress = intval(floor((intval($fpage) * 100) / $total_fpages)); + $fprogress = intval(round((intval($fpage) * 100) / $total_fpages)); $fcompleted_str = t('File sync completed!'); if(argv(1) === 'resume_filesync' && $fprogress < 100) { @@ -120,6 +121,7 @@ class Import_progress extends \Zotlabs\Web\Controller { } $fcompleted_str = t('File sync completed but no files were found!'); + } $fprogress_str = ((intval($fprogress)) ? $fprogress . '%' : $fprogress); @@ -127,13 +129,15 @@ class Import_progress extends \Zotlabs\Web\Controller { if(is_ajax()) { $ret = [ 'cprogress' => $cprogress, - 'fprogress' => $fprogress + 'ccompleted_str' => $ccompleted_str, + 'fprogress' => $fprogress, + 'fcompleted_str' => $fcompleted_str ]; json_return_and_die($ret); } - $o = replace_macros(get_markup_template("import_progress.tpl"), [ + return replace_macros(get_markup_template('import_progress.tpl'), [ '$chtitle_str' => t('Channel clone status'), '$ctitle_str' => t('Item sync status'), '$ftitle_str' => t('File sync status'), @@ -147,8 +151,6 @@ class Import_progress extends \Zotlabs\Web\Controller { '$resume_str' => t('Resume'), '$resume_helper_str' => t('Only resume if sync stalled!') ]); - - return $o; } } diff --git a/Zotlabs/Module/Item.php b/Zotlabs/Module/Item.php index 3d13655d2..ea561ee25 100644 --- a/Zotlabs/Module/Item.php +++ b/Zotlabs/Module/Item.php @@ -44,253 +44,30 @@ class Item extends Controller { function init() { if (Libzot::is_zot_request()) { - - $item_id = argv(1); - - if (!$item_id) - http_status_exit(404, 'Not found'); - - $portable_id = EMPTY_STR; - - $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 "; - - $i = null; - - // do we have the item (at all)? - - $r = q("select parent_mid from item where uuid = '%s' $item_normal limit 1", - dbesc($item_id) - ); - - if (!$r) { - http_status_exit(404, 'Not found'); - } - - // process an authenticated fetch - - $sigdata = HTTPSig::verify(($_SERVER['REQUEST_METHOD'] === 'POST') ? file_get_contents('php://input') : EMPTY_STR); - if ($sigdata['portable_id'] && $sigdata['header_valid']) { - $portable_id = $sigdata['portable_id']; - if (!check_channelallowed($portable_id)) { - http_status_exit(403, 'Permission denied'); - } - if (!check_siteallowed($sigdata['signer'])) { - http_status_exit(403, 'Permission denied'); - } - observer_auth($portable_id); - - $i = q("select id as item_id, uid from item where mid = '%s' $item_normal and owner_xchan = '%s' limit 1", - dbesc($r[0]['parent_mid']), - dbesc($portable_id) - ); - } - elseif (Config::get('system', 'require_authenticated_fetch', false)) { - http_status_exit(403, 'Permission denied'); - } - - // 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) { - $i = q("select id as item_id, uid, item_private from item where mid = '%s' $item_normal $sql_extra order by item_wall desc limit 1", - dbesc($r[0]['parent_mid']) - ); - } - - if (!$i) { - http_status_exit(403, 'Forbidden'); - } - - $chan = channelx_by_n($i[0]['uid']); - - if (!$chan) { - http_status_exit(404, 'Not found'); - } - - if (!perm_is_allowed($chan['channel_id'], get_observer_hash(), 'view_stream')) { - http_status_exit(403, 'Forbidden'); - } - - $parents_str = ids_to_querystr($i, 'item_id'); - - // We won't need to check for privacy mismatches if the verified observer is also owner - $parent_item_private = ((isset($i[0]['item_private'])) ? " and item_private = " . intval($i[0]['item_private']) . " " : ''); - - $total = q("SELECT count(*) AS count FROM item WHERE parent = %d $parent_item_private $item_normal ", - intval($parents_str) - ); - - App::set_pager_total($total[0]['count']); - App::set_pager_itemspage(30); - - if (App::$pager['total'] > App::$pager['itemspage']) { - // let mod conversation handle this request - App::$query_string = str_replace('item', 'conversation', App::$query_string); - $i = Activity::paged_collection_init(App::$pager['total'], App::$query_string); - as_return_and_die($i ,$chan); - } - else { - $items = q("SELECT item.*, item.id AS item_id FROM item WHERE item.parent = %d $parent_item_private $item_normal ORDER BY item.id", - intval($parents_str) - ); - - xchan_query($items, true); - $items = fetch_post_tags($items, true); - - $i = Activity::encode_item_collection($items, App::$query_string, 'OrderedCollection', App::$pager['total']); - } - - if ($portable_id && (!intval($items[0]['item_private']))) { - $c = q("select abook_id from abook where abook_channel = %d and abook_xchan = '%s'", - intval($items[0]['uid']), - dbesc($portable_id) - ); - if (!$c) { - ThreadListener::store(z_root() . '/item/' . $item_id, $portable_id); - } - } - - as_return_and_die($i ,$chan); + $this->init_zot_request(); } if (ActivityStreams::is_as_request()) { - - $item_id = argv(1); - if (!$item_id) - http_status_exit(404, 'Not found'); - - $portable_id = EMPTY_STR; - - $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 "; - - $i = null; - - // do we have the item (at all)? - // add preferential bias to item owners (item_wall = 1) - - $r = q("select * from item where uuid = '%s' $item_normal order by item_wall desc limit 1", - dbesc($item_id) - ); - - if (!$r) { - http_status_exit(404, 'Not found'); - } - - // process an authenticated fetch - - $sigdata = HTTPSig::verify(EMPTY_STR); - if ($sigdata['portable_id'] && $sigdata['header_valid']) { - $portable_id = $sigdata['portable_id']; - if (!check_channelallowed($portable_id)) { - http_status_exit(403, 'Permission denied'); - } - if (!check_siteallowed($sigdata['signer'])) { - http_status_exit(403, 'Permission denied'); - } - observer_auth($portable_id); - - $i = q("select id as item_id from item where mid = '%s' $item_normal and owner_xchan = '%s' limit 1 ", - dbesc($r[0]['parent_mid']), - dbesc($portable_id) - ); - } - elseif (Config::get('system', 'require_authenticated_fetch', false)) { - http_status_exit(403, 'Permission denied'); - } - - // 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) { - $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']) - ); - } - - $bear = Activity::token_from_request(); - if ($bear) { - logger('bear: ' . $bear, LOGGER_DEBUG); - if (!$i) { - $t = q("select * from iconfig where cat = 'ocap' and k = 'relay' and v = '%s'", - dbesc($bear) - ); - if ($t) { - $i = q("select id as item_id from item where uuid = '%s' and id = %d $item_normal limit 1", - dbesc($item_id), - intval($t[0]['iid']) - ); - } - } - } - - if (!$i) { - http_status_exit(403, 'Forbidden'); - } - - // If we get to this point we have determined we can access the original in $r (fetched much further above), so use it. - - xchan_query($r, true); - $items = fetch_post_tags($r, false); - - $chan = channelx_by_n($items[0]['uid']); - - if (!$chan) - http_status_exit(404, 'Not found'); - - if (!perm_is_allowed($chan['channel_id'], get_observer_hash(), 'view_stream')) - http_status_exit(403, 'Forbidden'); - - $i = Activity::encode_item($items[0]); - - if (!$i) - http_status_exit(404, 'Not found'); - - if ($portable_id && (!intval($items[0]['item_private']))) { - $c = q("select abook_id from abook where abook_channel = %d and abook_xchan = '%s'", - intval($items[0]['uid']), - dbesc($portable_id) - ); - if (!$c) { - ThreadListener::store(z_root() . '/item/' . $item_id, $portable_id); - } - } - - as_return_and_die($i ,$chan); - + $this->init_as_request(); } 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'); } @@ -323,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; @@ -401,6 +177,7 @@ class Item extends Controller { $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); + $item_delayed = ((x($_REQUEST, 'delayed')) ? intval($_REQUEST['delayed']) : 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']) : ''); @@ -430,7 +207,6 @@ class Item extends Controller { $expires = NULL_DATE; - $comments_closed = NULL_DATE; $route = ''; $parent_item = null; @@ -607,6 +383,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]; } @@ -677,7 +454,7 @@ class Item extends Controller { $title = escape_tags(trim($_REQUEST['title'])); $summary = escape_tags(trim($_REQUEST['summary'])); $body = trim($_REQUEST['body']); - $item_flags = $orig_post['item_flags']; + $item_flags = $orig_post['item_flags']; $item_origin = $orig_post['item_origin']; $item_unseen = $orig_post['item_unseen']; $item_starred = $orig_post['item_starred']; @@ -691,7 +468,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']; @@ -710,6 +487,7 @@ 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) { @@ -837,8 +615,10 @@ class Item extends Controller { if ($results) { - // Set permissions based on tag replacements - set_linkified_perms($results, $str_contact_allow, $str_group_allow, $profile_uid, $private, $parent_item); + // Set permissions based on tag replacements only if not editing an existing post + if (!$orig_post) { + set_linkified_perms($results, $str_contact_allow, $str_group_allow, $profile_uid, $private, $parent_item); + } foreach ($results as $result) { $success = $result['success']; @@ -1014,6 +794,7 @@ class Item extends Controller { $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 @@ -1027,18 +808,42 @@ class Item extends Controller { } - if ($moderated) + if ($moderated) { $item_blocked = ITEM_MODERATED; + } - if (!strlen($verb)) + if (!strlen($verb)) { $verb = 'Create'; + } $notify_type = (($parent) ? 'comment-new' : 'wall-new'); $uuid = $uuid ?? $message_id ?? item_message_id(); $mid = $mid ?? z_root() . '/item/' . $uuid; + + 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, @@ -1058,7 +863,7 @@ class Item extends Controller { $obj['id'] = $mid; $obj['diaspora:guid'] = $uuid; $obj['attributedTo'] = channel_url($channel); - $obj['published'] = $created; + $obj['published'] = datetime_convert('UTC', 'UTC', $created, ATOM_TIME); $obj['name'] = $title; $datarray['obj'] = $obj; @@ -1080,19 +885,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; } @@ -1155,7 +954,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 @@ -1243,6 +1042,7 @@ class Item extends Controller { $this->add_listeners($datarray); } + /* sync this is done in item_store_update() if (!$parent) { $r = q("select * from item where id = %d", intval($post_id) @@ -1253,9 +1053,14 @@ class Item extends Controller { Libsync::build_sync_packet($profile_uid, ['item' => [encode_item($sync_item[0], true)]]); } } - if (!$nopush) - Master::Summon(['Notifier', 'edit_post', $post_id]); + */ + if (!$nopush) { + Master::Summon(['Notifier', 'edit_post', $post_id]); + if (intval($x['approval_id'])) { + Master::Summon(['Notifier', 'edit_post', $x['approval_id']]); + } + } if ($api_source) return ($x); @@ -1279,6 +1084,7 @@ class Item extends Controller { } $post_id = $post['item_id']; + $approval_id = $post['approval_id'] ?? 0; $datarray = $post['item']; @@ -1353,6 +1159,7 @@ class Item extends Controller { killme(); } + /* sync this is done in item_store_update() if ($parent || $datarray['item_private'] == 1) { $r = q("select * from item where id = %d", intval($post_id) @@ -1363,6 +1170,7 @@ class Item extends Controller { Libsync::build_sync_packet($profile_uid, ['item' => [encode_item($sync_item[0], true)]]); } } + */ $datarray['id'] = $post_id; $datarray['llink'] = z_root() . '/display/' . $datarray['uuid']; @@ -1373,8 +1181,12 @@ class Item extends Controller { $nopush = false; } - if (!$nopush) + if (!$nopush) { Master::Summon(['Notifier', $notify_type, $post_id]); + if ($approval_id) { + Master::Summon(['Notifier', $notify_type, $approval_id]); + } + } logger('post_complete'); @@ -1427,10 +1239,7 @@ class Item extends Controller { if ((argc() == 3) && (argv(1) === 'drop') && intval(argv(2))) { - require_once('include/items.php'); - - - $i = q("select id, uid, item_origin, author_xchan, owner_xchan, source_xchan, item_type from item where id = %d limit 1", + $i = q("select * from item where id = %d limit 1", intval(argv(2)) ); @@ -1457,7 +1266,6 @@ class Item extends Controller { $can_delete = true; } - if (!($can_delete || $local_delete)) { notice(t('Permission denied.') . EOL); return; @@ -1473,13 +1281,14 @@ class Item extends Controller { } else { // complex deletion that needs to propagate and be performed in phases - drop_item($i[0]['id'], true, DROPITEM_PHASE1); + drop_item($i[0]['id'], DROPITEM_PHASE1); $complex = true; } $r = q("select * from item where id = %d", intval($i[0]['id']) ); + if ($r) { xchan_query($r); $sync_item = fetch_post_tags($r); @@ -1488,6 +1297,9 @@ class Item extends Controller { if ($complex) { tag_deliver($i[0]['uid'], $i[0]['id']); + if (intval($i[0]['item_wall']) || $i[0]['mid'] !== $i[0]['parent_mid']) { + Master::Summon(['Notifier', 'drop', $i[0]['id']]); + } } } @@ -1671,5 +1483,234 @@ class Item extends Controller { } } + private function init_zot_request() { + + $item_id = argv(1); + + if (!$item_id) + http_status_exit(404, 'Not found'); + + $portable_id = EMPTY_STR; + + $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 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 uuid = '%s' $item_normal limit 1", + dbesc($item_id) + ); + + if (!$r) { + http_status_exit(404, 'Not found'); + } + + // process an authenticated fetch + + $sigdata = HTTPSig::verify(($_SERVER['REQUEST_METHOD'] === 'POST') ? file_get_contents('php://input') : EMPTY_STR); + if ($sigdata['portable_id'] && $sigdata['header_valid']) { + $portable_id = $sigdata['portable_id']; + if (!check_channelallowed($portable_id)) { + http_status_exit(403, 'Permission denied'); + } + if (!check_siteallowed($sigdata['signer'])) { + http_status_exit(403, 'Permission denied'); + } + observer_auth($portable_id); + + $i = q("select id as item_id, uid from item where mid = '%s' $item_normal and owner_xchan = '%s' limit 1", + dbesc($r[0]['parent_mid']), + dbesc($portable_id) + ); + } + elseif (Config::get('system', 'require_authenticated_fetch', false)) { + http_status_exit(403, 'Permission denied'); + } + + // 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) { + $i = q("select id as item_id, uid, item_private from item where mid = '%s' $item_normal $sql_extra order by item_wall desc limit 1", + dbesc($r[0]['parent_mid']) + ); + } + + if (!$i) { + http_status_exit(403, 'Forbidden'); + } + + $chan = channelx_by_n($i[0]['uid']); + + if (!$chan) { + http_status_exit(404, 'Not found'); + } + + if (!perm_is_allowed($chan['channel_id'], get_observer_hash(), 'view_stream')) { + http_status_exit(403, 'Forbidden'); + } + + $parents_str = ids_to_querystr($i, 'item_id'); + + // We won't need to check for privacy mismatches if the verified observer is also owner + $parent_item_private = ((isset($i[0]['item_private'])) ? " and item_private = " . intval($i[0]['item_private']) . " " : ''); + + $total = q("SELECT count(*) AS count FROM item WHERE parent = %d $parent_item_private $item_normal ", + intval($parents_str) + ); + + App::set_pager_total($total[0]['count']); + App::set_pager_itemspage(30); + + if (App::$pager['total'] > App::$pager['itemspage']) { + // let mod conversation handle this request + App::$query_string = str_replace('item', 'conversation', App::$query_string); + $i = Activity::paged_collection_init(App::$pager['total'], App::$query_string); + as_return_and_die($i ,$chan); + } + else { + $items = q("SELECT item.*, item.id AS item_id FROM item WHERE item.parent = %d $parent_item_private $item_normal ORDER BY item.id", + intval($parents_str) + ); + + xchan_query($items, true); + $items = fetch_post_tags($items, true); + + $i = Activity::encode_item_collection($items, App::$query_string, 'OrderedCollection', App::$pager['total']); + } + + if ($portable_id && (!intval($items[0]['item_private']))) { + $c = q("select abook_id from abook where abook_channel = %d and abook_xchan = '%s'", + intval($items[0]['uid']), + dbesc($portable_id) + ); + if (!$c) { + ThreadListener::store(z_root() . '/item/' . $item_id, $portable_id); + } + } + + as_return_and_die($i ,$chan); + } + + private function init_as_request() { + + $item_id = argv(1); + if (!$item_id) + http_status_exit(404, 'Not found'); + + $portable_id = EMPTY_STR; + + $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 and item.item_uplink = 0 $item_normal_extra "; + + $i = null; + + // do we have the item (at all)? + // add preferential bias to item owners (item_wall = 1) + + $r = q("select * from item where uuid = '%s' $item_normal order by item_wall desc limit 1", + dbesc($item_id) + ); + + if (!$r) { + http_status_exit(404, 'Not found'); + } + + // process an authenticated fetch + + $sigdata = HTTPSig::verify(EMPTY_STR); + if ($sigdata['portable_id'] && $sigdata['header_valid']) { + $portable_id = $sigdata['portable_id']; + if (!check_channelallowed($portable_id)) { + http_status_exit(403, 'Permission denied'); + } + if (!check_siteallowed($sigdata['signer'])) { + http_status_exit(403, 'Permission denied'); + } + observer_auth($portable_id); + + $i = q("select id as item_id from item where mid = '%s' $item_normal and owner_xchan = '%s' limit 1 ", + dbesc($r[0]['parent_mid']), + dbesc($portable_id) + ); + } + elseif (Config::get('system', 'require_authenticated_fetch', false)) { + http_status_exit(403, 'Permission denied'); + } + + // 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) { + $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']) + ); + } + + $bear = Activity::token_from_request(); + if ($bear) { + logger('bear: ' . $bear, LOGGER_DEBUG); + if (!$i) { + $t = q("select * from iconfig where cat = 'ocap' and k = 'relay' and v = '%s'", + dbesc($bear) + ); + if ($t) { + $i = q("select id as item_id from item where uuid = '%s' and id = %d $item_normal limit 1", + dbesc($item_id), + intval($t[0]['iid']) + ); + } + } + } + + if (!$i) { + http_status_exit(403, 'Forbidden'); + } + + // If we get to this point we have determined we can access the original in $r (fetched much further above), so use it. + + xchan_query($r, true); + $items = fetch_post_tags($r, false); + + $chan = channelx_by_n($items[0]['uid']); + + if (!$chan) + http_status_exit(404, 'Not found'); + + if (!perm_is_allowed($chan['channel_id'], get_observer_hash(), 'view_stream')) + http_status_exit(403, 'Forbidden'); + + $i = Activity::encode_item($items[0]); + + if (!$i) + http_status_exit(404, 'Not found'); + + if ($portable_id && (!intval($items[0]['item_private']))) { + $c = q("select abook_id from abook where abook_channel = %d and abook_xchan = '%s'", + intval($items[0]['uid']), + dbesc($portable_id) + ); + if (!$c) { + ThreadListener::store(z_root() . '/item/' . $item_id, $portable_id); + } + } + + as_return_and_die($i ,$chan); + + } } diff --git a/Zotlabs/Module/Like.php b/Zotlabs/Module/Like.php index 4460900a8..2fb3fab83 100644 --- a/Zotlabs/Module/Like.php +++ b/Zotlabs/Module/Like.php @@ -284,7 +284,7 @@ class Like extends Controller { intval($ch[0]['channel_id']) ); if ($r) - drop_item($r[0]['id'], false); + drop_item($r[0]['id']); if ($interactive) { notice(t('Previous action reversed.') . EOL); return $o; @@ -387,17 +387,20 @@ class Like extends Controller { // already liked it. Drop that item. require_once('include/items.php'); foreach ($r as $rr) { - drop_item($rr['id'], false, DROPITEM_PHASE1); + drop_item($rr['id'], DROPITEM_PHASE1); + // set the changed timestamp on the parent so we'll see the update without a page reload q("update item set changed = '%s' where id = %d and uid = %d", dbesc(datetime_convert()), intval($rr['parent']), intval($rr['uid']) ); + // Prior activity was a duplicate of the one we're submitting, just undo it; // don't fall through and create another - if (activity_match($rr['verb'], $activity)) + if (activity_match($rr['verb'], $activity)) { $multi_undo = false; + } $d = q("select * from item where id = %d", intval($rr['id']) @@ -559,6 +562,7 @@ class Like extends Controller { $post = item_store($arr); $post_id = $post['item_id']; + $approval_id = $post['approval_id'] ?? 0; // save the conversation from expiration @@ -569,6 +573,12 @@ class Like extends Controller { call_hooks('post_local_end', $arr); + if ($is_rsvp && in_array($verb, ['attendyes', 'attendmaybe'])) { + event_addtocal($item_id, local_channel()); + } + + +/* Item sync is now done in item_store() $r = q("select * from item where id = %d", intval($post_id) ); @@ -577,7 +587,7 @@ class Like extends Controller { $sync_item = fetch_post_tags($r); Libsync::build_sync_packet($profile_uid, ['item' => [encode_item($sync_item[0], true)]]); } - +*/ if ($extended_like) { $r = q("insert into likes (channel_id,liker,likee,iid,i_mid,verb,target_type,target_id,target) values (%d,'%s','%s',%d,'%s','%s','%s','%s','%s')", @@ -604,7 +614,10 @@ class Like extends Controller { } - Master::Summon(array('Notifier', 'like', $post_id)); + Master::Summon(['Notifier', 'like', $post_id]); + if ($approval_id) { + Master::Summon(['Notifier', 'like', $approval_id]); + } if ($interactive) { notice(t('Action completed.') . EOL); diff --git a/Zotlabs/Module/Lockview.php b/Zotlabs/Module/Lockview.php index f3ae07f74..4b708a1aa 100644 --- a/Zotlabs/Module/Lockview.php +++ b/Zotlabs/Module/Lockview.php @@ -227,7 +227,7 @@ class Lockview extends Controller { $allowed_xchans = array_unique($allowed_xchans); foreach ($atokens as $atoken) { if (in_array($atoken['xchan_hash'], $allowed_xchans)) { - $guest_access_list[] = '<div class="dropdown-item d-flex justify-content-between cursor-pointer" title="' . sprintf(t('Click to copy link to this ressource for guest %s to clipboard'), $atoken['xchan_name']) . '" data-token="' . $url . '?zat=' . $atoken['atoken_token'] . '" onclick="navigator.clipboard.writeText(this.dataset.token); toast(\'' . t('Link copied') . '\', \'info\');"><span>' . $atoken['xchan_name'] . '</span><i class="fa fa-copy p-1"></i></div>'; + $guest_access_list[] = '<div class="dropdown-item d-flex justify-content-between cursor-pointer" title="' . sprintf(t('Click to copy link to this ressource for guest %s to clipboard'), $atoken['xchan_name']) . '" data-token="' . $url . '?zat=' . $atoken['atoken_token'] . '" onclick="navigator.clipboard.writeText(this.dataset.token); toast(\'' . t('Link copied') . '\', \'info\');"><span>' . $atoken['xchan_name'] . '</span><i class="bi bi-copy p-1"></i></div>'; } } } diff --git a/Zotlabs/Module/Login.php b/Zotlabs/Module/Login.php index 6430939b4..269990a54 100644 --- a/Zotlabs/Module/Login.php +++ b/Zotlabs/Module/Login.php @@ -10,7 +10,16 @@ class Login extends \Zotlabs\Web\Controller { if(remote_channel() && $_SESSION['atoken']) goaway(z_root()); - return login(true); + $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 $o; } - + } diff --git a/Zotlabs/Module/Magic.php b/Zotlabs/Module/Magic.php index 8259f7d39..732488002 100644 --- a/Zotlabs/Module/Magic.php +++ b/Zotlabs/Module/Magic.php @@ -11,37 +11,43 @@ class Magic extends Controller { function init() { - $ret = [ - 'success' => false, - 'url' => '', - 'message' => '' - ]; - logger('mod_magic: invoked', LOGGER_DEBUG); - logger('args: ' . print_r($_REQUEST,true),LOGGER_DATA); + if ($_SERVER['REQUEST_METHOD'] === 'POST') { + $data = $_POST; + } elseif ($_SERVER['REQUEST_METHOD'] === 'GET') { + $data = $_GET; + } else { + http_status_exit(405, 'Method Not Allowed'); + } + + logger('request method: ' . print_r($_SERVER['REQUEST_METHOD'], true), LOGGER_DATA); + logger('args: ' . print_r($data, true), LOGGER_DATA); - $addr = ((x($_REQUEST,'addr')) ? $_REQUEST['addr'] : ''); - $bdest = ((x($_REQUEST,'bdest')) ? $_REQUEST['bdest'] : ''); - $dest = ((x($_REQUEST,'dest')) ? $_REQUEST['dest'] : ''); - $rev = ((x($_REQUEST,'rev')) ? intval($_REQUEST['rev']) : 0); - $owa = ((x($_REQUEST,'owa')) ? intval($_REQUEST['owa']) : 0); - $delegate = ((x($_REQUEST,'delegate')) ? $_REQUEST['delegate'] : ''); + $bdest = $data['bdest'] ?? ''; + $owa = $data['owa'] ?? 0; + $delegate = $data['delegate'] ?? ''; // bdest is preferred as it is hex-encoded and can survive url rewrite and argument parsing - if ($bdest) { - $dest = hex2bin($bdest); + if (!$bdest) { + http_status_exit(400, 'Bad Request'); } + $dest = hex2bin($bdest); $parsed = parse_url($dest); - if (! $parsed) { - goaway($dest); + if (!$parsed) { + http_status_exit(400, 'Bad Request'); } - $basepath = $parsed['scheme'] . '://' . $parsed['host'] . (isset($parsed['port']) ? ':' . $parsed['port'] : ''); - $owapath = SConfig::get($basepath,'system','openwebauth', $basepath . '/owa'); + $basepath = unparse_url(array_filter( + $parsed, + fn (string $key) => in_array($key, ['scheme', 'host', 'port']), + ARRAY_FILTER_USE_KEY + )); + + $owapath = SConfig::get($basepath, 'system', 'openwebauth', $basepath . '/owa'); // This is ready-made for a plugin that provides a blacklist or "ask me" before blindly authenticating. // By default, we'll proceed without asking. @@ -53,12 +59,14 @@ class Magic extends Controller { ]; call_hooks('magic_auth',$arr); + $dest = $arr['destination']; - if (! $arr['proceed']) { + + if (!$arr['proceed']) { goaway($dest); } - if((get_observer_hash()) && (stripos($dest,z_root()) === 0)) { + if (get_observer_hash() && str_starts_with($dest, z_root())) { // We are already authenticated on this site and a registered observer. // First check if this is a delegate request on the local system and process accordingly. @@ -106,29 +114,41 @@ class Magic extends Controller { $headers['Content-Type'] = 'application/x-zot+json' ; $headers['X-Open-Web-Auth'] = random_string(); $headers['Host'] = $parsed['host']; - $headers['(request-target)'] = 'get ' . '/owa'; + $headers['(request-target)'] = 'get /owa'; $headers = HTTPSig::create_sig($headers,$channel['channel_prvkey'], channel_url($channel),true,'sha512'); $redirects = 0; + $x = z_fetch_url($owapath, false, $redirects, ['headers' => $headers]); logger('owa fetch returned: ' . print_r($x,true),LOGGER_DATA); + if ($x['success']) { $j = json_decode($x['body'],true); if ($j['success'] && $j['encrypted_token']) { // decrypt the token using our private key $token = ''; - openssl_private_decrypt(base64url_decode($j['encrypted_token']),$token,$channel['channel_prvkey']); + openssl_private_decrypt(base64url_decode($j['encrypted_token']), $token, $channel['channel_prvkey']); $x = strpbrk($dest,'?&'); // redirect using the encrypted token which will be exchanged for an authenticated session - $args = (($x) ? '&owt=' . $token : '?f=&owt=' . $token) . (($delegate) ? '&delegate=1' : ''); + $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; + } } } } - goaway($dest); + killme(); + } } diff --git a/Zotlabs/Module/Mitem.php b/Zotlabs/Module/Mitem.php index ac7470e13..81787f8c4 100644 --- a/Zotlabs/Module/Mitem.php +++ b/Zotlabs/Module/Mitem.php @@ -184,8 +184,8 @@ class Mitem extends \Zotlabs\Web\Controller { '$nick' => $which, '$sys' => \App::$is_sys )); - - $o .= replace_macros(get_markup_template('mitemlist.tpl'),array( + + return replace_macros(get_markup_template('mitemlist.tpl'),array( '$title' => t('Menu:'), '$create' => $create, '$nametitle' => t('Link Name'), @@ -204,29 +204,27 @@ class Mitem extends \Zotlabs\Web\Controller { '$hintedit' => t('Edit this menu item'), '$nick' => $which, )); - - return $o; } - - + + if(argc() > 3) { if(intval(argv(3))) { - + $m = q("select * from menu_item where mitem_id = %d and mitem_channel_id = %d limit 1", intval(argv(3)), intval($owner) ); - + if(! $m) { notice( t('Menu item not found.') . EOL); goaway(z_root() . '/menu/'. $which . ((\App::$is_sys) ? '?f=&sys=1' : '')); } - + $mitem = $m[0]; - + $lockstate = (($mitem['allow_cid'] || $mitem['allow_gid'] || $mitem['deny_cid'] || $mitem['deny_gid']) ? 'lock' : 'unlock'); - + if(argc() == 5 && argv(4) == 'drop') { menu_sync_packet($owner,get_observer_hash(),$mitem['mitem_menu_id']); $r = menu_del_item($mitem['mitem_menu_id'], $owner, intval(argv(3))); @@ -235,12 +233,12 @@ class Mitem extends \Zotlabs\Web\Controller { info( t('Menu item deleted.') . EOL); else notice( t('Menu item could not be deleted.'). EOL); - + goaway(z_root() . '/mitem/' . $which . '/' . $mitem['mitem_menu_id'] . ((\App::$is_sys) ? '?f=&sys=1' : '')); } - + // edit menu item - $o = replace_macros(get_markup_template('mitemedit.tpl'), array( + return replace_macros(get_markup_template('mitemedit.tpl'), array( '$header' => t('Edit Menu Element'), '$menu_id' => \App::$data['menu']['menu_id'], '$permissions' => t('Menu Item Permissions'), @@ -261,10 +259,8 @@ class Mitem extends \Zotlabs\Web\Controller { '$menu_names' => $menu_names, '$nick' => $which )); - - return $o; } } } - + } diff --git a/Zotlabs/Module/Moderate.php b/Zotlabs/Module/Moderate.php index ed2a1e4f9..2103684ab 100644 --- a/Zotlabs/Module/Moderate.php +++ b/Zotlabs/Module/Moderate.php @@ -74,7 +74,7 @@ class Moderate extends \Zotlabs\Web\Controller { // let the sender know we received their comment but we don't permit spam here. // Activity::send_rejection_activity(App::get_channel(), $item['author_xchan'], $item); - drop_item($post_id,false); + drop_item($post_id); notice( t('Item deleted') . EOL); } diff --git a/Zotlabs/Module/Network.php b/Zotlabs/Module/Network.php index 3ea813547..09a0a6ccc 100644 --- a/Zotlabs/Module/Network.php +++ b/Zotlabs/Module/Network.php @@ -278,32 +278,11 @@ class Network extends \Zotlabs\Web\Controller { $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'); - - $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 "; + $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 "; } 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) "; } } diff --git a/Zotlabs/Module/Notes.php b/Zotlabs/Module/Notes.php index 2fd719f25..ba693e4f2 100644 --- a/Zotlabs/Module/Notes.php +++ b/Zotlabs/Module/Notes.php @@ -13,31 +13,34 @@ class Notes extends Controller { function post() { - if(! local_channel()) - return EMPTY_STR; + if(!local_channel()) { + return; + } - if(! Apps::system_app_installed(local_channel(), 'Notes')) - return EMPTY_STR; + if(!Apps::system_app_installed(local_channel(), 'Notes')) { + return; + } $ret = [ 'success' => false, 'html' => '' ]; - - if(array_key_exists('note_text',$_REQUEST)) { + if (array_key_exists('note_text',$_REQUEST)) { $body = escape_tags($_REQUEST['note_text']); // I've had my notes vanish into thin air twice in four years. // Provide a backup copy if there were contents previously // and there are none being saved now. - if(! $body) { - $old_text = get_pconfig(local_channel(),'notes','text'); - if($old_text) - set_pconfig(local_channel(),'notes','text.bak',$old_text); + if(!$body) { + $old_text = get_pconfig(local_channel(), 'notes', 'text'); + if ($old_text) { + set_pconfig(local_channel(), 'notes', 'text.bak', $old_text); + } } - set_pconfig(local_channel(),'notes','text',$body); + + set_pconfig(local_channel(), 'notes', 'text', $body); $ret['html'] = bbcode($body, ['tryoembed' => false]); $ret['success'] = true; @@ -55,8 +58,9 @@ class Notes extends Controller { } function get() { - if(! local_channel()) + if(!local_channel()) { return EMPTY_STR; + } if(! Apps::system_app_installed(local_channel(), 'Notes')) { //Do not display any associated widgets at this point @@ -65,6 +69,8 @@ class Notes extends Controller { return Apps::app_render($papp, 'module'); } + App::$profile_uid = local_channel(); + $w = new \Zotlabs\Widget\Notes; $arr = ['app' => true]; diff --git a/Zotlabs/Module/Notify.php b/Zotlabs/Module/Notify.php index 0af2ec93a..7a7becbc8 100644 --- a/Zotlabs/Module/Notify.php +++ b/Zotlabs/Module/Notify.php @@ -1,8 +1,8 @@ <?php namespace Zotlabs\Module; -use \Zotlabs\Lib\PConfig; -use \Zotlabs\Web\Controller; +use Zotlabs\Lib\PConfig; +use Zotlabs\Web\Controller; class Notify extends Controller { diff --git a/Zotlabs/Module/OAuth2TestVehicle.php b/Zotlabs/Module/OAuth2TestVehicle.php index 5ae278e8c..57cda3c28 100644 --- a/Zotlabs/Module/OAuth2TestVehicle.php +++ b/Zotlabs/Module/OAuth2TestVehicle.php @@ -31,8 +31,8 @@ class OAuth2TestVehicle extends \Zotlabs\Web\Controller { $_SESSION['api_response'] = (x($_SESSION, 'api_response') ? $_SESSION['api_response'] : ''); } function get() { - - $o .= replace_macros(get_markup_template('oauth2testvehicle.tpl'), array( + + $output = replace_macros(get_markup_template('oauth2testvehicle.tpl'), array( '$baseurl' => z_root(), '$api_response' => $_SESSION['api_response'], /* @@ -97,8 +97,10 @@ class OAuth2TestVehicle extends \Zotlabs\Web\Controller { ) ) )); + $_SESSION['success'] = ''; - return $o; + + return $output; } function post() { diff --git a/Zotlabs/Module/Oauth.php b/Zotlabs/Module/Oauth.php index 061296257..6063c7738 100644 --- a/Zotlabs/Module/Oauth.php +++ b/Zotlabs/Module/Oauth.php @@ -103,7 +103,8 @@ class Oauth extends Controller { if((argc() > 1) && (argv(1) === 'add')) { $tpl = get_markup_template("oauth_edit.tpl"); - $o .= replace_macros($tpl, array( + + return replace_macros($tpl, array( '$form_security_token' => get_form_security_token("oauth"), '$title' => t('Add application'), '$submit' => t('Submit'), @@ -114,7 +115,6 @@ class Oauth extends Controller { '$redirect' => array('redirect', t('Redirect'), '', t('Redirect URI - leave blank unless your application specifically requires this')), '$icon' => array('icon', t('Icon url'), '', t('Optional')), )); - return $o; } if((argc() > 2) && (argv(1) === 'edit')) { @@ -129,7 +129,7 @@ class Oauth extends Controller { $app = $r[0]; $tpl = get_markup_template("oauth_edit.tpl"); - $o .= replace_macros($tpl, array( + return replace_macros($tpl, array( '$form_security_token' => get_form_security_token("oauth"), '$title' => t('Add application'), '$submit' => t('Update'), @@ -140,7 +140,6 @@ class Oauth extends Controller { '$redirect' => array('redirect', t('Redirect'), $app['redirect_uri'], ''), '$icon' => array('icon', t('Icon url'), $app['icon'], ''), )); - return $o; } if((argc() > 2) && (argv(1) === 'delete')) { @@ -163,7 +162,8 @@ class Oauth extends Controller { $tpl = get_markup_template("oauth.tpl"); - $o .= replace_macros($tpl, array( + + return replace_macros($tpl, array( '$form_security_token' => get_form_security_token("oauth"), '$baseurl' => z_root(), '$title' => t('Connected OAuth Apps'), @@ -175,8 +175,6 @@ class Oauth extends Controller { '$remove' => t('Remove authorization'), '$apps' => $r, )); - return $o; - } } diff --git a/Zotlabs/Module/Oauth2.php b/Zotlabs/Module/Oauth2.php index 4b0b1991e..7aadd91bc 100644 --- a/Zotlabs/Module/Oauth2.php +++ b/Zotlabs/Module/Oauth2.php @@ -108,7 +108,8 @@ class Oauth2 extends Controller { if((argc() > 1) && (argv(1) === 'add')) { $tpl = get_markup_template("oauth2_edit.tpl"); - $o .= replace_macros($tpl, array( + + return replace_macros($tpl, array( '$form_security_token' => get_form_security_token("oauth2"), '$title' => t('Add OAuth2 application'), '$submit' => t('Submit'), @@ -119,7 +120,6 @@ class Oauth2 extends Controller { '$grant' => array('grant', t('Grant Types'), '', t('leave blank unless your application sepcifically requires this')), '$scope' => array('scope', t('Authorization scope'), '', t('leave blank unless your application sepcifically requires this')), )); - return $o; } if((argc() > 2) && (argv(1) === 'edit')) { @@ -136,7 +136,7 @@ class Oauth2 extends Controller { $app = $r[0]; $tpl = get_markup_template("oauth2_edit.tpl"); - $o .= replace_macros($tpl, array( + return replace_macros($tpl, array( '$form_security_token' => get_form_security_token("oauth2"), '$title' => t('Add application'), '$submit' => t('Update'), @@ -147,7 +147,6 @@ class Oauth2 extends Controller { '$grant' => array('grant', t('Grant Types'), $app['grant_types'], t('leave blank unless your application specifically requires this')), '$scope' => array('scope', t('Authorization scope'), $app['scope'], t('leave blank unless your application specifically requires this')), )); - return $o; } if((argc() > 2) && (argv(1) === 'delete')) { @@ -184,7 +183,8 @@ class Oauth2 extends Controller { ); $tpl = get_markup_template("oauth2.tpl"); - $o .= replace_macros($tpl, array( + + return replace_macros($tpl, array( '$form_security_token' => get_form_security_token("oauth2"), '$baseurl' => z_root(), '$title' => t('Connected OAuth2 Apps'), @@ -196,8 +196,6 @@ class Oauth2 extends Controller { '$remove' => t('Remove authorization'), '$apps' => $r, )); - return $o; - } } 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/Page.php b/Zotlabs/Module/Page.php index 8a698005a..a4ee5eaa2 100644 --- a/Zotlabs/Module/Page.php +++ b/Zotlabs/Module/Page.php @@ -183,9 +183,7 @@ class Page extends \Zotlabs\Web\Controller { if($r[0]['mimetype'] === 'application/x-pdl') \App::$page['pdl_content'] = true; - $o .= prepare_page($r[0]); - return $o; - + return prepare_page($r[0]); } } diff --git a/Zotlabs/Module/Pdledit.php b/Zotlabs/Module/Pdledit.php index e0bbc31d0..aa512e6da 100644 --- a/Zotlabs/Module/Pdledit.php +++ b/Zotlabs/Module/Pdledit.php @@ -51,7 +51,7 @@ class Pdledit extends Controller { if(argc() > 1) $module = 'mod_' . argv(1) . '.pdl'; else { - $o .= '<div class="generic-content-wrapper-styled">'; + $o = '<div class="generic-content-wrapper-styled">'; $o .= '<h1>' . t('Edit System Page Description') . '</h1>'; $edited = []; diff --git a/Zotlabs/Module/Permcat.php b/Zotlabs/Module/Permcat.php index 064c9cefb..0335c7bc6 100644 --- a/Zotlabs/Module/Permcat.php +++ b/Zotlabs/Module/Permcat.php @@ -2,7 +2,7 @@ namespace Zotlabs\Module; -use \Zotlabs\Lib as Zlib; +use Zotlabs\Lib as Zlib; class Permcat extends \Zotlabs\Web\Controller { @@ -22,4 +22,4 @@ class Permcat extends \Zotlabs\Web\Controller { } -}
\ No newline at end of file +} diff --git a/Zotlabs/Module/Photos.php b/Zotlabs/Module/Photos.php index 870a2cb79..e31aa9dc1 100644 --- a/Zotlabs/Module/Photos.php +++ b/Zotlabs/Module/Photos.php @@ -1122,7 +1122,7 @@ class Photos extends \Zotlabs\Web\Controller { if(is_array($like_list) && (count($like_list) > MAX_LIKERS)) { $like_list_part = array_slice($like_list, 0, MAX_LIKERS); - array_push($like_list_part, '<a href="#" data-toggle="modal" data-target="#likeModal-' . $this->get_id() . '"><b>' . t('View all') . '</b></a>'); + array_push($like_list_part, '<a href="#" data-bs-toggle="modal" data-bs-target="#likeModal-' . $link_item['id'] . '"><b>' . t('View all') . '</b></a>'); } else { $like_list_part = ''; } @@ -1134,7 +1134,7 @@ class Photos extends \Zotlabs\Web\Controller { $dislike_button_label = tt('Dislike','Dislikes',$dislike_count,'noun'); if (is_array($dislike_list) && (count($dislike_list) > MAX_LIKERS)) { $dislike_list_part = array_slice($dislike_list, 0, MAX_LIKERS); - array_push($dislike_list_part, '<a href="#" data-toggle="modal" data-target="#dislikeModal-' . $this->get_id() . '"><b>' . t('View all') . '</b></a>'); + array_push($dislike_list_part, '<a href="#" data-bs-toggle="modal" data-bs-target="#dislikeModal-' . $link_item['id'] . '"><b>' . t('View all') . '</b></a>'); } else { $dislike_list_part = ''; } diff --git a/Zotlabs/Module/Profperm.php b/Zotlabs/Module/Profperm.php index 842197415..4594728b1 100644 --- a/Zotlabs/Module/Profperm.php +++ b/Zotlabs/Module/Profperm.php @@ -55,6 +55,8 @@ class Profperm extends \Zotlabs\Web\Controller { } + $o = ''; + if((argc() > 1) && (intval(argv(1)))) { $r = q("SELECT * FROM profile WHERE id = %d AND uid = %d AND is_default = 0 LIMIT 1", intval(argv(1)), diff --git a/Zotlabs/Module/Pubsites.php b/Zotlabs/Module/Pubsites.php index cbaa66042..f58b4adff 100644 --- a/Zotlabs/Module/Pubsites.php +++ b/Zotlabs/Module/Pubsites.php @@ -49,18 +49,18 @@ class Pubsites extends \Zotlabs\Web\Controller { } $m = parse_url($jj['url']); $host = strtolower(substr($jj['url'],strpos($jj['url'],'://')+3)); - $rate_links = ((local_channel()) ? '<td><a href="rate?f=&target=' . $host . '" class="btn-btn-default"><i class="fa fa-check-square-o"></i> ' . t('Rate') . '</a></td>' : ''); + $rate_links = ((local_channel()) ? '<td><a href="rate?f=&target=' . $host . '" class="btn-btn-default"><i class="bi bi-check-square"></i> ' . t('Rate') . '</a></td>' : ''); $location = ''; if(!empty($jj['location'])) { - $location = '<p title="' . t('Location') . '" style="margin: 5px 5px 0 0; text-align: right"><i class="fa fa-globe"></i> ' . $jj['location'] . '</p>'; + $location = '<p title="' . t('Location') . '" style="margin: 5px 5px 0 0; text-align: right"><i class="bi bi-globe"></i> ' . $jj['location'] . '</p>'; } else { $location = '<br /> '; } $urltext = str_replace(array('https://'), '', $jj['url']); - $o .= '<tr><td><a href="'. (($jj['sellpage']) ? $jj['sellpage'] : $jj['url'] . '/register' ) . '" ><i class="fa fa-link"></i> ' . $urltext . '</a>' . $location . '</td><td>' . $jj['access'] . '</td><td>' . $jj['register'] . '</td><!--td>' . '<a target="stats" href="https://hubchart-tarine.rhcloud.com/hub.jsp?hubFqdn=' . $m['host'] . '"><i class="fa fa-area-chart"></i></a></td--><td>' . ucwords($jj['project']) . (($jj['version']) ? ' ' . $jj['version'] : '') . '</td>'; + $o .= '<tr><td><a href="'. (($jj['sellpage']) ? $jj['sellpage'] : $jj['url'] . '/register' ) . '" ><i class="bi bi-link-45deg"></i> ' . $urltext . '</a>' . $location . '</td><td>' . $jj['access'] . '</td><td>' . $jj['register'] . '</td><!--td>' . '<a target="stats" href="https://hubchart-tarine.rhcloud.com/hub.jsp?hubFqdn=' . $m['host'] . '"><i class="bi bi-graph-up"></i></a></td--><td>' . ucwords($jj['project']) . (($jj['version']) ? ' ' . $jj['version'] : '') . '</td>'; if($rating_enabled) - $o .= '<td><a href="ratings/' . $host . '" class="btn-btn-default"><i class="fa fa-eye"></i> ' . t('View') . '</a></td>' . $rate_links ; + $o .= '<td><a href="ratings/' . $host . '" class="btn-btn-default"><i class="bi bi-eye"></i> ' . t('View') . '</a></td>' . $rate_links ; $o .= '</tr>'; } } diff --git a/Zotlabs/Module/Pubstream.php b/Zotlabs/Module/Pubstream.php index 6d8edf4d8..234e73792 100644 --- a/Zotlabs/Module/Pubstream.php +++ b/Zotlabs/Module/Pubstream.php @@ -202,11 +202,9 @@ 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 - and xchan.xchan_censored = 0 and (abook.abook_blocked = 0 or abook.abook_flags is null) $sql_extra $net_query2", dbesc($mid) @@ -216,11 +214,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 +227,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 +237,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" ); diff --git a/Zotlabs/Module/React.php b/Zotlabs/Module/React.php index e04b9b257..e1abd242e 100644 --- a/Zotlabs/Module/React.php +++ b/Zotlabs/Module/React.php @@ -91,6 +91,9 @@ class React extends Controller { if ($x['success']) { $nid = $x['item_id']; Master::Summon(['Notifier', 'like', $nid]); + if (!empty($x['approval_id'])) { + Master::Summon(['Notifier', 'like', $x['approval_id']]); + } } } diff --git a/Zotlabs/Module/Removeaccount.php b/Zotlabs/Module/Removeaccount.php index cd18b79c0..b41acb8b0 100644 --- a/Zotlabs/Module/Removeaccount.php +++ b/Zotlabs/Module/Removeaccount.php @@ -36,22 +36,22 @@ class Removeaccount extends \Zotlabs\Web\Controller { return; } } - + $global_remove = 0; //intval($_POST['global']); - - account_remove($account_id, 1 - $global_remove); + + account_remove($account_id, 1 - $global_remove); } - + function get() { - + if(! local_channel()) goaway(z_root()); - + $hash = random_string(); - + $_SESSION['remove_account_verify'] = $hash; $tpl = get_markup_template('removeaccount.tpl'); - $o .= replace_macros($tpl, array( + return replace_macros($tpl, array( '$basedir' => z_root(), '$hash' => $hash, '$title' => t('Remove This Account'), @@ -60,9 +60,5 @@ class Removeaccount extends \Zotlabs\Web\Controller { // '$global' => array('global', t('Remove this account, all its channels and all its channel clones from the network'), false, t('By default only the instances of the channels located on this hub will be removed from the network')), '$submit' => t('Remove Account') )); - - return $o; - } - } diff --git a/Zotlabs/Module/Removeme.php b/Zotlabs/Module/Removeme.php index 4d475ead6..d71f8d4ab 100644 --- a/Zotlabs/Module/Removeme.php +++ b/Zotlabs/Module/Removeme.php @@ -54,7 +54,7 @@ class Removeme extends \Zotlabs\Web\Controller { $_SESSION['remove_account_verify'] = $hash; $tpl = get_markup_template('removeme.tpl'); - $o .= replace_macros($tpl, array( + return replace_macros($tpl, array( '$basedir' => z_root(), '$hash' => $hash, '$title' => t('Remove Channel'), @@ -63,9 +63,5 @@ class Removeme extends \Zotlabs\Web\Controller { // '$global' => [ 'global', t('Remove this channel and all its clones from the network'), false, t('By default only the instance of the channel located on this hub will be removed from the network'), [ t('No'),t('Yes') ] ], '$submit' => t('Remove Channel') )); - - return $o; - } - } diff --git a/Zotlabs/Module/Rmagic.php b/Zotlabs/Module/Rmagic.php index 90cf8b854..4254dd38b 100644 --- a/Zotlabs/Module/Rmagic.php +++ b/Zotlabs/Module/Rmagic.php @@ -29,7 +29,7 @@ class Rmagic extends \Zotlabs\Web\Controller { if($r['hubloc_url'] === z_root()) goaway(z_root() . '/login'); $dest = bin2hex(z_root() . '/' . str_replace(['rmagic','zid='],['','zid_='],\App::$query_string)); - goaway($r['hubloc_url'] . '/magic' . '?f=&owa=1&bdest=' . $dest); + goaway($r['hubloc_url'] . '/magic?owa=1&bdest=' . $dest); } } } @@ -84,7 +84,7 @@ class Rmagic extends \Zotlabs\Web\Controller { else $dest = bin2hex(z_root() . '/' . str_replace([ 'rmagic', 'zid=' ] ,[ '', 'zid_='],\App::$query_string)); - goaway($url . '/magic' . '?f=&owa=1&bdest=' . $dest); + goaway($url . '/magic?owa=1&bdest=' . $dest); } } } diff --git a/Zotlabs/Module/Search_ac.php b/Zotlabs/Module/Search_ac.php index 24b724c5d..cd0960859 100644 --- a/Zotlabs/Module/Search_ac.php +++ b/Zotlabs/Module/Search_ac.php @@ -90,12 +90,7 @@ class Search_ac extends \Zotlabs\Web\Controller { 'items' => $results, ); echo json_encode($o); - - logger('search_ac: ' . print_r($x,true),LOGGER_DATA,LOG_INFO); - + killme(); } - - - } diff --git a/Zotlabs/Module/Settings/Account.php b/Zotlabs/Module/Settings/Account.php index 0266cee12..7f0d11069 100644 --- a/Zotlabs/Module/Settings/Account.php +++ b/Zotlabs/Module/Settings/Account.php @@ -100,7 +100,7 @@ class Account { $attremail = ((!strpos($email, '@')) ? 'disabled="disabled"' : ''); $tpl = get_markup_template("settings_account.tpl"); - $o .= replace_macros($tpl, array( + return replace_macros($tpl, array( '$form_security_token' => get_form_security_token("settings_account"), '$title' => t('Account Settings'), '$origpass' => array('origpass', t('Current Password'), ' ',''), @@ -114,7 +114,5 @@ class Account { '$removeaccount' => t('Remove this account including all its channels'), '$account_settings' => $account_settings )); - return $o; } - } diff --git a/Zotlabs/Module/Settings/Calendar.php b/Zotlabs/Module/Settings/Calendar.php index 65240c635..3b15f4aa6 100644 --- a/Zotlabs/Module/Settings/Calendar.php +++ b/Zotlabs/Module/Settings/Calendar.php @@ -33,7 +33,7 @@ class Calendar { $tpl = get_markup_template("settings_module.tpl"); - $o .= replace_macros($tpl, array( + return replace_macros($tpl, array( '$rpath' => escape_url($rpath), '$action_url' => 'settings/' . $module, '$form_security_token' => get_form_security_token('settings_' . $module), @@ -41,8 +41,5 @@ class Calendar { '$features' => process_module_features_get(local_channel(), $features), '$submit' => t('Submit') )); - - return $o; } - } diff --git a/Zotlabs/Module/Settings/Channel_home.php b/Zotlabs/Module/Settings/Channel_home.php index 470dbe4c3..388b70942 100644 --- a/Zotlabs/Module/Settings/Channel_home.php +++ b/Zotlabs/Module/Settings/Channel_home.php @@ -81,7 +81,7 @@ class Channel_home { $tpl = get_markup_template("settings_module.tpl"); - $o .= replace_macros($tpl, array( + return replace_macros($tpl, array( '$rpath' => escape_url($rpath), '$action_url' => 'settings/' . $module, '$form_security_token' => get_form_security_token('settings_' . $module), @@ -90,8 +90,5 @@ class Channel_home { '$extra_settings_html' => $extra_settings_html, '$submit' => t('Submit') )); - - return $o; } - } diff --git a/Zotlabs/Module/Settings/Connections.php b/Zotlabs/Module/Settings/Connections.php index 52a95a3d1..9d1069cf3 100644 --- a/Zotlabs/Module/Settings/Connections.php +++ b/Zotlabs/Module/Settings/Connections.php @@ -33,7 +33,7 @@ class Connections { $tpl = get_markup_template("settings_module.tpl"); - $o .= replace_macros($tpl, array( + return replace_macros($tpl, array( '$rpath' => escape_url($rpath), '$action_url' => 'settings/' . $module, '$form_security_token' => get_form_security_token('settings_' . $module), @@ -41,8 +41,5 @@ class Connections { '$features' => process_module_features_get(local_channel(), $features), '$submit' => t('Submit') )); - - return $o; } - } diff --git a/Zotlabs/Module/Settings/Conversation.php b/Zotlabs/Module/Settings/Conversation.php index aa0ff6a7e..51ee2c83a 100644 --- a/Zotlabs/Module/Settings/Conversation.php +++ b/Zotlabs/Module/Settings/Conversation.php @@ -11,24 +11,19 @@ class Conversation { $module = substr(strrchr(strtolower(static::class), '\\'), 1); check_form_security_token_redirectOnErr('/settings/' . $module, 'settings_' . $module); - + $features = get_module_features($module); process_module_features_post(local_channel(), $features, $_POST); - + Libsync::build_sync_packet(); - - if($_POST['aj']) { - if($_POST['auto_update'] == 1) - info(t('Settings saved.') . EOL); - else - info(t('Settings saved. Reload page please.') . EOL); + if($_POST['aj']) { killme(); } - else { - return; - } + + return; + } function get() { @@ -41,14 +36,14 @@ class Conversation { $tpl = (($aj) ? get_markup_template("settings_module_ajax.tpl") : get_markup_template("settings_module.tpl")); - $o .= replace_macros($tpl, array( + $o = replace_macros($tpl, array( '$action_url' => 'settings/' . $module, '$form_security_token' => get_form_security_token('settings_' . $module), '$title' => t('Conversation Settings'), '$features' => process_module_features_get(local_channel(), $features), '$submit' => t('Submit') )); - + if($aj) { echo $o; killme(); diff --git a/Zotlabs/Module/Settings/Directory.php b/Zotlabs/Module/Settings/Directory.php index 09ea61f60..e1957d2fa 100644 --- a/Zotlabs/Module/Settings/Directory.php +++ b/Zotlabs/Module/Settings/Directory.php @@ -33,7 +33,7 @@ class Directory { $tpl = get_markup_template("settings_module.tpl"); - $o .= replace_macros($tpl, array( + return replace_macros($tpl, array( '$rpath' => escape_url($rpath), '$action_url' => 'settings/' . $module, '$form_security_token' => get_form_security_token('settings_' . $module), @@ -41,8 +41,5 @@ class Directory { '$features' => process_module_features_get(local_channel(), $features), '$submit' => t('Submit') )); - - return $o; } - } diff --git a/Zotlabs/Module/Settings/Editor.php b/Zotlabs/Module/Settings/Editor.php index 85c3e69ae..50bd2b2ad 100644 --- a/Zotlabs/Module/Settings/Editor.php +++ b/Zotlabs/Module/Settings/Editor.php @@ -33,7 +33,7 @@ class Editor { $tpl = get_markup_template("settings_module.tpl"); - $o .= replace_macros($tpl, array( + return replace_macros($tpl, array( '$rpath' => escape_url($rpath), '$action_url' => 'settings/' . $module, '$form_security_token' => get_form_security_token('settings_' . $module), @@ -41,8 +41,5 @@ class Editor { '$features' => process_module_features_get(local_channel(), $features), '$submit' => t('Submit') )); - - return $o; } - } diff --git a/Zotlabs/Module/Settings/Events.php b/Zotlabs/Module/Settings/Events.php index 0a0e3516c..3a7faa8b4 100644 --- a/Zotlabs/Module/Settings/Events.php +++ b/Zotlabs/Module/Settings/Events.php @@ -33,7 +33,7 @@ class Events { $tpl = get_markup_template("settings_module.tpl"); - $o .= replace_macros($tpl, array( + return replace_macros($tpl, array( '$rpath' => escape_url($rpath), '$action_url' => 'settings/' . $module, '$form_security_token' => get_form_security_token('settings_' . $module), @@ -41,8 +41,5 @@ class Events { '$features' => process_module_features_get(local_channel(), $features), '$submit' => t('Submit') )); - - return $o; } - } diff --git a/Zotlabs/Module/Settings/Features.php b/Zotlabs/Module/Settings/Features.php index 553ff0836..84c868e48 100644 --- a/Zotlabs/Module/Settings/Features.php +++ b/Zotlabs/Module/Settings/Features.php @@ -38,17 +38,14 @@ class Features { $arr[$fname][1][] = array('feature_' . $f[0],$f[1],((intval(feature_enabled(local_channel(),$f[0]))) ? "1" : ''),$f[2],array(t('Off'),t('On'))); } } - + $tpl = get_markup_template("settings_features.tpl"); - $o .= replace_macros($tpl, array( + return replace_macros($tpl, array( '$form_security_token' => get_form_security_token("settings_features"), '$title' => t('Additional Features'), '$features' => $arr, '$baseurl' => z_root(), '$submit' => t('Submit'), )); - - return $o; } - } diff --git a/Zotlabs/Module/Settings/Manage.php b/Zotlabs/Module/Settings/Manage.php index 6fb57eafb..6e47cfcc7 100644 --- a/Zotlabs/Module/Settings/Manage.php +++ b/Zotlabs/Module/Settings/Manage.php @@ -34,7 +34,7 @@ class Manage { $tpl = get_markup_template("settings_module.tpl"); - $o .= replace_macros($tpl, array( + return replace_macros($tpl, array( '$rpath' => escape_url($rpath), '$action_url' => 'settings/' . $module, '$form_security_token' => get_form_security_token('settings_' . $module), @@ -42,8 +42,5 @@ class Manage { '$features' => process_module_features_get(local_channel(), $features), '$submit' => t('Submit') )); - - return $o; } - } diff --git a/Zotlabs/Module/Settings/Network.php b/Zotlabs/Module/Settings/Network.php index eae963a25..39c66622e 100644 --- a/Zotlabs/Module/Settings/Network.php +++ b/Zotlabs/Module/Settings/Network.php @@ -52,7 +52,7 @@ class Network { $tpl = get_markup_template("settings_module.tpl"); - $o .= replace_macros($tpl, array( + return replace_macros($tpl, array( '$rpath' => escape_url($rpath), '$action_url' => 'settings/' . $module, '$form_security_token' => get_form_security_token('settings_' . $module), @@ -61,8 +61,5 @@ class Network { '$extra_settings_html' => $extra_settings_html, '$submit' => t('Submit') )); - - return $o; } - } diff --git a/Zotlabs/Module/Settings/Photos.php b/Zotlabs/Module/Settings/Photos.php index f68c8847b..05c380850 100644 --- a/Zotlabs/Module/Settings/Photos.php +++ b/Zotlabs/Module/Settings/Photos.php @@ -33,7 +33,7 @@ class Photos { $tpl = get_markup_template("settings_module.tpl"); - $o .= replace_macros($tpl, array( + return replace_macros($tpl, array( '$rpath' => escape_url($rpath), '$action_url' => 'settings/' . $module, '$form_security_token' => get_form_security_token('settings_' . $module), @@ -41,8 +41,5 @@ class Photos { '$features' => process_module_features_get(local_channel(), $features), '$submit' => t('Submit') )); - - return $o; } - } diff --git a/Zotlabs/Module/Settings/Profiles.php b/Zotlabs/Module/Settings/Profiles.php index 0ff2dfb6d..5052385a8 100644 --- a/Zotlabs/Module/Settings/Profiles.php +++ b/Zotlabs/Module/Settings/Profiles.php @@ -42,7 +42,7 @@ class Profiles { $tpl = get_markup_template("settings_module.tpl"); - $o .= replace_macros($tpl, array( + return replace_macros($tpl, array( '$rpath' => escape_url($rpath), '$action_url' => 'settings/' . $module, '$form_security_token' => get_form_security_token('settings_' . $module), @@ -51,8 +51,5 @@ class Profiles { '$extra_settings_html' => $extra_settings_html, '$submit' => t('Submit') )); - - return $o; } - } diff --git a/Zotlabs/Module/Setup.php b/Zotlabs/Module/Setup.php index 35079e5e5..5b423f67d 100644 --- a/Zotlabs/Module/Setup.php +++ b/Zotlabs/Module/Setup.php @@ -263,7 +263,10 @@ class Setup extends \Zotlabs\Web\Controller { $this->check_htaccess($checks); - $checkspassed = array_reduce($checks, "self::check_passed", true); + $checkspassed = array_reduce( + $checks, + "Zotlabs\Module\Setup::check_passed", + true); $tpl = get_markup_template('install_checks.tpl'); $o .= replace_macros($tpl, array( diff --git a/Zotlabs/Module/Share.php b/Zotlabs/Module/Share.php index ea9313fa8..4fefdb4ef 100644 --- a/Zotlabs/Module/Share.php +++ b/Zotlabs/Module/Share.php @@ -94,6 +94,12 @@ class Share extends \Zotlabs\Web\Controller { else killme(); + $object = Activity::fetch_item([ 'id' => $item['mid'] ]); + + if (!$object) { + killme(); + } + $arr['aid'] = $item['aid']; $arr['uid'] = $item['uid']; @@ -121,7 +127,7 @@ class Share extends \Zotlabs\Web\Controller { $arr['owner_xchan'] = $item['author_xchan']; $arr['source_xchan'] = ''; - $arr['obj'] = $item['obj']; + $arr['obj'] = $object; $arr['obj_type'] = $item['obj_type']; $arr['verb'] = ACTIVITY_SHARE; @@ -130,6 +136,7 @@ class Share extends \Zotlabs\Web\Controller { $post = item_store($arr); $post_id = $post['item_id']; + $approval_id = $post['approval_id'] ?? 0; $arr['id'] = $post_id; @@ -137,6 +144,7 @@ class Share extends \Zotlabs\Web\Controller { // info( t('Post repeated') . EOL); +/* $r = q("select * from item where id = %d", intval($post_id) ); @@ -145,8 +153,12 @@ class Share extends \Zotlabs\Web\Controller { $sync_item = fetch_post_tags($r); Libsync::build_sync_packet($channel['channel_id'], [ 'item' => [ encode_item($sync_item[0],true) ] ]); } +*/ Master::Summon([ 'Notifier', 'like', $post_id ]); + if ($approval_id) { + Master::Summon(['Notifier', 'like', $approval_id]); + } killme(); diff --git a/Zotlabs/Module/Snap.php b/Zotlabs/Module/Snap.php index 89aebc097..770ba07c2 100644 --- a/Zotlabs/Module/Snap.php +++ b/Zotlabs/Module/Snap.php @@ -8,8 +8,8 @@ namespace Zotlabs\Module; * Module for accessing the DAV storage area from a DAV client. */ -use \Sabre\DAV as SDAV; -use \Zotlabs\Storage; +use Sabre\DAV as SDAV; +use Zotlabs\Storage; // composer autoloader for SabreDAV require_once('vendor/autoload.php'); @@ -24,7 +24,7 @@ require_once('vendor/autoload.php'); class Snap extends \Zotlabs\Web\Controller { function init() { - + // workaround for HTTP-auth in CGI mode if (x($_SERVER, 'REDIRECT_REMOTE_USER')) { $userpass = base64_decode(substr($_SERVER["REDIRECT_REMOTE_USER"], 6)) ; @@ -43,20 +43,20 @@ class Snap extends \Zotlabs\Web\Controller { $_SERVER['PHP_AUTH_PW'] = $password; } } - + if (! is_dir('store')) os_mkdir('store', STORAGE_DEFAULT_PERMISSIONS, false); - + $which = null; if (argc() > 1) $which = argv(1); - + $profile = 0; - + if($which) profile_load( $which, $profile); else - killme(); + killme(); if($_SERVER['PHP_AUTH_USER'] && $_SERVER['PHP_AUTH_USER'] !== $which) killme(); @@ -68,7 +68,7 @@ class Snap extends \Zotlabs\Web\Controller { } if(! in_array(strtolower($_SERVER['REQUEST_METHOD']),['propfind','get','head'])) - killme(); + killme(); $auth = new \Zotlabs\Storage\BasicAuth(); $auth->setRealm(ucfirst(\Zotlabs\Lib\System::get_platform_name()) . 'WebDAV'); @@ -101,5 +101,5 @@ class Snap extends \Zotlabs\Web\Controller { killme(); } - + } diff --git a/Zotlabs/Module/Sse.php b/Zotlabs/Module/Sse.php index 5baa90128..673457db1 100644 --- a/Zotlabs/Module/Sse.php +++ b/Zotlabs/Module/Sse.php @@ -19,25 +19,20 @@ class Sse extends Controller { function init() { + // This is important! + session_write_close(); + ignore_user_abort(true); + if((observer_prohibited(true))) { killme(); } - if(! intval(Config::Get('system','open_pubstream',1))) { - if(! get_observer_hash()) { - killme(); - } - } - - // this is important! - session_write_close(); - self::$uid = local_channel(); self::$ob_hash = get_observer_hash(); self::$sse_id = false; self::$vnotify = -1; - if(! self::$ob_hash) { + if (!self::$ob_hash) { if(session_id()) { self::$sse_id = true; self::$ob_hash = 'sse_id.' . session_id(); @@ -55,7 +50,7 @@ class Sse extends Controller { self::$sse_enabled = Config::Get('system', 'sse_enabled', 0); - if(self::$sse_enabled) { + if (self::$sse_enabled) { // Server Sent Events @@ -73,7 +68,7 @@ class Sse extends Controller { $i = 0; } - if(!self::$sse_id && $i === 0) { + if (!self::$sse_id && $i === 0) { // Update chat presence indication about once per minute $r = q("select cp_id, cp_room from chatpresence where cp_xchan = '%s' and cp_client = '%s' and cp_room = 0 limit 1", dbesc(self::$ob_hash), @@ -82,7 +77,7 @@ class Sse extends Controller { $basic_presence = false; - if($r) { + if ($r) { $basic_presence = true; q("update chatpresence set cp_last = '%s' where cp_id = %d", dbesc(datetime_convert()), @@ -90,7 +85,7 @@ class Sse extends Controller { ); } - if(!$basic_presence) { + if (!$basic_presence) { q("insert into chatpresence ( cp_xchan, cp_last, cp_status, cp_client) values( '%s', '%s', '%s', '%s' ) ", dbesc(self::$ob_hash), @@ -101,16 +96,16 @@ class Sse extends Controller { } } + $result = []; + XConfig::Load(self::$ob_hash); - $result = []; $lock = XConfig::Get(self::$ob_hash, 'sse', 'lock'); if (!$lock) { $result = XConfig::Get(self::$ob_hash, 'sse', 'notifications', []); } - // We do not have the local_channel in the addon. // Reset pubs here if the app is not installed. if (self::$uid && (!(self::$vnotify & VNOTIFY_PUBS) || !Apps::system_app_installed(self::$uid, 'Public Stream'))) { @@ -119,42 +114,61 @@ class Sse extends Controller { } } - if($result) { + if ($result) { echo "event: notifications\n"; echo 'data: ' . json_encode($result); echo "\n\n"; - - XConfig::Set(self::$ob_hash, 'sse', 'notifications', []); - unset($result); + } + else { + // if no result we will send a heartbeat to keep connected + echo "event: heartbeat\n"; + echo 'data: {}'; + echo "\n\n"; } - // always send heartbeat to detect disconnected clients - echo "event: heartbeat\n"; - echo 'data: {}'; - echo "\n\n"; + if (connection_status() != CONNECTION_NORMAL || connection_aborted()) { - if(ob_get_length() > 0) - ob_end_flush(); + // In case session_write_close() failed for some reason and + // the channel was changed we might need to reset the + // session to it's current stored state here. + // Otherwise the uid might switch back to the previous value + // in the background. - flush(); + session_reset(); - if(connection_status() != CONNECTION_NORMAL || connection_aborted()) { - //TODO: this does not seem to be triggered XConfig::Set(self::$ob_hash, 'sse', 'timestamp', NULL_DATE); - break; + XConfig::Set(self::$ob_hash, 'sse', 'notifications', []); + + if (ob_get_length() > 0) { + ob_end_flush(); + } + + flush(); + + exit; } - $i++; + if (ob_get_length() > 0) { + ob_flush(); + } + + flush(); usleep($sleep); + if ($result) { + XConfig::Set(self::$ob_hash, 'sse', 'notifications', []); + } + + $i++; + } } else { // Fallback to traditional polling - if(! self::$sse_id) { + if(!self::$sse_id) { // Update chat presence indication @@ -163,14 +177,14 @@ class Sse extends Controller { dbesc($_SERVER['REMOTE_ADDR']) ); $basic_presence = false; - if($r) { + if ($r) { $basic_presence = true; q("update chatpresence set cp_last = '%s' where cp_id = %d", dbesc(datetime_convert()), intval($r[0]['cp_id']) ); } - if(! $basic_presence) { + if (!$basic_presence) { q("insert into chatpresence ( cp_xchan, cp_last, cp_status, cp_client) values( '%s', '%s', '%s', '%s' ) ", dbesc(self::$ob_hash), @@ -181,17 +195,21 @@ class Sse extends Controller { } } + $result = []; + XConfig::Load(self::$ob_hash); - $result = XConfig::Get(self::$ob_hash, 'sse', 'notifications', []); $lock = XConfig::Get(self::$ob_hash, 'sse', 'lock'); - if($result && !$lock) { + if (!$lock) { + $result = XConfig::Get(self::$ob_hash, 'sse', 'notifications', []); + } + + 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..8847ff242 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 (isset($_REQUEST['sse_rmids'])) { + self::mark_read(explode(',', $_REQUEST['sse_rmids'])); + } if(!empty($_REQUEST['nquery']) && $_REQUEST['nquery'] !== '%') { $nquery = $_REQUEST['nquery']; @@ -502,13 +502,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 +602,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/Subthread.php b/Zotlabs/Module/Subthread.php index b927ee480..baabee78f 100644 --- a/Zotlabs/Module/Subthread.php +++ b/Zotlabs/Module/Subthread.php @@ -159,7 +159,7 @@ class Subthread extends \Zotlabs\Web\Controller { $arr['deny_cid'] = $item['deny_cid']; $arr['deny_gid'] = $item['deny_gid']; - $post = item_store($arr); + $post = item_store($arr, deliver: false, addAndSync: false); $post_id = $post['item_id']; $arr['id'] = $post_id; diff --git a/Zotlabs/Module/Tagger.php b/Zotlabs/Module/Tagger.php index b6067be5e..a88a3b112 100644 --- a/Zotlabs/Module/Tagger.php +++ b/Zotlabs/Module/Tagger.php @@ -1,6 +1,7 @@ <?php namespace Zotlabs\Module; +use App; use Zotlabs\Lib\Libsync; require_once('include/security.php'); @@ -18,6 +19,7 @@ class Tagger extends \Zotlabs\Web\Controller { } $sys = get_sys_channel(); + $channel = App::get_channel(); $observer_hash = get_observer_hash(); //strip html-tags @@ -125,10 +127,6 @@ class Tagger extends \Zotlabs\Web\Controller { $termlink = html_entity_decode('⋕') . '[zrl=' . z_root() . '/search?tag=' . urlencode($clean_term) . ']'. $clean_term . '[/zrl]'; - $channel = \App::get_channel(); - - $arr = array(); - $arr['owner_xchan'] = $item['owner_xchan']; $arr['author_xchan'] = $channel['channel_hash']; diff --git a/Zotlabs/Module/Tagrm.php b/Zotlabs/Module/Tagrm.php index a6dc21798..34eaf85b2 100644 --- a/Zotlabs/Module/Tagrm.php +++ b/Zotlabs/Module/Tagrm.php @@ -7,141 +7,141 @@ require_once('include/bbcode.php'); class Tagrm extends \Zotlabs\Web\Controller { function post() { - + if(! local_channel()) goaway(z_root() . '/' . $_SESSION['photo_return']); - - + + if((x($_POST,'submit')) && ($_POST['submit'] === t('Cancel'))) goaway(z_root() . '/' . $_SESSION['photo_return']); - + $tag = ((x($_POST,'tag')) ? trim($_POST['tag']) : ''); $item = ((x($_POST,'item')) ? intval($_POST['item']) : 0 ); - + $r = q("SELECT * FROM item WHERE id = %d AND uid = %d LIMIT 1", intval($item), intval(local_channel()) ); - + if(! $r) goaway(z_root() . '/' . $_SESSION['photo_return']); - + $r = fetch_post_tags($r,true); - + $item = $r[0]; $new_tags = array(); - + if($item['term']) { for($x = 0; $x < count($item['term']); $x ++) { if($item['term'][$x]['term'] !== hex2bin($tag)) $new_tags[] = $item['term'][$x]; } } - + if($new_tags) $item['term'] = $new_tags; else unset($item['term']); - - item_store_update($item); - + + item_store_update($item, deliver: false, addAndSync: false); + info( t('Tag removed') . EOL ); goaway(z_root() . '/' . $_SESSION['photo_return']); - + // NOTREACHED - + } - - - + + + function get() { - + if(! local_channel()) { goaway(z_root() . '/' . $_SESSION['photo_return']); // NOTREACHED } - + // remove tag on the fly if item and tag are provided if((argc() == 4) && (argv(1) === 'drop') && intval(argv(2))) { - + $item = intval(argv(2)); $tag = argv(3); - + $r = q("SELECT * FROM item WHERE id = %d AND uid = %d LIMIT 1", intval($item), intval(local_channel()) ); - + if(! $r) goaway(z_root() . '/' . $_SESSION['photo_return']); - + $r = fetch_post_tags($r,true); - + $item = $r[0]; - + $new_tags = array(); - + if($item['term']) { for($x = 0; $x < count($item['term']); $x ++) { if($item['term'][$x]['term'] !== hex2bin($tag)) $new_tags[] = $item['term'][$x]; } } - + if($new_tags) $item['term'] = $new_tags; else unset($item['term']); - - item_store_update($item); - + + item_store_update($item, deliver: false, addAndSync: false); + info( t('Tag removed') . EOL ); goaway(z_root() . '/' . $_SESSION['photo_return']); - + } - + //if we got only the item print a list of tags to select if((argc() == 3) && (argv(1) === 'drop') && intval(argv(2))) { - + $o = ''; - + $item = intval(argv(2)); - + $r = q("SELECT * FROM item WHERE id = %d AND uid = %d LIMIT 1", intval($item), intval(local_channel()) ); - + if(! $r) goaway(z_root() . '/' . $_SESSION['photo_return']); - + $r = fetch_post_tags($r,true); - + if(! count($r[0]['term'])) goaway(z_root() . '/' . $_SESSION['photo_return']); - + $o .= '<h3>' . t('Remove Item Tag') . '</h3>'; - + $o .= '<p id="tag-remove-desc">' . t('Select a tag to remove: ') . '</p>'; - + $o .= '<form id="tagrm" action="tagrm" method="post" >'; $o .= '<input type="hidden" name="item" value="' . $item . '" />'; $o .= '<ul>'; - - + + foreach($r[0]['term'] as $x) { $o .= '<li><input type="checkbox" name="tag" value="' . bin2hex($x['term']) . '" >' . bbcode($x['term']) . '</input></li>'; } - + $o .= '</ul>'; $o .= '<input id="tagrm-submit" type="submit" name="submit" value="' . t('Remove') .'" />'; $o .= '<input id="tagrm-cancel" type="submit" name="submit" value="' . t('Cancel') .'" />'; $o .= '</form>'; - + return $o; - + } - + } - + } diff --git a/Zotlabs/Module/Thing.php b/Zotlabs/Module/Thing.php index 2038db8c0..aef494e13 100644 --- a/Zotlabs/Module/Thing.php +++ b/Zotlabs/Module/Thing.php @@ -50,24 +50,31 @@ class Thing extends \Zotlabs\Web\Controller { $channel = \App::get_channel(); - $term_hash = (($_REQUEST['term_hash']) ? $_REQUEST['term_hash'] : ''); + $term_hash = (($_POST['term_hash']) ? $_POST['term_hash'] : ''); - $name = escape_tags($_REQUEST['term']); - $verb = escape_tags($_REQUEST['verb']); - $activity = intval($_REQUEST['activity']); - $profile_guid = escape_tags($_REQUEST['profile_assign']); - $url = $_REQUEST['url']; - $photo = $_REQUEST['img']; + $name = escape_tags($_POST['term']); + $verb = escape_tags($_POST['verb']); + $activity = intval($_POST['activity']); + $url = $_POST['url']; + $photo = $_POST['img']; + + $profile_guid = isset($_POST['profile_assign']) + ? escape_tags($_POST['profile_assign']) + : null; $hash = new_uuid(); $verbs = obj_verbs(); - /** - * verbs: [0] = first person singular, e.g. "I want", [1] = 3rd person singular, e.g. "Bill wants" - * We use the first person form when creating an activity, but the third person for use in activities - * @FIXME There is no accounting for verb gender for languages where this is significant. We may eventually - * require obj_verbs() to provide full conjugations and specify which form to use in the $_REQUEST params to this module. + /* + * verbs: [0] = first person singular, e.g. "I want", [1] = 3rd person + * singular, e.g. "Bill wants" We use the first person form when + * creating an activity, but the third person for use in activities + * + * @FIXME There is no accounting for verb gender for languages where + * this is significant. We may eventually require obj_verbs() to + * provide full conjugations and specify which form to use in the + * $_POST params to this module. */ $translated_verb = $verbs[$verb][1]; @@ -100,7 +107,7 @@ class Thing extends \Zotlabs\Web\Controller { return; $acl = new \Zotlabs\Access\AccessList($channel); - $acl->set_from_array($_REQUEST); + $acl->set_from_array($_POST); $x = $acl->get(); @@ -332,7 +339,7 @@ class Thing extends \Zotlabs\Web\Controller { return ''; } - $o .= replace_macros(get_markup_template('thing_edit.tpl'),array( + return replace_macros(get_markup_template('thing_edit.tpl'),array( '$thing_hdr' => t('Edit Thing'), '$multiprof' => feature_enabled(local_channel(),'multi_profiles'), '$profile_lbl' => t('Select a profile'), @@ -356,8 +363,6 @@ class Thing extends \Zotlabs\Web\Controller { '$lockstate' => $lockstate, '$submit' => t('Submit') )); - - return $o; } if(argc() == 3 && argv(1) === 'drop') { @@ -385,16 +390,16 @@ class Thing extends \Zotlabs\Web\Controller { Libsync::build_sync_packet(0,array('obj' => $r)); - return $o; + return ''; } - $o .= replace_macros(get_markup_template('thing_input.tpl'),array( + return replace_macros(get_markup_template('thing_input.tpl'),array( '$thing_hdr' => t('Add Thing to your Profile'), '$multiprof' => feature_enabled(local_channel(),'multi_profiles'), '$profile_lbl' => t('Select a profile'), '$profile_select' => contact_profile_assign(''), '$verb_lbl' => $channel['channel_name'], - '$activity' => array('activity',t('Post an activity'),((array_key_exists('activity',$_REQUEST)) ? $_REQUEST['activity'] : true),t('Only sends to viewers of the applicable profile')), + '$activity' => array('activity',t('Post an activity'),((array_key_exists('activity',$_GET)) ? $_GET['activity'] : true),t('Only sends to viewers of the applicable profile')), '$verb_select' => obj_verb_selector(), '$thing_lbl' => t('Name of thing e.g. something'), '$url_lbl' => t('URL of thing (optional)'), @@ -408,8 +413,5 @@ class Thing extends \Zotlabs\Web\Controller { '$lockstate' => $lockstate, '$submit' => t('Submit') )); - - return $o; } - } diff --git a/Zotlabs/Module/Vote.php b/Zotlabs/Module/Vote.php index 06c47f91f..5192e3043 100644 --- a/Zotlabs/Module/Vote.php +++ b/Zotlabs/Module/Vote.php @@ -107,10 +107,12 @@ class Vote extends Controller { retain_item($fetch[0]['id']); if($x['success']) { - $itemid = $x['item_id']; - Master::Summon( [ 'Notifier', 'like', $itemid ] ); + Master::Summon(['Notifier', 'like', $x['item_id']]); + if (!empty($x['approval_id'])) { + Master::Summon(['Notifier', 'like', $x['approval_id']]); + } } - +/* $r = q("select * from item where id = %d", intval($itemid) ); @@ -119,6 +121,7 @@ class Vote extends Controller { $sync_item = fetch_post_tags($r); Libsync::build_sync_packet($channel['channel_id'], [ 'item' => [ encode_item($sync_item[0],true) ] ]); } +*/ } $ret['success'] = true; diff --git a/Zotlabs/Module/Wall_attach.php b/Zotlabs/Module/Wall_attach.php index 3c57d4b94..e354f58f1 100644 --- a/Zotlabs/Module/Wall_attach.php +++ b/Zotlabs/Module/Wall_attach.php @@ -111,7 +111,7 @@ class Wall_attach extends \Zotlabs\Web\Controller { // give a wee bit of time for the background thumbnail processor to do its thing // or else we'll never see a video poster sleep(3); - $url = z_root() . '/cloud/' . $channel['channel_address'] . '/' . $r['data']['display_path']; + $url = z_root() . '/attach/' . $r['data']['hash']; $thumb = Linkinfo::get_video_poster($url); if($thumb) { $s = '[zvideo poster=\'' . $thumb . '\']' . $url . '[/zvideo]'; @@ -120,8 +120,8 @@ class Wall_attach extends \Zotlabs\Web\Controller { $s = '[zvideo]' . $url . '[/zvideo]'; } } - if(strpos($r['data']['filetype'],'audio') === 0) { - $url = z_root() . '/cloud/' . $channel['channel_address'] . '/' . $r['data']['display_path']; + if(strpos($r['data']['filetype'], 'audio') === 0) { + $url = z_root() . '/attach/' . $r['data']['hash']; $s = '[zaudio]' . $url . '[/zaudio]'; } if ($r['data']['filetype'] === 'image/svg+xml') { diff --git a/Zotlabs/Module/Webfinger.php b/Zotlabs/Module/Webfinger.php index 0dafae23c..ba0dca9e7 100644 --- a/Zotlabs/Module/Webfinger.php +++ b/Zotlabs/Module/Webfinger.php @@ -7,16 +7,16 @@ namespace Zotlabs\Module; class Webfinger extends \Zotlabs\Web\Controller { function get() { - - - $o .= '<h3>Webfinger Diagnostic</h3>'; - + + + $o = '<h3>Webfinger Diagnostic</h3>'; + $o .= '<form action="webfinger" method="get">'; $o .= 'Lookup address: <input type="text" style="width: 250px;" name="addr" value="' . $_GET['addr'] .'" />'; - $o .= '<input type="submit" name="submit" value="Submit" /></form>'; - + $o .= '<input type="submit" name="submit" value="Submit" /></form>'; + $o .= '<br /><br />'; - + if(x($_GET,'addr')) { $addr = trim($_GET['addr']); diff --git a/Zotlabs/Module/Webpages.php b/Zotlabs/Module/Webpages.php index ffb0d94ea..ca15c0b3a 100644 --- a/Zotlabs/Module/Webpages.php +++ b/Zotlabs/Module/Webpages.php @@ -63,7 +63,7 @@ class Webpages extends Controller { switch ($_SESSION['action']) { case 'import': $_SESSION['action'] = null; - $o .= replace_macros(get_markup_template('webpage_import.tpl'), array( + return replace_macros(get_markup_template('webpage_import.tpl'), array( '$title' => t('Import Webpage Elements'), '$importbtn' => t('Import selected'), '$action' => 'import', @@ -71,7 +71,6 @@ class Webpages extends Controller { '$layouts' => $_SESSION['layouts'], '$blocks' => $_SESSION['blocks'], )); - return $o; case 'importselected': $_SESSION['action'] = null; @@ -87,7 +86,7 @@ class Webpages extends Controller { $pages = get_webpage_elements($channel, 'pages'); $layouts = get_webpage_elements($channel, 'layouts'); $blocks = get_webpage_elements($channel, 'blocks'); - $o .= replace_macros(get_markup_template('webpage_export_list.tpl'), array( + $o = replace_macros(get_markup_template('webpage_export_list.tpl'), array( '$title' => t('Export Webpage Elements'), '$exportbtn' => t('Export selected'), '$action' => $_SESSION['export'], // value should be 'zipfile' or 'cloud' diff --git a/Zotlabs/Module/Zot_probe.php b/Zotlabs/Module/Zot_probe.php index 3eaabdd92..cf8355ce6 100644 --- a/Zotlabs/Module/Zot_probe.php +++ b/Zotlabs/Module/Zot_probe.php @@ -15,13 +15,19 @@ class Zot_probe extends \Zotlabs\Web\Controller { $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>'; |