Merge remote-tracking branch 'upstream/develop' into channel-relay

This commit is contained in:
Michael 2024-01-15 19:51:20 +00:00
commit 0c8c03153b
72 changed files with 2289 additions and 608 deletions

3
.gitignore vendored
View file

@ -83,8 +83,9 @@ venv/
#Ignore temporary installed phpunit #Ignore temporary installed phpunit
/bin/phpunit /bin/phpunit
#Ignore cache file #Ignore cache files
.php_cs.cache .php_cs.cache
.php-cs-fixer.cache
#ignore avatar picture cache path #ignore avatar picture cache path
/avatar /avatar

93
.php-cs-fixer.dist.php Normal file
View file

@ -0,0 +1,93 @@
<?php
/**
* @copyright Copyright (C) 2010-2024, the Friendica project
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
$finder = PhpCsFixer\Finder::create()
->in(__DIR__)
->notPath('addon')
->notPath('bin/dev')
->notPath('config')
->notPath('doc')
->notPath('images')
->notPath('mods')
->notPath('spec')
->notPath('vendor')
->notPath('view/asset')
->notPath('lang')
->notPath('view/smarty3/compiled');
$config = new PhpCsFixer\Config();
return $config
->setRules([
'@PSR1' => true,
'@PSR2' => true,
'@PSR12' => true,
'align_multiline_comment' => true,
'array_indentation' => true,
'array_syntax' => [
'syntax' => 'short',
],
'binary_operator_spaces' => [
'default' => 'single_space',
'operators' => [
'=>' => 'align_single_space_minimal',
'=' => 'align_single_space_minimal',
'??' => 'align_single_space_minimal',
],
],
'blank_line_after_namespace' => true,
'braces' => [
'position_after_anonymous_constructs' => 'same',
'position_after_control_structures' => 'same',
'position_after_functions_and_oop_constructs' => 'next',
],
'elseif' => true,
'encoding' => true,
'full_opening_tag' => true,
'function_declaration' => [
'closure_function_spacing' => 'one',
],
'indentation_type' => true,
'line_ending' => true,
'list_syntax' => [
'syntax' => 'long',
],
'lowercase_keywords' => true,
'method_argument_space' => [],
'no_closing_tag' => true,
'no_spaces_after_function_name' => true,
'no_spaces_inside_parenthesis' => true,
'no_trailing_whitespace' => true,
'no_trailing_whitespace_in_comment' => true,
'no_unused_imports' => true,
'single_blank_line_at_eof' => true,
'single_class_element_per_statement' => true,
'single_import_per_statement' => true,
'single_line_after_imports' => true,
'switch_case_space' => true,
'ternary_operator_spaces' => false,
'visibility_required' => [
'elements' => ['property', 'method']
],
'new_with_braces' => true,
])
->setFinder($finder)
->setIndent("\t");

View file

@ -6,6 +6,7 @@ require_once __DIR__ . '/bin/dev/php-cs-fixer/vendor/autoload.php';
$finder = PhpCsFixer\Finder::create() $finder = PhpCsFixer\Finder::create()
->in(__DIR__) ->in(__DIR__)
->notPath('addon')
->notPath('bin/dev') ->notPath('bin/dev')
->notPath('config') ->notPath('config')
->notPath('doc') ->notPath('doc')

View file

@ -29,12 +29,12 @@
"ext-xml": "*", "ext-xml": "*",
"asika/simple-console": "^1.0", "asika/simple-console": "^1.0",
"bacon/bacon-qr-code": "^2.0.0", "bacon/bacon-qr-code": "^2.0.0",
"divineomega/password_exposed": "^2.8", "divineomega/password_exposed": "^3",
"enyo/dropzone": "^5.9", "enyo/dropzone": "^5.9",
"ezyang/htmlpurifier": "^4.7", "ezyang/htmlpurifier": "^4.7",
"friendica/json-ld": "^1.0", "friendica/json-ld": "^1.0",
"geekwright/po": "^2.0", "geekwright/po": "^2.0",
"guzzlehttp/guzzle": "^6.5", "guzzlehttp/guzzle": "^7",
"guzzlehttp/oauth-subscriber": "^0.6", "guzzlehttp/oauth-subscriber": "^0.6",
"kornrunner/blurhash": "^1.2", "kornrunner/blurhash": "^1.2",
"league/html-to-markdown": "^4.8", "league/html-to-markdown": "^4.8",
@ -135,7 +135,8 @@
"mockery/mockery": "^1.3", "mockery/mockery": "^1.3",
"mikey179/vfsstream": "^1.6", "mikey179/vfsstream": "^1.6",
"phpunit/phpunit": "^9", "phpunit/phpunit": "^9",
"dms/phpunit-arraysubset-asserts": "^0.3.1" "dms/phpunit-arraysubset-asserts": "^0.3.1",
"friendsofphp/php-cs-fixer": "^3.46"
}, },
"scripts": { "scripts": {
"test": "phpunit", "test": "phpunit",
@ -149,6 +150,8 @@
"cs:fix": [ "cs:fix": [
"@cs:install", "@cs:install",
"bin/dev/php-cs-fixer/vendor/bin/php-cs-fixer fix" "bin/dev/php-cs-fixer/vendor/bin/php-cs-fixer fix"
] ],
"cs:check-v3": "vendor/bin/php-cs-fixer check --diff",
"cs:fix-v3": "vendor/bin/php-cs-fixer fix"
} }
} }

2212
composer.lock generated

File diff suppressed because it is too large Load diff

View file

@ -215,14 +215,14 @@ function photos_post(App $a)
// get the list of photos we are about to delete // get the list of photos we are about to delete
if ($visitor) { if ($visitor) {
$r = DBA::toArray(DBA::p( $r = DBA::toArray(DBA::p(
"SELECT distinct(`resource-id`) as `rid` FROM `photo` WHERE `contact-id` = ? AND `uid` = ? AND `album` = ?", "SELECT distinct(`resource-id`) AS `rid` FROM `photo` WHERE `contact-id` = ? AND `uid` = ? AND `album` = ?",
$visitor, $visitor,
$page_owner_uid, $page_owner_uid,
$album $album
)); ));
} else { } else {
$r = DBA::toArray(DBA::p( $r = DBA::toArray(DBA::p(
"SELECT distinct(`resource-id`) as `rid` FROM `photo` WHERE `uid` = ? AND `album` = ?", "SELECT distinct(`resource-id`) AS `rid` FROM `photo` WHERE `uid` = ? AND `album` = ?",
DI::userSession()->getLocalUserId(), DI::userSession()->getLocalUserId(),
$album $album
)); ));
@ -762,7 +762,7 @@ function photos_content(App $a)
$total = 0; $total = 0;
$r = DBA::toArray(DBA::p( $r = DBA::toArray(DBA::p(
"SELECT `resource-id`, max(`scale`) AS `scale` FROM `photo` WHERE `uid` = ? AND `album` = ? "SELECT `resource-id`, MAX(`scale`) AS `scale` FROM `photo` WHERE `uid` = ? AND `album` = ?
AND `scale` <= 4 $sql_extra GROUP BY `resource-id`", AND `scale` <= 4 $sql_extra GROUP BY `resource-id`",
$owner_uid, $owner_uid,
$album $album
@ -782,9 +782,9 @@ function photos_content(App $a)
} }
$r = DBA::toArray(DBA::p( $r = DBA::toArray(DBA::p(
"SELECT `resource-id`, ANY_VALUE(`id`) AS `id`, ANY_VALUE(`filename`) AS `filename`, "SELECT `resource-id`, MIN(`id`) AS `id`, MIN(`filename`) AS `filename`,
ANY_VALUE(`type`) AS `type`, max(`scale`) AS `scale`, ANY_VALUE(`desc`) as `desc`, MIN(`type`) AS `type`, MAX(`scale`) AS `scale`, MIN(`desc`) AS `desc`,
ANY_VALUE(`created`) as `created` MIN(`created`) AS `created`
FROM `photo` WHERE `uid` = ? AND `album` = ? FROM `photo` WHERE `uid` = ? AND `album` = ?
AND `scale` <= 4 $sql_extra GROUP BY `resource-id` ORDER BY `created` $order LIMIT ? , ?", AND `scale` <= 4 $sql_extra GROUP BY `resource-id` ORDER BY `created` $order LIMIT ? , ?",
intval($owner_uid), intval($owner_uid),
@ -1167,11 +1167,11 @@ function photos_content(App $a)
} }
if (!empty($conv_responses['like'][$link_item['uri']])) { if (!empty($conv_responses['like'][$link_item['uri']])) {
$like = DI::conversation()->formatActivity($conv_responses['like'][$link_item['uri']]['links'], 'like', $link_item['id']); $like = DI::conversation()->formatActivity($conv_responses['like'][$link_item['uri']]['links'], 'like', $link_item['id'], '', []);
} }
if (!empty($conv_responses['dislike'][$link_item['uri']])) { if (!empty($conv_responses['dislike'][$link_item['uri']])) {
$dislike = DI::conversation()->formatActivity($conv_responses['dislike'][$link_item['uri']]['links'], 'dislike', $link_item['id']); $dislike = DI::conversation()->formatActivity($conv_responses['dislike'][$link_item['uri']]['links'], 'dislike', $link_item['id'], '', []);
} }
if (($can_post || Security::canWriteToUserWall($owner_uid))) { if (($can_post || Security::canWriteToUserWall($owner_uid))) {

View file

@ -58,7 +58,7 @@ class User extends \Asika\SimpleConsole\Console
console user - Modify user settings per console commands. console user - Modify user settings per console commands.
Usage Usage
bin/console user password <nickname> [<password>] [-h|--help|-?] [-v] bin/console user password <nickname> [<password>] [-h|--help|-?] [-v]
bin/console user add [<name> [<nickname> [<email> [<language>]]]] [-h|--help|-?] [-v] bin/console user add [<name> [<nickname> [<email> [<language> [<avatar_url>]]]]] [-h|--help|-?] [-v]
bin/console user delete [<nickname>] [-y] [-h|--help|-?] [-v] bin/console user delete [<nickname>] [-y] [-h|--help|-?] [-v]
bin/console user allow [<nickname>] [-h|--help|-?] [-v] bin/console user allow [<nickname>] [-h|--help|-?] [-v]
bin/console user deny [<nickname>] [-h|--help|-?] [-v] bin/console user deny [<nickname>] [-h|--help|-?] [-v]
@ -232,6 +232,7 @@ HELP;
$nick = $this->getArgument(2); $nick = $this->getArgument(2);
$email = $this->getArgument(3); $email = $this->getArgument(3);
$lang = $this->getArgument(4); $lang = $this->getArgument(4);
$avatar = $this->getArgument(5);
if (empty($name)) { if (empty($name)) {
$this->out($this->l10n->t('Enter user name: ')); $this->out($this->l10n->t('Enter user name: '));
@ -262,10 +263,15 @@ HELP;
$lang = CliPrompt::prompt(); $lang = CliPrompt::prompt();
} }
if (empty($avatar)) {
$this->out($this->l10n->t('Enter URL of an image to use as avatar (optional): '));
$avatar = CliPrompt::prompt();
}
if (empty($lang)) { if (empty($lang)) {
return UserModel::createMinimal($name, $email, $nick); return UserModel::createMinimal($name, $email, $nick);
} else { } else {
return UserModel::createMinimal($name, $email, $nick, $lang); return UserModel::createMinimal($name, $email, $nick, $lang, $avatar);
} }
} }

View file

@ -80,7 +80,7 @@ class Avatar
return $fields; return $fields;
} }
$img_str = $fetchResult->getBody(); $img_str = $fetchResult->getBodyString();
if (empty($img_str)) { if (empty($img_str)) {
Logger::debug('Avatar is invalid', ['avatar' => $avatar]); Logger::debug('Avatar is invalid', ['avatar' => $avatar]);
return $fields; return $fields;

View file

@ -383,7 +383,7 @@ class Item
'url' => $item['author-link'], 'url' => $item['author-link'],
'alias' => $item['author-alias'], 'alias' => $item['author-alias'],
]; ];
$profile_link = Contact::magicLinkByContact($author, $item['author-link']); $profile_link = Contact::magicLinkByContact($author, Contact::getProfileLink($author));
if (strpos($profile_link, 'contact/redir/') === 0) { if (strpos($profile_link, 'contact/redir/') === 0) {
$status_link = $profile_link . '?' . http_build_query(['url' => $item['author-link'] . '/status']); $status_link = $profile_link . '?' . http_build_query(['url' => $item['author-link'] . '/status']);
$photos_link = $profile_link . '?' . http_build_query(['url' => $item['author-link'] . '/photos']); $photos_link = $profile_link . '?' . http_build_query(['url' => $item['author-link'] . '/photos']);

View file

@ -120,7 +120,7 @@ class OEmbed
['https://www.youtube.com/', 'https://player.vimeo.com/'], $href); ['https://www.youtube.com/', 'https://player.vimeo.com/'], $href);
$result = DI::httpClient()->fetchFull($href . '&maxwidth=' . $a->getThemeInfoValue('videowidth')); $result = DI::httpClient()->fetchFull($href . '&maxwidth=' . $a->getThemeInfoValue('videowidth'));
if ($result->getReturnCode() === 200) { if ($result->getReturnCode() === 200) {
$json_string = $result->getBody(); $json_string = $result->getBodyString();
break; break;
} }
} }

View file

@ -45,19 +45,21 @@ class Hovercard
$actions = []; $actions = [];
} }
$contact_url = Contact::getProfileLink($contact);
// Move the contact data to the profile array so we can deliver it to // Move the contact data to the profile array so we can deliver it to
$tpl = Renderer::getMarkupTemplate('hovercard.tpl'); $tpl = Renderer::getMarkupTemplate('hovercard.tpl');
return Renderer::replaceMacros($tpl, [ return Renderer::replaceMacros($tpl, [
'$profile' => [ '$profile' => [
'name' => $contact['name'], 'name' => $contact['name'],
'nick' => $contact['nick'], 'nick' => $contact['nick'],
'addr' => $contact['addr'] ?: $contact['url'], 'addr' => $contact['addr'] ?: $contact_url,
'thumb' => Contact::getThumb($contact), 'thumb' => Contact::getThumb($contact),
'url' => Contact::magicLinkByContact($contact), 'url' => Contact::magicLinkByContact($contact),
'nurl' => $contact['nurl'], 'nurl' => $contact['nurl'],
'location' => $contact['location'], 'location' => $contact['location'],
'about' => $contact['about'], 'about' => $contact['about'],
'network_link' => Strings::formatNetworkName($contact['network'], $contact['url']), 'network_link' => Strings::formatNetworkName($contact['network'], $contact_url),
'tags' => $contact['keywords'], 'tags' => $contact['keywords'],
'bd' => $contact['bd'] <= DBA::NULL_DATE ? '' : $contact['bd'], 'bd' => $contact['bd'] <= DBA::NULL_DATE ? '' : $contact['bd'],
'account_type' => Contact::getAccountType($contact['contact-type']), 'account_type' => Contact::getAccountType($contact['contact-type']),

View file

@ -50,11 +50,7 @@ class VCard
Logger::warning('Incomplete contact', ['contact' => $contact ?? []]); Logger::warning('Incomplete contact', ['contact' => $contact ?? []]);
} }
if (!Network::isValidHttpUrl($contact['url']) && Network::isValidHttpUrl($contact['alias'])) { $contact_url = Contact::getProfileLink($contact);
$contact_url = $contact['alias'];
} else {
$contact_url = $contact['url'];
}
if ($contact['network'] != '') { if ($contact['network'] != '') {
$network_link = Strings::formatNetworkName($contact['network'], $contact_url); $network_link = Strings::formatNetworkName($contact['network'], $contact_url);

View file

@ -263,7 +263,7 @@ class ErrorHandler
public function handleError(int $code, string $message, string $file = '', int $line = 0, ?array $context = []): bool public function handleError(int $code, string $message, string $file = '', int $line = 0, ?array $context = []): bool
{ {
if ($this->handleOnlyReportedErrors && !(error_reporting() & $code)) { if ($this->handleOnlyReportedErrors && !(error_reporting() & $code)) {
return false; return true;
} }
// fatal error codes are ignored if a fatal error handler is present as well to avoid duplicate log entries // fatal error codes are ignored if a fatal error handler is present as well to avoid duplicate log entries

View file

@ -234,7 +234,7 @@ class Search
$p = $page > 1 ? 'p=' . $page : ''; $p = $page > 1 ? 'p=' . $page : '';
$curlResult = DI::httpClient()->get(self::getGlobalDirectory() . '/search/people?' . $p . '&q=' . urlencode($search), HttpClientAccept::JSON); $curlResult = DI::httpClient()->get(self::getGlobalDirectory() . '/search/people?' . $p . '&q=' . urlencode($search), HttpClientAccept::JSON);
if ($curlResult->isSuccess()) { if ($curlResult->isSuccess()) {
$searchResult = json_decode($curlResult->getBody(), true); $searchResult = json_decode($curlResult->getBodyString(), true);
if (!empty($searchResult['profiles'])) { if (!empty($searchResult['profiles'])) {
// Converting Directory Search results into contact-looking records // Converting Directory Search results into contact-looking records
$return = array_map(function ($result) { $return = array_map(function ($result) {

View file

@ -70,12 +70,12 @@ class ExternalResource implements ICanReadFromStorage
} }
if (!empty($fetchResult) && $fetchResult->isSuccess()) { if (!empty($fetchResult) && $fetchResult->isSuccess()) {
$this->logger->debug('Got picture', ['Content-Type' => $fetchResult->getHeader('Content-Type'), 'uid' => $data->uid, 'url' => $data->url]); $this->logger->debug('Got picture', ['Content-Type' => $fetchResult->getHeader('Content-Type'), 'uid' => $data->uid, 'url' => $data->url]);
return $fetchResult->getBody(); return $fetchResult->getBodyString();
} else { } else {
if (empty($fetchResult)) { if (empty($fetchResult)) {
throw new ReferenceStorageException(sprintf('External resource failed to get %s', $reference)); throw new ReferenceStorageException(sprintf('External resource failed to get %s', $reference));
} else { } else {
throw new ReferenceStorageException(sprintf('External resource failed to get %s', $reference), $fetchResult->getReturnCode(), new Exception($fetchResult->getBody())); throw new ReferenceStorageException(sprintf('External resource failed to get %s', $reference), $fetchResult->getReturnCode(), new Exception($fetchResult->getBodyString()));
} }
} }
} }

View file

@ -132,22 +132,6 @@ class DBA
return DI::dba()->connected(); return DI::dba()->connected();
} }
/**
* Replaces ANY_VALUE() function by MIN() function,
* if the database server does not support ANY_VALUE().
*
* Considerations for Standard SQL, or MySQL with ONLY_FULL_GROUP_BY (default since 5.7.5).
* ANY_VALUE() is available from MySQL 5.7.5 https://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html
* A standard fall-back is to use MIN().
*
* @param string $sql An SQL string without the values
* @return string The input SQL string modified if necessary.
*/
public static function anyValueFallback(string $sql): string
{
return DI::dba()->anyValueFallback($sql);
}
/** /**
* beautifies the query - useful for "SHOW PROCESSLIST" * beautifies the query - useful for "SHOW PROCESSLIST"
* *

View file

@ -439,28 +439,6 @@ class Database
return $connected; return $connected;
} }
/**
* Replaces ANY_VALUE() function by MIN() function,
* if the database server does not support ANY_VALUE().
*
* Considerations for Standard SQL, or MySQL with ONLY_FULL_GROUP_BY (default since 5.7.5).
* ANY_VALUE() is available from MySQL 5.7.5 https://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html
* A standard fall-back is to use MIN().
*
* @param string $sql An SQL string without the values
*
* @return string The input SQL string modified if necessary.
*/
public function anyValueFallback(string $sql): string
{
$server_info = $this->serverInfo();
if (version_compare($server_info, '5.7.5', '<') ||
(stripos($server_info, 'MariaDB') !== false)) {
$sql = str_ireplace('ANY_VALUE(', 'MIN(', $sql);
}
return $sql;
}
/** /**
* Replaces the ? placeholders with the parameters in the $args array * Replaces the ? placeholders with the parameters in the $args array
* *
@ -532,7 +510,6 @@ class Database
} }
$sql = DBA::cleanQuery($sql); $sql = DBA::cleanQuery($sql);
$sql = $this->anyValueFallback($sql);
$orig_sql = $sql; $orig_sql = $sql;
@ -1440,7 +1417,7 @@ class Database
private function escapeFields(array $fields, array $options): array private function escapeFields(array $fields, array $options): array
{ {
// In the case of a "GROUP BY" we have to add all the ORDER fields to the fieldlist. // In the case of a "GROUP BY" we have to add all the ORDER fields to the fieldlist.
// This needs to done to apply the "ANY_VALUE(...)" treatment from below to them. // This needs to done to apply the "MIN(...)" treatment from below to them.
// Otherwise MySQL would report errors. // Otherwise MySQL would report errors.
if (!empty($options['group_by']) && !empty($options['order'])) { if (!empty($options['group_by']) && !empty($options['order'])) {
foreach ($options['order'] as $key => $field) { foreach ($options['order'] as $key => $field) {
@ -1461,7 +1438,7 @@ class Database
$value = DBA::quoteIdentifier($field); $value = DBA::quoteIdentifier($field);
if (!empty($options['group_by']) && !in_array($field, $options['group_by'])) { if (!empty($options['group_by']) && !in_array($field, $options['group_by'])) {
$value = 'ANY_VALUE(' . $value . ') AS ' . $value; $value = 'MIN(' . $value . ') AS ' . $value;
} }
}); });

View file

@ -198,11 +198,11 @@ class APContact
try { try {
$curlResult = HTTPSignature::fetchRaw($url); $curlResult = HTTPSignature::fetchRaw($url);
$failed = empty($curlResult) || empty($curlResult->getBody()) || $failed = empty($curlResult) || empty($curlResult->getBodyString()) ||
(!$curlResult->isSuccess() && ($curlResult->getReturnCode() != 410)); (!$curlResult->isSuccess() && ($curlResult->getReturnCode() != 410));
if (!$failed) { if (!$failed) {
$data = json_decode($curlResult->getBody(), true); $data = json_decode($curlResult->getBodyString(), true);
$failed = empty($data) || !is_array($data); $failed = empty($data) || !is_array($data);
} }

View file

@ -2305,7 +2305,7 @@ class Contact
try { try {
$fetchResult = HTTPSignature::fetchRaw($avatar, 0, [HttpClientOptions::ACCEPT_CONTENT => [HttpClientAccept::IMAGE]]); $fetchResult = HTTPSignature::fetchRaw($avatar, 0, [HttpClientOptions::ACCEPT_CONTENT => [HttpClientAccept::IMAGE]]);
$img_str = $fetchResult->getBody(); $img_str = $fetchResult->getBodyString();
if (!empty($img_str)) { if (!empty($img_str)) {
$image = new Image($img_str, Images::getMimeTypeByData($img_str)); $image = new Image($img_str, Images::getMimeTypeByData($img_str));
if ($image->isValid()) { if ($image->isValid()) {
@ -3495,6 +3495,21 @@ class Contact
return array_column($contacts, 'id'); return array_column($contacts, 'id');
} }
/**
* Return the link to the profile
*
* @param array $contact
* @return string
*/
public static function getProfileLink(array $contact): string
{
if (!empty($contact['alias']) && Network::isValidHttpUrl($contact['alias']) && (($contact['network'] ?? '') != Protocol::DFRN)) {
return $contact['alias'];
} else {
return $contact['url'];
}
}
/** /**
* Returns a magic link to authenticate remote visitors * Returns a magic link to authenticate remote visitors
* *
@ -3553,7 +3568,7 @@ class Contact
*/ */
public static function magicLinkByContact(array $contact, string $url = ''): string public static function magicLinkByContact(array $contact, string $url = ''): string
{ {
$destination = $url ?: (!Network::isValidHttpUrl($contact['url']) && !empty($contact['alias']) && Network::isValidHttpUrl($contact['alias']) ? $contact['alias'] : $contact['url']); $destination = $url ?: self::getProfileLink($contact);
if (!DI::userSession()->isAuthenticated()) { if (!DI::userSession()->isAuthenticated()) {
return $destination; return $destination;

View file

@ -649,7 +649,7 @@ class GServer
} }
if ($curlResult->isSuccess()) { if ($curlResult->isSuccess()) {
$json = json_decode($curlResult->getBody(), true); $json = json_decode($curlResult->getBodyString(), true);
if (!empty($json) && is_array($json)) { if (!empty($json) && is_array($json)) {
$data = self::fetchDataFromSystemActor($json, $serverdata); $data = self::fetchDataFromSystemActor($json, $serverdata);
$serverdata = $data['server']; $serverdata = $data['server'];
@ -657,7 +657,7 @@ class GServer
if (!$html_fetched && !in_array($serverdata['detection-method'], [self::DETECT_SYSTEM_ACTOR, self::DETECT_AP_COLLECTION])) { if (!$html_fetched && !in_array($serverdata['detection-method'], [self::DETECT_SYSTEM_ACTOR, self::DETECT_AP_COLLECTION])) {
$curlResult = DI::httpClient()->get($url, HttpClientAccept::HTML); $curlResult = DI::httpClient()->get($url, HttpClientAccept::HTML);
} }
} elseif (!$html_fetched && (strlen($curlResult->getBody()) < 1000)) { } elseif (!$html_fetched && (strlen($curlResult->getBodyString()) < 1000)) {
$curlResult = DI::httpClient()->get($url, HttpClientAccept::HTML); $curlResult = DI::httpClient()->get($url, HttpClientAccept::HTML);
} }
@ -667,7 +667,7 @@ class GServer
} }
} }
if (!$curlResult->isSuccess() || empty($curlResult->getBody())) { if (!$curlResult->isSuccess() || empty($curlResult->getBodyString())) {
self::setFailureByUrl($url); self::setFailureByUrl($url);
return false; return false;
} }
@ -872,7 +872,7 @@ class GServer
return; return;
} }
$data = json_decode($curlResult->getBody(), true); $data = json_decode($curlResult->getBodyString(), true);
if (!is_array($data)) { if (!is_array($data)) {
return; return;
} }
@ -967,7 +967,7 @@ class GServer
return $serverdata; return $serverdata;
} }
$data = json_decode($curlResult->getBody(), true); $data = json_decode($curlResult->getBodyString(), true);
if (empty($data)) { if (empty($data)) {
return $serverdata; return $serverdata;
} }
@ -1059,7 +1059,7 @@ class GServer
return []; return [];
} }
$nodeinfo = json_decode($httpResult->getBody(), true); $nodeinfo = json_decode($httpResult->getBodyString(), true);
if (!is_array($nodeinfo) || empty($nodeinfo['links'])) { if (!is_array($nodeinfo) || empty($nodeinfo['links'])) {
return []; return [];
@ -1114,7 +1114,7 @@ class GServer
return []; return [];
} }
$nodeinfo = json_decode($curlResult->getBody(), true); $nodeinfo = json_decode($curlResult->getBodyString(), true);
if (!is_array($nodeinfo)) { if (!is_array($nodeinfo)) {
return []; return [];
@ -1214,7 +1214,7 @@ class GServer
return []; return [];
} }
$nodeinfo = json_decode($curlResult->getBody(), true); $nodeinfo = json_decode($curlResult->getBodyString(), true);
if (!is_array($nodeinfo)) { if (!is_array($nodeinfo)) {
return []; return [];
} }
@ -1331,7 +1331,7 @@ class GServer
return []; return [];
} }
$nodeinfo = json_decode($httpResult->getBody(), true); $nodeinfo = json_decode($httpResult->getBodyString(), true);
if (!is_array($nodeinfo)) { if (!is_array($nodeinfo)) {
return []; return [];
@ -1434,7 +1434,7 @@ class GServer
return $serverdata; return $serverdata;
} }
$data = json_decode($curlResult->getBody(), true); $data = json_decode($curlResult->getBodyString(), true);
if (empty($data)) { if (empty($data)) {
return $serverdata; return $serverdata;
} }
@ -1587,11 +1587,11 @@ class GServer
{ {
$name = 'nomad'; $name = 'nomad';
$curlResult = DI::httpClient()->get($url . '/manifest', 'application/manifest+json'); $curlResult = DI::httpClient()->get($url . '/manifest', 'application/manifest+json');
if (!$curlResult->isSuccess() || ($curlResult->getBody() == '')) { if (!$curlResult->isSuccess() || ($curlResult->getBodyString() == '')) {
return $name; return $name;
} }
$data = json_decode($curlResult->getBody(), true); $data = json_decode($curlResult->getBodyString(), true);
if (empty($data)) { if (empty($data)) {
return $name; return $name;
} }
@ -1608,11 +1608,11 @@ class GServer
private static function getNomadVersion(string $url): string private static function getNomadVersion(string $url): string
{ {
$curlResult = DI::httpClient()->get($url . '/api/z/1.0/version', HttpClientAccept::JSON); $curlResult = DI::httpClient()->get($url . '/api/z/1.0/version', HttpClientAccept::JSON);
if (!$curlResult->isSuccess() || ($curlResult->getBody() == '')) { if (!$curlResult->isSuccess() || ($curlResult->getBodyString() == '')) {
return ''; return '';
} }
$data = json_decode($curlResult->getBody(), true); $data = json_decode($curlResult->getBodyString(), true);
if (empty($data)) { if (empty($data)) {
return ''; return '';
} }
@ -1634,7 +1634,7 @@ class GServer
return false; return false;
} }
$xrd = XML::parseString($curlResult->getBody(), true); $xrd = XML::parseString($curlResult->getBodyString(), true);
if (!is_object($xrd)) { if (!is_object($xrd)) {
return false; return false;
} }
@ -1733,7 +1733,7 @@ class GServer
return $serverdata; return $serverdata;
} }
$data = json_decode($curlResult->getBody(), true); $data = json_decode($curlResult->getBodyString(), true);
if (empty($data)) { if (empty($data)) {
return $serverdata; return $serverdata;
} }
@ -1763,7 +1763,7 @@ class GServer
return $serverdata; return $serverdata;
} }
$data = json_decode($curlResult->getBody(), true); $data = json_decode($curlResult->getBodyString(), true);
if (empty($data)) { if (empty($data)) {
return $serverdata; return $serverdata;
} }
@ -1786,11 +1786,11 @@ class GServer
private static function detectPeertube(string $url, array $serverdata): array private static function detectPeertube(string $url, array $serverdata): array
{ {
$curlResult = DI::httpClient()->get($url . '/api/v1/config', HttpClientAccept::JSON); $curlResult = DI::httpClient()->get($url . '/api/v1/config', HttpClientAccept::JSON);
if (!$curlResult->isSuccess() || ($curlResult->getBody() == '')) { if (!$curlResult->isSuccess() || ($curlResult->getBodyString() == '')) {
return $serverdata; return $serverdata;
} }
$data = json_decode($curlResult->getBody(), true); $data = json_decode($curlResult->getBodyString(), true);
if (empty($data)) { if (empty($data)) {
return $serverdata; return $serverdata;
} }
@ -1834,11 +1834,11 @@ class GServer
private static function detectNextcloud(string $url, array $serverdata, bool $validHostMeta): array private static function detectNextcloud(string $url, array $serverdata, bool $validHostMeta): array
{ {
$curlResult = DI::httpClient()->get($url . '/status.php', HttpClientAccept::JSON); $curlResult = DI::httpClient()->get($url . '/status.php', HttpClientAccept::JSON);
if (!$curlResult->isSuccess() || ($curlResult->getBody() == '')) { if (!$curlResult->isSuccess() || ($curlResult->getBodyString() == '')) {
return $serverdata; return $serverdata;
} }
$data = json_decode($curlResult->getBody(), true); $data = json_decode($curlResult->getBodyString(), true);
if (empty($data)) { if (empty($data)) {
return $serverdata; return $serverdata;
} }
@ -1870,11 +1870,11 @@ class GServer
private static function fetchWeeklyUsage(string $url, array $serverdata): array private static function fetchWeeklyUsage(string $url, array $serverdata): array
{ {
$curlResult = DI::httpClient()->get($url . '/api/v1/instance/activity', HttpClientAccept::JSON); $curlResult = DI::httpClient()->get($url . '/api/v1/instance/activity', HttpClientAccept::JSON);
if (!$curlResult->isSuccess() || ($curlResult->getBody() == '')) { if (!$curlResult->isSuccess() || ($curlResult->getBodyString() == '')) {
return $serverdata; return $serverdata;
} }
$data = json_decode($curlResult->getBody(), true); $data = json_decode($curlResult->getBodyString(), true);
if (empty($data)) { if (empty($data)) {
return $serverdata; return $serverdata;
} }
@ -1910,11 +1910,11 @@ class GServer
private static function detectMastodonAlikes(string $url, array $serverdata): array private static function detectMastodonAlikes(string $url, array $serverdata): array
{ {
$curlResult = DI::httpClient()->get($url . '/api/v1/instance', HttpClientAccept::JSON); $curlResult = DI::httpClient()->get($url . '/api/v1/instance', HttpClientAccept::JSON);
if (!$curlResult->isSuccess() || ($curlResult->getBody() == '')) { if (!$curlResult->isSuccess() || ($curlResult->getBodyString() == '')) {
return $serverdata; return $serverdata;
} }
$data = json_decode($curlResult->getBody(), true); $data = json_decode($curlResult->getBodyString(), true);
if (empty($data)) { if (empty($data)) {
return $serverdata; return $serverdata;
} }
@ -1982,11 +1982,11 @@ class GServer
private static function detectHubzilla(string $url, array $serverdata): array private static function detectHubzilla(string $url, array $serverdata): array
{ {
$curlResult = DI::httpClient()->get($url . '/api/statusnet/config.json', HttpClientAccept::JSON); $curlResult = DI::httpClient()->get($url . '/api/statusnet/config.json', HttpClientAccept::JSON);
if (!$curlResult->isSuccess() || ($curlResult->getBody() == '')) { if (!$curlResult->isSuccess() || ($curlResult->getBodyString() == '')) {
return $serverdata; return $serverdata;
} }
$data = json_decode($curlResult->getBody(), true); $data = json_decode($curlResult->getBodyString(), true);
if (empty($data) || empty($data['site'])) { if (empty($data) || empty($data['site'])) {
return $serverdata; return $serverdata;
} }
@ -2079,11 +2079,11 @@ class GServer
{ {
// Test for GNU Social // Test for GNU Social
$curlResult = DI::httpClient()->get($url . '/api/gnusocial/version.json', HttpClientAccept::JSON); $curlResult = DI::httpClient()->get($url . '/api/gnusocial/version.json', HttpClientAccept::JSON);
if ($curlResult->isSuccess() && ($curlResult->getBody() != '{"error":"not implemented"}') && if ($curlResult->isSuccess() && ($curlResult->getBodyString() != '{"error":"not implemented"}') &&
($curlResult->getBody() != '') && (strlen($curlResult->getBody()) < 30)) { ($curlResult->getBodyString() != '') && (strlen($curlResult->getBodyString()) < 30)) {
$serverdata['platform'] = 'gnusocial'; $serverdata['platform'] = 'gnusocial';
// Remove junk that some GNU Social servers return // Remove junk that some GNU Social servers return
$serverdata['version'] = str_replace(chr(239) . chr(187) . chr(191), '', $curlResult->getBody()); $serverdata['version'] = str_replace(chr(239) . chr(187) . chr(191), '', $curlResult->getBodyString());
$serverdata['version'] = str_replace(["\r", "\n", "\t"], '', $serverdata['version']); $serverdata['version'] = str_replace(["\r", "\n", "\t"], '', $serverdata['version']);
$serverdata['version'] = trim($serverdata['version'], '"'); $serverdata['version'] = trim($serverdata['version'], '"');
$serverdata['network'] = Protocol::OSTATUS; $serverdata['network'] = Protocol::OSTATUS;
@ -2097,11 +2097,11 @@ class GServer
// Test for Statusnet // Test for Statusnet
$curlResult = DI::httpClient()->get($url . '/api/statusnet/version.json', HttpClientAccept::JSON); $curlResult = DI::httpClient()->get($url . '/api/statusnet/version.json', HttpClientAccept::JSON);
if ($curlResult->isSuccess() && ($curlResult->getBody() != '{"error":"not implemented"}') && if ($curlResult->isSuccess() && ($curlResult->getBodyString() != '{"error":"not implemented"}') &&
($curlResult->getBody() != '') && (strlen($curlResult->getBody()) < 30)) { ($curlResult->getBodyString() != '') && (strlen($curlResult->getBodyString()) < 30)) {
// Remove junk that some GNU Social servers return // Remove junk that some GNU Social servers return
$serverdata['version'] = str_replace(chr(239).chr(187).chr(191), '', $curlResult->getBody()); $serverdata['version'] = str_replace(chr(239).chr(187).chr(191), '', $curlResult->getBodyString());
$serverdata['version'] = str_replace(["\r", "\n", "\t"], '', $serverdata['version']); $serverdata['version'] = str_replace(["\r", "\n", "\t"], '', $serverdata['version']);
$serverdata['version'] = trim($serverdata['version'], '"'); $serverdata['version'] = trim($serverdata['version'], '"');
@ -2148,7 +2148,7 @@ class GServer
return $serverdata; return $serverdata;
} }
$data = json_decode($curlResult->getBody(), true); $data = json_decode($curlResult->getBodyString(), true);
if (empty($data) || empty($data['version'])) { if (empty($data) || empty($data['version'])) {
return $serverdata; return $serverdata;
} }
@ -2466,7 +2466,7 @@ class GServer
$api = 'https://instances.social/api/1.0/instances/list?count=0'; $api = 'https://instances.social/api/1.0/instances/list?count=0';
$curlResult = DI::httpClient()->get($api, HttpClientAccept::JSON, [HttpClientOptions::HEADERS => ['Authorization' => ['Bearer ' . $accesstoken]]]); $curlResult = DI::httpClient()->get($api, HttpClientAccept::JSON, [HttpClientOptions::HEADERS => ['Authorization' => ['Bearer ' . $accesstoken]]]);
if ($curlResult->isSuccess()) { if ($curlResult->isSuccess()) {
$servers = json_decode($curlResult->getBody(), true); $servers = json_decode($curlResult->getBodyString(), true);
if (!empty($servers['instances'])) { if (!empty($servers['instances'])) {
foreach ($servers['instances'] as $server) { foreach ($servers['instances'] as $server) {

View file

@ -127,8 +127,6 @@ class Mail
*/ */
public static function send(int $sender_uid, int $recipient = 0, string $body = '', string $subject = '', string $replyto = ''): int public static function send(int $sender_uid, int $recipient = 0, string $body = '', string $subject = '', string $replyto = ''): int
{ {
$a = DI::app();
if (!$recipient) { if (!$recipient) {
return -1; return -1;
} }
@ -246,77 +244,4 @@ class Mail
return -3; return -3;
} }
} }
/**
* @param array $recipient recipient, default empty
* @param string $body message body, default empty
* @param string $subject message subject, default empty
* @param string $replyto reply to, default empty
* @return int
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
* @throws \ImagickException
*/
public static function sendWall(array $recipient = [], string $body = '', string $subject = '', string $replyto = ''): int
{
if (!$recipient) {
return -1;
}
if (!strlen($subject)) {
$subject = DI::l10n()->t('[no subject]');
}
$guid = System::createUUID();
$uri = Item::newURI($guid);
$me = Contact::getByURL($replyto);
if (!$me['name']) {
return -2;
}
$conv_guid = System::createUUID();
$recip_handle = $recipient['nickname'] . '@' . substr(DI::baseUrl(), strpos(DI::baseUrl(), '://') + 3);
$sender_handle = $me['addr'];
$handles = $recip_handle . ';' . $sender_handle;
$convid = null;
$fields = ['uid' => $recipient['uid'], 'guid' => $conv_guid, 'creator' => $sender_handle,
'created' => DateTimeFormat::utcNow(), 'updated' => DateTimeFormat::utcNow(),
'subject' => $subject, 'recips' => $handles];
if (DBA::insert('conv', $fields)) {
$convid = DBA::lastInsertId();
}
if (!$convid) {
Logger::warning('conversation not found.');
return -4;
}
self::insert(
[
'uid' => $recipient['uid'],
'guid' => $guid,
'convid' => $convid,
'from-name' => $me['name'],
'from-photo' => $me['photo'],
'from-url' => $me['url'],
'contact-id' => 0,
'title' => $subject,
'body' => $body,
'seen' => 0,
'reply' => 0,
'replied' => 0,
'uri' => $uri,
'parent-uri' => $me['url'],
'created' => DateTimeFormat::utcNow(),
'unknown' => 1
],
false
);
return 0;
}
} }

View file

@ -229,8 +229,8 @@ class Photo
return DBA::toArray( return DBA::toArray(
DBA::p( DBA::p(
"SELECT `resource-id`, ANY_VALUE(`id`) AS `id`, ANY_VALUE(`filename`) AS `filename`, ANY_VALUE(`type`) AS `type`, "SELECT `resource-id`, MIN(`id`) AS `id`, MIN(`filename`) AS `filename`, MIN(`type`) AS `type`,
min(`scale`) AS `hiq`, max(`scale`) AS `loq`, ANY_VALUE(`desc`) AS `desc`, ANY_VALUE(`created`) AS `created` min(`scale`) AS `hiq`, max(`scale`) AS `loq`, MIN(`desc`) AS `desc`, MIN(`created`) AS `created`
FROM `photo` WHERE `uid` = ? AND NOT `photo-type` IN (?, ?) $sqlExtra FROM `photo` WHERE `uid` = ? AND NOT `photo-type` IN (?, ?) $sqlExtra
GROUP BY `resource-id` $sqlExtra2", GROUP BY `resource-id` $sqlExtra2",
$values $values
@ -597,7 +597,7 @@ class Photo
if (!empty($image_url)) { if (!empty($image_url)) {
$ret = DI::httpClient()->get($image_url, HttpClientAccept::IMAGE); $ret = DI::httpClient()->get($image_url, HttpClientAccept::IMAGE);
Logger::debug('Got picture', ['Content-Type' => $ret->getHeader('Content-Type'), 'url' => $image_url]); Logger::debug('Got picture', ['Content-Type' => $ret->getHeader('Content-Type'), 'url' => $image_url]);
$img_str = $ret->getBody(); $img_str = $ret->getBodyString();
$type = $ret->getContentType(); $type = $ret->getContentType();
} else { } else {
$img_str = ''; $img_str = '';
@ -751,7 +751,7 @@ class Photo
if (!DI::config()->get('system', 'no_count', false)) { if (!DI::config()->get('system', 'no_count', false)) {
/// @todo This query needs to be renewed. It is really slow /// @todo This query needs to be renewed. It is really slow
// At this time we just store the data in the cache // At this time we just store the data in the cache
$albums = DBA::toArray(DBA::p("SELECT COUNT(DISTINCT `resource-id`) AS `total`, `album`, ANY_VALUE(`created`) AS `created` $albums = DBA::toArray(DBA::p("SELECT COUNT(DISTINCT `resource-id`) AS `total`, `album`, MIN(`created`) AS `created`
FROM `photo` FROM `photo`
WHERE `uid` = ? AND `photo-type` IN (?, ?, ?) $sql_extra WHERE `uid` = ? AND `photo-type` IN (?, ?, ?) $sql_extra
GROUP BY `album` ORDER BY `created` DESC", GROUP BY `album` ORDER BY `created` DESC",
@ -762,9 +762,10 @@ class Photo
)); ));
} else { } else {
// This query doesn't do the count and is much faster // This query doesn't do the count and is much faster
$albums = DBA::toArray(DBA::p("SELECT DISTINCT(`album`), '' AS `total` $albums = DBA::toArray(DBA::p("SELECT '' AS `total`, `album`, MIN(`created`) AS `created`
FROM `photo` USE INDEX (`uid_album_scale_created`) FROM `photo` USE INDEX (`uid_album_scale_created`)
WHERE `uid` = ? AND `photo-type` IN (?, ?, ?) $sql_extra", WHERE `uid` = ? AND `photo-type` IN (?, ?, ?) $sql_extra
GROUP BY `album` ORDER BY `created` DESC",
$uid, $uid,
self::DEFAULT, self::DEFAULT,
$banner_type, $banner_type,
@ -1047,7 +1048,7 @@ class Photo
if (!empty($image_url)) { if (!empty($image_url)) {
$ret = DI::httpClient()->get($image_url, HttpClientAccept::IMAGE); $ret = DI::httpClient()->get($image_url, HttpClientAccept::IMAGE);
Logger::debug('Got picture', ['Content-Type' => $ret->getHeader('Content-Type'), 'url' => $image_url]); Logger::debug('Got picture', ['Content-Type' => $ret->getHeader('Content-Type'), 'url' => $image_url]);
$img_str = $ret->getBody(); $img_str = $ret->getBodyString();
$type = $ret->getContentType(); $type = $ret->getContentType();
} else { } else {
$img_str = ''; $img_str = '';

View file

@ -135,7 +135,7 @@ class Link
} }
$fields = ['mimetype' => $curlResult->getHeader('Content-Type')[0]]; $fields = ['mimetype' => $curlResult->getHeader('Content-Type')[0]];
$img_str = $curlResult->getBody(); $img_str = $curlResult->getBodyString();
$image = new Image($img_str, Images::getMimeTypeByData($img_str)); $image = new Image($img_str, Images::getMimeTypeByData($img_str));
if ($image->isValid()) { if ($image->isValid()) {
$fields['mimetype'] = $image->getType(); $fields['mimetype'] = $image->getType();

View file

@ -208,13 +208,17 @@ class Media
$filetype = !empty($media['mimetype']) ? strtolower(current(explode('/', $media['mimetype']))) : ''; $filetype = !empty($media['mimetype']) ? strtolower(current(explode('/', $media['mimetype']))) : '';
if (($media['type'] == self::IMAGE) || ($filetype == 'image')) { if (($media['type'] == self::IMAGE) || ($filetype == 'image')) {
$imagedata = Images::getInfoFromURLCached($media['url']); $imagedata = Images::getInfoFromURLCached($media['url'], empty($media['description']));
if ($imagedata) { if ($imagedata) {
$media['mimetype'] = $imagedata['mime']; $media['mimetype'] = $imagedata['mime'];
$media['size'] = $imagedata['size']; $media['size'] = $imagedata['size'];
$media['width'] = $imagedata[0]; $media['width'] = $imagedata[0];
$media['height'] = $imagedata[1]; $media['height'] = $imagedata[1];
$media['blurhash'] = $imagedata['blurhash'] ?? null; $media['blurhash'] = $imagedata['blurhash'] ?? null;
if (!empty($imagedata['description']) && empty($media['description'])) {
$media['description'] = $imagedata['description'];
Logger::debug('Detected text for image', $media);
}
} else { } else {
Logger::notice('No image data', ['media' => $media]); Logger::notice('No image data', ['media' => $media]);
} }

View file

@ -874,7 +874,7 @@ class User
try { try {
$passwordExposedChecker = new PasswordExposed\PasswordExposedChecker(null, $cache); $passwordExposedChecker = new PasswordExposed\PasswordExposedChecker(null, $cache);
return $passwordExposedChecker->passwordExposed($password) === PasswordExposed\PasswordStatus::EXPOSED; return $passwordExposedChecker->passwordExposed($password) === PasswordExposed\Enums\PasswordStatus::EXPOSED;
} catch (Exception $e) { } catch (Exception $e) {
Logger::error('Password Exposed Exception: ' . $e->getMessage(), [ Logger::error('Password Exposed Exception: ' . $e->getMessage(), [
'code' => $e->getCode(), 'code' => $e->getCode(),
@ -1393,7 +1393,7 @@ class User
$curlResult = DI::httpClient()->get($photo, HttpClientAccept::IMAGE); $curlResult = DI::httpClient()->get($photo, HttpClientAccept::IMAGE);
if ($curlResult->isSuccess()) { if ($curlResult->isSuccess()) {
Logger::debug('Got picture', ['Content-Type' => $curlResult->getHeader('Content-Type'), 'url' => $photo]); Logger::debug('Got picture', ['Content-Type' => $curlResult->getHeader('Content-Type'), 'url' => $photo]);
$img_str = $curlResult->getBody(); $img_str = $curlResult->getBodyString();
$type = $curlResult->getContentType(); $type = $curlResult->getContentType();
} else { } else {
$img_str = ''; $img_str = '';
@ -1567,12 +1567,13 @@ class User
* @param string $email The user's email address * @param string $email The user's email address
* @param string $nick The user's nick name * @param string $nick The user's nick name
* @param string $lang The user's language (default is english) * @param string $lang The user's language (default is english)
* @param string $avatar URL to an image to use as avatar (default is to prompt user at first login)
* @return bool True, if the user was created successfully * @return bool True, if the user was created successfully
* @throws HTTPException\InternalServerErrorException * @throws HTTPException\InternalServerErrorException
* @throws ErrorException * @throws ErrorException
* @throws ImagickException * @throws ImagickException
*/ */
public static function createMinimal(string $name, string $email, string $nick, string $lang = L10n::DEFAULT): bool public static function createMinimal(string $name, string $email, string $nick, string $lang = L10n::DEFAULT, string $avatar = ''): bool
{ {
if (empty($name) || if (empty($name) ||
empty($email) || empty($email) ||
@ -1585,7 +1586,8 @@ class User
'email' => $email, 'email' => $email,
'nickname' => $nick, 'nickname' => $nick,
'verified' => 1, 'verified' => 1,
'language' => $lang 'language' => $lang,
'photo' => $avatar
]); ]);
$user = $result['user']; $user = $result['user'];

View file

@ -97,7 +97,7 @@ class Federation extends BaseAdmin
SUM(IFNULL(`local-posts`, 0) + IFNULL(`local-comments`, 0)) AS `posts`, SUM(IFNULL(`local-posts`, 0) + IFNULL(`local-comments`, 0)) AS `posts`,
SUM(IFNULL(`active-month-users`, `active-week-users`)) AS `month`, SUM(IFNULL(`active-month-users`, `active-week-users`)) AS `month`,
SUM(IFNULL(`active-halfyear-users`, `active-week-users`)) AS `halfyear`, `platform`, SUM(IFNULL(`active-halfyear-users`, `active-week-users`)) AS `halfyear`, `platform`,
ANY_VALUE(`network`) AS `network`, MAX(`version`) AS `version` MIN(`network`) AS `network`, MAX(`version`) AS `version`
FROM `gserver` WHERE NOT `failed` AND `platform` != ? AND `detection-method` != ? AND NOT `network` IN (?, ?) GROUP BY `platform`", FROM `gserver` WHERE NOT `failed` AND `platform` != ? AND `detection-method` != ? AND NOT `network` IN (?, ?) GROUP BY `platform`",
'', GServer::DETECT_MANUAL, Protocol::PHANTOM, Protocol::FEED); '', GServer::DETECT_MANUAL, Protocol::PHANTOM, Protocol::FEED);
while ($gserver = DBA::fetch($gservers)) { while ($gserver = DBA::fetch($gservers)) {

View file

@ -132,7 +132,7 @@ class MatchInterests extends BaseModule
} }
} }
$entries = $this->parseContacts(json_decode($result->getBody()), $entries, $limit); $entries = $this->parseContacts(json_decode($result->getBodyString()), $entries, $limit);
} }
if (empty($entries)) { if (empty($entries)) {

View file

@ -132,8 +132,8 @@ class Community extends Timeline
$pager = new BoundariesPager( $pager = new BoundariesPager(
$this->l10n, $this->l10n,
$this->args->getQueryString(), $this->args->getQueryString(),
$items[0]['received'], $items[array_key_first($items)]['received'],
$items[count($items) - 1]['received'], $items[array_key_last($items)]['received'],
$this->itemsPerPage $this->itemsPerPage
); );

View file

@ -155,7 +155,7 @@ class Magic extends BaseModule
System::externalRedirect($dest); System::externalRedirect($dest);
} }
$j = json_decode($curlResult->getBody(), true); $j = json_decode($curlResult->getBodyString(), true);
if (empty($j) || !$j['success']) { if (empty($j) || !$j['success']) {
$this->logger->notice('Invalid JSON, redirecting to destination.', ['json' => $j, 'dest' => $dest]); $this->logger->notice('Invalid JSON, redirecting to destination.', ['json' => $j, 'dest' => $dest]);
$this->app->redirect($dest); $this->app->redirect($dest);

View file

@ -154,7 +154,7 @@ class PubSubHubBub extends \Friendica\BaseModule
$separator = parse_url($hub_callback, PHP_URL_QUERY) === null ? '?' : '&'; $separator = parse_url($hub_callback, PHP_URL_QUERY) === null ? '?' : '&';
$fetchResult = $this->httpClient->fetchFull($hub_callback . $separator . $params); $fetchResult = $this->httpClient->fetchFull($hub_callback . $separator . $params);
$body = $fetchResult->getBody(); $body = $fetchResult->getBodyString();
$returnCode = $fetchResult->getReturnCode(); $returnCode = $fetchResult->getReturnCode();
// give up if the HTTP return code wasn't a success (2xx) // give up if the HTTP return code wasn't a success (2xx)

View file

@ -96,7 +96,7 @@ class Subscribe extends \Friendica\BaseModule
return $o . $this->t('Couldn\'t fetch friends for contact.'); return $o . $this->t('Couldn\'t fetch friends for contact.');
} }
$friends = $curlResult->getBody(); $friends = $curlResult->getBodyString();
if (empty($friends)) { if (empty($friends)) {
$this->pConfig->delete($uid, 'ostatus', 'legacy_contact'); $this->pConfig->delete($uid, 'ostatus', 'legacy_contact');
return $o . $this->t('Couldn\'t fetch following contacts.'); return $o . $this->t('Couldn\'t fetch following contacts.');

View file

@ -322,12 +322,12 @@ class Photos extends \Friendica\Module\BaseProfile
$photos = $this->database->toArray($this->database->p( $photos = $this->database->toArray($this->database->p(
"SELECT "SELECT
`resource-id`, `resource-id`,
ANY_VALUE(`id`) AS `id`, MIN(`id`) AS `id`,
ANY_VALUE(`filename`) AS `filename`, MIN(`filename`) AS `filename`,
ANY_VALUE(`type`) AS `type`, MIN(`type`) AS `type`,
ANY_VALUE(`album`) AS `album`, MIN(`album`) AS `album`,
max(`scale`) AS `scale`, MAX(`scale`) AS `scale`,
ANY_VALUE(`created`) AS `created` MIN(`created`) AS `created`
FROM `photo` FROM `photo`
WHERE `uid` = ? WHERE `uid` = ?
AND `photo-type` = ? AND `photo-type` = ?

View file

@ -85,7 +85,7 @@ class Proxy extends BaseModule
// Fetch the content with the local user // Fetch the content with the local user
try { try {
$fetchResult = HTTPSignature::fetchRaw($request['url'], DI::userSession()->getLocalUserId(), [HttpClientOptions::ACCEPT_CONTENT => [HttpClientAccept::IMAGE], 'timeout' => 10]); $fetchResult = HTTPSignature::fetchRaw($request['url'], DI::userSession()->getLocalUserId(), [HttpClientOptions::ACCEPT_CONTENT => [HttpClientAccept::IMAGE], 'timeout' => 10]);
$img_str = $fetchResult->getBody(); $img_str = $fetchResult->getBodyString();
if (!$fetchResult->isSuccess() || empty($img_str)) { if (!$fetchResult->isSuccess() || empty($img_str)) {
Logger::notice('Error fetching image', ['image' => $request['url'], 'return' => $fetchResult->getReturnCode(), 'empty' => empty($img_str)]); Logger::notice('Error fetching image', ['image' => $request['url'], 'return' => $fetchResult->getReturnCode(), 'empty' => empty($img_str)]);

View file

@ -97,10 +97,9 @@ interface ICanHandleHttpResponses
/** /**
* Getter for body * Getter for body
* *
* @see MessageInterface::getBody()
* @return string * @return string
*/ */
public function getBody(); public function getBodyString();
/** /**
* @return boolean * @return boolean

View file

@ -73,7 +73,7 @@ class HttpClient implements ICanSendHttpRequests
throw new \InvalidArgumentException('Unable to retrieve the host in URL: ' . $url); throw new \InvalidArgumentException('Unable to retrieve the host in URL: ' . $url);
} }
if(!filter_var($host, FILTER_VALIDATE_IP) && !@dns_get_record($host . '.', DNS_A + DNS_AAAA)) { if(!filter_var($host, FILTER_VALIDATE_IP) && !@dns_get_record($host . '.', DNS_A) && !@dns_get_record($host . '.', DNS_AAAA)) {
$this->logger->debug('URL cannot be resolved.', ['url' => $url]); $this->logger->debug('URL cannot be resolved.', ['url' => $url]);
$this->profiler->stopRecording(); $this->profiler->stopRecording();
return CurlResult::createErrorCurl($this->logger, $url); return CurlResult::createErrorCurl($this->logger, $url);
@ -271,7 +271,7 @@ class HttpClient implements ICanSendHttpRequests
{ {
$ret = $this->fetchFull($url, $accept_content, $timeout, $cookiejar); $ret = $this->fetchFull($url, $accept_content, $timeout, $cookiejar);
return $ret->getBody(); return $ret->getBodyString();
} }
/** /**

View file

@ -330,7 +330,7 @@ class CurlResult implements ICanHandleHttpResponses
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
public function getBody(): string public function getBodyString(): string
{ {
return $this->body; return $this->body;
} }

View file

@ -163,8 +163,7 @@ class GuzzleResponse extends Response implements ICanHandleHttpResponses, Respon
return $this->isTimeout; return $this->isTimeout;
} }
/// @todo - fix mismatching use of "getBody()" as string here and parent "getBody()" as streaminterface public function getBodyString(): string
public function getBody(): string
{ {
return (string) parent::getBody(); return (string) parent::getBody();
} }

View file

@ -225,7 +225,7 @@ class Probe
$curlResult = DI::httpClient()->get($ssl_url, HttpClientAccept::XRD_XML, [HttpClientOptions::TIMEOUT => $xrd_timeout]); $curlResult = DI::httpClient()->get($ssl_url, HttpClientAccept::XRD_XML, [HttpClientOptions::TIMEOUT => $xrd_timeout]);
$ssl_connection_error = ($curlResult->getErrorNumber() == CURLE_COULDNT_CONNECT) || ($curlResult->getReturnCode() == 0); $ssl_connection_error = ($curlResult->getErrorNumber() == CURLE_COULDNT_CONNECT) || ($curlResult->getReturnCode() == 0);
if ($curlResult->isSuccess()) { if ($curlResult->isSuccess()) {
$xml = $curlResult->getBody(); $xml = $curlResult->getBodyString();
$xrd = XML::parseString($xml, true); $xrd = XML::parseString($xml, true);
if (!empty($url)) { if (!empty($url)) {
$host_url = 'https://' . $host; $host_url = 'https://' . $host;
@ -250,7 +250,7 @@ class Probe
return []; return [];
} }
$xml = $curlResult->getBody(); $xml = $curlResult->getBodyString();
$xrd = XML::parseString($xml, true); $xrd = XML::parseString($xml, true);
$host_url = 'http://'.$host; $host_url = 'http://'.$host;
} }
@ -459,7 +459,7 @@ class Probe
return false; return false;
} }
$body = $curlResult->getBody(); $body = $curlResult->getBodyString();
if (empty($body)) { if (empty($body)) {
return false; return false;
} }
@ -865,7 +865,7 @@ class Probe
if ($curlResult->isTimeout()) { if ($curlResult->isTimeout()) {
return $data; return $data;
} }
$content = $curlResult->getBody(); $content = $curlResult->getBodyString();
if (!$content) { if (!$content) {
return $data; return $data;
} }
@ -971,7 +971,7 @@ class Probe
self::$isTimeout = true; self::$isTimeout = true;
return []; return [];
} }
$data = $curlResult->getBody(); $data = $curlResult->getBodyString();
$webfinger = json_decode($data, true); $webfinger = json_decode($data, true);
if (!empty($webfinger)) { if (!empty($webfinger)) {
@ -1040,7 +1040,7 @@ class Probe
self::$isTimeout = true; self::$isTimeout = true;
return $data; return $data;
} }
$content = $curlResult->getBody(); $content = $curlResult->getBodyString();
if (!$content) { if (!$content) {
Logger::info('Empty body', ['url' => $noscrape_url]); Logger::info('Empty body', ['url' => $noscrape_url]);
return $data; return $data;
@ -1303,7 +1303,7 @@ class Probe
self::$isTimeout = true; self::$isTimeout = true;
return []; return [];
} }
$content = $curlResult->getBody(); $content = $curlResult->getBodyString();
if (empty($content)) { if (empty($content)) {
return []; return [];
} }
@ -1580,7 +1580,7 @@ class Probe
return $short ? false : []; return $short ? false : [];
} }
Logger::debug('Fetched public key', ['Content-Type' => $curlResult->getHeader('Content-Type'), 'url' => $pubkey]); Logger::debug('Fetched public key', ['Content-Type' => $curlResult->getHeader('Content-Type'), 'url' => $pubkey]);
$pubkey = $curlResult->getBody(); $pubkey = $curlResult->getBodyString();
} }
try { try {
@ -1612,7 +1612,7 @@ class Probe
self::$isTimeout = true; self::$isTimeout = true;
return []; return [];
} }
$feed = $curlResult->getBody(); $feed = $curlResult->getBodyString();
$feed_data = Feed::import($feed); $feed_data = Feed::import($feed);
if (!$feed_data) { if (!$feed_data) {
return []; return [];
@ -1660,12 +1660,12 @@ class Probe
private static function pumpioProfileData(string $profile_link, string $baseurl): array private static function pumpioProfileData(string $profile_link, string $baseurl): array
{ {
$curlResult = DI::httpClient()->get($profile_link, HttpClientAccept::HTML); $curlResult = DI::httpClient()->get($profile_link, HttpClientAccept::HTML);
if (!$curlResult->isSuccess() || empty($curlResult->getBody())) { if (!$curlResult->isSuccess() || empty($curlResult->getBodyString())) {
return []; return [];
} }
$doc = new DOMDocument(); $doc = new DOMDocument();
if (!@$doc->loadHTML($curlResult->getBody())) { if (!@$doc->loadHTML($curlResult->getBodyString())) {
return []; return [];
} }
@ -1887,7 +1887,7 @@ class Probe
return []; return [];
} }
$feed = $curlResult->getBody(); $feed = $curlResult->getBodyString();
$feed_data = Feed::import($feed); $feed_data = Feed::import($feed);
if (!$feed_data) { if (!$feed_data) {
@ -2112,8 +2112,8 @@ class Probe
$curlResult = DI::httpClient()->get($gserver['noscrape'] . '/' . $data['nick'], HttpClientAccept::JSON); $curlResult = DI::httpClient()->get($gserver['noscrape'] . '/' . $data['nick'], HttpClientAccept::JSON);
if ($curlResult->isSuccess() && !empty($curlResult->getBody())) { if ($curlResult->isSuccess() && !empty($curlResult->getBodyString())) {
$noscrape = json_decode($curlResult->getBody(), true); $noscrape = json_decode($curlResult->getBodyString(), true);
if (!empty($noscrape) && !empty($noscrape['updated'])) { if (!empty($noscrape) && !empty($noscrape['updated'])) {
return DateTimeFormat::utc($noscrape['updated'], DateTimeFormat::MYSQL); return DateTimeFormat::utc($noscrape['updated'], DateTimeFormat::MYSQL);
} }
@ -2187,12 +2187,12 @@ class Probe
{ {
// Search for the newest entry in the feed // Search for the newest entry in the feed
$curlResult = DI::httpClient()->get($data['poll'], HttpClientAccept::ATOM_XML); $curlResult = DI::httpClient()->get($data['poll'], HttpClientAccept::ATOM_XML);
if (!$curlResult->isSuccess() || !$curlResult->getBody()) { if (!$curlResult->isSuccess() || !$curlResult->getBodyString()) {
return ''; return '';
} }
$doc = new DOMDocument(); $doc = new DOMDocument();
@$doc->loadXML($curlResult->getBody()); @$doc->loadXML($curlResult->getBodyString());
$xpath = new DOMXPath($doc); $xpath = new DOMXPath($doc);
$xpath->registerNamespace('atom', 'http://www.w3.org/2005/Atom'); $xpath->registerNamespace('atom', 'http://www.w3.org/2005/Atom');

View file

@ -614,7 +614,7 @@ class Processor
} }
if ($curlResult->isSuccess()) { if ($curlResult->isSuccess()) {
$object = json_decode($curlResult->getBody(), true); $object = json_decode($curlResult->getBodyString(), true);
if (!empty($object)) { if (!empty($object)) {
$activity = JsonLD::compact($object); $activity = JsonLD::compact($object);
if (JsonLD::fetchElement($activity, '@type') == 'as:Tombstone') { if (JsonLD::fetchElement($activity, '@type') == 'as:Tombstone') {
@ -1584,7 +1584,7 @@ class Processor
return ''; return '';
} }
$body = $curlResult->getBody(); $body = $curlResult->getBodyString();
if (!$curlResult->isSuccess() || empty($body)) { if (!$curlResult->isSuccess() || empty($body)) {
if (in_array($curlResult->getReturnCode(), [403, 404, 406, 410])) { if (in_array($curlResult->getReturnCode(), [403, 404, 406, 410])) {
return null; return null;

View file

@ -1012,7 +1012,7 @@ class DFRN
$content_type = ($public_batch ? 'application/magic-envelope+xml' : 'application/json'); $content_type = ($public_batch ? 'application/magic-envelope+xml' : 'application/json');
$postResult = DI::httpClient()->post($dest_url, $envelope, ['Content-Type' => $content_type]); $postResult = DI::httpClient()->post($dest_url, $envelope, ['Content-Type' => $content_type]);
$xml = $postResult->getBody(); $xml = $postResult->getBodyString();
$curl_stat = $postResult->getReturnCode(); $curl_stat = $postResult->getReturnCode();
if (!empty($contact['gsid']) && ($postResult->isTimeout() || empty($curl_stat))) { if (!empty($contact['gsid']) && ($postResult->isTimeout() || empty($curl_stat))) {

View file

@ -736,7 +736,7 @@ class OStatus
$stored = false; $stored = false;
$curlResult = DI::httpClient()->get($related, HttpClientAccept::ATOM_XML); $curlResult = DI::httpClient()->get($related, HttpClientAccept::ATOM_XML);
if (!$curlResult->isSuccess() || empty($curlResult->getBody())) { if (!$curlResult->isSuccess() || empty($curlResult->getBodyString())) {
return; return;
} }
@ -745,12 +745,12 @@ class OStatus
if ($curlResult->inHeader('Content-Type') && if ($curlResult->inHeader('Content-Type') &&
in_array('application/atom+xml', $curlResult->getHeader('Content-Type'))) { in_array('application/atom+xml', $curlResult->getHeader('Content-Type'))) {
Logger::info('Directly fetched XML for URI ' . $related_uri); Logger::info('Directly fetched XML for URI ' . $related_uri);
$xml = $curlResult->getBody(); $xml = $curlResult->getBodyString();
} }
if ($xml == '') { if ($xml == '') {
$doc = new DOMDocument(); $doc = new DOMDocument();
if (!@$doc->loadHTML($curlResult->getBody())) { if (!@$doc->loadHTML($curlResult->getBodyString())) {
return; return;
} }
$xpath = new DOMXPath($doc); $xpath = new DOMXPath($doc);
@ -770,7 +770,7 @@ class OStatus
if ($curlResult->isSuccess()) { if ($curlResult->isSuccess()) {
Logger::info('Fetched XML for URI ' . $related_uri); Logger::info('Fetched XML for URI ' . $related_uri);
$xml = $curlResult->getBody(); $xml = $curlResult->getBodyString();
} }
} }
} }
@ -782,7 +782,7 @@ class OStatus
if ($curlResult->isSuccess()) { if ($curlResult->isSuccess()) {
Logger::info('GNU Social workaround to fetch XML for URI ' . $related_uri); Logger::info('GNU Social workaround to fetch XML for URI ' . $related_uri);
$xml = $curlResult->getBody(); $xml = $curlResult->getBodyString();
} }
} }
@ -793,7 +793,7 @@ class OStatus
if ($curlResult->isSuccess()) { if ($curlResult->isSuccess()) {
Logger::info('GNU Social workaround 2 to fetch XML for URI ' . $related_uri); Logger::info('GNU Social workaround 2 to fetch XML for URI ' . $related_uri);
$xml = $curlResult->getBody(); $xml = $curlResult->getBodyString();
} }
} }

View file

@ -250,7 +250,7 @@ class ExAuth
return false; return false;
} }
$json = @json_decode($curlResult->getBody()); $json = @json_decode($curlResult->getBodyString());
if (!is_object($json)) { if (!is_object($json)) {
return false; return false;
} }

View file

@ -433,12 +433,12 @@ class HTTPSignature
return []; return [];
} }
if (!$curlResult->isSuccess() || empty($curlResult->getBody())) { if (!$curlResult->isSuccess() || empty($curlResult->getBodyString())) {
Logger::debug('Fetching was unsuccessful', ['url' => $request, 'return-code' => $curlResult->getReturnCode(), 'error-number' => $curlResult->getErrorNumber(), 'error' => $curlResult->getError()]); Logger::debug('Fetching was unsuccessful', ['url' => $request, 'return-code' => $curlResult->getReturnCode(), 'error-number' => $curlResult->getErrorNumber(), 'error' => $curlResult->getError()]);
return []; return [];
} }
$content = json_decode($curlResult->getBody(), true); $content = json_decode($curlResult->getBodyString(), true);
if (empty($content) || !is_array($content)) { if (empty($content) || !is_array($content)) {
return []; return [];
} }

View file

@ -21,6 +21,7 @@
namespace Friendica\Util; namespace Friendica\Util;
use Friendica\Core\Hook;
use Friendica\Core\Logger; use Friendica\Core\Logger;
use Friendica\DI; use Friendica\DI;
use Friendica\Model\Photo; use Friendica\Model\Photo;
@ -181,10 +182,11 @@ class Images
* Gets info array from given URL, cached data has priority * Gets info array from given URL, cached data has priority
* *
* @param string $url * @param string $url
* @param bool $ocr
* @return array Info * @return array Info
* @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/ */
public static function getInfoFromURLCached(string $url): array public static function getInfoFromURLCached(string $url, bool $ocr = false): array
{ {
$data = []; $data = [];
@ -192,12 +194,12 @@ class Images
return $data; return $data;
} }
$cacheKey = 'getInfoFromURL:' . sha1($url); $cacheKey = 'getInfoFromURL:' . sha1($url . $ocr);
$data = DI::cache()->get($cacheKey); $data = DI::cache()->get($cacheKey);
if (empty($data) || !is_array($data)) { if (empty($data) || !is_array($data)) {
$data = self::getInfoFromURL($url); $data = self::getInfoFromURL($url, $ocr);
DI::cache()->set($cacheKey, $data); DI::cache()->set($cacheKey, $data);
} }
@ -209,10 +211,11 @@ class Images
* Gets info from URL uncached * Gets info from URL uncached
* *
* @param string $url * @param string $url
* @param bool $ocr
* @return array Info array * @return array Info array
* @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/ */
public static function getInfoFromURL(string $url): array public static function getInfoFromURL(string $url, bool $ocr = false): array
{ {
$data = []; $data = [];
@ -257,6 +260,14 @@ class Images
if ($image->isValid()) { if ($image->isValid()) {
$data['blurhash'] = $image->getBlurHash(); $data['blurhash'] = $image->getBlurHash();
if ($ocr) {
$media = ['img_str' => $img_str];
Hook::callAll('ocr-detection', $media);
if (!empty($media['description'])) {
$data['description'] = $media['description'];
}
}
} }
$data['size'] = $filesize; $data['size'] = $filesize;

View file

@ -238,7 +238,7 @@ class ParseUrl
} }
$curlResult = DI::httpClient()->get($url, HttpClientAccept::HTML, [HttpClientOptions::CONTENT_LENGTH => 1000000]); $curlResult = DI::httpClient()->get($url, HttpClientAccept::HTML, [HttpClientOptions::CONTENT_LENGTH => 1000000]);
if (!$curlResult->isSuccess() || empty($curlResult->getBody())) { if (!$curlResult->isSuccess() || empty($curlResult->getBodyString())) {
Logger::info('Empty body or error when fetching', ['url' => $url, 'success' => $curlResult->isSuccess(), 'code' => $curlResult->getReturnCode()]); Logger::info('Empty body or error when fetching', ['url' => $url, 'success' => $curlResult->isSuccess(), 'code' => $curlResult->getReturnCode()]);
return $siteinfo; return $siteinfo;
} }
@ -252,7 +252,7 @@ class ParseUrl
} }
} }
$body = $curlResult->getBody(); $body = $curlResult->getBodyString();
if ($do_oembed) { if ($do_oembed) {
$oembed_data = OEmbed::fetchURL($url, false, false); $oembed_data = OEmbed::fetchURL($url, false, false);

View file

@ -70,7 +70,7 @@ class CheckRelMeProfileLink
return; return;
} }
$content = $curlResult->getBody(); $content = $curlResult->getBodyString();
if (!$content) { if (!$content) {
Logger::notice('Empty body of the fetched homepage link). Cannot verify the relation to profile of UID %s.', ['uid' => $uid, 'owner homepage' => $owner['homepage']]); Logger::notice('Empty body of the fetched homepage link). Cannot verify the relation to profile of UID %s.', ['uid' => $uid, 'owner homepage' => $owner['homepage']]);
return; return;

View file

@ -172,7 +172,7 @@ class OnePoll
return false; return false;
} }
$xml = $curlResult->getBody(); $xml = $curlResult->getBodyString();
if (empty($xml)) { if (empty($xml)) {
Logger::notice('Empty content', ['id' => $contact['id'], 'url' => $contact['poll']]); Logger::notice('Empty content', ['id' => $contact['id'], 'url' => $contact['poll']]);
return false; return false;

View file

@ -45,12 +45,12 @@ class UpdateServerPeers
} }
$ret = DI::httpClient()->get($url . '/api/v1/instance/peers', HttpClientAccept::JSON); $ret = DI::httpClient()->get($url . '/api/v1/instance/peers', HttpClientAccept::JSON);
if (!$ret->isSuccess() || empty($ret->getBody())) { if (!$ret->isSuccess() || empty($ret->getBodyString())) {
Logger::info('Server is not reachable or does not offer the "peers" endpoint', ['url' => $url]); Logger::info('Server is not reachable or does not offer the "peers" endpoint', ['url' => $url]);
return; return;
} }
$peers = json_decode($ret->getBody()); $peers = json_decode($ret->getBodyString());
if (empty($peers) || !is_array($peers)) { if (empty($peers) || !is_array($peers)) {
Logger::info('Server does not have any peers listed', ['url' => $url]); Logger::info('Server does not have any peers listed', ['url' => $url]);
return; return;

View file

@ -47,7 +47,7 @@ class CurlResultTest extends TestCase
self::assertFalse($curlResult->isTimeout()); self::assertFalse($curlResult->isTimeout());
self::assertFalse($curlResult->isRedirectUrl()); self::assertFalse($curlResult->isRedirectUrl());
self::assertSame($headerArray, $curlResult->getHeaders()); self::assertSame($headerArray, $curlResult->getHeaders());
self::assertSame($body, $curlResult->getBody()); self::assertSame($body, $curlResult->getBodyString());
self::assertSame('text/html; charset=utf-8', $curlResult->getContentType()); self::assertSame('text/html; charset=utf-8', $curlResult->getContentType());
self::assertSame('https://test.local', $curlResult->getUrl()); self::assertSame('https://test.local', $curlResult->getUrl());
self::assertSame('https://test.local', $curlResult->getRedirectUrl()); self::assertSame('https://test.local', $curlResult->getRedirectUrl());
@ -76,7 +76,7 @@ class CurlResultTest extends TestCase
self::assertFalse($curlResult->isTimeout()); self::assertFalse($curlResult->isTimeout());
self::assertTrue($curlResult->isRedirectUrl()); self::assertTrue($curlResult->isRedirectUrl());
self::assertSame($headerArray, $curlResult->getHeaders()); self::assertSame($headerArray, $curlResult->getHeaders());
self::assertSame($body, $curlResult->getBody()); self::assertSame($body, $curlResult->getBodyString());
self::assertSame('text/html; charset=utf-8', $curlResult->getContentType()); self::assertSame('text/html; charset=utf-8', $curlResult->getContentType());
self::assertSame('https://test.local/test/it', $curlResult->getUrl()); self::assertSame('https://test.local/test/it', $curlResult->getUrl());
self::assertSame('https://test.other/test/it', $curlResult->getRedirectUrl()); self::assertSame('https://test.other/test/it', $curlResult->getRedirectUrl());
@ -103,7 +103,7 @@ class CurlResultTest extends TestCase
self::assertTrue($curlResult->isTimeout()); self::assertTrue($curlResult->isTimeout());
self::assertFalse($curlResult->isRedirectUrl()); self::assertFalse($curlResult->isRedirectUrl());
self::assertSame($headerArray, $curlResult->getHeaders()); self::assertSame($headerArray, $curlResult->getHeaders());
self::assertSame($body, $curlResult->getBody()); self::assertSame($body, $curlResult->getBodyString());
self::assertSame('text/html; charset=utf-8', $curlResult->getContentType()); self::assertSame('text/html; charset=utf-8', $curlResult->getContentType());
self::assertSame('https://test.local/test/it', $curlResult->getRedirectUrl()); self::assertSame('https://test.local/test/it', $curlResult->getRedirectUrl());
self::assertSame('Tested error', $curlResult->getError()); self::assertSame('Tested error', $curlResult->getError());
@ -131,7 +131,7 @@ class CurlResultTest extends TestCase
self::assertFalse($curlResult->isTimeout()); self::assertFalse($curlResult->isTimeout());
self::assertTrue($curlResult->isRedirectUrl()); self::assertTrue($curlResult->isRedirectUrl());
self::assertSame($headerArray, $curlResult->getHeaders()); self::assertSame($headerArray, $curlResult->getHeaders());
self::assertSame($body, $curlResult->getBody()); self::assertSame($body, $curlResult->getBodyString());
self::assertSame('text/html; charset=utf-8', $curlResult->getContentType()); self::assertSame('text/html; charset=utf-8', $curlResult->getContentType());
self::assertSame('https://test.local/test/it?key=value', $curlResult->getUrl()); self::assertSame('https://test.local/test/it?key=value', $curlResult->getUrl());
self::assertSame('https://test.other/some/?key=value', $curlResult->getRedirectUrl()); self::assertSame('https://test.other/some/?key=value', $curlResult->getRedirectUrl());

View file

@ -953,7 +953,7 @@ msgstr ""
msgid "All pending post updates are done." msgid "All pending post updates are done."
msgstr "" msgstr ""
#: src/Console/User.php:158 src/Console/User.php:245 #: src/Console/User.php:158 src/Console/User.php:246
msgid "Enter user nickname: " msgid "Enter user nickname: "
msgstr "" msgstr ""
@ -980,44 +980,48 @@ msgstr ""
msgid "Password changed." msgid "Password changed."
msgstr "" msgstr ""
#: src/Console/User.php:237 #: src/Console/User.php:238
msgid "Enter user name: " msgid "Enter user name: "
msgstr "" msgstr ""
#: src/Console/User.php:253 #: src/Console/User.php:254
msgid "Enter user email address: " msgid "Enter user email address: "
msgstr "" msgstr ""
#: src/Console/User.php:261 #: src/Console/User.php:262
msgid "Enter a language (optional): " msgid "Enter a language (optional): "
msgstr "" msgstr ""
#: src/Console/User.php:286 #: src/Console/User.php:267
msgid "Enter URL of an image to use as avatar (optional): "
msgstr ""
#: src/Console/User.php:292
msgid "User is not pending." msgid "User is not pending."
msgstr "" msgstr ""
#: src/Console/User.php:318 #: src/Console/User.php:324
msgid "User has already been marked for deletion." msgid "User has already been marked for deletion."
msgstr "" msgstr ""
#: src/Console/User.php:323 #: src/Console/User.php:329
#, php-format #, php-format
msgid "Type \"yes\" to delete %s" msgid "Type \"yes\" to delete %s"
msgstr "" msgstr ""
#: src/Console/User.php:325 #: src/Console/User.php:331
msgid "Deletion aborted." msgid "Deletion aborted."
msgstr "" msgstr ""
#: src/Console/User.php:450 #: src/Console/User.php:456
msgid "Enter category: " msgid "Enter category: "
msgstr "" msgstr ""
#: src/Console/User.php:460 #: src/Console/User.php:466
msgid "Enter key: " msgid "Enter key: "
msgstr "" msgstr ""
#: src/Console/User.php:494 #: src/Console/User.php:500
msgid "Enter value: " msgid "Enter value: "
msgstr "" msgstr ""
@ -1377,7 +1381,7 @@ msgstr ""
msgid "Public post" msgid "Public post"
msgstr "" msgstr ""
#: src/Content/Conversation.php:426 src/Content/Widget/VCard.php:131 #: src/Content/Conversation.php:426 src/Content/Widget/VCard.php:127
#: src/Model/Profile.php:483 src/Module/Admin/Logs/View.php:92 #: src/Model/Profile.php:483 src/Module/Admin/Logs/View.php:92
#: src/Module/Post/Edit.php:181 #: src/Module/Post/Edit.php:181
msgid "Message" msgid "Message"
@ -2220,7 +2224,7 @@ msgstr ""
msgid "The end" msgid "The end"
msgstr "" msgstr ""
#: src/Content/Text/HTML.php:859 src/Content/Widget/VCard.php:127 #: src/Content/Text/HTML.php:859 src/Content/Widget/VCard.php:123
#: src/Model/Profile.php:477 src/Module/Contact/Profile.php:471 #: src/Model/Profile.php:477 src/Module/Contact/Profile.php:471
msgid "Follow" msgid "Follow"
msgstr "" msgstr ""
@ -2430,17 +2434,17 @@ msgstr ""
msgid "Mention" msgid "Mention"
msgstr "" msgstr ""
#: src/Content/Widget/VCard.php:120 src/Model/Profile.php:380 #: src/Content/Widget/VCard.php:116 src/Model/Profile.php:380
#: src/Module/Contact/Profile.php:408 src/Module/Profile/Profile.php:199 #: src/Module/Contact/Profile.php:408 src/Module/Profile/Profile.php:199
msgid "XMPP:" msgid "XMPP:"
msgstr "" msgstr ""
#: src/Content/Widget/VCard.php:121 src/Model/Profile.php:381 #: src/Content/Widget/VCard.php:117 src/Model/Profile.php:381
#: src/Module/Contact/Profile.php:410 src/Module/Profile/Profile.php:203 #: src/Module/Contact/Profile.php:410 src/Module/Profile/Profile.php:203
msgid "Matrix:" msgid "Matrix:"
msgstr "" msgstr ""
#: src/Content/Widget/VCard.php:122 src/Model/Event.php:82 #: src/Content/Widget/VCard.php:118 src/Model/Event.php:82
#: src/Model/Event.php:109 src/Model/Event.php:471 src/Model/Event.php:963 #: src/Model/Event.php:109 src/Model/Event.php:471 src/Model/Event.php:963
#: src/Model/Profile.php:375 src/Module/Contact/Profile.php:406 #: src/Model/Profile.php:375 src/Module/Contact/Profile.php:406
#: src/Module/Directory.php:147 src/Module/Notifications/Introductions.php:187 #: src/Module/Directory.php:147 src/Module/Notifications/Introductions.php:187
@ -2448,7 +2452,7 @@ msgstr ""
msgid "Location:" msgid "Location:"
msgstr "" msgstr ""
#: src/Content/Widget/VCard.php:125 src/Model/Profile.php:490 #: src/Content/Widget/VCard.php:121 src/Model/Profile.php:490
#: src/Module/Notifications/Introductions.php:201 #: src/Module/Notifications/Introductions.php:201
msgid "Network:" msgid "Network:"
msgstr "" msgstr ""

View file

@ -1,7 +1,7 @@
<div class="field checkbox" id="div_id_{{$field.0}}"> <div class="field checkbox" id="div_id_{{$field.0}}">
<label id="id_{{$field.0}}_label" for="id_{{$field.0}}">{{$field.1}}</label> <label id="id_{{$field.0}}_label" for="id_{{$field.0}}">{{$field.1}}</label>
<input type="hidden" name="{{$field.0}}" value="0"> <input type="hidden" name="{{$field.0}}" value="0">
<input type="checkbox" name="{{$field.0}}" id="id_{{$field.0}}" aria-describedby="{{$field.0}}_tip" value="1" {{if $field.2}}checked="checked"{{/if}} {{if $field.4}}{{$field.4}}{{/if}}> <input type="checkbox" name="{{$field.0}}" id="id_{{$field.0}}" aria-describedby="{{$field.0}}_tip" value="1" {{if $field.2}}checked{{/if}} {{$field.4 nofilter}}>
{{if $field.3}} {{if $field.3}}
<span class="field_help" role="tooltip" id="{{$field.0}}_tip">{{$field.3 nofilter}}</span> <span class="field_help" role="tooltip" id="{{$field.0}}_tip">{{$field.3 nofilter}}</span>
{{/if}} {{/if}}

View file

@ -1,12 +1,12 @@
<div class='field combobox'> <div class="field combobox">
<label for='id_{{$field.0}}' id='id_{{$field.0}}_label'>{{$field.1}}</label> <label for="id_{{$field.0}}" id="id_{{$field.0}}_label">{{$field.1}}</label>
{{* html5 don't work on Chrome, Safari and IE9 {{* html5 don't work on Chrome, Safari and IE9
<input id="id_{{$field.0}}" type="text" list="data_{{$field.0}}"> <input id="id_{{$field.0}}" type="text" list="data_{{$field.0}}">
<datalist id="data_{{$field.0}}"> <datalist id="data_{{$field.0}}">
{{foreach $field.4 as $opt=>$val}}<option value="{{$val}}">{{/foreach}} {{foreach $field.4 as $opt=>$val}}<option value="{{$val}}">{{/foreach}}
</datalist> *}} </datalist> *}}
<input id="id_{{$field.0}}" type="text" value="{{$field.2}}" aria-describedby='{{$field.0}}_tip'> <input id="id_{{$field.0}}" type="text" value="{{$field.2}}" aria-describedby="{{$field.0}}_tip">
<select id="select_{{$field.0}}" onChange="$('#id_{{$field.0}}').val($(this).val())"> <select id="select_{{$field.0}}" onChange="$('#id_{{$field.0}}').val($(this).val())">
<option value="">{{$field.5}}</option> <option value="">{{$field.5}}</option>
{{foreach $field.4 as $opt=>$val}}<option value="{{$val}}">{{$val}}</option>{{/foreach}} {{foreach $field.4 as $opt=>$val}}<option value="{{$val}}">{{$val}}</option>{{/foreach}}

View file

@ -1,7 +1,7 @@
<div class='field custom'> <div class="field custom">
<label for='{{$field.0}}'>{{$field.1}}</label> <label for="{{$field.0}}">{{$field.1}}</label>
{{$field.2 nofilter}} {{$field.2 nofilter}}
{{if $field.3}} {{if $field.3}}
<span class="field_help" role="tooltip" id="{{$field.0}}_tip">{{$field.3 nofilter}}</span> <span class="field_help" role="tooltip" id="{{$field.0}}_tip">{{$field.3 nofilter}}</span>

View file

@ -1,4 +1,4 @@
{{include file='field_input.tpl' field=$field}} {{include file="field_input.tpl" field=$field}}
<script type="text/javascript"> <script type="text/javascript">
$(function () { $(function () {

View file

@ -1,7 +1,7 @@
<div class="field input" id="wrapper_{{$field.0}}"> <div class="field input" id="wrapper_{{$field.0}}">
<label for="id_{{$field.0}}">{{$field.1}}{{if $field.4}} <span class="required" title="{{$field.4}}">*</span>{{/if}}</label> <label for="id_{{$field.0}}">{{$field.1}}{{if $field.4}} <span class="required" title="{{$field.4}}">*</span>{{/if}}</label>
<input type="{{$field.6|default:'text'}}" name="{{$field.0}}" id="id_{{$field.0}}" value="{{$field.2}}"{{if $field.4}} required{{/if}}{{if $field.5 eq "autofocus"}} autofocus{{elseif $field.5}} {{$field.5 nofilter}}{{/if}} aria-describedby="{{$field.0}}_tip" dir="auto"> <input type="{{$field.6|default:'text'}}" name="{{$field.0}}" id="id_{{$field.0}}" value="{{$field.2}}"{{if $field.4}} required{{/if}} {{$field.5 nofilter}} aria-describedby="{{$field.0}}_tip" dir="auto">
{{if $field.3}} {{if $field.3}}
<span class="field_help" role="tooltip" id="{{$field.0}}_tip">{{$field.3 nofilter}}</span> <span class="field_help" role="tooltip" id="{{$field.0}}_tip">{{$field.3 nofilter}}</span>
{{/if}} {{/if}}

View file

@ -1,9 +1,9 @@
<div class='field checkbox'> <div class="field checkbox">
<label for='id_{{$field.0}}'>{{$field.1}}</label> <label for="id_{{$field.0}}">{{$field.1}}</label>
<input type="checkbox" name='{{$field.0}}' id='id_{{$field.0}}' value="{{$field.3}}" {{if $field.2}}checked="true"{{/if}} aria-describedby='{{$field.0}}_tip'> <input type="checkbox" name="{{$field.0}}" id="id_{{$field.0}}" value="{{$field.3}}" {{if $field.2}}checked{{/if}} aria-describedby="{{$field.0}}_tip">
{{if $field.4}} {{if $field.4}}
<span class='field_help' role='tooltip' id='{{$field.0}}_tip'>{{$field.4 nofilter}}</span> <span class="field_help" role="tooltip" id="{{$field.0}}_tip">{{$field.4 nofilter}}</span>
{{/if}} {{/if}}
</div> </div>

View file

@ -1,6 +1,6 @@
<div class='field input openid' id='wrapper_{{$field.0}}'> <div class="field input openid" id="wrapper_{{$field.0}}">
<label for='id_{{$field.0}}'>{{$field.1}}</label> <label for="id_{{$field.0}}">{{$field.1}}</label>
<input name='{{$field.0}}' id='id_{{$field.0}}' type="text" value="{{$field.2}}" {{if $field.4}} readonly="readonly" {{/if}} aria-describedby='{{$field.0}}_tip'> <input name="{{$field.0}}" id="id_{{$field.0}}" type="text" value="{{$field.2}}" {{if $field.4}}readonly{{/if}} aria-describedby="{{$field.0}}_tip">
{{if $field.3}} {{if $field.3}}
<span class="field_help" role="tooltip" id="{{$field.0}}_tip">{{$field.3 nofilter}}</span> <span class="field_help" role="tooltip" id="{{$field.0}}_tip">{{$field.3 nofilter}}</span>
{{/if}} {{/if}}

View file

@ -1,6 +1,6 @@
<div class="field password" id="wrapper_{{$field.0}}"> <div class="field password" id="wrapper_{{$field.0}}">
<label for="id_{{$field.0}}">{{$field.1}}{{if $field.4}} <span class="required" title="{{$field.4}}">*</span>{{/if}}</label> <label for="id_{{$field.0}}">{{$field.1}}{{if $field.4}} <span class="required" title="{{$field.4}}">*</span>{{/if}}</label>
<input type="password" name="{{$field.0}}" id="id_{{$field.0}}" value="{{$field.2}}"{{if $field.4}} required{{/if}}{{if $field.5 eq "autofocus"}} autofocus{{elseif $field.5}} {{$field.5}}{{/if}}{{if $field.6}} pattern="(($field.6}}"{{/if}} aria-describedby="{{$field.0}}_tip"> <input type="password" name="{{$field.0}}" id="id_{{$field.0}}" value="{{$field.2}}" {{if $field.4}}required{{/if}} {{$field.5 nofilter}} {{if $field.6}}pattern="(($field.6}}"{{/if}} aria-describedby="{{$field.0}}_tip">
{{if $field.3}} {{if $field.3}}
<span class="field_help" role="tooltip" id="{{$field.0}}_tip">{{$field.3 nofilter}}</span> <span class="field_help" role="tooltip" id="{{$field.0}}_tip">{{$field.3 nofilter}}</span>
{{/if}} {{/if}}

View file

@ -1,7 +1,7 @@
<div class='field radio'> <div class="field radio">
<label for='id_{{$field.0}}_{{$field.2}}'>{{$field.1}}</label> <label for="id_{{$field.0}}_{{$field.2}}">{{$field.1}}</label>
<input type="radio" name='{{$field.0}}' id='id_{{$field.0}}_{{$field.2}}' value="{{$field.2}}" {{if $field.4}}checked{{/if}} aria-describedby={{$field.0}}_{{$field.2}}_tip'> <input type="radio" name="{{$field.0}}" id="id_{{$field.0}}_{{$field.2}}" value="{{$field.2}}" {{if $field.4}}checked{{/if}} aria-describedby="{{$field.0}}_{{$field.2}}_tip">
{{if $field.3}} {{if $field.3}}
<span class='field_help' role='tooltip' id='{{$field.0}}_{{$field.2}}_tip'>{{$field.3 nofilter}}</span> <span class="field_help" role="tooltip" id="{{$field.0}}_{{$field.2}}_tip">{{$field.3 nofilter}}</span>
{{/if}} {{/if}}
</div> </div>

View file

@ -3,10 +3,10 @@
<label for="id_{{$field.0}}">{{$field.1}}</label> <label for="id_{{$field.0}}">{{$field.1}}</label>
<select name="{{$field.0}}" id="id_{{$field.0}}" aria-describedby="{{$field.0}}_tip" {{$field.5 nofilter}}> <select name="{{$field.0}}" id="id_{{$field.0}}" aria-describedby="{{$field.0}}_tip" {{$field.5 nofilter}}>
{{foreach $field.4 as $opt => $val}} {{foreach $field.4 as $opt => $val}}
{{if $field.5 == 'multiple'}} {{if $field.5 == "multiple"}}
<option value="{{$opt}}" dir="auto"{{if in_array($opt, $field.2)}} selected="selected"{{/if}}>{{$val}}</option> <option value="{{$opt}}" dir="auto" {{if in_array($opt, $field.2)}}selected{{/if}}>{{$val}}</option>
{{else}} {{else}}
<option value="{{$opt}}" dir="auto"{{if $opt == $field.2}} selected="selected"{{/if}}>{{$val}}</option> <option value="{{$opt}}" dir="auto" {{if $opt == $field.2}}selected{{/if}}>{{$val}}</option>
{{/if}} {{/if}}
{{/foreach}} {{/foreach}}
</select> </select>

View file

@ -1,7 +1,7 @@
<div class="field textarea"> <div class="field textarea">
<label for="id_{{$field.0}}">{{$field.1}}{{if $field.4}} <span class="required" title="{{$field.4}}">*</span>{{/if}}</label> <label for="id_{{$field.0}}">{{$field.1}}{{if $field.4}} <span class="required" title="{{$field.4}}">*</span>{{/if}}</label>
<textarea class="form-control text-autosize" name="{{$field.0}}" id="id_{{$field.0}}" {{if $field.4}} required{{/if}}{{if $field.5}} {{$field.5}}{{/if}} aria-describedby="{{$field.0}}_tip" dir="auto">{{$field.2}}</textarea> <textarea class="form-control text-autosize" name="{{$field.0}}" id="id_{{$field.0}}" {{if $field.4}}required{{/if}} {{$field.5 nofilter}} aria-describedby="{{$field.0}}_tip" dir="auto">{{$field.2}}</textarea>
{{if $field.3}} {{if $field.3}}
<span class="field_help" role="tooltip" id="{{$field.0}}_tip">{{$field.3 nofilter}}</span> <span class="field_help" role="tooltip" id="{{$field.0}}_tip">{{$field.3 nofilter}}</span>
{{/if}} {{/if}}

View file

@ -6,7 +6,7 @@
<label for="id_{{$field.0}}">{{$field.1}}</label> <label for="id_{{$field.0}}">{{$field.1}}</label>
<select name="{{$field.0}}" id="id_{{$field.0}}" {{if $field.5}}onchange="previewTheme(this);"{{/if}} aria-describedby="{{$field.0}}_tip"> <select name="{{$field.0}}" id="id_{{$field.0}}" {{if $field.5}}onchange="previewTheme(this);"{{/if}} aria-describedby="{{$field.0}}_tip">
{{foreach $field.4 as $opt=>$val}} {{foreach $field.4 as $opt=>$val}}
<option value="{{$opt}}" dir="auto"{{if $opt==$field.2}} selected="selected"{{/if}}>{{$val}}</option> <option value="{{$opt}}" dir="auto" {{if $opt==$field.2}}selected{{/if}}>{{$val}}</option>
{{/foreach}} {{/foreach}}
</select> </select>
{{if $field.3}} {{if $field.3}}

View file

@ -1,7 +1,7 @@
<div class="field checkbox" id="div_id_{{$field.0}}"> <div class="field checkbox" id="div_id_{{$field.0}}">
<input type="hidden" name="{{$field.0}}" value="0"> <input type="hidden" name="{{$field.0}}" value="0">
<input type="checkbox" name="{{$field.0}}" id="id_{{$field.0}}" value="1" {{if $field.2}}checked="checked"{{/if}} {{if $field.3}}aria-describedby="{{$field.0}}_tip"{{/if}} {{if $field.4}}{{$field.4}}{{/if}}> <input type="checkbox" name="{{$field.0}}" id="id_{{$field.0}}" value="1" {{if $field.2}}checked{{/if}} {{if $field.3}}aria-describedby="{{$field.0}}_tip"{{/if}} {{$field.4 nofilter}}>
<label for="id_{{$field.0}}"> <label for="id_{{$field.0}}">
{{$field.1}} {{$field.1}}
{{if $field.3}} {{if $field.3}}

View file

@ -3,7 +3,7 @@
{{if !isset($label) || $label != false }} {{if !isset($label) || $label != false }}
<label for="id_{{$field.0}}" id="label_{{$field.0}}">{{$field.1 nofilter}}{{if $field.4}} <span class="required" title="{{$field.4}}">*</span>{{/if}}</label> <label for="id_{{$field.0}}" id="label_{{$field.0}}">{{$field.1 nofilter}}{{if $field.4}} <span class="required" title="{{$field.4}}">*</span>{{/if}}</label>
{{/if}} {{/if}}
<input class="form-control" name="{{$field.0}}" id="id_{{$field.0}}" type="{{$field.6|default:'text'}}" value="{{$field.2}}"{{if $field.4}} required{{/if}}{{if $field.5 eq "autofocus"}} autofocus{{elseif $field.5}} {{$field.5 nofilter}}{{/if}} aria-describedby="{{$field.0}}_tip"> <input class="form-control" name="{{$field.0}}" id="id_{{$field.0}}" type="{{$field.6|default:'text'}}" value="{{$field.2}}" {{if $field.4}}required{{/if}} {{$field.5 nofilter}} aria-describedby="{{$field.0}}_tip">
{{if $field.3}} {{if $field.3}}
<span class="help-block" id="{{$field.0}}_tip" role="tooltip">{{$field.3 nofilter}}</span> <span class="help-block" id="{{$field.0}}_tip" role="tooltip">{{$field.3 nofilter}}</span>
{{/if}} {{/if}}

View file

@ -1,6 +1,6 @@
<div class="form-group field checkbox"> <div class="form-group field checkbox">
<input type="checkbox" name="{{$field.0}}" id="id_{{$field.0}}" value="{{$field.3}}" {{if $field.2}}checked="checked"{{/if}} aria-checked="{{if $field.2}}true{{else}}false{{/if}}" aria-describedby="{{$field.0}}_tip"> <input type="checkbox" name="{{$field.0}}" id="id_{{$field.0}}" value="{{$field.3}}" {{if $field.2}}checked{{/if}} aria-checked="{{if $field.2}}true{{else}}false{{/if}}" aria-describedby="{{$field.0}}_tip">
<label for="id_{{$field.0}}">{{$field.1}}</label> <label for="id_{{$field.0}}">{{$field.1}}</label>
{{if $field.4}} {{if $field.4}}
<span class="help-block" id="{{$field.0}}_tip" role="tooltip">{{$field.4 nofilter}}</span> <span class="help-block" id="{{$field.0}}_tip" role="tooltip">{{$field.4 nofilter}}</span>

View file

@ -1,6 +1,6 @@
<div id="id_{{$field.0}}_wrapper" class="form-group field input openid"> <div id="id_{{$field.0}}_wrapper" class="form-group field input openid">
<label for="id_{{$field.0}}" id="label_{{$field.0}}">{{$field.1}}</label> <label for="id_{{$field.0}}" id="label_{{$field.0}}">{{$field.1}}</label>
<input class="form-control" name="{{$field.0}}" id="id_{{$field.0}}" type="text" value="{{$field.2}}" {{if $field.4}} readonly="readonly" {{/if}} aria-describedby="{{$field.0}}_tip"> <input class="form-control" name="{{$field.0}}" id="id_{{$field.0}}" type="text" value="{{$field.2}}" {{if $field.4}}readonly{{/if}} aria-describedby="{{$field.0}}_tip">
{{if $field.3}} {{if $field.3}}
<span class="help-block" id="{{$field.0}}_tip" role="tooltip">{{$field.3 nofilter}}</span> <span class="help-block" id="{{$field.0}}_tip" role="tooltip">{{$field.3 nofilter}}</span>
{{/if}} {{/if}}

View file

@ -1,6 +1,6 @@
<div id="id_{{$field.0}}_wrapper" class="form-group field input password"> <div id="id_{{$field.0}}_wrapper" class="form-group field input password">
<label for="id_{{$field.0}}" id="label_{{$field.0}}">{{$field.1}}{{if $field.4}} <span class="required" title="{{$field.4}}">*</span>{{/if}}</label> <label for="id_{{$field.0}}" id="label_{{$field.0}}">{{$field.1}}{{if $field.4}} <span class="required" title="{{$field.4}}">*</span>{{/if}}</label>
<input class="form-control" name="{{$field.0}}" id="id_{{$field.0}}" type="password" value="{{$field.2}}" {{if $field.4}} required{{/if}}{{if $field.5 eq "autofocus"}} autofocus{{elseif $field.5}} {{$field.5}}{{/if}}{{if $field.6}} pattern="{{$field.6}}"{{/if}} aria-describedby="{{$field.0}}_tip"> <input class="form-control" name="{{$field.0}}" id="id_{{$field.0}}" type="password" value="{{$field.2}}" {{if $field.4}}required{{/if}} {{$field.5 nofilter}} {{if $field.6}}pattern="{{$field.6}}"{{/if}} aria-describedby="{{$field.0}}_tip">
{{if $field.3}} {{if $field.3}}
<span class="help-block" id="{{$field.0}}_tip" role="tooltip">{{$field.3 nofilter}}</span> <span class="help-block" id="{{$field.0}}_tip" role="tooltip">{{$field.3 nofilter}}</span>
{{/if}} {{/if}}

View file

@ -3,10 +3,10 @@
<label for="id_{{$field.0}}">{{$field.1}}</label> <label for="id_{{$field.0}}">{{$field.1}}</label>
<select name="{{$field.0}}" id="id_{{$field.0}}" class="form-control" aria-describedby="{{$field.0}}_tip" {{$field.5 nofilter}}> <select name="{{$field.0}}" id="id_{{$field.0}}" class="form-control" aria-describedby="{{$field.0}}_tip" {{$field.5 nofilter}}>
{{foreach $field.4 as $opt => $val}} {{foreach $field.4 as $opt => $val}}
{{if $field.5 == 'multiple'}} {{if $field.5 == "multiple"}}
<option value="{{$opt}}" {{if in_array($opt, $field.2)}}selected="selected"{{/if}}>{{$val}}</option> <option value="{{$opt}}" {{if in_array($opt, $field.2)}}selected{{/if}}>{{$val}}</option>
{{else}} {{else}}
<option value="{{$opt}}" {{if $opt == $field.2}}selected="selected"{{/if}}>{{$val}}</option> <option value="{{$opt}}" {{if $opt == $field.2}}selected{{/if}}>{{$val}}</option>
{{/if}} {{/if}}
{{/foreach}} {{/foreach}}
</select> </select>

View file

@ -2,7 +2,7 @@
{{if $field.1}} {{if $field.1}}
<label for="id_{{$field.0}}">{{$field.1}}{{if $field.4}} <span class="required" title="{{$field.4}}">*</span>{{/if}}</label> <label for="id_{{$field.0}}">{{$field.1}}{{if $field.4}} <span class="required" title="{{$field.4}}">*</span>{{/if}}</label>
{{/if}} {{/if}}
<textarea class="form-control text-autosize" name="{{$field.0}}" id="id_{{$field.0}}"{{if $field.4}} required{{/if}}{{if $field.5}} {{$field.5}}{{/if}} aria-describedby="{{$field.0}}_tip">{{$field.2}}</textarea> <textarea class="form-control text-autosize" name="{{$field.0}}" id="id_{{$field.0}}" {{if $field.4}}required{{/if}} {{$field.5 nofilter}} aria-describedby="{{$field.0}}_tip">{{$field.2}}</textarea>
{{if $field.3}} {{if $field.3}}
<span class="help-block" id="{{$field.0}}_tip" role="tooltip">{{$field.3 nofilter}}</span> <span class="help-block" id="{{$field.0}}_tip" role="tooltip">{{$field.3 nofilter}}</span>
{{/if}} {{/if}}

View file

@ -6,7 +6,7 @@
<label for="id_{{$field.0}}">{{$field.1}}</label> <label for="id_{{$field.0}}">{{$field.1}}</label>
<select class="form-control" name="{{$field.0}}" id="id_{{$field.0}}" {{if $field.5=="preview"}}onchange="previewTheme(this);"{{/if}} aria-describedby="{{$field.0}}_tip"> <select class="form-control" name="{{$field.0}}" id="id_{{$field.0}}" {{if $field.5=="preview"}}onchange="previewTheme(this);"{{/if}} aria-describedby="{{$field.0}}_tip">
{{foreach $field.4 as $opt=>$val}} {{foreach $field.4 as $opt=>$val}}
<option value="{{$opt}}" {{if $opt==$field.2}}selected="selected"{{/if}}>{{$val}}</option> <option value="{{$opt}}" {{if $opt==$field.2}}selected{{/if}}>{{$val}}</option>
{{/foreach}} {{/foreach}}
</select> </select>
{{if $field.3}} {{if $field.3}}