aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMario <mario@mariovavti.com>2024-06-13 19:07:05 +0000
committerMario <mario@mariovavti.com>2024-06-13 19:07:05 +0000
commitff018b975b47a57433b5f76634f9948164919e25 (patch)
tree408f52fb71a955ab2bf13a3b8f89c6d293b217e6
parent6e0d0e38321dda6075586c12244c73eff6623565 (diff)
parentfcd657040e90b957068be0c6010faa78020cf05d (diff)
downloadvolse-hubzilla-ff018b975b47a57433b5f76634f9948164919e25.tar.gz
volse-hubzilla-ff018b975b47a57433b5f76634f9948164919e25.tar.bz2
volse-hubzilla-ff018b975b47a57433b5f76634f9948164919e25.zip
Merge branch 'fix-rpost-module' into 'dev'
Refactoring and fixed for Module\Rpost See merge request hubzilla/core!2136
-rw-r--r--Zotlabs/Module/Rpost.php248
-rw-r--r--include/conversation.php3
-rw-r--r--tests/unit/Module/RpostTest.php81
-rw-r--r--tests/unit/Module/TestCase.php1
-rw-r--r--tests/unit/includes/NetworkTest.php8
-rw-r--r--tests/unit/includes/dba/_files/config.yml4
-rw-r--r--view/tpl/jot-header.tpl2
7 files changed, 218 insertions, 129 deletions
diff --git a/Zotlabs/Module/Rpost.php b/Zotlabs/Module/Rpost.php
index 23324ee3a..45f19d7e7 100644
--- a/Zotlabs/Module/Rpost.php
+++ b/Zotlabs/Module/Rpost.php
@@ -28,119 +28,31 @@ require_once('include/conversation.php');
* type= choices are 'html' or 'bbcode', default is 'bbcode'
*
*/
-
-
-
-
class Rpost extends \Zotlabs\Web\Controller {
- function get() {
-
- $o = '';
-
- if(! local_channel()) {
- if(remote_channel()) {
- // redirect to your own site.
- // We can only do this with a GET request so you'll need to keep the text short or risk getting truncated
- // by the wretched beast called 'suhosin'. All the browsers now allow long GET requests, but suhosin
- // blocks them.
-
- $url = Libzot::get_rpost_path(App::get_observer());
- // make sure we're not looping to our own hub
- if(($url) && (! stristr($url, App::get_hostname()))) {
- foreach($_GET as $key => $arg) {
- if($key === 'q')
- continue;
- $url .= '&' . $key . '=' . $arg;
- }
- goaway($url);
- }
- }
+ /**
+ * Handle requests.
+ *
+ * Despite it's name, this method handles both POST and GET requests
+ * to the module.
+ */
+ public function get(): string {
- // The login procedure is going to bugger our $_REQUEST variables
- // so save them in the session.
+ $channel_id = local_channel();
- if(array_key_exists('body',$_REQUEST)) {
- $_SESSION['rpost'] = $_REQUEST;
- }
- return login();
+ if(! $channel_id) {
+ return $this->redirect_or_login();
}
nav_set_selected('Post');
- if (local_channel() && array_key_exists('userfile',$_FILES)) {
-
- $channel = App::get_channel();
- $observer = App::get_observer();
-
- $def_album = get_pconfig($channel['channel_id'],'system','photo_path');
- $def_attach = get_pconfig($channel['channel_id'],'system','attach_path');
-
- $r = attach_store($channel, (($observer) ? $observer['xchan_hash'] : ''), '', [
- 'source' => 'editor',
- 'visible' => 0,
- 'album' => $def_album,
- 'directory' => $def_attach,
- 'flags' => 1, // indicates temporary permissions are created
- 'allow_cid' => '<' . $channel['channel_hash'] . '>',
- 'allow_gid' => '',
- 'deny_cid' => '',
- 'deny_gid' => ''
- ]);
-
- if (! $r['success']) {
- notice( $r['message'] . EOL);
- }
-
- $s = EMPTY_STR;
-
- if (intval($r['data']['is_photo'])) {
- $s .= "\n\n" . $r['body'] . "\n\n";
- }
-
- $url = z_root() . '/cloud/' . $channel['channel_address'] . '/' . $r['data']['display_path'];
-
- if (strpos($r['data']['filetype'],'video') === 0) {
- $s .= "\n\n" . '[zvideo]' . $url . '[/zvideo]' . "\n\n";
- }
-
- if (strpos($r['data']['filetype'],'audio') === 0) {
- $s .= "\n\n" . '[zaudio]' . $url . '[/zaudio]' . "\n\n";
- }
-
- if ($r['data']['filetype'] === 'image/svg+xml') {
- $x = @file_get_contents('store/' . $channel['channel_address'] . '/' . $r['data']['os_path']);
- if ($x) {
- $bb = svg2bb($x);
- if ($bb) {
- $s .= "\n\n" . $bb;
- }
- else {
- logger('empty return from svgbb');
- }
- }
- else {
- logger('unable to read svg data file: ' . 'store/' . $channel['channel_address'] . '/' . $r['data']['os_path']);
- }
- }
-
- if ($r['data']['filetype'] === 'text/calendar') {
- $content = @file_get_contents('store/' . $channel['channel_address'] . '/' . $r['data']['os_path']);
- if ($content) {
- $ev = ical_to_ev($content);
- if ($ev) {
- $s .= "\n\n" . format_event_bbcode($ev[0]) . "\n\n";
- }
- }
- }
-
- $s .= "\n\n" . '[attachment]' . $r['data']['hash'] . ',' . $r['data']['revision'] . '[/attachment]' . "\n";
- $_REQUEST['body'] = ((array_key_exists('body',$_REQUEST)) ? $_REQUEST['body'] . $s : $s);
+ if (! empty($_FILES['userfile'])) {
+ $this->handle_attachments();
}
// If we have saved rpost session variables, but nothing in the current $_REQUEST, recover the saved variables
- if((! array_key_exists('body',$_REQUEST)) && (array_key_exists('rpost',$_SESSION))) {
+ if((! array_key_exists('body',$_REQUEST)) && isset($_SESSION['rpost'])) {
$_REQUEST = $_SESSION['rpost'];
unset($_SESSION['rpost']);
}
@@ -152,21 +64,10 @@ class Rpost extends \Zotlabs\Web\Controller {
);
if($r) {
require_once('include/security.php');
- $change = change_channel($r[0]['channel_id']);
+ change_channel($r[0]['channel_id']);
}
}
- if(isset($_REQUEST['remote_return']) && $_REQUEST['remote_return']) {
- $_SESSION['remote_return'] = $_REQUEST['remote_return'];
- }
- if(argc() > 1 && argv(1) === 'return') {
- if($_SESSION['remote_return'])
- goaway($_SESSION['remote_return']);
- goaway(z_root() . '/network');
- }
-
- $plaintext = true;
-
if(isset($_REQUEST['type']) && $_REQUEST['type'] === 'html') {
require_once('include/html2bbcode.php');
$_REQUEST['body'] = html2bbcode($_REQUEST['body']);
@@ -197,12 +98,12 @@ class Rpost extends \Zotlabs\Web\Controller {
'permissions' => $channel_acl,
'bang' => '',
'visitor' => true,
- 'profile_uid' => local_channel(),
+ 'profile_uid' => $channel_id,
'title' => $_REQUEST['title'] ?? '',
'body' => $_REQUEST['body'] ?? '',
'attachment' => $_REQUEST['attachment'] ?? '',
'source' => ((x($_REQUEST,'source')) ? strip_tags($_REQUEST['source']) : ''),
- 'return_path' => 'rpost/return',
+ 'return_path' => 'hq',
'bbco_autocomplete' => 'bbcode',
'editor_autocomplete' => true,
'bbcode' => true,
@@ -210,19 +111,128 @@ class Rpost extends \Zotlabs\Web\Controller {
'reset' => t('Reset form')
);
- $a = '';
$editor = status_editor($x, false, 'Rpost');
- $o .= replace_macros(get_markup_template('edpost_head.tpl'), array(
+ return replace_macros(get_markup_template('edpost_head.tpl'), array(
'$title' => t('Edit post'),
'$cancel' => '',
- '$editor' => $editor
+ '$editor' => $editor,
+ '$delete' => null,
));
+ }
+
+ /**
+ * Redirect to the observer's instance if not local, or return login form.
+ *
+ * The request is saved in the session if there's a `body` request
+ * param present. (Otherwise not.)
+ *
+ * @return string A login form if not redirected. If the session was
+ * determned to belong to a remote channel, the function does not
+ * return.
+ */
+ private function redirect_or_login(): string {
+ if(remote_channel()) {
+ // redirect to your own site.
+ // We can only do this with a GET request so you'll need to keep the text short or risk getting truncated
+ // by the wretched beast called 'suhosin'. All the browsers now allow long GET requests, but suhosin
+ // blocks them.
+
+ $url = Libzot::get_rpost_path(App::get_observer());
+ // make sure we're not looping to our own hub
+ if(($url) && (! stristr($url, App::get_hostname()))) {
+ foreach($_GET as $key => $arg) {
+ if($key === 'q')
+ continue;
+ $url .= '&' . $key . '=' . $arg;
+ }
+ goaway($url);
+ }
+ }
- return $o;
+ // The login procedure is going to bugger our $_REQUEST variables
+ // so save them in the session.
+ if(array_key_exists('body',$_REQUEST)) {
+ $_SESSION['rpost'] = $_REQUEST;
+ }
+ return login();
}
+ /**
+ * Handle uplads of attachments in the rpost call.
+ *
+ * This is only relevant for POST requests.
+ *
+ * The function will modify the `$_REQUEST['body']` superglobal
+ * (or add it if it does not exist).
+ */
+ private function handle_attachments(): void {
+ $channel = App::get_channel();
+ $observer = App::get_observer();
+
+ $def_album = get_pconfig($channel['channel_id'],'system','photo_path');
+ $def_attach = get_pconfig($channel['channel_id'],'system','attach_path');
+
+ $r = attach_store($channel, (($observer) ? $observer['xchan_hash'] : ''), '', [
+ 'source' => 'editor',
+ 'visible' => 0,
+ 'album' => $def_album,
+ 'directory' => $def_attach,
+ 'flags' => 1, // indicates temporary permissions are created
+ 'allow_cid' => '<' . $channel['channel_hash'] . '>',
+ 'allow_gid' => '',
+ 'deny_cid' => '',
+ 'deny_gid' => ''
+ ]);
+
+ if (! $r['success']) {
+ notice( $r['message'] . EOL);
+ }
+
+ $s = EMPTY_STR;
+
+ if (intval($r['data']['is_photo'])) {
+ $s .= "\n\n" . $r['body'] . "\n\n";
+ }
+
+ $url = z_root() . '/cloud/' . $channel['channel_address'] . '/' . $r['data']['display_path'];
+ if (strpos($r['data']['filetype'],'video') === 0) {
+ $s .= "\n\n" . '[zvideo]' . $url . '[/zvideo]' . "\n\n";
+ }
+
+ if (strpos($r['data']['filetype'],'audio') === 0) {
+ $s .= "\n\n" . '[zaudio]' . $url . '[/zaudio]' . "\n\n";
+ }
+ if ($r['data']['filetype'] === 'image/svg+xml') {
+ $x = @file_get_contents('store/' . $channel['channel_address'] . '/' . $r['data']['os_path']);
+ if ($x) {
+ $bb = svg2bb($x);
+ if ($bb) {
+ $s .= "\n\n" . $bb;
+ }
+ else {
+ logger('empty return from svgbb');
+ }
+ }
+ else {
+ logger('unable to read svg data file: ' . 'store/' . $channel['channel_address'] . '/' . $r['data']['os_path']);
+ }
+ }
+
+ if ($r['data']['filetype'] === 'text/calendar') {
+ $content = @file_get_contents('store/' . $channel['channel_address'] . '/' . $r['data']['os_path']);
+ if ($content) {
+ $ev = ical_to_ev($content);
+ if ($ev) {
+ $s .= "\n\n" . format_event_bbcode($ev[0]) . "\n\n";
+ }
+ }
+ }
+
+ $s .= "\n\n" . '[attachment]' . $r['data']['hash'] . ',' . $r['data']['revision'] . '[/attachment]' . "\n";
+ $_REQUEST['body'] = ((array_key_exists('body',$_REQUEST)) ? $_REQUEST['body'] . $s : $s);
+ }
}
diff --git a/include/conversation.php b/include/conversation.php
index 3992f06f6..c631d53a2 100644
--- a/include/conversation.php
+++ b/include/conversation.php
@@ -1183,6 +1183,7 @@ function hz_status_editor($x, $popup = false) {
'$modalerroralbum' => t('Error getting album'),
'$nocomment_enabled' => t('Comments enabled'),
'$nocomment_disabled' => t('Comments disabled'),
+ '$confirmdelete' => t('Confirm delete'),
'$auto_save_draft' => $feature_auto_save_draft,
'$reset' => $reset,
'$popup' => $popup
@@ -1263,7 +1264,7 @@ function hz_status_editor($x, $popup = false) {
'$poll_option_label' => t('Option'),
'$poll_add_option_label' => t('Add option'),
'$poll_expire_unit_label' => [t('Minutes'), t('Hours'), t('Days')],
- '$multiple_answers' => ['poll_multiple_answers', t("Allow multiple answers"), '', '', [t('No'), t('Yes')]],
+ '$multiple_answers' => ['poll_multiple_answers', t("Allow multiple answers"), '', '', [t('No'), t('Yes')],null,null],
'$consensus' => ((array_key_exists('item',$x)) ? $x['item']['item_consensus'] : 0),
'$nocommenttitle' => t('Disable comments'),
'$nocommenttitlesub' => t('Toggle comments'),
diff --git a/tests/unit/Module/RpostTest.php b/tests/unit/Module/RpostTest.php
new file mode 100644
index 000000000..ad94f2f06
--- /dev/null
+++ b/tests/unit/Module/RpostTest.php
@@ -0,0 +1,81 @@
+<?php
+/**
+ * Tests for Rpost module.
+ *
+ * SPDX-FileCopyrightText: 2024 Hubzilla Community
+ * SPDX-FileContributor: Harald Eilertsen
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+class RpostTest extends \Zotlabs\Tests\Unit\Module\TestCase {
+
+ /**
+ * Basic test of a get request with no args as an authenticated user.
+ */
+ public function test_get_with_no_args(): void {
+ $this->get_authenticated();
+
+ $this->assertPageContains('<form id="profile-jot-form"');
+ $this->assertPageContains('<input type="hidden" name="profile_uid" value="42"');
+ }
+
+ /**
+ * Display login form if session is not authenticated.
+ */
+ public function test_display_login_form_if_not_logged_in(): void {
+ $lc_mock = $this->getFunctionMock('Zotlabs\Module', 'local_channel')
+ ->expects($this->any())
+ ->willReturn(false);
+
+ $this->get('rpost');
+
+ $this->assertPageContains('<form action="https://hubzilla.test/rpost" id="main_login"');
+ }
+
+ public function test_populates_form_from_query_params(): void {
+ $this->get_authenticated([
+ 'title' => 'This is my title',
+ 'body' => 'The body of the post',
+ 'source' => 'The temple of the Dagon',
+ ]);
+
+ $this->assertPageContains('value="This is my title"');
+ $this->assertPageContains('>The body of the post</textarea>');
+ $this->assertPageContains('value="The temple of the Dagon"');
+ }
+
+ public function test_convert_body_from_html_to_bbcode(): void {
+ $this->get_authenticated([
+ 'body' => "<h1>Awesome page</h1>\r\n<p>Awesome content!</p>",
+ 'type' => 'html',
+ ]);
+
+ $this->assertPageContains(">[h1]Awesome page[/h1]\n\nAwesome content!</textarea>");
+ }
+
+ /**
+ * Private helper method to perform an authenticated GET request.
+ *
+ * @param array $query An associative array of query parameters.
+ */
+ private function get_authenticated(array $query = []): void {
+ // Mock `local_chanel()` to emulate a valid logged in channel
+ $lc_mock = $this->getFunctionMock('Zotlabs\Module', 'local_channel')
+ ->expects($this->any())
+ ->willReturn(42);
+
+ // Set basic access controls to keep AccessList happy.
+ \App::$channel = [
+ 'channel_id' => 42,
+ 'channel_location' => null,
+ 'channel_address' => '',
+ 'channel_allow_cid' => '',
+ 'channel_allow_gid' => '',
+ 'channel_deny_cid' => '',
+ 'channel_deny_gid' => '',
+ ];
+
+ $this->get('rpost', $query);
+ }
+}
diff --git a/tests/unit/Module/TestCase.php b/tests/unit/Module/TestCase.php
index e7051e001..f2e19f265 100644
--- a/tests/unit/Module/TestCase.php
+++ b/tests/unit/Module/TestCase.php
@@ -25,6 +25,7 @@ class TestCase extends \Zotlabs\Tests\Unit\UnitTestCase {
$_SERVER['REQUEST_METHOD'] = 'GET';
$_SERVER['SERVER_PROTOCOL'] = 'HTTP/1.1';
+ $_SERVER['QUERY_STRING'] = "q={$uri}";
$_REQUEST = $_GET;
\App::init();
diff --git a/tests/unit/includes/NetworkTest.php b/tests/unit/includes/NetworkTest.php
index 5bf175953..a41075f25 100644
--- a/tests/unit/includes/NetworkTest.php
+++ b/tests/unit/includes/NetworkTest.php
@@ -7,12 +7,6 @@
class NetworkTest extends Zotlabs\Tests\Unit\UnitTestCase {
- public function setUp() : void {
- parent::setUp();
-
- \App::set_baseurl("https://mytest.org");
- }
-
/**
* @dataProvider localUrlTestProvider
*/
@@ -23,7 +17,7 @@ class NetworkTest extends Zotlabs\Tests\Unit\UnitTestCase {
public static function localUrlTestProvider() : array {
return [
[ '/some/path', true ],
- [ 'https://mytest.org/some/path', true ],
+ [ 'https://hubzilla.test/some/path', true ],
[ 'https://other.site/some/path', false ],
];
}
diff --git a/tests/unit/includes/dba/_files/config.yml b/tests/unit/includes/dba/_files/config.yml
index e93486857..ac3c8acb0 100644
--- a/tests/unit/includes/dba/_files/config.yml
+++ b/tests/unit/includes/dba/_files/config.yml
@@ -2,6 +2,10 @@
config:
-
cat: system
+ k: baseurl
+ v: https://hubzilla.test
+ -
+ cat: system
k: do_not_check_dns
v: true
-
diff --git a/view/tpl/jot-header.tpl b/view/tpl/jot-header.tpl
index ca3cabd61..67ba1824b 100644
--- a/view/tpl/jot-header.tpl
+++ b/view/tpl/jot-header.tpl
@@ -184,7 +184,6 @@ var activeCommentText = '';
}
function jotGetExpiry() {
- //reply = prompt("{{$expirewhen}}", $('#jot-expire').val());
$('#expiryModal').modal('show');
$('#expiry-modal-OKButton').on('click', function() {
reply=$('#expiration-date').val();
@@ -196,7 +195,6 @@ var activeCommentText = '';
}
function jotGetPubDate() {
- //reply = prompt("{{$expirewhen}}", $('#jot-expire').val());
$('#createdModal').modal('show');
$('#created-modal-OKButton').on('click', function() {
reply=$('#created-date').val();