kopia lustrzana https://github.com/friendica/friendica
Porównaj commity
19 Commity
9fe0d72461
...
bae1f63424
Autor | SHA1 | Data |
---|---|---|
Hypolite Petovan | bae1f63424 | |
Michael | 652802f758 | |
Tobias Diekershoff | ac195c7061 | |
Michael | 9cf8678323 | |
Michael | 0e79b5373b | |
Hypolite Petovan | c30e4c02de | |
Michael | b351819986 | |
Michael | 642c55ee3e | |
Michael | 6e0118f3fe | |
Hypolite Petovan | 49a0b0fc3c | |
Hypolite Petovan | 4a0b989386 | |
Hypolite Petovan | 9329eebec0 | |
Matthew Exon | 619a63af6b | |
Michael | 38da9013ff | |
Matthew Exon | e24d1da13b | |
Hypolite Petovan | ed01b0f409 | |
Matthew Exon | f616dc054f | |
Matthew Exon | a20b876d67 | |
Matthew Exon | c5b8abcaf0 |
|
@ -138,9 +138,9 @@ function execute_tests() {
|
|||
if [ -n "${USEDOCKER}" ]; then
|
||||
echo "Fire up the mysql docker"
|
||||
DOCKER_CONTAINER_ID=$(docker run \
|
||||
-e MYSQL_ROOT_PASSWORD=friendica \
|
||||
-e MYSQL_ROOT_PASSWORD="${DATABASE_PASSWORD}" \
|
||||
-e MYSQL_USER="${DATABASE_USER}" \
|
||||
-e MYSQL_PASSWORD=friendica \
|
||||
-e MYSQL_PASSWORD="${DATABASE_PASSWORD}" \
|
||||
-e MYSQL_DATABASE="${DATABASE_NAME}" \
|
||||
-d mysql)
|
||||
DATABASE_HOST=$(docker inspect --format="{{.NetworkSettings.IPAddress}}" "${DOCKER_CONTAINER_ID}")
|
||||
|
@ -152,8 +152,8 @@ function execute_tests() {
|
|||
echo "To use the docker container set the USEDOCKER environment variable"
|
||||
exit 3
|
||||
fi
|
||||
mysql -u "${DATABASE_USER}" -pfriendica -e "DROP DATABASE IF EXISTS ${DATABASE_NAME}" -h ${DATABASE_HOST} || true
|
||||
mysql -u "${DATABASE_USER}" -pfriendica -e "CREATE DATABASE ${DATABASE_NAME} DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci" -h ${DATABASE_HOST}
|
||||
mysql -u "${DATABASE_USER}" -p"${DATABASE_PASSWORD}" -e "DROP DATABASE IF EXISTS ${DATABASE_NAME}" -h ${DATABASE_HOST} || true
|
||||
mysql -u "${DATABASE_USER}" -p"${DATABASE_PASSWORD}" -e "CREATE DATABASE ${DATABASE_NAME} DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci" -h ${DATABASE_HOST}
|
||||
else
|
||||
DATABASE_HOST=mysql
|
||||
fi
|
||||
|
@ -171,9 +171,9 @@ function execute_tests() {
|
|||
if [ -n "${USEDOCKER}" ]; then
|
||||
echo "Fire up the mariadb docker"
|
||||
DOCKER_CONTAINER_ID=$(docker run \
|
||||
-e MYSQL_ROOT_PASSWORD=friendica \
|
||||
-e MYSQL_ROOT_PASSWORD="${DATABASE_PASSWORD}" \
|
||||
-e MYSQL_USER="${DATABASE_USER}" \
|
||||
-e MYSQL_PASSWORD=friendica \
|
||||
-e MYSQL_PASSWORD="${DATABASE_PASSWORD}" \
|
||||
-e MYSQL_DATABASE="${DATABASE_NAME}" \
|
||||
-d mariadb)
|
||||
DATABASE_HOST=$(docker inspect --format="{{.NetworkSettings.IPAddress}}" "${DOCKER_CONTAINER_ID}")
|
||||
|
@ -185,8 +185,8 @@ function execute_tests() {
|
|||
echo "To use the docker container set the USEDOCKER environment variable"
|
||||
exit 3
|
||||
fi
|
||||
mysql -u "${DATABASE_USER}" -pfriendica -e "DROP DATABASE IF EXISTS ${DATABASE_NAME}" -h ${DATABASE_HOST} || true
|
||||
mysql -u "${DATABASE_USER}" -pfriendica -e "CREATE DATABASE ${DATABASE_NAME} DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci" -h ${DATABASE_HOST}
|
||||
mysql -u "${DATABASE_USER}" -p"${DATABASE_PASSWORD}" -e "DROP DATABASE IF EXISTS ${DATABASE_NAME}" -h ${DATABASE_HOST} || true
|
||||
mysql -u "${DATABASE_USER}" -p"${DATABASE_PASSWORD}" -e "CREATE DATABASE ${DATABASE_NAME} DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci" -h ${DATABASE_HOST}
|
||||
else
|
||||
DATABASE_HOST=mariadb
|
||||
fi
|
||||
|
@ -203,14 +203,14 @@ function execute_tests() {
|
|||
|
||||
if [ -n "${USEDOCKER}" ]; then
|
||||
echo "Initialize database..."
|
||||
docker exec ${DOCKER_CONTAINER_ID} mysql -u root -pfriendica -e "CREATE DATABASE IF NOT EXISTS ${DATABASE_NAME};"
|
||||
docker exec ${DOCKER_CONTAINER_ID} mysql -u root -p"${DATABASE_PASSWORD}" -e "CREATE DATABASE IF NOT EXISTS ${DATABASE_NAME};"
|
||||
fi
|
||||
|
||||
export MYSQL_HOST="${DATABASE_HOST}"
|
||||
|
||||
#call installer
|
||||
echo "Installing Friendica..."
|
||||
"${PHP}" ./bin/console.php autoinstall --dbuser="${DATABASE_USER}" --dbpass=friendica --dbdata="${DATABASE_NAME}" --dbhost="${DATABASE_HOST}" --url=https://friendica.local --admin=admin@friendica.local
|
||||
"${PHP}" ./bin/console.php autoinstall --dbuser="${DATABASE_USER}" --dbpass="${DATABASE_PASSWORD}" --dbdata="${DATABASE_NAME}" --dbhost="${DATABASE_HOST}" --url=https://friendica.local --admin=admin@friendica.local
|
||||
fi
|
||||
|
||||
#test execution
|
||||
|
|
|
@ -279,6 +279,7 @@ function item_process(array $post, array $request, bool $preview, string $return
|
|||
$post['body'] = BBCode::removeSharedData(Item::setHashtags($post['body']));
|
||||
$post['writable'] = true;
|
||||
$post['sensitive'] = false;
|
||||
$post['post-reason'] = Item::PR_LOCAL;
|
||||
|
||||
$o = DI::conversation()->render([$post], Conversation::MODE_SEARCH, false, true);
|
||||
|
||||
|
|
Plik diff jest za duży
Load Diff
|
@ -253,13 +253,12 @@ class HTML
|
|||
self::tagToBBCode($doc, 'span', ['class' => 'type-link'], '[class=type-link]', '[/class]');
|
||||
self::tagToBBCode($doc, 'span', ['class' => 'type-video'], '[class=type-video]', '[/class]');
|
||||
|
||||
self::tagToBBCode($doc, 'strong', [], '[b]', '[/b]');
|
||||
self::tagToBBCode($doc, 'em', [], '[i]', '[/i]');
|
||||
self::tagToBBCode($doc, 'b', [], '[b]', '[/b]');
|
||||
self::tagToBBCode($doc, 'i', [], '[i]', '[/i]');
|
||||
self::tagToBBCode($doc, 'u', [], '[u]', '[/u]');
|
||||
self::tagToBBCode($doc, 's', [], '[s]', '[/s]');
|
||||
self::tagToBBCode($doc, 'del', [], '[s]', '[/s]');
|
||||
$elements = ['b', 'del', 'em', 'i', 'ins', 'kbd', 'mark',
|
||||
's', 'samp', 'strong', 'sub', 'sup', 'u', 'var'];
|
||||
foreach ($elements as $element) {
|
||||
self::tagToBBCode($doc, $element, [], '[' . $element . ']', '[/' . $element . ']');
|
||||
}
|
||||
|
||||
self::tagToBBCode($doc, 'strike', [], '[s]', '[/s]');
|
||||
|
||||
self::tagToBBCode($doc, 'big', [], "[size=large]", "[/size]");
|
||||
|
|
|
@ -97,7 +97,6 @@ class Site extends BaseAdmin
|
|||
$adjust_poll_frequency = !empty($_POST['adjust_poll_frequency']);
|
||||
$min_poll_interval = (!empty($_POST['min_poll_interval']) ? intval(trim($_POST['min_poll_interval'])) : 0);
|
||||
$explicit_content = !empty($_POST['explicit_content']);
|
||||
$proxify_content = !empty($_POST['proxify_content']);
|
||||
$local_search = !empty($_POST['local_search']);
|
||||
$blocked_tags = (!empty($_POST['blocked_tags']) ? trim($_POST['blocked_tags']) : '');
|
||||
$cache_contact_avatar = !empty($_POST['cache_contact_avatar']);
|
||||
|
@ -271,7 +270,6 @@ class Site extends BaseAdmin
|
|||
$transactionConfig->set('system', 'adjust_poll_frequency' , $adjust_poll_frequency);
|
||||
$transactionConfig->set('system', 'min_poll_interval' , $min_poll_interval);
|
||||
$transactionConfig->set('system', 'explicit_content' , $explicit_content);
|
||||
$transactionConfig->set('system', 'proxify_content' , $proxify_content);
|
||||
$transactionConfig->set('system', 'local_search' , $local_search);
|
||||
$transactionConfig->set('system', 'blocked_tags' , Strings::cleanTags($blocked_tags));
|
||||
$transactionConfig->set('system', 'cache_contact_avatar' , $cache_contact_avatar);
|
||||
|
@ -518,7 +516,6 @@ class Site extends BaseAdmin
|
|||
'$private_addons' => ['private_addons', DI::l10n()->t('Disallow public access to addons listed in the apps menu.'), DI::config()->get('config', 'private_addons'), DI::l10n()->t('Checking this box will restrict addons listed in the apps menu to members only.')],
|
||||
'$disable_embedded' => ['disable_embedded', DI::l10n()->t('Don\'t embed private images in posts'), DI::config()->get('system', 'disable_embedded'), DI::l10n()->t('Don\'t replace locally-hosted private photos in posts with an embedded copy of the image. This means that contacts who receive posts containing private photos will have to authenticate and load each image, which may take a while.')],
|
||||
'$explicit_content' => ['explicit_content', DI::l10n()->t('Explicit Content'), DI::config()->get('system', 'explicit_content'), DI::l10n()->t('Set this to announce that your node is used mostly for explicit content that might not be suited for minors. This information will be published in the node information and might be used, e.g. by the global directory, to filter your node from listings of nodes to join. Additionally a note about this will be shown at the user registration page.')],
|
||||
'$proxify_content' => ['proxify_content', DI::l10n()->t('Proxify external content'), DI::config()->get('system', 'proxify_content'), DI::l10n()->t('Route external content via the proxy functionality. This is used for example for some OEmbed accesses and in some other rare cases.')],
|
||||
'$local_search' => ['local_search', DI::l10n()->t('Only local search'), DI::config()->get('system', 'local_search'), DI::l10n()->t('Blocks search for users who are not logged in to prevent crawlers from blocking your system.')],
|
||||
'$blocked_tags' => ['blocked_tags', DI::l10n()->t('Blocked tags for trending tags'), DI::config()->get('system', 'blocked_tags'), DI::l10n()->t("Comma separated list of hashtags that shouldn't be displayed in the trending tags.")],
|
||||
'$cache_contact_avatar' => ['cache_contact_avatar', DI::l10n()->t('Cache contact avatars'), DI::config()->get('system', 'cache_contact_avatar'), DI::l10n()->t('Locally store the avatar pictures of the contacts. This uses a lot of storage space but it increases the performance.')],
|
||||
|
|
|
@ -83,6 +83,10 @@ class Statuses extends BaseApi
|
|||
$item['network'] = $post['network'];
|
||||
$item['gravity'] = $post['gravity'];
|
||||
$item['verb'] = $post['verb'];
|
||||
$item['allow_cid'] = $post['allow_cid'];
|
||||
$item['allow_gid'] = $post['allow_gid'];
|
||||
$item['deny_cid'] = $post['deny_cid'];
|
||||
$item['deny_gid'] = $post['deny_gid'];
|
||||
$item['app'] = $this->getApp();
|
||||
$item['sensitive'] = $request['sensitive'];
|
||||
|
||||
|
|
|
@ -1,211 +0,0 @@
|
|||
<?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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace Friendica\Module;
|
||||
|
||||
use Friendica\BaseModule;
|
||||
use Friendica\Core\Logger;
|
||||
use Friendica\Core\System;
|
||||
use Friendica\DI;
|
||||
use Friendica\Network\HTTPClient\Client\HttpClientAccept;
|
||||
use Friendica\Network\HTTPClient\Client\HttpClientOptions;
|
||||
use Friendica\Network\HTTPException\NotModifiedException;
|
||||
use Friendica\Object\Image;
|
||||
use Friendica\Util\HTTPSignature;
|
||||
use Friendica\Util\Images;
|
||||
use Friendica\Util\Proxy as ProxyUtils;
|
||||
|
||||
/**
|
||||
* Module Proxy
|
||||
*
|
||||
* urls:
|
||||
* /proxy/[sub1/[sub2/]]<base64url image url>[.ext][:size]
|
||||
* /proxy?url=<image url>
|
||||
*/
|
||||
class Proxy extends BaseModule
|
||||
{
|
||||
|
||||
/**
|
||||
* Fetch remote image content
|
||||
*/
|
||||
protected function rawContent(array $request = [])
|
||||
{
|
||||
$request = $this->getRequestInfo();
|
||||
|
||||
if (!DI::config()->get('system', 'proxify_content')) {
|
||||
Logger::notice('Proxy access is forbidden', ['request' => $request, 'agent' => $_SERVER['HTTP_USER_AGENT'] ?? '', 'accept' => $_SERVER['HTTP_ACCEPT'] ?? '']);
|
||||
throw new \Friendica\Network\HTTPException\NotFoundException();
|
||||
}
|
||||
|
||||
if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) {
|
||||
header('Last-Modified: ' . gmdate('D, d M Y H:i:s', time()) . ' GMT');
|
||||
if (!empty($_SERVER['HTTP_IF_NONE_MATCH'])) {
|
||||
header('Etag: ' . $_SERVER['HTTP_IF_NONE_MATCH']);
|
||||
}
|
||||
header('Expires: ' . gmdate('D, d M Y H:i:s', time() + (31536000)) . ' GMT');
|
||||
header('Cache-Control: max-age=31536000');
|
||||
if (function_exists('header_remove')) {
|
||||
header_remove('Last-Modified');
|
||||
header_remove('Expires');
|
||||
header_remove('Cache-Control');
|
||||
}
|
||||
throw new NotModifiedException();
|
||||
}
|
||||
|
||||
if (empty($request['url'])) {
|
||||
throw new \Friendica\Network\HTTPException\BadRequestException();
|
||||
}
|
||||
|
||||
if (!DI::userSession()->getLocalUserId()) {
|
||||
Logger::debug('Redirecting not logged in user to original address', ['url' => $request['url']]);
|
||||
System::externalRedirect($request['url']);
|
||||
}
|
||||
|
||||
// It shouldn't happen but it does - spaces in URL
|
||||
$request['url'] = str_replace(' ', '+', $request['url']);
|
||||
|
||||
// Fetch the content with the local user
|
||||
try {
|
||||
$fetchResult = HTTPSignature::fetchRaw($request['url'], DI::userSession()->getLocalUserId(), [HttpClientOptions::ACCEPT_CONTENT => [HttpClientAccept::IMAGE], 'timeout' => 10]);
|
||||
$img_str = $fetchResult->getBodyString();
|
||||
|
||||
if (!$fetchResult->isSuccess() || empty($img_str)) {
|
||||
Logger::notice('Error fetching image', ['image' => $request['url'], 'return' => $fetchResult->getReturnCode(), 'empty' => empty($img_str)]);
|
||||
self::responseError();
|
||||
// stop.
|
||||
}
|
||||
} catch (\Exception $exception) {
|
||||
Logger::notice('Error fetching image', ['image' => $request['url'], 'exception' => $exception]);
|
||||
self::responseError();
|
||||
}
|
||||
|
||||
Logger::debug('Got picture', ['Content-Type' => $fetchResult->getHeader('Content-Type'), 'uid' => DI::userSession()->getLocalUserId(), 'image' => $request['url']]);
|
||||
|
||||
$image = new Image($img_str, $fetchResult->getContentType(), $request['url']);
|
||||
if (!$image->isValid()) {
|
||||
Logger::notice('The image is invalid', ['image' => $request['url'], 'mime' => $fetchResult->getContentType()]);
|
||||
self::responseError();
|
||||
// stop.
|
||||
}
|
||||
|
||||
// reduce quality - if it is supported for this image type
|
||||
if (Images::canResize($image->getType())) {
|
||||
$image->scaleDown($request['size']);
|
||||
}
|
||||
|
||||
self::responseImageHttpCache($image);
|
||||
// stop.
|
||||
}
|
||||
|
||||
/**
|
||||
* Build info about requested image to be proxied
|
||||
*
|
||||
* @return array
|
||||
* [
|
||||
* 'url' => requested url,
|
||||
* 'size' => requested image size (int)
|
||||
* 'sizetype' => requested image size (string): ':micro', ':thumb', ':small', ':medium', ':large'
|
||||
* ]
|
||||
* @throws \Exception
|
||||
*/
|
||||
private function getRequestInfo(): array
|
||||
{
|
||||
$size = ProxyUtils::PIXEL_LARGE;
|
||||
$sizetype = '';
|
||||
|
||||
if (!empty($this->parameters['url']) && empty($_REQUEST['url'])) {
|
||||
$url = $this->parameters['url'];
|
||||
|
||||
// thumb, small, medium and large.
|
||||
if (substr($url, -6) == ':micro') {
|
||||
$size = ProxyUtils::PIXEL_MICRO;
|
||||
$sizetype = ':micro';
|
||||
$url = substr($url, 0, -6);
|
||||
} elseif (substr($url, -6) == ':thumb') {
|
||||
$size = ProxyUtils::PIXEL_THUMB;
|
||||
$sizetype = ':thumb';
|
||||
$url = substr($url, 0, -6);
|
||||
} elseif (substr($url, -6) == ':small') {
|
||||
$size = ProxyUtils::PIXEL_SMALL;
|
||||
$url = substr($url, 0, -6);
|
||||
$sizetype = ':small';
|
||||
} elseif (substr($url, -7) == ':medium') {
|
||||
$size = ProxyUtils::PIXEL_MEDIUM;
|
||||
$url = substr($url, 0, -7);
|
||||
$sizetype = ':medium';
|
||||
} elseif (substr($url, -6) == ':large') {
|
||||
$size = ProxyUtils::PIXEL_LARGE;
|
||||
$url = substr($url, 0, -6);
|
||||
$sizetype = ':large';
|
||||
}
|
||||
|
||||
$pos = strrpos($url, '=.');
|
||||
if ($pos) {
|
||||
$url = substr($url, 0, $pos + 1);
|
||||
}
|
||||
|
||||
$url = str_replace(['.jpg', '.jpeg', '.gif', '.png'], ['','','',''], $url);
|
||||
|
||||
$url = base64_decode(strtr($url, '-_', '+/'), true);
|
||||
} else {
|
||||
$url = $_REQUEST['url'] ?? '';
|
||||
}
|
||||
|
||||
return [
|
||||
'url' => $url,
|
||||
'size' => $size,
|
||||
'sizetype' => $sizetype,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* In case of an error just stop. We don't return content to avoid caching problems
|
||||
*
|
||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||
*/
|
||||
private static function responseError()
|
||||
{
|
||||
throw new \Friendica\Network\HTTPException\InternalServerErrorException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Output the image with cache headers
|
||||
*
|
||||
* @param Image $img
|
||||
* @return void
|
||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||
*/
|
||||
private static function responseImageHttpCache(Image $img)
|
||||
{
|
||||
if (is_null($img) || !$img->isValid()) {
|
||||
Logger::notice('The cached image is invalid');
|
||||
self::responseError();
|
||||
// stop.
|
||||
}
|
||||
header('Content-type: ' . $img->getType());
|
||||
header('Last-Modified: ' . gmdate('D, d M Y H:i:s', time()) . ' GMT');
|
||||
header('Etag: "' . md5($img->asString()) . '"');
|
||||
header('Expires: ' . gmdate('D, d M Y H:i:s', time() + (31536000)) . ' GMT');
|
||||
header('Cache-Control: max-age=31536000');
|
||||
echo $img->asString();
|
||||
System::exit();
|
||||
}
|
||||
}
|
|
@ -26,6 +26,7 @@ use Friendica\Content\Conversation\Factory;
|
|||
use Friendica\Content\Conversation\Repository\UserDefinedChannel;
|
||||
use Friendica\Core\Config\Capability\IManageConfigValues;
|
||||
use Friendica\Core\L10n;
|
||||
use Friendica\Core\PConfig\Capability\IManagePersonalConfigValues;
|
||||
use Friendica\Core\Renderer;
|
||||
use Friendica\Core\Session\Capability\IHandleUserSessions;
|
||||
use Friendica\Model\Circle;
|
||||
|
@ -41,18 +42,21 @@ class Channels extends BaseSettings
|
|||
{
|
||||
/** @var UserDefinedChannel */
|
||||
private $channel;
|
||||
/** @var IManagePersonalConfigValues */
|
||||
private $pConfig;
|
||||
/** @var Factory\UserDefinedChannel */
|
||||
private $userDefinedChannel;
|
||||
/** @var IManageConfigValues */
|
||||
private $config;
|
||||
|
||||
public function __construct(Factory\UserDefinedChannel $userDefinedChannel, UserDefinedChannel $channel, App\Page $page, IHandleUserSessions $session, L10n $l10n, App\BaseURL $baseUrl, App\Arguments $args, LoggerInterface $logger, Profiler $profiler, Response $response, IManageConfigValues $config, array $server, array $parameters = [])
|
||||
public function __construct(Factory\UserDefinedChannel $userDefinedChannel, UserDefinedChannel $channel, App\Page $page, IHandleUserSessions $session, L10n $l10n, App\BaseURL $baseUrl, App\Arguments $args, LoggerInterface $logger, Profiler $profiler, Response $response, IManagePersonalConfigValues $pConfig, IManageConfigValues $config, array $server, array $parameters = [])
|
||||
{
|
||||
parent::__construct($session, $page, $l10n, $baseUrl, $args, $logger, $profiler, $response, $server, $parameters);
|
||||
|
||||
$this->userDefinedChannel = $userDefinedChannel;
|
||||
$this->channel = $channel;
|
||||
$this->config = $config;
|
||||
$this->pConfig = $pConfig;
|
||||
}
|
||||
|
||||
protected function post(array $request = [])
|
||||
|
@ -91,6 +95,7 @@ class Channels extends BaseSettings
|
|||
]);
|
||||
$saved = $this->channel->save($channel);
|
||||
$this->logger->debug('New channel added', ['saved' => $saved]);
|
||||
$this->enableTimeline($uid, $saved->code);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -123,6 +128,7 @@ class Channels extends BaseSettings
|
|||
]);
|
||||
$saved = $this->channel->save($channel);
|
||||
$this->logger->debug('Save channel', ['id' => $id, 'saved' => $saved]);
|
||||
$this->enableTimeline($uid, $id);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -232,4 +238,21 @@ class Channels extends BaseSettings
|
|||
'$form_security_token' => self::getFormSecurityToken('settings_channels'),
|
||||
]);
|
||||
}
|
||||
|
||||
private function enableTimeline(int $uid, int $id)
|
||||
{
|
||||
$bookmarked_timelines = $this->pConfig->get($uid, 'system', 'network_timelines');
|
||||
$enabled_timelines = $this->pConfig->get($uid, 'system', 'enabled_timelines');
|
||||
|
||||
if (empty($enabled_timelines) || empty($bookmarked_timelines)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (in_array($id, $enabled_timelines) || in_array($id, $bookmarked_timelines)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$enabled_timelines[] = $id;
|
||||
$this->pConfig->set($uid, 'system', 'enabled_timelines', $enabled_timelines);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2000,8 +2000,8 @@ class Probe
|
|||
if (isset($adr)) {
|
||||
foreach ($adr as $feadr) {
|
||||
if ((strcasecmp($feadr->mailbox, $data['name']) == 0)
|
||||
&&(strcasecmp($feadr->host, $phost) == 0)
|
||||
&& (strlen($feadr->personal))
|
||||
&& (strcasecmp($feadr->host, $phost) == 0)
|
||||
&& !empty($feadr->personal)
|
||||
) {
|
||||
$personal = imap_mime_header_decode($feadr->personal);
|
||||
$data['name'] = '';
|
||||
|
|
|
@ -591,6 +591,9 @@ class Image
|
|||
if (!$this->isValid()) {
|
||||
return false;
|
||||
}
|
||||
if ($dest_width <= 0 || $dest_height <= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($this->isImagick()) {
|
||||
/*
|
||||
|
|
|
@ -418,19 +418,19 @@ class Images
|
|||
|
||||
if ((($height * 9) / 16) > $width) {
|
||||
$dest_width = $max;
|
||||
$dest_height = intval(($height * $max) / $width);
|
||||
$dest_height = intval(ceil(($height * $max) / $width));
|
||||
} elseif ($width > $height) {
|
||||
// else constrain both dimensions
|
||||
$dest_width = $max;
|
||||
$dest_height = intval(($height * $max) / $width);
|
||||
$dest_height = intval(ceil(($height * $max) / $width));
|
||||
} else {
|
||||
$dest_width = intval(($width * $max) / $height);
|
||||
$dest_width = intval(ceil(($width * $max) / $height));
|
||||
$dest_height = $max;
|
||||
}
|
||||
} else {
|
||||
if ($width > $max) {
|
||||
$dest_width = $max;
|
||||
$dest_height = intval(($height * $max) / $width);
|
||||
$dest_height = intval(ceil(($height * $max) / $width));
|
||||
} else {
|
||||
if ($height > $max) {
|
||||
// very tall image (greater than 16:9)
|
||||
|
@ -440,7 +440,7 @@ class Images
|
|||
$dest_width = $width;
|
||||
$dest_height = $height;
|
||||
} else {
|
||||
$dest_width = intval(($width * $max) / $height);
|
||||
$dest_width = intval(ceil(($width * $max) / $height));
|
||||
$dest_height = $max;
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -49,19 +49,6 @@ class Proxy
|
|||
const PIXEL_MEDIUM = 640;
|
||||
const PIXEL_LARGE = 1024;
|
||||
|
||||
/**
|
||||
* Accepted extensions
|
||||
*
|
||||
* @var array
|
||||
* @todo Make this configurable?
|
||||
*/
|
||||
private static $extensions = [
|
||||
'jpg',
|
||||
'jpeg',
|
||||
'gif',
|
||||
'png',
|
||||
];
|
||||
|
||||
/**
|
||||
* Private constructor
|
||||
*/
|
||||
|
@ -69,63 +56,6 @@ class Proxy
|
|||
// No instances from utilities classes
|
||||
}
|
||||
|
||||
/**
|
||||
* Transform a remote URL into a local one.
|
||||
*
|
||||
* This function only performs the URL replacement on http URL and if the
|
||||
* provided URL isn't local
|
||||
*
|
||||
* @param string $url The URL to proxify
|
||||
* @param string $size One of the Proxy::SIZE_* constants
|
||||
* @return string The proxified URL or relative path
|
||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||
*/
|
||||
public static function proxifyUrl(string $url, string $size = ''): string
|
||||
{
|
||||
if (!DI::config()->get('system', 'proxify_content')) {
|
||||
return $url;
|
||||
}
|
||||
|
||||
// Trim URL first
|
||||
$url = trim($url);
|
||||
|
||||
// Quit if not an HTTP/HTTPS link or if local
|
||||
if (!in_array(parse_url($url, PHP_URL_SCHEME), ['http', 'https']) || self::isLocalImage($url)) {
|
||||
return $url;
|
||||
}
|
||||
|
||||
// Image URL may have encoded ampersands for display which aren't desirable for proxy
|
||||
$url = html_entity_decode($url, ENT_NOQUOTES, 'utf-8');
|
||||
|
||||
$shortpath = hash('md5', $url);
|
||||
$longpath = substr($shortpath, 0, 2);
|
||||
|
||||
$longpath .= '/' . strtr(base64_encode($url), '+/', '-_');
|
||||
|
||||
// Extract the URL extension
|
||||
$extension = pathinfo(parse_url($url, PHP_URL_PATH), PATHINFO_EXTENSION);
|
||||
|
||||
if (in_array($extension, self::$extensions)) {
|
||||
$shortpath .= '.' . $extension;
|
||||
$longpath .= '.' . $extension;
|
||||
}
|
||||
|
||||
$proxypath = DI::baseUrl() . '/proxy/' . $longpath;
|
||||
|
||||
if ($size != '') {
|
||||
$size = ':' . $size;
|
||||
}
|
||||
|
||||
Logger::info('Created proxy link', ['url' => $url]);
|
||||
|
||||
// Too long files aren't supported by Apache
|
||||
if (strlen($proxypath) > 250) {
|
||||
return DI::baseUrl() . '/proxy/' . $shortpath . '?url=' . urlencode($url);
|
||||
} else {
|
||||
return $proxypath . $size;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* "Proxifies" HTML code's image tags
|
||||
*
|
||||
|
|
|
@ -595,13 +595,6 @@ return [
|
|||
'/u/{nickname}' => $profileRoutes,
|
||||
'/~{nickname}' => $profileRoutes,
|
||||
|
||||
'/proxy' => [
|
||||
'[/]' => [Module\Proxy::class, [R::GET]],
|
||||
'/{url}' => [Module\Proxy::class, [R::GET]],
|
||||
'/{sub1}/{url}' => [Module\Proxy::class, [R::GET]],
|
||||
'/{sub1}/{sub2}/{url}' => [Module\Proxy::class, [R::GET]],
|
||||
],
|
||||
|
||||
// OStatus stack modules
|
||||
'/ostatus/repair' => [Module\OStatus\Repair::class, [R::GET ]],
|
||||
'/ostatus/subscribe' => [Module\OStatus\Subscribe::class, [R::GET ]],
|
||||
|
|
|
@ -241,10 +241,6 @@ return [
|
|||
// Maximum amount of tags in a post before it is rejected as spam.
|
||||
'relay_max_tags' => 20,
|
||||
|
||||
// proxify_content (Boolean)
|
||||
// Use the proxy functionality for fetching external content
|
||||
'proxify_content' => true,
|
||||
|
||||
// relay_directly (Boolean)
|
||||
// Directly transmit content to relay subscribers without using a relay server
|
||||
'relay_directly' => false,
|
||||
|
|
|
@ -1,13 +1,83 @@
|
|||
# Using the Friendica tests
|
||||
|
||||
## Install PHPUnit
|
||||
## Install Tools
|
||||
|
||||
Please use [setup-phpunit.sh](https://github.com/friendica/friendica/bin/dev/setup-phpunit.sh) to install the necessary PHPUnit version.
|
||||
It will temporarily install the `phpunit` phar file into the `bin/` subdirectory
|
||||
You need to install the following software:
|
||||
|
||||
* PHP
|
||||
* MySQL or Mariadb (the latter is preferred)
|
||||
|
||||
Currently, Friendica uses PHPUnit 8.
|
||||
For example in Ubuntu you can run:
|
||||
|
||||
## Supported PHP versions of these tests
|
||||
```
|
||||
sudo apt install mariadb-server php
|
||||
```
|
||||
|
||||
The Unit-Tests of Friendica requires at least PHP 7.2.
|
||||
## Install PHP extensions
|
||||
|
||||
The following extensions must be installed:
|
||||
|
||||
* MySQL
|
||||
* Curl
|
||||
* GD
|
||||
* XML
|
||||
* DOM
|
||||
* SimpleXML
|
||||
* Intl
|
||||
* Multi-precision
|
||||
* Multi-byte string
|
||||
|
||||
For example in Ubuntu:
|
||||
|
||||
```
|
||||
sudo apt install php-mysql php-curl php-gd php-xml php-intl php-gmp php-mbstring
|
||||
```
|
||||
|
||||
## Create Local Database
|
||||
|
||||
The default database name is `test`, username `friendica`, password
|
||||
`friendica`. These can be overridden using environment variables
|
||||
`DATABASE_NAME`, `DATABASE_USER`, `DATABASE_HOST`, and
|
||||
`DATABASE_PASSWORD`. Whatever settings you choose, you must give the
|
||||
corresponding user the necessary privileges to create and destroy the
|
||||
chosen database.
|
||||
|
||||
```
|
||||
GRANT ALL PRIVILEGES ON test.* TO 'friendica'@'localhost' IDENTIFIED BY 'friendica' WITH GRANT OPTION;
|
||||
GRANT CREATE, DROP ON test.* TO 'friendica'@'localhost';
|
||||
```
|
||||
|
||||
## Use Docker Database
|
||||
|
||||
Instead of using a local database, you can also use a database running in a docker container.
|
||||
|
||||
TODO this section needs to be filled in with working examples.
|
||||
|
||||
## Running Tests
|
||||
|
||||
You can then run the tests using the `autotest.sh` script. You should
|
||||
specify the type of database as an argument, either `mysql` or
|
||||
`mariadb`:
|
||||
|
||||
```
|
||||
bin/dev/autotest.sh mariadb
|
||||
```
|
||||
|
||||
You can also run just one particular file of tests:
|
||||
|
||||
```
|
||||
bin/dev/autotest.sh mariadb src/Util/ImagesTest.php
|
||||
```
|
||||
|
||||
Example output of tests passing:
|
||||
|
||||
```
|
||||
OK (2 tests, 2 assertions)
|
||||
```
|
||||
|
||||
Failed tests look like this. Examine the output before this to see which tests failed.
|
||||
|
||||
```
|
||||
FAILURES!
|
||||
Tests: 2, Assertions: 2, Failures: 1.
|
||||
```
|
||||
|
|
|
@ -67,7 +67,7 @@ class DirectMessageTest extends FixtureTest
|
|||
->toArray();
|
||||
|
||||
self::assertEquals('item_title', $directMessage['title']);
|
||||
self::assertEquals('<strong>item_body</strong>', $directMessage['text']);
|
||||
self::assertEquals('<b>item_body</b>', $directMessage['text']);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -96,4 +96,104 @@ class ImagesTest extends MockedTest
|
|||
|
||||
self::assertArraySubset($assertion, Images::getInfoFromURL($url));
|
||||
}
|
||||
|
||||
public function dataScalingDimensions()
|
||||
{
|
||||
return [
|
||||
'landscape' => [
|
||||
'width' => 640,
|
||||
'height' => 480,
|
||||
'max' => 320,
|
||||
'assertion' => [
|
||||
'width' => 320,
|
||||
'height' => 240,
|
||||
]
|
||||
],
|
||||
'wide_landscape' => [
|
||||
'width' => 640,
|
||||
'height' => 120,
|
||||
'max' => 320,
|
||||
'assertion' => [
|
||||
'width' => 320,
|
||||
'height' => 60,
|
||||
]
|
||||
],
|
||||
'landscape_round_up' => [
|
||||
'width' => 640,
|
||||
'height' => 479,
|
||||
'max' => 320,
|
||||
'assertion' => [
|
||||
'width' => 320,
|
||||
'height' => 240,
|
||||
]
|
||||
],
|
||||
'landscape_zero_height' => [
|
||||
'width' => 640,
|
||||
'height' => 1,
|
||||
'max' => 160,
|
||||
'assertion' => [
|
||||
'width' => 160,
|
||||
'height' => 1,
|
||||
]
|
||||
],
|
||||
'portrait' => [
|
||||
'width' => 480,
|
||||
'height' => 640,
|
||||
'max' => 320,
|
||||
'assertion' => [
|
||||
'width' => 240,
|
||||
'height' => 320,
|
||||
]
|
||||
],
|
||||
// For portrait with aspect ratio <= 16:9, constrain height
|
||||
'portrait_16_9' => [
|
||||
'width' => 1080,
|
||||
'height' => 1920,
|
||||
'max' => 320,
|
||||
'assertion' => [
|
||||
'width' => 180,
|
||||
'height' => 320,
|
||||
]
|
||||
],
|
||||
// For portrait with aspect ratio > 16:9, constrain width
|
||||
'portrait_over_16_9_too_wide' => [
|
||||
'width' => 1080,
|
||||
'height' => 1921,
|
||||
'max' => 320,
|
||||
'assertion' => [
|
||||
'width' => 320,
|
||||
'height' => 570,
|
||||
]
|
||||
],
|
||||
// For portrait with aspect ratio > 16:9, constrain width
|
||||
'portrait_over_16_9_not_too_wide' => [
|
||||
'width' => 1080,
|
||||
'height' => 1921,
|
||||
'max' => 1080,
|
||||
'assertion' => [
|
||||
'width' => 1080,
|
||||
'height' => 1921,
|
||||
]
|
||||
],
|
||||
'portrait_round_up' => [
|
||||
'width' => 479,
|
||||
'height' => 640,
|
||||
'max' => 320,
|
||||
'assertion' => [
|
||||
'width' => 240,
|
||||
'height' => 320,
|
||||
]
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the Images::getScalingDimensions() method
|
||||
*
|
||||
* @dataProvider dataScalingDimensions
|
||||
*/
|
||||
public function testGetScalingDimensions(int $width, int $height, int $max, array $assertion)
|
||||
{
|
||||
self::assertArraySubset($assertion, Images::getScalingDimensions($width, $height, $max));
|
||||
}
|
||||
}
|
||||
|
|
Plik diff jest za duży
Load Diff
|
@ -88,7 +88,6 @@
|
|||
{{include file="field_checkbox.tpl" field=$allow_relay_channels}}
|
||||
{{include file="field_checkbox.tpl" field=$adjust_poll_frequency}}
|
||||
{{include file="field_checkbox.tpl" field=$explicit_content}}
|
||||
{{include file="field_checkbox.tpl" field=$proxify_content}}
|
||||
{{include file="field_checkbox.tpl" field=$local_search}}
|
||||
{{include file="field_input.tpl" field=$blocked_tags}}
|
||||
<div class="submit"><input type="submit" name="page_site" value="{{$submit}}"/></div>
|
||||
|
|
|
@ -168,7 +168,6 @@
|
|||
{{include file="field_checkbox.tpl" field=$allow_relay_channels}}
|
||||
{{include file="field_checkbox.tpl" field=$adjust_poll_frequency}}
|
||||
{{include file="field_checkbox.tpl" field=$explicit_content}}
|
||||
{{include file="field_checkbox.tpl" field=$proxify_content}}
|
||||
{{include file="field_checkbox.tpl" field=$local_search}}
|
||||
{{include file="field_input.tpl" field=$blocked_tags}}
|
||||
</div>
|
||||
|
|
Ładowanie…
Reference in New Issue