Merge branch '2019.03-RC'

This commit is contained in:
Tobias Diekershoff 2019-03-22 20:53:21 +01:00
commit 854cc3e472
505 changed files with 63964 additions and 51254 deletions

View File

@ -1,36 +1,10 @@
codecov:
branch: develop
comment: off
coverage:
status:
patch:
default: off
source:
target: 80%
flags: source
backend:
target: 80%
flags: backend
project:
default: off
source:
flags: source
backend:
flags: backend
default:
target: auto
threshold: null
base: auto
flags:
source:
paths:
- src/
backend:
paths:
- mod/
- include/
binary:
paths:
- bin/
tests:
paths:
- tests/
comment: off

3
.gitignore vendored
View File

@ -71,3 +71,6 @@ venv/
#ignore .htaccess
.htaccess
#ignore filesystem storage default path
/storage

View File

@ -1,11 +1,10 @@
---
language: php
## Friendica supports PHP version >= 5.6.1
## Friendica officially supports PHP version >= 7.1
php:
- 5.6
- 7.0
- 7.1
- 7.2
- 7.3
services:
- mysql

View File

@ -1,3 +1,92 @@
Version 2019.03 (2019-03-22)
Friendica Core:
Update to the translation (CS, DE, EN-GB, EN-US, ES, FR, IT, PL, SV, ZH-CN) [translation teams]
Update to the documentation [Aditoo17, JeroenED, m4sk1n, softmetz, tobiasd]
Update to the themes (duepuntozero, frio, smoothy, quattro, vier) [lxiter, MrPetovan, nupplaphil, rabuzarus, tobiasd]
Enhancements to the API [jasonscheng]
Enhancements to the Vagrant development VM [JeroenED]
Enhancements to the storage of gender, sexual preferences and maritial status [JeroenED]
Enhancements to the wording of notifications [MrPetovan]
Enhancements to the display of contacts in the profile [MrPetovan]
Enhancements to the handling of local links [lxiter]
Enhancements to the explicit and implicit mentioning in conversations [annando, MrPetovan]
Enhancements to the warnings in the admin panel [tobiasd]
Enhancements to the AP implementation [annando]
Enhancements to the worker process [annando]
Enhancements to the testing process [MrPetovan, nupplaphil]
Enhancements to the LibreJS compatibility [tobiasd]
Enhancements to the federated display of postings [MrPetovan]
Enhancements to the photo menu [annando]
Enhancements to the probing of contacts [annando]
Fixed several bugs with weird tagging in code blocks [lxiter]
Fixed a bug during contact entries update [rabuzarus]
Fixed several PHP warnings and errors [annando, MrPetovan, tobiasd]
Fixed an issue when Friendica is installed in a subdirectory [rabuzarus]
Fixed several issues in the handling of the Markdown parsing from and to d* [lxiter, MrPetovan]
Fixed a bug that prevented blocked contacts from being removed from groups [MrPetovan]
Fixed a bug in the ACL with preselected items [lxiter]
Fixed an issue with polling Events via AP [annando]
Fixed a memory issue with the JSON-LD parser [annando]
Fixed an issue with the forced DB structure update [nupplaphil]
Fixed an issue with wrongly encoded HTML entities in URLs [annando]
Fixed an issue with the rotation of images in the gallery [nupplaphil]
Fixed issues with redirs in the photo menu of Friendica contacts [tobiasd]
Fixed an issue with sending out notification mails to the admin [nupplaphil]
Fixed an the issue, that the API was ignoring the globalsilence setting [nupplaphil]
Fixed issues with the autolinker of URLs in postings [MrPetovan]
Fixed an issue resulting in multible emails after successful updates of the database [nupplaphil]
Fixed a timeout issue during detection process of the remote profile [annando]
Fixed an issue with postings from blocked servers [annando, MrPetovan]
Fixed an issue with the paging of stored folders [MrPetovan]
Fixed an issue with notifications about interactions with Friendica contacts [annando]
Fixed an issue that caused double postings of images uploaded to the gallery [annando]
Fixed an issue handling legacy config files [nupplaphil]
Fixed an issue that caused notifications about interaction with a locally deleted posting [annando]
If the node does not want to publish information, nodeinfo now returns 404 instead of non-existing entries [nupplaphil]
General Code cleaning and restructuring [annando, JeroenED, MrPetovan, nupplaphil]
Switched logging engine to monolog [nupplaphil]
Added plugable storage backend [fabrixxm, nupplaphil]
Added item delivery indicator to posting header [MrPetovan]
Added URL parameter to force a specific language [JeroenED]
Added live preview of attachments to frio [rabuzarus]
Added a "friendica_author" field to the API results which holds the real author [annando]
Added support for AP with forum postings [annando]
Added a summary of articles send over AP [annando]
Friendica Addons:
Updates to the translations (CS, DE, EN-GB, ES, FR, NL, PL, SV) [translation teams]
Updated documentation [softmetz, tobiasd]
blackout:
Fix applying the translations [JeroenED, tobiasd]
Fixed some templating of the settings [tobiasd]
blogger:
The addon was marked as unsupported as it does currently not work (needs OAuth support) [annando]
cookienotice:
Added new addon to display a cookie usage notice in the browser [lxiter]
forumdirectory:
Fixed a theming issue with frio [rabuzarus]
js_upload:
Fixed a missing extionsion index [nupplaphil]
mailstream:
Fixed a curl issue [MrPetovan]
piwik:
Make it clear that Piwik is now Matomo but the addon supports both [tobiasd]
securemail:
updated the addon dependencies [MrPetovan]
twitter:
@ mentions are now stripped from the posts send to Twitter [MrPetovan]
Closed Issues:
1777, 2487, 3218, 3506, 3837, 4496, 5884, 6087, 6161, 6167, 6205,
6232, 6263, 6274, 6292, 6337, 6338, 6375, 6378, 6382, 6384, 6386,
6403, 6405, 6449, 6468, 6472, 6489, 6491, 6492, 6495, 6498, 6501,
6503, 6505, 6511, 6514, 6521, 6522, 6529, 6532, 6533, 6544, 6545,
6551, 6553, 6537, 6558, 6552, 6561, 6570, 6575, 6585, 6603, 6610,
6629, 6630, 6633, 6635, 6652, 6656, 6658, 6667, 6668, 6669, 6672,
6674, 6676, 6677, 6679, 6691, 6710, 6711, 6714, 6716, 6733, 6758,
6772, 6778, 6785, 6788, 6800, 6805, 6812, 6819, 6822, 6823, 6840,
6855, 6866, 6874, 6891, 6901, 6913
Version 2019.01 (2019-01-21)
Friendica Core:
Update to the translation (CS, DE, EN-UK, EN-US, FR, NB-NO, NL, PL) [translation teams]

View File

@ -1,11 +1,11 @@
23n
Abinoam P. Marques Jr.
Abraham Pérez Hernández
Abrax
Adam Clark
Adam Jurkiewicz
Adam Magness
Aditoo
Aditoo17
AgnesElisa
Albert
Alberto Díaz Tormo
@ -23,7 +23,6 @@ André Alves
André Lohan
Andy
Andy Hee
AndyHee
Angristan
Anthronaut
Arian - Cazare Muncitori
@ -93,10 +92,8 @@ greeneyedred
Gregory Smith
Haakon Meland Eriksen
Hans Meine
hauke
Hauke
Hauke Altmann
Hauke Zühl
Herbert Thielen
hoergen
Hubert Kościański
@ -167,6 +164,7 @@ Pascal
Pascal Deklerck
Pavel Morozov
PerigGouanvic
Peter Liebetrau
peturisfeld
Philipp
Philipp Holzer
@ -201,6 +199,7 @@ Seth
Silke Meyer
Simon L'nu
Simó Albert i Beltran
softmetz
soko1
St John Karp
Stanislav N.
@ -233,12 +232,14 @@ Tubuntu
Tupambae.org
U-SOUND\mike
ufic
Ulf Rompe
Unknown
Vasudev Kamath
Vasya Novikov
Vinzenz Vietzke
vislav
vladimir N
Vladimir Núñez
VVelox
Vít Šesták 'v6ak'
Waldemar Stoczkowski

View File

@ -1 +1 @@
2019.01
2019.03

View File

@ -32,7 +32,7 @@
*
*/
use Friendica\App;
use Friendica\Factory;
use Friendica\Util\ExAuth;
if (sizeof($_SERVER["argv"]) == 0) {
@ -51,7 +51,7 @@ chdir($directory);
require dirname(__DIR__) . '/vendor/autoload.php';
$a = new App(dirname(__DIR__));
$a = Factory\DependencyFactory::setUp('auth_ejabbered', dirname(__DIR__));
if ($a->getMode()->isNormal()) {
$oAuth = new ExAuth();

View File

@ -3,7 +3,9 @@
require dirname(__DIR__) . '/vendor/autoload.php';
$a = new Friendica\App(dirname(__DIR__));
use Friendica\Factory;
$a = Factory\DependencyFactory::setUp('console', dirname(__DIR__));
\Friendica\BaseObject::setApp($a);
(new Friendica\Core\Console($argv))->execute();

View File

@ -7,11 +7,11 @@
* This script was taken from http://php.net/manual/en/function.pcntl-fork.php
*/
use Friendica\App;
use Friendica\Core\Config;
use Friendica\Core\Logger;
use Friendica\Core\Worker;
use Friendica\Database\DBA;
use Friendica\Factory;
// Get options
$shortopts = 'f';
@ -32,7 +32,7 @@ if (!file_exists("boot.php") && (sizeof($_SERVER["argv"]) != 0)) {
require dirname(__DIR__) . '/vendor/autoload.php';
$a = new App(dirname(__DIR__));
$a = Factory\DependencyFactory::setUp('daemon', dirname(__DIR__));
if ($a->getMode()->isInstall()) {
die("Friendica isn't properly installed yet.\n");
@ -102,7 +102,7 @@ if ($mode == "stop") {
unlink($pidfile);
Logger::log("Worker daemon process $pid was killed.", Logger::DEBUG);
Logger::notice("Worker daemon process was killed", ["pid" => $pid]);
Config::set('system', 'worker_daemon_mode', false);
die("Worker daemon process $pid was killed.\n");
@ -112,7 +112,7 @@ if (!empty($pid) && posix_kill($pid, 0)) {
die("Daemon process $pid is already running.\n");
}
Logger::log('Starting worker daemon.', Logger::DEBUG);
Logger::notice('Starting worker daemon.', ["pid" => $pid]);
if (!$foreground) {
echo "Starting worker daemon.\n";
@ -144,7 +144,9 @@ if (!$foreground) {
file_put_contents($pidfile, $pid);
// We lose the database connection upon forking
$a->loadDatabase();
/// @todo refactoring during https://github.com/friendica/friendica/issues/6720
$basePath = \Friendica\Util\BasePath::create(dirname(__DIR__), $_SERVER);
Factory\DBFactory::init($basePath, $a->getConfigCache(), $a->getProfiler(), $_SERVER);
}
Config::set('system', 'worker_daemon_mode', true);
@ -160,7 +162,7 @@ $last_cron = 0;
// Now running as a daemon.
while (true) {
if (!$do_cron && ($last_cron + $wait_interval) < time()) {
Logger::log('Forcing cron worker call.', Logger::DEBUG);
Logger::info('Forcing cron worker call.', ["pid" => $pid]);
$do_cron = true;
}
@ -174,7 +176,7 @@ while (true) {
$last_cron = time();
}
Logger::log("Sleeping", Logger::DEBUG);
Logger::info("Sleeping", ["pid" => $pid]);
$start = time();
do {
$seconds = (time() - $start);
@ -191,10 +193,10 @@ while (true) {
if ($timeout) {
$do_cron = true;
Logger::log("Woke up after $wait_interval seconds.", Logger::DEBUG);
Logger::info("Woke up after $wait_interval seconds.", ["pid" => $pid, 'sleep' => $wait_interval]);
} else {
$do_cron = false;
Logger::log("Worker jobs are calling to be forked.", Logger::DEBUG);
Logger::info("Worker jobs are calling to be forked.", ["pid" => $pid]);
}
}

View File

@ -4,10 +4,12 @@
* @file bin/worker.php
* @brief Starts the background processing
*/
use Friendica\App;
use Friendica\Core\Config;
use Friendica\Core\Worker;
use Friendica\Core\Update;
use Friendica\Core\Worker;
use Friendica\Factory;
// Get options
$shortopts = 'sn';
@ -28,10 +30,10 @@ if (!file_exists("boot.php") && (sizeof($_SERVER["argv"]) != 0)) {
require dirname(__DIR__) . '/vendor/autoload.php';
$a = new App(dirname(__DIR__));
$a = Factory\DependencyFactory::setUp('worker', dirname(__DIR__));
// Check the database structure and possibly fixes it
Update::check(true);
Update::check($a->getBasePath(), true);
// Quit when in maintenance
if (!$a->getMode()->has(App\Mode::MAINTENANCEDISABLED)) {
@ -44,7 +46,7 @@ $spawn = array_key_exists('s', $options) || array_key_exists('spawn', $options);
if ($spawn) {
Worker::spawnWorker();
killme();
exit();
}
$run_cron = !array_key_exists('n', $options) && !array_key_exists('no_cron', $options);

View File

@ -19,23 +19,19 @@
use Friendica\App;
use Friendica\BaseObject;
use Friendica\Core\Addon;
use Friendica\Core\Cache;
use Friendica\Core\Config;
use Friendica\Core\L10n;
use Friendica\Core\PConfig;
use Friendica\Core\Protocol;
use Friendica\Core\System;
use Friendica\Core\Update;
use Friendica\Core\Worker;
use Friendica\Database\DBA;
use Friendica\Model\Contact;
use Friendica\Model\Conversation;
use Friendica\Model\Term;
use Friendica\Util\BasePath;
use Friendica\Util\DateTimeFormat;
define('FRIENDICA_PLATFORM', 'Friendica');
define('FRIENDICA_CODENAME', 'The Tazmans Flax-lily');
define('FRIENDICA_VERSION', '2019.01');
define('FRIENDICA_CODENAME', 'Dalmatian Bellflower');
define('FRIENDICA_VERSION', '2019.03');
define('DFRN_PROTOCOL_VERSION', '2.23');
define('NEW_UPDATE_ROUTINE_VERSION', 1170);
@ -97,18 +93,12 @@ define('SSL_POLICY_FULL', 1);
define('SSL_POLICY_SELFSIGN', 2);
/* @}*/
/**
* @name Register
*
* Registration policies
* @{
*/
define('REGISTER_CLOSED', 0);
define('REGISTER_APPROVE', 1);
define('REGISTER_OPEN', 2);
/**
* @}
*/
/** @deprecated since version 2019.03, please use \Friendica\Module\Register::CLOSED instead */
define('REGISTER_CLOSED', \Friendica\Module\Register::CLOSED);
/** @deprecated since version 2019.03, please use \Friendica\Module\Register::APPROVE instead */
define('REGISTER_APPROVE', \Friendica\Module\Register::APPROVE);
/** @deprecated since version 2019.03, please use \Friendica\Module\Register::OPEN instead */
define('REGISTER_OPEN', \Friendica\Module\Register::OPEN);
/**
* @name CP
@ -182,23 +172,27 @@ define('NOTIFY_SYSTEM', 32768);
/* @}*/
/**
* @name Term
*
* Tag/term types
* @{
*/
define('TERM_UNKNOWN', 0);
define('TERM_HASHTAG', 1);
define('TERM_MENTION', 2);
define('TERM_CATEGORY', 3);
define('TERM_PCATEGORY', 4);
define('TERM_FILE', 5);
define('TERM_SAVEDSEARCH', 6);
define('TERM_CONVERSATION', 7);
/** @deprecated since 2019.03, use Term::UNKNOWN instead */
define('TERM_UNKNOWN', Term::UNKNOWN);
/** @deprecated since 2019.03, use Term::HASHTAG instead */
define('TERM_HASHTAG', Term::HASHTAG);
/** @deprecated since 2019.03, use Term::MENTION instead */
define('TERM_MENTION', Term::MENTION);
/** @deprecated since 2019.03, use Term::CATEGORY instead */
define('TERM_CATEGORY', Term::CATEGORY);
/** @deprecated since 2019.03, use Term::PCATEGORY instead */
define('TERM_PCATEGORY', Term::PCATEGORY);
/** @deprecated since 2019.03, use Term::FILE instead */
define('TERM_FILE', Term::FILE);
/** @deprecated since 2019.03, use Term::SAVEDSEARCH instead */
define('TERM_SAVEDSEARCH', Term::SAVEDSEARCH);
/** @deprecated since 2019.03, use Term::CONVERSATION instead */
define('TERM_CONVERSATION', Term::CONVERSATION);
define('TERM_OBJ_POST', 1);
define('TERM_OBJ_PHOTO', 2);
/** @deprecated since 2019.03, use Term::OBJECT_TYPE_POST instead */
define('TERM_OBJ_POST', Term::OBJECT_TYPE_POST);
/** @deprecated since 2019.03, use Term::OBJECT_TYPE_PHOTO instead */
define('TERM_OBJ_PHOTO', Term::OBJECT_TYPE_PHOTO);
/**
* @name Namespaces
@ -653,18 +647,18 @@ function get_temppath()
$temppath = Config::get("system", "temppath");
if (($temppath != "") && App::isDirectoryUsable($temppath)) {
if (($temppath != "") && System::isDirectoryUsable($temppath)) {
// We have a temp path and it is usable
return App::getRealPath($temppath);
return BasePath::getRealPath($temppath);
}
// We don't have a working preconfigured temp path, so we take the system path.
$temppath = sys_get_temp_dir();
// Check if it is usable
if (($temppath != "") && App::isDirectoryUsable($temppath)) {
if (($temppath != "") && System::isDirectoryUsable($temppath)) {
// Always store the real path, not the path through symlinks
$temppath = App::getRealPath($temppath);
$temppath = BasePath::getRealPath($temppath);
// To avoid any interferences with other systems we create our own directory
$new_temppath = $temppath . "/" . $a->getHostName();
@ -673,7 +667,7 @@ function get_temppath()
mkdir($new_temppath);
}
if (App::isDirectoryUsable($new_temppath)) {
if (System::isDirectoryUsable($new_temppath)) {
// The new path is usable, we are happy
Config::set("system", "temppath", $new_temppath);
return $new_temppath;
@ -755,8 +749,8 @@ function get_itemcachepath()
}
$itemcache = Config::get('system', 'itemcache');
if (($itemcache != "") && App::isDirectoryUsable($itemcache)) {
return App::getRealPath($itemcache);
if (($itemcache != "") && System::isDirectoryUsable($itemcache)) {
return BasePath::getRealPath($itemcache);
}
$temppath = get_temppath();
@ -767,7 +761,7 @@ function get_itemcachepath()
mkdir($itemcache);
}
if (App::isDirectoryUsable($itemcache)) {
if (System::isDirectoryUsable($itemcache)) {
Config::set("system", "itemcache", $itemcache);
return $itemcache;
}
@ -783,7 +777,7 @@ function get_itemcachepath()
function get_spoolpath()
{
$spoolpath = Config::get('system', 'spoolpath');
if (($spoolpath != "") && App::isDirectoryUsable($spoolpath)) {
if (($spoolpath != "") && System::isDirectoryUsable($spoolpath)) {
// We have a spool path and it is usable
return $spoolpath;
}
@ -798,7 +792,7 @@ function get_spoolpath()
mkdir($spoolpath);
}
if (App::isDirectoryUsable($spoolpath)) {
if (System::isDirectoryUsable($spoolpath)) {
// The new path is usable, we are happy
Config::set("system", "spoolpath", $spoolpath);
return $spoolpath;

View File

@ -14,10 +14,17 @@
},
"require": {
"php": ">=5.6.1",
"ext-ctype": "*",
"ext-curl": "*",
"ext-dom": "*",
"ext-fileinfo": "*",
"ext-gd": "*",
"ext-iconv": "*",
"ext-json": "*",
"ext-libxml": "*",
"ext-mbstring": "*",
"ext-openssl": "*",
"ext-simplexml": "*",
"ext-xml": "*",
"asika/simple-console": "^1.0",
"divineomega/password_exposed": "^2.4",
@ -27,19 +34,22 @@
"lightopenid/lightopenid": "dev-master",
"michelf/php-markdown": "^1.7",
"mobiledetect/mobiledetectlib": "2.8.*",
"monolog/monolog": "^1.24",
"paragonie/random_compat": "^2.0",
"pear/Text_LanguageDetect": "1.*",
"pear/text_languagedetect": "1.*",
"psr/container": "^1.0",
"seld/cli-prompt": "^1.0",
"smarty/smarty": "^3.1",
"fxp/composer-asset-plugin": "~1.3",
"bower-asset/base64": "^1.0",
"bower-asset/Chart-js": "^2.7",
"bower-asset/chart-js": "^2.7",
"bower-asset/perfect-scrollbar": "^0.6",
"bower-asset/vue": "^2.5",
"npm-asset/jquery": "^2.0",
"npm-asset/jquery-colorbox": "^1.6",
"npm-asset/jquery-datetimepicker": "^2.4.0",
"npm-asset/jgrowl": "^1.4",
"npm-asset/moment": "^2.20.1",
"npm-asset/fullcalendar": "^3.0.1",
"npm-asset/cropperjs": "1.2.2",
"npm-asset/imagesloaded": "4.1.4"
@ -53,7 +63,8 @@
"autoload": {
"psr-4": {
"Friendica\\": "src/",
"Friendica\\Test\\": "tests/"
"Friendica\\Test\\": "tests/",
"Friendica\\Addon\\": "addon/"
},
"psr-0": {
"": "library/"
@ -87,7 +98,7 @@
"phpunit/dbunit": "^2.0",
"phpdocumentor/reflection-docblock": "^3.0.2",
"phpunit/php-token-stream": "^1.4.2",
"mikey179/vfsStream": "^1.6",
"mikey179/vfsstream": "^1.6",
"mockery/mockery": "^1.2",
"johnkary/phpunit-speedtrap": "1.1"
},

219
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "51f7b3ab622038d7ef62ed03c06b48d0",
"content-hash": "8897c1f6912cc9b889534a8c59deead1",
"packages": [
{
"name": "asika/simple-console",
@ -809,6 +809,84 @@
],
"time": "2018-09-01T15:05:15+00:00"
},
{
"name": "monolog/monolog",
"version": "1.24.0",
"source": {
"type": "git",
"url": "https://github.com/Seldaek/monolog.git",
"reference": "bfc9ebb28f97e7a24c45bdc3f0ff482e47bb0266"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Seldaek/monolog/zipball/bfc9ebb28f97e7a24c45bdc3f0ff482e47bb0266",
"reference": "bfc9ebb28f97e7a24c45bdc3f0ff482e47bb0266",
"shasum": ""
},
"require": {
"php": ">=5.3.0",
"psr/log": "~1.0"
},
"provide": {
"psr/log-implementation": "1.0.0"
},
"require-dev": {
"aws/aws-sdk-php": "^2.4.9 || ^3.0",
"doctrine/couchdb": "~1.0@dev",
"graylog2/gelf-php": "~1.0",
"jakub-onderka/php-parallel-lint": "0.9",
"php-amqplib/php-amqplib": "~2.4",
"php-console/php-console": "^3.1.3",
"phpunit/phpunit": "~4.5",
"phpunit/phpunit-mock-objects": "2.3.0",
"ruflin/elastica": ">=0.90 <3.0",
"sentry/sentry": "^0.13",
"swiftmailer/swiftmailer": "^5.3|^6.0"
},
"suggest": {
"aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB",
"doctrine/couchdb": "Allow sending log messages to a CouchDB server",
"ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)",
"ext-mongo": "Allow sending log messages to a MongoDB server",
"graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server",
"mongodb/mongodb": "Allow sending log messages to a MongoDB server via PHP Driver",
"php-amqplib/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib",
"php-console/php-console": "Allow sending log messages to Google Chrome",
"rollbar/rollbar": "Allow sending log messages to Rollbar",
"ruflin/elastica": "Allow sending log messages to an Elastic Search server",
"sentry/sentry": "Allow sending log messages to a Sentry server"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.0.x-dev"
}
},
"autoload": {
"psr-4": {
"Monolog\\": "src/Monolog"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Jordi Boggiano",
"email": "j.boggiano@seld.be",
"homepage": "http://seld.be"
}
],
"description": "Sends your logs to files, sockets, inboxes, databases and various web services",
"homepage": "http://github.com/Seldaek/monolog",
"keywords": [
"log",
"logging",
"psr-3"
],
"time": "2018-11-05T09:00:11+00:00"
},
{
"name": "npm-asset/cropperjs",
"version": "1.2.2",
@ -948,32 +1026,18 @@
},
{
"name": "npm-asset/fullcalendar",
"version": "3.9.0",
"version": "3.10.0",
"dist": {
"type": "tar",
"url": "https://registry.npmjs.org/fullcalendar/-/fullcalendar-3.9.0.tgz",
"url": "https://registry.npmjs.org/fullcalendar/-/fullcalendar-3.10.0.tgz",
"reference": null,
"shasum": "b608a9989f3416f0b1d526c6bdfeeaf2ac79eda5"
},
"require": {
"npm-asset/jquery": ">=2,<4.0",
"npm-asset/moment": ">=2.20.1,<3.0.0"
"shasum": "cc5e87d518fd6550e142816a31dd191664847919"
},
"type": "npm-asset-library",
"extra": {
"npm-asset-bugs": {
"url": "https://fullcalendar.io/wiki/Reporting-Bugs/"
},
"npm-asset-files": [
"dist/*.js",
"dist/*.css",
"dist/*.d.ts",
"dist/locale/*.js",
"README.*",
"LICENSE.*",
"CHANGELOG.*",
"CONTRIBUTING.*"
],
"npm-asset-main": "dist/fullcalendar.js",
"npm-asset-directories": [],
"npm-asset-repository": {
@ -983,7 +1047,7 @@
"npm-asset-scripts": {
"clean": "gulp clean",
"dist": "gulp dist",
"lint": "gulp lint",
"lint": "gulp lint-and-example-repos",
"test": "gulp test:single"
}
},
@ -1005,7 +1069,7 @@
"full-sized",
"jquery-plugin"
],
"time": "2018-03-05T03:30:23+00:00"
"time": "2019-01-11T02:39:12+00:00"
},
{
"name": "npm-asset/imagesloaded",
@ -1804,6 +1868,55 @@
],
"time": "2016-08-06T20:24:11+00:00"
},
{
"name": "psr/container",
"version": "1.0.0",
"source": {
"type": "git",
"url": "https://github.com/php-fig/container.git",
"reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
"reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"autoload": {
"psr-4": {
"Psr\\Container\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "http://www.php-fig.org/"
}
],
"description": "Common Container Interface (PHP FIG PSR-11)",
"homepage": "https://github.com/php-fig/container",
"keywords": [
"PSR-11",
"container",
"container-interface",
"container-interop",
"psr"
],
"time": "2017-02-14T16:28:37+00:00"
},
{
"name": "psr/http-message",
"version": "1.0.1",
@ -1854,6 +1967,53 @@
],
"time": "2016-08-06T14:39:51+00:00"
},
{
"name": "psr/log",
"version": "1.1.0",
"source": {
"type": "git",
"url": "https://github.com/php-fig/log.git",
"reference": "6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/log/zipball/6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd",
"reference": "6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"autoload": {
"psr-4": {
"Psr\\Log\\": "Psr/Log/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "http://www.php-fig.org/"
}
],
"description": "Common interface for logging libraries",
"homepage": "https://github.com/php-fig/log",
"keywords": [
"log",
"psr",
"psr-3"
],
"time": "2018-11-20T15:27:04+00:00"
},
{
"name": "seld/cli-prompt",
"version": "1.0.3",
@ -2525,6 +2685,7 @@
"testing",
"xunit"
],
"abandoned": true,
"time": "2016-12-02T14:39:14+00:00"
},
{
@ -2915,6 +3076,7 @@
"mock",
"xunit"
],
"abandoned": true,
"time": "2017-06-30T09:13:00+00:00"
},
{
@ -3018,7 +3180,7 @@
}
],
"description": "Provides the functionality to compare PHP values for equality",
"homepage": "https://github.com/sebastianbergmann/comparator",
"homepage": "http://www.github.com/sebastianbergmann/comparator",
"keywords": [
"comparator",
"compare",
@ -3120,7 +3282,7 @@
}
],
"description": "Provides functionality to handle HHVM/PHP environments",
"homepage": "https://github.com/sebastianbergmann/environment",
"homepage": "http://www.github.com/sebastianbergmann/environment",
"keywords": [
"Xdebug",
"environment",
@ -3188,7 +3350,7 @@
}
],
"description": "Provides the functionality to export PHP variables for visualization",
"homepage": "https://github.com/sebastianbergmann/exporter",
"homepage": "http://www.github.com/sebastianbergmann/exporter",
"keywords": [
"export",
"exporter"
@ -3240,7 +3402,7 @@
}
],
"description": "Snapshotting of global state",
"homepage": "https://github.com/sebastianbergmann/global-state",
"homepage": "http://www.github.com/sebastianbergmann/global-state",
"keywords": [
"global state"
],
@ -3342,7 +3504,7 @@
}
],
"description": "Provides functionality to recursively process PHP variables",
"homepage": "https://github.com/sebastianbergmann/recursion-context",
"homepage": "http://www.github.com/sebastianbergmann/recursion-context",
"time": "2016-11-19T07:33:16+00:00"
},
{
@ -3607,10 +3769,17 @@
"prefer-lowest": false,
"platform": {
"php": ">=5.6.1",
"ext-ctype": "*",
"ext-curl": "*",
"ext-dom": "*",
"ext-fileinfo": "*",
"ext-gd": "*",
"ext-iconv": "*",
"ext-json": "*",
"ext-libxml": "*",
"ext-mbstring": "*",
"ext-openssl": "*",
"ext-simplexml": "*",
"ext-xml": "*"
},
"platform-dev": []

View File

@ -34,7 +34,7 @@
use Friendica\Database\DBA;
if (!defined('DB_UPDATE_VERSION')) {
define('DB_UPDATE_VERSION', 1293);
define('DB_UPDATE_VERSION', 1304);
}
return [
@ -99,6 +99,8 @@ return [
"allow_gid" => ["type" => "mediumtext", "comment" => "Access Control - list of allowed groups"],
"deny_cid" => ["type" => "mediumtext", "comment" => "Access Control - list of denied contact.id"],
"deny_gid" => ["type" => "mediumtext", "comment" => "Access Control - list of denied groups"],
"backend-class" => ["type" => "tinytext", "comment" => "Storage backend class"],
"backend-ref" => ["type" => "text", "comment" => "Storage backend data reference"],
],
"indexes" => [
"PRIMARY" => ["id"],
@ -707,6 +709,8 @@ return [
"iid" => ["type" => "int unsigned", "not null" => "1", "primary" => "1", "relation" => ["item" => "id"], "comment" => "Item id"],
"postopts" => ["type" => "text", "comment" => "External post connectors add their network name to this comma-separated string to identify that they should be delivered to these networks during delivery"],
"inform" => ["type" => "mediumtext", "comment" => "Additional receivers of the linked item"],
"queue_count" => ["type" => "mediumint", "not null" => "1", "default" => "0", "comment" => "Initial number of delivery recipients, used as item.delivery_queue_count"],
"queue_done" => ["type" => "mediumint", "not null" => "1", "default" => "0", "comment" => "Number of successful deliveries, used as item.delivery_queue_done"],
],
"indexes" => [
"PRIMARY" => ["iid"],
@ -955,6 +959,9 @@ return [
"allow_gid" => ["type" => "mediumtext", "comment" => "Access Control - list of allowed groups"],
"deny_cid" => ["type" => "mediumtext", "comment" => "Access Control - list of denied contact.id"],
"deny_gid" => ["type" => "mediumtext", "comment" => "Access Control - list of denied groups"],
"backend-class" => ["type" => "tinytext", "comment" => "Storage backend class"],
"backend-ref" => ["type" => "text", "comment" => "Storage backend data reference"],
"updated" => ["type" => "datetime", "not null" => "1", "default" => DBA::NULL_DATETIME, "comment" => ""]
],
"indexes" => [
"PRIMARY" => ["id"],
@ -1359,7 +1366,7 @@ return [
"comment" => "Background tasks queue entries",
"fields" => [
"id" => ["type" => "int unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1", "comment" => "Auto incremented worker task id"],
"parameter" => ["type" => "mediumblob", "comment" => "Task command"],
"parameter" => ["type" => "mediumtext", "comment" => "Task command"],
"priority" => ["type" => "tinyint unsigned", "not null" => "1", "default" => "0", "comment" => "Task priority"],
"created" => ["type" => "datetime", "not null" => "1", "default" => DBA::NULL_DATETIME, "comment" => "Creation date"],
"pid" => ["type" => "int unsigned", "not null" => "1", "default" => "0", "comment" => "Process id of the worker"],
@ -1370,13 +1377,23 @@ return [
],
"indexes" => [
"PRIMARY" => ["id"],
"pid" => ["pid"],
"parameter" => ["parameter(64)"],
"priority_created_next_try" => ["priority", "created", "next_try"],
"done_priority_executed_next_try" => ["done", "priority", "executed", "next_try"],
"done_executed_next_try" => ["done", "executed", "next_try"],
"done_parameter" => ["done", "parameter(64)"],
"done_executed" => ["done", "executed"],
"done_priority_created" => ["done", "priority", "created"],
"done_priority_next_try" => ["done", "priority", "next_try"],
"done_next_try" => ["done", "next_try"]
"done_pid_next_try" => ["done", "pid", "next_try"],
"done_pid_priority_created" => ["done", "pid", "priority", "created"]
]
],
"storage" => [
"comment" => "Data stored by Database storage backend",
"fields" => [
"id" => ["type" => "int unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1", "comment" => "Auto incremented image data id"],
"data" => ["type" => "longblob", "not null" => "1", "comment" => "file data"]
],
"indexes" => [
"PRIMARY" => ["id"]
]
]
];

View File

@ -135,6 +135,15 @@ return [
// Disables the check if a mail address is in a valid format and can be resolved via DNS.
'disable_email_validation' => false,
// disable_implicit_mentions (Boolean) since 2019.03
// Implicit mentions are mentions in the body of replies that are redundant in a thread-enabled system like Friendica.
// This config key disables the gathering of implicit mentions in incoming and outgoing posts.
// Also disables the default automatic removal of implicit mentions from the body of incoming posts.
// Also disables the default automatic addition of implicit mentions in the body of outgoing posts.
// Disabling implicit mentions also affects the "explicit_mentions" additional feature by limiting it
// to the replied-to post author mention in the comment boxes.
'disable_implicit_mentions' => false,
// disable_url_validation (Boolean)
// Disables the DNS lookup of an URL.
'disable_url_validation' => false,
@ -393,6 +402,14 @@ return [
// Number of worker tasks that are fetched in a single query.
'worker_fetch_limit' => 1,
// worker_jpm (Boolean)
// If enabled, it prints out the jobs per minute.
'worker_jpm' => false,
// worker_jpm_range (String)
// List of minutes for the jobs per minute (JPM) calculation
'worker_jpm_range' => '1, 10, 60',
// worker_load_exponent (Integer)
// Default 3, which allows only 25% of the maximum worker queues when server load reaches around 37% of maximum load.
// For a linear response where 25% of worker queues are allowed at 75% of maximum load, set this to 1.
@ -421,4 +438,13 @@ return [
// Must be writable by the ejabberd process. if set then it will prevent the running of multiple processes.
'lockpath' => '',
],
'debug' => [
// ap_inbox_log (Boolean)
// Logs every call to /inbox as a JSON file in Friendica's temporary directory
'ap_inbox_log' => false,
// total_ap_delivery (Boolean)
// Deliver via AP to every possible receiver and we suppress the delivery to these contacts with other protocols
'total_ap_delivery' => false,
]
];

View File

@ -34,7 +34,7 @@ return [
'config' => [
'admin_email' => '',
'sitename' => 'Friendica Social Network',
'register_policy' => REGISTER_OPEN,
'register_policy' => \Friendica\Module\Register::OPEN,
'register_text' => '',
],
'system' => [

View File

@ -16,10 +16,11 @@ return [
'info' => '',
// register_policy (Constant)
// Your choices are REGISTER_OPEN, REGISTER_APPROVE, or REGISTER_CLOSED.
// Be certain to create your own personal account before setting REGISTER_CLOSED.
// REGISTER_APPROVE requires you set system.admin_email to the email address of an already registered person who can authorize and/or approve/deny the request.
'register_policy' => REGISTER_CLOSED,
// Your choices are OPEN, APPROVE, or CLOSED.
// Be certain to create your own personal account before setting CLOSED.
// APPROVE requires you set system.admin_email to the email address of an
// already registered person who can authorize and/or approve/deny the request.
'register_policy' => \Friendica\Module\Register::CLOSED,
// register_text (String)
// Will be displayed prominently on the registration page.
@ -43,6 +44,10 @@ return [
// Themes users can change to in their settings.
'allowed_themes' => 'quattro,vier,duepuntozero,smoothly',
// debugging (boolean)
// Enable/Disable Debugging (logging)
'debugging' => false,
// default_timezone (String)
// Choose a default timezone. See https://secure.php.net/manual/en/timezones.php
// It only applies to timestamps for anonymous viewers.
@ -66,6 +71,16 @@ return [
// Two-letters ISO 639-1 code.
'language' => 'en',
// logfile (String)
// The logfile for storing logs.
// Can be a full path or a relative path to the Friendica home directory
'logfile' => 'friendica.log',
// loglevel (String)
// The loglevel for all logs.
// Has to be one of these values: emergency, alert, critical, error, warning, notice, info, debug
'loglevel' => 'notice',
// max_image_length (Integer)
// An alternate way of limiting picture upload sizes.
// Specify the maximum pixel length that pictures are allowed to be (for non-square pictures, it will apply to the longest side).
@ -87,6 +102,10 @@ return [
// 0 to use internal default (100MB)
'optimize_max_tablesize' => -1,
// maxloadavg (Integer)
// Maximum system load before delivery and poll processes are deferred.
'maxloadavg' => 20,
// rino_encrypt (Integer)
// Server-to-server private message encryption (RINO).
// Encryption will only be provided if this setting is set to a non zero value on both servers.

View File

@ -1,6 +1,6 @@
-- ------------------------------------------
-- Friendica 2019.01-rc (The Tazmans Flax-lily)
-- DB_UPDATE_VERSION 1293
-- Friendica 2019.03-dev (The Tazmans Flax-lily)
-- DB_UPDATE_VERSION 1300
-- ------------------------------------------
@ -64,6 +64,8 @@ CREATE TABLE IF NOT EXISTS `attach` (
`allow_gid` mediumtext COMMENT 'Access Control - list of allowed groups',
`deny_cid` mediumtext COMMENT 'Access Control - list of denied contact.id',
`deny_gid` mediumtext COMMENT 'Access Control - list of denied groups',
`backend-class` tinytext COMMENT 'Storage backend class',
`backend-ref` text COMMENT 'Storage backend data reference',
PRIMARY KEY(`id`)
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='file attachments';
@ -641,6 +643,8 @@ CREATE TABLE IF NOT EXISTS `item-delivery-data` (
`iid` int unsigned NOT NULL COMMENT 'Item id',
`postopts` text COMMENT 'External post connectors add their network name to this comma-separated string to identify that they should be delivered to these networks during delivery',
`inform` mediumtext COMMENT 'Additional receivers of the linked item',
`queue_count` mediumint NOT NULL DEFAULT 0 COMMENT 'Initial number of delivery recipients, used as item.delivery_queue_count',
`queue_done` mediumint NOT NULL DEFAULT 0 COMMENT 'Number of successful deliveries, used as item.delivery_queue_done',
PRIMARY KEY(`iid`)
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='Delivery data for items';
@ -873,6 +877,9 @@ CREATE TABLE IF NOT EXISTS `photo` (
`allow_gid` mediumtext COMMENT 'Access Control - list of allowed groups',
`deny_cid` mediumtext COMMENT 'Access Control - list of denied contact.id',
`deny_gid` mediumtext COMMENT 'Access Control - list of denied groups',
`backend-class` tinytext COMMENT 'Storage backend class',
`backend-ref` text COMMENT 'Storage backend data reference',
`updated` datetime NOT NULL DEFAULT '0001-01-01 00:00:00' COMMENT 'edited timestamp',
PRIMARY KEY(`id`),
INDEX `contactid` (`contact-id`),
INDEX `uid_contactid` (`uid`,`contact-id`),
@ -1254,7 +1261,7 @@ CREATE TABLE IF NOT EXISTS `worker-ipc` (
--
CREATE TABLE IF NOT EXISTS `workerqueue` (
`id` int unsigned NOT NULL auto_increment COMMENT 'Auto incremented worker task id',
`parameter` mediumblob COMMENT 'Task command',
`parameter` mediumtext COMMENT 'Task command',
`priority` tinyint unsigned NOT NULL DEFAULT 0 COMMENT 'Task priority',
`created` datetime NOT NULL DEFAULT '0001-01-01 00:00:00' COMMENT 'Creation date',
`pid` int unsigned NOT NULL DEFAULT 0 COMMENT 'Process id of the worker',
@ -1272,4 +1279,13 @@ CREATE TABLE IF NOT EXISTS `workerqueue` (
INDEX `done_next_try` (`done`,`next_try`)
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='Background tasks queue entries';
--
-- TABLE storage
--
CREATE TABLE IF NOT EXISTS `storage` (
`id` int unsigned NOT NULL auto_increment COMMENT 'Auto incremented image data id',
`data` longblob NOT NULL COMMENT 'file data',
PRIMARY KEY(`id`)
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='Data stored by Database storage backend';

204
doc/AddonStorageBackend.md Normal file
View File

@ -0,0 +1,204 @@
Friendica Storage Backend Addon development
===========================================
* [Home](help)
Storage backends can be added via addons.
A storage backend is implemented as a class, and the plugin register the class to make it avaiable to the system.
## The Storage Backend Class
The class must live in `Friendica\Addon\youraddonname` namespace, where `youraddonname` the folder name of your addon.
The class must implement `Friendica\Model\Storage\IStorage` interface. All method in the interface must be implemented:
namespace Friendica\Model\Storage;
```php
interface IStorage
{
public static function get($ref);
public static function put($data, $ref = "");
public static function delete($ref);
public static function getOptions();
public static function saveOptions($data);
}
```
- `get($ref)` returns data pointed by `$ref`
- `put($data, $ref)` saves data in `$data` to position `$ref`, or a new position if `$ref` is empty.
- `delete($ref)` delete data pointed by `$ref`
Each storage backend can have options the admin can set in admin page.
- `getOptions()` returns an array with details about each option to build the interface.
- `saveOptions($data)` get `$data` from admin page, validate it and save it.
The array returned by `getOptions()` is defined as:
[
'option1name' => [ ..info.. ],
'option2name' => [ ..info.. ],
...
]
An empty array can be returned if backend doesn't have any options.
The info array for each option is defined as:
[
'type',
define the field used in form, and the type of data.
one of 'checkbox', 'combobox', 'custom', 'datetime', 'input', 'intcheckbox', 'password', 'radio', 'richtext', 'select', 'select_raw', 'textarea', 'yesno'
'label',
Translatable label of the field. This label will be shown in admin page
value,
Current value of the option
'help text',
Translatable description for the field. Will be shown in admin page
extra data
Optional. Depends on which 'type' this option is:
- 'select': array `[ value => label ]` of choices
- 'intcheckbox': value of input element
- 'select_raw': prebuild html string of `<option >` tags
- 'yesno': array `[ 'label no', 'label yes']`
Each label should be translatable
];
See doxygen documentation of `IStorage` interface for details about each method.
## Register a storage backend class
Each backend must be registered in the system when the plugin is installed, to be aviable.
`Friendica\Core\StorageManager::register($name, $class)` is used to register the backend class.
The `$name` must be univocal and will be shown to admin.
When the plugin is uninstalled, registered backends must be unregistered using
`Friendica\Core\StorageManager::unregister($class)`.
## Example
Here an hypotetical addon which register an unusefull storage backend.
Let's call it `samplestorage`.
This backend will discard all data we try to save and will return always the same image when we ask for some data.
The image returned can be set by the administrator in admin page.
First, the backend class.
The file will be `addon/samplestorage/SampleStorageBackend.php`:
```php
<?php
namespace Friendica\Addon\samplestorage;
use Friendica\Model\Storage\IStorage;
use Friendica\Core\Config;
use Friendica\Core\L10n;
class SampleStorageBackend implements IStorage
{
public static function get($ref)
{
// we return alwais the same image data. Which file we load is defined by
// a config key
$filename = Config::get("storage", "samplestorage", "sample.jpg");
return file_get_contents($filename);
}
public static function put($data, $ref = "")
{
if ($ref === "") {
$ref = "sample";
}
// we don't save $data !
return $ref;
}
public static function delete($ref)
{
// we pretend to delete the data
return true;
}
public static function getOptions()
{
$filename = Config::get("storage", "samplestorage", "sample.jpg");
return [
"filename" => [
"input", // will use a simple text input
L10n::t("The file to return"), // the label
$filename, // the current value
L10n::t("Enter the path to a file"), // the help text
// no extra data for "input" type..
];
}
public static function saveOptions($data)
{
// the keys in $data are the same keys we defined in getOptions()
$newfilename = trim($data["filename"]);
// this function should always validate the data.
// in this example we check if file exists
if (!file_exists($newfilename)) {
// in case of error we return an array with
// ["optionname" => "error message"]
return ["filename" => "The file doesn't exists"];
}
Config::set("storage", "samplestorage", $newfilename);
// no errors, return empty array
return [];
}
}
```
Now the plugin main file. Here we register and unregister the backend class.
The file is `addon/samplestorage/samplestorage.php`
```php
<?php
/**
* Name: Sample Storage Addon
* Description: A sample addon which implements an unusefull storage backend
* Version: 1.0.0
* Author: Alice <https://alice.social/~alice>
*/
use Friendica\Core\StorageManager;
use Friendica\Addon\samplestorage\SampleStorageBackend;
function samplestorage_install()
{
// on addon install, we register our class with name "Sample Storage".
// note: we use `::class` property, which returns full class name as string
// this save us the problem of correctly escape backslashes in class name
StorageManager::register("Sample Storage", SampleStorageBackend::class);
}
function samplestorage_unistall()
{
// when the plugin is uninstalled, we unregister the backend.
StorageManager::unregister("Sample Storage");
}
```

View File

@ -32,7 +32,7 @@ It will be displayed in the admin panel and should include some further informat
Register your addon hooks during installation.
Addon::registerHook($hookname, $file, $function);
\Friendica\Core\Hook::register($hookname, $file, $function);
$hookname is a string and corresponds to a known Friendica PHP hook.
@ -74,7 +74,7 @@ If your addon requires adding a stylesheet on all pages of Friendica, add the fo
```php
function <addon>_install()
{
Addon::registerHook('head', __FILE__, '<addon>_head');
\Friendica\Core\Hook::register('head', __FILE__, '<addon>_head');
...
}
@ -97,7 +97,7 @@ If your addon requires adding a script on all pages of Friendica, add the follow
```php
function <addon>_install()
{
Addon::registerHook('footer', __FILE__, '<addon>_footer');
\Friendica\Core\Hook::register('footer', __FILE__, '<addon>_footer');
...
}
@ -417,281 +417,281 @@ Here is a complete list of all hook callbacks with file locations (as of 24-Sep-
### index.php
Addon::callHooks('init_1');
Addon::callHooks('app_menu', $arr);
Addon::callHooks('page_content_top', $a->page['content']);
Addon::callHooks($a->module.'_mod_init', $placeholder);
Addon::callHooks($a->module.'_mod_init', $placeholder);
Addon::callHooks($a->module.'_mod_post', $_POST);
Addon::callHooks($a->module.'_mod_afterpost', $placeholder);
Addon::callHooks($a->module.'_mod_content', $arr);
Addon::callHooks($a->module.'_mod_aftercontent', $arr);
Addon::callHooks('page_end', $a->page['content']);
Hook::callAll('init_1');
Hook::callAll('app_menu', $arr);
Hook::callAll('page_content_top', $a->page['content']);
Hook::callAll($a->module.'_mod_init', $placeholder);
Hook::callAll($a->module.'_mod_init', $placeholder);
Hook::callAll($a->module.'_mod_post', $_POST);
Hook::callAll($a->module.'_mod_afterpost', $placeholder);
Hook::callAll($a->module.'_mod_content', $arr);
Hook::callAll($a->module.'_mod_aftercontent', $arr);
Hook::callAll('page_end', $a->page['content']);
### include/api.php
Addon::callHooks('logged_in', $a->user);
Addon::callHooks('authenticate', $addon_auth);
Addon::callHooks('logged_in', $a->user);
Hook::callAll('logged_in', $a->user);
Hook::callAll('authenticate', $addon_auth);
Hook::callAll('logged_in', $a->user);
### include/enotify.php
Addon::callHooks('enotify', $h);
Addon::callHooks('enotify_store', $datarray);
Addon::callHooks('enotify_mail', $datarray);
Addon::callHooks('check_item_notification', $notification_data);
Hook::callAll('enotify', $h);
Hook::callAll('enotify_store', $datarray);
Hook::callAll('enotify_mail', $datarray);
Hook::callAll('check_item_notification', $notification_data);
### include/conversation.php
Addon::callHooks('conversation_start', $cb);
Addon::callHooks('render_location', $locate);
Addon::callHooks('display_item', $arr);
Addon::callHooks('display_item', $arr);
Addon::callHooks('item_photo_menu', $args);
Addon::callHooks('jot_tool', $jotplugins);
Hook::callAll('conversation_start', $cb);
Hook::callAll('render_location', $locate);
Hook::callAll('display_item', $arr);
Hook::callAll('display_item', $arr);
Hook::callAll('item_photo_menu', $args);
Hook::callAll('jot_tool', $jotplugins);
### include/text.php
Addon::callHooks('contact_block_end', $arr);
Addon::callHooks('poke_verbs', $arr);
Addon::callHooks('put_item_in_cache', $hook_data);
Addon::callHooks('prepare_body_init', $item);
Addon::callHooks('prepare_body_content_filter', $hook_data);
Addon::callHooks('prepare_body', $hook_data);
Addon::callHooks('prepare_body_final', $hook_data);
Hook::callAll('contact_block_end', $arr);
Hook::callAll('poke_verbs', $arr);
Hook::callAll('put_item_in_cache', $hook_data);
Hook::callAll('prepare_body_init', $item);
Hook::callAll('prepare_body_content_filter', $hook_data);
Hook::callAll('prepare_body', $hook_data);
Hook::callAll('prepare_body_final', $hook_data);
### include/items.php
Addon::callHooks('page_info_data', $data);
Hook::callAll('page_info_data', $data);
### mod/directory.php
Addon::callHooks('directory_item', $arr);
Hook::callAll('directory_item', $arr);
### mod/xrd.php
Addon::callHooks('personal_xrd', $arr);
Hook::callAll('personal_xrd', $arr);
### mod/ping.php
Addon::callHooks('network_ping', $arr);
Hook::callAll('network_ping', $arr);
### mod/parse_url.php
Addon::callHooks("parse_link", $arr);
Hook::callAll("parse_link", $arr);
### mod/manage.php
Addon::callHooks('home_init', $ret);
Hook::callAll('home_init', $ret);
### mod/acl.php
Addon::callHooks('acl_lookup_end', $results);
Hook::callAll('acl_lookup_end', $results);
### mod/network.php
Addon::callHooks('network_content_init', $arr);
Addon::callHooks('network_tabs', $arr);
Hook::callAll('network_content_init', $arr);
Hook::callAll('network_tabs', $arr);
### mod/friendica.php
Addon::callHooks('about_hook', $o);
Hook::callAll('about_hook', $o);
### mod/subthread.php
Addon::callHooks('post_local_end', $arr);
Hook::callAll('post_local_end', $arr);
### mod/profiles.php
Addon::callHooks('profile_post', $_POST);
Addon::callHooks('profile_edit', $arr);
Hook::callAll('profile_post', $_POST);
Hook::callAll('profile_edit', $arr);
### mod/settings.php
Addon::callHooks('addon_settings_post', $_POST);
Addon::callHooks('connector_settings_post', $_POST);
Addon::callHooks('display_settings_post', $_POST);
Addon::callHooks('settings_post', $_POST);
Addon::callHooks('addon_settings', $settings_addons);
Addon::callHooks('connector_settings', $settings_connectors);
Addon::callHooks('display_settings', $o);
Addon::callHooks('settings_form', $o);
Hook::callAll('addon_settings_post', $_POST);
Hook::callAll('connector_settings_post', $_POST);
Hook::callAll('display_settings_post', $_POST);
Hook::callAll('settings_post', $_POST);
Hook::callAll('addon_settings', $settings_addons);
Hook::callAll('connector_settings', $settings_connectors);
Hook::callAll('display_settings', $o);
Hook::callAll('settings_form', $o);
### mod/photos.php
Addon::callHooks('photo_post_init', $_POST);
Addon::callHooks('photo_post_file', $ret);
Addon::callHooks('photo_post_end', $foo);
Addon::callHooks('photo_post_end', $foo);
Addon::callHooks('photo_post_end', $foo);
Addon::callHooks('photo_post_end', $foo);
Addon::callHooks('photo_post_end', intval($item_id));
Addon::callHooks('photo_upload_form', $ret);
Hook::callAll('photo_post_init', $_POST);
Hook::callAll('photo_post_file', $ret);
Hook::callAll('photo_post_end', $foo);
Hook::callAll('photo_post_end', $foo);
Hook::callAll('photo_post_end', $foo);
Hook::callAll('photo_post_end', $foo);
Hook::callAll('photo_post_end', intval($item_id));
Hook::callAll('photo_upload_form', $ret);
### mod/profile.php
Addon::callHooks('profile_advanced', $o);
Hook::callAll('profile_advanced', $o);
### mod/home.php
Addon::callHooks('home_init', $ret);
Addon::callHooks("home_content", $content);
Hook::callAll('home_init', $ret);
Hook::callAll("home_content", $content);
### mod/poke.php
Addon::callHooks('post_local_end', $arr);
Hook::callAll('post_local_end', $arr);
### mod/contacts.php
Addon::callHooks('contact_edit_post', $_POST);
Addon::callHooks('contact_edit', $arr);
Hook::callAll('contact_edit_post', $_POST);
Hook::callAll('contact_edit', $arr);
### mod/tagger.php
Addon::callHooks('post_local_end', $arr);
Hook::callAll('post_local_end', $arr);
### mod/lockview.php
Addon::callHooks('lockview_content', $item);
Hook::callAll('lockview_content', $item);
### mod/uexport.php
Addon::callHooks('uexport_options', $options);
Hook::callAll('uexport_options', $options);
### mod/register.php
Addon::callHooks('register_post', $arr);
Addon::callHooks('register_form', $arr);
Hook::callAll('register_post', $arr);
Hook::callAll('register_form', $arr);
### mod/item.php
Addon::callHooks('post_local_start', $_REQUEST);
Addon::callHooks('post_local', $datarray);
Addon::callHooks('post_local_end', $datarray);
Hook::callAll('post_local_start', $_REQUEST);
Hook::callAll('post_local', $datarray);
Hook::callAll('post_local_end', $datarray);
### mod/editpost.php
Addon::callHooks('jot_tool', $jotplugins);
Hook::callAll('jot_tool', $jotplugins);
### src/Network/FKOAuth1.php
Addon::callHooks('logged_in', $a->user);
Hook::callAll('logged_in', $a->user);
### src/Render/FriendicaSmartyEngine.php
Addon::callHooks("template_vars", $arr);
Hook::callAll("template_vars", $arr);
### src/App.php
Addon::callHooks('load_config');
Addon::callHooks('head');
Addon::callHooks('footer');
Hook::callAll('load_config');
Hook::callAll('head');
Hook::callAll('footer');
### src/Model/Item.php
Addon::callHooks('post_local', $item);
Addon::callHooks('post_remote', $item);
Addon::callHooks('post_local_end', $posted_item);
Addon::callHooks('post_remote_end', $posted_item);
Addon::callHooks('tagged', $arr);
Addon::callHooks('post_local_end', $new_item);
Hook::callAll('post_local', $item);
Hook::callAll('post_remote', $item);
Hook::callAll('post_local_end', $posted_item);
Hook::callAll('post_remote_end', $posted_item);
Hook::callAll('tagged', $arr);
Hook::callAll('post_local_end', $new_item);
### src/Model/Contact.php
Addon::callHooks('contact_photo_menu', $args);
Addon::callHooks('follow', $arr);
Hook::callAll('contact_photo_menu', $args);
Hook::callAll('follow', $arr);
### src/Model/Profile.php
Addon::callHooks('profile_sidebar_enter', $profile);
Addon::callHooks('profile_sidebar', $arr);
Addon::callHooks('profile_tabs', $arr);
Addon::callHooks('zrl_init', $arr);
Addon::callHooks('magic_auth_success', $arr);
Hook::callAll('profile_sidebar_enter', $profile);
Hook::callAll('profile_sidebar', $arr);
Hook::callAll('profile_tabs', $arr);
Hook::callAll('zrl_init', $arr);
Hook::callAll('magic_auth_success', $arr);
### src/Model/Event.php
Addon::callHooks('event_updated', $event['id']);
Addon::callHooks("event_created", $event['id']);
Hook::callAll('event_updated', $event['id']);
Hook::callAll("event_created", $event['id']);
### src/Model/User.php
Addon::callHooks('register_account', $uid);
Addon::callHooks('remove_user', $user);
Hook::callAll('register_account', $uid);
Hook::callAll('remove_user', $user);
### src/Content/Text/BBCode.php
Addon::callHooks('bbcode', $text);
Addon::callHooks('bb2diaspora', $text);
Hook::callAll('bbcode', $text);
Hook::callAll('bb2diaspora', $text);
### src/Content/Text/HTML.php
Addon::callHooks('html2bbcode', $message);
Hook::callAll('html2bbcode', $message);
### src/Content/Smilies.php
Addon::callHooks('smilie', $params);
Hook::callAll('smilie', $params);
### src/Content/Feature.php
Addon::callHooks('isEnabled', $arr);
Addon::callHooks('get', $arr);
Hook::callAll('isEnabled', $arr);
Hook::callAll('get', $arr);
### src/Content/ContactSelector.php
Addon::callHooks('network_to_name', $nets);
Addon::callHooks('gender_selector', $select);
Addon::callHooks('sexpref_selector', $select);
Addon::callHooks('marital_selector', $select);
Hook::callAll('network_to_name', $nets);
Hook::callAll('gender_selector', $select);
Hook::callAll('sexpref_selector', $select);
Hook::callAll('marital_selector', $select);
### src/Content/OEmbed.php
Addon::callHooks('oembed_fetch_url', $embedurl, $j);
Hook::callAll('oembed_fetch_url', $embedurl, $j);
### src/Content/Nav.php
Addon::callHooks('page_header', $a->page['nav']);
Addon::callHooks('nav_info', $nav);
Hook::callAll('page_header', $a->page['nav']);
Hook::callAll('nav_info', $nav);
### src/Worker/Directory.php
Addon::callHooks('globaldir_update', $arr);
Hook::callAll('globaldir_update', $arr);
### src/Worker/Notifier.php
Addon::callHooks('notifier_end', $target_item);
Hook::callAll('notifier_end', $target_item);
### src/Worker/Queue.php
Addon::callHooks('queue_predeliver', $r);
Addon::callHooks('queue_deliver', $params);
Hook::callAll('queue_predeliver', $r);
Hook::callAll('queue_deliver', $params);
### src/Module/Login.php
Addon::callHooks('authenticate', $addon_auth);
Addon::callHooks('login_hook', $o);
Hook::callAll('authenticate', $addon_auth);
Hook::callAll('login_hook', $o);
### src/Module/Logout.php
Addon::callHooks("logging_out");
Hook::callAll("logging_out");
### src/Object/Post.php
Addon::callHooks('render_location', $locate);
Addon::callHooks('display_item', $arr);
Hook::callAll('render_location', $locate);
Hook::callAll('display_item', $arr);
### src/Core/ACL.php
Addon::callHooks('contact_select_options', $x);
Addon::callHooks($a->module.'_pre_'.$selname, $arr);
Addon::callHooks($a->module.'_post_'.$selname, $o);
Addon::callHooks($a->module.'_pre_'.$selname, $arr);
Addon::callHooks($a->module.'_post_'.$selname, $o);
Addon::callHooks('jot_networks', $jotnets);
Hook::callAll('contact_select_options', $x);
Hook::callAll($a->module.'_pre_'.$selname, $arr);
Hook::callAll($a->module.'_post_'.$selname, $o);
Hook::callAll($a->module.'_pre_'.$selname, $arr);
Hook::callAll($a->module.'_post_'.$selname, $o);
Hook::callAll('jot_networks', $jotnets);
### src/Core/Authentication.php
Addon::callHooks('logged_in', $a->user);
Hook::callAll('logged_in', $a->user);
### src/Core/Hook.php
@ -699,31 +699,31 @@ Here is a complete list of all hook callbacks with file locations (as of 24-Sep-
### src/Core/Worker.php
Addon::callHooks("proc_run", $arr);
Hook::callAll("proc_run", $arr);
### src/Util/Emailer.php
Addon::callHooks('emailer_send_prepare', $params);
Addon::callHooks("emailer_send", $hookdata);
Hook::callAll('emailer_send_prepare', $params);
Hook::callAll("emailer_send", $hookdata);
### src/Util/Map.php
Addon::callHooks('generate_map', $arr);
Addon::callHooks('generate_named_map', $arr);
Addon::callHooks('Map::getCoordinates', $arr);
Hook::callAll('generate_map', $arr);
Hook::callAll('generate_named_map', $arr);
Hook::callAll('Map::getCoordinates', $arr);
### src/Util/Network.php
Addon::callHooks('avatar_lookup', $avatar);
Hook::callAll('avatar_lookup', $avatar);
### src/Util/ParseUrl.php
Addon::callHooks("getsiteinfo", $siteinfo);
Hook::callAll("getsiteinfo", $siteinfo);
### src/Protocol/DFRN.php
Addon::callHooks('atom_feed_end', $atom);
Addon::callHooks('atom_feed_end', $atom);
Hook::callAll('atom_feed_end', $atom);
Hook::callAll('atom_feed_end', $atom);
### view/js/main.js

View File

@ -68,6 +68,10 @@ table.bbcodes > * > tr > th {
<td>[img]https://raw.githubusercontent.com/friendica/friendica/master/images/friendica-32.jpg[/img]</td>
<td><img src="https://raw.githubusercontent.com/friendica/friendica/master/images/friendica-32.jpg" alt="Immagine/foto"></td>
</tr>
<tr>
<td>[img=https://raw.githubusercontent.com/friendica/friendica/master/images/friendica-32.jpg]The Friendica Logo[/img]</td>
<td><img src="https://raw.githubusercontent.com/friendica/friendica/master/images/friendica-32.jpg" alt="The Friendica Logo"></td>
</tr>
<tr>
<td>[img=64x32]https://raw.githubusercontent.com/friendica/friendica/master/images/friendica-32.jpg[/img]<br>
<br>Note: provided height is simply discarded.</td>

View File

@ -142,7 +142,7 @@ $a->config['register_policy'] = REGISTER_CLOSED;
</pre></td>
<td><pre>
'config' => [
'register_policty' => REGISTER_CLOSED,
'register_policy' => \Friendica\Module\Register::CLOSED,
],
</pre></td>
</tr>
@ -242,7 +242,7 @@ register_policty = REGISTER_CLOSED
</pre></td>
<td><pre>
'config' => [
'register_policty' => REGISTER_CLOSED,
'register_policy' => \Friendica\Module\Register::CLOSED,
],
</pre></td>
</tr>

View File

@ -8,6 +8,7 @@ User
* **[Why do I getting warnings about certificates?](help/FAQ#ssl)**
* **[How can I upload images, files, links, videos and sound files to posts?](help/FAQ#upload)**
* **[Is it possible to have different avatars per profile?](help/FAQ#avatars)**
* **[How can I view Friendica in a certain language?](help/FAQ#language)**
* **[What is the difference between blocked|ignored|archived|hidden contacts?](help/FAQ#contacts)**
* **[What happens when an account is removed? Is it truly deleted?](help/FAQ#removed)**
* **[Can I subscribe to a hashtag?](help/FAQ#hashtag)**
@ -75,6 +76,33 @@ On your Edit/Manage Profiles page, you will find a "change profile photo" link.
Clicking this will take you to a page where you can upload a photograph and select which profile it will be associated with.
To avoid privacy leakage, we only display the photograph associated with your default profile as the avatar in your posts.
<a name="language"></a>
### How can I view Friendica in a certain language?
You can do this by adding the `lang` parameter to the url in your url bar.
The data in the parameter is a [ISO 639-1](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) code.
A question mark is required for the separation between url and parameters.
Example:
https://social.example.com/profile/example
in German:
https://social.example.com/profile/example?lang=de.
If the question mark is already in the url you need to do it using a ampersand.
Example:
https://social.example.com/profile/example?tab=profile
in German:
https://social.example.com/profile/example?tab=profile&lang=de.
When a certain language is forced, the language remains until session is closed.
<a name="contacts"></a>
### What is the difference between blocked|ignored|archived|hidden contacts?
@ -144,7 +172,9 @@ Friendica is using a [Twitter/GNU Social compatible API](help/api), which means
Here is a list of known working clients:
* Android
* [Friendiqa](https://github.com/lubuwest/friendiqa) (available in Google Playstore or from a binary repository you can add to [F-Droid](https://freunde.ma-nic.de/display/3e98eba8185a13c5bdbf3d1539646854))
* [Friendiqa](https://git.friendi.ca/lubuwest/Friendiqa) (available in Google Playstore or from a binary repository you can add to [F-Droid](https://freunde.ma-nic.de/display/3e98eba8185a13c5bdbf3d1539646854))
* [Fedilab](https://gitlab.com/tom79/mastalab) (available in F-Droid and Google stores)
* [DiCa](https://dica.mixi.cool/)
* AndStatus
* Twidere
* Mustard and Mustard-Mod

View File

@ -47,6 +47,7 @@ Friendica Documentation and Resources
* [Addon Development](help/Addons)
* [Theme Development](help/themes)
* [Smarty 3 Templates](help/smarty3-templates)
* [Storage backend addon](help/AddonStorageBackend)
* How To
* [Translate Friendica](help/translations)
* [Use Composer](help/Composer)

View File

@ -18,10 +18,8 @@ If you do not have a Friendica account yet, you can register a temporary one at
The account will expire after 7 days, but you can ask the server admin to keep your account longer, should the problem not be resolved after that.
Before you begin: Choose a domain name or subdomain name for your server.
Put some thought into this. Changing it after installation is currently not supported.
Things will break, and some of your friends may have difficulty communicating with you.
We plan to address this limitation in a future release.
Put some thought into this.
While changing it after installation is supported, things still might break.
Requirements
---
@ -57,7 +55,7 @@ The Linux commands to clone the repository into a directory "mywebsite" would be
git clone https://github.com/friendica/friendica.git -b master mywebsite
cd mywebsite
bin/composer.phar install
bin/composer.phar install --no-dev
Make sure the folder *view/smarty3* exists and is writable by the webserver user, in this case `www-data`

View File

@ -15,6 +15,6 @@ Remember the link at the top of this page will bring you back here.
Once you've added some groups, <a href="help/Quick-Start-andfinally">move on to the next section</a>.
<iframe src="http://dir.friendica.social/directory" width="950" height="600"></iframe>
<iframe src="https://dir.friendica.social/forum" width="950" height="600"></iframe>

View File

@ -101,6 +101,32 @@ Default is false.
### File upload
#### File storage backend
Set the backend used by Friendica to store uploaded file data.
Two storage backends are avaiable with Friendica:
- **Database** : Data is stored in a dedicated table in database (`storage`)
- **Filesystem** : Data is stored as file on the filesystem.
More storage backends can be avaiable from third-party addons.
If you use those, please refer to the documentation of those addons for further information.
Default value is 'Database (legacy)': it's the legacy way used to store data directly in database.
Existing data can be moved to the current active backend using the ['storage move' console command](help/tools)
If selected backend has configurable options, new fields are shown here.
##### Filesystem: Storage base path
The base path where Filesystem storage backend saves data.
For maximum security, this path should be outside the folder tree served by the web server: this way files can't be downloaded bypassing the privacy checks.
Default value is `storage`, that is the `storage` folder in Friendica code root folder.
#### Maximum Image Size
Maximum size in bytes of uploaded images.

View File

@ -21,7 +21,7 @@ You can get the latest changes at any time with
cd path/to/friendica
git pull
bin/composer.phar install
bin/composer.phar install --no-dev
The addon tree has to be updated separately like so:
@ -69,4 +69,4 @@ DROP TABLE <table_name>;
RENAME TABLE <table_name>_new TO <table_name>;
```
This method is slower overall, but it is better suited for large numbers of duplicates.
This method is slower overall, but it is better suited for large numbers of duplicates.

View File

@ -379,6 +379,18 @@ Friendica doesn't allow showing the friends of other users.
* media: image data
#### Return values
Object of:
* media_id: a media identifier (integer)
* media_id_string: a media identifier (string)
* size: size in byte
* image.w: image width
* image.h: image height
* image.image_type: image mime type
* image.friendica_preview_url: image preview url
---
### oauth/request_token (*)
@ -642,9 +654,11 @@ Returned status object is conform to GNU Social/Twitter api.
Friendica adds some addictional fields:
- author: a user object, it's the author of the item. In case of a reshare for legacy reasons the "user" field doesn't show the real author. This field always contains the real author of a post.
- owner: a user object, it's the owner of the item.
- private: boolean, true if the item is marked as private
- activities: map with activities related to the item. Every activity is a list of user objects.
- comments: comment numbers
This properties are prefixed with "friendica_" in JSON responses and namespaced under "http://friendi.ca/schema/api/1/" in XML responses
@ -654,6 +668,9 @@ JSON:
[
{
// ...
'friendica_author' : {
// user object
},
'friendica_owner' : {
// user object
},
@ -669,7 +686,8 @@ JSON:
'attendyes': [],
'attendno': [],
'attendmaybe': []
}
},
'friendica_comments': 12
},
// ...
]
@ -695,6 +713,7 @@ XML:
<friendica:attendno/>
<friendica:attendmaybe/>
</friendica:activities>
<friendica:comments>21</friendica:comments>
</status>
<!-- ... -->
</statuses>
@ -744,6 +763,7 @@ Friendica doesn't allow showing followers of other users.
* count: alias for the rpp parameter
* since_id: returns statuses with ids greater than the given id
* max_id: returns statuses with ids lower or equal to the given id
* exclude_replies: don't show replies (default: false)
#### Unsupported parameters

View File

@ -26,7 +26,7 @@ Addons sollten einen Kommentarblock mit den folgenden vier Parametern enthalten:
Registriere deine Addon-Hooks während der Installation.
Addon::registerHook($hookname, $file, $function);
\Friendica\Core\Hook::register($hookname, $file, $function);
$hookname ist ein String und entspricht einem bekannten Friendica-Hook.
@ -193,299 +193,299 @@ Eine komplette Liste aller Hook-Callbacks mit den zugehörigen Dateien (am 01-Ap
### index.php
Addon::callHooks('init_1');
Addon::callHooks('app_menu', $arr);
Addon::callHooks('page_content_top', $a->page['content']);
Addon::callHooks($a->module.'_mod_init', $placeholder);
Addon::callHooks($a->module.'_mod_init', $placeholder);
Addon::callHooks($a->module.'_mod_post', $_POST);
Addon::callHooks($a->module.'_mod_afterpost', $placeholder);
Addon::callHooks($a->module.'_mod_content', $arr);
Addon::callHooks($a->module.'_mod_aftercontent', $arr);
Addon::callHooks('page_end', $a->page['content']);
Hook::callAll('init_1');
Hook::callAll('app_menu', $arr);
Hook::callAll('page_content_top', $a->page['content']);
Hook::callAll($a->module.'_mod_init', $placeholder);
Hook::callAll($a->module.'_mod_init', $placeholder);
Hook::callAll($a->module.'_mod_post', $_POST);
Hook::callAll($a->module.'_mod_afterpost', $placeholder);
Hook::callAll($a->module.'_mod_content', $arr);
Hook::callAll($a->module.'_mod_aftercontent', $arr);
Hook::callAll('page_end', $a->page['content']);
### include/api.php
Addon::callHooks('logged_in', $a->user);
Addon::callHooks('authenticate', $addon_auth);
Addon::callHooks('logged_in', $a->user);
Hook::callAll('logged_in', $a->user);
Hook::callAll('authenticate', $addon_auth);
Hook::callAll('logged_in', $a->user);
### include/enotify.php
Addon::callHooks('enotify', $h);
Addon::callHooks('enotify_store', $datarray);
Addon::callHooks('enotify_mail', $datarray);
Addon::callHooks('check_item_notification', $notification_data);
Hook::callAll('enotify', $h);
Hook::callAll('enotify_store', $datarray);
Hook::callAll('enotify_mail', $datarray);
Hook::callAll('check_item_notification', $notification_data);
### include/conversation.php
Addon::callHooks('conversation_start', $cb);
Addon::callHooks('render_location', $locate);
Addon::callHooks('display_item', $arr);
Addon::callHooks('display_item', $arr);
Addon::callHooks('item_photo_menu', $args);
Addon::callHooks('jot_tool', $jotplugins);
Hook::callAll('conversation_start', $cb);
Hook::callAll('render_location', $locate);
Hook::callAll('display_item', $arr);
Hook::callAll('display_item', $arr);
Hook::callAll('item_photo_menu', $args);
Hook::callAll('jot_tool', $jotplugins);
### include/text.php
Addon::callHooks('contact_block_end', $arr);
Addon::callHooks('poke_verbs', $arr);
Addon::callHooks('put_item_in_cache', $hook_data);
Addon::callHooks('prepare_body_init', $item);
Addon::callHooks('prepare_body_content_filter', $hook_data);
Addon::callHooks('prepare_body', $hook_data);
Addon::callHooks('prepare_body_final', $hook_data);
Hook::callAll('contact_block_end', $arr);
Hook::callAll('poke_verbs', $arr);
Hook::callAll('put_item_in_cache', $hook_data);
Hook::callAll('prepare_body_init', $item);
Hook::callAll('prepare_body_content_filter', $hook_data);
Hook::callAll('prepare_body', $hook_data);
Hook::callAll('prepare_body_final', $hook_data);
### include/items.php
Addon::callHooks('page_info_data', $data);
Hook::callAll('page_info_data', $data);
### mod/directory.php
Addon::callHooks('directory_item', $arr);
Hook::callAll('directory_item', $arr);
### mod/xrd.php
Addon::callHooks('personal_xrd', $arr);
Hook::callAll('personal_xrd', $arr);
### mod/ping.php
Addon::callHooks('network_ping', $arr);
Hook::callAll('network_ping', $arr);
### mod/parse_url.php
Addon::callHooks("parse_link", $arr);
Hook::callAll("parse_link", $arr);
### mod/manage.php
Addon::callHooks('home_init', $ret);
Hook::callAll('home_init', $ret);
### mod/acl.php
Addon::callHooks('acl_lookup_end', $results);
Hook::callAll('acl_lookup_end', $results);
### mod/network.php
Addon::callHooks('network_content_init', $arr);
Addon::callHooks('network_tabs', $arr);
Hook::callAll('network_content_init', $arr);
Hook::callAll('network_tabs', $arr);
### mod/friendica.php
Addon::callHooks('about_hook', $o);
Hook::callAll('about_hook', $o);
### mod/subthread.php
Addon::callHooks('post_local_end', $arr);
Hook::callAll('post_local_end', $arr);
### mod/profiles.php
Addon::callHooks('profile_post', $_POST);
Addon::callHooks('profile_edit', $arr);
Hook::callAll('profile_post', $_POST);
Hook::callAll('profile_edit', $arr);
### mod/settings.php
Addon::callHooks('addon_settings_post', $_POST);
Addon::callHooks('connector_settings_post', $_POST);
Addon::callHooks('display_settings_post', $_POST);
Addon::callHooks('settings_post', $_POST);
Addon::callHooks('addon_settings', $settings_addons);
Addon::callHooks('connector_settings', $settings_connectors);
Addon::callHooks('display_settings', $o);
Addon::callHooks('settings_form', $o);
Hook::callAll('addon_settings_post', $_POST);
Hook::callAll('connector_settings_post', $_POST);
Hook::callAll('display_settings_post', $_POST);
Hook::callAll('settings_post', $_POST);
Hook::callAll('addon_settings', $settings_addons);
Hook::callAll('connector_settings', $settings_connectors);
Hook::callAll('display_settings', $o);
Hook::callAll('settings_form', $o);
### mod/photos.php
Addon::callHooks('photo_post_init', $_POST);
Addon::callHooks('photo_post_file', $ret);
Addon::callHooks('photo_post_end', $foo);
Addon::callHooks('photo_post_end', $foo);
Addon::callHooks('photo_post_end', $foo);
Addon::callHooks('photo_post_end', $foo);
Addon::callHooks('photo_post_end', intval($item_id));
Addon::callHooks('photo_upload_form', $ret);
Hook::callAll('photo_post_init', $_POST);
Hook::callAll('photo_post_file', $ret);
Hook::callAll('photo_post_end', $foo);
Hook::callAll('photo_post_end', $foo);
Hook::callAll('photo_post_end', $foo);
Hook::callAll('photo_post_end', $foo);
Hook::callAll('photo_post_end', intval($item_id));
Hook::callAll('photo_upload_form', $ret);
### mod/profile.php
Addon::callHooks('profile_advanced', $o);
Hook::callAll('profile_advanced', $o);
### mod/home.php
Addon::callHooks('home_init', $ret);
Addon::callHooks("home_content", $content);
Hook::callAll('home_init', $ret);
Hook::callAll("home_content", $content);
### mod/poke.php
Addon::callHooks('post_local_end', $arr);
Hook::callAll('post_local_end', $arr);
### mod/contacts.php
Addon::callHooks('contact_edit_post', $_POST);
Addon::callHooks('contact_edit', $arr);
Hook::callAll('contact_edit_post', $_POST);
Hook::callAll('contact_edit', $arr);
### mod/tagger.php
Addon::callHooks('post_local_end', $arr);
Hook::callAll('post_local_end', $arr);
### mod/lockview.php
Addon::callHooks('lockview_content', $item);
Hook::callAll('lockview_content', $item);
### mod/uexport.php
Addon::callHooks('uexport_options', $options);
Hook::callAll('uexport_options', $options);
### mod/register.php
Addon::callHooks('register_post', $arr);
Addon::callHooks('register_form', $arr);
Hook::callAll('register_post', $arr);
Hook::callAll('register_form', $arr);
### mod/item.php
Addon::callHooks('post_local_start', $_REQUEST);
Addon::callHooks('post_local', $datarray);
Addon::callHooks('post_local_end', $datarray);
Hook::callAll('post_local_start', $_REQUEST);
Hook::callAll('post_local', $datarray);
Hook::callAll('post_local_end', $datarray);
### mod/editpost.php
Addon::callHooks('jot_tool', $jotplugins);
Hook::callAll('jot_tool', $jotplugins);
### src/Network/FKOAuth1.php
Addon::callHooks('logged_in', $a->user);
Hook::callAll('logged_in', $a->user);
### src/Render/FriendicaSmartyEngine.php
Addon::callHooks("template_vars", $arr);
Hook::callAll("template_vars", $arr);
### src/Model/Item.php
Addon::callHooks('post_local', $item);
Addon::callHooks('post_remote', $item);
Addon::callHooks('post_local_end', $posted_item);
Addon::callHooks('post_remote_end', $posted_item);
Addon::callHooks('tagged', $arr);
Addon::callHooks('post_local_end', $new_item);
Hook::callAll('post_local', $item);
Hook::callAll('post_remote', $item);
Hook::callAll('post_local_end', $posted_item);
Hook::callAll('post_remote_end', $posted_item);
Hook::callAll('tagged', $arr);
Hook::callAll('post_local_end', $new_item);
### src/Model/Contact.php
Addon::callHooks('contact_photo_menu', $args);
Addon::callHooks('follow', $arr);
Hook::callAll('contact_photo_menu', $args);
Hook::callAll('follow', $arr);
### src/Model/Profile.php
Addon::callHooks('profile_sidebar_enter', $profile);
Addon::callHooks('profile_sidebar', $arr);
Addon::callHooks('profile_tabs', $arr);
Addon::callHooks('zrl_init', $arr);
Hook::callAll('profile_sidebar_enter', $profile);
Hook::callAll('profile_sidebar', $arr);
Hook::callAll('profile_tabs', $arr);
Hook::callAll('zrl_init', $arr);
### src/Model/Event.php
Addon::callHooks('event_updated', $event['id']);
Addon::callHooks("event_created", $event['id']);
Hook::callAll('event_updated', $event['id']);
Hook::callAll("event_created", $event['id']);
### src/Model/User.php
Addon::callHooks('register_account', $uid);
Addon::callHooks('remove_user', $user);
Hook::callAll('register_account', $uid);
Hook::callAll('remove_user', $user);
### src/Content/Text/BBCode.php
Addon::callHooks('bbcode', $text);
Addon::callHooks('bb2diaspora', $text);
Hook::callAll('bbcode', $text);
Hook::callAll('bb2diaspora', $text);
### src/Content/Text/HTML.php
Addon::callHooks('html2bbcode', $message);
Hook::callAll('html2bbcode', $message);
### src/Content/Smilies.php
Addon::callHooks('smilie', $params);
Hook::callAll('smilie', $params);
### src/Content/Feature.php
Addon::callHooks('isEnabled', $arr);
Addon::callHooks('get', $arr);
Hook::callAll('isEnabled', $arr);
Hook::callAll('get', $arr);
### src/Content/ContactSelector.php
Addon::callHooks('network_to_name', $nets);
Addon::callHooks('gender_selector', $select);
Addon::callHooks('sexpref_selector', $select);
Addon::callHooks('marital_selector', $select);
Hook::callAll('network_to_name', $nets);
Hook::callAll('gender_selector', $select);
Hook::callAll('sexpref_selector', $select);
Hook::callAll('marital_selector', $select);
### src/Content/OEmbed.php
Addon::callHooks('oembed_fetch_url', $embedurl, $j);
Hook::callAll('oembed_fetch_url', $embedurl, $j);
### src/Content/Nav.php
Addon::callHooks('page_header', $a->page['nav']);
Addon::callHooks('nav_info', $nav);
Hook::callAll('page_header', $a->page['nav']);
Hook::callAll('nav_info', $nav);
### src/Core/Authentication.php
Addon::callHooks('logged_in', $a->user);
Hook::callAll('logged_in', $a->user);
### src/Worker/Directory.php
Addon::callHooks('globaldir_update', $arr);
Hook::callAll('globaldir_update', $arr);
### src/Worker/Notifier.php
Addon::callHooks('notifier_end', $target_item);
Hook::callAll('notifier_end', $target_item);
### src/Worker/Queue.php
Addon::callHooks('queue_predeliver', $r);
Addon::callHooks('queue_deliver', $params);
Hook::callAll('queue_predeliver', $r);
Hook::callAll('queue_deliver', $params);
### src/Module/Login.php
Addon::callHooks('authenticate', $addon_auth);
Addon::callHooks('login_hook', $o);
Hook::callAll('authenticate', $addon_auth);
Hook::callAll('login_hook', $o);
### src/Module/Logout.php
Addon::callHooks("logging_out");
Hook::callAll("logging_out");
### src/Object/Post.php
Addon::callHooks('render_location', $locate);
Addon::callHooks('display_item', $arr);
Hook::callAll('render_location', $locate);
Hook::callAll('display_item', $arr);
### src/Core/ACL.php
Addon::callHooks('contact_select_options', $x);
Addon::callHooks($a->module.'_pre_'.$selname, $arr);
Addon::callHooks($a->module.'_post_'.$selname, $o);
Addon::callHooks($a->module.'_pre_'.$selname, $arr);
Addon::callHooks($a->module.'_post_'.$selname, $o);
Addon::callHooks('jot_networks', $jotnets);
Hook::callAll('contact_select_options', $x);
Hook::callAll($a->module.'_pre_'.$selname, $arr);
Hook::callAll($a->module.'_post_'.$selname, $o);
Hook::callAll($a->module.'_pre_'.$selname, $arr);
Hook::callAll($a->module.'_post_'.$selname, $o);
Hook::callAll('jot_networks', $jotnets);
### src/Core/Worker.php
Addon::callHooks("proc_run", $arr);
Hook::callAll("proc_run", $arr);
### src/Util/Emailer.php
Addon::callHooks('emailer_send_prepare', $params);
Addon::callHooks("emailer_send", $hookdata);
Hook::callAll('emailer_send_prepare', $params);
Hook::callAll("emailer_send", $hookdata);
### src/Util/Map.php
Addon::callHooks('generate_map', $arr);
Addon::callHooks('generate_named_map', $arr);
Addon::callHooks('Map::getCoordinates', $arr);
Hook::callAll('generate_map', $arr);
Hook::callAll('generate_named_map', $arr);
Hook::callAll('Map::getCoordinates', $arr);
### src/Util/Network.php
Addon::callHooks('avatar_lookup', $avatar);
Hook::callAll('avatar_lookup', $avatar);
### src/Util/ParseUrl.php
Addon::callHooks("getsiteinfo", $siteinfo);
Hook::callAll("getsiteinfo", $siteinfo);
### src/Protocol/DFRN.php
Addon::callHooks('atom_feed_end', $atom);
Addon::callHooks('atom_feed_end', $atom);
Hook::callAll('atom_feed_end', $atom);
Hook::callAll('atom_feed_end', $atom);

View File

@ -68,6 +68,10 @@ table.bbcodes > * > tr > th {
<td>[img]https://raw.githubusercontent.com/friendica/friendica/master/images/friendica-32.jpg[/img]</td>
<td><img src="https://raw.githubusercontent.com/friendica/friendica/master/images/friendica-32.jpg" alt="Immagine/foto"></td>
</tr>
<tr>
<td>[img=https://raw.githubusercontent.com/friendica/friendica/master/images/friendica-32.jpg]Das Friendica Logo[/img]</td>
<td><img src="https://raw.githubusercontent.com/friendica/friendica/master/images/friendica-32.jpg" alt="Das Friendica Logo"></td>
</tr>
<tr>
<td>[img=64x32]https://raw.githubusercontent.com/friendica/friendica/master/images/friendica-32.jpg[/img]<br>
<br>Note: provided height is simply discarded.</td>

View File

@ -188,7 +188,9 @@ Das bedeutet, dass du jeden Twitter/GNU Social Client verwenden kannst in dem du
Hier ist eine Liste von Clients bei denen dies möglich ist, bzw. die speziell für Friendica entwickelt werden:
* Android
* [Friendiqa](https://github.com/lubuwest/friendiqa) (Gibt es im Google Playstore oder als [binary Repository](https://freunde.ma-nic.de/display/3e98eba8185a13c5bdbf3d1539646854) für F-Droid)
* [Friendiqa](https://git.friendi.ca/lubuwest/Friendiqa) (Gibt es im Google Playstore oder als [binary Repository](https://freunde.ma-nic.de/display/3e98eba8185a13c5bdbf3d1539646854) für F-Droid)
* [Fedilab](https://gitlab.com/tom79/mastalab) (Gibt es im F-Droid und dem Google Play Store)
* [DiCa](https://dica.mixi.cool/) (Gibt es bei Google Play)
* AndStatus
* Twidere
* Mustard and Mustard-Mod

View File

@ -21,6 +21,6 @@ Solltest Du beim Stöbern durch die vielen Gruppen nicht wieder hierher zurück
Wenn Du einige Gruppen hinzugefügt hast, gehe <a href="help/Quick-Start-andfinally">weiter zum nächsten Schritt</a>.
<iframe src="https://dir.friendica.social/home" width="950" height="600"></iframe>
<iframe src="https://dir.friendica.social/forum" width="950" height="600"></iframe>

View File

@ -12,7 +12,7 @@ Die zweite Zahl steht für die Anzahl der Aufgaben, die die Worker noch vor sich
Die Worker arbeiten Hintergrundprozesse ab.
Die Aufgaben der Worker sind priorisiert und werden anhand dieser Prioritäten abgearbeitet.
Desweiteren findest du eine Übersicht über die Accounts auf dem Friendica Knoten, die unter dem Punkt "Nutzer" moderiert werden können.
Des weiteren findest du eine Übersicht über die Accounts auf dem Friendica Knoten, die unter dem Punkt "Nutzer" moderiert werden können.
Sowie eine Liste der derzeit aktivierten Addons.
Diese Liste ist verlinkt, so dass du schnellen Zugriff auf die Informationsseiten der einzelnen Addons hast.
Abschließend findest du auf der Startseite des Admin Panels die installierte Version von Friendica.
@ -47,7 +47,7 @@ Mehr Informationen zum Übersetzungsprozess von Friendica findest du [auf dieser
Hier kann das Theme bestimmt werden, welches standardmäßig zum Anzeigen der Seite verwendet werden soll.
Nutzer können in ihren Einstellungen andere Themes wählen.
Derzeit ist das "duepunto zero" Theme das vorausgewählte Theme.
Derzeit ist das "vier" Theme das vorausgewählte Theme.
Für mobile Geräte kannst du ein spezielles Theme wählen, wenn das Standardtheme ungeeignet für mobile Geräte sein sollte.
Das `vier` Theme z.B. unterstützt kleine Anzeigen und benötigt kein zusätzliches mobiles Theme.
@ -92,6 +92,32 @@ Standardmäßig ist hier "false" gesetzt.
### Datei hochladen
#### Datenspeicher Backend
Legt das Datenspeicher Backend fest, mit dem Friendica hoch geladene Daten speichert.
Zwei Speicher Backends sind standardmäßig bei Friendica verfügbar:
- **Database** : Die Daten werden in einer speziellen Tabelle in der Datenbank (`storage`) gespeichert.
- **Filesystem** : Die Daten werden als Dateien im Dateisystem gespeichert.
Weitere Speicher Backends können als Addons von Drittanbietern verfügbar sein.
Falls ein solches verwendet wird, sei an dieser Stelle nur auf deren Dokumentation für weitere Informationen verwiesen.
Die Grundeinstellung ist 'Datenbank (legacy)': Dies ist die alte Methode von Friendica Daten direkt in der Datenbank abzulegen.
Bestehende Daten können zum aktuell ausgewählten Backend verschoben werden.
Hierfür kann der ['storage move'](help/tools) Befehl der Friendica Konsole verwendet werden.
Sollte das ausgewählte Speicher Backand zusätzliche Konfigurationsparameter besitzen, werden nach der Auswahl des Backends hier weitere Felder angezeigt.
##### Dateipfad zum Speicher
Der Basispfad unter dem das Filesystem Datenspeicher Backend die Daten speichern soll.
Um zu verhindern, dass Daten unter Umgehung der Privatsphären-Einstellungen herunter geladen werden, sollte dieser Pfad außerhalb der Verzeichnisstruktur des Webservers liegen.
Die Grundeinstellung ist `storage`, das ist das `storage` Unterverzeichnis innerhalb des Friendica Verzeichnisses.
#### Maximale Bildgröße
Maximale Bild-Dateigröße in Byte. Standardmäßig ist 0 gesetzt, was bedeutet, dass kein Limit gesetzt ist.

View File

@ -9,6 +9,7 @@ Friendica Tools
Friendica has a build in command console you can find in the *bin* directory.
The console provides the following commands:
* cache: Manage node cache
* config: Edit site config
* createdoxygen: Generate Doxygen headers
* dbstructure: Do database updates
@ -24,6 +25,8 @@ The console provides the following commands:
* php2po: Generate a messages.po file from a strings.php file
* po2php: Generate a strings.php file from a messages.po file
* typo: Checks for parse errors in Friendica files
* postupdate: Execute pending post update scripts (can last days)
* storage: Manage storage backend
Please consult *bin/console help* on the command line interface of your server for details about the commands.
@ -53,7 +56,7 @@ In */etc/fail2ban/jail.local* create a section for Friendica:
And create a filter definition in */etc/fail2ban/filter.d/friendica.conf*:
[Definition]
failregex = ^.*Login\.php.*failed login attempt.*from IP <HOST>.*$
failregex = ^.*authenticate\: failed login attempt.*\"ip\"\:\"<HOST>\".*$
ignoreregex =
Additionally you have to define the number of failed logins before the ban should be activated.

File diff suppressed because it is too large Load Diff

View File

@ -8,8 +8,8 @@ use Friendica\Content\ContactSelector;
use Friendica\Content\Feature;
use Friendica\Content\Pager;
use Friendica\Content\Text\BBCode;
use Friendica\Core\Addon;
use Friendica\Core\Config;
use Friendica\Core\Hook;
use Friendica\Core\L10n;
use Friendica\Core\Logger;
use Friendica\Core\PConfig;
@ -117,6 +117,10 @@ function item_redir_and_replace_images($body, $images, $cid) {
/**
* Render actions localized
*
* @param $item
* @throws ImagickException
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
function localize_item(&$item)
{
@ -172,6 +176,7 @@ function localize_item(&$item)
$plink = '[url=' . $obj['plink'] . ']' . $post_type . '[/url]';
$bodyverb = '';
if (activity_match($item['verb'], ACTIVITY_LIKE)) {
$bodyverb = L10n::t('%1$s likes %2$s\'s %3$s');
} elseif (activity_match($item['verb'], ACTIVITY_DISLIKE)) {
@ -205,8 +210,8 @@ function localize_item(&$item)
foreach ($links->link as $l) {
$atts = $l->attributes();
switch ($atts['rel']) {
case "alternate": $Blink = $atts['href'];
case "photo": $Bphoto = $atts['href'];
case "alternate": $Blink = $atts['href']; break;
case "photo": $Bphoto = $atts['href']; break;
}
}
@ -360,13 +365,15 @@ function localize_item(&$item)
// Only create a redirection to a magic link when logged in
if (!empty($item['plink']) && (local_user() || remote_user())) {
$item['plink'] = Contact::magicLinkbyContact($author, $item['plink']);
$item['plink'] = Contact::magicLinkByContact($author, $item['plink']);
}
}
/**
* Count the total of comments on this item and its desendants
* @TODO proper type-hint + doc-tag
* @param $item
* @return int
*/
function count_descendants($item) {
$total = count($item['children']);
@ -436,7 +443,17 @@ function conv_get_blocklist()
* The $mode parameter decides between the various renderings and also
* figures out how to determine page owner and other contextual items
* that are based on unique features of the calling module.
*
* @param App $a
* @param array $items
* @param Pager $pager
* @param $mode
* @param $update
* @param bool $preview
* @param string $order
* @param int $uid
* @return string
* @throws ImagickException
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
function conversation(App $a, array $items, Pager $pager, $mode, $update, $preview = false, $order = 'commented', $uid = 0)
{
@ -543,7 +560,7 @@ function conversation(App $a, array $items, Pager $pager, $mode, $update, $previ
}
$cb = ['items' => $items, 'mode' => $mode, 'update' => $update, 'preview' => $preview];
Addon::callHooks('conversation_start',$cb);
Hook::callAll('conversation_start',$cb);
$items = $cb['items'];
@ -608,14 +625,14 @@ function conversation(App $a, array $items, Pager $pager, $mode, $update, $previ
$author = ['uid' => 0, 'id' => $item['author-id'],
'network' => $item['author-network'], 'url' => $item['author-link']];
$profile_link = Contact::magicLinkbyContact($author);
$profile_link = Contact::magicLinkByContact($author);
if (strpos($profile_link, 'redir/') === 0) {
$sparkle = ' sparkle';
}
$locate = ['location' => $item['location'], 'coord' => $item['coord'], 'html' => ''];
Addon::callHooks('render_location',$locate);
Hook::callAll('render_location',$locate);
$location = ((strlen($locate['html'])) ? $locate['html'] : render_location_dummy($locate));
@ -643,21 +660,12 @@ function conversation(App $a, array $items, Pager $pager, $mode, $update, $previ
list($categories, $folders) = get_cats_and_terms($item);
$profile_name_e = $profile_name;
if (!empty($item['content-warning']) && PConfig::get(local_user(), 'system', 'disable_cw', false)) {
$title_e = ucfirst($item['content-warning']);
$title = ucfirst($item['content-warning']);
} else {
$title_e = $item['title'];
$title = $item['title'];
}
$body_e = $body;
$tags_e = $tags['tags'];
$hashtags_e = $tags['hashtags'];
$mentions_e = $tags['mentions'];
$location_e = $location;
$owner_name_e = $owner_name;
$tmp_item = [
'template' => $tpl,
'id' => ($preview ? 'P0' : $item['id']),
@ -667,27 +675,28 @@ function conversation(App $a, array $items, Pager $pager, $mode, $update, $previ
'linktitle' => L10n::t('View %s\'s profile @ %s', $profile_name, $item['author-link']),
'profile_url' => $profile_link,
'item_photo_menu' => item_photo_menu($item),
'name' => $profile_name_e,
'name' => $profile_name,
'sparkle' => $sparkle,
'lock' => $lock,
'thumb' => System::removedBaseUrl(ProxyUtils::proxifyUrl($item['author-avatar'], false, ProxyUtils::SIZE_THUMB)),
'title' => $title_e,
'body' => $body_e,
'tags' => $tags_e,
'hashtags' => $hashtags_e,
'mentions' => $mentions_e,
'title' => $title,
'body' => $body,
'tags' => $tags['tags'],
'hashtags' => $tags['hashtags'],
'mentions' => $tags['mentions'],
'implicit_mentions' => $tags['implicit_mentions'],
'txt_cats' => L10n::t('Categories:'),
'txt_folders' => L10n::t('Filed under:'),
'has_cats' => ((count($categories)) ? 'true' : ''),
'has_folders' => ((count($folders)) ? 'true' : ''),
'categories' => $categories,
'folders' => $folders,
'text' => strip_tags($body_e),
'text' => strip_tags($body),
'localtime' => DateTimeFormat::local($item['created'], 'r'),
'ago' => (($item['app']) ? L10n::t('%s from %s', Temporal::getRelativeDate($item['created']),$item['app']) : Temporal::getRelativeDate($item['created'])),
'location' => $location_e,
'location' => $location,
'indent' => '',
'owner_name' => $owner_name_e,
'owner_name' => $owner_name,
'owner_url' => $owner_url,
'owner_photo' => System::removedBaseUrl(ProxyUtils::proxifyUrl($item['owner-avatar'], false, ProxyUtils::SIZE_THUMB)),
'plink' => Item::getPlink($item),
@ -706,7 +715,7 @@ function conversation(App $a, array $items, Pager $pager, $mode, $update, $previ
];
$arr = ['item' => $item, 'output' => $tmp_item];
Addon::callHooks('display_item', $arr);
Hook::callAll('display_item', $arr);
$threads[$threadsid]['id'] = $item['id'];
$threads[$threadsid]['network'] = $item['network'];
@ -743,7 +752,7 @@ function conversation(App $a, array $items, Pager $pager, $mode, $update, $previ
/// @todo Check if this call is needed or not
$arr = ['item' => $item];
Addon::callHooks('display_item', $arr);
Hook::callAll('display_item', $arr);
$item['pagedrop'] = $page_dropping;
@ -783,7 +792,11 @@ function conversation(App $a, array $items, Pager $pager, $mode, $update, $previ
*
* @param array $parents Parent items
*
* @param $block_authors
* @param $order
* @param $uid
* @return array items with parents and comments
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
function conversation_add_children(array $parents, $block_authors, $order, $uid) {
$max_comments = Config::get('system', 'max_comments', 100);
@ -830,6 +843,8 @@ function item_photo_menu($item) {
$status_link = '';
$photos_link = '';
$posts_link = '';
$block_link = '';
$ignore_link = '';
if (local_user() && local_user() == $item['uid'] && $item['parent'] == $item['id'] && !$item['self']) {
$sub_link = 'javascript:dosubthread(' . $item['id'] . '); return false;';
@ -837,10 +852,11 @@ function item_photo_menu($item) {
$author = ['uid' => 0, 'id' => $item['author-id'],
'network' => $item['author-network'], 'url' => $item['author-link']];
$profile_link = Contact::magicLinkbyContact($author);
$profile_link = Contact::magicLinkByContact($author, $item['author-link']);
$sparkle = (strpos($profile_link, 'redir/') === 0);
$cid = 0;
$pcid = Contact::getIdForURL($item['author-link'], 0, true);
$network = '';
$rel = 0;
$condition = ['uid' => local_user(), 'nurl' => Strings::normaliseLink($item['author-link'])];
@ -852,9 +868,16 @@ function item_photo_menu($item) {
}
if ($sparkle) {
$status_link = $profile_link . '?url=status';
$photos_link = $profile_link . '?url=photos';
$profile_link = $profile_link . '?url=profile';
$status_link = $profile_link . '?tab=status';
$photos_link = str_replace('/profile/', '/photos/', $profile_link);
$profile_link = $profile_link . '?=profile';
}
if (!empty($pcid)) {
$contact_url = 'contact/' . $pcid;
$posts_link = 'contact/' . $pcid . '/posts';
$block_link = 'contact/' . $pcid . '/block';
$ignore_link = 'contact/' . $pcid . '/ignore';
}
if ($cid && !$item['self']) {
@ -875,7 +898,9 @@ function item_photo_menu($item) {
L10n::t('View Photos') => $photos_link,
L10n::t('Network Posts') => $posts_link,
L10n::t('View Contact') => $contact_url,
L10n::t('Send PM') => $pm_url
L10n::t('Send PM') => $pm_url,
L10n::t('Block') => $block_link,
L10n::t('Ignore') => $ignore_link
];
if ($network == Protocol::DFRN) {
@ -892,7 +917,7 @@ function item_photo_menu($item) {
$args = ['item' => $item, 'menu' => $menu];
Addon::callHooks('item_photo_menu', $args);
Hook::callAll('item_photo_menu', $args);
$menu = $args['menu'];
@ -912,13 +937,14 @@ function item_photo_menu($item) {
* @brief Checks item to see if it is one of the builtin activities (like/dislike, event attendance, consensus items, etc.)
* Increments the count of each matching activity and adds a link to the author as needed.
*
* @param array $item
* @param array $item
* @param array &$conv_responses (already created with builtin activity structure)
* @return void
* @throws ImagickException
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
function builtin_activity_puller($item, &$conv_responses) {
foreach ($conv_responses as $mode => $v) {
$url = '';
$sparkle = '';
switch ($mode) {
@ -944,7 +970,7 @@ function builtin_activity_puller($item, &$conv_responses) {
if (activity_match($item['verb'], $verb) && ($item['id'] != $item['parent'])) {
$author = ['uid' => 0, 'id' => $item['author-id'],
'network' => $item['author-network'], 'url' => $item['author-link']];
$url = Contact::magicLinkbyContact($author);
$url = Contact::magicLinkByContact($author);
if (strpos($url, 'redir/') === 0) {
$sparkle = ' class="sparkle" ';
}
@ -985,11 +1011,13 @@ function builtin_activity_puller($item, &$conv_responses) {
/**
* Format the vote text for a profile item
* @param int $cnt = number of people who vote the item
* @param array $arr = array of pre-linked names of likers/dislikers
*
* @param int $cnt = number of people who vote the item
* @param array $arr = array of pre-linked names of likers/dislikers
* @param string $type = one of 'like, 'dislike', 'attendyes', 'attendno', 'attendmaybe'
* @param int $id = item id
* @param int $id = item id
* @return string formatted text
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
function format_like($cnt, array $arr, $type, $id) {
$o = '';
@ -1022,23 +1050,19 @@ function format_like($cnt, array $arr, $type, $id) {
if ($cnt > 1) {
$total = count($arr);
if ($total >= MAX_LIKERS) {
$arr = array_slice($arr, 0, MAX_LIKERS - 1);
}
if ($total < MAX_LIKERS) {
$last = L10n::t('and') . ' ' . $arr[count($arr)-1];
$arr2 = array_slice($arr, 0, -1);
$str = implode(', ', $arr2) . ' ' . $last;
$likers = implode(', ', $arr2) . ' ' . $last;
} else {
$arr = array_slice($arr, 0, MAX_LIKERS - 1);
$likers = implode(', ', $arr);
$likers .= L10n::t('and %d other people', $total - MAX_LIKERS);
}
if ($total >= MAX_LIKERS) {
$str = implode(', ', $arr);
$str .= L10n::t('and %d other people', $total - MAX_LIKERS);
}
$likers = $str;
$spanatts = "class=\"fakelink\" onclick=\"openClose('{$type}list-$id');\"";
$explikers = '';
switch ($type) {
case 'like':
$phrase = L10n::t('<span %1$s>%2$d people</span> like this', $spanatts, $cnt);
@ -1062,10 +1086,9 @@ function format_like($cnt, array $arr, $type, $id) {
break;
}
$expanded .= "\t" . '<div class="wall-item-' . $type . '-expanded" id="' . $type . 'list-' . $id . '" style="display: none;" >' . $explikers . EOL . '</div>';
$expanded .= "\t" . '<p class="wall-item-' . $type . '-expanded" id="' . $type . 'list-' . $id . '" style="display: none;" >' . $explikers . EOL . '</p>';
}
$phrase .= EOL;
$o .= Renderer::replaceMacros(Renderer::getMarkupTemplate('voting_fakelink.tpl'), [
'$phrase' => $phrase,
'$type' => $type,
@ -1097,7 +1120,7 @@ function status_editor(App $a, $x, $notes_cid = 0, $popup = false)
]);
$jotplugins = '';
Addon::callHooks('jot_tool', $jotplugins);
Hook::callAll('jot_tool', $jotplugins);
// Private/public post links for the non-JS ACL form
$private_post = 1;
@ -1199,8 +1222,8 @@ function status_editor(App $a, $x, $notes_cid = 0, $popup = false)
*
* @param array $item_list
* @param array $parent
* @param bool $recursive
* @return type
* @param bool $recursive
* @return array
*/
function get_item_children(array &$item_list, array $parent, $recursive = true)
{
@ -1330,6 +1353,7 @@ function smart_flatten_conversation(array $parent)
* @param array $item_list A list of items belonging to one or more conversations
* @param string $order Either on "created" or "commented"
* @return array
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
function conv_sort(array $item_list, $order)
{
@ -1425,7 +1449,7 @@ function sort_thr_created_rev(array $a, array $b)
*
* @param array $a
* @param array $b
* @return type
* @return int
*/
function sort_thr_commented(array $a, array $b)
{
@ -1442,7 +1466,7 @@ function render_location_dummy(array $item) {
}
}
function get_responses(array $conv_responses, array $response_verbs, $ob, array $item) {
function get_responses(array $conv_responses, array $response_verbs, array $item, Post $ob = null) {
$ret = [];
foreach ($response_verbs as $v) {
$ret[$v] = [];
@ -1473,6 +1497,7 @@ function get_responses(array $conv_responses, array $response_verbs, $ob, array
function get_response_button_text($v, $count)
{
$return = '';
switch ($v) {
case 'like':
$return = L10n::tt('Like', 'Likes', $count);

View File

@ -9,8 +9,9 @@ use Friendica\Database\DBA;
* DBA::select, DBA::exists, DBA::insert
* DBA::delete, DBA::update, DBA::p, DBA::e
*
* @param $args Query parameters (1 to N parameters of different types)
* @param $sql
* @return array|bool Query array
* @throws Exception
* @deprecated
*/
function q($sql) {

View File

@ -4,15 +4,15 @@
*/
use Friendica\Content\Text\BBCode;
use Friendica\Core\Addon;
use Friendica\Core\Config;
use Friendica\Core\Hook;
use Friendica\Core\L10n;
use Friendica\Core\Logger;
use Friendica\Core\Renderer;
use Friendica\Core\System;
use Friendica\Database\DBA;
use Friendica\Model\Contact;
use Friendica\Model\Item;
use Friendica\Model\User;
use Friendica\Util\DateTimeFormat;
use Friendica\Util\Emailer;
use Friendica\Util\Strings;
@ -21,18 +21,20 @@ use Friendica\Util\Strings;
* @brief Creates a notification entry and possibly sends a mail
*
* @param array $params Array with the elements:
* uid, item, parent, type, otype, verb, event,
* link, subject, body, to_name, to_email, source_name,
* source_link, activity, preamble, notify_flags,
* language, show_in_notification_page
* uid, item, parent, type, otype, verb, event,
* link, subject, body, to_name, to_email, source_name,
* source_link, activity, preamble, notify_flags,
* language, show_in_notification_page
* @return bool
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
function notification($params)
{
$a = \get_app();
// Temporary logging for finding the origin
if (!isset($params['language']) || !isset($params['uid'])) {
Logger::log('Missing parameters.' . System::callstack());
if (!isset($params['uid'])) {
Logger::notice('Missing parameters "uid".', ['params' => $params, 'callstack' => System::callstack()]);
}
// Ensure that the important fields are set at any time
@ -40,8 +42,8 @@ function notification($params)
$user = DBA::selectFirst('user', $fields, ['uid' => $params['uid']]);
if (!DBA::isResult($user)) {
Logger::log('Unknown user ' . $params['uid']);
return;
Logger::error('Unknown user', ['uid' => $params['uid']]);
return false;
}
$params['notify_flags'] = defaults($params, 'notify_flags', $user['notify-flags']);
@ -76,8 +78,8 @@ function notification($params)
['uid' => $params['uid']]);
// There is no need to create notifications for forum accounts
if (!DBA::isResult($user) || in_array($user["page-flags"], [Contact::PAGE_COMMUNITY, Contact::PAGE_PRVGROUP])) {
return;
if (!DBA::isResult($user) || in_array($user["page-flags"], [User::PAGE_FLAGS_COMMUNITY, User::PAGE_FLAGS_PRVGROUP])) {
return false;
}
$nickname = $user["nickname"];
} else {
@ -118,6 +120,12 @@ function notification($params)
}
$epreamble = '';
$preamble = '';
$subject = '';
$sitelink = '';
$tsitelink = '';
$hsitelink = '';
$itemlink = '';
if ($params['type'] == NOTIFY_MAIL) {
$itemlink = $siteurl.'/message/'.$params['item']['id'];
@ -126,19 +134,19 @@ function notification($params)
$subject = L10n::t('[Friendica:Notify] New mail received at %s', $sitename);
$preamble = L10n::t('%1$s sent you a new private message at %2$s.', $params['source_name'], $sitename);
$epreamble = L10n::t('%1$s sent you %2$s.', '[url='.$params['source_link'].']'.$params['source_name'].'[/url]', '[url=$itemlink]'.L10n::t('a private message').'[/url]');
$epreamble = L10n::t('%1$s sent you %2$s.', '[url='.$params['source_link'].']'.$params['source_name'].'[/url]', '[url=' . $itemlink . ']'.L10n::t('a private message').'[/url]');
$sitelink = L10n::t('Please visit %s to view and/or reply to your private messages.');
$tsitelink = sprintf($sitelink, $siteurl.'/message/'.$params['item']['id']);
$hsitelink = sprintf($sitelink, '<a href="'.$siteurl.'/message/'.$params['item']['id'].'">'.$sitename.'</a>');
}
if ($params['type'] == NOTIFY_COMMENT) {
$thread = Item::selectFirstThreadForUser($params['uid'] ,['ignored'], ['iid' => $parent_id]);
if (DBA::isResult($thread) && $thread["ignored"]) {
Logger::log("Thread ".$parent_id." will be ignored", Logger::DEBUG);
if ($params['type'] == NOTIFY_COMMENT || $params['type'] == NOTIFY_TAGSELF) {
$thread = Item::selectFirstThreadForUser($params['uid'], ['ignored'], ['iid' => $parent_id]);
if (DBA::isResult($thread) && $thread['ignored']) {
Logger::log('Thread ' . $parent_id . ' will be ignored', Logger::DEBUG);
L10n::popLang();
return;
return false;
}
// Check to see if there was already a tag notify or comment notify for this post.
@ -147,13 +155,11 @@ function notification($params)
'link' => $params['link'], 'uid' => $params['uid']];
if (DBA::exists('notify', $condition)) {
L10n::popLang();
return;
return false;
}
// if it's a post figure out who's post it is.
$item = null;
if ($params['otype'] === 'item' && $parent_id) {
$item = Item::selectFirstForUser($params['uid'], Item::ITEM_FIELDLIST, ['id' => $parent_id]);
}
@ -162,44 +168,92 @@ function notification($params)
$itemlink = $item['plink'];
// "a post"
$dest_str = L10n::t('%1$s commented on [url=%2$s]a %3$s[/url]',
'[url='.$params['source_link'].']'.$params['source_name'].'[/url]',
$itemlink,
$item_post_type
);
// "George Bull's post"
if ($item) {
$dest_str = L10n::t('%1$s commented on [url=%2$s]%3$s\'s %4$s[/url]',
'[url='.$params['source_link'].']'.$params['source_name'].'[/url]',
if ($params['type'] == NOTIFY_TAGSELF) {
$dest_str = L10n::t('%1$s tagged you on [url=%2$s]a %3$s[/url]',
'[url=' . $params['source_link'] . ']' . $params['source_name'] . '[/url]',
$itemlink,
$item['author-name'],
$item_post_type
);
} else {
$dest_str = L10n::t('%1$s commented on [url=%2$s]a %3$s[/url]',
'[url=' . $params['source_link'] . ']' . $params['source_name'] . '[/url]',
$itemlink,
$item_post_type
);
}
// "George Bull's post"
if (DBA::isResult($item)) {
if ($params['type'] == NOTIFY_TAGSELF) {
$dest_str = L10n::t('%1$s tagged you on [url=%2$s]%3$s\'s %4$s[/url]',
'[url=' . $params['source_link'] . ']' . $params['source_name'] . '[/url]',
$itemlink,
$item['author-name'],
$item_post_type
);
} else {
$dest_str = L10n::t('%1$s commented on [url=%2$s]%3$s\'s %4$s[/url]',
'[url=' . $params['source_link'] . ']' . $params['source_name'] . '[/url]',
$itemlink,
$item['author-name'],
$item_post_type
);
}
}
// "your post"
if (DBA::isResult($item) && $item['owner-id'] == $item['author-id'] && $item['wall']) {
$dest_str = L10n::t('%1$s commented on [url=%2$s]your %3$s[/url]',
'[url='.$params['source_link'].']'.$params['source_name'].'[/url]',
$itemlink,
$item_post_type
);
if ($params['type'] == NOTIFY_TAGSELF) {
$dest_str = L10n::t('%1$s tagged you on [url=%2$s]your %3$s[/url]',
'[url=' . $params['source_link'] . ']' . $params['source_name'] . '[/url]',
$itemlink,
$item_post_type
);
} else {
$dest_str = L10n::t('%1$s commented on [url=%2$s]your %3$s[/url]',
'[url=' . $params['source_link'] . ']' . $params['source_name'] . '[/url]',
$itemlink,
$item_post_type
);
}
}
// Some mail softwares relies on subject field for threading.
// "their post"
if (DBA::isResult($item) && $item['author-link'] == $params['source_link']) {
if ($params['type'] == NOTIFY_TAGSELF) {
$dest_str = L10n::t('%1$s tagged you on [url=%2$s]their %3$s[/url]',
'[url=' . $params['source_link'] . ']' . $params['source_name'] . '[/url]',
$itemlink,
$item_post_type
);
} else {
$dest_str = L10n::t('%1$s commented on [url=%2$s]their %3$s[/url]',
'[url=' . $params['source_link'] . ']' . $params['source_name'] . '[/url]',
$itemlink,
$item_post_type
);
}
}
// Some mail software relies on subject field for threading.
// So, we cannot have different subjects for notifications of the same thread.
// Before this we have the name of the replier on the subject rendering
// differents subjects for messages on the same thread.
// different subjects for messages on the same thread.
if ($params['type'] == NOTIFY_TAGSELF) {
$subject = L10n::t('[Friendica:Notify] %s tagged you', $params['source_name']);
$subject = L10n::t('[Friendica:Notify] Comment to conversation #%1$d by %2$s', $parent_id, $params['source_name']);
$preamble = L10n::t('%1$s tagged you at %2$s', $params['source_name'], $sitename);
} else {
$subject = L10n::t('[Friendica:Notify] Comment to conversation #%1$d by %2$s', $parent_id, $params['source_name']);
$preamble = L10n::t('%s commented on an item/conversation you have been following.', $params['source_name']);
}
$preamble = L10n::t('%s commented on an item/conversation you have been following.', $params['source_name']);
$epreamble = $dest_str;
$sitelink = L10n::t('Please visit %s to view and/or reply to the conversation.');
$tsitelink = sprintf($sitelink, $siteurl);
$hsitelink = sprintf($sitelink, '<a href="'.$siteurl.'">'.$sitename.'</a>');
$hsitelink = sprintf($sitelink, '<a href="' . $siteurl . '">' . $sitename . '</a>');
$itemlink = $params['link'];
}
@ -218,21 +272,6 @@ function notification($params)
$itemlink = $params['link'];
}
if ($params['type'] == NOTIFY_TAGSELF) {
$subject = L10n::t('[Friendica:Notify] %s tagged you', $params['source_name']);
$preamble = L10n::t('%1$s tagged you at %2$s', $params['source_name'], $sitename);
$epreamble = L10n::t('%1$s [url=%2$s]tagged you[/url].',
'[url='.$params['source_link'].']'.$params['source_name'].'[/url]',
$params['link']
);
$sitelink = L10n::t('Please visit %s to view and/or reply to the conversation.');
$tsitelink = sprintf($sitelink, $siteurl);
$hsitelink = sprintf($sitelink, '<a href="'.$siteurl.'">'.$sitename.'</a>');
$itemlink = $params['link'];
}
if ($params['type'] == NOTIFY_SHARE) {
$subject = L10n::t('[Friendica:Notify] %s shared a new post', $params['source_name']);
@ -414,16 +453,21 @@ function notification($params)
// It will be used by the system to send emails to users (like
// password reset, invitations and so) using one look (but without
// add a notification to the user, with could be inexistent)
$subject = $params['subject'];
if (!isset($params['subject'])) {
Logger::warning('subject isn\'t set.', ['type' => $params['type']]);
}
$subject = defaults($params, 'subject', '');
$preamble = $params['preamble'];
if (!isset($params['preamble'])) {
Logger::warning('preamble isn\'t set.', ['type' => $params['type'], 'subject' => $subject]);
}
$preamble = defaults($params, 'preamble', '');
$body = $params['body'];
if (!isset($params['body'])) {
Logger::warning('body isn\'t set.', ['type' => $params['type'], 'subject' => $subject, 'preamble' => $preamble]);
}
$body = defaults($params, 'body', '');
$sitelink = "";
$tsitelink = "";
$hsitelink = "";
$itemlink = "";
$show_in_notification_page = false;
}
@ -441,7 +485,7 @@ function notification($params)
'itemlink' => $itemlink
];
Addon::callHooks('enotify', $h);
Hook::callAll('enotify', $h);
$subject = $h['subject'];
@ -454,6 +498,8 @@ function notification($params)
$hsitelink = $h['hsitelink'];
$itemlink = $h['itemlink'];
$notify_id = 0;
if ($show_in_notification_page) {
Logger::log("adding notification entry", Logger::DEBUG);
do {
@ -481,11 +527,11 @@ function notification($params)
$datarray['otype'] = $params['otype'];
$datarray['abort'] = false;
Addon::callHooks('enotify_store', $datarray);
Hook::callAll('enotify_store', $datarray);
if ($datarray['abort']) {
L10n::popLang();
return False;
return false;
}
// create notification entry in DB
@ -584,7 +630,7 @@ function notification($params)
$datarray['subject'] = $subject;
$datarray['headers'] = $additional_mail_header;
Addon::callHooks('enotify_mail', $datarray);
Hook::callAll('enotify_mail', $datarray);
// check whether sending post content in email notifications is allowed
// always true for SYSTEM_EMAIL
@ -634,8 +680,7 @@ function notification($params)
L10n::popLang();
// use the Emailer class to send the message
return Emailer::send(
[
return Emailer::send([
'uid' => $params['uid'],
'fromName' => $sender_name,
'fromEmail' => $sender_email,
@ -644,8 +689,8 @@ function notification($params)
'messageSubject' => $datarray['subject'],
'htmlVersion' => $email_html_body,
'textVersion' => $email_text_body,
'additionalMailHeader' => $datarray['headers']]
);
'additionalMailHeader' => $datarray['headers']
]);
}
L10n::popLang();
@ -656,6 +701,7 @@ function notification($params)
* @brief Checks for users who should be notified
*
* @param int $itemid ID of the item for which the check should be done
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
function check_user_notification($itemid) {
// fetch all users in the thread
@ -671,13 +717,15 @@ function check_user_notification($itemid) {
/**
* @brief Checks for item related notifications and sends them
*
* @param int $itemid ID of the item for which the check should be done
* @param int $uid User ID
* @param int $itemid ID of the item for which the check should be done
* @param int $uid User ID
* @param string $defaulttype (Optional) Forces a notification with this type.
* @return bool
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
function check_item_notification($itemid, $uid, $defaulttype = "") {
$notification_data = ["uid" => $uid, "profiles" => []];
Addon::callHooks('check_item_notification', $notification_data);
Hook::callAll('check_item_notification', $notification_data);
$profiles = $notification_data["profiles"];
@ -736,9 +784,9 @@ function check_item_notification($itemid, $uid, $defaulttype = "") {
'author-link', 'author-name', 'author-avatar', 'author-id',
'guid', 'parent-uri', 'uri', 'contact-id', 'network'];
$condition = ['id' => $itemid, 'gravity' => [GRAVITY_PARENT, GRAVITY_COMMENT]];
$item = Item::selectFirst($fields, $condition);
$item = Item::selectFirstForUser($uid, $fields, $condition);
if (!DBA::isResult($item) || in_array($item['author-id'], $contacts)) {
return;
return false;
}
// Generate the notification array

View File

@ -5,8 +5,8 @@
use Friendica\BaseObject;
use Friendica\Content\Feature;
use Friendica\Core\Addon;
use Friendica\Core\Config;
use Friendica\Core\Hook;
use Friendica\Core\L10n;
use Friendica\Core\Logger;
use Friendica\Core\PConfig;
@ -24,10 +24,11 @@ use Friendica\Util\ParseUrl;
use Friendica\Util\Strings;
use Friendica\Util\Temporal;
require_once 'mod/share.php';
require_once __DIR__ . '/../mod/share.php';
function add_page_info_data(array $data, $no_photos = false)
{
Addon::callHooks('page_info_data', $data);
Hook::callAll('page_info_data', $data);
if (empty($data['type'])) {
return '';
@ -242,26 +243,26 @@ function add_page_info_to_body($body, $texturl = false, $no_photos = false)
* model where comments can have sub-threads. That would require some massive sorting
* to get all the feed items into a mostly linear ordering, and might still require
* recursion.
*
* @param $xml
* @param array $importer
* @param array $contact
* @param $hub
* @throws ImagickException
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
function consume_feed($xml, array $importer, array $contact, &$hub, $datedir = 0, $pass = 0)
function consume_feed($xml, array $importer, array $contact, &$hub)
{
if ($contact['network'] === Protocol::OSTATUS) {
if ($pass < 2) {
// Test - remove before flight
//$tempfile = tempnam(get_temppath(), "ostatus2");
//file_put_contents($tempfile, $xml);
Logger::log("Consume OStatus messages ", Logger::DEBUG);
OStatus::import($xml, $importer, $contact, $hub);
}
Logger::log("Consume OStatus messages ", Logger::DEBUG);
OStatus::import($xml, $importer, $contact, $hub);
return;
}
if ($contact['network'] === Protocol::FEED) {
if ($pass < 2) {
Logger::log("Consume feeds", Logger::DEBUG);
Feed::import($xml, $importer, $contact, $hub);
}
Logger::log("Consume feeds", Logger::DEBUG);
Feed::import($xml, $importer, $contact, $hub);
return;
}
@ -293,8 +294,6 @@ function subscribe_to_hub($url, array $importer, array $contact, $hubmode = 'sub
return;
}
$a = BaseObject::getApp();
$user = DBA::selectFirst('user', ['nickname'], ['uid' => $importer['uid']]);
// No user, no nickname, we quit

View File

@ -4,31 +4,14 @@
*/
use Friendica\App;
use Friendica\Content\ContactSelector;
use Friendica\Content\Feature;
use Friendica\Content\Smilies;
use Friendica\Content\Text\BBCode;
use Friendica\Core\Addon;
use Friendica\Core\Config;
use Friendica\Core\L10n;
use Friendica\Core\PConfig;
use Friendica\Core\Protocol;
use Friendica\Core\System;
use Friendica\Database\DBA;
use Friendica\Model\Contact;
use Friendica\Model\Event;
use Friendica\Model\Item;
use Friendica\Render\FriendicaSmarty;
use Friendica\Util\DateTimeFormat;
use Friendica\Util\Map;
use Friendica\Util\Proxy as ProxyUtils;
use Friendica\Core\Logger;
use Friendica\Core\Renderer;
use Friendica\Model\FileTag;
use Friendica\Util\Strings;
use Friendica\Util\XML;
use Friendica\Content\Text\HTML;
/**
* Turn user/group ACLs stored as angle bracketed text into arrays
@ -139,7 +122,7 @@ function qp($s) {
*/
function redir_private_images($a, &$item)
{
$matches = false;
$matches = [];
$cnt = preg_match_all('|\[img\](http[^\[]*?/photo/[a-fA-F0-9]+?(-[0-9]\.[\w]+?)?)\[\/img\]|', $item['body'], $matches, PREG_SET_ORDER);
if ($cnt) {
foreach ($matches as $mtch) {
@ -160,6 +143,7 @@ function redir_private_images($a, &$item)
*
* @param string $text String with bbcode.
* @return string Formattet HTML.
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
function prepare_text($text) {
if (stristr($text, '[nosmile]')) {
@ -203,7 +187,7 @@ function get_cats_and_terms($item)
$categories = [];
$folders = [];
$matches = false;
$matches = [];
$first = true;
$cnt = preg_match_all('/<(.*?)>/', $item['file'], $matches, PREG_SET_ORDER);
if ($cnt) {
@ -224,7 +208,7 @@ function get_cats_and_terms($item)
}
if (local_user() == $item['uid']) {
$matches = false;
$matches = [];
$first = true;
$cnt = preg_match_all('/\[(.*?)\]/', $item['file'], $matches, PREG_SET_ORDER);
if ($cnt) {
@ -251,7 +235,7 @@ function get_cats_and_terms($item)
/**
* return number of bytes in size (K, M, G)
* @param string $size_str
* @return number
* @return int
*/
function return_bytes($size_str) {
switch (substr ($size_str, -1)) {

View File

@ -4,14 +4,15 @@
* Friendica
*/
use Friendica\Factory;
if (!file_exists(__DIR__ . '/vendor/autoload.php')) {
die('Vendor path not found. Please execute "bin/composer.phar --no-dev install" on the command line in the web root.');
}
require __DIR__ . '/vendor/autoload.php';
// We assume that the index.php is called by a frontend process
// The value is set to "true" by default in App
$a = new Friendica\App(__DIR__, false);
$a = Factory\DependencyFactory::setUp('index', __DIR__, false);
$a->runFrontend();

View File

@ -91,7 +91,6 @@ abstract class OAuthSignatureMethod {
*/
public function check_signature($request, $consumer, $token, $signature) {
$built = $this->build_signature($request, $consumer, $token);
//echo "<pre>"; var_dump($signature, $built, ($built == $signature)); killme();
return ($built == $signature);
}
}
@ -296,7 +295,6 @@ class OAuthRequest {
$http_url = substr($http_url, 0, strpos($http_url,$parameters['pagename'])+strlen($parameters['pagename']));
unset( $parameters['pagename'] );
//echo "<pre>".__function__."\n"; var_dump($http_method, $http_url, $parameters, $_SERVER['REQUEST_URI']); killme();
return new OAuthRequest($http_method, $http_url, $parameters);
}
@ -561,7 +559,6 @@ class OAuthServer {
public function verify_request(&$request) {
$this->get_version($request);
$consumer = $this->get_consumer($request);
//echo __file__.__line__.__function__."<pre>"; var_dump($consumer); die();
$token = $this->get_token($request, $consumer, "access");
$this->check_signature($request, $consumer, $token);
return array($consumer, $token);

View File

@ -27,7 +27,6 @@ function _well_known_init(App $a)
}
}
System::httpExit(404);
killme();
}
function wk_social_relay()

View File

@ -5,7 +5,7 @@
use Friendica\App;
use Friendica\Content\Widget;
use Friendica\Core\ACL;
use Friendica\Core\Addon;
use Friendica\Core\Hook;
use Friendica\Core\Logger;
use Friendica\Core\Protocol;
use Friendica\Database\DBA;
@ -34,7 +34,7 @@ function acl_content(App $a)
$search = $_REQUEST['query'];
}
Logger::log("Searching for ".$search." - type ".$type." conversation ".$conv_id, Logger::DEBUG);
Logger::info('ACL {action} - {subaction}', ['module' => 'acl', 'action' => 'content', 'subaction' => 'search', 'search' => $search, 'type' => $type, 'conversation' => $conv_id]);
if ($search != '') {
$sql_extra = "AND `name` LIKE '%%" . DBA::escape($search) . "%%'";
@ -305,7 +305,7 @@ function acl_content(App $a)
'search' => $search,
];
Addon::callHooks('acl_lookup_end', $results);
Hook::callAll('acl_lookup_end', $results);
$o = [
'tot' => $results['tot'],

View File

@ -15,6 +15,7 @@ use Friendica\Core\Config;
use Friendica\Core\L10n;
use Friendica\Core\Logger;
use Friendica\Core\Renderer;
use Friendica\Core\StorageManager;
use Friendica\Core\System;
use Friendica\Core\Theme;
use Friendica\Core\Update;
@ -25,13 +26,17 @@ use Friendica\Model\Contact;
use Friendica\Model\Item;
use Friendica\Model\Register;
use Friendica\Model\User;
use Friendica\Module;
use Friendica\Module\Login;
use Friendica\Module\Tos;
use Friendica\Protocol\PortableContact;
use Friendica\Util\Arrays;
use Friendica\Util\BasePath;
use Friendica\Util\DateTimeFormat;
use Friendica\Util\Network;
use Friendica\Util\Strings;
use Friendica\Util\Temporal;
use Psr\Log\LogLevel;
/**
* Sets the current theme for theme settings pages.
@ -61,7 +66,8 @@ function admin_init(App $a)
* return the HTML for the pages of the admin panel.
*
* @param App $a
*
* @throws ImagickException
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
function admin_post(App $a)
{
@ -160,6 +166,7 @@ function admin_post(App $a)
*
* @param App $a
* @return string
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
function admin_content(App $a)
{
@ -300,8 +307,7 @@ function admin_content(App $a)
if ($a->isAjax()) {
echo $o;
killme();
return '';
exit();
} else {
return $o;
}
@ -312,6 +318,7 @@ function admin_content(App $a)
*
* @param App $a
* @return string
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
function admin_page_tos(App $a)
{
@ -334,6 +341,7 @@ function admin_page_tos(App $a)
* @brief Process send data from Admin TOS Page
*
* @param App $a
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
function admin_page_tos_post(App $a)
{
@ -366,6 +374,7 @@ function admin_page_tos_post(App $a)
*
* @param App $a
* @return string
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
function admin_page_blocklist(App $a)
{
@ -406,6 +415,7 @@ function admin_page_blocklist(App $a)
* @brief Process send data from Admin Blocklist Page
*
* @param App $a
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
function admin_page_blocklist_post(App $a)
{
@ -450,6 +460,8 @@ function admin_page_blocklist_post(App $a)
* @brief Process data send by the contact block admin page
*
* @param App $a
* @throws ImagickException
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
function admin_page_contactblock_post(App $a)
{
@ -482,6 +494,7 @@ function admin_page_contactblock_post(App $a)
*
* @param App $a
* @return string
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
function admin_page_contactblock(App $a)
{
@ -534,6 +547,7 @@ function admin_page_contactblock(App $a)
*
* @param App $a
* @return string
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
function admin_page_deleteitem(App $a)
{
@ -558,6 +572,7 @@ function admin_page_deleteitem(App $a)
* URLs like the full /display URL to make the process more easy for the admin.
*
* @param App $a
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
function admin_page_deleteitem_post(App $a)
{
@ -597,6 +612,7 @@ function admin_page_deleteitem_post(App $a)
*
* @param App $a
* @return string
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
function admin_page_federation(App $a)
{
@ -783,6 +799,7 @@ function admin_page_federation(App $a)
*
* @param App $a
* @return string
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
function admin_page_queue(App $a)
{
@ -825,7 +842,9 @@ function admin_page_queue(App $a)
* The returned string holds the content of the page.
*
* @param App $a
* @param $deferred
* @return string
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
function admin_page_workerqueue(App $a, $deferred)
{
@ -875,6 +894,7 @@ function admin_page_workerqueue(App $a, $deferred)
*
* @param App $a
* @return string
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
function admin_page_summary(App $a)
{
@ -897,7 +917,7 @@ function admin_page_summary(App $a)
}
if (Config::get('system', 'dbupdate', DBStructure::UPDATE_NOT_CHECKED) == DBStructure::UPDATE_NOT_CHECKED) {
DBStructure::update(false, true);
DBStructure::update($a->getBasePath(), false, true);
}
if (Config::get('system', 'dbupdate') == DBStructure::UPDATE_FAILED) {
$showwarning = true;
@ -918,6 +938,10 @@ function admin_page_summary(App $a)
$showwarning = true;
$warningtext[] = L10n::t('Friendica\'s configuration now is stored in config/local.config.php, please copy config/local-sample.config.php and move your config from <code>.htconfig.php</code>. See <a href="%s">the Config help page</a> for help with the transition.', $a->getBaseURL() . '/help/Config');
}
if (file_exists('config/local.ini.php')) {
$showwarning = true;
$warningtext[] = L10n::t('Friendica\'s configuration now is stored in config/local.config.php, please copy config/local-sample.config.php and move your config from <code>config/local.ini.php</code>. See <a href="%s">the Config help page</a> for help with the transition.', $a->getBaseURL() . '/help/Config');
}
// Check server vitality
if (!admin_page_server_vital()) {
@ -993,6 +1017,7 @@ function admin_page_summary(App $a)
* @brief Process send data from Admin Site Page
*
* @param App $a
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
function admin_page_site_post(App $a)
{
@ -1085,7 +1110,7 @@ function admin_page_site_post(App $a)
$banner = (!empty($_POST['banner']) ? trim($_POST['banner']) : false);
$shortcut_icon = (!empty($_POST['shortcut_icon']) ? Strings::escapeTags(trim($_POST['shortcut_icon'])) : '');
$touch_icon = (!empty($_POST['touch_icon']) ? Strings::escapeTags(trim($_POST['touch_icon'])) : '');
$info = (!empty($_POST['info']) ? trim($_POST['info']) : false);
$additional_info = (!empty($_POST['additional_info']) ? trim($_POST['additional_info']) : '');
$language = (!empty($_POST['language']) ? Strings::escapeTags(trim($_POST['language'])) : '');
$theme = (!empty($_POST['theme']) ? Strings::escapeTags(trim($_POST['theme'])) : '');
$theme_mobile = (!empty($_POST['theme_mobile']) ? Strings::escapeTags(trim($_POST['theme_mobile'])) : '');
@ -1124,14 +1149,14 @@ function admin_page_site_post(App $a)
$proxyuser = (!empty($_POST['proxyuser']) ? Strings::escapeTags(trim($_POST['proxyuser'])) : '');
$proxy = (!empty($_POST['proxy']) ? Strings::escapeTags(trim($_POST['proxy'])) : '');
$timeout = (!empty($_POST['timeout']) ? intval(trim($_POST['timeout'])) : 60);
$maxloadavg = (!empty($_POST['maxloadavg']) ? intval(trim($_POST['maxloadavg'])) : 50);
$maxloadavg = (!empty($_POST['maxloadavg']) ? intval(trim($_POST['maxloadavg'])) : 20);
$maxloadavg_frontend = (!empty($_POST['maxloadavg_frontend']) ? intval(trim($_POST['maxloadavg_frontend'])) : 50);
$min_memory = (!empty($_POST['min_memory']) ? intval(trim($_POST['min_memory'])) : 0);
$optimize_max_tablesize = (!empty($_POST['optimize_max_tablesize']) ? intval(trim($_POST['optimize_max_tablesize'])) : 100);
$optimize_fragmentation = (!empty($_POST['optimize_fragmentation']) ? intval(trim($_POST['optimize_fragmentation'])) : 30);
$poco_completion = (!empty($_POST['poco_completion']) ? intval(trim($_POST['poco_completion'])) : false);
$poco_requery_days = (!empty($_POST['poco_requery_days']) ? intval(trim($_POST['poco_requery_days'])) : 7);
$poco_discovery = (!empty($_POST['poco_discovery']) ? intval(trim($_POST['poco_discovery'])) : 0);
$poco_discovery = (!empty($_POST['poco_discovery']) ? intval(trim($_POST['poco_discovery'])) : PortableContact::DISABLED);
$poco_discovery_since = (!empty($_POST['poco_discovery_since']) ? intval(trim($_POST['poco_discovery_since'])) : 30);
$poco_local_search = !empty($_POST['poco_local_search']);
$nodeinfo = !empty($_POST['nodeinfo']);
@ -1171,6 +1196,45 @@ function admin_page_site_post(App $a)
$relay_user_tags = !empty($_POST['relay_user_tags']);
$active_panel = (!empty($_POST['active_panel']) ? "#" . Strings::escapeTags(trim($_POST['active_panel'])) : '');
/**
* @var $storagebackend \Friendica\Model\Storage\IStorage
*/
$storagebackend = Strings::escapeTags(trim(defaults($_POST, 'storagebackend', '')));
if (!StorageManager::setBackend($storagebackend)) {
info(L10n::t('Invalid storage backend setting value.'));
}
// save storage backend form
if (!is_null($storagebackend) && $storagebackend != "") {
$storage_opts = $storagebackend::getOptions();
$storage_form_prefix=preg_replace('|[^a-zA-Z0-9]|' ,'', $storagebackend);
$storage_opts_data = [];
foreach($storage_opts as $name => $info) {
$fieldname = $storage_form_prefix . '_' . $name;
switch ($info[0]) { // type
case 'checkbox':
case 'yesno':
$value = !empty($_POST[$fieldname]);
break;
default:
$value = defaults($_POST, $fieldname, '');
}
$storage_opts_data[$name] = $value;
}
unset($name);
unset($info);
$storage_form_errors = $storagebackend::saveOptions($storage_opts_data);
if (count($storage_form_errors)) {
foreach($storage_form_errors as $name => $err) {
notice('Storage backend, ' . $storage_opts[$name][1] . ': ' . $err);
}
$a->internalRedirect('admin/site' . $active_panel);
}
}
// Has the directory url changed? If yes, then resubmit the existing profiles there
if ($global_directory != Config::get('system', 'directory') && ($global_directory != '')) {
Config::set('system', 'directory', $global_directory);
@ -1244,10 +1308,10 @@ function admin_page_site_post(App $a)
Config::set('system', 'banner', $banner);
}
if ($info == "") {
if (empty($additional_info)) {
Config::delete('config', 'info');
} else {
Config::set('config', 'info', $info);
Config::set('config', 'info', $additional_info);
}
Config::set('system', 'language', $language);
Config::set('system', 'theme', $theme);
@ -1315,7 +1379,7 @@ function admin_page_site_post(App $a)
Config::set('system', 'dbclean-expire-unclaimed', $dbclean_unclaimed);
if ($itemcache != '') {
$itemcache = App::getRealPath($itemcache);
$itemcache = BasePath::getRealPath($itemcache);
}
Config::set('system', 'itemcache', $itemcache);
@ -1323,13 +1387,13 @@ function admin_page_site_post(App $a)
Config::set('system', 'max_comments', $max_comments);
if ($temppath != '') {
$temppath = App::getRealPath($temppath);
$temppath = BasePath::getRealPath($temppath);
}
Config::set('system', 'temppath', $temppath);
if ($basepath != '') {
$basepath = App::getRealPath($basepath);
$basepath = BasePath::getRealPath($basepath);
}
Config::set('system', 'basepath' , $basepath);
@ -1363,6 +1427,7 @@ function admin_page_site_post(App $a)
*
* @param App $a
* @return string
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
function admin_page_site(App $a)
{
@ -1415,10 +1480,10 @@ function admin_page_site(App $a)
];
$poco_discovery_choices = [
"0" => L10n::t("Disabled"),
"1" => L10n::t("Users"),
"2" => L10n::t("Users, Global Contacts"),
"3" => L10n::t("Users, Global Contacts/fallback"),
PortableContact::DISABLED => L10n::t("Disabled"),
PortableContact::USERS => L10n::t("Users"),
PortableContact::USERS_GCONTACTS => L10n::t("Users, Global Contacts"),
PortableContact::USERS_GCONTACTS_FALLBACK => L10n::t("Users, Global Contacts/fallback"),
];
$poco_discovery_since_choices = [
@ -1444,7 +1509,7 @@ function admin_page_site(App $a)
$banner = '<a href="https://friendi.ca"><img id="logo-img" src="images/friendica-32.png" alt="logo" /></a><span id="logo-text"><a href="https://friendi.ca">Friendica</a></span>';
}
$info = Config::get('config', 'info');
$additional_info = Config::get('config', 'info');
// Automatically create temporary paths
get_temppath();
@ -1454,9 +1519,9 @@ function admin_page_site(App $a)
/* Register policy */
$register_choices = [
REGISTER_CLOSED => L10n::t("Closed"),
REGISTER_APPROVE => L10n::t("Requires approval"),
REGISTER_OPEN => L10n::t("Open")
Module\Register::CLOSED => L10n::t("Closed"),
Module\Register::APPROVE => L10n::t("Requires approval"),
Module\Register::OPEN => L10n::t("Open")
];
$ssl_choices = [
@ -1482,6 +1547,36 @@ function admin_page_site(App $a)
$optimize_max_tablesize = -1;
}
/* storage backend */
$storage_backends = StorageManager::listBackends();
/**
* @var $storage_current_backend \Friendica\Model\Storage\IStorage
*/
$storage_current_backend = StorageManager::getBackend();
$storage_backends_choices = [
'' => L10n::t('Database (legacy)')
];
foreach($storage_backends as $name=>$class) {
$storage_backends_choices[$class] = $name;
}
unset($storage_backends);
// build storage config form,
$storage_form_prefix=preg_replace('|[^a-zA-Z0-9]|' ,'', $storage_current_backend);
$storage_form = [];
if (!is_null($storage_current_backend) && $storage_current_backend != "") {
foreach ($storage_current_backend::getOptions() as $name => $info) {
$type = $info[0];
$info[0] = $storage_form_prefix . '_' . $name;
$info['type'] = $type;
$info['field'] = 'field_' . $type . '.tpl';
$storage_form[$name] = $info;
}
}
$t = Renderer::getMarkupTemplate('admin/site.tpl');
return Renderer::replaceMacros($t, [
'$title' => L10n::t('Administration'),
@ -1507,7 +1602,7 @@ function admin_page_site(App $a)
'$banner' => ['banner', L10n::t("Banner/Logo"), $banner, ""],
'$shortcut_icon' => ['shortcut_icon', L10n::t("Shortcut icon"), Config::get('system', 'shortcut_icon'), L10n::t("Link to an icon that will be used for browsers.")],
'$touch_icon' => ['touch_icon', L10n::t("Touch icon"), Config::get('system', 'touch_icon'), L10n::t("Link to an icon that will be used for tablets and mobiles.")],
'$info' => ['info', L10n::t('Additional Info'), $info, L10n::t('For public servers: you can add additional information here that will be listed at %s/servers.', get_server())],
'$additional_info' => ['additional_info', L10n::t('Additional Info'), $additional_info, L10n::t('For public servers: you can add additional information here that will be listed at %s/servers.', get_server())],
'$language' => ['language', L10n::t("System language"), Config::get('system', 'language'), "", $lang_choices],
'$theme' => ['theme', L10n::t("System theme"), Config::get('system', 'theme'), L10n::t("Default system theme - may be over-ridden by user profiles - <a href='#' id='cnftheme'>change theme settings</a>"), $theme_choices],
'$theme_mobile' => ['theme_mobile', L10n::t("Mobile system theme"), Config::get('system', 'mobile-theme', '---'), L10n::t("Theme for mobile devices"), $theme_choices_mobile],
@ -1515,6 +1610,9 @@ function admin_page_site(App $a)
'$force_ssl' => ['force_ssl', L10n::t("Force SSL"), Config::get('system', 'force_ssl'), L10n::t("Force all Non-SSL requests to SSL - Attention: on some systems it could lead to endless loops.")],
'$hide_help' => ['hide_help', L10n::t("Hide help entry from navigation menu"), Config::get('system', 'hide_help'), L10n::t("Hides the menu entry for the Help pages from the navigation menu. You can still access it calling /help directly.")],
'$singleuser' => ['singleuser', L10n::t("Single user instance"), Config::get('system', 'singleuser', '---'), L10n::t("Make this instance multi-user or single-user for the named user"), $user_names],
'$storagebackend' => ['storagebackend', L10n::t("File storage backend"), $storage_current_backend, L10n::t('The backend used to store uploaded data. If you change the storage backend, you can manually move the existing files. If you do not do so, the files uploaded before the change will still be available at the old backend. Please see <a href="/help/Settings#1_2_3_1">the settings documentation</a> for more information about the choices and the moving procedure.'), $storage_backends_choices],
'$storageform' => $storage_form,
'$maximagesize' => ['maximagesize', L10n::t("Maximum image size"), Config::get('system', 'maximagesize'), L10n::t("Maximum size in bytes of uploaded images. Default is 0, which means no limits.")],
'$maximagelength' => ['maximagelength', L10n::t("Maximum image length"), Config::get('system', 'max_image_length'), L10n::t("Maximum length in pixels of the longest side of uploaded images. Default is -1, which means no limits.")],
'$jpegimagequality' => ['jpegimagequality', L10n::t("JPEG image quality"), Config::get('system', 'jpeg_quality'), L10n::t("Uploaded JPEGS will be saved at this quality setting [0-100]. Default is 100, which is full quality.")],
@ -1553,7 +1651,7 @@ function admin_page_site(App $a)
'$proxyuser' => ['proxyuser', L10n::t("Proxy user"), Config::get('system', 'proxyuser'), ""],
'$proxy' => ['proxy', L10n::t("Proxy URL"), Config::get('system', 'proxy'), ""],
'$timeout' => ['timeout', L10n::t("Network timeout"), Config::get('system', 'curl_timeout', 60), L10n::t("Value is in seconds. Set to 0 for unlimited \x28not recommended\x29.")],
'$maxloadavg' => ['maxloadavg', L10n::t("Maximum Load Average"), Config::get('system', 'maxloadavg', 50), L10n::t("Maximum system load before delivery and poll processes are deferred - default 50.")],
'$maxloadavg' => ['maxloadavg', L10n::t("Maximum Load Average"), Config::get('system', 'maxloadavg', 20), L10n::t("Maximum system load before delivery and poll processes are deferred - default %d.", 20)],
'$maxloadavg_frontend' => ['maxloadavg_frontend', L10n::t("Maximum Load Average \x28Frontend\x29"), Config::get('system', 'maxloadavg_frontend', 50), L10n::t("Maximum system load before the frontend quits service - default 50.")],
'$min_memory' => ['min_memory', L10n::t("Minimal Memory"), Config::get('system', 'min_memory', 0), L10n::t("Minimal free memory in MB for the worker. Needs access to /proc/meminfo - default 0 \x28deactivated\x29.")],
'$optimize_max_tablesize' => ['optimize_max_tablesize', L10n::t("Maximum table size for optimization"), $optimize_max_tablesize, L10n::t("Maximum table size \x28in MB\x29 for the automatic optimization. Enter -1 to disable it.")],
@ -1561,7 +1659,7 @@ function admin_page_site(App $a)
'$poco_completion' => ['poco_completion', L10n::t("Periodical check of global contacts"), Config::get('system', 'poco_completion'), L10n::t("If enabled, the global contacts are checked periodically for missing or outdated data and the vitality of the contacts and servers.")],
'$poco_requery_days' => ['poco_requery_days', L10n::t("Days between requery"), Config::get('system', 'poco_requery_days'), L10n::t("Number of days after which a server is requeried for his contacts.")],
'$poco_discovery' => ['poco_discovery', L10n::t("Discover contacts from other servers"), (string)intval(Config::get('system', 'poco_discovery')), L10n::t("Periodically query other servers for contacts. You can choose between 'users': the users on the remote system, 'Global Contacts': active contacts that are known on the system. The fallback is meant for Redmatrix servers and older friendica servers, where global contacts weren't available. The fallback increases the server load, so the recommened setting is 'Users, Global Contacts'."), $poco_discovery_choices],
'$poco_discovery' => ['poco_discovery', L10n::t("Discover contacts from other servers"), (string)intval(Config::get('system', 'poco_discovery')), L10n::t("Periodically query other servers for contacts. You can choose between 'users': the users on the remote system, 'Global Contacts': active contacts that are known on the system. The fallback is meant for Redmatrix servers and older friendica servers, where global contacts weren't available. The fallback increases the server load, so the recommended setting is 'Users, Global Contacts'."), $poco_discovery_choices],
'$poco_discovery_since' => ['poco_discovery_since', L10n::t("Timeframe for fetching global contacts"), (string)intval(Config::get('system', 'poco_discovery_since')), L10n::t("When the discovery is activated, this value defines the timeframe for the activity of the global contacts that are fetched from other servers."), $poco_discovery_since_choices],
'$poco_local_search' => ['poco_local_search', L10n::t("Search the local directory"), Config::get('system', 'poco_local_search'), L10n::t("Search the local directory instead of the global directory. When searching locally, every search will be executed on the global directory in the background. This improves the search results when the search is repeated.")],
@ -1613,7 +1711,8 @@ function admin_page_site(App $a)
*
* @param App $a
* @return string
* */
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
function admin_page_dbsync(App $a)
{
$o = '';
@ -1629,7 +1728,7 @@ function admin_page_dbsync(App $a)
}
if (($a->argc > 2) && (intval($a->argv[2]) || ($a->argv[2] === 'check'))) {
$retval = DBStructure::update(false, true);
$retval = DBStructure::update($a->getBasePath(), false, true);
if ($retval === '') {
$o .= L10n::t("Database structure update %s was successfully applied.", DB_UPDATE_VERSION) . "<br />";
Config::set('database', 'last_successful_update', DB_UPDATE_VERSION);
@ -1703,6 +1802,7 @@ function admin_page_dbsync(App $a)
* @brief Process data send by Users admin page
*
* @param App $a
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
function admin_page_users_post(App $a)
{
@ -1820,6 +1920,7 @@ function admin_page_users_post(App $a)
*
* @param App $a
* @return string
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
function admin_page_users(App $a)
{
@ -1897,17 +1998,18 @@ function admin_page_users(App $a)
$adminlist = explode(",", str_replace(" ", "", Config::get('config', 'admin_email')));
$_setup_users = function ($e) use ($adminlist) {
$page_types = [
Contact::PAGE_NORMAL => L10n::t('Normal Account Page'),
Contact::PAGE_SOAPBOX => L10n::t('Soapbox Page'),
Contact::PAGE_COMMUNITY => L10n::t('Public Forum'),
Contact::PAGE_FREELOVE => L10n::t('Automatic Friend Page'),
Contact::PAGE_PRVGROUP => L10n::t('Private Forum')
User::PAGE_FLAGS_NORMAL => L10n::t('Normal Account Page'),
User::PAGE_FLAGS_SOAPBOX => L10n::t('Soapbox Page'),
User::PAGE_FLAGS_COMMUNITY => L10n::t('Public Forum'),
User::PAGE_FLAGS_FREELOVE => L10n::t('Automatic Friend Page'),
User::PAGE_FLAGS_PRVGROUP => L10n::t('Private Forum')
];
$account_types = [
Contact::ACCOUNT_TYPE_PERSON => L10n::t('Personal Page'),
Contact::ACCOUNT_TYPE_ORGANISATION => L10n::t('Organisation Page'),
Contact::ACCOUNT_TYPE_NEWS => L10n::t('News Page'),
Contact::ACCOUNT_TYPE_COMMUNITY => L10n::t('Community Forum')
User::ACCOUNT_TYPE_PERSON => L10n::t('Personal Page'),
User::ACCOUNT_TYPE_ORGANISATION => L10n::t('Organisation Page'),
User::ACCOUNT_TYPE_NEWS => L10n::t('News Page'),
User::ACCOUNT_TYPE_COMMUNITY => L10n::t('Community Forum'),
User::ACCOUNT_TYPE_RELAY => L10n::t('Relay'),
];
$e['page_flags_raw'] = $e['page-flags'];
@ -2018,6 +2120,7 @@ function admin_page_users(App $a)
* @param App $a
* @param array $addons_admin A list of admin addon names
* @return string
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
function admin_page_addons(App $a, array $addons_admin)
{
@ -2223,6 +2326,7 @@ function rebuild_theme_table($themes)
*
* @param App $a
* @return string
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
function admin_page_themes(App $a)
{
@ -2393,6 +2497,7 @@ function admin_page_themes(App $a)
* @brief Prosesses data send by Logs admin page
*
* @param App $a
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
function admin_page_logs_post(App $a)
{
@ -2401,7 +2506,7 @@ function admin_page_logs_post(App $a)
$logfile = (!empty($_POST['logfile']) ? Strings::escapeTags(trim($_POST['logfile'])) : '');
$debugging = !empty($_POST['debugging']);
$loglevel = (!empty($_POST['loglevel']) ? intval(trim($_POST['loglevel'])) : 0);
$loglevel = defaults($_POST, 'loglevel', LogLevel::ERROR);
Config::set('system', 'logfile', $logfile);
Config::set('system', 'debugging', $debugging);
@ -2428,16 +2533,16 @@ function admin_page_logs_post(App $a)
*
* @param App $a
* @return string
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
function admin_page_logs(App $a)
{
$log_choices = [
Logger::WARNING => 'Warning',
Logger::INFO => 'Info',
Logger::TRACE => 'Trace',
Logger::DEBUG => 'Debug',
Logger::DATA => 'Data',
Logger::ALL => 'All'
LogLevel::ERROR => 'Error',
LogLevel::WARNING => 'Warning',
LogLevel::NOTICE => 'Notice',
LogLevel::INFO => 'Info',
LogLevel::DEBUG => 'Debug',
];
if (ini_get('log_errors')) {
@ -2484,6 +2589,7 @@ function admin_page_logs(App $a)
*
* @param App $a
* @return string
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
function admin_page_viewlogs(App $a)
{
@ -2527,6 +2633,7 @@ function admin_page_viewlogs(App $a)
* @brief Prosesses data send by the features admin page
*
* @param App $a
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
function admin_page_features_post(App $a)
{
@ -2574,6 +2681,7 @@ function admin_page_features_post(App $a)
*
* @param App $a
* @return string
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
function admin_page_features(App $a)
{

View File

@ -60,8 +60,6 @@ function allfriends_content(App $a)
//get further details of the contact
$contact_details = Model\Contact::getDetailsByURL($rr['url'], $uid, $rr);
$photo_menu = '';
$connlnk = '';
// $rr[cid] is only available for common contacts. So if the contact is a common one, use contact_photo_menu to generate the photo_menu
// If the contact is not common to the user, Connect/Follow' will be added to the photo menu

View File

@ -1,7 +1,5 @@
<?php
use Friendica\App;
function amcd_content()
{
echo <<< JSON
@ -47,5 +45,5 @@ function amcd_content()
}
}
JSON;
killme();
exit();
}

View File

@ -6,16 +6,13 @@ use Friendica\App;
use Friendica\Core\Config;
use Friendica\Core\L10n;
use Friendica\Core\Renderer;
use Friendica\Core\System;
use Friendica\Database\DBA;
use Friendica\Module\Login;
require_once 'include/api.php';
function oauth_get_client($request)
function oauth_get_client(OAuthRequest $request)
{
$params = $request->get_parameters();
$token = $params['oauth_token'];
@ -59,7 +56,7 @@ function api_content(App $a)
} catch (Exception $e) {
echo "<pre>";
var_dump($e);
killme();
exit();
}
if (!empty($_POST['oauth_yes'])) {
@ -79,7 +76,7 @@ function api_content(App $a)
$glue = "?";
}
$a->internalRedirect($consumer->callback_url . $glue . 'oauth_token=' . OAuthUtil::urlencode_rfc3986($params['oauth_token']) . '&oauth_verifier=' . OAuthUtil::urlencode_rfc3986($verifier));
killme();
exit();
}
$tpl = Renderer::getMarkupTemplate("oauth_authorize_done.tpl");
@ -117,5 +114,5 @@ function api_content(App $a)
}
echo api_call($a);
killme();
exit();
}

View File

@ -1,54 +0,0 @@
<?php
/**
* @file mod/attach.php
*/
use Friendica\App;
use Friendica\Core\L10n;
use Friendica\Database\DBA;
use Friendica\Util\Security;
function attach_init(App $a)
{
if ($a->argc != 2) {
notice(L10n::t('Item not available.') . EOL);
return;
}
$item_id = intval($a->argv[1]);
// Check for existence, which will also provide us the owner uid
$r = DBA::selectFirst('attach', [], ['id' => $item_id]);
if (!DBA::isResult($r)) {
notice(L10n::t('Item was not found.'). EOL);
return;
}
$sql_extra = Security::getPermissionsSQLByUserId($r['uid']);
// Now we'll see if we can access the attachment
$r = q("SELECT * FROM `attach` WHERE `id` = '%d' $sql_extra LIMIT 1",
DBA::escape($item_id)
);
if (!DBA::isResult($r)) {
notice(L10n::t('Permission denied.') . EOL);
return;
}
// Use quotes around the filename to prevent a "multiple Content-Disposition"
// error in Chrome for filenames with commas in them
header('Content-type: ' . $r[0]['filetype']);
header('Content-length: ' . $r[0]['filesize']);
if (isset($_GET['attachment']) && $_GET['attachment'] === '0') {
header('Content-disposition: filename="' . $r[0]['filename'] . '"');
} else {
header('Content-disposition: attachment; filename="' . $r[0]['filename'] . '"');
}
echo $r[0]['data'];
killme();
// NOTREACHED
}

View File

@ -72,6 +72,21 @@ function babel_content()
'title' => L10n::t('BBCode::toMarkdown => Markdown::convert => HTML::toBBCode'),
'content' => visible_whitespace($bbcode4)
];
$item = [
'body' => $bbcode,
'tag' => '',
];
\Friendica\Model\Item::setHashtags($item);
$results[] = [
'title' => L10n::t('Item Body'),
'content' => visible_whitespace($item['body'])
];
$results[] = [
'title' => L10n::t('Item Tags'),
'content' => $item['tag']
];
break;
case 'markdown':
$markdown = trim($_REQUEST['text']);
@ -83,7 +98,7 @@ function babel_content()
$html = Text\Markdown::convert($markdown);
$results[] = [
'title' => L10n::t('Markdown::convert (raw HTML)'),
'content' => htmlspecialchars($html)
'content' => visible_whitespace(htmlspecialchars($html))
];
$results[] = [

View File

@ -20,7 +20,7 @@ function bookmarklet_content(App $a)
{
if (!local_user()) {
$o = '<h2>' . L10n::t('Login') . '</h2>';
$o .= Login::form($a->query_string, intval(Config::get('config', 'register_policy')) === REGISTER_CLOSED ? false : true);
$o .= Login::form($a->query_string, intval(Config::get('config', 'register_policy')) === \Friendica\Module\Register::CLOSED ? false : true);
return $o;
}

View File

@ -23,7 +23,6 @@ use Friendica\Model\Profile;
use Friendica\Protocol\DFRN;
use Friendica\Util\DateTimeFormat;
use Friendica\Util\Temporal;
use Friendica\Util\Security;
function cal_init(App $a)
{
@ -244,7 +243,7 @@ function cal_content(App $a)
if (!empty($a->argv[2]) && ($a->argv[2] === 'json')) {
echo json_encode($events);
killme();
exit();
}
// links: array('href', 'text', 'extra css classes', 'title')
@ -286,7 +285,7 @@ function cal_content(App $a)
if (!empty($_GET['id'])) {
echo $o;
killme();
exit();
}
return $o;
@ -331,7 +330,7 @@ function cal_content(App $a)
header('Content-type: text/calendar');
header('content-disposition: attachment; filename="' . L10n::t('calendar') . '-' . $nick . '.' . $evexport["extension"] . '"');
echo $evexport["content"];
killme();
exit();
}
return;

View File

@ -14,6 +14,7 @@ use Friendica\Core\Renderer;
use Friendica\Database\DBA;
use Friendica\Model\Contact;
use Friendica\Model\Item;
use Friendica\Model\User;
function community_init(App $a)
{
@ -44,16 +45,16 @@ function community_content(App $a, $update = 0)
if ($a->argc > 2) {
switch ($a->argv[2]) {
case 'person':
$accounttype = Contact::ACCOUNT_TYPE_PERSON;
$accounttype = User::ACCOUNT_TYPE_PERSON;
break;
case 'organisation':
$accounttype = Contact::ACCOUNT_TYPE_ORGANISATION;
$accounttype = User::ACCOUNT_TYPE_ORGANISATION;
break;
case 'news':
$accounttype = Contact::ACCOUNT_TYPE_NEWS;
$accounttype = User::ACCOUNT_TYPE_NEWS;
break;
case 'community':
$accounttype = Contact::ACCOUNT_TYPE_COMMUNITY;
$accounttype = User::ACCOUNT_TYPE_COMMUNITY;
break;
}
}
@ -218,9 +219,9 @@ function community_getitems($start, $itemspage, $content, $accounttype)
}
$r = DBA::p("SELECT `item`.`uri`, `author`.`url` AS `author-link` FROM `thread`
INNER JOIN `user` ON `user`.`uid` = `thread`.`uid` AND NOT `user`.`hidewall`
INNER JOIN `item` ON `item`.`id` = `thread`.`iid`
INNER JOIN `contact` AS `author` ON `author`.`id`=`item`.`author-id`
STRAIGHT_JOIN `user` ON `user`.`uid` = `thread`.`uid` AND NOT `user`.`hidewall`
STRAIGHT_JOIN `item` ON `item`.`id` = `thread`.`iid`
STRAIGHT_JOIN `contact` AS `author` ON `author`.`id`=`item`.`author-id`
WHERE `thread`.`visible` AND NOT `thread`.`deleted` AND NOT `thread`.`moderated`
AND NOT `thread`.`private` AND `thread`.`wall` AND `thread`.`origin` $sql_accounttype
ORDER BY `thread`.`commented` DESC LIMIT ?, ?", $values);

View File

@ -1,53 +0,0 @@
<?php
use Friendica\App;
use Friendica\Database\DBA;
use Friendica\Model\Contact;
use Friendica\Model\Group;
function contactgroup_content(App $a)
{
if (!local_user()) {
killme();
}
$change = null;
if (($a->argc > 2) && intval($a->argv[1]) && intval($a->argv[2])) {
$r = q("SELECT `id` FROM `contact` WHERE `id` = %d AND `uid` = %d and `self` = 0 and `blocked` = 0 AND `pending` = 0 LIMIT 1",
intval($a->argv[2]),
intval(local_user())
);
if (DBA::isResult($r)) {
$change = intval($a->argv[2]);
}
}
if (($a->argc > 1) && (intval($a->argv[1]))) {
$r = q("SELECT * FROM `group` WHERE `id` = %d AND `uid` = %d AND `deleted` = 0 LIMIT 1",
intval($a->argv[1]),
intval(local_user())
);
if (!DBA::isResult($r)) {
killme();
}
$group = $r[0];
$members = Contact::getByGroupId($group['id']);
$preselected = [];
if (count($members)) {
foreach ($members as $member) {
$preselected[] = $member['id'];
}
}
if (!empty($change)) {
if (in_array($change, $preselected)) {
Group::removeMember($group['id'], $change);
} else {
Group::addMember($group['id'], $change);
}
}
}
killme();
}

View File

@ -5,7 +5,7 @@
* (only contributors to the git repositories for friendica core and the
* addons repository will be listed though ATM)
*/
use Friendica\App;
use Friendica\Core\L10n;
use Friendica\Core\Renderer;

View File

@ -19,20 +19,6 @@ function crepair_init(App $a)
if (!local_user()) {
return;
}
$contact = null;
if (($a->argc == 2) && intval($a->argv[1])) {
$contact = DBA::selectFirst('contact', [], ['uid' => local_user(), 'id' => $a->argv[1]]);
}
if (empty($a->page['aside'])) {
$a->page['aside'] = '';
}
if (DBA::isResult($contact)) {
$a->data['contact'] = $contact;
Model\Profile::load($a, "", 0, Model\Contact::getDetailsByURL($contact["url"]));
}
}
function crepair_post(App $a)
@ -55,6 +41,7 @@ function crepair_post(App $a)
$name = defaults($_POST, 'name' , $contact['name']);
$nick = defaults($_POST, 'nick' , '');
$url = defaults($_POST, 'url' , '');
$alias = defaults($_POST, 'alias' , '');
$request = defaults($_POST, 'request' , '');
$confirm = defaults($_POST, 'confirm' , '');
$notify = defaults($_POST, 'notify' , '');
@ -64,20 +51,22 @@ function crepair_post(App $a)
$remote_self = defaults($_POST, 'remote_self', false);
$nurl = Strings::normaliseLink($url);
$r = q("UPDATE `contact` SET `name` = '%s', `nick` = '%s', `url` = '%s', `nurl` = '%s', `request` = '%s', `confirm` = '%s', `notify` = '%s', `poll` = '%s', `attag` = '%s' , `remote_self` = %d
WHERE `id` = %d AND `uid` = %d",
DBA::escape($name),
DBA::escape($nick),
DBA::escape($url),
DBA::escape($nurl),
DBA::escape($request),
DBA::escape($confirm),
DBA::escape($notify),
DBA::escape($poll),
DBA::escape($attag),
intval($remote_self),
intval($contact['id']),
local_user()
$r = DBA::update(
'contact',
[
'name' => $name,
'nick' => $nick,
'url' => $url,
'nurl' => $nurl,
'alias' => $alias,
'request' => $request,
'confirm' => $confirm,
'notify' => $notify,
'poll' => $poll,
'attag' => $attag,
'remote_self' => $remote_self,
],
['id' => $contact['id'], 'uid' => local_user()]
);
if ($photo) {
@ -114,6 +103,15 @@ function crepair_content(App $a)
return;
}
if (empty($a->page['aside'])) {
$a->page['aside'] = '';
}
if (DBA::isResult($contact)) {
$a->data['contact'] = $contact;
Model\Profile::load($a, "", 0, Model\Contact::getDetailsByURL($contact["url"]));
}
$warning = L10n::t('<strong>WARNING: This is highly advanced</strong> and if you enter incorrect information your communications with this contact may stop working.');
$info = L10n::t('Please use your browser \'Back\' button <strong>now</strong> if you are uncertain what to do on this page.');
@ -162,6 +160,7 @@ function crepair_content(App $a)
'$nick' => ['nick', L10n::t('Account Nickname'), $contact['nick']],
'$attag' => ['attag', L10n::t('@Tagname - overrides Name/Nickname'), $contact['attag']],
'$url' => ['url', L10n::t('Account URL'), $contact['url']],
'$alias' => ['alias', L10n::t('Account URL Alias'), $contact['alias']],
'$request' => ['request', L10n::t('Friend Request URL'), $contact['request']],
'confirm' => ['confirm', L10n::t('Friend Confirm URL'), $contact['confirm']],
'notify' => ['notify', L10n::t('Notification Endpoint URL'), $contact['notify']],

View File

@ -11,14 +11,13 @@ use Friendica\Core\Renderer;
use Friendica\Core\System;
use Friendica\Database\DBA;
use Friendica\Model\User;
use Friendica\Util\Security;
use Friendica\Util\Strings;
require_once 'mod/settings.php';
function delegate_init(App $a)
{
return settings_init($a);
settings_init($a);
}
function delegate_post(App $a)

View File

@ -202,11 +202,11 @@ function dfrn_confirm_post(App $a, $handsfree = null)
$params['duplex'] = 1;
}
if ($user['page-flags'] == Contact::PAGE_COMMUNITY) {
if ($user['page-flags'] == User::PAGE_FLAGS_COMMUNITY) {
$params['page'] = 1;
}
if ($user['page-flags'] == Contact::PAGE_PRVGROUP) {
if ($user['page-flags'] == User::PAGE_FLAGS_PRVGROUP) {
$params['page'] = 2;
}

View File

@ -12,6 +12,7 @@ use Friendica\Core\Logger;
use Friendica\Core\System;
use Friendica\Database\DBA;
use Friendica\Model\Contact;
use Friendica\Model\User;
use Friendica\Protocol\DFRN;
use Friendica\Protocol\Diaspora;
use Friendica\Util\Strings;
@ -253,7 +254,6 @@ function dfrn_notify_content(App $a) {
*/
$dfrn_id = Strings::escapeTags(trim($_GET['dfrn_id']));
$dfrn_version = (float) $_GET['dfrn_version'];
$rino_remote = (!empty($_GET['rino']) ? intval($_GET['rino']) : 0);
$type = "";
$last_update = "";
@ -281,7 +281,7 @@ function dfrn_notify_content(App $a) {
$user = DBA::selectFirst('user', ['uid'], ['nickname' => $a->argv[1]]);
if (!DBA::isResult($user)) {
Logger::log('User not found for nickname ' . $a->argv[1]);
killme();
exit();
}
$condition = [];
@ -300,6 +300,7 @@ function dfrn_notify_content(App $a) {
break;
default:
$status = 1;
$my_id = '';
break;
}
@ -313,7 +314,7 @@ function dfrn_notify_content(App $a) {
$importer = DFRN::getImporter($contact['id'], $user['uid']);
if (empty($importer)) {
Logger::log('No importer data found for user ' . $a->argv[1] . ' and contact ' . $dfrn_id);
killme();
exit();
}
Logger::log("Remote rino version: ".$rino_remote." for ".$importer["url"], Logger::DATA);
@ -352,7 +353,7 @@ function dfrn_notify_content(App $a) {
$rino = $rino_remote;
}
if (($importer['rel'] && ($importer['rel'] != Contact::SHARING)) || ($importer['page-flags'] == Contact::PAGE_COMMUNITY)) {
if (($importer['rel'] && ($importer['rel'] != Contact::SHARING)) || ($importer['page-flags'] == User::PAGE_FLAGS_COMMUNITY)) {
$perm = 'rw';
} else {
$perm = 'r';
@ -370,6 +371,6 @@ function dfrn_notify_content(App $a) {
. "\t" . '<challenge>' . $challenge . '</challenge>' . "\r\n"
. '</dfrn_notify>' . "\r\n";
killme();
exit();
}
}

View File

@ -28,7 +28,6 @@ function dfrn_poll_init(App $a)
$challenge = defaults($_GET, 'challenge' , '');
$sec = defaults($_GET, 'sec' , '');
$dfrn_version = (float) defaults($_GET, 'dfrn_version' , 2.0);
$perm = defaults($_GET, 'perm' , 'r');
$quiet = !empty($_GET['quiet']);
// Possibly it is an OStatus compatible server that requests a user feed
@ -37,7 +36,7 @@ function dfrn_poll_init(App $a)
$nickname = $a->argv[1];
header("Content-type: application/atom+xml");
echo OStatus::feed($nickname, $last_update, 10);
killme();
exit();
}
$direction = -1;
@ -71,7 +70,7 @@ function dfrn_poll_init(App $a)
Logger::log('dfrn_poll: public feed request from ' . $_SERVER['REMOTE_ADDR'] . ' for ' . $user);
header("Content-type: application/atom+xml");
echo DFRN::feed('', $user, $last_update, 0, $hidewall);
killme();
exit();
}
if (($type === 'profile') && (!strlen($sec))) {
@ -198,7 +197,7 @@ function dfrn_poll_init(App $a)
header("Content-type: text/xml");
echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?><dfrn_poll><status>0</status><challenge>$decoded_challenge</challenge><sec>$sec</sec></dfrn_poll>";
killme();
exit();
// NOTREACHED
} else {
// old protocol
@ -290,7 +289,7 @@ function dfrn_poll_post(App $a)
header("Content-type: text/xml");
echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?><dfrn_poll><status>0</status><challenge>$decoded_challenge</challenge><sec>$sec</sec></dfrn_poll>";
killme();
exit();
// NOTREACHED
}
}
@ -307,7 +306,7 @@ function dfrn_poll_post(App $a)
);
if (!DBA::isResult($r)) {
killme();
exit();
}
$type = $r[0]['type'];
@ -319,15 +318,12 @@ function dfrn_poll_post(App $a)
switch ($direction) {
case -1:
$sql_extra = sprintf(" AND `issued-id` = '%s' ", DBA::escape($dfrn_id));
$my_id = $dfrn_id;
break;
case 0:
$sql_extra = sprintf(" AND `issued-id` = '%s' AND `duplex` = 1 ", DBA::escape($dfrn_id));
$my_id = '1:' . $dfrn_id;
break;
case 1:
$sql_extra = sprintf(" AND `dfrn-id` = '%s' AND `duplex` = 1 ", DBA::escape($dfrn_id));
$my_id = '0:' . $dfrn_id;
break;
default:
$a->internalRedirect();
@ -336,7 +332,7 @@ function dfrn_poll_post(App $a)
$r = q("SELECT * FROM `contact` WHERE `blocked` = 0 AND `pending` = 0 $sql_extra LIMIT 1");
if (!DBA::isResult($r)) {
killme();
exit();
}
$contact = $r[0];
@ -368,7 +364,7 @@ function dfrn_poll_post(App $a)
<description>$text</description>
</reputation>
";
killme();
exit();
// NOTREACHED
} else {
// Update the writable flag if it changed
@ -391,7 +387,7 @@ function dfrn_poll_post(App $a)
header("Content-type: application/atom+xml");
$o = DFRN::feed($dfrn_id, $a->argv[1], $last_update, $direction);
echo $o;
killme();
exit();
}
}
@ -420,7 +416,7 @@ function dfrn_poll_content(App $a)
DBA::delete('challenge', ["`expire` < ?", time()]);
if ($type !== 'profile') {
$r = q("INSERT INTO `challenge` ( `challenge`, `dfrn-id`, `expire` , `type`, `last_update` )
q("INSERT INTO `challenge` ( `challenge`, `dfrn-id`, `expire` , `type`, `last_update` )
VALUES( '%s', '%s', '%s', '%s', '%s' ) ",
DBA::escape($hash),
DBA::escape($dfrn_id),
@ -573,7 +569,7 @@ function dfrn_poll_content(App $a)
. "\t" . '<dfrn_id>' . $encrypted_id . '</dfrn_id>' . "\r\n"
. "\t" . '<challenge>' . $challenge . '</challenge>' . "\r\n"
. '</dfrn_poll>' . "\r\n";
killme();
exit();
// NOTREACHED
}
}

View File

@ -34,9 +34,9 @@ function dfrn_request_init(App $a)
{
if ($a->argc > 1) {
$which = $a->argv[1];
Profile::load($a, $which);
}
Profile::load($a, $which);
return;
}
@ -54,6 +54,9 @@ function dfrn_request_init(App $a)
* in order to link our friend request with our own server cell.
* After logging in, we click 'submit' to approve the linkage.
*
* @param App $a
* @throws ImagickException
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
function dfrn_request_post(App $a)
{
@ -165,7 +168,7 @@ function dfrn_request_post(App $a)
$r = q("SELECT `id`, `network` FROM `contact` WHERE `uid` = %d AND `url` = '%s' AND `site-pubkey` = '%s' LIMIT 1",
intval(local_user()),
DBA::escape($dfrn_url),
$parms['key'] // this was already escaped
defaults($parms, 'key', '') // Potentially missing
);
if (DBA::isResult($r)) {
Group::addMember(User::getDefaultGroup(local_user(), $r[0]["network"]), $r[0]['id']);
@ -184,8 +187,8 @@ function dfrn_request_post(App $a)
$dfrn_request = $contact_record['request'];
}
if (strlen($dfrn_request) && strlen($confirm_key)) {
$s = Network::fetchUrl($dfrn_request . '?confirm_key=' . $confirm_key);
if (!empty($dfrn_request) && strlen($confirm_key)) {
Network::fetchUrl($dfrn_request . '?confirm_key=' . $confirm_key);
}
// (ignore reply, nothing we can do it failed)
@ -227,7 +230,6 @@ function dfrn_request_post(App $a)
}
$nickname = $a->profile['nickname'];
$notify_flags = $a->profile['notify-flags'];
$uid = $a->profile['uid'];
$maxreq = intval($a->profile['maxreq']);
$contact_record = null;
@ -268,8 +270,6 @@ function dfrn_request_post(App $a)
}
}
$real_name = !empty($_POST['realname']) ? Strings::escapeTags(trim($_POST['realname'])) : '';
$url = trim($_POST['dfrn_url']);
if (!strlen($url)) {
notice(L10n::t("Invalid locator") . EOL);
@ -417,7 +417,7 @@ function dfrn_request_post(App $a)
$hash = Strings::getRandomHex() . (string) time(); // Generate a confirm_key
if (is_array($contact_record)) {
$ret = q("INSERT INTO `intro` ( `uid`, `contact-id`, `blocked`, `knowyou`, `note`, `hash`, `datetime`)
q("INSERT INTO `intro` ( `uid`, `contact-id`, `blocked`, `knowyou`, `note`, `hash`, `datetime`)
VALUES ( %d, %d, 1, %d, '%s', '%s', '%s' )",
intval($uid),
intval($contact_record['id']),
@ -544,7 +544,7 @@ function dfrn_request_content(App $a)
$auto_confirm = false;
if (DBA::isResult($r)) {
if ($r[0]['page-flags'] != Contact::PAGE_NORMAL && $r[0]['page-flags'] != Contact::PAGE_PRVGROUP) {
if ($r[0]['page-flags'] != User::PAGE_FLAGS_NORMAL && $r[0]['page-flags'] != User::PAGE_FLAGS_PRVGROUP) {
$auto_confirm = true;
}
@ -572,7 +572,7 @@ function dfrn_request_content(App $a)
'node' => $r[0]['nickname'],
'dfrn_id' => $r[0]['issued-id'],
'intro_id' => $intro[0]['id'],
'duplex' => (($r[0]['page-flags'] == Contact::PAGE_FREELOVE) ? 1 : 0),
'duplex' => (($r[0]['page-flags'] == User::PAGE_FLAGS_FREELOVE) ? 1 : 0),
];
dfrn_confirm_post($a, $handsfree);
}
@ -583,14 +583,13 @@ function dfrn_request_content(App $a)
// If we are auto_confirming, this record will have already been nuked
// in dfrn_confirm_post()
$r = q("UPDATE `intro` SET `blocked` = 0 WHERE `hash` = '%s'",
q("UPDATE `intro` SET `blocked` = 0 WHERE `hash` = '%s'",
DBA::escape($_GET['confirm_key'])
);
}
}
killme();
return; // NOTREACHED
exit();
} else {
// Normal web request. Display our user's introduction form.
if ((Config::get('system', 'block_public')) && (!local_user()) && (!remote_user())) {
@ -624,7 +623,7 @@ function dfrn_request_content(App $a)
* because nobody is going to read the comments and
* it doesn't matter if they know you or not.
*/
if ($a->profile['page-flags'] == Contact::PAGE_NORMAL) {
if ($a->profile['page-flags'] == User::PAGE_FLAGS_NORMAL) {
$tpl = Renderer::getMarkupTemplate('dfrn_request.tpl');
} else {
$tpl = Renderer::getMarkupTemplate('auto_request.tpl');
@ -655,6 +654,4 @@ function dfrn_request_content(App $a)
]);
return $o;
}
return; // Somebody is fishing.
}

View File

@ -7,8 +7,8 @@ use Friendica\App;
use Friendica\Content\Nav;
use Friendica\Content\Pager;
use Friendica\Content\Widget;
use Friendica\Core\Addon;
use Friendica\Core\Config;
use Friendica\Core\Hook;
use Friendica\Core\L10n;
use Friendica\Core\Renderer;
use Friendica\Database\DBA;
@ -45,6 +45,8 @@ function directory_content(App $a)
}
$o = '';
$entries = [];
Nav::setSelected('directory');
if (!empty($a->data['search'])) {
@ -98,7 +100,7 @@ function directory_content(App $a)
$limit = $pager->getStart()."," . $pager->getItemsPerPage();
$r = DBA::p("SELECT `profile`.*, `profile`.`uid` AS `profile_uid`, `user`.`nickname`, `user`.`timezone` , `user`.`page-flags`,
`contact`.`addr`, `contact`.`url` AS profile_url FROM `profile`
`contact`.`addr`, `contact`.`url` AS `profile_url` FROM `profile`
LEFT JOIN `user` ON `user`.`uid` = `profile`.`uid`
LEFT JOIN `contact` ON `contact`.`uid` = `user`.`uid`
WHERE `is-default` $publish AND NOT `user`.`blocked` AND NOT `user`.`account_removed` AND `contact`.`self`
@ -112,114 +114,117 @@ function directory_content(App $a)
}
while ($rr = DBA::fetch($r)) {
$itemurl= '';
$itemurl = (($rr['addr'] != "") ? $rr['addr'] : $rr['profile_url']);
$profile_link = $rr['profile_url'];
$pdesc = (($rr['pdesc']) ? $rr['pdesc'] . '<br />' : '');
$details = '';
if (strlen($rr['locality'])) {
$details .= $rr['locality'];
}
if (strlen($rr['region'])) {
if (strlen($rr['locality'])) {
$details .= ', ';
}
$details .= $rr['region'];
}
if (strlen($rr['country-name'])) {
if (strlen($details)) {
$details .= ', ';
}
$details .= $rr['country-name'];
}
// if(strlen($rr['dob'])) {
// if(($years = age($rr['dob'],$rr['timezone'],'')) != 0)
// $details .= '<br />' . L10n::t('Age: ') . $years;
// }
// if(strlen($rr['gender']))
// $details .= '<br />' . L10n::t('Gender: ') . $rr['gender'];
$profile = $rr;
if (!empty($profile['address'])
|| !empty($profile['locality'])
|| !empty($profile['region'])
|| !empty($profile['postal-code'])
|| !empty($profile['country-name'])
) {
$location = L10n::t('Location:');
} else {
$location = '';
}
$gender = (!empty($profile['gender']) ? L10n::t('Gender:') : false);
$marital = (!empty($profile['marital']) ? L10n::t('Status:') : false);
$homepage = (!empty($profile['homepage']) ? L10n::t('Homepage:') : false);
$about = (!empty($profile['about']) ? L10n::t('About:') : false);
$location_e = $location;
$photo_menu = [
'profile' => [L10n::t("View Profile"), Contact::magicLink($profile_link)]
];
$entry = [
'id' => $rr['id'],
'url' => Contact::magicLInk($profile_link),
'itemurl' => $itemurl,
'thumb' => ProxyUtils::proxifyUrl($rr[$photo], false, ProxyUtils::SIZE_THUMB),
'img_hover' => $rr['name'],
'name' => $rr['name'],
'details' => $details,
'account_type' => Contact::getAccountType($rr),
'profile' => $profile,
'location' => $location_e,
'tags' => $rr['pub_keywords'],
'gender' => $gender,
'pdesc' => $pdesc,
'marital' => $marital,
'homepage' => $homepage,
'about' => $about,
'photo_menu' => $photo_menu,
];
$arr = ['contact' => $rr, 'entry' => $entry];
Addon::callHooks('directory_item', $arr);
unset($profile);
unset($location);
if (!$arr['entry']) {
continue;
}
$entries[] = $arr['entry'];
$entries[] = format_directory_entry($rr, $photo);
}
DBA::close($r);
$tpl = Renderer::getMarkupTemplate('directory_header.tpl');
$o .= Renderer::replaceMacros($tpl, [
'$search' => $search,
'$globaldir' => L10n::t('Global Directory'),
'$gdirpath' => $gdirpath,
'$desc' => L10n::t('Find on this site'),
'$contacts' => $entries,
'$finding' => L10n::t('Results for:'),
'$findterm' => (strlen($search) ? $search : ""),
'$title' => L10n::t('Site Directory'),
'$submit' => L10n::t('Find'),
'$paginate' => $pager->renderFull($total),
]);
} else {
info(L10n::t("No entries \x28some entries may be hidden\x29.") . EOL);
}
$tpl = Renderer::getMarkupTemplate('directory_header.tpl');
$o .= Renderer::replaceMacros($tpl, [
'$search' => $search,
'$globaldir' => L10n::t('Global Directory'),
'$gdirpath' => $gdirpath,
'$desc' => L10n::t('Find on this site'),
'$contacts' => $entries,
'$finding' => L10n::t('Results for:'),
'$findterm' => (strlen($search) ? $search : ""),
'$title' => L10n::t('Site Directory'),
'$search_mod' => 'directory',
'$submit' => L10n::t('Find'),
'$paginate' => $pager->renderFull($total),
]);
return $o;
}
/**
* Format contact/profile/user data from the database into an usable
* array for displaying directory entries.
*
* @param array $arr The directory entry from the database.
* @param string $photo_size Avatar size (thumb, photo or micro).
*
* @return array
*/
function format_directory_entry(array $arr, $photo_size = 'photo')
{
$itemurl = (($arr['addr'] != "") ? $arr['addr'] : $arr['profile_url']);
$profile_link = $arr['profile_url'];
$pdesc = (($arr['pdesc']) ? $arr['pdesc'] . '<br />' : '');
$details = '';
if (strlen($arr['locality'])) {
$details .= $arr['locality'];
}
if (strlen($arr['region'])) {
if (strlen($arr['locality'])) {
$details .= ', ';
}
$details .= $arr['region'];
}
if (strlen($arr['country-name'])) {
if (strlen($details)) {
$details .= ', ';
}
$details .= $arr['country-name'];
}
$profile = $arr;
if (!empty($profile['address'])
|| !empty($profile['locality'])
|| !empty($profile['region'])
|| !empty($profile['postal-code'])
|| !empty($profile['country-name'])
) {
$location = L10n::t('Location:');
} else {
$location = '';
}
$gender = (!empty($profile['gender']) ? L10n::t('Gender:') : false);
$marital = (!empty($profile['marital']) ? L10n::t('Status:') : false);
$homepage = (!empty($profile['homepage']) ? L10n::t('Homepage:') : false);
$about = (!empty($profile['about']) ? L10n::t('About:') : false);
$location_e = $location;
$photo_menu = [
'profile' => [L10n::t("View Profile"), Contact::magicLink($profile_link)]
];
$entry = [
'id' => $arr['id'],
'url' => Contact::magicLInk($profile_link),
'itemurl' => $itemurl,
'thumb' => ProxyUtils::proxifyUrl($arr[$photo_size], false, ProxyUtils::SIZE_THUMB),
'img_hover' => $arr['name'],
'name' => $arr['name'],
'details' => $details,
'account_type' => Contact::getAccountType($arr),
'profile' => $profile,
'location' => $location_e,
'tags' => $arr['pub_keywords'],
'gender' => $gender,
'pdesc' => $pdesc,
'marital' => $marital,
'homepage' => $homepage,
'about' => $about,
'photo_menu' => $photo_menu,
];
$hook = ['contact' => $arr, 'entry' => $entry];
Hook::callAll('directory_item', $hook);
unset($profile);
unset($location);
return $hook['entry'];
}

View File

@ -179,21 +179,19 @@ function dirfind_content(App $a, $prefix = "") {
// Add found profiles from the global directory to the local directory
Worker::add(PRIORITY_LOW, 'DiscoverPoCo', "dirsearch", urlencode($search));
} else {
} elseif (strlen(Config::get('system','directory'))) {
$p = (($pager->getPage() != 1) ? '&p=' . $pager->getPage() : '');
if (strlen(Config::get('system','directory'))) {
$x = Network::fetchUrl(get_server() . '/lsearch?f=' . $p . '&search=' . urlencode($search));
}
$x = Network::fetchUrl(get_server() . '/lsearch?f=' . $p . '&search=' . urlencode($search));
$j = json_decode($x);
$pager->setItemsPerPage($j->items_page);
}
if (!empty($j->results)) {
$id = 0;
$entries = [];
foreach ($j->results as $jj) {
$alt_text = "";

View File

@ -19,10 +19,10 @@ use Friendica\Model\Contact;
use Friendica\Model\Group;
use Friendica\Model\Item;
use Friendica\Model\Profile;
use Friendica\Module\Objects;
use Friendica\Protocol\ActivityPub;
use Friendica\Protocol\DFRN;
use Friendica\Util\Strings;
use Friendica\Module\Objects;
function display_init(App $a)
{
@ -35,7 +35,6 @@ function display_init(App $a)
}
$nick = (($a->argc > 1) ? $a->argv[1] : '');
$profiledata = [];
if ($a->argc == 3) {
if (substr($a->argv[2], -5) == '.atom') {
@ -96,7 +95,7 @@ function display_init(App $a)
}
if ($item["id"] != $item["parent"]) {
$item = Item::selectFirstForUser(local_user(), $fields, ['id' => $item["parent"]]);
$item = Item::selectFirstForUser($item_user, $fields, ['id' => $item["parent"]]);
}
$profiledata = display_fetchauthor($a, $item);
@ -157,7 +156,6 @@ function display_fetchauthor($a, $item)
}
if (!$skip) {
$author = "";
preg_match("/author='(.*?)'/ism", $attributes, $matches);
if (!empty($matches[1])) {
$profiledata["name"] = html_entity_decode($matches[1],ENT_QUOTES,'UTF-8');
@ -166,7 +164,6 @@ function display_fetchauthor($a, $item)
if (!empty($matches[1])) {
$profiledata["name"] = html_entity_decode($matches[1],ENT_QUOTES,'UTF-8');
}
$profile = "";
preg_match("/profile='(.*?)'/ism", $attributes, $matches);
if (!empty($matches[1])) {
$profiledata["url"] = $matches[1];
@ -175,7 +172,6 @@ function display_fetchauthor($a, $item)
if (!empty($matches[1])) {
$profiledata["url"] = $matches[1];
}
$avatar = "";
preg_match("/avatar='(.*?)'/ism", $attributes, $matches);
if (!empty($matches[1])) {
$profiledata["photo"] = $matches[1];
@ -287,22 +283,25 @@ function display_content(App $a, $update = false, $update_uid = 0)
$is_remote_contact = false;
$item_uid = local_user();
$parent = Item::selectFirst(['uid'], ['uri' => $item_parent_uri, 'wall' => true]);
if (DBA::isResult($parent)) {
$a->profile['uid'] = defaults($a->profile, 'uid', $parent['uid']);
$a->profile['profile_uid'] = defaults($a->profile, 'profile_uid', $parent['uid']);
$is_remote_contact = Contact::isFollower(remote_user(), $a->profile['profile_uid']);
}
if (isset($item_parent_uri)) {
$parent = Item::selectFirst(['uid'], ['uri' => $item_parent_uri, 'wall' => true]);
if (DBA::isResult($parent)) {
$a->profile['uid'] = defaults($a->profile, 'uid', $parent['uid']);
$a->profile['profile_uid'] = defaults($a->profile, 'profile_uid', $parent['uid']);
$is_remote_contact = Contact::isFollower(remote_user(), $a->profile['profile_uid']);
if ($is_remote_contact) {
$cdata = Contact::getPublicAndUserContacID(remote_user(), $a->profile['profile_uid']);
if (!empty($cdata['user'])) {
$groups = Group::getIdsByContactId($cdata['user']);
$remote_cid = $cdata['user'];
$item_uid = $parent['uid'];
if ($is_remote_contact) {
$cdata = Contact::getPublicAndUserContacID(remote_user(), $a->profile['profile_uid']);
if (!empty($cdata['user'])) {
$groups = Group::getIdsByContactId($cdata['user']);
$remote_cid = $cdata['user'];
$item_uid = $parent['uid'];
}
}
}
}
$page_contact = DBA::selectFirst('contact', [], ['self' => true, 'uid' => $a->profile['uid']]);
if (DBA::isResult($page_contact)) {
$a->page_contact = $page_contact;
@ -426,5 +425,5 @@ function displayShowFeed($item_id, $conversation)
}
header("Content-type: application/atom+xml");
echo $xml;
killme();
exit();
}

View File

@ -2,10 +2,9 @@
/**
* @file mod/editpost.php
*/
use Friendica\App;
use Friendica\Content\Feature;
use Friendica\Core\Addon;
use Friendica\Core\Config;
use Friendica\Core\Hook;
use Friendica\Core\L10n;
use Friendica\Core\Renderer;
@ -64,25 +63,6 @@ function editpost_content(App $a)
$jotplugins = '';
$jotnets = '';
$mail_disabled = ((function_exists('imap_open') && !Config::get('system', 'imap_disabled')) ? 0 : 1);
$mail_enabled = false;
$pubmail_enabled = false;
if (!$mail_disabled) {
$r = q("SELECT * FROM `mailacct` WHERE `uid` = %d AND `server` != '' LIMIT 1",
intval(local_user())
);
if (DBA::isResult($r)) {
$mail_enabled = true;
if (intval($r[0]['pubmail'])) {
$pubmail_enabled = true;
}
}
}
Hook::callAll('jot_tool', $jotplugins);
$tpl = Renderer::getMarkupTemplate("jot.tpl");

View File

@ -117,7 +117,7 @@ function events_post(App $a)
notice(L10n::t('Event can not end before it has started.') . EOL);
if (intval($_REQUEST['preview'])) {
echo L10n::t('Event can not end before it has started.');
killme();
exit();
}
$a->internalRedirect($onerror_path);
}
@ -126,7 +126,7 @@ function events_post(App $a)
notice(L10n::t('Event title and start time are required.') . EOL);
if (intval($_REQUEST['preview'])) {
echo L10n::t('Event title and start time are required.');
killme();
exit();
}
$a->internalRedirect($onerror_path);
}
@ -213,14 +213,14 @@ function events_content(App $a)
}
if (($a->argc > 2) && ($a->argv[1] === 'ignore') && intval($a->argv[2])) {
$r = q("UPDATE `event` SET `ignore` = 1 WHERE `id` = %d AND `uid` = %d",
q("UPDATE `event` SET `ignore` = 1 WHERE `id` = %d AND `uid` = %d",
intval($a->argv[2]),
intval(local_user())
);
}
if (($a->argc > 2) && ($a->argv[1] === 'unignore') && intval($a->argv[2])) {
$r = q("UPDATE `event` SET `ignore` = 0 WHERE `id` = %d AND `uid` = %d",
q("UPDATE `event` SET `ignore` = 0 WHERE `id` = %d AND `uid` = %d",
intval($a->argv[2]),
intval(local_user())
);
@ -300,21 +300,6 @@ function events_content(App $a)
$y = 2100;
}
$nextyear = $y;
$nextmonth = $m + 1;
if ($nextmonth > 12) {
$nextmonth = 1;
$nextyear ++;
}
$prevyear = $y;
if ($m > 1) {
$prevmonth = $m - 1;
} else {
$prevmonth = 12;
$prevyear --;
}
$dim = Temporal::getDaysInMonth($y, $m);
$start = sprintf('%d-%d-%d %d:%d:%d', $y, $m, 1, 0, 0, 0);
$finish = sprintf('%d-%d-%d %d:%d:%d', $y, $m, $dim, 23, 59, 59);
@ -414,7 +399,7 @@ function events_content(App $a)
if (!empty($_GET['id'])) {
echo $o;
killme();
exit();
}
return $o;
@ -526,7 +511,7 @@ function events_content(App $a)
'$s_text' => L10n::t('Event Starts:') . ' <span class="required" title="' . L10n::t('Required') . '">*</span>',
'$s_dsel' => Temporal::getDateTimeField(
new DateTime(),
DateTime::createFromFormat('Y', $syear+5),
DateTime::createFromFormat('Y', intval($syear) + 5),
DateTime::createFromFormat('Y-m-d H:i', "$syear-$smonth-$sday $shour:$sminute"),
L10n::t('Event Starts:'),
'start_text',
@ -541,7 +526,7 @@ function events_content(App $a)
'$f_text' => L10n::t('Event Finishes:'),
'$f_dsel' => Temporal::getDateTimeField(
new DateTime(),
DateTime::createFromFormat('Y', $fyear+5),
DateTime::createFromFormat('Y', intval($fyear) + 5),
DateTime::createFromFormat('Y-m-d H:i', "$fyear-$fmonth-$fday $fhour:$fminute"),
L10n::t('Event Finishes:'),
'finish_text',

View File

@ -14,22 +14,22 @@ use Friendica\Object\Image;
/**
* @param App $a
* @return string
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
function fbrowser_content(App $a)
{
if (!local_user()) {
killme();
exit();
}
if ($a->argc == 1) {
killme();
exit();
}
$template_file = "filebrowser.tpl";
$mode = "";
if (!empty($_GET['mode'])) {
$mode = "?mode=".$_GET['mode'];
}
$o = '';
switch ($a->argv[1]) {
case "image":
@ -53,12 +53,11 @@ function fbrowser_content(App $a)
$albums = array_map("_map_folder1", $albums);
}
$album = "";
if ($a->argc==3) {
if ($a->argc == 3) {
$album = hex2bin($a->argv[2]);
$sql_extra = sprintf("AND `album` = '%s' ", DBA::escape($album));
$sql_extra2 = "";
$path[]=[$a->argv[2], $album];
$path[] = [$a->argv[2], $album];
}
$r = q("SELECT `resource-id`, ANY_VALUE(`id`) AS `id`, ANY_VALUE(`filename`) AS `filename`, ANY_VALUE(`type`) AS `type`,
@ -116,8 +115,7 @@ function fbrowser_content(App $a)
function _map_files2($rr)
{
$a = \get_app();
list($m1,$m2) = explode("/", $rr['filetype']);
list($m1, $m2) = explode("/", $rr['filetype']);
$filetype = ( (file_exists("images/icons/$m1.png"))?$m1:"zip");
$filename_e = $rr['filename'];
@ -146,6 +144,6 @@ function fbrowser_content(App $a)
return $o;
} else {
echo $o;
killme();
exit();
}
}

View File

@ -35,7 +35,7 @@ function feedtest_content(App $a)
$import_result = Feed::import($xml, $importer, $contact, $dummy, true);
$result = [
'input' => text_highlight($xml, 'xml'),
'input' => $xml,
'output' => var_export($import_result, true),
];
}

View File

@ -4,14 +4,12 @@ This file is part of the Diaspora protocol. It is used for fetching single publi
*/
use Friendica\App;
use Friendica\Core\L10n;
use Friendica\Core\Protocol;
use Friendica\Core\System;
use Friendica\Protocol\Diaspora;
use Friendica\Model\Item;
use Friendica\Model\User;
use Friendica\Util\Strings;
use Friendica\Util\XML;
use Friendica\Database\DBA;
function fetch_init(App $a)
@ -40,7 +38,7 @@ function fetch_init(App $a)
header("HTTP/1.1 301 Moved Permanently");
header("Location:".$location);
killme();
exit();
}
}
@ -60,5 +58,5 @@ function fetch_init(App $a)
header("Content-Type: application/magic-envelope+xml; charset=utf-8");
echo Diaspora::buildMagicEnvelope($xml, $user);
killme();
exit();
}

View File

@ -13,7 +13,7 @@ use Friendica\Util\XML;
function filer_content(App $a)
{
if (! local_user()) {
killme();
exit();
}
$term = XML::unescape(trim(defaults($_GET, 'term', '')));
@ -38,5 +38,5 @@ function filer_content(App $a)
echo $o;
}
killme();
exit();
}

View File

@ -2,7 +2,6 @@
use Friendica\App;
use Friendica\Core\Logger;
use Friendica\Core\System;
use Friendica\Model\FileTag;
use Friendica\Util\XML;
@ -10,10 +9,10 @@ function filerm_content(App $a)
{
if (! local_user())
{
killme();
exit();
}
$term = XML::unescape(trim($_GET['term']));
$term = XML::unescape(trim(defaults($_GET, 'term', '')));
$cat = XML::unescape(trim(defaults($_GET, 'cat', '')));
$category = (($cat) ? true : false);
@ -37,5 +36,5 @@ function filerm_content(App $a)
}
$a->internalRedirect('/network?f=&file=' . rawurlencode($term));
killme();
exit();
}

View File

@ -12,7 +12,6 @@ use Friendica\Model\Contact;
use Friendica\Model\Profile;
use Friendica\Network\Probe;
use Friendica\Database\DBA;
use Friendica\Util\Proxy as ProxyUtils;
use Friendica\Util\Strings;
function follow_post(App $a)
@ -61,7 +60,16 @@ function follow_content(App $a)
}
$uid = local_user();
$url = Strings::escapeTags(trim($_REQUEST['url']));
$url = Strings::escapeTags(trim(defaults($_REQUEST, 'url', '')));
// Issue 6874: Allow remote following from Peertube
if (strpos($url, 'acct:') === 0) {
$url = str_replace('acct:', '', $url);
}
if (!$url) {
$a->internalRedirect($return_path);
}
$submit = L10n::t('Submit Request');

View File

@ -6,43 +6,52 @@
use Friendica\App;
use Friendica\Core\Addon;
use Friendica\Core\Config;
use Friendica\Core\Hook;
use Friendica\Core\L10n;
use Friendica\Core\System;
use Friendica\Database\DBA;
use Friendica\Module\Register;
function friendica_init(App $a)
{
if (!empty($a->argv[1]) && ($a->argv[1] == "json")) {
$register_policies = ['REGISTER_CLOSED', 'REGISTER_APPROVE', 'REGISTER_OPEN'];
$register_policies = [
Register::CLOSED => 'REGISTER_CLOSED',
Register::APPROVE => 'REGISTER_APPROVE',
Register::OPEN => 'REGISTER_OPEN'
];
$register_policy = $register_policies[intval(Config::get('config', 'register_policy'))];
if ($register_policy == 'REGISTER_OPEN' && Config::get('config', 'invitation_only')) {
$register_policy_int = intval(Config::get('config', 'register_policy'));
if ($register_policy_int !== Register::CLOSED && Config::get('config', 'invitation_only')) {
$register_policy = 'REGISTER_INVITATION';
} else {
$register_policy = $register_policies[$register_policy_int];
}
$sql_extra = '';
if (!empty($a->config['admin_nickname'])) {
$sql_extra = sprintf(" AND `nickname` = '%s' ", DBA::escape(Config::get('config', 'admin_nickname')));
$condition = [];
$admin = false;
if (!empty(Config::get('config', 'admin_nickname'))) {
$condition['nickname'] = Config::get('config', 'admin_nickname');
}
if (!empty(Config::get('config', 'admin_email'))) {
$adminlist = explode(",", str_replace(" ", "", Config::get('config', 'admin_email')));
$r = q("SELECT `username`, `nickname` FROM `user` WHERE `email` = '%s' $sql_extra", DBA::escape($adminlist[0]));
$admin = [
'name' => $r[0]['username'],
'profile'=> System::baseUrl() . '/profile/' . $r[0]['nickname'],
];
} else {
$admin = false;
$condition['email'] = $adminlist[0];
$administrator = DBA::selectFirst('user', ['username', 'nickname'], $condition);
if (DBA::isResult($administrator)) {
$admin = [
'name' => $administrator['username'],
'profile'=> System::baseUrl() . '/profile/' . $administrator['nickname'],
];
}
}
$visible_addons = Addon::getVisibleList();
Config::load('feature_lock');
$locked_features = [];
if (!empty($a->config['feature_lock'])) {
foreach ($a->config['feature_lock'] as $k => $v) {
$featureLock = Config::get('config', 'feature_lock');
if (isset($featureLock)) {
foreach ($featureLock as $k => $v) {
if ($k === 'config_loaded') {
continue;
}
@ -68,7 +77,7 @@ function friendica_init(App $a)
header('Content-type: application/json; charset=utf-8');
echo json_encode($data);
killme();
exit();
}
}
@ -126,7 +135,7 @@ function friendica_content(App $a)
$o .= '</tbody></table></div>' . PHP_EOL;
}
Addon::callHooks('about_hook', $o);
Hook::callAll('about_hook', $o);
return $o;
}

View File

@ -23,15 +23,11 @@ function fsuggest_post(App $a)
$contact_id = intval($a->argv[1]);
$r = q("SELECT * FROM `contact` WHERE `id` = %d AND `uid` = %d LIMIT 1",
intval($contact_id),
intval(local_user())
);
if (! DBA::isResult($r)) {
$contact = DBA::selectFirst('contact', [], ['id' => $contact_id, 'uid' => local_user()]);
if (! DBA::isResult($contact)) {
notice(L10n::t('Contact not found.') . EOL);
return;
}
$contact = $r[0];
$new_contact = intval($_POST['suggest']);
@ -45,14 +41,14 @@ function fsuggest_post(App $a)
intval(local_user())
);
if (DBA::isResult($r)) {
$x = q("INSERT INTO `fsuggest` ( `uid`,`cid`,`name`,`url`,`request`,`photo`,`note`,`created`)
q("INSERT INTO `fsuggest` ( `uid`,`cid`,`name`,`url`,`request`,`photo`,`note`,`created`)
VALUES ( %d, %d, '%s','%s','%s','%s','%s','%s')",
intval(local_user()),
intval($contact_id),
DBA::escape($r[0]['name']),
DBA::escape($r[0]['url']),
DBA::escape($r[0]['request']),
DBA::escape($r[0]['photo']),
DBA::escape($contact['name']),
DBA::escape($contact['url']),
DBA::escape($contact['request']),
DBA::escape($contact['photo']),
DBA::escape($hash),
DBA::escape(DateTimeFormat::utcNow())
);
@ -61,7 +57,7 @@ function fsuggest_post(App $a)
intval(local_user())
);
if (DBA::isResult($r)) {
$fsuggest_id = $r[0]['id'];
$fsuggest_id = $contact['id'];
q("UPDATE `fsuggest` SET `note` = '%s' WHERE `id` = %d AND `uid` = %d",
DBA::escape($note),
intval($fsuggest_id),
@ -88,16 +84,11 @@ function fsuggest_content(App $a)
$contact_id = intval($a->argv[1]);
$r = q(
"SELECT * FROM `contact` WHERE `id` = %d AND `uid` = %d LIMIT 1",
intval($contact_id),
intval(local_user())
);
if (! DBA::isResult($r)) {
$contact = DBA::selectFirst('contact', [], ['id' => $contact_id, 'uid' => local_user()]);
if (! DBA::isResult($contact)) {
notice(L10n::t('Contact not found.') . EOL);
return;
}
$contact = $r[0];
$o = '<h3>' . L10n::t('Suggest Friends') . '</h3>';

View File

@ -1,318 +0,0 @@
<?php
/**
* @file mod/group.php
* @brief The group module (create and rename contact groups, add and
* remove contacts to the contact groups
*/
use Friendica\App;
use Friendica\BaseModule;
use Friendica\Core\Config;
use Friendica\Core\L10n;
use Friendica\Core\PConfig;
use Friendica\Core\Renderer;
use Friendica\Core\System;
use Friendica\Database\DBA;
use Friendica\Model;
use Friendica\Module;
use Friendica\Util\Security;
use Friendica\Util\Strings;
function group_init(App $a) {
if (local_user()) {
$a->page['aside'] = Model\Group::sidebarWidget('contacts', 'group', 'extended', (($a->argc > 1) ? $a->argv[1] : 'everyone'));
}
}
function group_post(App $a) {
if (!local_user()) {
notice(L10n::t('Permission denied.') . EOL);
return;
}
if (($a->argc == 2) && ($a->argv[1] === 'new')) {
BaseModule::checkFormSecurityTokenRedirectOnError('/group/new', 'group_edit');
$name = Strings::escapeTags(trim($_POST['groupname']));
$r = Model\Group::create(local_user(), $name);
if ($r) {
info(L10n::t('Group created.') . EOL);
$r = Model\Group::getIdByName(local_user(), $name);
if ($r) {
$a->internalRedirect('group/' . $r);
}
} else {
notice(L10n::t('Could not create group.') . EOL);
}
$a->internalRedirect('group');
return; // NOTREACHED
}
if (($a->argc == 2) && intval($a->argv[1])) {
BaseModule::checkFormSecurityTokenRedirectOnError('/group', 'group_edit');
$r = q("SELECT * FROM `group` WHERE `id` = %d AND `uid` = %d LIMIT 1",
intval($a->argv[1]),
intval(local_user())
);
if (!DBA::isResult($r)) {
notice(L10n::t('Group not found.') . EOL);
$a->internalRedirect('contact');
return; // NOTREACHED
}
$group = $r[0];
$groupname = Strings::escapeTags(trim($_POST['groupname']));
if (strlen($groupname) && ($groupname != $group['name'])) {
$r = q("UPDATE `group` SET `name` = '%s' WHERE `uid` = %d AND `id` = %d",
DBA::escape($groupname),
intval(local_user()),
intval($group['id'])
);
if ($r) {
info(L10n::t('Group name changed.') . EOL);
}
}
$a->page['aside'] = Model\Group::sidebarWidget();
}
return;
}
function group_content(App $a) {
$change = false;
if (!local_user()) {
notice(L10n::t('Permission denied') . EOL);
return;
}
// With no group number provided we jump to the unassigned contacts as a starting point
if ($a->argc == 1) {
$a->internalRedirect('group/none');
}
// Switch to text mode interface if we have more than 'n' contacts or group members
$switchtotext = PConfig::get(local_user(), 'system', 'groupedit_image_limit');
if (is_null($switchtotext)) {
$switchtotext = Config::get('system', 'groupedit_image_limit', 400);
}
$tpl = Renderer::getMarkupTemplate('group_edit.tpl');
$context = [
'$submit' => L10n::t('Save Group'),
'$submit_filter' => L10n::t('Filter'),
];
if (($a->argc == 2) && ($a->argv[1] === 'new')) {
return Renderer::replaceMacros($tpl, $context + [
'$title' => L10n::t('Create a group of contacts/friends.'),
'$gname' => ['groupname', L10n::t('Group Name: '), '', ''],
'$gid' => 'new',
'$form_security_token' => BaseModule::getFormSecurityToken("group_edit"),
]);
}
$nogroup = false;
if (($a->argc == 2) && ($a->argv[1] === 'none')) {
$id = -1;
$nogroup = true;
$group = [
'id' => $id,
'name' => L10n::t('Contacts not in any group'),
];
$members = [];
$preselected = [];
$entry = [];
$context = $context + [
'$title' => $group['name'],
'$gname' => ['groupname', L10n::t('Group Name: '), $group['name'], ''],
'$gid' => $id,
'$editable' => 0,
];
}
if (($a->argc == 3) && ($a->argv[1] === 'drop')) {
BaseModule::checkFormSecurityTokenRedirectOnError('/group', 'group_drop', 't');
if (intval($a->argv[2])) {
$r = q("SELECT `name` FROM `group` WHERE `id` = %d AND `uid` = %d LIMIT 1",
intval($a->argv[2]),
intval(local_user())
);
$result = null;
if (DBA::isResult($r)) {
$result = Model\Group::removeByName(local_user(), $r[0]['name']);
}
if ($result) {
info(L10n::t('Group removed.') . EOL);
} else {
notice(L10n::t('Unable to remove group.') . EOL);
}
}
$a->internalRedirect('group');
// NOTREACHED
}
if (($a->argc > 2) && intval($a->argv[1]) && intval($a->argv[2])) {
BaseModule::checkFormSecurityTokenForbiddenOnError('group_member_change', 't');
$r = q("SELECT `id` FROM `contact` WHERE `id` = %d AND `uid` = %d and `self` = 0 and `blocked` = 0 AND `pending` = 0 LIMIT 1",
intval($a->argv[2]),
intval(local_user())
);
if (DBA::isResult($r)) {
$change = intval($a->argv[2]);
}
}
if (($a->argc > 1) && intval($a->argv[1])) {
$r = q("SELECT * FROM `group` WHERE `id` = %d AND `uid` = %d AND `deleted` = 0 LIMIT 1",
intval($a->argv[1]),
intval(local_user())
);
if (!DBA::isResult($r)) {
notice(L10n::t('Group not found.') . EOL);
$a->internalRedirect('contact');
}
$group = $r[0];
$members = Model\Contact::getByGroupId($group['id']);
$preselected = [];
$entry = [];
$id = 0;
if (count($members)) {
foreach ($members as $member) {
$preselected[] = $member['id'];
}
}
if ($change) {
if (in_array($change, $preselected)) {
Model\Group::removeMember($group['id'], $change);
} else {
Model\Group::addMember($group['id'], $change);
}
$members = Model\Contact::getByGroupId($group['id']);
$preselected = [];
if (count($members)) {
foreach ($members as $member) {
$preselected[] = $member['id'];
}
}
}
$drop_tpl = Renderer::getMarkupTemplate('group_drop.tpl');
$drop_txt = Renderer::replaceMacros($drop_tpl, [
'$id' => $group['id'],
'$delete' => L10n::t('Delete Group'),
'$form_security_token' => BaseModule::getFormSecurityToken("group_drop"),
]);
$context = $context + [
'$title' => $group['name'],
'$gname' => ['groupname', L10n::t('Group Name: '), $group['name'], ''],
'$gid' => $group['id'],
'$drop' => $drop_txt,
'$form_security_token' => BaseModule::getFormSecurityToken('group_edit'),
'$edit_name' => L10n::t('Edit Group Name'),
'$editable' => 1,
];
}
if (!isset($group)) {
return;
}
$groupeditor = [
'label_members' => L10n::t('Members'),
'members' => [],
'label_contacts' => L10n::t('All Contacts'),
'group_is_empty' => L10n::t('Group is empty'),
'contacts' => [],
];
$sec_token = addslashes(BaseModule::getFormSecurityToken('group_member_change'));
// Format the data of the group members
foreach ($members as $member) {
if ($member['url']) {
$entry = Module\Contact::getContactTemplateVars($member);
$entry['label'] = 'members';
$entry['photo_menu'] = '';
$entry['change_member'] = [
'title' => L10n::t("Remove contact from group"),
'gid' => $group['id'],
'cid' => $member['id'],
'sec_token' => $sec_token
];
$groupeditor['members'][] = $entry;
} else {
Model\Group::removeMember($group['id'], $member['id']);
}
}
if ($nogroup) {
$r = Model\Contact::getUngroupedList(local_user());
} else {
$r = q("SELECT * FROM `contact` WHERE `uid` = %d AND NOT `blocked` AND NOT `pending` AND NOT `self` ORDER BY `name` ASC",
intval(local_user())
);
$context['$desc'] = L10n::t('Click on a contact to add or remove.');
}
if (DBA::isResult($r)) {
// Format the data of the contacts who aren't in the contact group
foreach ($r as $member) {
if (!in_array($member['id'], $preselected)) {
$entry = Module\Contact::getContactTemplateVars($member);
$entry['label'] = 'contacts';
if (!$nogroup)
$entry['photo_menu'] = [];
if (!$nogroup) {
$entry['change_member'] = [
'title' => L10n::t("Add contact to group"),
'gid' => $group['id'],
'cid' => $member['id'],
'sec_token' => $sec_token
];
}
$groupeditor['contacts'][] = $entry;
}
}
}
$context['$groupeditor'] = $groupeditor;
// If there are to many contacts we could provide an alternative view mode
$total = count($groupeditor['members']) + count($groupeditor['contacts']);
$context['$shortmode'] = (($switchtotext && ($total > $switchtotext)) ? true : false);
if ($change) {
$tpl = Renderer::getMarkupTemplate('groupeditor.tpl');
echo Renderer::replaceMacros($tpl, $context);
killme();
}
return Renderer::replaceMacros($tpl, $context);
}

View File

@ -8,6 +8,7 @@ use Friendica\Core\L10n;
use Friendica\Core\System;
use Friendica\Model\Contact;
use Friendica\Model\Profile;
use Friendica\Model\User;
function hcard_init(App $a)
{
@ -29,7 +30,7 @@ function hcard_init(App $a)
Profile::load($a, $which, $profile);
if (!empty($a->profile['page-flags']) && ($a->profile['page-flags'] == Contact::PAGE_COMMUNITY)) {
if (!empty($a->profile['page-flags']) && ($a->profile['page-flags'] == User::PAGE_FLAGS_COMMUNITY)) {
$a->page['htmlhead'] .= '<meta name="friendica.community" content="true" />';
}
if (!empty($a->profile['openidserver'])) {

View File

@ -33,6 +33,7 @@ function help_content(App $a)
Nav::setSelected('help');
$text = '';
$filename = '';
if ($a->argc > 1) {
$path = '';
@ -83,7 +84,7 @@ function help_content(App $a)
$level = intval($level);
if ($level < $lastlevel) {
for ($k = $level; $k < $lastlevel; $k++) {
$toc .= "</ul>";
$toc .= "</ul></li>";
}
for ($k = $level + 1; $k < count($idnum); $k++) {
@ -92,7 +93,7 @@ function help_content(App $a)
}
if ($level > $lastlevel) {
$toc .= "<ul>";
$toc .= "<li><ul>";
}
$idnum[$level] ++;

View File

@ -3,8 +3,8 @@
* @file mod/home.php
*/
use Friendica\App;
use Friendica\Core\Addon;
use Friendica\Core\Config;
use Friendica\Core\Hook;
use Friendica\Core\L10n;
use Friendica\Core\Renderer;
use Friendica\Core\System;
@ -14,7 +14,7 @@ if(! function_exists('home_init')) {
function home_init(App $a) {
$ret = [];
Addon::callHooks('home_init',$ret);
Hook::callAll('home_init',$ret);
if (local_user() && ($a->user['nickname'])) {
$a->internalRedirect('network');
@ -48,10 +48,10 @@ function home_content(App $a) {
}
}
$login = Login::form($a->query_string, intval(Config::get('config', 'register_policy')) === REGISTER_CLOSED ? 0 : 1);
$login = Login::form($a->query_string, intval(Config::get('config', 'register_policy')) === \Friendica\Module\Register::CLOSED ? 0 : 1);
$content = '';
Addon::callHooks("home_content",$content);
Hook::callAll("home_content",$content);
$tpl = Renderer::getMarkupTemplate('home.tpl');
@ -61,7 +61,4 @@ function home_content(App $a) {
'$login' => $login,
'$content' => $content
]);
return $o;
}}

View File

@ -41,13 +41,12 @@ function hovercard_content()
if ($datatype == 'tpl') {
$templatecontent = get_template_content('hovercard.tpl');
echo $templatecontent;
killme();
exit();
}
// If a contact is connected the url is internally changed to 'redir/CID'. We need the pure url to search for
// the contact. So we strip out the contact id from the internal url and look in the contact table for
// the real url (nurl)
$cid = 0;
if (strpos($profileurl, 'redir/') === 0) {
$cid = intval(substr($profileurl, 6));
$remote_contact = DBA::selectFirst('contact', ['nurl'], ['id' => $cid]);
@ -127,16 +126,19 @@ function hovercard_content()
* @brief Get the raw content of a template file
*
* @param string $template The name of the template
* @param string $root Directory of the template
* @param string $root Directory of the template
*
* @return string|bool Output the raw content if existent, otherwise false
* @throws Exception
*/
function get_template_content($template, $root = '')
{
// We load the whole template system to get the filename.
// Maybe we can do it a little bit smarter if I get time.
$t = Renderer::getMarkupTemplate($template, $root);
$filename = $t->filename;
$templateEngine = Renderer::getTemplateEngine();
$template = $templateEngine->getTemplateFile($template, $root);
$filename = $template->filename;
// Get the content of the template file
if (file_exists($filename)) {

View File

@ -1,27 +1,26 @@
<?php
use Friendica\App;
use Friendica\Core\System;
use Friendica\Database\DBA;
use Friendica\Model\Item;
function ignored_init(App $a)
{
if (!local_user()) {
killme();
exit();
}
if ($a->argc > 1) {
$message_id = intval($a->argv[1]);
}
if (!$message_id) {
killme();
if (empty($message_id)) {
exit();
}
$thread = Item::selectFirstThreadForUser(local_user(), ['uid', 'ignored'], ['iid' => $message_id]);
if (!DBA::isResult($thread)) {
killme();
exit();
}
// Numeric values are needed for the json output further below
@ -49,5 +48,5 @@ function ignored_init(App $a)
// the json doesn't really matter, it will either be 0 or 1
echo json_encode($ignored);
killme();
exit();
}

View File

@ -13,10 +13,8 @@ use Friendica\Core\L10n;
use Friendica\Core\PConfig;
use Friendica\Core\Renderer;
use Friendica\Core\System;
use Friendica\Database\DBA;
use Friendica\Module\Register;
use Friendica\Protocol\Email;
use Friendica\Util\DateTimeFormat;
use Friendica\Util\Security;
use Friendica\Util\Strings;
function invite_post(App $a)
@ -44,6 +42,8 @@ function invite_post(App $a)
$message = !empty($_POST['message']) ? Strings::escapeTags(trim($_POST['message'])) : '';
$total = 0;
$invitation_only = false;
$invites_remaining = null;
if (Config::get('system', 'invitation_only')) {
$invitation_only = true;
@ -126,14 +126,14 @@ function invite_content(App $a) {
$dirloc = Config::get('system', 'directory');
if (strlen($dirloc)) {
if (intval(Config::get('config', 'register_policy')) === REGISTER_CLOSED) {
if (intval(Config::get('config', 'register_policy')) === Register::CLOSED) {
$linktxt = L10n::t('Visit %s for a list of public sites that you can join. Friendica members on other sites can all connect with each other, as well as with members of many other social networks.', $dirloc . '/servers');
} else {
$linktxt = L10n::t('To accept this invitation, please visit and register at %s or any other public Friendica website.', System::baseUrl())
. "\r\n" . "\r\n" . L10n::t('Friendica sites all inter-connect to create a huge privacy-enhanced social web that is owned and controlled by its members. They can also connect with many traditional social networks. See %s for a list of alternate Friendica sites you can join.', $dirloc . '/servers');
}
} else { // there is no global directory URL defined
if (intval(Config::get('config', 'register_policy')) === REGISTER_CLOSED) {
if (intval(Config::get('config', 'register_policy')) === Register::CLOSED) {
$o = L10n::t('Our apologies. This system is not currently configured to connect with other public sites or invite members.');
return $o;
} else {

View File

@ -19,8 +19,8 @@ use Friendica\App;
use Friendica\Content\Pager;
use Friendica\Content\Text\BBCode;
use Friendica\Content\Text\HTML;
use Friendica\Core\Addon;
use Friendica\Core\Config;
use Friendica\Core\Hook;
use Friendica\Core\L10n;
use Friendica\Core\Logger;
use Friendica\Core\Protocol;
@ -31,6 +31,9 @@ use Friendica\Model\Contact;
use Friendica\Model\Conversation;
use Friendica\Model\FileTag;
use Friendica\Model\Item;
use Friendica\Model\Photo;
use Friendica\Model\Attach;
use Friendica\Model\Term;
use Friendica\Protocol\Diaspora;
use Friendica\Protocol\Email;
use Friendica\Util\DateTimeFormat;
@ -38,6 +41,8 @@ use Friendica\Util\Emailer;
use Friendica\Util\Security;
use Friendica\Util\Strings;
require_once 'include/items.php';
function item_post(App $a) {
if (!local_user() && !remote_user()) {
return 0;
@ -50,10 +55,10 @@ function item_post(App $a) {
drop_items($arr_drop);
$json = ['success' => 1];
echo json_encode($json);
killme();
exit();
}
Addon::callHooks('post_local_start', $_REQUEST);
Hook::callAll('post_local_start', $_REQUEST);
Logger::log('postvars ' . print_r($_REQUEST, true), Logger::DATA);
@ -79,13 +84,13 @@ function item_post(App $a) {
}
// Is this a reply to something?
$thr_parent = intval(defaults($_REQUEST, 'parent', 0));
$toplevel_item_id = intval(defaults($_REQUEST, 'parent', 0));
$thr_parent_uri = trim(defaults($_REQUEST, 'parent_uri', ''));
$thr_parent_contact = null;
$thread_parent_id = 0;
$thread_parent_contact = null;
$parent = 0;
$parent_item = null;
$toplevel_item = null;
$parent_user = null;
$parent_contact = null;
@ -94,42 +99,41 @@ function item_post(App $a) {
$profile_uid = defaults($_REQUEST, 'profile_uid', local_user());
$posttype = defaults($_REQUEST, 'post_type', Item::PT_ARTICLE);
if ($thr_parent || $thr_parent_uri) {
if ($thr_parent) {
$parent_item = Item::selectFirst([], ['id' => $thr_parent]);
if ($toplevel_item_id || $thr_parent_uri) {
if ($toplevel_item_id) {
$toplevel_item = Item::selectFirst([], ['id' => $toplevel_item_id]);
} elseif ($thr_parent_uri) {
$parent_item = Item::selectFirst([], ['uri' => $thr_parent_uri, 'uid' => $profile_uid]);
$toplevel_item = Item::selectFirst([], ['uri' => $thr_parent_uri, 'uid' => $profile_uid]);
}
// if this isn't the real parent of the conversation, find it
if (DBA::isResult($parent_item)) {
// if this isn't the top-level parent of the conversation, find it
if (DBA::isResult($toplevel_item)) {
// The URI and the contact is taken from the direct parent which needn't to be the top parent
$thr_parent_uri = $parent_item['uri'];
$thr_parent_contact = Contact::getDetailsByURL($parent_item["author-link"]);
$thread_parent_id = $toplevel_item['id'];
$thr_parent_uri = $toplevel_item['uri'];
$thread_parent_contact = Contact::getDetailsByURL($toplevel_item["author-link"]);
if ($parent_item['id'] != $parent_item['parent']) {
$parent_item = Item::selectFirst(Item::ITEM_FIELDLIST, ['id' => $parent_item['parent']]);
if ($toplevel_item['id'] != $toplevel_item['parent']) {
$toplevel_item = Item::selectFirst(Item::ITEM_FIELDLIST, ['id' => $toplevel_item['parent']]);
}
}
if (!DBA::isResult($parent_item)) {
if (!DBA::isResult($toplevel_item)) {
notice(L10n::t('Unable to locate original post.') . EOL);
if (!empty($_REQUEST['return'])) {
$a->internalRedirect($return_path);
}
killme();
exit();
}
$parent = $parent_item['id'];
$parent_user = $parent_item['uid'];
$parent_contact = Contact::getDetailsByURL($parent_item["author-link"]);
$toplevel_item_id = $toplevel_item['id'];
$parent_user = $toplevel_item['uid'];
$objecttype = ACTIVITY_OBJ_COMMENT;
}
if ($parent) {
Logger::log('mod_item: item_post parent=' . $parent);
if ($toplevel_item_id) {
Logger::info('mod_item: item_post parent=' . $toplevel_item_id);
}
$post_id = intval(defaults($_REQUEST, 'post_id', 0));
@ -158,7 +162,7 @@ function item_post(App $a) {
}
// Allow commenting if it is an answer to a public post
$allow_comment = local_user() && ($profile_uid == 0) && $parent && in_array($parent_item['network'], [Protocol::ACTIVITYPUB, Protocol::OSTATUS, Protocol::DIASPORA, Protocol::DFRN]);
$allow_comment = local_user() && ($profile_uid == 0) && $toplevel_item_id && in_array($toplevel_item['network'], [Protocol::ACTIVITYPUB, Protocol::OSTATUS, Protocol::DIASPORA, Protocol::DFRN]);
// Now check that valid personal details have been provided
if (!Security::canWriteToUserWall($profile_uid) && !$allow_comment) {
@ -168,7 +172,7 @@ function item_post(App $a) {
$a->internalRedirect($return_path);
}
killme();
exit();
}
// Init post instance
@ -181,13 +185,47 @@ function item_post(App $a) {
$user = DBA::selectFirst('user', [], ['uid' => $profile_uid]);
if (!DBA::isResult($user) && !$parent) {
if (!DBA::isResult($user) && !$toplevel_item_id) {
return 0;
}
$categories = '';
$postopts = '';
$emailcc = '';
$body = defaults($_REQUEST, 'body', '');
$has_attachment = defaults($_REQUEST, 'has_attachment', 0);
// If we have a speparate attachment, we need to add it to the body.
if (!empty($has_attachment)) {
$attachment_type = defaults($_REQUEST, 'attachment_type', '');
$attachment_title = defaults($_REQUEST, 'attachment_title', '');
$attachment_text = defaults($_REQUEST, 'attachment_text', '');
$attachment_url = hex2bin(defaults($_REQUEST, 'attachment_url', ''));
$attachment_img_src = hex2bin(defaults($_REQUEST, 'attachment_img_src', ''));
$attachment_img_width = defaults($_REQUEST, 'attachment_img_width', 0);
$attachment_img_height = defaults($_REQUEST, 'attachment_img_height', 0);
$attachment = [
'type' => $attachment_type,
'title' => $attachment_title,
'text' => $attachment_text,
'url' => $attachment_url,
];
if (!empty($attachment_img_src)) {
$attachment['images'] = [
0 => [
'src' => $attachment_img_src,
'width' => $attachment_img_width,
'height' => $attachment_img_height
]
];
}
$att_bbcode = add_page_info_data($attachment);
$body .= $att_bbcode;
}
if (!empty($orig_post)) {
$str_group_allow = $orig_post['allow_gid'];
@ -201,7 +239,7 @@ function item_post(App $a) {
$app = $orig_post['app'];
$categories = $orig_post['file'];
$title = Strings::escapeTags(trim($_REQUEST['title']));
$body = Strings::escapeHtml(trim($_REQUEST['body']));
$body = Strings::escapeHtml(trim($body));
$private = $orig_post['private'];
$pubmail_enabled = $orig_post['pubmail'];
$network = $orig_post['network'];
@ -237,7 +275,7 @@ function item_post(App $a) {
$coord = Strings::escapeTags(trim(defaults($_REQUEST, 'coord' , '')));
$verb = Strings::escapeTags(trim(defaults($_REQUEST, 'verb' , '')));
$emailcc = Strings::escapeTags(trim(defaults($_REQUEST, 'emailcc' , '')));
$body = Strings::escapeHtml(trim(defaults($_REQUEST, 'body' , '')));
$body = Strings::escapeHtml(trim($body));
$network = Strings::escapeTags(trim(defaults($_REQUEST, 'network' , Protocol::DFRN)));
$guid = System::createUUID();
@ -251,21 +289,21 @@ function item_post(App $a) {
// If this is a comment, set the permissions from the parent.
if ($parent_item) {
if ($toplevel_item) {
// for non native networks use the network of the original post as network of the item
if (($parent_item['network'] != Protocol::DIASPORA)
&& ($parent_item['network'] != Protocol::OSTATUS)
if (($toplevel_item['network'] != Protocol::DIASPORA)
&& ($toplevel_item['network'] != Protocol::OSTATUS)
&& ($network == "")) {
$network = $parent_item['network'];
$network = $toplevel_item['network'];
}
$str_contact_allow = $parent_item['allow_cid'];
$str_group_allow = $parent_item['allow_gid'];
$str_contact_deny = $parent_item['deny_cid'];
$str_group_deny = $parent_item['deny_gid'];
$private = $parent_item['private'];
$str_contact_allow = $toplevel_item['allow_cid'];
$str_group_allow = $toplevel_item['allow_gid'];
$str_contact_deny = $toplevel_item['deny_cid'];
$str_group_deny = $toplevel_item['deny_gid'];
$private = $toplevel_item['private'];
$wall = $parent_item['wall'];
$wall = $toplevel_item['wall'];
}
$pubmail_enabled = defaults($_REQUEST, 'pubmail_enable', false) && !$private;
@ -279,13 +317,13 @@ function item_post(App $a) {
if (!strlen($body)) {
if ($preview) {
killme();
exit();
}
info(L10n::t('Empty post discarded.') . EOL);
if (!empty($_REQUEST['return'])) {
$a->internalRedirect($return_path);
}
killme();
exit();
}
}
@ -346,12 +384,8 @@ function item_post(App $a) {
$tags = BBCode::getTags($body);
// Add a tag if the parent contact is from ActivityPub or OStatus (This will notify them)
if ($parent && in_array($thr_parent_contact['network'], [Protocol::OSTATUS, Protocol::ACTIVITYPUB])) {
$contact = '@[url=' . $thr_parent_contact['url'] . ']' . $thr_parent_contact['nick'] . '[/url]';
if (!stripos(implode($tags), '[url=' . $thr_parent_contact['url'] . ']')) {
$tags[] = $contact;
}
if ($thread_parent_id && !\Friendica\Content\Feature::isEnabled($uid, 'explicit_mentions')) {
$tags = item_add_implicit_mentions($tags, $thread_parent_contact, $thread_parent_id);
}
$tagged = [];
@ -364,7 +398,7 @@ function item_post(App $a) {
foreach ($tags as $tag) {
$tag_type = substr($tag, 0, 1);
if ($tag_type == '#') {
if ($tag_type == Term::TAG_CHARACTER[Term::HASHTAG]) {
continue;
}
@ -384,14 +418,14 @@ function item_post(App $a) {
continue;
}
$success = handle_tag($a, $body, $inform, $str_tags, local_user() ? local_user() : $profile_uid, $tag, $network);
$success = handle_tag($body, $inform, $str_tags, local_user() ? local_user() : $profile_uid, $tag, $network);
if ($success['replaced']) {
$tagged[] = $tag;
}
// When the forum is private or the forum is addressed with a "!" make the post private
if (is_array($success['contact']) && (!empty($success['contact']['prv']) || ($tag_type == '!'))) {
if (is_array($success['contact']) && (!empty($success['contact']['prv']) || ($tag_type == Term::TAG_CHARACTER[Term::EXCLUSIVE_MENTION]))) {
$private_forum = $success['contact']['prv'];
$only_to_forum = ($tag_type == '!');
$only_to_forum = ($tag_type == Term::TAG_CHARACTER[Term::EXCLUSIVE_MENTION]);
$private_id = $success['contact']['id'];
$forum_contact = $success['contact'];
} elseif (is_array($success['contact']) && !empty($success['contact']['forum']) &&
@ -406,7 +440,7 @@ function item_post(App $a) {
$original_contact_id = $contact_id;
if (!$parent && count($forum_contact) && ($private_forum || $only_to_forum)) {
if (!$toplevel_item_id && count($forum_contact) && ($private_forum || $only_to_forum)) {
// we tagged a forum in a top level post. Now we change the post
$private = $private_forum;
@ -456,16 +490,18 @@ function item_post(App $a) {
// Ensure to only modify photos that you own
$srch = '<' . intval($original_contact_id) . '>';
$condition = ['allow_cid' => $srch, 'allow_gid' => '', 'deny_cid' => '', 'deny_gid' => '',
'resource-id' => $image_uri, 'uid' => $profile_uid];
if (!DBA::exists('photo', $condition)) {
$condition = [
'allow_cid' => $srch, 'allow_gid' => '', 'deny_cid' => '', 'deny_gid' => '',
'resource-id' => $image_uri, 'uid' => $profile_uid
];
if (!Photo::exists($condition)) {
continue;
}
$fields = ['allow_cid' => $str_contact_allow, 'allow_gid' => $str_group_allow,
'deny_cid' => $str_contact_deny, 'deny_gid' => $str_group_deny];
$condition = ['resource-id' => $image_uri, 'uid' => $profile_uid];
DBA::update('photo', $fields, $condition);
Photo::update($fields, $condition);
}
}
}
@ -486,14 +522,14 @@ function item_post(App $a) {
$condition = ['allow_cid' => $srch, 'allow_gid' => '', 'deny_cid' => '', 'deny_gid' => '',
'id' => $attach];
if (!DBA::exists('attach', $condition)) {
if (!Attach::exists($condition)) {
continue;
}
$fields = ['allow_cid' => $str_contact_allow, 'allow_gid' => $str_group_allow,
'deny_cid' => $str_contact_deny, 'deny_gid' => $str_group_deny];
$condition = ['id' => $attach];
DBA::update('attach', $fields, $condition);
Attach::update($fields, $condition);
}
}
}
@ -536,8 +572,8 @@ function item_post(App $a) {
if (preg_match_all('/(\[attachment\]([0-9]+)\[\/attachment\])/',$body,$match)) {
foreach ($match[2] as $mtch) {
$fields = ['id', 'filename', 'filesize', 'filetype'];
$attachment = DBA::selectFirst('attach', $fields, ['id' => $mtch]);
if (DBA::isResult($attachment)) {
$attachment = Attach::selectFirst($fields, ['id' => $mtch]);
if ($attachment !== false) {
if (strlen($attachments)) {
$attachments .= ',';
}
@ -557,7 +593,7 @@ function item_post(App $a) {
$network = Protocol::DFRN;
}
$gravity = ($parent ? GRAVITY_COMMENT : GRAVITY_PARENT);
$gravity = ($toplevel_item_id ? GRAVITY_COMMENT : GRAVITY_PARENT);
// even if the post arrived via API we are considering that it
// originated on this site by default for determining relayability.
@ -569,12 +605,12 @@ function item_post(App $a) {
$origin = $_REQUEST['origin'];
}
$notify_type = ($parent ? 'comment-new' : 'wall-new');
$notify_type = ($toplevel_item_id ? 'comment-new' : 'wall-new');
$uri = ($message_id ? $message_id : Item::newURI($api_source ? $profile_uid : $uid, $guid));
// Fallback so that we alway have a parent uri
if (!$thr_parent_uri || !$parent) {
if (!$thr_parent_uri || !$toplevel_item_id) {
$thr_parent_uri = $uri;
}
@ -632,7 +668,7 @@ function item_post(App $a) {
* 'self' if true indicates the owner is posting on their own wall
* If parent is 0 it is a top-level post.
*/
$datarray['parent'] = $parent;
$datarray['parent'] = $toplevel_item_id;
$datarray['self'] = $self;
// This triggers posts via API and the mirror functions
@ -676,7 +712,7 @@ function item_post(App $a) {
exit();
}
Addon::callHooks('post_local',$datarray);
Hook::callAll('post_local',$datarray);
if (!empty($datarray['cancel'])) {
Logger::log('mod_item: post cancelled by addon.');
@ -690,7 +726,7 @@ function item_post(App $a) {
}
echo json_encode($json);
killme();
exit();
}
if ($orig_post) {
@ -718,9 +754,7 @@ function item_post(App $a) {
Logger::log('return: ' . $return_path);
$a->internalRedirect($return_path);
}
killme();
} else {
$post_id = 0;
exit();
}
unset($datarray['edit']);
@ -752,7 +786,7 @@ function item_post(App $a) {
FileTag::updatePconfig($uid, $categories_old, $categories_new, 'category');
// These notifications are sent if someone else is commenting other your wall
if ($parent) {
if ($toplevel_item_id) {
if ($contact_record != $author) {
notification([
'type' => NOTIFY_COMMENT,
@ -768,8 +802,8 @@ function item_post(App $a) {
'source_photo' => $datarray['author-avatar'],
'verb' => ACTIVITY_POST,
'otype' => 'item',
'parent' => $parent,
'parent_uri' => $parent_item['uri']
'parent' => $toplevel_item_id,
'parent_uri' => $toplevel_item['uri']
]);
}
} else {
@ -792,7 +826,7 @@ function item_post(App $a) {
}
}
Addon::callHooks('post_local_end', $datarray);
Hook::callAll('post_local_end', $datarray);
if (strlen($emailcc) && $profile_uid == local_user()) {
$erecips = explode(',', $emailcc);
@ -871,7 +905,7 @@ function item_post_return($baseurl, $api_source, $return_path)
Logger::log('post_json: ' . print_r($json, true), Logger::DEBUG);
echo json_encode($json);
killme();
exit();
}
function item_content(App $a)
@ -897,7 +931,7 @@ function item_content(App $a)
if ($a->isAjax()) {
// ajax return: [<item id>, 0 (no perm) | <owner id>]
echo json_encode([intval($a->argv[2]), intval($o)]);
killme();
exit();
}
}
@ -906,26 +940,27 @@ function item_content(App $a)
/**
* This function removes the tag $tag from the text $body and replaces it with
* the appropiate link.
* the appropriate link.
*
* @param App $a Application instance @TODO is unused in this function's scope (excluding included files)
* @param unknown_type $body the text to replace the tag in
* @param string $inform a comma-seperated string containing everybody to inform
* @param string $str_tags string to add the tag to
* @param App $a
* @param string $body the text to replace the tag in
* @param string $inform a comma-seperated string containing everybody to inform
* @param string $str_tags string to add the tag to
* @param integer $profile_uid
* @param string $tag the tag to replace
* @param string $network The network of the post
* @param string $tag the tag to replace
* @param string $network The network of the post
*
* @return boolean true if replaced, false if not replaced
* @return array|bool ['replaced' => $replaced, 'contact' => $contact];
* @throws ImagickException
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
function handle_tag(App $a, &$body, &$inform, &$str_tags, $profile_uid, $tag, $network = "")
function handle_tag(&$body, &$inform, &$str_tags, $profile_uid, $tag, $network = "")
{
$replaced = false;
$r = null;
$tag_type = '@';
//is it a person tag?
if ((strpos($tag, '@') === 0) || (strpos($tag, '!') === 0)) {
if (Term::isType($tag, Term::MENTION, Term::IMPLICIT_MENTION, Term::EXCLUSIVE_MENTION)) {
$tag_type = substr($tag, 0, 1);
//is it already replaced?
if (strpos($tag, '[url=')) {
@ -958,7 +993,6 @@ function handle_tag(App $a, &$body, &$inform, &$str_tags, $profile_uid, $tag, $n
return $replaced;
}
$stat = false;
//get the person's name
$name = substr($tag, 1);
@ -1049,7 +1083,7 @@ function handle_tag(App $a, &$body, &$inform, &$str_tags, $profile_uid, $tag, $n
* Status.Net seems to require the numeric ID URL in a mention if the person isn't
* subscribed to you. But the nickname URL is OK if they are. Grrr. We'll tag both.
*/
if (strlen($alias)) {
if (!empty($alias)) {
$newtag = '@[url=' . $alias . ']' . $newname . '[/url]';
if (!stripos($str_tags, '[url=' . $alias . ']')) {
if (strlen($str_tags)) {
@ -1063,3 +1097,34 @@ function handle_tag(App $a, &$body, &$inform, &$str_tags, $profile_uid, $tag, $n
return ['replaced' => $replaced, 'contact' => $contact];
}
function item_add_implicit_mentions(array $tags, array $thread_parent_contact, $thread_parent_id)
{
if (Config::get('system', 'disable_implicit_mentions')) {
// Add a tag if the parent contact is from ActivityPub or OStatus (This will notify them)
if (in_array($thread_parent_contact['network'], [Protocol::OSTATUS, Protocol::ACTIVITYPUB])) {
$contact = Term::TAG_CHARACTER[Term::MENTION] . '[url=' . $thread_parent_contact['url'] . ']' . $thread_parent_contact['nick'] . '[/url]';
if (!stripos(implode($tags), '[url=' . $thread_parent_contact['url'] . ']')) {
$tags[] = $contact;
}
}
} else {
$implicit_mentions = [
$thread_parent_contact['url'] => $thread_parent_contact['nick']
];
$parent_terms = Term::tagArrayFromItemId($thread_parent_id, [Term::MENTION, Term::IMPLICIT_MENTION]);
foreach ($parent_terms as $parent_term) {
$implicit_mentions[$parent_term['url']] = $parent_term['term'];
}
foreach ($implicit_mentions as $url => $label) {
if ($url != \Friendica\Model\Profile::getMyURL() && !stripos(implode($tags), '[url=' . $url . ']')) {
$tags[] = Term::TAG_CHARACTER[Term::IMPLICIT_MENTION] . '[url=' . $url . ']' . $label . '[/url]';
}
}
}
return $tags;
}

View File

@ -1,7 +1,6 @@
<?php
use Friendica\App;
use Friendica\Core\System;
use Friendica\Model\Item;
use Friendica\Util\Strings;
@ -28,7 +27,7 @@ function like_content(App $a) {
$return_path = defaults($_REQUEST, 'return', '');
like_content_return($a, $return_path);
killme(); // NOTREACHED
exit();
}
@ -46,6 +45,4 @@ function like_content_return(App $a, $return_path) {
$a->internalRedirect($return_path . $rand);
}
killme();
}

View File

@ -3,7 +3,7 @@
* @file mod/lockview.php
*/
use Friendica\App;
use Friendica\Core\Addon;
use Friendica\Core\Hook;
use Friendica\Core\L10n;
use Friendica\Database\DBA;
use Friendica\Model\Item;
@ -19,11 +19,11 @@ function lockview_content(App $a)
}
if (!$item_id) {
killme();
exit();
}
if (!in_array($type, ['item','photo','event'])) {
killme();
exit();
}
$fields = ['uid', 'allow_cid', 'allow_gid', 'deny_cid', 'deny_gid'];
@ -37,14 +37,14 @@ function lockview_content(App $a)
}
if (!DBA::isResult($item)) {
killme();
exit();
}
Addon::callHooks('lockview_content', $item);
Hook::callAll('lockview_content', $item);
if ($item['uid'] != local_user()) {
echo L10n::t('Remote privacy information not available.') . '<br />';
killme();
exit();
}
if (isset($item['private'])
@ -55,7 +55,7 @@ function lockview_content(App $a)
&& empty($item['deny_gid']))
{
echo L10n::t('Remote privacy information not available.') . '<br />';
killme();
exit();
}
$allowed_users = expand_acl($item['allow_cid']);
@ -111,6 +111,6 @@ function lockview_content(App $a)
}
echo $o . implode(', ', $l);
killme();
exit();
}

View File

@ -81,7 +81,6 @@ function lostpass_post(App $a)
function lostpass_content(App $a)
{
$o = '';
if ($a->argc > 1) {
$pwdreset_token = $a->argv[1];
@ -127,7 +126,6 @@ function lostpass_form()
function lostpass_generate_password($user)
{
$o = '';
$a = \get_app();
$new_password = User::generateNewPassword();
$result = User::updatePassword($user['uid'], $new_password);

View File

@ -4,10 +4,9 @@
*/
use Friendica\App;
use Friendica\Core\Authentication;
use Friendica\Core\Addon;
use Friendica\Core\Hook;
use Friendica\Core\L10n;
use Friendica\Core\Renderer;
use Friendica\Core\System;
use Friendica\Database\DBA;
function manage_post(App $a) {
@ -116,7 +115,7 @@ function manage_post(App $a) {
}
$ret = [];
Addon::callHooks('home_init',$ret);
Hook::callAll('home_init',$ret);
$a->internalRedirect('profile/' . $a->user['nickname'] );
// NOTREACHED

View File

@ -24,5 +24,5 @@ function manifest_content(App $a) {
echo $o;
killme();
exit();
}

View File

@ -25,6 +25,9 @@ use Friendica\Util\Proxy as ProxyUtils;
* @param App $a App
*
* @return string
* @throws ImagickException
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
* @throws Exception
*/
function match_content(App $a)
{
@ -72,7 +75,7 @@ function match_content(App $a)
$profile = $msearch->results[$i];
// Already known contact
if (Contact::getIdForURL($profile->url, local_user(), true)) {
if (!$profile || Contact::getIdForURL($profile->url, local_user(), true)) {
continue;
}

View File

@ -185,7 +185,6 @@ function message_content(App $a)
);
if (DBA::isResult($r)) {
$parent = $r[0]['parent-uri'];
$convid = $r[0]['convid'];
if (DBA::delete('mail', ['parent-uri' => $parent, 'uid' => local_user()])) {
info(L10n::t('Conversation removed.') . EOL);
@ -230,7 +229,6 @@ function message_content(App $a)
if (DBA::isResult($r)) {
$prename = $r[0]['name'];
$preurl = $r[0]['url'];
$preid = $r[0]['id'];
$preselect = [$preid];
} else {

View File

@ -6,7 +6,7 @@ use Friendica\Database\DBA;
function modexp_init(App $a) {
if($a->argc != 2)
killme();
exit();
$nick = $a->argv[1];
$r = q("SELECT `spubkey` FROM `user` WHERE `nickname` = '%s' LIMIT 1",
@ -14,7 +14,7 @@ function modexp_init(App $a) {
);
if (! DBA::isResult($r)) {
killme();
exit();
}
$lines = explode("\n",$r[0]['spubkey']);
@ -30,7 +30,7 @@ function modexp_init(App $a) {
header("Content-type: application/magic-public-key");
echo 'RSA' . '.' . $m . '.' . $e;
killme();
exit();
}

View File

@ -20,6 +20,8 @@ function msearch_post(App $a)
exit();
}
$total = 0;
$count_stmt = DBA::p(
"SELECT COUNT(*) AS `total`
FROM `profile`
@ -29,7 +31,6 @@ function msearch_post(App $a)
AND MATCH(`pub_keywords`) AGAINST (?)",
$search
);
if (DBA::isResult($count_stmt)) {
$row = DBA::fetch($count_stmt);
$total = $row['total'];

View File

@ -12,7 +12,6 @@ use Friendica\Content\Pager;
use Friendica\Content\Widget;
use Friendica\Content\Text\HTML;
use Friendica\Core\ACL;
use Friendica\Core\Addon;
use Friendica\Core\Config;
use Friendica\Core\Hook;
use Friendica\Core\L10n;
@ -25,6 +24,7 @@ use Friendica\Model\Contact;
use Friendica\Model\Group;
use Friendica\Model\Item;
use Friendica\Model\Profile;
use Friendica\Model\Term;
use Friendica\Module\Login;
use Friendica\Util\DateTimeFormat;
use Friendica\Util\Proxy as ProxyUtils;
@ -201,15 +201,16 @@ function saved_searches($search)
* Return selected tab from query
*
* urls -> returns
* '/network' => $no_active = 'active'
* '/network?f=&order=comment' => $comment_active = 'active'
* '/network?f=&order=post' => $postord_active = 'active'
* '/network?f=&conv=1', => $conv_active = 'active'
* '/network/new', => $new_active = 'active'
* '/network?f=&star=1', => $starred_active = 'active'
* '/network?f=&bmark=1', => $bookmarked_active = 'active'
* '/network' => $no_active = 'active'
* '/network?f=&order=comment' => $comment_active = 'active'
* '/network?f=&order=post' => $postord_active = 'active'
* '/network?f=&conv=1', => $conv_active = 'active'
* '/network/new', => $new_active = 'active'
* '/network?f=&star=1', => $starred_active = 'active'
* '/network?f=&bmark=1', => $bookmarked_active = 'active'
*
* @return Array ($no_active, $comment_active, $postord_active, $conv_active, $new_active, $starred_active, $bookmarked_active);
* @param App $a
* @return array ($no_active, $comment_active, $postord_active, $conv_active, $new_active, $starred_active, $bookmarked_active);
*/
function network_query_get_sel_tab(App $a)
{
@ -265,9 +266,11 @@ function network_query_get_sel_group(App $a)
/**
* @brief Sets the pager data and returns SQL
*
* @param App $a The global App
* @param App $a The global App
* @param Pager $pager
* @param integer $update Used for the automatic reloading
* @return string SQL with the appropriate LIMIT clause
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
function networkPager(App $a, Pager $pager, $update)
{
@ -301,6 +304,7 @@ function networkPager(App $a, Pager $pager, $update)
* @brief Sets items as seen
*
* @param array $condition The array with the SQL condition
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
function networkSetSeen($condition)
{
@ -311,7 +315,7 @@ function networkSetSeen($condition)
$unseen = Item::exists($condition);
if ($unseen) {
$r = Item::update(['unseen' => false], $condition);
Item::update(['unseen' => false], $condition);
}
}
@ -320,9 +324,13 @@ function networkSetSeen($condition)
*
* @param App $a The global App
* @param array $items Items of the conversation
* @param Pager $pager
* @param string $mode Display mode for the conversation
* @param integer $update Used for the automatic reloading
* @param string $ordering
* @return string HTML of the conversation
* @throws ImagickException
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
function networkConversation(App $a, $items, Pager $pager, $mode, $update, $ordering = '')
{
@ -355,7 +363,7 @@ function network_content(App $a, $update = 0, $parent = 0)
/// @TODO Is this really necessary? $a is already available to hooks
$arr = ['query' => $a->query_string];
Addon::callHooks('network_content_init', $arr);
Hook::callAll('network_content_init', $arr);
$flat_mode = false;
@ -387,10 +395,12 @@ function network_content(App $a, $update = 0, $parent = 0)
/**
* @brief Get the network content in flat view
*
* @param Pager $pager
* @param App $a The global App
* @param integer $update Used for the automatic reloading
* @return string HTML of the network content in flat view
* @throws ImagickException
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
* @global Pager $pager
*/
function networkFlatView(App $a, $update = 0)
{
@ -398,12 +408,6 @@ function networkFlatView(App $a, $update = 0)
// Rawmode is used for fetching new content at the end of the page
$rawmode = (isset($_GET['mode']) && ($_GET['mode'] == 'raw'));
if (isset($_GET['last_id'])) {
$last_id = intval($_GET['last_id']);
} else {
$last_id = 0;
}
$o = '';
$file = defaults($_GET, 'file', '');
@ -440,14 +444,15 @@ function networkFlatView(App $a, $update = 0)
$pager = new Pager($a->query_string);
/// @TODO Figure out why this variable is unused
$pager_sql = networkPager($a, $pager, $update);
networkPager($a, $pager, $update);
$item_params = ['order' => ['id' => true]];
if (strlen($file)) {
$condition = ["`term` = ? AND `otype` = ? AND `type` = ? AND `uid` = ?",
$file, TERM_OBJ_POST, TERM_FILE, local_user()];
$params = ['order' => ['tid' => true], 'limit' => [$pager->getStart(), $pager->getItemsPerPage()]];
$result = DBA::select('term', ['oid'], $condition);
$term_condition = ["`term` = ? AND `otype` = ? AND `type` = ? AND `uid` = ?",
$file, Term::OBJECT_TYPE_POST, Term::FILE, local_user()];
$term_params = ['order' => ['tid' => true], 'limit' => [$pager->getStart(), $pager->getItemsPerPage()]];
$result = DBA::select('term', ['oid'], $term_condition, $term_params);
$posts = [];
while ($term = DBA::fetch($result)) {
@ -458,18 +463,16 @@ function networkFlatView(App $a, $update = 0)
if (count($posts) == 0) {
return '';
}
$condition = ['uid' => local_user(), 'id' => $posts];
$item_condition = ['uid' => local_user(), 'id' => $posts];
} else {
$condition = ['uid' => local_user()];
$item_condition = ['uid' => local_user()];
$item_params['limit'] = [$pager->getStart(), $pager->getItemsPerPage()];
networkSetSeen(['unseen' => true, 'uid' => local_user()]);
}
$params = ['order' => ['id' => true], 'limit' => [$pager->getStart(), $pager->getItemsPerPage()]];
$result = Item::selectForUser(local_user(), [], $condition, $params);
$result = Item::selectForUser(local_user(), [], $item_condition, $item_params);
$items = Item::inArray($result);
$condition = ['unseen' => true, 'uid' => local_user()];
networkSetSeen($condition);
$o .= networkConversation($a, $items, $pager, 'network-new', $update);
return $o;
@ -478,11 +481,13 @@ function networkFlatView(App $a, $update = 0)
/**
* @brief Get the network content in threaded view
*
* @global Pager $pager
* @param App $a The global App
* @param integer $update Used for the automatic reloading
* @param integer $parent
* @return string HTML of the network content in flat view
* @throws ImagickException
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
* @global Pager $pager
*/
function networkThreadedView(App $a, $update, $parent)
{
@ -521,7 +526,7 @@ function networkThreadedView(App $a, $update, $parent)
}
} elseif (intval($a->argv[$x])) {
$gid = intval($a->argv[$x]);
$default_permissions = ['allow_gid' => '<' . $gid . '>'];
$default_permissions['allow_gid'] = [$gid];
}
}
}
@ -535,20 +540,28 @@ function networkThreadedView(App $a, $update, $parent)
$order = Strings::escapeTags(defaults($_GET, 'order', 'comment'));
$nets = defaults($_GET, 'nets' , '');
$allowedCids = [];
if ($cid) {
$default_permissions = ['allow_cid' => '<' . intval($cid) . '>'];
$allowedCids[] = (int) $cid;
} elseif ($nets) {
$condition = [
'uid' => local_user(),
'network' => $nets,
'self' => false,
'blocked' => false,
'pending' => false,
'archive' => false,
'rel' => [Contact::SHARING, Contact::FRIEND],
];
$contactStmt = DBA::select('contact', ['id'], $condition);
while ($contact = DBA::fetch($contactStmt)) {
$allowedCids[] = (int) $contact['id'];
}
DBA::close($contactStmt);
}
if ($nets) {
$r = DBA::select('contact', ['id'], ['uid' => local_user(), 'network' => $nets], ['self' => false]);
$str = '';
while ($rr = DBA::fetch($r)) {
$str .= '<' . $rr['id'] . '>';
}
if (strlen($str)) {
$default_permissions = ['allow_cid' => $str];
}
if (count($allowedCids)) {
$default_permissions['allow_cid'] = $allowedCids;
}
if (!$update && !$rawmode) {
@ -610,7 +623,6 @@ function networkThreadedView(App $a, $update, $parent)
$sql_extra3 = '';
$sql_table = '`thread`';
$sql_parent = '`iid`';
$sql_order = '';
if ($update) {
$sql_table = '`item`';
@ -625,7 +637,7 @@ function networkThreadedView(App $a, $update, $parent)
$group = DBA::selectFirst('group', ['name'], ['id' => $gid, 'uid' => local_user()]);
if (!DBA::isResult($group)) {
if ($update) {
killme();
exit();
}
notice(L10n::t('No such group') . EOL);
$a->internalRedirect('network/0');
@ -941,6 +953,7 @@ function networkThreadedView(App $a, $update, $parent)
*
* @param App $a The global App
* @return string Html of the networktab
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
function network_tabs(App $a)
{
@ -1024,7 +1037,7 @@ function network_tabs(App $a)
}
$arr = ['tabs' => $tabs];
Addon::callHooks('network_tabs', $arr);
Hook::callAll('network_tabs', $arr);
$tpl = Renderer::getMarkupTemplate('common_tabs.tpl');
@ -1040,13 +1053,17 @@ function network_tabs(App $a)
* of the page to make the correct asynchronous call. This is obtained through the Pager that was instantiated in
* networkThreadedView or networkFlatView.
*
* @global Pager $pager
* @param App $a
* @param App $a
* @param string $htmlhead The head tag HTML string
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
* @global Pager $pager
*/
function network_infinite_scroll_head(App $a, &$htmlhead)
{
/// @TODO this will have to be converted to a static property of the converted Module\Network class
/**
* @var $pager Pager
*/
global $pager;
if (PConfig::get(local_user(), 'system', 'infinite_scroll')

View File

@ -15,7 +15,7 @@ function newmember_content(App $a)
$o .= L10n::t('We would like to offer some tips and links to help make your experience enjoyable. Click any item to visit the relevant page. A link to this page will be visible from your home page for two weeks after your initial registration and then will quietly disappear.');
$o .= '<h4>' . L10n::t('Getting Started') . '</h4>';
$o .= '<ul>';
$o .= '<li> ' . '<a target="newmember" href="help/guide">' . L10n::t('Friendica Walk-Through') . '</a><br />' . L10n::t('On your <em>Quick Start</em> page - find a brief introduction to your profile and network tabs, make some new connections, and find some groups to join.') . '</li>' . EOL;
$o .= '<li> ' . '<a target="newmember" href="help/Quick-Start-guide">' . L10n::t('Friendica Walk-Through') . '</a><br />' . L10n::t('On your <em>Quick Start</em> page - find a brief introduction to your profile and network tabs, make some new connections, and find some groups to join.') . '</li>' . EOL;
$o .= '</ul>';
$o .= '<h4>' . L10n::t('Settings') . '</h4>';
$o .= '<ul>';

View File

@ -12,7 +12,12 @@ use Friendica\Core\Logger;
use Friendica\Core\System;
use Friendica\Database\DBA;
use Friendica\Util\Network;
function nodeinfo_wellknown(App $a) {
if (!Config::get('system', 'nodeinfo')) {
System::httpExit(404);
}
$nodeinfo = ['links' => [['rel' => 'http://nodeinfo.diaspora.software/ns/schema/1.0',
'href' => System::baseUrl().'/nodeinfo/1.0']]];
@ -24,12 +29,10 @@ function nodeinfo_wellknown(App $a) {
function nodeinfo_init(App $a) {
if (!Config::get('system', 'nodeinfo')) {
System::httpExit(404);
killme();
}
if (($a->argc != 2) || ($a->argv[1] != '1.0')) {
System::httpExit(404);
killme();
}
$smtp = (function_exists('imap_open') && !Config::get('system', 'imap_disabled') && !Config::get('system', 'dfrn_only'));
@ -61,7 +64,7 @@ function nodeinfo_init(App $a) {
$nodeinfo['usage'] = [];
$nodeinfo['openRegistrations'] = intval(Config::get('config', 'register_policy')) !== REGISTER_CLOSED;
$nodeinfo['openRegistrations'] = intval(Config::get('config', 'register_policy')) !== \Friendica\Module\Register::CLOSED;
$nodeinfo['metadata'] = ['nodeName' => Config::get('config', 'sitename')];
@ -149,7 +152,6 @@ function nodeinfo_cron() {
$addon = 'statistics_json';
$addons = Config::get('system', 'addon');
$addons_arr = [];
if ($addons) {
$addons_arr = explode(',',str_replace(' ', '',$addons));

View File

@ -3,12 +3,7 @@
* @file mod/nogroup.php
*/
use Friendica\App;
use Friendica\Content\ContactSelector;
use Friendica\Core\L10n;
use Friendica\Database\DBA;
use Friendica\Model\Contact;
use Friendica\Model\Group;
use Friendica\Core\System;
function nogroup_init(App $a)
{

View File

@ -9,13 +9,14 @@ use Friendica\Core\System;
use Friendica\Database\DBA;
use Friendica\Model\Contact;
use Friendica\Model\Profile;
use Friendica\Model\User;
function noscrape_init(App $a)
{
if ($a->argc > 1) {
$which = $a->argv[1];
} else {
killme();
exit();
}
$profile = 0;
@ -32,7 +33,7 @@ function noscrape_init(App $a)
'guid' => $a->profile['guid'],
'key' => $a->profile['pubkey'],
'homepage' => System::baseUrl()."/profile/{$which}",
'comm' => ($a->profile['account-type'] == Contact::ACCOUNT_TYPE_COMMUNITY),
'comm' => ($a->profile['account-type'] == User::ACCOUNT_TYPE_COMMUNITY),
'account-type' => $a->profile['account-type'],
];

View File

@ -17,13 +17,7 @@ function notes_init(App $a)
return;
}
$profile = 0;
$which = $a->user['nickname'];
Nav::setSelected('home');
//Profile::load($a, $which, $profile);
}

View File

@ -6,7 +6,6 @@
use Friendica\App;
use Friendica\Core\L10n;
use Friendica\Core\System;
use Friendica\Database\DBA;
function notice_init(App $a)

View File

@ -92,6 +92,8 @@ function notifications_content(App $a)
$notif_header = L10n::t('Notifications');
$all = false;
// Get introductions
if ((($a->argc > 1) && ($a->argv[1] == 'intros')) || (($a->argc == 1))) {
Nav::setSelected('introductions');

Some files were not shown because too many files have changed in this diff Show More