Merge pull request #9170 from MrPetovan/bug/9164-query-string-urlencoded
Ensure query parameters are URL encoded in Arguments
This commit is contained in:
commit
bca6d9b089
19 changed files with 109 additions and 297 deletions
32
boot.php
32
boot.php
|
@ -382,38 +382,6 @@ function is_site_admin()
|
||||||
return local_user() && $admin_email && in_array($a->user['email'] ?? '', $adminlist);
|
return local_user() && $admin_email && in_array($a->user['email'] ?? '', $adminlist);
|
||||||
}
|
}
|
||||||
|
|
||||||
function explode_querystring($query)
|
|
||||||
{
|
|
||||||
$arg_st = strpos($query, '?');
|
|
||||||
if ($arg_st !== false) {
|
|
||||||
$base = substr($query, 0, $arg_st);
|
|
||||||
$arg_st += 1;
|
|
||||||
} else {
|
|
||||||
$base = '';
|
|
||||||
$arg_st = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
$args = explode('&', substr($query, $arg_st));
|
|
||||||
foreach ($args as $k => $arg) {
|
|
||||||
/// @TODO really compare type-safe here?
|
|
||||||
if ($arg === '') {
|
|
||||||
unset($args[$k]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$args = array_values($args);
|
|
||||||
|
|
||||||
if (!$base) {
|
|
||||||
$base = $args[0];
|
|
||||||
unset($args[0]);
|
|
||||||
$args = array_values($args);
|
|
||||||
}
|
|
||||||
|
|
||||||
return [
|
|
||||||
'base' => $base,
|
|
||||||
'args' => $args,
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the complete URL of the current page, e.g.: http(s)://something.com/network
|
* Returns the complete URL of the current page, e.g.: http(s)://something.com/network
|
||||||
*
|
*
|
||||||
|
|
|
@ -311,22 +311,22 @@ function api_call(App $a, App\Arguments $args = null)
|
||||||
}
|
}
|
||||||
|
|
||||||
$type = "json";
|
$type = "json";
|
||||||
if (strpos($args->getQueryString(), ".xml") > 0) {
|
if (strpos($args->getCommand(), ".xml") > 0) {
|
||||||
$type = "xml";
|
$type = "xml";
|
||||||
}
|
}
|
||||||
if (strpos($args->getQueryString(), ".json") > 0) {
|
if (strpos($args->getCommand(), ".json") > 0) {
|
||||||
$type = "json";
|
$type = "json";
|
||||||
}
|
}
|
||||||
if (strpos($args->getQueryString(), ".rss") > 0) {
|
if (strpos($args->getCommand(), ".rss") > 0) {
|
||||||
$type = "rss";
|
$type = "rss";
|
||||||
}
|
}
|
||||||
if (strpos($args->getQueryString(), ".atom") > 0) {
|
if (strpos($args->getCommand(), ".atom") > 0) {
|
||||||
$type = "atom";
|
$type = "atom";
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
foreach ($API as $p => $info) {
|
foreach ($API as $p => $info) {
|
||||||
if (strpos($args->getQueryString(), $p) === 0) {
|
if (strpos($args->getCommand(), $p) === 0) {
|
||||||
if (!api_check_method($info['method'])) {
|
if (!api_check_method($info['method'])) {
|
||||||
throw new MethodNotAllowedException();
|
throw new MethodNotAllowedException();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1148,17 +1148,12 @@ function status_editor(App $a, $x, $notes_cid = 0, $popup = false)
|
||||||
$jotplugins = '';
|
$jotplugins = '';
|
||||||
Hook::callAll('jot_tool', $jotplugins);
|
Hook::callAll('jot_tool', $jotplugins);
|
||||||
|
|
||||||
$query_str = DI::args()->getQueryString();
|
|
||||||
if (strpos($query_str, 'public=1') !== false) {
|
|
||||||
$query_str = str_replace(['?public=1', '&public=1'], ['', ''], $query_str);
|
|
||||||
}
|
|
||||||
|
|
||||||
// $tpl = Renderer::replaceMacros($tpl,array('$jotplugins' => $jotplugins));
|
// $tpl = Renderer::replaceMacros($tpl,array('$jotplugins' => $jotplugins));
|
||||||
$tpl = Renderer::getMarkupTemplate("jot.tpl");
|
$tpl = Renderer::getMarkupTemplate("jot.tpl");
|
||||||
|
|
||||||
$o .= Renderer::replaceMacros($tpl,[
|
$o .= Renderer::replaceMacros($tpl,[
|
||||||
'$new_post' => DI::l10n()->t('New Post'),
|
'$new_post' => DI::l10n()->t('New Post'),
|
||||||
'$return_path' => $query_str,
|
'$return_path' => DI::args()->getQueryString(),
|
||||||
'$action' => 'item',
|
'$action' => 'item',
|
||||||
'$share' => ($x['button'] ?? '') ?: DI::l10n()->t('Share'),
|
'$share' => ($x['button'] ?? '') ?: DI::l10n()->t('Share'),
|
||||||
'$loading' => DI::l10n()->t('Loading...'),
|
'$loading' => DI::l10n()->t('Loading...'),
|
||||||
|
|
36
mod/item.php
36
mod/item.php
|
@ -904,40 +904,8 @@ function drop_item(int $id, string $return = '')
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((local_user() == $item['uid']) || $contact_id) {
|
if ((local_user() == $item['uid']) || $contact_id) {
|
||||||
// Check if we should do HTML-based delete confirmation
|
|
||||||
if (!empty($_REQUEST['confirm'])) {
|
|
||||||
// <form> can't take arguments in its "action" parameter
|
|
||||||
// so add any arguments as hidden inputs
|
|
||||||
$query = explode_querystring(DI::args()->getQueryString());
|
|
||||||
$inputs = [];
|
|
||||||
|
|
||||||
foreach ($query['args'] as $arg) {
|
|
||||||
if (strpos($arg, 'confirm=') === false) {
|
|
||||||
$arg_parts = explode('=', $arg);
|
|
||||||
$inputs[] = ['name' => $arg_parts[0], 'value' => $arg_parts[1]];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Renderer::replaceMacros(Renderer::getMarkupTemplate('confirm.tpl'), [
|
|
||||||
'$method' => 'get',
|
|
||||||
'$message' => DI::l10n()->t('Do you really want to delete this item?'),
|
|
||||||
'$extra_inputs' => $inputs,
|
|
||||||
'$confirm' => DI::l10n()->t('Yes'),
|
|
||||||
'$confirm_url' => $query['base'],
|
|
||||||
'$confirm_name' => 'confirmed',
|
|
||||||
'$cancel' => DI::l10n()->t('Cancel'),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
// Now check how the user responded to the confirmation query
|
|
||||||
if (!empty($_REQUEST['canceled'])) {
|
|
||||||
DI::baseUrl()->redirect('display/' . $item['guid']);
|
|
||||||
}
|
|
||||||
|
|
||||||
$is_comment = $item['gravity'] == GRAVITY_COMMENT;
|
|
||||||
$parentitem = null;
|
|
||||||
if (!empty($item['parent'])) {
|
if (!empty($item['parent'])) {
|
||||||
$fields = ['guid'];
|
$parentitem = Item::selectFirstForUser(local_user(), ['guid'], ['id' => $item['parent']]);
|
||||||
$parentitem = Item::selectFirstForUser(local_user(), $fields, ['id' => $item['parent']]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// delete the item
|
// delete the item
|
||||||
|
@ -949,7 +917,7 @@ function drop_item(int $id, string $return = '')
|
||||||
$return_url = str_replace("update_", "", $return_url);
|
$return_url = str_replace("update_", "", $return_url);
|
||||||
|
|
||||||
// Check if delete a comment
|
// Check if delete a comment
|
||||||
if ($is_comment) {
|
if ($item['gravity'] == GRAVITY_COMMENT) {
|
||||||
// Return to parent guid
|
// Return to parent guid
|
||||||
if (!empty($parentitem)) {
|
if (!empty($parentitem)) {
|
||||||
DI::baseUrl()->redirect('display/' . $parentitem['guid']);
|
DI::baseUrl()->redirect('display/' . $parentitem['guid']);
|
||||||
|
|
|
@ -141,36 +141,6 @@ function message_content(App $a)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if we should do HTML-based delete confirmation
|
|
||||||
if (!empty($_REQUEST['confirm'])) {
|
|
||||||
// <form> can't take arguments in its "action" parameter
|
|
||||||
// so add any arguments as hidden inputs
|
|
||||||
$query = explode_querystring(DI::args()->getQueryString());
|
|
||||||
$inputs = [];
|
|
||||||
foreach ($query['args'] as $arg) {
|
|
||||||
if (strpos($arg, 'confirm=') === false) {
|
|
||||||
$arg_parts = explode('=', $arg);
|
|
||||||
$inputs[] = ['name' => $arg_parts[0], 'value' => $arg_parts[1]];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//DI::page()['aside'] = '';
|
|
||||||
return Renderer::replaceMacros(Renderer::getMarkupTemplate('confirm.tpl'), [
|
|
||||||
'$method' => 'get',
|
|
||||||
'$message' => DI::l10n()->t('Do you really want to delete this message?'),
|
|
||||||
'$extra_inputs' => $inputs,
|
|
||||||
'$confirm' => DI::l10n()->t('Yes'),
|
|
||||||
'$confirm_url' => $query['base'],
|
|
||||||
'$confirm_name' => 'confirmed',
|
|
||||||
'$cancel' => DI::l10n()->t('Cancel'),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now check how the user responded to the confirmation query
|
|
||||||
if (!empty($_REQUEST['canceled'])) {
|
|
||||||
DI::baseUrl()->redirect('message');
|
|
||||||
}
|
|
||||||
|
|
||||||
$cmd = $a->argv[1];
|
$cmd = $a->argv[1];
|
||||||
if ($cmd === 'drop') {
|
if ($cmd === 'drop') {
|
||||||
$message = DBA::selectFirst('mail', ['convid'], ['id' => $a->argv[2], 'uid' => local_user()]);
|
$message = DBA::selectFirst('mail', ['convid'], ['id' => $a->argv[2], 'uid' => local_user()]);
|
||||||
|
|
|
@ -635,9 +635,7 @@ function network_display_post($a, $pager, $mark_all, $update, $ordering, $items)
|
||||||
$parents_str = implode(', ', $parents_arr);
|
$parents_str = implode(', ', $parents_arr);
|
||||||
}
|
}
|
||||||
|
|
||||||
$query_string = DI::args()->getQueryString();
|
$pager->setQueryString(DI::args()->getQueryString());
|
||||||
|
|
||||||
$pager->setQueryString($query_string);
|
|
||||||
|
|
||||||
// We aren't going to try and figure out at the item, group, and page
|
// We aren't going to try and figure out at the item, group, and page
|
||||||
// level which items you've seen and which you haven't. If you're looking
|
// level which items you've seen and which you haven't. If you're looking
|
||||||
|
|
|
@ -1039,7 +1039,6 @@ function photos_content(App $a)
|
||||||
return Renderer::replaceMacros(Renderer::getMarkupTemplate('confirm.tpl'), [
|
return Renderer::replaceMacros(Renderer::getMarkupTemplate('confirm.tpl'), [
|
||||||
'$method' => 'post',
|
'$method' => 'post',
|
||||||
'$message' => DI::l10n()->t('Do you really want to delete this photo album and all its photos?'),
|
'$message' => DI::l10n()->t('Do you really want to delete this photo album and all its photos?'),
|
||||||
'$extra_inputs' => [],
|
|
||||||
'$confirm' => DI::l10n()->t('Delete Album'),
|
'$confirm' => DI::l10n()->t('Delete Album'),
|
||||||
'$confirm_url' => $drop_url,
|
'$confirm_url' => $drop_url,
|
||||||
'$confirm_name' => 'dropalbum',
|
'$confirm_name' => 'dropalbum',
|
||||||
|
@ -1146,7 +1145,6 @@ function photos_content(App $a)
|
||||||
return Renderer::replaceMacros(Renderer::getMarkupTemplate('confirm.tpl'), [
|
return Renderer::replaceMacros(Renderer::getMarkupTemplate('confirm.tpl'), [
|
||||||
'$method' => 'post',
|
'$method' => 'post',
|
||||||
'$message' => DI::l10n()->t('Do you really want to delete this photo?'),
|
'$message' => DI::l10n()->t('Do you really want to delete this photo?'),
|
||||||
'$extra_inputs' => [],
|
|
||||||
'$confirm' => DI::l10n()->t('Delete Photo'),
|
'$confirm' => DI::l10n()->t('Delete Photo'),
|
||||||
'$confirm_url' => $drop_url,
|
'$confirm_url' => $drop_url,
|
||||||
'$confirm_name' => 'delete',
|
'$confirm_name' => 'delete',
|
||||||
|
|
|
@ -829,26 +829,6 @@ function settings_content(App $a)
|
||||||
|
|
||||||
$stpl = Renderer::getMarkupTemplate('settings/settings.tpl');
|
$stpl = Renderer::getMarkupTemplate('settings/settings.tpl');
|
||||||
|
|
||||||
// Private/public post links for the non-JS ACL form
|
|
||||||
$private_post = 1;
|
|
||||||
if (!empty($_REQUEST['public']) && !$_REQUEST['public']) {
|
|
||||||
$private_post = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
$query_str = DI::args()->getQueryString();
|
|
||||||
if (strpos($query_str, 'public=1') !== false) {
|
|
||||||
$query_str = str_replace(['?public=1', '&public=1'], ['', ''], $query_str);
|
|
||||||
}
|
|
||||||
|
|
||||||
// I think $a->query_string may never have ? in it, but I could be wrong
|
|
||||||
// It looks like it's from the index.php?q=[etc] rewrite that the web
|
|
||||||
// server does, which converts any ? to &, e.g. suggest&ignore=61 for suggest?ignore=61
|
|
||||||
if (strpos($query_str, '?') === false) {
|
|
||||||
$public_post_link = '?public=1';
|
|
||||||
} else {
|
|
||||||
$public_post_link = '&public=1';
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Installed langs */
|
/* Installed langs */
|
||||||
$lang_choices = DI::l10n()->getAvailableLanguages();
|
$lang_choices = DI::l10n()->getAvailableLanguages();
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,7 @@ class Arguments
|
||||||
*/
|
*/
|
||||||
private $argc;
|
private $argc;
|
||||||
|
|
||||||
public function __construct(string $queryString = '', string $command = '', array $argv = [Module::DEFAULT], int $argc = 1)
|
public function __construct(string $queryString = '', string $command = '', array $argv = [], int $argc = 0)
|
||||||
{
|
{
|
||||||
$this->queryString = $queryString;
|
$this->queryString = $queryString;
|
||||||
$this->command = $command;
|
$this->command = $command;
|
||||||
|
@ -56,7 +56,7 @@ class Arguments
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return string The whole query string of this call
|
* @return string The whole query string of this call with url-encoded query parameters
|
||||||
*/
|
*/
|
||||||
public function getQueryString()
|
public function getQueryString()
|
||||||
{
|
{
|
||||||
|
@ -121,50 +121,27 @@ class Arguments
|
||||||
*/
|
*/
|
||||||
public function determine(array $server, array $get)
|
public function determine(array $server, array $get)
|
||||||
{
|
{
|
||||||
$queryString = '';
|
// removing leading / - maybe a nginx problem
|
||||||
|
$server['QUERY_STRING'] = ltrim($server['QUERY_STRING'] ?? '', '/');
|
||||||
|
|
||||||
if (!empty($server['QUERY_STRING']) && strpos($server['QUERY_STRING'], 'pagename=') === 0) {
|
$queryParameters = [];
|
||||||
$queryString = urldecode(substr($server['QUERY_STRING'], 9));
|
parse_str($server['QUERY_STRING'], $queryParameters);
|
||||||
} elseif (!empty($server['QUERY_STRING']) && strpos($server['QUERY_STRING'], 'q=') === 0) {
|
|
||||||
$queryString = urldecode(substr($server['QUERY_STRING'], 2));
|
|
||||||
}
|
|
||||||
|
|
||||||
// eventually strip ZRL
|
|
||||||
$queryString = $this->stripZRLs($queryString);
|
|
||||||
|
|
||||||
// eventually strip OWT
|
|
||||||
$queryString = $this->stripQueryParam($queryString, 'owt');
|
|
||||||
|
|
||||||
// removing trailing / - maybe a nginx problem
|
|
||||||
$queryString = ltrim($queryString, '/');
|
|
||||||
|
|
||||||
if (!empty($get['pagename'])) {
|
if (!empty($get['pagename'])) {
|
||||||
$command = trim($get['pagename'], '/\\');
|
$command = trim($get['pagename'], '/\\');
|
||||||
|
} elseif (!empty($queryParameters['pagename'])) {
|
||||||
|
$command = trim($queryParameters['pagename'], '/\\');
|
||||||
} elseif (!empty($get['q'])) {
|
} elseif (!empty($get['q'])) {
|
||||||
|
// Legacy page name parameter, now conflicts with the search query parameter
|
||||||
$command = trim($get['q'], '/\\');
|
$command = trim($get['q'], '/\\');
|
||||||
} else {
|
} else {
|
||||||
$command = Module::DEFAULT;
|
$command = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Remove generated and one-time use parameters
|
||||||
// fix query_string
|
unset($queryParameters['pagename']);
|
||||||
if (!empty($command)) {
|
unset($queryParameters['zrl']);
|
||||||
$queryString = str_replace(
|
unset($queryParameters['owt']);
|
||||||
$command . '&',
|
|
||||||
$command . '?',
|
|
||||||
$queryString
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// unix style "homedir"
|
|
||||||
if (substr($command, 0, 1) === '~') {
|
|
||||||
$command = 'profile/' . substr($command, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Diaspora style profile url
|
|
||||||
if (substr($command, 0, 2) === 'u/') {
|
|
||||||
$command = 'profile/' . substr($command, 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Break the URL path into C style argc/argv style arguments for our
|
* Break the URL path into C style argc/argv style arguments for our
|
||||||
|
@ -173,41 +150,17 @@ class Arguments
|
||||||
* [0] => 'module'
|
* [0] => 'module'
|
||||||
* [1] => 'arg1'
|
* [1] => 'arg1'
|
||||||
* [2] => 'arg2'
|
* [2] => 'arg2'
|
||||||
*
|
|
||||||
*
|
|
||||||
* There will always be one argument. If provided a naked domain
|
|
||||||
* URL, $this->argv[0] is set to "home".
|
|
||||||
*/
|
*/
|
||||||
|
if ($command) {
|
||||||
|
$argv = explode('/', $command);
|
||||||
|
} else {
|
||||||
|
$argv = [];
|
||||||
|
}
|
||||||
|
|
||||||
$argv = explode('/', $command);
|
|
||||||
$argc = count($argv);
|
$argc = count($argv);
|
||||||
|
|
||||||
|
$queryString = $command . ($queryParameters ? '?' . http_build_query($queryParameters) : '');
|
||||||
|
|
||||||
return new Arguments($queryString, $command, $argv, $argc);
|
return new Arguments($queryString, $command, $argv, $argc);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
/**
|
|
||||||
* Strip zrl parameter from a string.
|
|
||||||
*
|
|
||||||
* @param string $queryString The input string.
|
|
||||||
*
|
|
||||||
* @return string The zrl.
|
|
||||||
*/
|
|
||||||
public function stripZRLs(string $queryString)
|
|
||||||
{
|
|
||||||
return preg_replace('/[?&]zrl=(.*?)(&|$)/ism', '$2', $queryString);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Strip query parameter from a string.
|
|
||||||
*
|
|
||||||
* @param string $queryString The input string.
|
|
||||||
* @param string $param
|
|
||||||
*
|
|
||||||
* @return string The query parameter.
|
|
||||||
*/
|
|
||||||
public function stripQueryParam(string $queryString, string $param)
|
|
||||||
{
|
|
||||||
return preg_replace('/[?&]' . $param . '=(.*?)(&|$)/ism', '$2', $queryString);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -128,7 +128,7 @@ class Pager
|
||||||
/**
|
/**
|
||||||
* Sets the base query string from a full query string.
|
* Sets the base query string from a full query string.
|
||||||
*
|
*
|
||||||
* Strips the 'page' parameter, and remove the 'q=' string for some reason.
|
* Strips the 'page' parameter
|
||||||
*
|
*
|
||||||
* @param string $queryString
|
* @param string $queryString
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -229,8 +229,6 @@ class Addon
|
||||||
*/
|
*/
|
||||||
public static function getInfo($addon)
|
public static function getInfo($addon)
|
||||||
{
|
{
|
||||||
$a = DI::app();
|
|
||||||
|
|
||||||
$addon = Strings::sanitizeFilePathItem($addon);
|
$addon = Strings::sanitizeFilePathItem($addon);
|
||||||
|
|
||||||
$info = [
|
$info = [
|
||||||
|
|
|
@ -42,13 +42,13 @@ class BaseApi extends BaseModule
|
||||||
{
|
{
|
||||||
$arguments = DI::args();
|
$arguments = DI::args();
|
||||||
|
|
||||||
if (substr($arguments->getQueryString(), -4) === '.xml') {
|
if (substr($arguments->getCommand(), -4) === '.xml') {
|
||||||
self::$format = 'xml';
|
self::$format = 'xml';
|
||||||
}
|
}
|
||||||
if (substr($arguments->getQueryString(), -4) === '.rss') {
|
if (substr($arguments->getCommand(), -4) === '.rss') {
|
||||||
self::$format = 'rss';
|
self::$format = 'rss';
|
||||||
}
|
}
|
||||||
if (substr($arguments->getQueryString(), -4) === '.atom') {
|
if (substr($arguments->getCommand(), -4) === '.atom') {
|
||||||
self::$format = 'atom';
|
self::$format = 'atom';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -436,17 +436,6 @@ class Contact extends BaseModule
|
||||||
if ($cmd === 'drop' && ($orig_record['uid'] != 0)) {
|
if ($cmd === 'drop' && ($orig_record['uid'] != 0)) {
|
||||||
// Check if we should do HTML-based delete confirmation
|
// Check if we should do HTML-based delete confirmation
|
||||||
if (!empty($_REQUEST['confirm'])) {
|
if (!empty($_REQUEST['confirm'])) {
|
||||||
// <form> can't take arguments in its 'action' parameter
|
|
||||||
// so add any arguments as hidden inputs
|
|
||||||
$query = explode_querystring(DI::args()->getQueryString());
|
|
||||||
$inputs = [];
|
|
||||||
foreach ($query['args'] as $arg) {
|
|
||||||
if (strpos($arg, 'confirm=') === false) {
|
|
||||||
$arg_parts = explode('=', $arg);
|
|
||||||
$inputs[] = ['name' => $arg_parts[0], 'value' => $arg_parts[1]];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DI::page()['aside'] = '';
|
DI::page()['aside'] = '';
|
||||||
|
|
||||||
return Renderer::replaceMacros(Renderer::getMarkupTemplate('contact_drop_confirm.tpl'), [
|
return Renderer::replaceMacros(Renderer::getMarkupTemplate('contact_drop_confirm.tpl'), [
|
||||||
|
@ -454,9 +443,8 @@ class Contact extends BaseModule
|
||||||
'$contact' => self::getContactTemplateVars($orig_record),
|
'$contact' => self::getContactTemplateVars($orig_record),
|
||||||
'$method' => 'get',
|
'$method' => 'get',
|
||||||
'$message' => DI::l10n()->t('Do you really want to delete this contact?'),
|
'$message' => DI::l10n()->t('Do you really want to delete this contact?'),
|
||||||
'$extra_inputs' => $inputs,
|
|
||||||
'$confirm' => DI::l10n()->t('Yes'),
|
'$confirm' => DI::l10n()->t('Yes'),
|
||||||
'$confirm_url' => $query['base'],
|
'$confirm_url' => DI::args()->getCommand(),
|
||||||
'$confirm_name' => 'confirmed',
|
'$confirm_name' => 'confirmed',
|
||||||
'$cancel' => DI::l10n()->t('Cancel'),
|
'$cancel' => DI::l10n()->t('Cancel'),
|
||||||
]);
|
]);
|
||||||
|
|
|
@ -30,6 +30,14 @@
|
||||||
use Friendica\App\Router as R;
|
use Friendica\App\Router as R;
|
||||||
use Friendica\Module;
|
use Friendica\Module;
|
||||||
|
|
||||||
|
$profileRoutes = [
|
||||||
|
'' => [Module\Profile\Index::class, [R::GET]],
|
||||||
|
'/profile' => [Module\Profile\Profile::class, [R::GET]],
|
||||||
|
'/contacts/common' => [Module\Profile\Common::class, [R::GET]],
|
||||||
|
'/contacts[/{type}]' => [Module\Profile\Contacts::class, [R::GET]],
|
||||||
|
'/status[/{category}[/{date1}[/{date2}]]]' => [Module\Profile\Status::class, [R::GET]],
|
||||||
|
];
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'/' => [Module\Home::class, [R::GET]],
|
'/' => [Module\Home::class, [R::GET]],
|
||||||
|
|
||||||
|
@ -250,13 +258,9 @@ return [
|
||||||
'/pretheme' => [Module\ThemeDetails::class, [R::GET]],
|
'/pretheme' => [Module\ThemeDetails::class, [R::GET]],
|
||||||
'/probe' => [Module\Debug\Probe::class, [R::GET]],
|
'/probe' => [Module\Debug\Probe::class, [R::GET]],
|
||||||
|
|
||||||
'/profile' => [
|
'/profile/{nickname}' => $profileRoutes,
|
||||||
'/{nickname}' => [Module\Profile\Index::class, [R::GET]],
|
'/u/{nickname}' => $profileRoutes,
|
||||||
'/{nickname}/profile' => [Module\Profile\Profile::class, [R::GET]],
|
'/~{nickname}' => $profileRoutes,
|
||||||
'/{nickname}/contacts/common' => [Module\Profile\Common::class, [R::GET]],
|
|
||||||
'/{nickname}/contacts[/{type}]' => [Module\Profile\Contacts::class, [R::GET]],
|
|
||||||
'/{nickname}/status[/{category}[/{date1}[/{date2}]]]' => [Module\Profile\Status::class, [R::GET]],
|
|
||||||
],
|
|
||||||
|
|
||||||
'/proxy' => [
|
'/proxy' => [
|
||||||
'[/]' => [Module\Proxy::class, [R::GET]],
|
'[/]' => [Module\Proxy::class, [R::GET]],
|
||||||
|
|
|
@ -75,7 +75,7 @@ class ApiTest extends FixtureTest
|
||||||
$this->app = DI::app();
|
$this->app = DI::app();
|
||||||
|
|
||||||
$this->app->argc = 1;
|
$this->app->argc = 1;
|
||||||
$this->app->argv = ['home'];
|
$this->app->argv = [''];
|
||||||
|
|
||||||
// User data that the test database is populated with
|
// User data that the test database is populated with
|
||||||
$this->selfUser = [
|
$this->selfUser = [
|
||||||
|
@ -417,7 +417,7 @@ class ApiTest extends FixtureTest
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
$_SERVER['REQUEST_METHOD'] = 'method';
|
$_SERVER['REQUEST_METHOD'] = 'method';
|
||||||
$_SERVER['QUERY_STRING'] = 'q=api_path';
|
$_SERVER['QUERY_STRING'] = 'pagename=api_path';
|
||||||
$_GET['callback'] = 'callback_name';
|
$_GET['callback'] = 'callback_name';
|
||||||
|
|
||||||
$args = DI::args()->determine($_SERVER, $_GET);
|
$args = DI::args()->determine($_SERVER, $_GET);
|
||||||
|
@ -445,7 +445,7 @@ class ApiTest extends FixtureTest
|
||||||
];
|
];
|
||||||
|
|
||||||
$_SERVER['REQUEST_METHOD'] = 'method';
|
$_SERVER['REQUEST_METHOD'] = 'method';
|
||||||
$_SERVER['QUERY_STRING'] = 'q=api_path';
|
$_SERVER['QUERY_STRING'] = 'pagename=api_path';
|
||||||
|
|
||||||
$args = DI::args()->determine($_SERVER, $_GET);
|
$args = DI::args()->determine($_SERVER, $_GET);
|
||||||
|
|
||||||
|
@ -481,7 +481,7 @@ class ApiTest extends FixtureTest
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
$_SERVER['REQUEST_METHOD'] = 'method';
|
$_SERVER['REQUEST_METHOD'] = 'method';
|
||||||
$_SERVER['QUERY_STRING'] = 'q=api_path';
|
$_SERVER['QUERY_STRING'] = 'pagename=api_path';
|
||||||
|
|
||||||
$args = DI::args()->determine($_SERVER, $_GET);
|
$args = DI::args()->determine($_SERVER, $_GET);
|
||||||
|
|
||||||
|
@ -521,7 +521,7 @@ class ApiTest extends FixtureTest
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
$_SERVER['REQUEST_METHOD'] = 'method';
|
$_SERVER['REQUEST_METHOD'] = 'method';
|
||||||
$_SERVER['QUERY_STRING'] = 'q=api_path.json';
|
$_SERVER['QUERY_STRING'] = 'pagename=api_path.json';
|
||||||
|
|
||||||
$args = DI::args()->determine($_SERVER, $_GET);
|
$args = DI::args()->determine($_SERVER, $_GET);
|
||||||
|
|
||||||
|
@ -547,7 +547,7 @@ class ApiTest extends FixtureTest
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
$_SERVER['REQUEST_METHOD'] = 'method';
|
$_SERVER['REQUEST_METHOD'] = 'method';
|
||||||
$_SERVER['QUERY_STRING'] = 'q=api_path.xml';
|
$_SERVER['QUERY_STRING'] = 'pagename=api_path.xml';
|
||||||
|
|
||||||
$args = DI::args()->determine($_SERVER, $_GET);
|
$args = DI::args()->determine($_SERVER, $_GET);
|
||||||
|
|
||||||
|
@ -573,7 +573,7 @@ class ApiTest extends FixtureTest
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
$_SERVER['REQUEST_METHOD'] = 'method';
|
$_SERVER['REQUEST_METHOD'] = 'method';
|
||||||
$_SERVER['QUERY_STRING'] = 'q=api_path.rss';
|
$_SERVER['QUERY_STRING'] = 'pagename=api_path.rss';
|
||||||
|
|
||||||
$args = DI::args()->determine($_SERVER, $_GET);
|
$args = DI::args()->determine($_SERVER, $_GET);
|
||||||
|
|
||||||
|
@ -600,7 +600,7 @@ class ApiTest extends FixtureTest
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
$_SERVER['REQUEST_METHOD'] = 'method';
|
$_SERVER['REQUEST_METHOD'] = 'method';
|
||||||
$_SERVER['QUERY_STRING'] = 'q=api_path.atom';
|
$_SERVER['QUERY_STRING'] = 'pagename=api_path.atom';
|
||||||
|
|
||||||
$args = DI::args()->determine($_SERVER, $_GET);
|
$args = DI::args()->determine($_SERVER, $_GET);
|
||||||
|
|
||||||
|
@ -622,7 +622,7 @@ class ApiTest extends FixtureTest
|
||||||
global $API;
|
global $API;
|
||||||
$API['api_path'] = ['method' => 'method'];
|
$API['api_path'] = ['method' => 'method'];
|
||||||
|
|
||||||
$_SERVER['QUERY_STRING'] = 'q=api_path';
|
$_SERVER['QUERY_STRING'] = 'pagename=api_path';
|
||||||
|
|
||||||
$args = DI::args()->determine($_SERVER, $_GET);
|
$args = DI::args()->determine($_SERVER, $_GET);
|
||||||
|
|
||||||
|
@ -647,7 +647,7 @@ class ApiTest extends FixtureTest
|
||||||
];
|
];
|
||||||
$_SESSION['authenticated'] = false;
|
$_SESSION['authenticated'] = false;
|
||||||
$_SERVER['REQUEST_METHOD'] = 'method';
|
$_SERVER['REQUEST_METHOD'] = 'method';
|
||||||
$_SERVER['QUERY_STRING'] = 'q=api_path';
|
$_SERVER['QUERY_STRING'] = 'pagename=api_path';
|
||||||
|
|
||||||
$args = DI::args()->determine($_SERVER, $_GET);
|
$args = DI::args()->determine($_SERVER, $_GET);
|
||||||
|
|
||||||
|
|
|
@ -45,8 +45,8 @@ class ArgumentsTest extends TestCase
|
||||||
$this->assertArguments([
|
$this->assertArguments([
|
||||||
'queryString' => '',
|
'queryString' => '',
|
||||||
'command' => '',
|
'command' => '',
|
||||||
'argv' => ['home'],
|
'argv' => [],
|
||||||
'argc' => 1,
|
'argc' => 0,
|
||||||
],
|
],
|
||||||
$arguments);
|
$arguments);
|
||||||
}
|
}
|
||||||
|
@ -55,34 +55,6 @@ class ArgumentsTest extends TestCase
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'withPagename' => [
|
'withPagename' => [
|
||||||
'assert' => [
|
|
||||||
'queryString' => 'profile/test/it?arg1=value1&arg2=value2',
|
|
||||||
'command' => 'profile/test/it',
|
|
||||||
'argv' => ['profile', 'test', 'it'],
|
|
||||||
'argc' => 3,
|
|
||||||
],
|
|
||||||
'server' => [
|
|
||||||
'QUERY_STRING' => 'pagename=profile/test/it?arg1=value1&arg2=value2',
|
|
||||||
],
|
|
||||||
'get' => [
|
|
||||||
'pagename' => 'profile/test/it',
|
|
||||||
],
|
|
||||||
],
|
|
||||||
'withQ' => [
|
|
||||||
'assert' => [
|
|
||||||
'queryString' => 'profile/test/it?arg1=value1&arg2=value2',
|
|
||||||
'command' => 'profile/test/it',
|
|
||||||
'argv' => ['profile', 'test', 'it'],
|
|
||||||
'argc' => 3,
|
|
||||||
],
|
|
||||||
'server' => [
|
|
||||||
'QUERY_STRING' => 'q=profile/test/it?arg1=value1&arg2=value2',
|
|
||||||
],
|
|
||||||
'get' => [
|
|
||||||
'q' => 'profile/test/it',
|
|
||||||
],
|
|
||||||
],
|
|
||||||
'withWrongDelimiter' => [
|
|
||||||
'assert' => [
|
'assert' => [
|
||||||
'queryString' => 'profile/test/it?arg1=value1&arg2=value2',
|
'queryString' => 'profile/test/it?arg1=value1&arg2=value2',
|
||||||
'command' => 'profile/test/it',
|
'command' => 'profile/test/it',
|
||||||
|
@ -99,12 +71,12 @@ class ArgumentsTest extends TestCase
|
||||||
'withUnixHomeDir' => [
|
'withUnixHomeDir' => [
|
||||||
'assert' => [
|
'assert' => [
|
||||||
'queryString' => '~test/it?arg1=value1&arg2=value2',
|
'queryString' => '~test/it?arg1=value1&arg2=value2',
|
||||||
'command' => 'profile/test/it',
|
'command' => '~test/it',
|
||||||
'argv' => ['profile', 'test', 'it'],
|
'argv' => ['~test', 'it'],
|
||||||
'argc' => 3,
|
'argc' => 2,
|
||||||
],
|
],
|
||||||
'server' => [
|
'server' => [
|
||||||
'QUERY_STRING' => 'pagename=~test/it?arg1=value1&arg2=value2',
|
'QUERY_STRING' => 'pagename=~test/it&arg1=value1&arg2=value2',
|
||||||
],
|
],
|
||||||
'get' => [
|
'get' => [
|
||||||
'pagename' => '~test/it',
|
'pagename' => '~test/it',
|
||||||
|
@ -113,12 +85,12 @@ class ArgumentsTest extends TestCase
|
||||||
'withDiasporaHomeDir' => [
|
'withDiasporaHomeDir' => [
|
||||||
'assert' => [
|
'assert' => [
|
||||||
'queryString' => 'u/test/it?arg1=value1&arg2=value2',
|
'queryString' => 'u/test/it?arg1=value1&arg2=value2',
|
||||||
'command' => 'profile/test/it',
|
'command' => 'u/test/it',
|
||||||
'argv' => ['profile', 'test', 'it'],
|
'argv' => ['u', 'test', 'it'],
|
||||||
'argc' => 3,
|
'argc' => 3,
|
||||||
],
|
],
|
||||||
'server' => [
|
'server' => [
|
||||||
'QUERY_STRING' => 'pagename=u/test/it?arg1=value1&arg2=value2',
|
'QUERY_STRING' => 'pagename=u/test/it&arg1=value1&arg2=value2',
|
||||||
],
|
],
|
||||||
'get' => [
|
'get' => [
|
||||||
'pagename' => 'u/test/it',
|
'pagename' => 'u/test/it',
|
||||||
|
@ -126,13 +98,13 @@ class ArgumentsTest extends TestCase
|
||||||
],
|
],
|
||||||
'withTrailingSlash' => [
|
'withTrailingSlash' => [
|
||||||
'assert' => [
|
'assert' => [
|
||||||
'queryString' => 'profile/test/it?arg1=value1&arg2=value2/',
|
'queryString' => 'profile/test/it?arg1=value1&arg2=value2%2F',
|
||||||
'command' => 'profile/test/it',
|
'command' => 'profile/test/it',
|
||||||
'argv' => ['profile', 'test', 'it'],
|
'argv' => ['profile', 'test', 'it'],
|
||||||
'argc' => 3,
|
'argc' => 3,
|
||||||
],
|
],
|
||||||
'server' => [
|
'server' => [
|
||||||
'QUERY_STRING' => 'pagename=profile/test/it?arg1=value1&arg2=value2/',
|
'QUERY_STRING' => 'pagename=profile/test/it&arg1=value1&arg2=value2/',
|
||||||
],
|
],
|
||||||
'get' => [
|
'get' => [
|
||||||
'pagename' => 'profile/test/it',
|
'pagename' => 'profile/test/it',
|
||||||
|
@ -140,14 +112,13 @@ class ArgumentsTest extends TestCase
|
||||||
],
|
],
|
||||||
'withWrongQueryString' => [
|
'withWrongQueryString' => [
|
||||||
'assert' => [
|
'assert' => [
|
||||||
// empty query string?!
|
'queryString' => 'profile/test/it?wrong=profile%2Ftest%2Fit&arg1=value1&arg2=value2%2F',
|
||||||
'queryString' => '',
|
|
||||||
'command' => 'profile/test/it',
|
'command' => 'profile/test/it',
|
||||||
'argv' => ['profile', 'test', 'it'],
|
'argv' => ['profile', 'test', 'it'],
|
||||||
'argc' => 3,
|
'argc' => 3,
|
||||||
],
|
],
|
||||||
'server' => [
|
'server' => [
|
||||||
'QUERY_STRING' => 'wrong=profile/test/it?arg1=value1&arg2=value2/',
|
'QUERY_STRING' => 'wrong=profile/test/it&arg1=value1&arg2=value2/',
|
||||||
],
|
],
|
||||||
'get' => [
|
'get' => [
|
||||||
'pagename' => 'profile/test/it',
|
'pagename' => 'profile/test/it',
|
||||||
|
@ -155,17 +126,44 @@ class ArgumentsTest extends TestCase
|
||||||
],
|
],
|
||||||
'withMissingPageName' => [
|
'withMissingPageName' => [
|
||||||
'assert' => [
|
'assert' => [
|
||||||
'queryString' => 'notvalid/it?arg1=value1&arg2=value2/',
|
'queryString' => 'notvalid/it?arg1=value1&arg2=value2%2F',
|
||||||
'command' => App\Module::DEFAULT,
|
'command' => 'notvalid/it',
|
||||||
'argv' => [App\Module::DEFAULT],
|
'argv' => ['notvalid', 'it'],
|
||||||
'argc' => 1,
|
'argc' => 2,
|
||||||
],
|
],
|
||||||
'server' => [
|
'server' => [
|
||||||
'QUERY_STRING' => 'pagename=notvalid/it?arg1=value1&arg2=value2/',
|
'QUERY_STRING' => 'pagename=notvalid/it&arg1=value1&arg2=value2/',
|
||||||
],
|
],
|
||||||
'get' => [
|
'get' => [
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
|
'withNothing' => [
|
||||||
|
'assert' => [
|
||||||
|
'queryString' => '?arg1=value1&arg2=value2%2F',
|
||||||
|
'command' => '',
|
||||||
|
'argv' => [],
|
||||||
|
'argc' => 0,
|
||||||
|
],
|
||||||
|
'server' => [
|
||||||
|
'QUERY_STRING' => 'arg1=value1&arg2=value2/',
|
||||||
|
],
|
||||||
|
'get' => [
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'withFileExtension' => [
|
||||||
|
'assert' => [
|
||||||
|
'queryString' => 'api/call.json',
|
||||||
|
'command' => 'api/call.json',
|
||||||
|
'argv' => ['api', 'call.json'],
|
||||||
|
'argc' => 2,
|
||||||
|
],
|
||||||
|
'server' => [
|
||||||
|
'QUERY_STRING' => 'pagename=api/call.json',
|
||||||
|
],
|
||||||
|
'get' => [
|
||||||
|
'pagename' => 'api/call.json'
|
||||||
|
],
|
||||||
|
],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -207,27 +205,27 @@ class ArgumentsTest extends TestCase
|
||||||
return [
|
return [
|
||||||
'strippedZRLFirst' => [
|
'strippedZRLFirst' => [
|
||||||
'assert' => '?arg1=value1',
|
'assert' => '?arg1=value1',
|
||||||
'input' => '?zrl=nope&arg1=value1',
|
'input' => '&zrl=nope&arg1=value1',
|
||||||
],
|
],
|
||||||
'strippedZRLLast' => [
|
'strippedZRLLast' => [
|
||||||
'assert' => '?arg1=value1',
|
'assert' => '?arg1=value1',
|
||||||
'input' => '?arg1=value1&zrl=nope',
|
'input' => '&arg1=value1&zrl=nope',
|
||||||
],
|
],
|
||||||
'strippedZTLMiddle' => [
|
'strippedZTLMiddle' => [
|
||||||
'assert' => '?arg1=value1&arg2=value2',
|
'assert' => '?arg1=value1&arg2=value2',
|
||||||
'input' => '?arg1=value1&zrl=nope&arg2=value2',
|
'input' => '&arg1=value1&zrl=nope&arg2=value2',
|
||||||
],
|
],
|
||||||
'strippedOWTFirst' => [
|
'strippedOWTFirst' => [
|
||||||
'assert' => '?arg1=value1',
|
'assert' => '?arg1=value1',
|
||||||
'input' => '?owt=test&arg1=value1',
|
'input' => '&owt=test&arg1=value1',
|
||||||
],
|
],
|
||||||
'strippedOWTLast' => [
|
'strippedOWTLast' => [
|
||||||
'assert' => '?arg1=value1',
|
'assert' => '?arg1=value1',
|
||||||
'input' => '?arg1=value1&owt=test',
|
'input' => '&arg1=value1&owt=test',
|
||||||
],
|
],
|
||||||
'strippedOWTMiddle' => [
|
'strippedOWTMiddle' => [
|
||||||
'assert' => '?arg1=value1&arg2=value2',
|
'assert' => '?arg1=value1&arg2=value2',
|
||||||
'input' => '?arg1=value1&owt=test&arg2=value2',
|
'input' => '&arg1=value1&owt=test&arg2=value2',
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
@ -242,7 +240,7 @@ class ArgumentsTest extends TestCase
|
||||||
$command = 'test/it';
|
$command = 'test/it';
|
||||||
|
|
||||||
$arguments = (new App\Arguments())
|
$arguments = (new App\Arguments())
|
||||||
->determine(['QUERY_STRING' => 'q=' . $command . $input,], ['pagename' => $command]);
|
->determine(['QUERY_STRING' => 'pagename=' . $command . $input,], ['pagename' => $command]);
|
||||||
|
|
||||||
$this->assertEquals($command . $assert, $arguments->getQueryString());
|
$this->assertEquals($command . $assert, $arguments->getQueryString());
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,9 +3,6 @@
|
||||||
<form action="{{$confirm_url}}" id="confirm-form" method="{{$method}}">
|
<form action="{{$confirm_url}}" id="confirm-form" method="{{$method}}">
|
||||||
|
|
||||||
<h3 id="confirm-message">{{$message}}</h3>
|
<h3 id="confirm-message">{{$message}}</h3>
|
||||||
{{foreach $extra_inputs as $input}}
|
|
||||||
<input type="hidden" name="{{$input.name}}" value="{{$input.value}}" />
|
|
||||||
{{/foreach}}
|
|
||||||
|
|
||||||
<input class="confirm-button" id="confirm-submit-button" type="submit" name="{{$confirm_name}}" value="{{$confirm}}" />
|
<input class="confirm-button" id="confirm-submit-button" type="submit" name="{{$confirm_name}}" value="{{$confirm}}" />
|
||||||
<input class="confirm-button" id="confirm-cancel-button" type="submit" name="canceled" value="{{$cancel}}" />
|
<input class="confirm-button" id="confirm-cancel-button" type="submit" name="canceled" value="{{$cancel}}" />
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
|
|
||||||
<h1><img src="{{$baseurl}}/images/friendica-32.png"> {{$title}}</h1>
|
<h1><img src="{{$baseurl}}/images/friendica-32.png"> {{$title}}</h1>
|
||||||
<h2>{{$pass}}</h2>
|
<h2>{{$pass}}</h2>
|
||||||
<form action="{{$baseurl}}/index.php?q=install" method="post">
|
<form action="{{$baseurl}}/index.php?pagename=install" method="post">
|
||||||
<table>
|
<table>
|
||||||
{{foreach $checks as $check}}
|
{{foreach $checks as $check}}
|
||||||
<tr><td>{{$check.title nofilter}} </td><td>
|
<tr><td>{{$check.title nofilter}} </td><td>
|
||||||
|
|
|
@ -1,9 +1,6 @@
|
||||||
|
|
||||||
<form action="{{$confirm_url}}" id="confirm-form" method="{{$method}}" class="generic-page-wrapper">
|
<form action="{{$confirm_url}}" id="confirm-form" method="{{$method}}" class="generic-page-wrapper">
|
||||||
<div id="confirm-message">{{$message}}</div>
|
<div id="confirm-message">{{$message}}</div>
|
||||||
{{foreach $extra_inputs as $input}}
|
|
||||||
<input type="hidden" name="{{$input.name}}" value="{{$input.value}}" />
|
|
||||||
{{/foreach}}
|
|
||||||
|
|
||||||
<div class="form-group pull-right settings-submit-wrapper" >
|
<div class="form-group pull-right settings-submit-wrapper" >
|
||||||
<button type="submit" name="{{$confirm_name}}" id="confirm-submit-button" class="btn btn-primary confirm-button" value="{{$confirm}}">{{$confirm}}</button>
|
<button type="submit" name="{{$confirm_name}}" id="confirm-submit-button" class="btn btn-primary confirm-button" value="{{$confirm}}">{{$confirm}}</button>
|
||||||
|
|
Loading…
Reference in a new issue