diff --git a/CHANGELOG b/CHANGELOG index 6385d22bb1..2f675fb6d3 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,134 @@ +Version 2018.09 (2018-09-23) + Friendica Core: + Update to the translation (CS, DE, EN-US, FI, IT, NL, PL, ZH-CN) [translation teams] + Update to the documentation [Aditoo17, annando, astifter, rebeka-catalina, fabrixxm, M-arcus, microgroove, nupplaphil, tobiasd] + Enhancements to the database structure, handling and documentation [abanink, Angristan, annando, miqrogroove, tobiasd] + Enhancements of unit testing [abanink, nupplaphil, rudloff] + Enhancements to labelling of UI elements [andyhee, tobiasd] + Enhancements to the background workers [annando, miqrogroove, rabuzarus] + Enhancements to the PHP7.2 compatibility [annando, miqrogroove, MrPetovan] + Enhancements to the content filter [MrPetovan] + Enhancements to the hooks provided for addons [abanink] + Enhancements to the interaction with public postings [annando] + Enhancements to the config storage [frabrixxm] + Enhancements to the themes (frio, quattro, smoothly, vier) [annando, astifter, hoergen, MrPetovan, rabuzarus, tobiasd] + Enhancements to the handling of locks [nupplaphil] + Enhancements to the redis integration [nupplaphil] + Enhancements to the admin panel [JeroenED, tobiasd] + Enhancements to the user import process [annando] + Enhancements to the display of invitation information [JeroenED] + Enhancements to the automatic installation process [nupplaphil] + Enhancements to the contact group UI [annando, astifter] + Enhancements to the call of JS [hypolite] + Enhancements to the storage of items in the database [annando] + Enhancements to the process of changing relationships [annando] + Enhancements to the OEmbed of data [MrPetovan] + Fixed various PHP notice occurrences [annando, MrPetovan] + Fixed a bug that could lead to the display of posts from deleted accounts on the community page for a short period [annando] + Fixed a bug that prevented email notification to be send out [annando] + Fixed a bug in database optimisation [annando] + Fixed a bug during removing contacts [annando] + Fixed a bug in the tag-cloud widget [annando] + Fixed a bug in the daemon mode of the background worker [annando] + Fixed a bug in the frio theme that contact filtering [rabuzarus] + Fixed a bug that mangled the display of some additional smileys [abanink] + Fixed a bug in generating registration mails [MrPetovan] + Fixed a bug that caused blank re-share bodies [MrPetovon] + Fixed a bug in the API handling of private mails [fabrixxm] + Fixed a bug when calling the mail() function [miqrogroove] + Fixed a bug that caused deleted accounts being displayed in the local directory [miqrogroove] + Fixed a bug when checking the domain of an email address [VVelox] + Fixed a bug that prevented re-shares from Twitter to be shown as this [annando] + Fixed a bug that caused broken profile links [miqrogroove] + Fixed a bug that caused content from unknown accounts appearing in the timeline [annando] + Fixed a bug with the ignoring and blocking of contacts [annando] + Fixed a bug with showing hidden contacts in some places [annando] + Fixed a bug that prevented the deletion of events by contacts [annando] + Fixed a bug that prevented email contacts from being added [annando] + Fixed a bug in the notification/seen API call [fabrixxm] + Fixed a bug that prevented a refresh after un-/ignoring a conversation [annando] + Fixed a bug in the handling of some language translations [anndno] + Fixed a bug in the hook handling [annando] + Fixed the handling of too long tags [annando] + Fixed a bug that prevented the unliking of dis-/likes [annando] + Fixed bugs with the handling of private nodes [annando] + Fixed a bug in the session initialisation [annando] + Fixed bugs in the execution of the background processes [annando, Quix0r] + Fixed a problem with the notification page [MrPetovan] + Fixed a bug with wrong dates in importing some Atom feeds [annando] + Fixed forum exclusive distribution of postings using the !notation [annando] + Fixed a bug that lead to empty notifications [MrPetovan] + Fixed a problem that could sometimes prevent the execution of the relocation [annando] + Fixed a bug with the handling of images in postings over the connectors [annando] + Added conversation cleanup configuration [miqrogroove] + Added support of the usage of internal diaspora links to accounts [annando] + Added the possibility for admins to block certain nicknames (e.g. role names) [tobiasd] + Added the generation of system guid [nupplaphil] + Added the possibility for admins to mark a node for explicit content [tobiasd] + Added filter by account type to the community page [annando] + Added private flag to API results [fabrixxm] + Added post update checks to the console utility [annando] + Added codecov analysis [nupplaphil] + Added access-keys to the frio theme [tobiasd] + Added the profile settings to the user settings [tobiasd] + General code refactoring and beautification work [annando, MrPetovan, Quix0r, tobiasd] + Fixation of the position on the network page when new posts arrive [rabuzarus] + Ported OpenWebAuth from Hubzilla [annando, rabuzarus] + Removed hard coded syntax highlighting from code blocks [MrPetovan] + Removed (temporarily) the possibility to add pictures to private messages [annando] + New INI style config file format in /config [MrPetovan, tobiasd] + The .htaccess file is not part of the git repository anymore [annando, Quix0r] + + Friendica Addons: + Update to the translations (CS, DE, EN-US, NL, PL, ZH-CN) [translation teams] + General update to adopt changes in core [annando, MrPetovan, Quix0r, tobiasd] + advancedcontentfilter: + Enhancement to the error handling [MrPetovan] + Honour the CSP settings [MrPetovan] + Fixed translation problems [annando] + blockem: + Enhancement of the settings [AlfredSK] + buffer: + support for app.net removed [annando] + js_upload: + Enhancement of the album name handling [rabuzarus] + Enhancement to the wording of the labels [astifter] + langfilter: + Fixed a problem with default values of the filtered languages [tobiasd] + libravatar: + The service wont shutdown, so we can keep the addon [tobiasd] + pumpio: + Fixed a problem that prevented new connections [annando] + superblock: + Fixed a bug that prevented the addon to block accounts [annando] + Enhancements of the settings [AlfredSK] + twitter: + Use rich text for quote tweets [MrPetovan] + Prevent empty quotes from being created [annando] + Fixed a problem with re-shares from remote_self contacts [annando] + Changed URL display after link expansion [MrPetovan] + Fixed a problem with EXIF handling [MrPetovan] + added addons: + mastodoncustomemojis [MrPetovan] + deprecated addons: + notimeline, retriver, remote_permissions, widgets + + Directory: + Enhancements of the health summary [andyhee] + Enhancements of the PHP7 compatibility [MrPetovan] + + Closed Issues: + 901, 1034, 1074, 1303, 1308, 1391, 1490, 1470, 1559, 2093, 2337, + 2340, 2381, 2396, 2675, 3291, 3299, 3493, 3501, 3535, 3643, 3840, + 4148, 4419, 4475, 4507, 4655, 4659, 4710, 4726, 4739, 4753, 4814, + 4830, 4868, 4889, 4923, 4971, 4950, 4985, 5066, 5099, 5137, 5148, + 5158, 5168, 5188, 5202, 5211, 5222, 5233, 5243, 5247, 5252, 5257, + 5260, 5262, 5268, 5274, 5275, 5276, 5278, 5298, 5318, 5319, 5320, + 5321, 5322, 5330, 5333, 5341, 5365, 5405, 5407, 5411, 5423, 5432, + 5434, 5436, 5443, 5455, 5464, 5467, 5469, 5486, 5496, 5497, 5514, + 5539, 5524, 5541, 5544, 5550, 5564, 5566, 5605, 5630, 5638, 5651, + 5653, 5660, 5670, 5691, 5733, 5745, 5768 + Version 2018.05 (2018-06-01) Friendica Core: Update to the translations (DE, EN-GB, EN-US, FI, IS, IT, NL, PL, RU, ZN CH) [translation teams] diff --git a/INSTALL.txt b/INSTALL.txt index 705eb8fed2..2f0613fb7d 100644 --- a/INSTALL.txt +++ b/INSTALL.txt @@ -56,6 +56,13 @@ you wish to communicate with the Diaspora network. - For alternative server configurations (such as Nginx server and MariaDB database engine), refer to the wiki at https://github.com/friendica/friendica/wiki +This guide will walk you through the manual installation process of Friendica. +If this is nothing for you, you might be interested in + +* the Friendica Docker image (https://github.com/friendica/docker) or +* how install Friendica with YunoHost (https://github.com/YunoHost-Apps/friendica_ynh). + + 2. Unpack the Friendica files into the root of your web server document area. - If you copy the directory tree to your webserver, make sure diff --git a/VERSION b/VERSION index 40284ee692..8033ba2083 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2018.08-rc +2018.12-dev diff --git a/bin/auth_ejabberd.php b/bin/auth_ejabberd.php index 7ad28c96f5..1f03b94af9 100755 --- a/bin/auth_ejabberd.php +++ b/bin/auth_ejabberd.php @@ -54,7 +54,7 @@ require_once "include/dba.php"; $a = new App(dirname(__DIR__)); -if ($a->mode === App::MODE_NORMAL) { +if ($a->getMode()->isNormal()) { $oAuth = new ExAuth(); $oAuth->readStdin(); -} \ No newline at end of file +} diff --git a/bin/composer.phar b/bin/composer.phar index c8152aded2..96fa2df7bd 100755 Binary files a/bin/composer.phar and b/bin/composer.phar differ diff --git a/bin/daemon.php b/bin/daemon.php index 159b20e159..f0f5826d92 100755 --- a/bin/daemon.php +++ b/bin/daemon.php @@ -34,7 +34,7 @@ require_once "include/dba.php"; $a = new App(dirname(__DIR__)); -if ($a->isInstallMode()) { +if ($a->getMode()->isInstall()) { die("Friendica isn't properly installed yet.\n"); } diff --git a/bin/worker.php b/bin/worker.php index ceab479cea..cb09a4929d 100755 --- a/bin/worker.php +++ b/bin/worker.php @@ -45,7 +45,7 @@ if (Config::get('system', 'maintenance', false, true)) { return; } -$a->set_baseurl(Config::get('system', 'url')); +$a->setBaseURL(Config::get('system', 'url')); Addon::loadHooks(); diff --git a/boot.php b/boot.php index 2236a4d5df..acbc737658 100644 --- a/boot.php +++ b/boot.php @@ -39,9 +39,9 @@ require_once 'include/text.php'; define('FRIENDICA_PLATFORM', 'Friendica'); define('FRIENDICA_CODENAME', 'The Tazmans Flax-lily'); -define('FRIENDICA_VERSION', '2018.08-rc'); +define('FRIENDICA_VERSION', '2018.12-dev'); define('DFRN_PROTOCOL_VERSION', '2.23'); -define('DB_UPDATE_VERSION', 1283); +define('DB_UPDATE_VERSION', 1288); define('NEW_UPDATE_ROUTINE_VERSION', 1170); /** @@ -475,44 +475,6 @@ function defaults() { return $return; } -/** - * @brief Returns the baseurl. - * - * @see System::baseUrl() - * - * @return string - * @TODO Function is deprecated and only used in some addons - */ -function z_root() -{ - return System::baseUrl(); -} - -/** - * @brief Return absolut URL for given $path. - * - * @param string $path given path - * - * @return string - */ -function absurl($path) -{ - if (strpos($path, '/') === 0) { - return z_path() . $path; - } - return $path; -} - -/** - * @brief Function to check if request was an AJAX (xmlhttprequest) request. - * - * @return boolean - */ -function is_ajax() -{ - return (!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest'); -} - /** * @brief Function to check if request was an AJAX (xmlhttprequest) request. * @@ -556,7 +518,7 @@ function check_url(App $a) // and www.example.com vs example.com. // We will only change the url to an ip address if there is no existing setting - if (empty($url) || (!link_compare($url, System::baseUrl())) && (!preg_match("/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/", $a->get_hostname()))) { + if (empty($url) || (!link_compare($url, System::baseUrl())) && (!preg_match("/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/", $a->getHostName()))) { Config::set('system', 'url', System::baseUrl()); } @@ -673,62 +635,6 @@ function run_update_function($x, $prefix) } } -/** - * @brief Synchronise addons: - * - * system.addon contains a comma-separated list of names - * of addons which are used on this system. - * Go through the database list of already installed addons, and if we have - * an entry, but it isn't in the config list, call the uninstall procedure - * and mark it uninstalled in the database (for now we'll remove it). - * Then go through the config list and if we have a addon that isn't installed, - * call the install procedure and add it to the database. - * - * @param object $a App - */ -function check_addons(App $a) -{ - $r = q("SELECT * FROM `addon` WHERE `installed` = 1"); - if (DBA::isResult($r)) { - $installed = $r; - } else { - $installed = []; - } - - $addons = Config::get('system', 'addon'); - $addons_arr = []; - - if ($addons) { - $addons_arr = explode(',', str_replace(' ', '', $addons)); - } - - $a->addons = $addons_arr; - - $installed_arr = []; - - if (count($installed)) { - foreach ($installed as $i) { - if (!in_array($i['name'], $addons_arr)) { - Addon::uninstall($i['name']); - } else { - $installed_arr[] = $i['name']; - } - } - } - - if (count($addons_arr)) { - foreach ($addons_arr as $p) { - if (!in_array($p, $installed_arr)) { - Addon::install($p); - } - } - } - - Addon::loadHooks(); - - return; -} - /** * @brief Used to end the current process, after saving session state. * @deprecated @@ -741,7 +647,7 @@ function killme() /** * @brief Redirect to another URL and terminate this process. */ -function goaway($path) +function goaway($path = '') { if (strstr(normalise_link($path), 'http://')) { $url = $path; @@ -1031,27 +937,27 @@ function get_temppath() $temppath = Config::get("system", "temppath"); - if (($temppath != "") && App::directory_usable($temppath)) { + if (($temppath != "") && App::isDirectoryUsable($temppath)) { // We have a temp path and it is usable - return App::realpath($temppath); + return App::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::directory_usable($temppath)) { + if (($temppath != "") && App::isDirectoryUsable($temppath)) { // Always store the real path, not the path through symlinks - $temppath = App::realpath($temppath); + $temppath = App::getRealPath($temppath); // To avoid any interferences with other systems we create our own directory - $new_temppath = $temppath . "/" . $a->get_hostname(); + $new_temppath = $temppath . "/" . $a->getHostName(); if (!is_dir($new_temppath)) { /// @TODO There is a mkdir()+chmod() upwards, maybe generalize this (+ configurable) into a function/method? mkdir($new_temppath); } - if (App::directory_usable($new_temppath)) { + if (App::isDirectoryUsable($new_temppath)) { // The new path is usable, we are happy Config::set("system", "temppath", $new_temppath); return $new_temppath; @@ -1133,8 +1039,8 @@ function get_itemcachepath() } $itemcache = Config::get('system', 'itemcache'); - if (($itemcache != "") && App::directory_usable($itemcache)) { - return App::realpath($itemcache); + if (($itemcache != "") && App::isDirectoryUsable($itemcache)) { + return App::getRealPath($itemcache); } $temppath = get_temppath(); @@ -1145,7 +1051,7 @@ function get_itemcachepath() mkdir($itemcache); } - if (App::directory_usable($itemcache)) { + if (App::isDirectoryUsable($itemcache)) { Config::set("system", "itemcache", $itemcache); return $itemcache; } @@ -1161,7 +1067,7 @@ function get_itemcachepath() function get_spoolpath() { $spoolpath = Config::get('system', 'spoolpath'); - if (($spoolpath != "") && App::directory_usable($spoolpath)) { + if (($spoolpath != "") && App::isDirectoryUsable($spoolpath)) { // We have a spool path and it is usable return $spoolpath; } @@ -1176,7 +1082,7 @@ function get_spoolpath() mkdir($spoolpath); } - if (App::directory_usable($spoolpath)) { + if (App::isDirectoryUsable($spoolpath)) { // The new path is usable, we are happy Config::set("system", "spoolpath", $spoolpath); return $spoolpath; @@ -1231,46 +1137,6 @@ function validate_include(&$file) return $valid; } -function current_load() -{ - if (!function_exists('sys_getloadavg')) { - return false; - } - - $load_arr = sys_getloadavg(); - - if (!is_array($load_arr)) { - return false; - } - - return max($load_arr[0], $load_arr[1]); -} - -/** - * @brief get c-style args - * - * @return int - */ -function argc() -{ - return get_app()->argc; -} - -/** - * @brief Returns the value of a argv key - * - * @param int $x argv key - * @return string Value of the argv key - */ -function argv($x) -{ - if (array_key_exists($x, get_app()->argv)) { - return get_app()->argv[$x]; - } - - return ''; -} - /** * @brief Get the data which is needed for infinite scroll * diff --git a/composer.json b/composer.json index 04e4b655da..5df9a5355b 100644 --- a/composer.json +++ b/composer.json @@ -18,13 +18,13 @@ "asika/simple-console": "^1.0", "divineomega/password_exposed": "^2.4", "ezyang/htmlpurifier": "~4.7.0", - "league/html-to-markdown": "~4.4.1", + "friendica/json-ld": "^1.0", + "league/html-to-markdown": "~4.8.0", "lightopenid/lightopenid": "dev-master", "michelf/php-markdown": "^1.7", "mobiledetect/mobiledetectlib": "2.8.*", "paragonie/random_compat": "^2.0", "pear/Text_LanguageDetect": "1.*", - "pear/Text_Highlighter": "dev-master", "seld/cli-prompt": "^1.0", "smarty/smarty": "^3.1", "fxp/composer-asset-plugin": "~1.3", @@ -43,7 +43,7 @@ "repositories": [ { "type": "vcs", - "url": "https://github.com/pear/Text_Highlighter" + "url": "https://git.friendi.ca/friendica/php-json-ld" } ], "autoload": { @@ -75,7 +75,8 @@ "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" }, "scripts": { "test": "phpunit" diff --git a/composer.lock b/composer.lock index 76c20a1b93..9230bb4db9 100644 --- a/composer.lock +++ b/composer.lock @@ -1,10 +1,10 @@ { "_readme": [ "This file locks the dependencies of your project to a known state", - "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "d62c3e3d6971ee63a862a22ff3cd3768", + "content-hash": "9f0dbeccbae197460a0ce74a940177cd", "packages": [ { "name": "asika/simple-console", @@ -41,16 +41,16 @@ }, { "name": "bower-asset/Chart-js", - "version": "v2.7.1", + "version": "v2.7.2", "source": { "type": "git", "url": "https://github.com/chartjs/Chart.js.git", - "reference": "0fead21939b92c15093c1b7d5ee2627fb5900fff" + "reference": "98f104cdd03617f1300b417b3d60c23d4e3e3403" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/chartjs/Chart.js/zipball/0fead21939b92c15093c1b7d5ee2627fb5900fff", - "reference": "0fead21939b92c15093c1b7d5ee2627fb5900fff", + "url": "https://api.github.com/repos/chartjs/Chart.js/zipball/98f104cdd03617f1300b417b3d60c23d4e3e3403", + "reference": "98f104cdd03617f1300b417b3d60c23d4e3e3403", "shasum": "" }, "type": "bower-asset-library", @@ -69,7 +69,7 @@ "MIT" ], "description": "Simple HTML5 charts using the canvas element.", - "time": "2017-10-28T15:01:52+00:00" + "time": "2018-03-01T21:45:21+00:00" }, { "name": "bower-asset/base64", @@ -135,44 +135,133 @@ }, { "name": "bower-asset/vue", - "version": "v2.5.16", + "version": "v2.5.17", "source": { "type": "git", "url": "https://github.com/vuejs/vue.git", - "reference": "25342194016dc3bcc81cb3e8e229b0fb7ba1d1d6" + "reference": "636c9b4ef17f2062720b677cbbe613f146f4d4db" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/vuejs/vue/zipball/25342194016dc3bcc81cb3e8e229b0fb7ba1d1d6", - "reference": "25342194016dc3bcc81cb3e8e229b0fb7ba1d1d6", + "url": "https://api.github.com/repos/vuejs/vue/zipball/636c9b4ef17f2062720b677cbbe613f146f4d4db", + "reference": "636c9b4ef17f2062720b677cbbe613f146f4d4db", "shasum": "" }, "type": "bower-asset-library" }, { - "name": "divineomega/password_exposed", - "version": "v2.5.1", + "name": "divineomega/do-file-cache", + "version": "v2.0.2", "source": { "type": "git", - "url": "https://github.com/DivineOmega/password_exposed.git", - "reference": "c928bf722eb02398df11076add60df070cb55581" + "url": "https://github.com/DivineOmega/DO-File-Cache.git", + "reference": "261c6e30a0de8cd325f826d08b2e51b2e367a1a3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/DivineOmega/password_exposed/zipball/c928bf722eb02398df11076add60df070cb55581", - "reference": "c928bf722eb02398df11076add60df070cb55581", + "url": "https://api.github.com/repos/DivineOmega/DO-File-Cache/zipball/261c6e30a0de8cd325f826d08b2e51b2e367a1a3", + "reference": "261c6e30a0de8cd325f826d08b2e51b2e367a1a3", "shasum": "" }, "require": { + "php": ">=5.6" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.1", + "phpunit/phpunit": "^6.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-4": { + "DivineOmega\\DOFileCache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-3.0-only" + ], + "description": "DO File Cache is a PHP File-based Caching Library. Its syntax is designed to closely resemble the PHP memcache extension.", + "keywords": [ + "cache", + "caching", + "caching library", + "file cache", + "library", + "php" + ], + "time": "2018-09-12T23:08:34+00:00" + }, + { + "name": "divineomega/do-file-cache-psr-6", + "version": "v2.0.1", + "source": { + "type": "git", + "url": "https://github.com/DivineOmega/DO-File-Cache-PSR-6.git", + "reference": "18f9807d0491d093e9a12741afb40257d92f017e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/DivineOmega/DO-File-Cache-PSR-6/zipball/18f9807d0491d093e9a12741afb40257d92f017e", + "reference": "18f9807d0491d093e9a12741afb40257d92f017e", + "shasum": "" + }, + "require": { + "divineomega/do-file-cache": "^2.0.0", + "psr/cache": "^1.0" + }, + "require-dev": { + "cache/integration-tests": "^0.16.0", + "php-coveralls/php-coveralls": "^2.1", + "phpunit/phpunit": "^5.7" + }, + "type": "library", + "autoload": { + "psr-4": { + "DivineOmega\\DOFileCachePSR6\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-3.0-only" + ], + "authors": [ + { + "name": "Jordan Hall", + "email": "jordan@hall05.co.uk" + } + ], + "description": "PSR-6 adapter for DO File Cache", + "time": "2018-07-13T08:32:36+00:00" + }, + { + "name": "divineomega/password_exposed", + "version": "v2.5.3", + "source": { + "type": "git", + "url": "https://github.com/DivineOmega/password_exposed.git", + "reference": "1f1b49e3ec55b0f07115d342b145091368b081c4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/DivineOmega/password_exposed/zipball/1f1b49e3ec55b0f07115d342b145091368b081c4", + "reference": "1f1b49e3ec55b0f07115d342b145091368b081c4", + "shasum": "" + }, + "require": { + "divineomega/do-file-cache-psr-6": "^2.0", "guzzlehttp/guzzle": "^6.3", "paragonie/certainty": "^1", - "php": ">=5.6", - "rapidwebltd/rw-file-cache-psr-6": "^1.0" + "php": ">=5.6" }, "require-dev": { "fzaninotto/faker": "^1.7", + "php-coveralls/php-coveralls": "^2.1", "phpunit/phpunit": "^5.7", - "satooshi/php-coveralls": "^2.0", "vimeo/psalm": "^1" }, "type": "library", @@ -195,7 +284,7 @@ } ], "description": "This PHP package provides a `password_exposed` helper function, that uses the haveibeenpwned.com API to check if a password has been exposed in a data breach.", - "time": "2018-04-02T18:16:36+00:00" + "time": "2018-07-12T22:09:43+00:00" }, { "name": "ezyang/htmlpurifier", @@ -241,18 +330,62 @@ ], "time": "2015-08-05T01:03:42+00:00" }, + { + "name": "friendica/json-ld", + "version": "1.1.1", + "source": { + "type": "git", + "url": "https://git.friendi.ca/friendica/php-json-ld", + "reference": "ca3916d10d2ad9073b3b1eae383978dbe828e1e1" + }, + "require": { + "ext-json": "*", + "php": ">=5.4.0" + }, + "type": "library", + "autoload": { + "files": [ + "jsonld.php" + ] + }, + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Digital Bazaar, Inc.", + "email": "support@digitalbazaar.com", + "homepage": "http://digitalbazaar.com/" + }, + { + "name": "Friendica Team", + "homepage": "https://friendi.ca/" + } + ], + "description": "A JSON-LD Processor and API implementation in PHP.", + "homepage": "https://git.friendi.ca/friendica/php-json-ld", + "keywords": [ + "JSON", + "JSON-LD", + "Linked Data", + "RDF", + "Semantic Web", + "jsonld" + ], + "time": "2018-10-08T20:41:00+00:00" + }, { "name": "fxp/composer-asset-plugin", - "version": "v1.4.2", + "version": "v1.4.4", "source": { "type": "git", "url": "https://github.com/fxpio/composer-asset-plugin.git", - "reference": "61352d99940d2b2392a5d2db83b8c0ef5faf222a" + "reference": "0d07328eef6e6f3753aa835fd2faef7fed1717bf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/fxpio/composer-asset-plugin/zipball/61352d99940d2b2392a5d2db83b8c0ef5faf222a", - "reference": "61352d99940d2b2392a5d2db83b8c0ef5faf222a", + "url": "https://api.github.com/repos/fxpio/composer-asset-plugin/zipball/0d07328eef6e6f3753aa835fd2faef7fed1717bf", + "reference": "0d07328eef6e6f3753aa835fd2faef7fed1717bf", "shasum": "" }, "require": { @@ -260,7 +393,7 @@ "php": ">=5.3.3" }, "require-dev": { - "composer/composer": "^1.4.0" + "composer/composer": "^1.6.0" }, "type": "composer-plugin", "extra": { @@ -298,20 +431,20 @@ "npm", "package" ], - "time": "2017-10-20T06:53:56+00:00" + "time": "2018-07-02T11:37:17+00:00" }, { "name": "guzzlehttp/guzzle", - "version": "6.3.0", + "version": "6.3.3", "source": { "type": "git", "url": "https://github.com/guzzle/guzzle.git", - "reference": "f4db5a78a5ea468d4831de7f0bf9d9415e348699" + "reference": "407b0cb880ace85c9b63c5f9551db498cb2d50ba" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/f4db5a78a5ea468d4831de7f0bf9d9415e348699", - "reference": "f4db5a78a5ea468d4831de7f0bf9d9415e348699", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/407b0cb880ace85c9b63c5f9551db498cb2d50ba", + "reference": "407b0cb880ace85c9b63c5f9551db498cb2d50ba", "shasum": "" }, "require": { @@ -321,7 +454,7 @@ }, "require-dev": { "ext-curl": "*", - "phpunit/phpunit": "^4.0 || ^5.0", + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.4 || ^7.0", "psr/log": "^1.0" }, "suggest": { @@ -330,7 +463,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "6.2-dev" + "dev-master": "6.3-dev" } }, "autoload": { @@ -363,7 +496,7 @@ "rest", "web service" ], - "time": "2017-06-22T18:50:49+00:00" + "time": "2018-04-22T15:46:56+00:00" }, { "name": "guzzlehttp/promises", @@ -483,16 +616,16 @@ }, { "name": "league/html-to-markdown", - "version": "4.4.1", + "version": "4.8.0", "source": { "type": "git", "url": "https://github.com/thephpleague/html-to-markdown.git", - "reference": "82ea375b5b2b1da1da222644c0565c695bf88186" + "reference": "f9a879a068c68ff47b722de63f58bec79e448f9d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/html-to-markdown/zipball/82ea375b5b2b1da1da222644c0565c695bf88186", - "reference": "82ea375b5b2b1da1da222644c0565c695bf88186", + "url": "https://api.github.com/repos/thephpleague/html-to-markdown/zipball/f9a879a068c68ff47b722de63f58bec79e448f9d", + "reference": "f9a879a068c68ff47b722de63f58bec79e448f9d", "shasum": "" }, "require": { @@ -511,7 +644,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.5-dev" + "dev-master": "4.9-dev" } }, "autoload": { @@ -524,17 +657,17 @@ "MIT" ], "authors": [ - { - "name": "Colin O'Dell", - "email": "colinodell@gmail.com", - "homepage": "http://www.colinodell.com", - "role": "Lead Developer" - }, { "name": "Nick Cernis", "email": "nick@cern.is", "homepage": "http://modernnerd.net", "role": "Original Author" + }, + { + "name": "Colin O'Dell", + "email": "colinodell@gmail.com", + "homepage": "https://www.colinodell.com", + "role": "Lead Developer" } ], "description": "An HTML-to-markdown conversion helper for PHP", @@ -543,7 +676,7 @@ "html", "markdown" ], - "time": "2017-03-16T00:45:59+00:00" + "time": "2018-09-18T12:18:08+00:00" }, { "name": "lightopenid/lightopenid", @@ -626,16 +759,16 @@ }, { "name": "mobiledetect/mobiledetectlib", - "version": "2.8.30", + "version": "2.8.33", "source": { "type": "git", "url": "https://github.com/serbanghita/Mobile-Detect.git", - "reference": "5500bbbf312fe77ef0c7223858dad84fe49ee0c3" + "reference": "cd385290f9a0d609d2eddd165a1e44ec1bf12102" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/serbanghita/Mobile-Detect/zipball/5500bbbf312fe77ef0c7223858dad84fe49ee0c3", - "reference": "5500bbbf312fe77ef0c7223858dad84fe49ee0c3", + "url": "https://api.github.com/repos/serbanghita/Mobile-Detect/zipball/cd385290f9a0d609d2eddd165a1e44ec1bf12102", + "reference": "cd385290f9a0d609d2eddd165a1e44ec1bf12102", "shasum": "" }, "require": { @@ -674,7 +807,7 @@ "mobile detector", "php mobile detect" ], - "time": "2017-12-18T10:38:51+00:00" + "time": "2018-09-01T15:05:15+00:00" }, { "name": "npm-asset/cropperjs", @@ -815,67 +948,16 @@ }, { "name": "npm-asset/fullcalendar", - "version": "3.8.2", + "version": "3.9.0", "dist": { "type": "tar", - "url": "https://registry.npmjs.org/fullcalendar/-/fullcalendar-3.8.2.tgz", + "url": "https://registry.npmjs.org/fullcalendar/-/fullcalendar-3.9.0.tgz", "reference": null, - "shasum": "ef7dc77b89134bbe6163e51136f7a1f8bfc1d807" + "shasum": "b608a9989f3416f0b1d526c6bdfeeaf2ac79eda5" }, "require": { "npm-asset/jquery": ">=2,<4.0", - "npm-asset/moment": ">=2.9.0,<3.0.0" - }, - "require-dev": { - "npm-asset/awesome-typescript-loader": ">=3.3.0,<4.0.0", - "npm-asset/bootstrap": ">=3.3.7,<4.0.0", - "npm-asset/components-jqueryui": "dev-github:components/jqueryui", - "npm-asset/css-loader": ">=0.28.7,<0.29.0", - "npm-asset/del": ">=2.2.1,<3.0.0", - "npm-asset/dts-generator": ">=2.1.0,<3.0.0", - "npm-asset/eslint": ">=4.13.1,<5.0.0", - "npm-asset/eslint-config-standard": ">=11.0.0-beta.0,<12.0.0", - "npm-asset/eslint-plugin-import": ">=2.8.0,<3.0.0", - "npm-asset/eslint-plugin-node": ">=5.2.1,<6.0.0", - "npm-asset/eslint-plugin-promise": ">=3.6.0,<4.0.0", - "npm-asset/eslint-plugin-standard": ">=3.0.1,<4.0.0", - "npm-asset/extract-text-webpack-plugin": ">=3.0.2,<4.0.0", - "npm-asset/glob": ">=7.1.2,<8.0.0", - "npm-asset/gulp": ">=3.9.1,<4.0.0", - "npm-asset/gulp-cssmin": ">=0.1.7,<0.2.0", - "npm-asset/gulp-eslint": ">=4.0.0,<5.0.0", - "npm-asset/gulp-filter": ">=4.0.0,<5.0.0", - "npm-asset/gulp-modify-file": ">=1.0.0,<2.0.0", - "npm-asset/gulp-rename": ">=1.2.2,<2.0.0", - "npm-asset/gulp-shell": ">=0.6.5,<0.7.0", - "npm-asset/gulp-tslint": ">=8.1.2,<9.0.0", - "npm-asset/gulp-uglify": ">=2.0.0,<3.0.0", - "npm-asset/gulp-util": ">=3.0.7,<4.0.0", - "npm-asset/gulp-watch": ">=4.3.11,<5.0.0", - "npm-asset/gulp-zip": ">=3.2.0,<4.0.0", - "npm-asset/jasmine-core": "2.5.2", - "npm-asset/jasmine-fixture": ">=2.0.0,<3.0.0", - "npm-asset/jasmine-jquery": ">=2.1.1,<3.0.0", - "npm-asset/jquery-mockjax": ">=2.2.0,<3.0.0", - "npm-asset/jquery-simulate": "dev-github:jquery/jquery-simulate", - "npm-asset/karma": ">=0.13.22,<0.14.0", - "npm-asset/karma-jasmine": ">=1.0.2,<2.0.0", - "npm-asset/karma-phantomjs-launcher": ">=1.0.0,<2.0.0", - "npm-asset/karma-sourcemap-loader": ">=0.3.7,<0.4.0", - "npm-asset/karma-verbose-reporter": "0.0.6", - "npm-asset/moment-timezone": ">=0.5.5,<0.6.0", - "npm-asset/native-promise-only": ">=0.8.1,<0.9.0", - "npm-asset/node-sass": ">=4.7.2,<5.0.0", - "npm-asset/phantomjs-prebuilt": ">=2.1.7,<3.0.0", - "npm-asset/sass-loader": ">=6.0.6,<7.0.0", - "npm-asset/tslib": ">=1.8.0,<2.0.0", - "npm-asset/tslint": ">=5.8.0,<6.0.0", - "npm-asset/tslint-config-standard": ">=7.0.0,<8.0.0", - "npm-asset/types--jquery": "2.0.47", - "npm-asset/typescript": ">=2.6.2,<3.0.0", - "npm-asset/webpack": ">=3.8.1,<4.0.0", - "npm-asset/webpack-stream": ">=4.0.0,<5.0.0", - "npm-asset/yargs": ">=4.8.1,<5.0.0" + "npm-asset/moment": ">=2.20.1,<3.0.0" }, "type": "npm-asset-library", "extra": { @@ -923,7 +1005,7 @@ "full-sized", "jquery-plugin" ], - "time": "2018-01-30T23:49:01+00:00" + "time": "2018-03-05T03:30:23+00:00" }, { "name": "npm-asset/imagesloaded", @@ -1150,24 +1232,18 @@ }, { "name": "npm-asset/jquery-datetimepicker", - "version": "2.5.17", + "version": "2.5.20", "dist": { "type": "tar", - "url": "https://registry.npmjs.org/jquery-datetimepicker/-/jquery-datetimepicker-2.5.17.tgz", + "url": "https://registry.npmjs.org/jquery-datetimepicker/-/jquery-datetimepicker-2.5.20.tgz", "reference": null, - "shasum": "8857a631f248081d4072563bde40fa8c17e407b1" + "shasum": "687d6204b90b03dc93f725f8df036e1d061f37ac" }, "require": { "npm-asset/jquery": ">=1.7.2", "npm-asset/jquery-mousewheel": ">=3.1.13", "npm-asset/php-date-formatter": ">=1.3.4,<2.0.0" }, - "require-dev": { - "npm-asset/concat": "dev-github:azer/concat", - "npm-asset/concat-cli": ">=4.0.0,<5.0.0", - "npm-asset/uglifycss": ">=0.0.27,<0.0.28", - "npm-asset/uglifyjs": ">=2.4.10,<3.0.0" - }, "type": "npm-asset-library", "extra": { "npm-asset-bugs": { @@ -1180,13 +1256,13 @@ "url": "git+https://github.com/xdan/datetimepicker.git" }, "npm-asset-scripts": { - "test": "echo \"Error: no test specified\" && exit 1", + "test": "karma start --browsers Firefox karma.conf.js --single-run", "concat": "concat-cli -f node_modules/php-date-formatter/js/php-date-formatter.min.js jquery.datetimepicker.js node_modules/jquery-mousewheel/jquery.mousewheel.js -o build/jquery.datetimepicker.full.js", "minify": "uglifyjs jquery.datetimepicker.js -c -m -o build/jquery.datetimepicker.min.js && uglifycss jquery.datetimepicker.css > build/jquery.datetimepicker.min.css", "minifyconcat": "uglifyjs build/jquery.datetimepicker.full.js -c -m -o build/jquery.datetimepicker.full.min.js", "github": "git add --all && git commit -m \"New version %npm_package_version% \" && git tag %npm_package_version% && git push --tags origin HEAD:master && npm publish", "build": "npm run minify && npm run concat && npm run minifyconcat", - "public": "npm version patch --no-git-tag-version && npm run build && npm run github" + "public": "npm run test && npm version patch --no-git-tag-version && npm run build && npm run github" } }, "license": [ @@ -1196,7 +1272,7 @@ { "name": "Chupurnov", "email": "chupurnov@gmail.com", - "url": "http://xdsoft.net/" + "url": "https://xdsoft.net/" } ], "description": "jQuery Plugin DateTimePicker it is DatePicker and TimePicker in one", @@ -1210,7 +1286,7 @@ "time", "timepicker" ], - "time": "2018-01-23T05:56:50+00:00" + "time": "2018-03-21T16:26:39+00:00" }, { "name": "npm-asset/jquery-mousewheel", @@ -1269,45 +1345,12 @@ }, { "name": "npm-asset/moment", - "version": "2.20.1", + "version": "2.22.2", "dist": { "type": "tar", - "url": "https://registry.npmjs.org/moment/-/moment-2.20.1.tgz", + "url": "https://registry.npmjs.org/moment/-/moment-2.22.2.tgz", "reference": null, - "shasum": "d6eb1a46cbcc14a2b2f9434112c1ff8907f313fd" - }, - "require-dev": { - "npm-asset/benchmark": "dev-default|*", - "npm-asset/coveralls": ">=2.11.2,<3.0.0", - "npm-asset/es6-promise": "dev-default|*", - "npm-asset/grunt": "~0.4", - "npm-asset/grunt-benchmark": "dev-default|*", - "npm-asset/grunt-cli": "dev-default|*", - "npm-asset/grunt-contrib-clean": "dev-default|*", - "npm-asset/grunt-contrib-concat": "dev-default|*", - "npm-asset/grunt-contrib-copy": "dev-default|*", - "npm-asset/grunt-contrib-jshint": "dev-default|*", - "npm-asset/grunt-contrib-uglify": "dev-default|*", - "npm-asset/grunt-contrib-watch": "dev-default|*", - "npm-asset/grunt-env": "dev-default|*", - "npm-asset/grunt-exec": "dev-default|*", - "npm-asset/grunt-jscs": "dev-default|*", - "npm-asset/grunt-karma": "dev-default|*", - "npm-asset/grunt-nuget": "dev-default|*", - "npm-asset/grunt-string-replace": "dev-default|*", - "npm-asset/karma": "dev-default|*", - "npm-asset/karma-chrome-launcher": "dev-default|*", - "npm-asset/karma-firefox-launcher": "dev-default|*", - "npm-asset/karma-qunit": "dev-default|*", - "npm-asset/karma-sauce-launcher": "dev-default|*", - "npm-asset/load-grunt-tasks": "dev-default|*", - "npm-asset/nyc": ">=2.1.4,<3.0.0", - "npm-asset/qunit": ">=0.7.5,<0.8.0", - "npm-asset/qunit-cli": ">=0.1.4,<0.2.0", - "npm-asset/rollup": "dev-default|*", - "npm-asset/spacejam": "dev-default|*", - "npm-asset/typescript": ">=1.8.10,<2.0.0", - "npm-asset/uglify-js": "dev-default|*" + "shasum": "3c257f9839fc0e93ff53149632239eb90783ff66" }, "type": "npm-asset-library", "extra": { @@ -1377,16 +1420,21 @@ "time", "validate" ], - "time": "2017-12-19T04:44:18+00:00" + "time": "2018-06-01T06:58:41+00:00" }, { "name": "npm-asset/php-date-formatter", - "version": "1.3.4", + "version": "v1.3.5", + "source": { + "type": "git", + "url": "https://github.com/kartik-v/php-date-formatter.git", + "reference": "d842e1c4e6a8d6108017b726321c305bb5ae4fb5" + }, "dist": { - "type": "tar", - "url": "https://registry.npmjs.org/php-date-formatter/-/php-date-formatter-1.3.4.tgz", - "reference": null, - "shasum": "09a15ae0766ba0beb1900c27c1ec319ef2e4563e" + "type": "zip", + "url": "https://api.github.com/repos/kartik-v/php-date-formatter/zipball/d842e1c4e6a8d6108017b726321c305bb5ae4fb5", + "reference": "d842e1c4e6a8d6108017b726321c305bb5ae4fb5", + "shasum": "" }, "type": "npm-asset-library", "extra": { @@ -1399,35 +1447,31 @@ }, "npm-asset-repository": { "type": "git", - "url": "git+https://github.com/kartik-v/php-date-formatter.git" - }, - "npm-asset-scripts": [] + "url": "https://github.com/kartik-v/php-date-formatter.git" + } }, "license": [ "BSD-3-Clause" ], "authors": [ - { - "name": "Kartik Visweswaran", - "email": "kartikv2@gmail.com" - } + "Kartik Visweswaran " ], "description": "A Javascript datetime formatting and manipulation library using PHP date-time formats.", "homepage": "https://github.com/kartik-v/php-date-formatter", - "time": "2016-02-18T15:15:55+00:00" + "time": "2018-07-13T06:56:46+00:00" }, { "name": "paragonie/certainty", - "version": "v1.0.2", + "version": "v1.0.4", "source": { "type": "git", "url": "https://github.com/paragonie/certainty.git", - "reference": "a2d14f5b0b85c58329dee248d77d34e7e1202a32" + "reference": "d0f22c0fe579cf0e4f8ee301de5bc97ab124faac" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/paragonie/certainty/zipball/a2d14f5b0b85c58329dee248d77d34e7e1202a32", - "reference": "a2d14f5b0b85c58329dee248d77d34e7e1202a32", + "url": "https://api.github.com/repos/paragonie/certainty/zipball/d0f22c0fe579cf0e4f8ee301de5bc97ab124faac", + "reference": "d0f22c0fe579cf0e4f8ee301de5bc97ab124faac", "shasum": "" }, "require": { @@ -1474,29 +1518,29 @@ "ssl", "tls" ], - "time": "2018-03-12T18:34:23+00:00" + "time": "2018-04-09T07:21:55+00:00" }, { "name": "paragonie/constant_time_encoding", - "version": "v1.0.2", + "version": "v1.0.4", "source": { "type": "git", "url": "https://github.com/paragonie/constant_time_encoding.git", - "reference": "6111a38faf6fdebc14e36652d22036f379ba58d3" + "reference": "2132f0f293d856026d7d11bd81b9f4a23a1dc1f6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/paragonie/constant_time_encoding/zipball/6111a38faf6fdebc14e36652d22036f379ba58d3", - "reference": "6111a38faf6fdebc14e36652d22036f379ba58d3", + "url": "https://api.github.com/repos/paragonie/constant_time_encoding/zipball/2132f0f293d856026d7d11bd81b9f4a23a1dc1f6", + "reference": "2132f0f293d856026d7d11bd81b9f4a23a1dc1f6", "shasum": "" }, "require": { "php": "^5.3|^7" }, "require-dev": { - "paragonie/random_compat": "^1|^2", + "paragonie/random_compat": "^1.4|^2", "phpunit/phpunit": "4.*|5.*", - "vimeo/psalm": "^1" + "vimeo/psalm": "^0.3|^1" }, "type": "library", "autoload": { @@ -1537,20 +1581,20 @@ "hex2bin", "rfc4648" ], - "time": "2018-03-10T19:46:06+00:00" + "time": "2018-04-30T17:57:16+00:00" }, { "name": "paragonie/random_compat", - "version": "v2.0.11", + "version": "v2.0.17", "source": { "type": "git", "url": "https://github.com/paragonie/random_compat.git", - "reference": "5da4d3c796c275c55f057af5a643ae297d96b4d8" + "reference": "29af24f25bab834fcbb38ad2a69fa93b867e070d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/paragonie/random_compat/zipball/5da4d3c796c275c55f057af5a643ae297d96b4d8", - "reference": "5da4d3c796c275c55f057af5a643ae297d96b4d8", + "url": "https://api.github.com/repos/paragonie/random_compat/zipball/29af24f25bab834fcbb38ad2a69fa93b867e070d", + "reference": "29af24f25bab834fcbb38ad2a69fa93b867e070d", "shasum": "" }, "require": { @@ -1582,27 +1626,28 @@ "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", "keywords": [ "csprng", + "polyfill", "pseudorandom", "random" ], - "time": "2017-09-27T21:40:39+00:00" + "time": "2018-07-04T16:31:37+00:00" }, { "name": "paragonie/sodium_compat", - "version": "v1.6.0", + "version": "v1.7.0", "source": { "type": "git", "url": "https://github.com/paragonie/sodium_compat.git", - "reference": "1f6e5682eff4a5a6a394b14331a1904f1740e432" + "reference": "7b73005be3c224f12c47bd75a23ce24b762e47e8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/paragonie/sodium_compat/zipball/1f6e5682eff4a5a6a394b14331a1904f1740e432", - "reference": "1f6e5682eff4a5a6a394b14331a1904f1740e432", + "url": "https://api.github.com/repos/paragonie/sodium_compat/zipball/7b73005be3c224f12c47bd75a23ce24b762e47e8", + "reference": "7b73005be3c224f12c47bd75a23ce24b762e47e8", "shasum": "" }, "require": { - "paragonie/random_compat": "^1|^2", + "paragonie/random_compat": ">=1", "php": "^5.2.4|^5.3|^5.4|^5.5|^5.6|^7" }, "require-dev": { @@ -1667,205 +1712,7 @@ "secret-key cryptography", "side-channel resistant" ], - "time": "2018-02-15T05:50:20+00:00" - }, - { - "name": "pear/console_getopt", - "version": "v1.4.1", - "source": { - "type": "git", - "url": "https://github.com/pear/Console_Getopt.git", - "reference": "82f05cd1aa3edf34e19aa7c8ca312ce13a6a577f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/pear/Console_Getopt/zipball/82f05cd1aa3edf34e19aa7c8ca312ce13a6a577f", - "reference": "82f05cd1aa3edf34e19aa7c8ca312ce13a6a577f", - "shasum": "" - }, - "type": "library", - "autoload": { - "psr-0": { - "Console": "./" - } - }, - "notification-url": "https://packagist.org/downloads/", - "include-path": [ - "./" - ], - "license": [ - "BSD-2-Clause" - ], - "authors": [ - { - "name": "Greg Beaver", - "email": "cellog@php.net", - "role": "Helper" - }, - { - "name": "Andrei Zmievski", - "email": "andrei@php.net", - "role": "Lead" - }, - { - "name": "Stig Bakken", - "email": "stig@php.net", - "role": "Developer" - } - ], - "description": "More info available on: http://pear.php.net/package/Console_Getopt", - "time": "2015-07-20T20:28:12+00:00" - }, - { - "name": "pear/pear-core-minimal", - "version": "v1.10.3", - "source": { - "type": "git", - "url": "https://github.com/pear/pear-core-minimal.git", - "reference": "070f0b600b2caca2501e2c9b7e553016e4b0d115" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/pear/pear-core-minimal/zipball/070f0b600b2caca2501e2c9b7e553016e4b0d115", - "reference": "070f0b600b2caca2501e2c9b7e553016e4b0d115", - "shasum": "" - }, - "require": { - "pear/console_getopt": "~1.4", - "pear/pear_exception": "~1.0" - }, - "replace": { - "rsky/pear-core-min": "self.version" - }, - "type": "library", - "autoload": { - "psr-0": { - "": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "include-path": [ - "src/" - ], - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Christian Weiske", - "email": "cweiske@php.net", - "role": "Lead" - } - ], - "description": "Minimal set of PEAR core files to be used as composer dependency", - "time": "2017-02-28T16:46:11+00:00" - }, - { - "name": "pear/pear_exception", - "version": "v1.0.0", - "source": { - "type": "git", - "url": "https://github.com/pear/PEAR_Exception.git", - "reference": "8c18719fdae000b690e3912be401c76e406dd13b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/pear/PEAR_Exception/zipball/8c18719fdae000b690e3912be401c76e406dd13b", - "reference": "8c18719fdae000b690e3912be401c76e406dd13b", - "shasum": "" - }, - "require": { - "php": ">=4.4.0" - }, - "require-dev": { - "phpunit/phpunit": "*" - }, - "type": "class", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-0": { - "PEAR": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "include-path": [ - "." - ], - "license": [ - "BSD-2-Clause" - ], - "authors": [ - { - "name": "Helgi Thormar", - "email": "dufuz@php.net" - }, - { - "name": "Greg Beaver", - "email": "cellog@php.net" - } - ], - "description": "The PEAR Exception base class.", - "homepage": "https://github.com/pear/PEAR_Exception", - "keywords": [ - "exception" - ], - "time": "2015-02-10T20:07:52+00:00" - }, - { - "name": "pear/text_highlighter", - "version": "dev-master", - "source": { - "type": "git", - "url": "https://github.com/pear/Text_Highlighter.git", - "reference": "2ccac2d9eaf55dc08bbbdb7136c93fb399d0f855" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/pear/Text_Highlighter/zipball/2ccac2d9eaf55dc08bbbdb7136c93fb399d0f855", - "reference": "2ccac2d9eaf55dc08bbbdb7136c93fb399d0f855", - "shasum": "" - }, - "require": { - "pear/pear-core-minimal": "~1.10.0", - "php": ">=5.4.0" - }, - "require-dev": { - "phpunit/phpunit": "@stable" - }, - "type": "library", - "autoload": { - "psr-0": { - "Text": "./" - } - }, - "include-path": [ - "./" - ], - "license": [ - "PHP-3.01" - ], - "authors": [ - { - "email": "ssttoo@gmail.com", - "name": "Stoyan Stefanov", - "role": "Lead" - }, - { - "email": "demenev@gmail.com", - "name": "Andrey Demenev", - "role": "Lead" - } - ], - "description": "More info available on: http://pear.php.net/package/Text_Highlighter", - "support": { - "issues": "http://pear.php.net/bugs/search.php?cmd=display&package_name[]=Text_Highlighter", - "source": "https://github.com/pear/Text_Highlighter" - }, - "time": "2018-01-27T08:24:15+00:00" + "time": "2018-09-22T03:59:58+00:00" }, { "name": "pear/text_languagedetect", @@ -2007,94 +1854,6 @@ ], "time": "2016-08-06T14:39:51+00:00" }, - { - "name": "rapidwebltd/rw-file-cache", - "version": "v1.2.5", - "source": { - "type": "git", - "url": "https://github.com/rapidwebltd/RW-File-Cache.git", - "reference": "4a1d5aaefa6ffafec8e2d60787f12bcd9890977e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/rapidwebltd/RW-File-Cache/zipball/4a1d5aaefa6ffafec8e2d60787f12bcd9890977e", - "reference": "4a1d5aaefa6ffafec8e2d60787f12bcd9890977e", - "shasum": "" - }, - "require": { - "php": ">=5.2.1" - }, - "require-dev": { - "phpunit/phpunit": "^5.7" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0-dev" - } - }, - "autoload": { - "psr-4": { - "rapidweb\\RWFileCache\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "LGPL-3.0-only" - ], - "description": "RW File Cache is a PHP File-based Caching Library. Its syntax is designed to closely resemble the PHP memcache extension.", - "homepage": "https://github.com/rapidwebltd/RW-File-Cache", - "keywords": [ - "cache", - "caching", - "caching library", - "file cache", - "library", - "php" - ], - "time": "2018-01-23T17:20:58+00:00" - }, - { - "name": "rapidwebltd/rw-file-cache-psr-6", - "version": "v1.0.0", - "source": { - "type": "git", - "url": "https://github.com/rapidwebltd/RW-File-Cache-PSR-6.git", - "reference": "b74ea201d4c964f0e6db0fb036d1ab28a570df66" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/rapidwebltd/RW-File-Cache-PSR-6/zipball/b74ea201d4c964f0e6db0fb036d1ab28a570df66", - "reference": "b74ea201d4c964f0e6db0fb036d1ab28a570df66", - "shasum": "" - }, - "require": { - "psr/cache": "^1.0", - "rapidwebltd/rw-file-cache": "^1.2.3" - }, - "require-dev": { - "cache/integration-tests": "^0.16.0", - "phpunit/phpunit": "^5.7" - }, - "type": "library", - "autoload": { - "psr-4": { - "rapidweb\\RWFileCachePSR6\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "LGPL-3.0-only" - ], - "authors": [ - { - "name": "Jordan Hall", - "email": "jordan.hall@rapidweb.biz" - } - ], - "description": "PSR-6 adapter for RW File Cache", - "time": "2018-01-30T19:13:45+00:00" - }, { "name": "seld/cli-prompt", "version": "1.0.3", @@ -2145,16 +1904,16 @@ }, { "name": "smarty/smarty", - "version": "v3.1.31", + "version": "v3.1.33", "source": { "type": "git", "url": "https://github.com/smarty-php/smarty.git", - "reference": "c7d42e4a327c402897dd587871434888fde1e7a9" + "reference": "dd55b23121e55a3b4f1af90a707a6c4e5969530f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/smarty-php/smarty/zipball/c7d42e4a327c402897dd587871434888fde1e7a9", - "reference": "c7d42e4a327c402897dd587871434888fde1e7a9", + "url": "https://api.github.com/repos/smarty-php/smarty/zipball/dd55b23121e55a3b4f1af90a707a6c4e5969530f", + "reference": "dd55b23121e55a3b4f1af90a707a6c4e5969530f", "shasum": "" }, "require": { @@ -2194,7 +1953,7 @@ "keywords": [ "templating" ], - "time": "2016-12-14T21:57:25+00:00" + "time": "2018-09-12T20:54:16+00:00" } ], "packages-dev": [ @@ -2252,6 +2011,54 @@ ], "time": "2015-06-14T21:17:01+00:00" }, + { + "name": "hamcrest/hamcrest-php", + "version": "v2.0.0", + "source": { + "type": "git", + "url": "https://github.com/hamcrest/hamcrest-php.git", + "reference": "776503d3a8e85d4f9a1148614f95b7a608b046ad" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hamcrest/hamcrest-php/zipball/776503d3a8e85d4f9a1148614f95b7a608b046ad", + "reference": "776503d3a8e85d4f9a1148614f95b7a608b046ad", + "shasum": "" + }, + "require": { + "php": "^5.3|^7.0" + }, + "replace": { + "cordoval/hamcrest-php": "*", + "davedevelopment/hamcrest-php": "*", + "kodova/hamcrest-php": "*" + }, + "require-dev": { + "phpunit/php-file-iterator": "1.3.3", + "phpunit/phpunit": "~4.0", + "satooshi/php-coveralls": "^1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "hamcrest" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD" + ], + "description": "This is the PHP port of Hamcrest Matchers", + "keywords": [ + "test" + ], + "time": "2016-01-20T08:20:44+00:00" + }, { "name": "mikey179/vfsStream", "version": "v1.6.5", @@ -2298,6 +2105,71 @@ "homepage": "http://vfs.bovigo.org/", "time": "2017-08-01T08:02:14+00:00" }, + { + "name": "mockery/mockery", + "version": "1.2.0", + "source": { + "type": "git", + "url": "https://github.com/mockery/mockery.git", + "reference": "100633629bf76d57430b86b7098cd6beb996a35a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/mockery/mockery/zipball/100633629bf76d57430b86b7098cd6beb996a35a", + "reference": "100633629bf76d57430b86b7098cd6beb996a35a", + "shasum": "" + }, + "require": { + "hamcrest/hamcrest-php": "~2.0", + "lib-pcre": ">=7.0", + "php": ">=5.6.0" + }, + "require-dev": { + "phpunit/phpunit": "~5.7.10|~6.5|~7.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-0": { + "Mockery": "library/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Pádraic Brady", + "email": "padraic.brady@gmail.com", + "homepage": "http://blog.astrumfutura.com" + }, + { + "name": "Dave Marshall", + "email": "dave.marshall@atstsolutions.co.uk", + "homepage": "http://davedevelopment.co.uk" + } + ], + "description": "Mockery is a simple yet flexible PHP mock object framework", + "homepage": "https://github.com/mockery/mockery", + "keywords": [ + "BDD", + "TDD", + "library", + "mock", + "mock objects", + "mockery", + "stub", + "test", + "test double", + "testing" + ], + "time": "2018-10-02T21:52:37+00:00" + }, { "name": "myclabs/deep-copy", "version": "1.7.0", @@ -2343,53 +2215,6 @@ ], "time": "2017-10-19T19:58:43+00:00" }, - { - "name": "phar-io/version", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/phar-io/version.git", - "reference": "a70c0ced4be299a63d32fa96d9281d03e94041df" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phar-io/version/zipball/a70c0ced4be299a63d32fa96d9281d03e94041df", - "reference": "a70c0ced4be299a63d32fa96d9281d03e94041df", - "shasum": "" - }, - "require": { - "php": "^5.6 || ^7.0" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" - }, - { - "name": "Sebastian Heuer", - "email": "sebastian@phpeople.de", - "role": "Developer" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "Developer" - } - ], - "description": "Library for handling version information and constraints", - "time": "2017-03-05T17:38:23+00:00" - }, { "name": "phpdocumentor/reflection-common", "version": "1.0.1", @@ -2538,16 +2363,16 @@ }, { "name": "phpspec/prophecy", - "version": "1.7.6", + "version": "1.8.0", "source": { "type": "git", "url": "https://github.com/phpspec/prophecy.git", - "reference": "33a7e3c4fda54e912ff6338c48823bd5c0f0b712" + "reference": "4ba436b55987b4bf311cb7c6ba82aa528aac0a06" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/33a7e3c4fda54e912ff6338c48823bd5c0f0b712", - "reference": "33a7e3c4fda54e912ff6338c48823bd5c0f0b712", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/4ba436b55987b4bf311cb7c6ba82aa528aac0a06", + "reference": "4ba436b55987b4bf311cb7c6ba82aa528aac0a06", "shasum": "" }, "require": { @@ -2559,12 +2384,12 @@ }, "require-dev": { "phpspec/phpspec": "^2.5|^3.2", - "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5" + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5 || ^7.1" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.7.x-dev" + "dev-master": "1.8.x-dev" } }, "autoload": { @@ -2597,7 +2422,7 @@ "spy", "stub" ], - "time": "2018-04-18T13:57:24+00:00" + "time": "2018-08-05T17:53:17+00:00" }, { "name": "phpunit/dbunit", @@ -3558,21 +3383,80 @@ "time": "2016-10-03T07:35:21+00:00" }, { - "name": "symfony/yaml", - "version": "v3.4.8", + "name": "symfony/polyfill-ctype", + "version": "v1.9.0", "source": { "type": "git", - "url": "https://github.com/symfony/yaml.git", - "reference": "a42f9da85c7c38d59f5e53f076fe81a091f894d0" + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "e3d826245268269cd66f8326bd8bc066687b4a19" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/a42f9da85c7c38d59f5e53f076fe81a091f894d0", - "reference": "a42f9da85c7c38d59f5e53f076fe81a091f894d0", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/e3d826245268269cd66f8326bd8bc066687b4a19", + "reference": "e3d826245268269cd66f8326bd8bc066687b4a19", "shasum": "" }, "require": { - "php": "^5.5.9|>=7.0.8" + "php": ">=5.3.3" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.9-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + }, + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "time": "2018-08-06T14:22:27+00:00" + }, + { + "name": "symfony/yaml", + "version": "v3.4.16", + "source": { + "type": "git", + "url": "https://github.com/symfony/yaml.git", + "reference": "61973ecda60e9f3561e929e19c07d4878b960fc1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/yaml/zipball/61973ecda60e9f3561e929e19c07d4878b960fc1", + "reference": "61973ecda60e9f3561e929e19c07d4878b960fc1", + "shasum": "" + }, + "require": { + "php": "^5.5.9|>=7.0.8", + "symfony/polyfill-ctype": "~1.8" }, "conflict": { "symfony/console": "<3.4" @@ -3613,7 +3497,7 @@ ], "description": "Symfony Yaml Component", "homepage": "https://symfony.com", - "time": "2018-04-03T05:14:20+00:00" + "time": "2018-09-24T08:15:45+00:00" }, { "name": "webmozart/assert", @@ -3669,8 +3553,7 @@ "aliases": [], "minimum-stability": "stable", "stability-flags": { - "lightopenid/lightopenid": 20, - "pear/text_highlighter": 20 + "lightopenid/lightopenid": 20 }, "prefer-stable": false, "prefer-lowest": false, diff --git a/config/config.ini.php b/config/config.ini.php index 8274399843..ea3df52cbd 100644 --- a/config/config.ini.php +++ b/config/config.ini.php @@ -140,6 +140,10 @@ disable_url_validation = false ; Disable the exposition check against the remote haveibeenpwned API on password change. disable_password_exposed = false +; disable_polling (Boolean) +; Disable the polling of DFRN and OStatus contacts through onepoll.php. +disable_polling = false + ; dlogfile (Path) ; location of the developer log file. dlogfile = diff --git a/config/dbstructure.json b/config/dbstructure.json index c467ba6bc7..da1da7a66b 100644 --- a/config/dbstructure.json +++ b/config/dbstructure.json @@ -15,6 +15,34 @@ "name": ["UNIQUE", "name"] } }, + "apcontact": { + "comment": "ActivityPub compatible contacts - used in the ActivityPub implementation", + "fields": { + "url": {"type": "varbinary(255)", "not null": "1", "primary": "1", "comment": "URL of the contact"}, + "uuid": {"type": "varchar(255)", "comment": ""}, + "type": {"type": "varchar(20)", "not null": "1", "comment": ""}, + "following": {"type": "varchar(255)", "comment": ""}, + "followers": {"type": "varchar(255)", "comment": ""}, + "inbox": {"type": "varchar(255)", "not null": "1", "comment": ""}, + "outbox": {"type": "varchar(255)", "comment": ""}, + "sharedinbox": {"type": "varchar(255)", "comment": ""}, + "nick": {"type": "varchar(255)", "not null": "1", "default": "", "comment": ""}, + "name": {"type": "varchar(255)", "comment": ""}, + "about": {"type": "text", "comment": ""}, + "photo": {"type": "varchar(255)", "comment": ""}, + "addr": {"type": "varchar(255)", "comment": ""}, + "alias": {"type": "varchar(255)", "comment": ""}, + "pubkey": {"type": "text", "comment": ""}, + "baseurl": {"type": "varchar(255)", "comment": "baseurl of the ap contact"}, + "updated": {"type": "datetime", "not null": "1", "default": "0001-01-01 00:00:00", "comment": ""} + + }, + "indexes": { + "PRIMARY": ["url"], + "addr": ["addr(32)"], + "url": ["followers(190)"] + } + }, "attach": { "comment": "file attachments", "fields": { @@ -164,6 +192,7 @@ "hidden": {"type": "boolean", "not null": "1", "default": "0", "comment": ""}, "archive": {"type": "boolean", "not null": "1", "default": "0", "comment": ""}, "pending": {"type": "boolean", "not null": "1", "default": "1", "comment": ""}, + "deleted": {"type": "boolean", "not null": "1", "default": "0", "comment": "Contact has been deleted"}, "rating": {"type": "tinyint", "not null": "1", "default": "0", "comment": ""}, "reason": {"type": "text", "comment": ""}, "closeness": {"type": "tinyint unsigned", "not null": "1", "default": "99", "comment": ""}, @@ -215,7 +244,7 @@ "reply-to-uri": {"type": "varbinary(255)", "not null": "1", "default": "", "comment": "URI to which this item is a reply"}, "conversation-uri": {"type": "varbinary(255)", "not null": "1", "default": "", "comment": "GNU Social conversation URI"}, "conversation-href": {"type": "varbinary(255)", "not null": "1", "default": "", "comment": "GNU Social conversation link"}, - "protocol": {"type": "tinyint unsigned", "not null": "1", "default": "0", "comment": "The protocol of the item"}, + "protocol": {"type": "tinyint unsigned", "not null": "1", "default": "255", "comment": "The protocol of the item"}, "source": {"type": "mediumtext", "comment": "Original source"}, "received": {"type": "datetime", "not null": "1", "default": "0001-01-01 00:00:00", "comment": "Receiving date"} }, @@ -225,6 +254,16 @@ "received": ["received"] } }, + "diaspora-interaction": { + "comment": "Signed Diaspora Interaction", + "fields": { + "uri-id": {"type": "int unsigned", "not null": "1", "primary": "1", "relation": {"item-uri": "id"}, "comment": "Id of the item-uri table entry that contains the item uri"}, + "interaction": {"type": "mediumtext", "comment": "The Diaspora interaction"} + }, + "indexes": { + "PRIMARY": ["uri-id"] + } + }, "event": { "comment": "Events", "fields": { @@ -581,7 +620,8 @@ "indexes": { "PRIMARY": ["id"], "uri-hash": ["UNIQUE", "uri-hash"], - "uri": ["uri(191)"] + "uri": ["uri(191)"], + "uri-id": ["uri-id"] } }, "item-content": { @@ -610,7 +650,8 @@ "indexes": { "PRIMARY": ["id"], "uri-plink-hash": ["UNIQUE", "uri-plink-hash"], - "uri": ["uri(191)"] + "uri": ["uri(191)"], + "uri-id": ["uri-id"] } }, "item-delivery-data": { @@ -1269,14 +1310,16 @@ "created": {"type": "datetime", "not null": "1", "default": "0001-01-01 00:00:00", "comment": "Creation date"}, "pid": {"type": "int unsigned", "not null": "1", "default": "0", "comment": "Process id of the worker"}, "executed": {"type": "datetime", "not null": "1", "default": "0001-01-01 00:00:00", "comment": "Execution date"}, + "next_try": {"type": "datetime", "not null": "1", "default": "0001-01-01 00:00:00", "comment": "Next retrial date"}, + "retrial": {"type": "tinyint", "not null": "1", "default": "0", "comment": "Retrial counter"}, "done": {"type": "boolean", "not null": "1", "default": "0", "comment": "Marked 1 when the task was done - will be deleted later"} }, "indexes": { "PRIMARY": ["id"], "pid": ["pid"], "parameter": ["parameter(64)"], - "priority_created": ["priority", "created"], - "done_executed": ["done", "executed"] + "priority_created_next_try": ["priority", "created", "next_try"], + "done_executed_next_try": ["done", "executed", "next_try"] } } } diff --git a/database.sql b/database.sql index 60d4b1c88e..2f67a341cc 100644 --- a/database.sql +++ b/database.sql @@ -1,6 +1,6 @@ -- ------------------------------------------ --- Friendica 2018.08-dev (The Tazmans Flax-lily) --- DB_UPDATE_VERSION 1283 +-- Friendica 2018.12-dev (The Tazmans Flax-lily) +-- DB_UPDATE_VERSION 1287 -- ------------------------------------------ @@ -19,6 +19,32 @@ CREATE TABLE IF NOT EXISTS `addon` ( UNIQUE INDEX `name` (`name`) ) DEFAULT COLLATE utf8mb4_general_ci COMMENT='registered addons'; +-- +-- TABLE apcontact +-- +CREATE TABLE IF NOT EXISTS `apcontact` ( + `url` varbinary(255) NOT NULL COMMENT 'URL of the contact', + `uuid` varchar(255) COMMENT '', + `type` varchar(20) NOT NULL COMMENT '', + `following` varchar(255) COMMENT '', + `followers` varchar(255) COMMENT '', + `inbox` varchar(255) NOT NULL COMMENT '', + `outbox` varchar(255) COMMENT '', + `sharedinbox` varchar(255) COMMENT '', + `nick` varchar(255) NOT NULL DEFAULT '' COMMENT '', + `name` varchar(255) COMMENT '', + `about` text COMMENT '', + `photo` varchar(255) COMMENT '', + `addr` varchar(255) COMMENT '', + `alias` varchar(255) COMMENT '', + `pubkey` text COMMENT '', + `baseurl` varchar(255) COMMENT 'baseurl of the ap contact', + `updated` datetime NOT NULL DEFAULT '0001-01-01 00:00:00' COMMENT '', + PRIMARY KEY(`url`), + INDEX `addr` (`addr`(32)), + INDEX `url` (`followers`(190)) +) DEFAULT COLLATE utf8mb4_general_ci COMMENT='ActivityPub compatible contacts - used in the ActivityPub implementation'; + -- -- TABLE attach -- @@ -163,6 +189,7 @@ CREATE TABLE IF NOT EXISTS `contact` ( `hidden` boolean NOT NULL DEFAULT '0' COMMENT '', `archive` boolean NOT NULL DEFAULT '0' COMMENT '', `pending` boolean NOT NULL DEFAULT '1' COMMENT '', + `deleted` boolean NOT NULL DEFAULT '0' COMMENT 'Contact has been deleted', `rating` tinyint NOT NULL DEFAULT 0 COMMENT '', `reason` text COMMENT '', `closeness` tinyint unsigned NOT NULL DEFAULT 99 COMMENT '', @@ -212,7 +239,7 @@ CREATE TABLE IF NOT EXISTS `conversation` ( `reply-to-uri` varbinary(255) NOT NULL DEFAULT '' COMMENT 'URI to which this item is a reply', `conversation-uri` varbinary(255) NOT NULL DEFAULT '' COMMENT 'GNU Social conversation URI', `conversation-href` varbinary(255) NOT NULL DEFAULT '' COMMENT 'GNU Social conversation link', - `protocol` tinyint unsigned NOT NULL DEFAULT 0 COMMENT 'The protocol of the item', + `protocol` tinyint unsigned NOT NULL DEFAULT 255 COMMENT 'The protocol of the item', `source` mediumtext COMMENT 'Original source', `received` datetime NOT NULL DEFAULT '0001-01-01 00:00:00' COMMENT 'Receiving date', PRIMARY KEY(`item-uri`), @@ -220,6 +247,15 @@ CREATE TABLE IF NOT EXISTS `conversation` ( INDEX `received` (`received`) ) DEFAULT COLLATE utf8mb4_general_ci COMMENT='Raw data and structure information for messages'; +-- +-- TABLE diaspora-interaction +-- +CREATE TABLE IF NOT EXISTS `diaspora-interaction` ( + `uri-id` int unsigned NOT NULL COMMENT 'Id of the item-uri table entry that contains the item uri', + `interaction` mediumtext COMMENT 'The Diaspora interaction', + PRIMARY KEY(`uri-id`) +) DEFAULT COLLATE utf8mb4_general_ci COMMENT='Signed Diaspora Interaction'; + -- -- TABLE event -- @@ -1215,12 +1251,14 @@ CREATE TABLE IF NOT EXISTS `workerqueue` ( `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', `executed` datetime NOT NULL DEFAULT '0001-01-01 00:00:00' COMMENT 'Execution date', + `next_try` datetime NOT NULL DEFAULT '0001-01-01 00:00:00' COMMENT 'Next retrial date', + `retrial` tinyint NOT NULL DEFAULT 0 COMMENT 'Retrial counter', `done` boolean NOT NULL DEFAULT '0' COMMENT 'Marked 1 when the task was done - will be deleted later', PRIMARY KEY(`id`), INDEX `pid` (`pid`), INDEX `parameter` (`parameter`(64)), - INDEX `priority_created` (`priority`,`created`), - INDEX `done_executed` (`done`,`executed`) + INDEX `priority_created_next_try` (`priority`,`created`,`next_try`), + INDEX `done_executed_next_try` (`done`,`executed`,`next_try`) ) DEFAULT COLLATE utf8mb4_general_ci COMMENT='Background tasks queue entries'; diff --git a/doc/Addons.md b/doc/Addons.md index 2465db7307..011bca0737 100644 --- a/doc/Addons.md +++ b/doc/Addons.md @@ -67,55 +67,67 @@ $b can be called anything you like. This is information specific to the hook currently being processed, and generally contains information that is being immediately processed or acted on that you can use, display, or alter. Remember to declare it with `&` if you wish to alter it. -## JavaScript addon hooks +## Global stylesheets -### PHP part - -Make sure your JavaScript addon file (addon/*addon_name*/*addon_name*.js) is listed in the document response. - -In your addon install function, add: +If your addon requires adding a stylesheet on all pages of Friendica, add the following hook: ```php -Addon::registerHook('template_vars', __FILE__, '_template_vars'); -``` - -In your addon uninstall function, add: - -```php -Addon::unregisterHook('template_vars', __FILE__, '_template_vars'); -``` - -Then, add your addon name to the *addon_hooks* template variable array: - -```php -function _template_vars($a, &$arr) +function _install() { - if (!array_key_exists('addon_hooks', $arr['vars'])) - { - $arr['vars']['addon_hooks'] = array(); - } - $arr['vars']['addon_hooks'][] = ""; + Addon::registerHook('head', __FILE__, '_head'); + ... +} + + +function _head(App $a) +{ + $a->registerStylesheet(__DIR__ . '/relative/path/to/addon/stylesheet.css'); } ``` -### JavaScript part +`__DIR__` is the folder path of your addon. -Register your addon hooks in file `addon/*addon_name*/*addon_name*.js`. +## JavaScript + +### Global scripts + +If your addon requires adding a script on all pages of Friendica, add the following hook: + + +```php +function _install() +{ + Addon::registerHook('footer', __FILE__, '_footer'); + ... +} + +function _footer(App $a) +{ + $a->registerFooterScript(__DIR__ . '/relative/path/to/addon/script.js'); +} +``` + +`__DIR__` is the folder path of your addon. + +### JavaScript hooks + +The main Friendica script provides hooks via events dispatched on the `document` property. +In your Javascript file included as described above, add your event listener like this: ```js -Addon_registerHook(type, hookfnstr); +document.addEventListener(name, callback); ``` -*type* is the name of the hook and corresponds to a known Friendica JavaScript hook. -*hookfnstr* is the name of your JavaScript function to execute. +- *name* is the name of the hook and corresponds to a known Friendica JavaScript hook. +- *callback* is a JavaScript anonymous function to execute. -No arguments are provided to your JavaScript callback function. Example: +More info about Javascript event listeners: https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener -```javascript -function myhook_function() { +#### Current JavaScript hooks -} -``` +##### postprocess_liveupdate +Called at the end of the live update process (XmlHttpRequest) and on a post preview. +No additional data is provided. ## Modules @@ -260,6 +272,11 @@ Called after conversion of bbcode to HTML. Called after tag conversion of HTML to bbcode (e.g. remote message posting) `$b` is a string converted text +### head +Called when building the `` sections. +Stylesheets should be registered using this hook. +`$b` is an HTML string of the `` tag. + ### page_header Called after building the page navigation section. `$b` is a string HTML of nav region. @@ -294,6 +311,11 @@ No hook data. Called after HTML content functions have completed. `$b` is (string) HTML of content div. +### footer +Called after HTML content functions have completed. +Deferred Javascript files should be registered using this hook. +`$b` is (string) HTML of footer div/element. + ### avatar_lookup Called when looking up the avatar. `$b` is an array: @@ -389,14 +411,9 @@ Hook data: visitor => array with the contact record of the visitor url => the query string -## Current JavaScript hooks - -### postprocess_liveupdate -Called at the end of the live update process (XmlHttpRequest) - ## Complete list of hook callbacks -Here is a complete list of all hook callbacks with file locations (as of 01-Apr-2018). Please see the source for details of any hooks not documented above. +Here is a complete list of all hook callbacks with file locations (as of 24-Sep-2018). Please see the source for details of any hooks not documented above. ### index.php @@ -571,6 +588,8 @@ Here is a complete list of all hook callbacks with file locations (as of 01-Apr- ### src/App.php Addon::callHooks('load_config'); + Addon::callHooks('head'); + Addon::callHooks('footer'); ### src/Model/Item.php @@ -704,4 +723,4 @@ Here is a complete list of all hook callbacks with file locations (as of 01-Apr- ### view/js/main.js - callAddonHooks("postprocess_liveupdate"); + document.dispatchEvent(new Event('postprocess_liveupdate')); diff --git a/doc/Developers-Intro.md b/doc/Developers-Intro.md index 1e077902d6..5deaf98ff0 100644 --- a/doc/Developers-Intro.md +++ b/doc/Developers-Intro.md @@ -33,7 +33,7 @@ If you don't want to translate the UI, or it is already done to your satisfactio Are you good at designing things? If you have seen Friendica you probably have ideas to improve it, haven't you? -* If you would like to work with us on enhancing the user interface, please join the [UX Watchdogs forum](https://fc.oscp.info/profile/ux-watchdogs) +* If you would like to work with us on enhancing the user interface, please join the [forum for Friendica development](https://forum.friendi.ca/profile/developers). * Make plans for a better Friendica interface design and share them with us. * Tell us if you are able to realize your ideas or what kind of help you need. We can't promise we have the right skills in the group but we'll try. diff --git a/doc/Install.md b/doc/Install.md index 3854c32bce..e6d1d40645 100644 --- a/doc/Install.md +++ b/doc/Install.md @@ -40,6 +40,14 @@ Requirements Installation procedure --- +### Alternative Installation Methods + +This guide will walk you through the manual installation process of Friendica. +If this is nothing for you, you might be interested in + +* the [Friendica Docker image](https://github.com/friendica/docker) or +* how [install Friendica with YunoHost](https://github.com/YunoHost-Apps/friendica_ynh). + ### Get Friendica Unpack the Friendica files into the root of your web server document area. @@ -164,6 +172,7 @@ if you don't use the option `--savedb` during installation, the DB credentials w This variables wont be used at normal Friendica runtime. Instead, they get saved into `config/local.ini.php`. +- `FRIENDICA_URL_PATH` The URL path of Friendica (f.e. '/friendica') - `FRIENDICA_PHP_PATH` The path of the PHP binary - `FRIENDICA_ADMIN_MAIL` The admin email address of Friendica (this email will be used for admin access) - `FRIENDICA_TZ` The timezone of Friendica @@ -182,7 +191,8 @@ All options will be saved in the `config/local.ini.php` and are overruling the a - `-U|--dbuser ` The username of the mysql/mariadb database login (env `MYSQL_USER` or `MYSQL_USERNAME`) - `-P|--dbpass ` The password of the mysql/mariadb database login (env `MYSQL_PASSWORD`) - `-d|--dbdata ` The name of the mysql/mariadb database (env `MYSQL_DATABASE`) -- `-b|--phppath ` The path of the PHP binary (env `FRIENDICA_PHP_PATH`) +- `-u|--urlpath ` The URL path of Friendica - f.e. '/friendica' (env `FRIENDICA_URL_PATH`) +- `-b|--phppath ` The path of the PHP binary (env `FRIENDICA_PHP_PATH`) - `-A|--admin ` The admin email address of Friendica (env `FRIENDICA_ADMIN_MAIL`) - `-T|--tz ` The timezone of Friendica (env `FRIENDICA_TZ`) - `-L|--land ` The language of Friendica (env `FRIENDICA_LANG`) diff --git a/doc/Quick-Start-groupsandpages.md b/doc/Quick-Start-groupsandpages.md index 652407d642..d4680f65f2 100644 --- a/doc/Quick-Start-groupsandpages.md +++ b/doc/Quick-Start-groupsandpages.md @@ -15,6 +15,6 @@ Remember the link at the top of this page will bring you back here. Once you've added some groups, move on to the next section. - + diff --git a/doc/de/FAQ.md b/doc/de/FAQ.md index 6baa5c5f5e..fe8a9d128d 100644 --- a/doc/de/FAQ.md +++ b/doc/de/FAQ.md @@ -180,7 +180,7 @@ Hier ist eine Liste von Clients bei denen dies möglich ist, bzw. die speziell f ### Wo finde ich Hilfe? -Wenn Du Probleme mit Deiner Friendica-Seite hast, dann kannst Du die Community in der [Friendica-Support-Gruppe](https://forum.friendi.ca/profile/helpers) oder im [deutschen Friendica-Support-Forum](http://toktan.org/profile/wiki) fragen oder Dir das [deutsche Wiki](http://wiki.toktan.org/doku.php) anschauen. +Wenn Du Probleme mit Deiner Friendica-Seite hast, dann kannst Du die Community in der [Friendica-Support-Gruppe](https://forum.friendi.ca/profile/helpers) fragen oder Dir das [deutsche Wiki](https://friendica-wiki.de/) anschauen. Wenn Du Deinen Account nicht nutzen kannst, kannst Du entweder einen [Testaccount](https://tryfriendica.de) bzw. einen Account auf einer öffentlichen Seite ([Liste](https://dir.friendica.social/servers)) nutzen. Wenn du dir keinen weiteren Friendica Account einrichten willst, kannst du auch gerne über einen der folgenden alternativen Kanäle Hilfe suchen: diff --git a/doc/de/Home.md b/doc/de/Home.md index b6a07cc09a..6c95476eda 100644 --- a/doc/de/Home.md +++ b/doc/de/Home.md @@ -61,7 +61,7 @@ Friendica - Dokumentation und Ressourcen **Externe Ressourcen** * [Haupt-Webseite](https://friendi.ca) -* [Deutsches Friendica-Wiki](http://wiki.toktan.org/doku.php) +* [Deutsches Friendica-Wiki](https://friendica-wiki.de) * Support Kanäle * [Friendica Support Forum](https://forum.friendi.ca/~helpers) * [Mailing Listen Archiv](http://mailman.friendi.ca/mailman/listinfo/support-friendi.ca) zum Abonnieren der Liste eine E-Mail an ``support-request(at)friendi.ca?subject=subscribe`` senden diff --git a/doc/de/Install.md b/doc/de/Install.md index 05a4e1e465..132fbc1904 100644 --- a/doc/de/Install.md +++ b/doc/de/Install.md @@ -40,6 +40,14 @@ Requirements Installation --- +### Alternative Wege um Friendica zu Installieren + +Diese Anleitung wird dir Schritt-für-Schritt zeigen wie du Friendica auf deinem Server installieren kannst. +Falls du an automatischen Möglichkeiten interesse hast, wirf doch einen Blick auf + +* das [Docker image für Friendica](https://github.com/friendica/docker) oder +* die [Installation von Friendica auf YunoHost](https://github.com/YunoHost-Apps/friendica_ynh). + ### Friendica Entpacke die Friendica-Daten in das Quellverzeichnis (root) des Dokumentenbereichs deines Webservers. @@ -82,7 +90,7 @@ Dies tust du mit den folgenden Befehlen Die Entwickler Version kann nach einem fehlerhaften Commit vorübergehend Probleme haben oder gar nicht mehr funktionieren. Sollte dir so etwas passieren, lass es uns bitte wissen, damit der Fehler behoben werden kann. -### Erselle eine Datenbank +### Erstelle eine Datenbank Erstelle eine leere Datenbank und notiere alle Zugangsdaten (Adresse der Datenbank, Nutzername, Passwort, Datenbankname). diff --git a/include/api.php b/include/api.php index f40674b894..ff763e9885 100644 --- a/include/api.php +++ b/include/api.php @@ -581,7 +581,10 @@ function api_get_user(App $a, $contact_id = null) if (is_null($user) && ($a->argc > (count($called_api) - 1)) && (count($called_api) > 0)) { $argid = count($called_api); if (!empty($a->argv[$argid])) { - list($user, $null) = explode(".", $a->argv[$argid]); + $data = explode(".", $a->argv[$argid]); + if (count($data) > 1) { + list($user, $null) = $data; + } } if (is_numeric($user)) { $user = DBA::escape(api_unique_id_to_nurl(intval($user))); @@ -758,7 +761,7 @@ function api_get_user(App $a, $contact_id = null) 'statusnet_blocking' => false, 'notifications' => false, /// @TODO old way? - //'statusnet_profile_url' => System::baseUrl()."/contacts/".$uinfo[0]['cid'], + //'statusnet_profile_url' => System::baseUrl()."/contact/".$uinfo[0]['cid'], 'statusnet_profile_url' => $uinfo[0]['url'], 'uid' => intval($uinfo[0]['uid']), 'cid' => intval($uinfo[0]['cid']), @@ -816,7 +819,7 @@ function api_item_get_user(App $a, $item) $status_user["protected"] = defaults($item, 'private', 0); if (defaults($item, 'thr-parent', '') == defaults($item, 'uri', '')) { - $owner_user = api_get_user($a, defaults($item, 'author-id', null)); + $owner_user = api_get_user($a, defaults($item, 'owner-id', null)); } else { $owner_user = $status_user; } @@ -1056,10 +1059,10 @@ function api_statuses_mediap($type) // now that we have the img url in bbcode we can add it to the status and insert the wall item. $_REQUEST['body'] = $txt . "\n\n" . '[url=' . $picture["albumpage"] . '][img]' . $picture["preview"] . "[/img][/url]"; - item_post($a); + $item_id = item_post($a); - // this should output the last post (the one we just posted). - return api_status_show($type); + // output the post that we just posted. + return api_status_show($type, $item_id); } /// @TODO move this to top of file or somewhere better! @@ -1075,7 +1078,6 @@ api_register_func('api/statuses/mediap', 'api_statuses_mediap', true, API_METHOD */ function api_statuses_update($type) { - $a = get_app(); if (api_user() === false) { @@ -1129,8 +1131,8 @@ function api_statuses_update($type) if ($throttle_day > 0) { $datefrom = date(DateTimeFormat::MYSQL, time() - 24*60*60); - $condition = ["`uid` = ? AND `wall` AND `created` > ? AND `id` = `parent`", api_user(), $datefrom]; - $posts_day = DBA::count('item', $condition); + $condition = ["`uid` = ? AND `wall` AND `created` > ?", api_user(), $datefrom]; + $posts_day = DBA::count('thread', $condition); if ($posts_day > $throttle_day) { logger('Daily posting limit reached for user '.api_user(), LOGGER_DEBUG); @@ -1143,8 +1145,8 @@ function api_statuses_update($type) if ($throttle_week > 0) { $datefrom = date(DateTimeFormat::MYSQL, time() - 24*60*60*7); - $condition = ["`uid` = ? AND `wall` AND `created` > ? AND `id` = `parent`", api_user(), $datefrom]; - $posts_week = DBA::count('item', $condition); + $condition = ["`uid` = ? AND `wall` AND `created` > ?", api_user(), $datefrom]; + $posts_week = DBA::count('thread', $condition); if ($posts_week > $throttle_week) { logger('Weekly posting limit reached for user '.api_user(), LOGGER_DEBUG); @@ -1157,8 +1159,8 @@ function api_statuses_update($type) if ($throttle_month > 0) { $datefrom = date(DateTimeFormat::MYSQL, time() - 24*60*60*30); - $condition = ["`uid` = ? AND `wall` AND `created` > ? AND `id` = `parent`", api_user(), $datefrom]; - $posts_month = DBA::count('item', $condition); + $condition = ["`uid` = ? AND `wall` AND `created` > ?", api_user(), $datefrom]; + $posts_month = DBA::count('thread', $condition); if ($posts_month > $throttle_month) { logger('Monthly posting limit reached for user '.api_user(), LOGGER_DEBUG); @@ -1200,10 +1202,10 @@ function api_statuses_update($type) } // call out normal post function - item_post($a); + $item_id = item_post($a); - // this should output the last post (the one we just posted). - return api_status_show($type); + // output the post that we just posted. + return api_status_show($type, $item_id); } /// @TODO move to top of file or somewhere better @@ -1260,7 +1262,7 @@ api_register_func('api/media/upload', 'api_media_upload', true, API_METHOD_POST) * * @return array|string */ -function api_status_show($type) +function api_status_show($type, $item_id = 0) { $a = get_app(); @@ -1274,9 +1276,14 @@ function api_status_show($type) $privacy_sql = ""; } - // get last public wall message - $condition = ['owner-id' => $user_info['pid'], 'uid' => api_user(), - 'gravity' => [GRAVITY_PARENT, GRAVITY_COMMENT]]; + if (!empty($item_id)) { + // Get the item with the given id + $condition = ['id' => $item_id]; + } else { + // get last public wall message + $condition = ['owner-id' => $user_info['pid'], 'uid' => api_user(), + 'gravity' => [GRAVITY_PARENT, GRAVITY_COMMENT]]; + } $lastwall = Item::selectFirst(Item::ITEM_FIELDLIST, $condition, ['order' => ['id' => true]]); if (DBA::isResult($lastwall)) { @@ -1993,14 +2000,14 @@ function api_statuses_repeat($type) $_REQUEST["source"] = api_source(); } - item_post($a); + $item_id = item_post($a); } else { throw new ForbiddenException(); } - // this should output the last post (the one we just posted). + // output the post that we just posted. $called_api = []; - return api_status_show($type); + return api_status_show($type, $item_id); } /// @TODO move to top of file or somewhere better @@ -2344,7 +2351,7 @@ function api_format_messages($item, $recipient, $sender) // standard meta information $ret = [ 'id' => $item['id'], - 'sender_id' => $sender['id'] , + 'sender_id' => $sender['id'], 'text' => "", 'recipient_id' => $recipient['id'], 'created_at' => api_date(defaults($item, 'created', DateTimeFormat::utcNow())), @@ -2725,7 +2732,7 @@ function api_contactlink_to_array($txt) * likes => int count, * dislikes => int count */ -function api_format_items_activities(&$item, $type = "json") +function api_format_items_activities($item, $type = "json") { $a = get_app(); @@ -2740,13 +2747,13 @@ function api_format_items_activities(&$item, $type = "json") $condition = ['uid' => $item['uid'], 'thr-parent' => $item['uri']]; $ret = Item::selectForUser($item['uid'], ['author-id', 'verb'], $condition); - while ($item = Item::fetch($ret)) { + while ($parent_item = Item::fetch($ret)) { // not used as result should be structured like other user data //builtin_activity_puller($i, $activities); // get user data and add it to the array of the activity - $user = api_get_user($a, $item['author-id']); - switch ($item['verb']) { + $user = api_get_user($a, $parent_item['author-id']); + switch ($parent_item['verb']) { case ACTIVITY_LIKE: $activities['like'][] = $user; break; @@ -2886,7 +2893,7 @@ function api_format_items($r, $user_info, $filter_user = false, $type = "json") 'in_reply_to_screen_name' => $in_reply_to['screen_name'], $geo => null, 'favorited' => $item['starred'] ? true : false, - 'user' => $status_user , + 'user' => $status_user, 'friendica_owner' => $owner_user, 'friendica_private' => $item['private'] == 1, //'entities' => NULL, @@ -3337,7 +3344,7 @@ function api_statusnet_config($type) $a = get_app(); $name = Config::get('config', 'sitename'); - $server = $a->get_hostname(); + $server = $a->getHostName(); $logo = System::baseUrl() . '/images/friendica-64.png'; $email = Config::get('config', 'admin_email'); $closed = intval(Config::get('config', 'register_policy')) === REGISTER_CLOSED ? 'true' : 'false'; @@ -3394,7 +3401,7 @@ api_register_func('api/statusnet/version', 'api_statusnet_version', false); */ function api_ff_ids($type) { - if (! api_user()) { + if (!api_user()) { throw new ForbiddenException(); } @@ -3622,6 +3629,84 @@ function api_direct_messages_destroy($type) /// @TODO move to top of file or somewhere better api_register_func('api/direct_messages/destroy', 'api_direct_messages_destroy', true, API_METHOD_DELETE); +/** + * Unfollow Contact + * + * @brief unfollow contact + * + * @param string $type Known types are 'atom', 'rss', 'xml' and 'json' + * @return string|array + * @see https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/post-friendships-destroy.html + */ +function api_friendships_destroy($type) +{ + $uid = api_user(); + + if ($uid === false) { + throw new ForbiddenException(); + } + + $contact_id = defaults($_REQUEST, 'user_id'); + + if (empty($contact_id)) { + logger("No user_id specified", LOGGER_DEBUG); + throw new BadRequestException("no user_id specified"); + } + + // Get Contact by given id + $contact = DBA::selectFirst('contact', ['url'], ['id' => $contact_id, 'uid' => 0, 'self' => false]); + + if(!DBA::isResult($contact)) { + logger("No contact found for ID" . $contact_id, LOGGER_DEBUG); + throw new NotFoundException("no contact found to given ID"); + } + + $url = $contact["url"]; + + $condition = ["`uid` = ? AND (`rel` = ? OR `rel` = ?) AND (`nurl` = ? OR `alias` = ? OR `alias` = ?)", + $uid, Contact::SHARING, Contact::FRIEND, normalise_link($url), + normalise_link($url), $url]; + $contact = DBA::selectFirst('contact', [], $condition); + + if (!DBA::isResult($contact)) { + logger("Not following Contact", LOGGER_DEBUG); + throw new NotFoundException("Not following Contact"); + } + + if (!in_array($contact['network'], Protocol::NATIVE_SUPPORT)) { + logger("Not supported", LOGGER_DEBUG); + throw new ExpectationFailedException("Not supported"); + } + + $dissolve = ($contact['rel'] == Contact::SHARING); + + $owner = User::getOwnerDataById($uid); + if ($owner) { + Contact::terminateFriendship($owner, $contact, $dissolve); + } + else { + logger("No owner found", LOGGER_DEBUG); + throw new NotFoundException("Error Processing Request"); + } + + // Sharing-only contacts get deleted as there no relationship any more + if ($dissolve) { + Contact::remove($contact['id']); + } else { + DBA::update('contact', ['rel' => Contact::FOLLOWER], ['id' => $contact['id']]); + } + + // "uid" and "self" are only needed for some internal stuff, so remove it from here + unset($contact["uid"]); + unset($contact["self"]); + + // Set screen_name since Twidere requests it + $contact["screen_name"] = $contact["nick"]; + + return api_format_data("friendships-destroy", $type, ['user' => $contact]); +} +api_register_func('api/friendships/destroy', 'api_friendships_destroy', true, API_METHOD_POST); + /** * * @param string $type Return type (atom, rss, xml, json) @@ -4396,7 +4481,7 @@ function save_media_to_database($mediatype, $media, $type, $album, $allow_cid, $ if ($filetype == "") { $filetype=Image::guessType($filename); } - $imagedata = getimagesize($src); + $imagedata = @getimagesize($src); if ($imagedata) { $filetype = $imagedata['mime']; } @@ -4420,7 +4505,7 @@ function save_media_to_database($mediatype, $media, $type, $album, $allow_cid, $ // create Photo instance with the data of the image $imagedata = @file_get_contents($src); $Image = new Image($imagedata, $filetype); - if (! $Image->isValid()) { + if (!$Image->isValid()) { throw new InternalServerErrorException("unable to process image data"); } @@ -4430,7 +4515,7 @@ function save_media_to_database($mediatype, $media, $type, $album, $allow_cid, $ // check max length of images on server $max_length = Config::get('system', 'max_image_length'); - if (! $max_length) { + if (!$max_length) { $max_length = MAX_IMAGE_LENGTH; } if ($max_length > 0) { @@ -4448,13 +4533,13 @@ function save_media_to_database($mediatype, $media, $type, $album, $allow_cid, $ logger("photo upload: starting new photo upload", LOGGER_DEBUG); $r = Photo::store($Image, local_user(), $visitor, $hash, $filename, $album, 0, 0, $allow_cid, $allow_gid, $deny_cid, $deny_gid, $desc); - if (! $r) { + if (!$r) { logger("photo upload: image upload with scale 0 (original size) failed"); } if ($width > 640 || $height > 640) { $Image->scaleDown(640); $r = Photo::store($Image, local_user(), $visitor, $hash, $filename, $album, 1, 0, $allow_cid, $allow_gid, $deny_cid, $deny_gid, $desc); - if (! $r) { + if (!$r) { logger("photo upload: image upload with scale 1 (640x640) failed"); } } @@ -4462,7 +4547,7 @@ function save_media_to_database($mediatype, $media, $type, $album, $allow_cid, $ if ($width > 320 || $height > 320) { $Image->scaleDown(320); $r = Photo::store($Image, local_user(), $visitor, $hash, $filename, $album, 2, 0, $allow_cid, $allow_gid, $deny_cid, $deny_gid, $desc); - if (! $r) { + if (!$r) { logger("photo upload: image upload with scale 2 (320x320) failed"); } } @@ -4474,7 +4559,7 @@ function save_media_to_database($mediatype, $media, $type, $album, $allow_cid, $ if ($width > 175 || $height > 175) { $Image->scaleDown(175); $r = Photo::store($Image, local_user(), $visitor, $hash, $filename, $album, 4, $profile, $allow_cid, $allow_gid, $deny_cid, $deny_gid, $desc); - if (! $r) { + if (!$r) { logger("photo upload: profile image upload with scale 4 (175x175) failed"); } } @@ -4482,7 +4567,7 @@ function save_media_to_database($mediatype, $media, $type, $album, $allow_cid, $ if ($width > 80 || $height > 80) { $Image->scaleDown(80); $r = Photo::store($Image, local_user(), $visitor, $hash, $filename, $album, 5, $profile, $allow_cid, $allow_gid, $deny_cid, $deny_gid, $desc); - if (! $r) { + if (!$r) { logger("photo upload: profile image upload with scale 5 (80x80) failed"); } } @@ -4490,7 +4575,7 @@ function save_media_to_database($mediatype, $media, $type, $album, $allow_cid, $ if ($width > 48 || $height > 48) { $Image->scaleDown(48); $r = Photo::store($Image, local_user(), $visitor, $hash, $filename, $album, 6, $profile, $allow_cid, $allow_gid, $deny_cid, $deny_gid, $desc); - if (! $r) { + if (!$r) { logger("photo upload: profile image upload with scale 6 (48x48) failed"); } } @@ -4527,7 +4612,7 @@ function post_photo_item($hash, $allow_cid, $deny_cid, $allow_gid, $deny_gid, $f $owner_record = DBA::selectFirst('contact', [], ['uid' => api_user(), 'self' => true]); $arr = []; - $arr['guid'] = System::createGUID(32); + $arr['guid'] = System::createUUID(); $arr['uid'] = intval(api_user()); $arr['uri'] = $uri; $arr['parent-uri'] = $uri; @@ -4742,77 +4827,86 @@ function api_share_as_retweet(&$item) { $body = trim($item["body"]); - if (Diaspora::isReshare($body, false)===false) { - return false; + if (Diaspora::isReshare($body, false) === false) { + if ($item['author-id'] == $item['owner-id']) { + return false; + } else { + // Reshares from OStatus, ActivityPub and Twitter + $reshared_item = $item; + $reshared_item['owner-id'] = $reshared_item['author-id']; + $reshared_item['owner-link'] = $reshared_item['author-link']; + $reshared_item['owner-name'] = $reshared_item['author-name']; + $reshared_item['owner-avatar'] = $reshared_item['author-avatar']; + return $reshared_item; + } } /// @TODO "$1" should maybe mean '$1' ? $attributes = preg_replace("/\[share(.*?)\]\s?(.*?)\s?\[\/share\]\s?/ism", "$1", $body); /* - * Skip if there is no shared message in there - * we already checked this in diaspora::isReshare() - * but better one more than one less... - */ - if ($body == $attributes) { + * Skip if there is no shared message in there + * we already checked this in diaspora::isReshare() + * but better one more than one less... + */ + if (($body == $attributes) || empty($attributes)) { return false; } - // build the fake reshared item $reshared_item = $item; $author = ""; preg_match("/author='(.*?)'/ism", $attributes, $matches); - if ($matches[1] != "") { + if (!empty($matches[1])) { $author = html_entity_decode($matches[1], ENT_QUOTES, 'UTF-8'); } preg_match('/author="(.*?)"/ism', $attributes, $matches); - if ($matches[1] != "") { + if (!empty($matches[1])) { $author = $matches[1]; } $profile = ""; preg_match("/profile='(.*?)'/ism", $attributes, $matches); - if ($matches[1] != "") { + if (!empty($matches[1])) { $profile = $matches[1]; } preg_match('/profile="(.*?)"/ism', $attributes, $matches); - if ($matches[1] != "") { + if (!empty($matches[1])) { $profile = $matches[1]; } $avatar = ""; preg_match("/avatar='(.*?)'/ism", $attributes, $matches); - if ($matches[1] != "") { + if (!empty($matches[1])) { $avatar = $matches[1]; } preg_match('/avatar="(.*?)"/ism', $attributes, $matches); - if ($matches[1] != "") { + if (!empty($matches[1])) { $avatar = $matches[1]; } $link = ""; preg_match("/link='(.*?)'/ism", $attributes, $matches); - if ($matches[1] != "") { + if (!empty($matches[1])) { $link = $matches[1]; } preg_match('/link="(.*?)"/ism', $attributes, $matches); - if ($matches[1] != "") { + if (!empty($matches[1])) { $link = $matches[1]; } $posted = ""; preg_match("/posted='(.*?)'/ism", $attributes, $matches); - if ($matches[1] != "") { + if (!empty($matches[1])) { $posted = $matches[1]; } preg_match('/posted="(.*?)"/ism', $attributes, $matches); - if ($matches[1] != "") { + if (!empty($matches[1])) { $posted = $matches[1]; } diff --git a/include/conversation.php b/include/conversation.php index ca01997f6a..31920c2fcb 100644 --- a/include/conversation.php +++ b/include/conversation.php @@ -229,12 +229,12 @@ function localize_item(&$item) $xmlhead = "<" . "?xml version='1.0' encoding='UTF-8' ?" . ">"; $obj = XML::parseString($xmlhead.$item['object']); - $links = XML::parseString($xmlhead."".unxmlify($obj->link).""); $Bname = $obj->title; - $Blink = ""; + $Blink = $obj->id; $Bphoto = ""; - foreach ($links->link as $l) { + + foreach ($obj->link as $l) { $atts = $l->attributes(); switch ($atts['rel']) { case "alternate": $Blink = $atts['href']; @@ -556,7 +556,7 @@ function conversation(App $a, array $items, $mode, $update, $preview = false, $o if (in_array($mode, ['community', 'contacts'])) { $writable = true; } else { - $writable = ($items[0]['uid'] == 0) && in_array($items[0]['network'], [Protocol::OSTATUS, Protocol::DIASPORA, Protocol::DFRN]); + $writable = ($items[0]['uid'] == 0) && in_array($items[0]['network'], [Protocol::ACTIVITYPUB, Protocol::OSTATUS, Protocol::DIASPORA, Protocol::DFRN]); } if (!local_user()) { @@ -657,7 +657,7 @@ function conversation(App $a, array $items, $mode, $update, $preview = false, $o 'id' => ($preview ? 'P0' : $item['id']), 'guid' => ($preview ? 'Q0' : $item['guid']), 'network' => $item['network'], - 'network_name' => ContactSelector::networkToName($item['network'], $profile_link), + 'network_name' => ContactSelector::networkToName($item['network'], $item['author-link']), 'linktitle' => L10n::t('View %s\'s profile @ %s', $profile_name, $item['author-link']), 'profile_url' => $profile_link, 'item_photo_menu' => item_photo_menu($item), @@ -807,7 +807,7 @@ function conversation_add_children(array $parents, $block_authors, $order, $uid) foreach ($items as $index => $item) { if ($item['uid'] == 0) { - $items[$index]['writable'] = in_array($item['network'], [Protocol::OSTATUS, Protocol::DIASPORA, Protocol::DFRN]); + $items[$index]['writable'] = in_array($item['network'], [Protocol::ACTIVITYPUB, Protocol::OSTATUS, Protocol::DIASPORA, Protocol::DFRN]); } } @@ -853,8 +853,8 @@ function item_photo_menu($item) { if ($cid && !$item['self']) { $poke_link = 'poke/?f=&c=' . $cid; - $contact_url = 'contacts/' . $cid; - $posts_link = 'contacts/' . $cid . '/posts'; + $contact_url = 'contact/' . $cid; + $posts_link = 'contact/' . $cid . '/posts'; if (in_array($network, [Protocol::DFRN, Protocol::DIASPORA])) { $pm_url = 'message/new/' . $cid; @@ -877,7 +877,7 @@ function item_photo_menu($item) { } if ((($cid == 0) || ($rel == Contact::FOLLOWER)) && - in_array($item['network'], [Protocol::DFRN, Protocol::OSTATUS, Protocol::DIASPORA])) { + in_array($item['network'], [Protocol::ACTIVITYPUB, Protocol::DFRN, Protocol::OSTATUS, Protocol::DIASPORA])) { $menu[L10n::t('Connect/Follow')] = 'follow?url=' . urlencode($item['author-link']); } } else { @@ -1091,21 +1091,6 @@ function status_editor(App $a, $x, $notes_cid = 0, $popup = false) '$delitems' => L10n::t("Delete item\x28s\x29?") ]); - $tpl = get_markup_template('jot-end.tpl'); - $a->page['end'] .= replace_macros($tpl, [ - '$newpost' => 'true', - '$baseurl' => System::baseUrl(true), - '$geotag' => $geotag, - '$nickname' => $x['nickname'], - '$ispublic' => L10n::t('Visible to everybody'), - '$linkurl' => L10n::t('Please enter a link URL:'), - '$vidurl' => L10n::t("Please enter a video link/URL:"), - '$audurl' => L10n::t("Please enter an audio link/URL:"), - '$term' => L10n::t('Tag term:'), - '$fileas' => L10n::t('Save to Folder:'), - '$whereareu' => L10n::t('Where are you right now?') - ]); - $jotplugins = ''; Addon::callHooks('jot_tool', $jotplugins); @@ -1454,7 +1439,7 @@ function get_responses(array $conv_responses, array $response_verbs, $ob, array $ret = []; foreach ($response_verbs as $v) { $ret[$v] = []; - $ret[$v]['count'] = defaults($conv_responses[$v], $item['uri'], ''); + $ret[$v]['count'] = defaults($conv_responses[$v], $item['uri'], 0); $ret[$v]['list'] = defaults($conv_responses[$v], $item['uri'] . '-l', []); $ret[$v]['self'] = defaults($conv_responses[$v], $item['uri'] . '-self', '0'); if (count($ret[$v]['list']) > MAX_LIKERS) { diff --git a/include/enotify.php b/include/enotify.php index 70abce5845..6d8cef8794 100644 --- a/include/enotify.php +++ b/include/enotify.php @@ -42,9 +42,9 @@ function notification($params) } $params['notify_flags'] = defaults($params, 'notify_flags', $user['notify-flags']); - $params['language'] = defaults($params, 'language', $user['language']); - $params['to_name'] = defaults($params, 'to_name', $user['username']); - $params['to_email'] = defaults($params, 'to_email', $user['email']); + $params['language'] = defaults($params, 'language' , $user['language']); + $params['to_name'] = defaults($params, 'to_name' , $user['username']); + $params['to_email'] = defaults($params, 'to_email' , $user['email']); // from here on everything is in the recipients language L10n::pushLang($params['language']); @@ -61,7 +61,7 @@ function notification($params) } $sender_name = $sitename; - $hostname = $a->get_hostname(); + $hostname = $a->getHostName(); if (strpos($hostname, ':')) { $hostname = substr($hostname, 0, strpos($hostname, ':')); } @@ -84,7 +84,7 @@ function notification($params) // with $params['show_in_notification_page'] == false, the notification isn't inserted into // the database, and an email is sent if applicable. // default, if not specified: true - $show_in_notification_page = ((x($params, 'show_in_notification_page')) ? $params['show_in_notification_page']:true); + $show_in_notification_page = isset($params['show_in_notification_page']) ? $params['show_in_notification_page'] : true; $additional_mail_header = ""; $additional_mail_header .= "Precedence: list\n"; diff --git a/include/items.php b/include/items.php index 2d7597dcd6..27a7db767b 100644 --- a/include/items.php +++ b/include/items.php @@ -72,7 +72,8 @@ function add_page_info_data(array $data, $no_photos = false) $text .= " title='".$data["title"]."'"; } - if (!empty($data["images"])) { + // Only embedd a picture link when it seems to be a valid picture ("width" is set) + if (!empty($data["images"]) && !empty($data["images"][0]["width"])) { $preview = str_replace(["[", "]"], ["[", "]"], htmlentities($data["images"][0]["src"], ENT_QUOTES, 'UTF-8', false)); // if the preview picture is larger than 500 pixels then show it in a larger mode // But only, if the picture isn't higher than large (To prevent huge posts) @@ -315,9 +316,9 @@ function subscribe_to_hub($url, array $importer, array $contact, $hubmode = 'sub DBA::update('contact', ['hub-verify' => $verify_token], ['id' => $contact['id']]); } - Network::post($url, $params); + $postResult = Network::post($url, $params); - logger('subscribe_to_hub: returns: ' . $a->get_curl_code(), LOGGER_DEBUG); + logger('subscribe_to_hub: returns: ' . $postResult->getReturnCode(), LOGGER_DEBUG); return; @@ -348,12 +349,12 @@ function drop_item($id) // locate item to be deleted - $fields = ['id', 'uid', 'contact-id', 'deleted']; + $fields = ['id', 'uid', 'guid', 'contact-id', 'deleted']; $item = Item::selectFirstForUser(local_user(), $fields, ['id' => $id]); if (!DBA::isResult($item)) { notice(L10n::t('Item not found.') . EOL); - goaway(System::baseUrl() . '/' . $_SESSION['return_url']); + goaway('/network'); } if ($item['deleted']) { @@ -400,17 +401,17 @@ function drop_item($id) } // Now check how the user responded to the confirmation query if (!empty($_REQUEST['canceled'])) { - goaway(System::baseUrl() . '/' . $_SESSION['return_url']); + goaway('/display/' . $item['guid']); } // delete the item Item::deleteForUser(['id' => $item['id']], local_user()); - goaway(System::baseUrl() . '/' . $_SESSION['return_url']); + goaway('/network'); //NOTREACHED } else { notice(L10n::t('Permission denied.') . EOL); - goaway(System::baseUrl() . '/' . $_SESSION['return_url']); + goaway('/display/' . $item['guid']); //NOTREACHED } } diff --git a/include/text.php b/include/text.php index d251824e2b..5a18529d93 100644 --- a/include/text.php +++ b/include/text.php @@ -42,7 +42,7 @@ function replace_macros($s, $r) { // pass $baseurl to all templates $r['$baseurl'] = System::baseUrl(); - $t = $a->template_engine(); + $t = $a->getTemplateEngine(); try { $output = $t->replaceMacros($s, $r); } catch (Exception $e) { @@ -50,7 +50,7 @@ function replace_macros($s, $r) { killme(); } - $a->save_timestamp($stamp1, "rendering"); + $a->saveTimestamp($stamp1, "rendering"); return $output; } @@ -473,7 +473,7 @@ function get_markup_template($s, $root = '') { $stamp1 = microtime(true); $a = get_app(); - $t = $a->template_engine(); + $t = $a->getTemplateEngine(); try { $template = $t->getTemplateFile($s, $root); } catch (Exception $e) { @@ -481,7 +481,7 @@ function get_markup_template($s, $root = '') { killme(); } - $a->save_timestamp($stamp1, "file"); + $a->saveTimestamp($stamp1, "file"); return $template; } @@ -574,7 +574,7 @@ function logger($msg, $level = LOGGER_INFO) { $stamp1 = microtime(true); @file_put_contents($logfile, $logline, FILE_APPEND); - $a->save_timestamp($stamp1, "file"); + $a->saveTimestamp($stamp1, "file"); } /** @@ -634,7 +634,7 @@ function dlogger($msg, $level = LOGGER_INFO) { $stamp1 = microtime(true); @file_put_contents($logfile, $logline, FILE_APPEND); - $a->save_timestamp($stamp1, "file"); + $a->saveTimestamp($stamp1, "file"); } @@ -1191,9 +1191,6 @@ function prepare_body(array &$item, $attach = false, $is_preview = false) $a->page['htmlhead'] .= replace_macros(get_markup_template('videos_head.tpl'), [ '$baseurl' => System::baseUrl(), ]); - $a->page['end'] .= replace_macros(get_markup_template('videos_end.tpl'), [ - '$baseurl' => System::baseUrl(), - ]); } $url_parts = explode('/', $the_url); @@ -1417,7 +1414,7 @@ function get_plink($item) { ]; if (x($item, 'plink')) { - $ret["href"] = $a->remove_baseurl($item['plink']); + $ret["href"] = $a->removeBaseURL($item['plink']); $ret["title"] = L10n::t('link to source'); } @@ -1911,58 +1908,3 @@ function format_network_name($network, $url = 0) { return $network_name; } } - -/** - * @brief Syntax based code highlighting for popular languages. - * @param string $s Code block - * @param string $lang Programming language - * @return string Formated html - */ -function text_highlight($s, $lang) { - if ($lang === 'js') { - $lang = 'javascript'; - } - - if ($lang === 'bash') { - $lang = 'sh'; - } - - // @TODO: Replace Text_Highlighter_Renderer_Html by scrivo/highlight.php - - // Autoload the library to make constants available - class_exists('Text_Highlighter_Renderer_Html'); - - $options = [ - 'numbers' => HL_NUMBERS_LI, - 'tabsize' => 4, - ]; - - $tag_added = false; - $s = trim(html_entity_decode($s, ENT_COMPAT)); - $s = str_replace(' ', "\t", $s); - - /* - * The highlighter library insists on an opening php tag for php code blocks. If - * it isn't present, nothing is highlighted. So we're going to see if it's present. - * If not, we'll add it, and then quietly remove it after we get the processed output back. - */ - if ($lang === 'php' && strpos($s, 'factory($lang); - $hl->setRenderer($renderer); - $o = $hl->highlight($s); - $o = str_replace("\n", '', $o); - - if ($tag_added) { - $b = substr($o, 0, strpos($o, '
  • ')); - $e = substr($o, strpos($o, '
  • ')); - $o = $b . $e; - } - - return '' . $o . ''; -} diff --git a/index.php b/index.php index 8b0bd47251..6ab405c632 100644 --- a/index.php +++ b/index.php @@ -23,11 +23,9 @@ use Friendica\Module\Login; require_once 'boot.php'; -$a = new App(__DIR__); - // We assume that the index.php is called by a frontend process // The value is set to "true" by default in boot.php -$a->backend = false; +$a = new App(__DIR__, false); /** * Try to open the database; @@ -36,7 +34,7 @@ $a->backend = false; require_once "include/dba.php"; // Missing DB connection: ERROR -if ($a->mode & App::MODE_LOCALCONFIGPRESENT && !($a->mode & App::MODE_DBAVAILABLE)) { +if ($a->getMode()->has(App\Mode::LOCALCONFIGPRESENT) && !$a->getMode()->has(App\Mode::DBAVAILABLE)) { System::httpExit(500, ['title' => 'Error 500 - Internal Server Error', 'description' => 'Apologies but the website is unavailable at the moment.']); } @@ -48,8 +46,12 @@ if ($a->isMaxProcessesReached() || $a->isMaxLoadReached()) { System::httpExit(503, ['title' => 'Error 503 - Service Temporarily Unavailable', 'description' => 'System is currently overloaded. Please try again later.']); } -if (!$a->isInstallMode()) { - if (Config::get('system', 'force_ssl') && ($a->get_scheme() == "http") +if (strstr($a->query_string, '.well-known/host-meta') && ($a->query_string != '.well-known/host-meta')) { + System::httpExit(404); +} + +if (!$a->getMode()->isInstall()) { + if (Config::get('system', 'force_ssl') && ($a->getScheme() == "http") && (intval(Config::get('system', 'ssl_policy')) == SSL_POLICY_FULL) && (substr(System::baseUrl(), 0, 8) == "https://") && ($_SERVER['REQUEST_METHOD'] == 'GET')) { @@ -78,10 +80,10 @@ L10n::loadTranslationTable($lang); */ // Exclude the backend processes from the session management -if (!$a->is_backend()) { +if (!$a->isBackend()) { $stamp1 = microtime(true); session_start(); - $a->save_timestamp($stamp1, "parser"); + $a->saveTimestamp($stamp1, "parser"); } else { $_SESSION = []; Worker::executeIfIdle(); @@ -91,7 +93,7 @@ if (!$a->is_backend()) { * Language was set earlier, but we can over-ride it in the session. * We have to do it here because the session was just now opened. */ -if (x($_SESSION, 'authenticated') && !x($_SESSION, 'language')) { +if (!empty($_SESSION['authenticated']) && empty($_SESSION['language'])) { $_SESSION['language'] = $lang; // we haven't loaded user data yet, but we need user language if (!empty($_SESSION['uid'])) { @@ -102,12 +104,12 @@ if (x($_SESSION, 'authenticated') && !x($_SESSION, 'language')) { } } -if (x($_SESSION, 'language') && ($_SESSION['language'] !== $lang)) { +if (!empty($_SESSION['language']) && $_SESSION['language'] !== $lang) { $lang = $_SESSION['language']; L10n::loadTranslationTable($lang); } -if (!empty($_GET['zrl']) && $a->mode == App::MODE_NORMAL) { +if (!empty($_GET['zrl']) && $a->getMode()->isNormal()) { $a->query_string = Profile::stripZrls($a->query_string); if (!local_user()) { // Only continue when the given profile link seems valid @@ -125,12 +127,12 @@ if (!empty($_GET['zrl']) && $a->mode == App::MODE_NORMAL) { logger("Invalid ZRL parameter " . $_GET['zrl'], LOGGER_DEBUG); header('HTTP/1.1 403 Forbidden'); echo "

    403 Forbidden

    "; - killme(); + exit(); } } } -if ((x($_GET,'owt')) && $a->mode == App::MODE_NORMAL) { +if (!empty($_GET['owt']) && $a->getMode()->isNormal()) { $token = $_GET['owt']; $a->query_string = Profile::stripQueryParam($a->query_string, 'owt'); Profile::openWebAuthInit($token); @@ -149,14 +151,10 @@ if ((x($_GET,'owt')) && $a->mode == App::MODE_NORMAL) { Login::sessionAuth(); -if (! x($_SESSION, 'authenticated')) { +if (empty($_SESSION['authenticated'])) { header('X-Account-Management-Status: none'); } -/* set up page['htmlhead'] and page['end'] for the modules to use */ -$a->page['htmlhead'] = ''; -$a->page['end'] = ''; - $_SESSION['sysmsg'] = defaults($_SESSION, 'sysmsg' , []); $_SESSION['sysmsg_info'] = defaults($_SESSION, 'sysmsg_info' , []); $_SESSION['last_updated'] = defaults($_SESSION, 'last_updated', []); @@ -169,14 +167,14 @@ $_SESSION['last_updated'] = defaults($_SESSION, 'last_updated', []); // in install mode, any url loads install module // but we need "view" module for stylesheet -if ($a->isInstallMode() && $a->module!="view") { +if ($a->getMode()->isInstall() && $a->module != 'view') { $a->module = 'install'; -} elseif (!($a->mode & App::MODE_MAINTENANCEDISABLED) && $a->module != "view") { +} elseif (!$a->getMode()->has(App\Mode::MAINTENANCEDISABLED) && $a->module != 'view') { $a->module = 'maintenance'; } else { check_url($a); check_db(false); - check_addons($a); + Addon::check(); } Nav::setSelected('nothing'); @@ -295,11 +293,11 @@ if (strlen($a->module)) { if (! $a->module_loaded) { // Stupid browser tried to pre-fetch our Javascript img template. Don't log the event or return anything - just quietly exit. - if ((x($_SERVER, 'QUERY_STRING')) && preg_match('/{[0-9]}/', $_SERVER['QUERY_STRING']) !== 0) { + if (!empty($_SERVER['QUERY_STRING']) && preg_match('/{[0-9]}/', $_SERVER['QUERY_STRING']) !== 0) { killme(); } - if ((x($_SERVER, 'QUERY_STRING')) && ($_SERVER['QUERY_STRING'] === 'q=internal_error.html') && isset($dreamhost_error_hack)) { + if (!empty($_SERVER['QUERY_STRING']) && ($_SERVER['QUERY_STRING'] === 'q=internal_error.html') && isset($dreamhost_error_hack)) { logger('index.php: dreamhost_error_hack invoked. Original URI =' . $_SERVER['REQUEST_URI']); goaway(System::baseUrl() . $_SERVER['REQUEST_URI']); } @@ -307,11 +305,9 @@ if (strlen($a->module)) { logger('index.php: page not found: ' . $_SERVER['REQUEST_URI'] . ' ADDRESS: ' . $_SERVER['REMOTE_ADDR'] . ' QUERY: ' . $_SERVER['QUERY_STRING'], LOGGER_DEBUG); header($_SERVER["SERVER_PROTOCOL"] . ' 404 ' . L10n::t('Not Found')); $tpl = get_markup_template("404.tpl"); - $a->page['content'] = replace_macros( - $tpl, - [ - '$message' => L10n::t('Page not found.')] - ); + $a->page['content'] = replace_macros($tpl, [ + '$message' => L10n::t('Page not found.') + ]); } } @@ -326,11 +322,7 @@ if (file_exists($theme_info_file)) { /* initialise content region */ -if (! x($a->page, 'content')) { - $a->page['content'] = ''; -} - -if ($a->mode == App::MODE_NORMAL) { +if ($a->getMode()->isNormal()) { Addon::callHooks('page_content_top', $a->page['content']); } @@ -342,15 +334,21 @@ if ($a->module_loaded) { $a->page['page_title'] = $a->module; $placeholder = ''; + Addon::callHooks($a->module . '_mod_init', $placeholder); + if ($a->module_class) { - Addon::callHooks($a->module . '_mod_init', $placeholder); call_user_func([$a->module_class, 'init']); } else if (function_exists($a->module . '_init')) { - Addon::callHooks($a->module . '_mod_init', $placeholder); $func = $a->module . '_init'; $func($a); } + // "rawContent" is especially meant for technical endpoints. + // This endpoint doesn't need any theme initialization or other comparable stuff. + if (!$a->error && $a->module_class) { + call_user_func([$a->module_class, 'rawContent']); + } + if (function_exists(str_replace('-', '_', $a->getCurrentTheme()) . '_init')) { $func = str_replace('-', '_', $a->getCurrentTheme()) . '_init'; $func($a); @@ -405,24 +403,13 @@ if ($a->module_loaded) { * theme choices made by the modules can take effect. */ -$a->init_pagehead(); +$a->initHead(); /* * Build the page ending -- this is stuff that goes right before * the closing tag */ -$a->init_page_end(); - -// If you're just visiting, let javascript take you home -if (x($_SESSION, 'visitor_home')) { - $homebase = $_SESSION['visitor_home']; -} elseif (local_user()) { - $homebase = 'profile/' . $a->user['nickname']; -} - -if (isset($homebase)) { - $a->page['content'] .= ''; -} +$a->initFooter(); /* * now that we've been through the module content, see if the page reported @@ -444,36 +431,9 @@ if ($a->module != 'install' && $a->module != 'maintenance') { Nav::build($a); } -/* - * Add a "toggle mobile" link if we're using a mobile device - */ -if ($a->is_mobile || $a->is_tablet) { - if (isset($_SESSION['show-mobile']) && !$_SESSION['show-mobile']) { - $link = 'toggle_mobile?address=' . curPageURL(); - } else { - $link = 'toggle_mobile?off=1&address=' . curPageURL(); - } - $a->page['footer'] = replace_macros( - get_markup_template("toggle_mobile_footer.tpl"), - [ - '$toggle_link' => $link, - '$toggle_text' => L10n::t('toggle mobile')] - ); -} - /** * Build the page - now that we have all the components */ - -if (!$a->theme['stylesheet']) { - $stylesheet = $a->getCurrentThemeStylesheetPath(); -} else { - $stylesheet = $a->theme['stylesheet']; -} - -$a->page['htmlhead'] = str_replace('{{$stylesheet}}', $stylesheet, $a->page['htmlhead']); -//$a->page['htmlhead'] = replace_macros($a->page['htmlhead'], array('$stylesheet' => $stylesheet)); - if (isset($_GET["mode"]) && (($_GET["mode"] == "raw") || ($_GET["mode"] == "minimal"))) { $doc = new DOMDocument(); @@ -502,7 +462,7 @@ if (isset($_GET["mode"]) && ($_GET["mode"] == "raw")) { echo substr($target->saveHTML(), 6, -8); - killme(); + exit(); } $page = $a->page; @@ -540,5 +500,3 @@ if (empty($template)) { /// @TODO Looks unsafe (remote-inclusion), is maybe not but Theme::getPathForFile() uses file_exists() but does not escape anything require_once $template; - -killme(); diff --git a/mod/acctlink.php b/mod/acctlink.php deleted file mode 100644 index fb8cfd400f..0000000000 --- a/mod/acctlink.php +++ /dev/null @@ -1,16 +0,0 @@ -= `failure_update` - AND `network` IN ('%s', '%s') $sql_extra2", + AND `network` IN ('%s', '%s', '%s') $sql_extra2", intval(local_user()), + DBA::escape(Protocol::ACTIVITYPUB), DBA::escape(Protocol::DFRN), DBA::escape(Protocol::DIASPORA) ); @@ -169,10 +170,11 @@ function acl_content(App $a) } elseif ($type == 'm') { $r = q("SELECT `id`, `name`, `nick`, `micro`, `network`, `url`, `attag`, `addr` FROM `contact` WHERE `uid` = %d AND NOT `self` AND NOT `blocked` AND NOT `pending` AND NOT `archive` - AND `success_update` >= `failure_update` AND `network` IN ('%s', '%s') + AND `success_update` >= `failure_update` AND `network` IN ('%s', '%s', '%s') $sql_extra2 ORDER BY `name` ASC ", intval(local_user()), + DBA::escape(Protocol::ACTIVITYPUB), DBA::escape(Protocol::DFRN), DBA::escape(Protocol::DIASPORA) ); diff --git a/mod/admin.php b/mod/admin.php index d4fcc533f7..b0fb6d4726 100644 --- a/mod/admin.php +++ b/mod/admin.php @@ -18,13 +18,14 @@ use Friendica\Database\DBA; use Friendica\Database\DBStructure; use Friendica\Model\Contact; use Friendica\Model\Item; +use Friendica\Model\Register; use Friendica\Model\User; use Friendica\Module\Login; use Friendica\Module\Tos; use Friendica\Util\Arrays; use Friendica\Util\DateTimeFormat; -use Friendica\Util\Temporal; use Friendica\Util\Network; +use Friendica\Util\Temporal; require_once 'include/enotify.php'; require_once 'include/text.php'; @@ -33,11 +34,11 @@ require_once 'include/items.php'; /** * @brief Process send data from the admin panels subpages * - * This function acts as relais for processing the data send from the subpages + * This function acts as relay for processing the data send from the subpages * of the admin panel. Depending on the 1st parameter of the url (argv[1]) * specialized functions are called to process the data from the subpages. * - * The function itself does not return anything, but the subsequencely function + * The function itself does not return anything, but the subsequently function * return the HTML for the pages of the admin panel. * * @param App $a @@ -77,7 +78,7 @@ function admin_post(App $a) break; case 'themes': if ($a->argc < 2) { - if (is_ajax()) { + if ($a->isAjax()) { return; } goaway('admin/'); @@ -107,7 +108,7 @@ function admin_post(App $a) } info(L10n::t('Theme settings updated.')); - if (is_ajax()) { + if ($a->isAjax()) { return; } $return_path = 'admin/themes/' . $theme; @@ -286,7 +287,7 @@ function admin_content(App $a) $o = admin_page_summary($a); } - if (is_ajax()) { + if ($a->isAjax()) { echo $o; killme(); return ''; @@ -475,8 +476,8 @@ function admin_page_contactblock(App $a) $total = DBA::count('contact', $condition); - $a->set_pager_total($total); - $a->set_pager_itemspage(30); + $a->setPagerTotal($total); + $a->setPagerItemsPage(30); $statement = DBA::select('contact', [], $condition, ['limit' => [$a->pager['start'], $a->pager['itemspage']]]); @@ -866,15 +867,15 @@ function admin_page_summary(App $a) // Legacy config file warning if (file_exists('.htconfig.php')) { $showwarning = true; - $warningtext[] = L10n::t('Friendica\'s configuration now is stored in config/local.ini.php, please copy config/local-sample.ini.php and move your config from .htconfig.php. See the Config help page for help with the transition.', $a->get_baseurl() . '/help/Config'); + $warningtext[] = L10n::t('Friendica\'s configuration now is stored in config/local.ini.php, please copy config/local-sample.ini.php and move your config from .htconfig.php. See the Config help page for help with the transition.', $a->getBaseURL() . '/help/Config'); } // Check server vitality if (!admin_page_server_vital()) { $showwarning = true; - $well_known = $a->get_baseurl() . '/.well-known/host-meta'; + $well_known = $a->getBaseURL() . '/.well-known/host-meta'; $warningtext[] = L10n::t('%s is not reachable on your system. This is a severe configuration issue that prevents server to server communication. See the installation page for help.', - $well_known, $well_known, $a->get_baseurl() . '/help/Install'); + $well_known, $well_known, $a->getBaseURL() . '/help/Install'); } $r = q("SELECT `page-flags`, COUNT(`uid`) AS `count` FROM `user` GROUP BY `page-flags`"); @@ -895,8 +896,7 @@ function admin_page_summary(App $a) logger('accounts: ' . print_r($accounts, true), LOGGER_DATA); - $r = q("SELECT COUNT(`id`) AS `count` FROM `register`"); - $pending = $r[0]['count']; + $pending = Register::getPendingCount(); $r = q("SELECT COUNT(*) AS `total` FROM `queue` WHERE 1"); $queue = (($r) ? $r[0]['total'] : 0); @@ -909,6 +909,15 @@ function admin_page_summary(App $a) $queues = ['label' => L10n::t('Message queues'), 'queue' => $queue, 'workerq' => $workerqueue]; + $r = q("SHOW variables LIKE 'max_allowed_packet'"); + $max_allowed_packet = (($r) ? $r[0]['Value'] : 0); + + $server_settings = ['label' => L10n::t('Server Settings'), + 'php' => ['upload_max_filesize' => ini_get('upload_max_filesize'), + 'post_max_size' => ini_get('post_max_size'), + 'memory_limit' => ini_get('memory_limit')], + 'mysql' => ['max_allowed_packet' => $max_allowed_packet]]; + $t = get_markup_template('admin/summary.tpl'); return replace_macros($t, [ '$title' => L10n::t('Administration'), @@ -923,6 +932,7 @@ function admin_page_summary(App $a) '$codename' => FRIENDICA_CODENAME, '$build' => Config::get('system', 'build'), '$addons' => [L10n::t('Active addons'), $a->addons], + '$serversettings' => $server_settings, '$showwarning' => $showwarning, '$warningtext' => $warningtext ]); @@ -1002,7 +1012,7 @@ function admin_page_site_post(App $a) // update config Config::set('system', 'hostname', parse_url($new_url, PHP_URL_HOST)); Config::set('system', 'url', $new_url); - $a->set_baseurl($new_url); + $a->setBaseURL($new_url); // send relocate $users = q("SELECT `uid` FROM `user` WHERE `account_removed` = 0 AND `account_expired` = 0"); @@ -1114,7 +1124,7 @@ function admin_page_site_post(App $a) Worker::add(PRIORITY_LOW, 'Directory'); } - if ($a->get_path() != "") { + if ($a->getURLPath() != "") { $diaspora_enabled = false; } if ($ssl_policy != intval(Config::get('system', 'ssl_policy'))) { @@ -1251,7 +1261,7 @@ function admin_page_site_post(App $a) Config::set('system', 'dbclean-expire-unclaimed', $dbclean_unclaimed); if ($itemcache != '') { - $itemcache = App::realpath($itemcache); + $itemcache = App::getRealPath($itemcache); } Config::set('system', 'itemcache', $itemcache); @@ -1259,13 +1269,13 @@ function admin_page_site_post(App $a) Config::set('system', 'max_comments', $max_comments); if ($temppath != '') { - $temppath = App::realpath($temppath); + $temppath = App::getRealPath($temppath); } Config::set('system', 'temppath', $temppath); if ($basepath != '') { - $basepath = App::realpath($basepath); + $basepath = App::getRealPath($basepath); } Config::set('system', 'basepath', $basepath); @@ -1409,9 +1419,9 @@ function admin_page_site(App $a) ]; if (empty(Config::get('config', 'hostname'))) { - Config::set('config', 'hostname', $a->get_hostname()); + Config::set('config', 'hostname', $a->getHostName()); } - $diaspora_able = ($a->get_path() == ""); + $diaspora_able = ($a->getURLPath() == ""); $optimize_max_tablesize = Config::get('system', 'optimize_max_tablesize', -1); @@ -1478,7 +1488,7 @@ function admin_page_site(App $a) '$community_page_style' => ['community_page_style', L10n::t("Community pages for visitors"), Config::get('system','community_page_style'), L10n::t("Which community pages should be available for visitors. Local users always see both pages."), $community_page_style_choices], '$max_author_posts_community_page' => ['max_author_posts_community_page', L10n::t("Posts per user on community page"), Config::get('system','max_author_posts_community_page'), L10n::t("The maximum number of posts per user on the community page. \x28Not valid for 'Global Community'\x29")], '$ostatus_disabled' => ['ostatus_disabled', L10n::t("Enable OStatus support"), !Config::get('system','ostatus_disabled'), L10n::t("Provide built-in OStatus \x28StatusNet, GNU Social etc.\x29 compatibility. All communications in OStatus are public, so privacy warnings will be occasionally displayed.")], - '$ostatus_full_threads' => ['ostatus_full_threads', L10n::t("Only import OStatus threads from our contacts"), Config::get('system','ostatus_full_threads'), L10n::t("Normally we import every content from our OStatus contacts. With this option we only store threads that are started by a contact that is known on our system.")], + '$ostatus_full_threads' => ['ostatus_full_threads', L10n::t("Only import OStatus/ActivityPub threads from our contacts"), Config::get('system','ostatus_full_threads'), L10n::t("Normally we import every content from our OStatus and ActivityPub contacts. With this option we only store threads that are started by a contact that is known on our system.")], '$ostatus_not_able' => L10n::t("OStatus support can only be enabled if threading is enabled."), '$diaspora_able' => $diaspora_able, '$diaspora_not_able' => L10n::t("Diaspora support can't be enabled because Friendica was installed into a sub directory."), @@ -1782,17 +1792,13 @@ function admin_page_users(App $a) } /* get pending */ - $pending = q("SELECT `register`.*, `contact`.`name`, `user`.`email` - FROM `register` - INNER JOIN `contact` ON `register`.`uid` = `contact`.`uid` - INNER JOIN `user` ON `register`.`uid` = `user`.`uid`;"); - + $pending = Register::getPending(); /* get users */ $total = q("SELECT COUNT(*) AS `total` FROM `user` WHERE 1"); if (count($total)) { - $a->set_pager_total($total[0]['total']); - $a->set_pager_itemspage(100); + $a->setPagerTotal($total[0]['total']); + $a->setPagerItemsPage(100); } /* ordering */ @@ -1912,7 +1918,7 @@ function admin_page_users(App $a) '$h_users' => L10n::t('Users'), '$h_newuser' => L10n::t('New User'), - '$th_deleted' => [L10n::t('Name'), L10n::t('Email'), L10n::t('Register date'), L10n::t('Last login'), L10n::t('Last item'), L10n::t('Deleted since')], + '$th_deleted' => [L10n::t('Name'), L10n::t('Email'), L10n::t('Register date'), L10n::t('Last login'), L10n::t('Last item'), L10n::t('Delete in')], '$th_users' => $th_users, '$order_users' => $order, '$order_direction_users' => $order_direction, @@ -2526,7 +2532,7 @@ function admin_page_features_post(App $a) */ function admin_page_features(App $a) { - if ((argc() > 1) && (argv(1) === 'features')) { + if (($a->argc > 1) && ($a->getArgumentValue(1) === 'features')) { $arr = []; $features = Feature::get(false); @@ -2557,6 +2563,5 @@ function admin_page_features(App $a) function admin_page_server_vital() { // Fetch the host-meta to check if this really is a vital server - $serverret = Network::curl(System::baseUrl() . '/.well-known/host-meta'); - return $serverret["success"]; + return Network::curl(System::baseUrl() . '/.well-known/host-meta')->isSuccess(); } diff --git a/mod/allfriends.php b/mod/allfriends.php index 7623a9cd06..cee067e97a 100644 --- a/mod/allfriends.php +++ b/mod/allfriends.php @@ -8,13 +8,12 @@ use Friendica\Content\ContactSelector; use Friendica\Core\L10n; use Friendica\Core\System; use Friendica\Database\DBA; -use Friendica\Model\Contact; -use Friendica\Model\GContact; -use Friendica\Model\Profile; +use Friendica\Model; +use Friendica\Module; use Friendica\Util\Proxy as ProxyUtils; + require_once 'include/dba.php'; -require_once 'mod/contacts.php'; function allfriends_content(App $a) { @@ -42,13 +41,13 @@ function allfriends_content(App $a) } $a->page['aside'] = ""; - Profile::load($a, "", 0, Contact::getDetailsByURL($contact["url"])); + Model\Profile::load($a, "", 0, Model\Contact::getDetailsByURL($contact["url"])); - $total = GContact::countAllFriends(local_user(), $cid); + $total = Model\GContact::countAllFriends(local_user(), $cid); - $a->set_pager_total($total); + $a->setPagerTotal($total); - $r = GContact::allFriends(local_user(), $cid, $a->pager['start'], $a->pager['itemspage']); + $r = Model\GContact::allFriends(local_user(), $cid, $a->pager['start'], $a->pager['itemspage']); if (!DBA::isResult($r)) { $o .= L10n::t('No friends to display.'); return $o; @@ -59,7 +58,7 @@ function allfriends_content(App $a) $entries = []; foreach ($r as $rr) { //get further details of the contact - $contact_details = Contact::getDetailsByURL($rr['url'], $uid, $rr); + $contact_details = Model\Contact::getDetailsByURL($rr['url'], $uid, $rr); $photo_menu = ''; @@ -68,11 +67,11 @@ function allfriends_content(App $a) // If the contact is not common to the user, Connect/Follow' will be added to the photo menu if ($rr['cid']) { $rr['id'] = $rr['cid']; - $photo_menu = Contact::photoMenu($rr); + $photo_menu = Model\Contact::photoMenu($rr); } else { $connlnk = System::baseUrl() . '/follow/?url=' . $rr['url']; $photo_menu = [ - 'profile' => [L10n::t("View Profile"), Contact::magicLink($rr['url'])], + 'profile' => [L10n::t("View Profile"), Model\Contact::magicLink($rr['url'])], 'follow' => [L10n::t("Connect/Follow"), $connlnk] ]; } @@ -86,7 +85,7 @@ function allfriends_content(App $a) 'details' => $contact_details['location'], 'tags' => $contact_details['keywords'], 'about' => $contact_details['about'], - 'account_type' => Contact::getAccountType($contact_details), + 'account_type' => Model\Contact::getAccountType($contact_details), 'network' => ContactSelector::networkToName($contact_details['network'], $contact_details['url']), 'photo_menu' => $photo_menu, 'conntxt' => L10n::t('Connect'), @@ -96,7 +95,7 @@ function allfriends_content(App $a) $entries[] = $entry; } - $tab_str = contacts_tab($a, $contact, 4); + $tab_str = Module\Contact::getTabsHTML($a, $contact, 4); $tpl = get_markup_template('viewcontact_template.tpl'); diff --git a/mod/babel.php b/mod/babel.php index 3352366bd5..65287b9f2b 100644 --- a/mod/babel.php +++ b/mod/babel.php @@ -6,9 +6,11 @@ use Friendica\Content\Text; use Friendica\Core\L10n; -function visible_lf($s) +function visible_whitespace($s) { - return str_replace("\n", '
    ', $s); + $s = str_replace(' ', ' ', $s); + + return str_replace(["\r\n", "\n", "\r"], '
    ', $s); } function babel_content() @@ -20,19 +22,19 @@ function babel_content() $bbcode = trim($_REQUEST['text']); $results[] = [ 'title' => L10n::t('Source input'), - 'content' => visible_lf($bbcode) + 'content' => visible_whitespace($bbcode) ]; $plain = Text\BBCode::toPlaintext($bbcode, false); $results[] = [ 'title' => L10n::t('BBCode::toPlaintext'), - 'content' => visible_lf($plain) + 'content' => visible_whitespace($plain) ]; $html = Text\BBCode::convert($bbcode); $results[] = [ - 'title' => L10n::t("BBCode::convert \x28raw HTML\x29"), - 'content' => htmlspecialchars($html) + 'title' => L10n::t('BBCode::convert (raw HTML)'), + 'content' => visible_whitespace(htmlspecialchars($html)) ]; $results[] = [ @@ -43,13 +45,13 @@ function babel_content() $bbcode2 = Text\HTML::toBBCode($html); $results[] = [ 'title' => L10n::t('BBCode::convert => HTML::toBBCode'), - 'content' => visible_lf($bbcode2) + 'content' => visible_whitespace($bbcode2) ]; $markdown = Text\BBCode::toMarkdown($bbcode); $results[] = [ 'title' => L10n::t('BBCode::toMarkdown'), - 'content' => visible_lf($markdown) + 'content' => visible_whitespace($markdown) ]; $html2 = Text\Markdown::convert($markdown); @@ -61,22 +63,33 @@ function babel_content() $bbcode3 = Text\Markdown::toBBCode($markdown); $results[] = [ 'title' => L10n::t('BBCode::toMarkdown => Markdown::toBBCode'), - 'content' => visible_lf($bbcode3) + 'content' => visible_whitespace($bbcode3) ]; $bbcode4 = Text\HTML::toBBCode($html2); $results[] = [ 'title' => L10n::t('BBCode::toMarkdown => Markdown::convert => HTML::toBBCode'), - 'content' => visible_lf($bbcode4) + 'content' => visible_whitespace($bbcode4) ]; break; case 'markdown': $markdown = trim($_REQUEST['text']); $results[] = [ - 'title' => L10n::t('Source input \x28Diaspora format\x29'), + 'title' => L10n::t('Source input (Diaspora format)'), 'content' => '
    ' . $markdown . '
    ' ]; + $html = Text\Markdown::convert($markdown); + $results[] = [ + 'title' => L10n::t('Markdown::convert (raw HTML)'), + 'content' => htmlspecialchars($html) + ]; + + $results[] = [ + 'title' => L10n::t('Markdown::convert'), + 'content' => $html + ]; + $bbcode = Text\Markdown::toBBCode($markdown); $results[] = [ 'title' => L10n::t('Markdown::toBBCode'), @@ -86,7 +99,7 @@ function babel_content() case 'html' : $html = trim($_REQUEST['text']); $results[] = [ - 'title' => L10n::t("Raw HTML input"), + 'title' => L10n::t('Raw HTML input'), 'content' => htmlspecialchars($html) ]; @@ -98,7 +111,24 @@ function babel_content() $bbcode = Text\HTML::toBBCode($html); $results[] = [ 'title' => L10n::t('HTML::toBBCode'), - 'content' => visible_lf($bbcode) + 'content' => visible_whitespace($bbcode) + ]; + + $html2 = Text\BBCode::convert($bbcode); + $results[] = [ + 'title' => L10n::t('HTML::toBBCode => BBCode::convert'), + 'content' => $html2 + ]; + + $results[] = [ + 'title' => L10n::t('HTML::toBBCode => BBCode::convert (raw HTML)'), + 'content' => htmlspecialchars($html2) + ]; + + $markdown = Text\HTML::toMarkdown($html); + $results[] = [ + 'title' => L10n::t('HTML::toMarkdown'), + 'content' => visible_whitespace($markdown) ]; $text = Text\HTML::toPlaintext($html); @@ -111,7 +141,7 @@ function babel_content() $tpl = get_markup_template('babel.tpl'); $o = replace_macros($tpl, [ - '$text' => ['text', L10n::t('Source text'), defaults($_REQUEST, 'text', ''), ''], + '$text' => ['text', L10n::t('Source text'), htmlentities(defaults($_REQUEST, 'text', '')), ''], '$type_bbcode' => ['type', L10n::t('BBCode'), 'bbcode', '', defaults($_REQUEST, 'type', 'bbcode') == 'bbcode'], '$type_markdown' => ['type', L10n::t('Markdown'), 'markdown', '', defaults($_REQUEST, 'type', 'bbcode') == 'markdown'], '$type_html' => ['type', L10n::t('HTML'), 'html', '', defaults($_REQUEST, 'type', 'bbcode') == 'html'], diff --git a/mod/bookmarklet.php b/mod/bookmarklet.php index 21b2039c58..e1ae9aa64c 100644 --- a/mod/bookmarklet.php +++ b/mod/bookmarklet.php @@ -30,6 +30,10 @@ function bookmarklet_content(App $a) $page = normalise_link(System::baseUrl() . "/bookmarklet"); if (!strstr($referer, $page)) { + if (empty($_REQUEST["url"])) { + System::httpExit(400, ["title" => L10n::t('Bad Request')]); + } + $content = add_page_info($_REQUEST["url"]); $x = [ diff --git a/mod/cal.php b/mod/cal.php index bdedaaacfa..ae1060c47a 100644 --- a/mod/cal.php +++ b/mod/cal.php @@ -94,11 +94,6 @@ function cal_content(App $a) '$i18n' => $i18n, ]); - $etpl = get_markup_template('event_end.tpl'); - $a->page['end'] .= replace_macros($etpl, [ - '$baseurl' => System::baseUrl(), - ]); - $mode = 'view'; $y = 0; $m = 0; diff --git a/mod/common.php b/mod/common.php index afe78ce460..0b51f20d73 100644 --- a/mod/common.php +++ b/mod/common.php @@ -7,13 +7,12 @@ use Friendica\App; use Friendica\Content\ContactSelector; use Friendica\Core\L10n; use Friendica\Database\DBA; -use Friendica\Model\Contact; -use Friendica\Model\GContact; -use Friendica\Model\Profile; +use Friendica\Model; +use Friendica\Module; use Friendica\Util\Proxy as ProxyUtils; + require_once 'include/dba.php'; -require_once 'mod/contacts.php'; function common_content(App $a) { @@ -42,16 +41,16 @@ function common_content(App $a) if (DBA::isResult($contact)) { $a->page['aside'] = ""; - Profile::load($a, "", 0, Contact::getDetailsByURL($contact["url"])); + Model\Profile::load($a, "", 0, Model\Contact::getDetailsByURL($contact["url"])); } } else { $contact = DBA::selectFirst('contact', ['name', 'url', 'photo', 'uid', 'id'], ['self' => true, 'uid' => $uid]); if (DBA::isResult($contact)) { $vcard_widget = replace_macros(get_markup_template("vcard-widget.tpl"), [ - '$name' => htmlentities($contact['name']), + '$name' => htmlentities($contact['name']), '$photo' => $contact['photo'], - 'url' => 'contacts/' . $cid + 'url' => 'contact/' . $cid ]); if (!x($a->page, 'aside')) { @@ -65,12 +64,12 @@ function common_content(App $a) return; } - if (!$cid && Profile::getMyURL()) { - $contact = DBA::selectFirst('contact', ['id'], ['nurl' => normalise_link(Profile::getMyURL()), 'uid' => $uid]); + if (!$cid && Model\Profile::getMyURL()) { + $contact = DBA::selectFirst('contact', ['id'], ['nurl' => normalise_link(Model\Profile::getMyURL()), 'uid' => $uid]); if (DBA::isResult($contact)) { $cid = $contact['id']; } else { - $gcontact = DBA::selectFirst('gcontact', ['id'], ['nurl' => normalise_link(Profile::getMyURL())]); + $gcontact = DBA::selectFirst('gcontact', ['id'], ['nurl' => normalise_link(Model\Profile::getMyURL())]); if (DBA::isResult($gcontact)) { $zcid = $gcontact['id']; } @@ -82,22 +81,22 @@ function common_content(App $a) } if ($cid) { - $t = GContact::countCommonFriends($uid, $cid); + $t = Model\GContact::countCommonFriends($uid, $cid); } else { - $t = GContact::countCommonFriendsZcid($uid, $zcid); + $t = Model\GContact::countCommonFriendsZcid($uid, $zcid); } if ($t > 0) { - $a->set_pager_total($t); + $a->setPagerTotal($t); } else { notice(L10n::t('No contacts in common.') . EOL); return $o; } if ($cid) { - $r = GContact::commonFriends($uid, $cid, $a->pager['start'], $a->pager['itemspage']); + $r = Model\GContact::commonFriends($uid, $cid, $a->pager['start'], $a->pager['itemspage']); } else { - $r = GContact::commonFriendsZcid($uid, $zcid, $a->pager['start'], $a->pager['itemspage']); + $r = Model\GContact::commonFriendsZcid($uid, $zcid, $a->pager['start'], $a->pager['itemspage']); } if (!DBA::isResult($r)) { @@ -109,13 +108,13 @@ function common_content(App $a) $entries = []; foreach ($r as $rr) { //get further details of the contact - $contact_details = Contact::getDetailsByURL($rr['url'], $uid); + $contact_details = Model\Contact::getDetailsByURL($rr['url'], $uid); // $rr['id'] is needed to use contact_photo_menu() /// @TODO Adding '/" here avoids E_NOTICE on missing constants $rr['id'] = $rr['cid']; - $photo_menu = Contact::photoMenu($rr); + $photo_menu = Model\Contact::photoMenu($rr); $entry = [ 'url' => $rr['url'], @@ -126,7 +125,7 @@ function common_content(App $a) 'details' => $contact_details['location'], 'tags' => $contact_details['keywords'], 'about' => $contact_details['about'], - 'account_type' => Contact::getAccountType($contact_details), + 'account_type' => Model\Contact::getAccountType($contact_details), 'network' => ContactSelector::networkToName($contact_details['network'], $contact_details['url']), 'photo_menu' => $photo_menu, 'id' => ++$id, @@ -137,7 +136,7 @@ function common_content(App $a) $title = ''; $tab_str = ''; if ($cmd === 'loc' && $cid && local_user() == $uid) { - $tab_str = contacts_tab($a, $contact, 4); + $tab_str = Module\Contact::getTabsHTML($a, $contact, 4); } else { $title = L10n::t('Common Friends'); } diff --git a/mod/community.php b/mod/community.php index 685eda6da0..4b2169fd06 100644 --- a/mod/community.php +++ b/mod/community.php @@ -154,7 +154,7 @@ function community_content(App $a, $update = 0) $itemspage_network = $a->force_max_items; } - $a->set_pager_itemspage($itemspage_network); + $a->setPagerItemsPage($itemspage_network); $r = community_getitems($a->pager['start'], $a->pager['itemspage'], $content, $accounttype); diff --git a/mod/contacts.php b/mod/contacts.php deleted file mode 100644 index 4e87697172..0000000000 --- a/mod/contacts.php +++ /dev/null @@ -1,1139 +0,0 @@ -page, 'aside')) { - $a->page['aside'] = ''; - } - - $contact_id = null; - $contact = null; - if ((($a->argc == 2) && intval($a->argv[1])) || (($a->argc == 3) && intval($a->argv[1]) && in_array($a->argv[2], ['posts', 'conversations']))) { - $contact_id = intval($a->argv[1]); - $contact = DBA::selectFirst('contact', [], ['id' => $contact_id, 'uid' => local_user()]); - - if (!DBA::isResult($contact)) { - $contact = DBA::selectFirst('contact', [], ['id' => $contact_id, 'uid' => 0]); - } - } - - if (DBA::isResult($contact)) { - if ($contact['self']) { - if (($a->argc == 3) && intval($a->argv[1]) && in_array($a->argv[2], ['posts', 'conversations'])) { - goaway('profile/' . $contact['nick']); - } else { - goaway('profile/' . $contact['nick'] . '?tab=profile'); - } - } - - $a->data['contact'] = $contact; - - if (($a->data['contact']['network'] != "") && ($a->data['contact']['network'] != Protocol::DFRN)) { - $networkname = format_network_name($a->data['contact']['network'], $a->data['contact']['url']); - } else { - $networkname = ''; - } - - /// @TODO Add nice spaces - $vcard_widget = replace_macros(get_markup_template("vcard-widget.tpl"), [ - '$name' => htmlentities($a->data['contact']['name']), - '$photo' => $a->data['contact']['photo'], - '$url' => Contact::MagicLink($a->data['contact']['url']), - '$addr' => (($a->data['contact']['addr'] != "") ? ($a->data['contact']['addr']) : ""), - '$network_name' => $networkname, - '$network' => L10n::t('Network:'), - '$account_type' => Contact::getAccountType($a->data['contact']) - ]); - - $findpeople_widget = ''; - $follow_widget = ''; - $networks_widget = ''; - } else { - $vcard_widget = ''; - $networks_widget = Widget::networks('contacts', $nets); - if (isset($_GET['add'])) { - $follow_widget = Widget::follow($_GET['add']); - } else { - $follow_widget = Widget::follow(); - } - - $findpeople_widget = Widget::findPeople(); - } - - if ($contact['uid'] != 0) { - $groups_widget = Group::sidebarWidget('contacts', 'group', 'full', 'everyone', $contact_id); - } else { - $groups_widget = null; - } - - $a->page['aside'] .= replace_macros(get_markup_template("contacts-widget-sidebar.tpl"), [ - '$vcard_widget' => $vcard_widget, - '$findpeople_widget' => $findpeople_widget, - '$follow_widget' => $follow_widget, - '$groups_widget' => $groups_widget, - '$networks_widget' => $networks_widget - ]); - - $base = System::baseUrl(); - $tpl = get_markup_template("contacts-head.tpl"); - $a->page['htmlhead'] .= replace_macros($tpl, [ - '$baseurl' => System::baseUrl(true), - '$base' => $base - ]); - - $tpl = get_markup_template("contacts-end.tpl"); - $a->page['end'] .= replace_macros($tpl, [ - '$baseurl' => System::baseUrl(true), - '$base' => $base - ]); -} - -function contacts_batch_actions(App $a) -{ - $contacts_id = $_POST['contact_batch']; - if (!is_array($contacts_id)) { - return; - } - - $orig_records = q("SELECT * FROM `contact` WHERE `id` IN (%s) AND `uid` = %d AND `self` = 0", - implode(",", $contacts_id), - intval(local_user()) - ); - - $count_actions = 0; - foreach ($orig_records as $orig_record) { - $contact_id = $orig_record['id']; - if (x($_POST, 'contacts_batch_update')) { - _contact_update($contact_id); - $count_actions++; - } - if (x($_POST, 'contacts_batch_block')) { - _contact_block($contact_id); - $count_actions++; - } - if (x($_POST, 'contacts_batch_ignore')) { - _contact_ignore($contact_id); - $count_actions++; - } - if (x($_POST, 'contacts_batch_archive')) { - $r = _contact_archive($contact_id, $orig_record); - if ($r) { - $count_actions++; - } - } - if (x($_POST, 'contacts_batch_drop')) { - _contact_drop($orig_record); - $count_actions++; - } - } - if ($count_actions > 0) { - info(L10n::tt("%d contact edited.", "%d contacts edited.", $count_actions)); - } - - if (x($_SESSION, 'return_url')) { - goaway('' . $_SESSION['return_url']); - } else { - goaway('contacts'); - } -} - -function contacts_post(App $a) -{ - if (!local_user()) { - return; - } - - if ($a->argv[1] === "batch") { - contacts_batch_actions($a); - return; - } - - $contact_id = intval($a->argv[1]); - if (!$contact_id) { - return; - } - - if (!DBA::exists('contact', ['id' => $contact_id, 'uid' => local_user()])) { - notice(L10n::t('Could not access contact record.') . EOL); - goaway('contacts'); - return; // NOTREACHED - } - - Addon::callHooks('contact_edit_post', $_POST); - - $profile_id = intval(defaults($_POST, 'profile-assign', 0)); - if ($profile_id) { - if (!DBA::exists('profile', ['id' => $profile_id, 'uid' => local_user()])) { - notice(L10n::t('Could not locate selected profile.') . EOL); - return; - } - } - - $hidden = intval($_POST['hidden']); - - $notify = intval($_POST['notify']); - - $fetch_further_information = intval(defaults($_POST, 'fetch_further_information', 0)); - - $ffi_keyword_blacklist = escape_tags(trim(defaults($_POST, 'ffi_keyword_blacklist', ''))); - - $priority = intval(defaults($_POST, 'poll', 0)); - if ($priority > 5 || $priority < 0) { - $priority = 0; - } - - $info = escape_tags(trim($_POST['info'])); - - $r = q("UPDATE `contact` SET `profile-id` = %d, `priority` = %d , `info` = '%s', - `hidden` = %d, `notify_new_posts` = %d, `fetch_further_information` = %d, - `ffi_keyword_blacklist` = '%s' WHERE `id` = %d AND `uid` = %d", - intval($profile_id), - intval($priority), - DBA::escape($info), - intval($hidden), - intval($notify), - intval($fetch_further_information), - DBA::escape($ffi_keyword_blacklist), - intval($contact_id), - intval(local_user()) - ); - if (DBA::isResult($r)) { - info(L10n::t('Contact updated.') . EOL); - } else { - notice(L10n::t('Failed to update contact record.') . EOL); - } - - $contact = DBA::selectFirst('contact', [], ['id' => $contact_id, 'uid' => local_user()]); - if (DBA::isResult($contact)) { - $a->data['contact'] = $contact; - } - - return; -} - -/* contact actions */ - -function _contact_update($contact_id) -{ - $contact = DBA::selectFirst('contact', ['uid', 'url', 'network'], ['id' => $contact_id, 'uid' => local_user()]); - if (!DBA::isResult($contact)) { - return; - } - - $uid = $contact["uid"]; - - if ($contact["network"] == Protocol::OSTATUS) { - $result = Contact::createFromProbe($uid, $contact["url"], false, $contact["network"]); - - if ($result['success']) { - q("UPDATE `contact` SET `subhub` = 1 WHERE `id` = %d", intval($contact_id)); - } - } else { - // pull feed and consume it, which should subscribe to the hub. - Worker::add(PRIORITY_HIGH, "OnePoll", $contact_id, "force"); - } -} - -function _contact_update_profile($contact_id) -{ - $contact = DBA::selectFirst('contact', ['uid', 'url', 'network'], ['id' => $contact_id, 'uid' => local_user()]); - if (!DBA::isResult($contact)) { - return; - } - - $uid = $contact["uid"]; - - $data = Probe::uri($contact["url"], "", 0, false); - - // "Feed" or "Unknown" is mostly a sign of communication problems - if ((in_array($data["network"], [Protocol::FEED, Protocol::PHANTOM])) && ($data["network"] != $contact["network"])) { - return; - } - - $updatefields = ["name", "nick", "url", "addr", "batch", "notify", "poll", "request", "confirm", - "poco", "network", "alias"]; - $update = []; - - if ($data["network"] == Protocol::OSTATUS) { - $result = Contact::createFromProbe($uid, $data["url"], false); - - if ($result['success']) { - $update["subhub"] = true; - } - } - - foreach ($updatefields AS $field) { - if (isset($data[$field]) && ($data[$field] != "")) { - $update[$field] = $data[$field]; - } - } - - $update["nurl"] = normalise_link($data["url"]); - - $query = ""; - - if (isset($data["priority"]) && ($data["priority"] != 0)) { - $query = "`priority` = " . intval($data["priority"]); - } - - foreach ($update AS $key => $value) { - if ($query != "") { - $query .= ", "; - } - - $query .= "`" . $key . "` = '" . DBA::escape($value) . "'"; - } - - if ($query == "") { - return; - } - - $r = q("UPDATE `contact` SET $query WHERE `id` = %d AND `uid` = %d", - intval($contact_id), - intval(local_user()) - ); - - // Update the entry in the contact table - Contact::updateAvatar($data['photo'], local_user(), $contact_id, true); - - // Update the entry in the gcontact table - GContact::updateFromProbe($data["url"]); -} - -function _contact_block($contact_id) -{ - $blocked = !Contact::isBlockedByUser($contact_id, local_user()); - Contact::setBlockedForUser($contact_id, local_user(), $blocked); -} - -function _contact_ignore($contact_id) -{ - $ignored = !Contact::isIgnoredByUser($contact_id, local_user()); - Contact::setIgnoredForUser($contact_id, local_user(), $ignored); -} - -function _contact_archive($contact_id, $orig_record) -{ - $archived = (($orig_record['archive']) ? 0 : 1); - $r = q("UPDATE `contact` SET `archive` = %d WHERE `id` = %d AND `uid` = %d", - intval($archived), - intval($contact_id), - intval(local_user()) - ); - return DBA::isResult($r); -} - -function _contact_drop($orig_record) -{ - $a = get_app(); - - $r = q("SELECT `contact`.*, `user`.* FROM `contact` INNER JOIN `user` ON `contact`.`uid` = `user`.`uid` - WHERE `user`.`uid` = %d AND `contact`.`self` LIMIT 1", - intval($a->user['uid']) - ); - if (!DBA::isResult($r)) { - return; - } - - Contact::terminateFriendship($r[0], $orig_record); - Contact::remove($orig_record['id']); -} - -function contacts_content(App $a, $update = 0) -{ - $sort_type = 0; - $o = ''; - Nav::setSelected('contacts'); - - if (!local_user()) { - notice(L10n::t('Permission denied.') . EOL); - return; - } - - if ($a->argc == 3) { - $contact_id = intval($a->argv[1]); - if (!$contact_id) { - return; - } - - $cmd = $a->argv[2]; - - $orig_record = DBA::selectFirst('contact', [], ['id' => $contact_id, 'uid' => [0, local_user()], 'self' => false]); - if (!DBA::isResult($orig_record)) { - notice(L10n::t('Could not access contact record.') . EOL); - goaway('contacts'); - return; // NOTREACHED - } - - if ($cmd === 'update' && ($orig_record['uid'] != 0)) { - _contact_update($contact_id); - goaway('contacts/' . $contact_id); - // NOTREACHED - } - - if ($cmd === 'updateprofile' && ($orig_record['uid'] != 0)) { - _contact_update_profile($contact_id); - goaway('crepair/' . $contact_id); - // NOTREACHED - } - - if ($cmd === 'block') { - _contact_block($contact_id); - - $blocked = Contact::isBlockedByUser($contact_id, local_user()); - info(($blocked ? L10n::t('Contact has been blocked') : L10n::t('Contact has been unblocked')) . EOL); - - goaway('contacts/' . $contact_id); - return; // NOTREACHED - } - - if ($cmd === 'ignore') { - _contact_ignore($contact_id); - - $ignored = Contact::isIgnoredByUser($contact_id, local_user()); - info(($ignored ? L10n::t('Contact has been ignored') : L10n::t('Contact has been unignored')) . EOL); - - goaway('contacts/' . $contact_id); - return; // NOTREACHED - } - - if ($cmd === 'archive' && ($orig_record['uid'] != 0)) { - $r = _contact_archive($contact_id, $orig_record); - if ($r) { - $archived = (($orig_record['archive']) ? 0 : 1); - info((($archived) ? L10n::t('Contact has been archived') : L10n::t('Contact has been unarchived')) . EOL); - } - - goaway('contacts/' . $contact_id); - return; // NOTREACHED - } - - if ($cmd === 'drop' && ($orig_record['uid'] != 0)) { - // Check if we should do HTML-based delete confirmation - if (x($_REQUEST, 'confirm')) { - //
    can't take arguments in its "action" parameter - // so add any arguments as hidden inputs - $query = explode_querystring($a->query_string); - $inputs = []; - foreach ($query['args'] as $arg) { - if (strpos($arg, 'confirm=') === false) { - $arg_parts = explode('=', $arg); - $inputs[] = ['name' => $arg_parts[0], 'value' => $arg_parts[1]]; - } - } - - $a->page['aside'] = ''; - - return replace_macros(get_markup_template('contact_drop_confirm.tpl'), [ - '$header' => L10n::t('Drop contact'), - '$contact' => _contact_detail_for_template($orig_record), - '$method' => 'get', - '$message' => L10n::t('Do you really want to delete this contact?'), - '$extra_inputs' => $inputs, - '$confirm' => L10n::t('Yes'), - '$confirm_url' => $query['base'], - '$confirm_name' => 'confirmed', - '$cancel' => L10n::t('Cancel'), - ]); - } - // Now check how the user responded to the confirmation query - if (x($_REQUEST, 'canceled')) { - if (x($_SESSION, 'return_url')) { - goaway('' . $_SESSION['return_url']); - } else { - goaway('contacts'); - } - } - - _contact_drop($orig_record); - info(L10n::t('Contact has been removed.') . EOL); - if (x($_SESSION, 'return_url')) { - goaway('' . $_SESSION['return_url']); - } else { - goaway('contacts'); - } - return; // NOTREACHED - } - if ($cmd === 'posts') { - return contact_posts($a, $contact_id); - } - if ($cmd === 'conversations') { - return contact_conversations($a, $contact_id, $update); - } - } - - $_SESSION['return_url'] = $a->query_string; - - if ((x($a->data, 'contact')) && (is_array($a->data['contact']))) { - $contact_id = $a->data['contact']['id']; - $contact = $a->data['contact']; - - $a->page['htmlhead'] .= replace_macros(get_markup_template('contact_head.tpl'), [ - '$baseurl' => System::baseUrl(true), - ]); - $a->page['end'] .= replace_macros(get_markup_template('contact_end.tpl'), [ - '$baseurl' => System::baseUrl(true), - ]); - - $contact['blocked'] = Contact::isBlockedByUser($contact['id'], local_user()); - $contact['readonly'] = Contact::isIgnoredByUser($contact['id'], local_user()); - - $dir_icon = ''; - $relation_text = ''; - switch ($contact['rel']) { - case Contact::FRIEND: - $dir_icon = 'images/lrarrow.gif'; - $relation_text = L10n::t('You are mutual friends with %s'); - break; - - case Contact::FOLLOWER; - $dir_icon = 'images/larrow.gif'; - $relation_text = L10n::t('You are sharing with %s'); - break; - - case Contact::SHARING; - $dir_icon = 'images/rarrow.gif'; - $relation_text = L10n::t('%s is sharing with you'); - break; - - default: - break; - } - - if ($contact['uid'] == 0) { - $relation_text = ''; - } - - if (!in_array($contact['network'], [Protocol::DFRN, Protocol::OSTATUS, Protocol::DIASPORA])) { - $relation_text = ""; - } - - $relation_text = sprintf($relation_text, htmlentities($contact['name'])); - - $url = Contact::magicLink($contact['url']); - if (strpos($url, 'redir/') === 0) { - $sparkle = ' class="sparkle" '; - } else { - $sparkle = ''; - } - - $insecure = L10n::t('Private communications are not available for this contact.'); - - $last_update = (($contact['last-update'] <= NULL_DATE) ? L10n::t('Never') : DateTimeFormat::local($contact['last-update'], 'D, j M Y, g:i A')); - - if ($contact['last-update'] > NULL_DATE) { - $last_update .= ' ' . (($contact['last-update'] <= $contact['success_update']) ? L10n::t("\x28Update was successful\x29") : L10n::t("\x28Update was not successful\x29")); - } - $lblsuggest = (($contact['network'] === Protocol::DFRN) ? L10n::t('Suggest friends') : ''); - - $poll_enabled = in_array($contact['network'], [Protocol::DFRN, Protocol::OSTATUS, Protocol::FEED, Protocol::MAIL]); - - $nettype = L10n::t('Network type: %s', ContactSelector::networkToName($contact['network'], $contact["url"])); - - // tabs - $tab_str = contacts_tab($a, $contact, 3); - - $lost_contact = (($contact['archive'] && $contact['term-date'] > NULL_DATE && $contact['term-date'] < DateTimeFormat::utcNow()) ? L10n::t('Communications lost with this contact!') : ''); - - $fetch_further_information = null; - if ($contact['network'] == Protocol::FEED) { - $fetch_further_information = [ - 'fetch_further_information', - L10n::t('Fetch further information for feeds'), - $contact['fetch_further_information'], - L10n::t("Fetch information like preview pictures, title and teaser from the feed item. You can activate this if the feed doesn't contain much text. Keywords are taken from the meta header in the feed item and are posted as hash tags."), - ['0' => L10n::t('Disabled'), - '1' => L10n::t('Fetch information'), - '3' => L10n::t('Fetch keywords'), - '2' => L10n::t('Fetch information and keywords') - ] - ]; - } - - $poll_interval = null; - if (in_array($contact['network'], [Protocol::FEED, Protocol::MAIL])) { - $poll_interval = ContactSelector::pollInterval($contact['priority'], (!$poll_enabled)); - } - - $profile_select = null; - if ($contact['network'] == Protocol::DFRN) { - $profile_select = ContactSelector::profileAssign($contact['profile-id'], (($contact['network'] !== Protocol::DFRN) ? true : false)); - } - - /// @todo Only show the following link with DFRN when the remote version supports it - $follow = ''; - $follow_text = ''; - if (in_array($contact['network'], [Protocol::DIASPORA, Protocol::OSTATUS, Protocol::DFRN])) { - if (in_array($contact['rel'], [Contact::FRIEND, Contact::SHARING])) { - $follow = System::baseUrl(true) . "/unfollow?url=" . urlencode($contact["url"]); - $follow_text = L10n::t("Disconnect/Unfollow"); - } else { - $follow = System::baseUrl(true) . "/follow?url=" . urlencode($contact["url"]); - $follow_text = L10n::t("Connect/Follow"); - } - } - - if ($contact['uid'] == 0) { - $follow = System::baseUrl(true) . "/follow?url=" . urlencode($contact["url"]); - $follow_text = L10n::t("Connect/Follow"); - } - - // Load contactact related actions like hide, suggest, delete and others - $contact_actions = contact_actions($contact); - - if ($contact['uid'] != 0) { - $lbl_vis1 = L10n::t('Profile Visibility'); - $lbl_info1 = L10n::t('Contact Information / Notes'); - $contact_settings_label = L10n::t('Contact Settings'); - } else { - $lbl_vis1 = null; - $lbl_info1 = null; - $contact_settings_label = null; - } - - $tpl = get_markup_template("contact_edit.tpl"); - $o .= replace_macros($tpl, [ - '$header' => L10n::t("Contact"), - '$tab_str' => $tab_str, - '$submit' => L10n::t('Submit'), - '$lbl_vis1' => $lbl_vis1, - '$lbl_vis2' => L10n::t('Please choose the profile you would like to display to %s when viewing your profile securely.', $contact['name']), - '$lbl_info1' => $lbl_info1, - '$lbl_info2' => L10n::t('Their personal note'), - '$reason' => trim(notags($contact['reason'])), - '$infedit' => L10n::t('Edit contact notes'), - '$common_link' => 'common/loc/' . local_user() . '/' . $contact['id'], - '$relation_text' => $relation_text, - '$visit' => L10n::t('Visit %s\'s profile [%s]', $contact['name'], $contact['url']), - '$blockunblock' => L10n::t('Block/Unblock contact'), - '$ignorecont' => L10n::t('Ignore contact'), - '$lblcrepair' => L10n::t("Repair URL settings"), - '$lblrecent' => L10n::t('View conversations'), - '$lblsuggest' => $lblsuggest, - '$nettype' => $nettype, - '$poll_interval' => $poll_interval, - '$poll_enabled' => $poll_enabled, - '$lastupdtext' => L10n::t('Last update:'), - '$lost_contact' => $lost_contact, - '$updpub' => L10n::t('Update public posts'), - '$last_update' => $last_update, - '$udnow' => L10n::t('Update now'), - '$follow' => $follow, - '$follow_text' => $follow_text, - '$profile_select' => $profile_select, - '$contact_id' => $contact['id'], - '$block_text' => (($contact['blocked']) ? L10n::t('Unblock') : L10n::t('Block') ), - '$ignore_text' => (($contact['readonly']) ? L10n::t('Unignore') : L10n::t('Ignore') ), - '$insecure' => (($contact['network'] !== Protocol::DFRN && $contact['network'] !== Protocol::MAIL && $contact['network'] !== Protocol::DIASPORA) ? $insecure : ''), - '$info' => $contact['info'], - '$cinfo' => ['info', '', $contact['info'], ''], - '$blocked' => (($contact['blocked']) ? L10n::t('Currently blocked') : ''), - '$ignored' => (($contact['readonly']) ? L10n::t('Currently ignored') : ''), - '$archived' => (($contact['archive']) ? L10n::t('Currently archived') : ''), - '$pending' => (($contact['pending']) ? L10n::t('Awaiting connection acknowledge') : ''), - '$hidden' => ['hidden', L10n::t('Hide this contact from others'), ($contact['hidden'] == 1), L10n::t('Replies/likes to your public posts may still be visible')], - '$notify' => ['notify', L10n::t('Notification for new posts'), ($contact['notify_new_posts'] == 1), L10n::t('Send a notification of every new post of this contact')], - '$fetch_further_information' => $fetch_further_information, - '$ffi_keyword_blacklist' => $contact['ffi_keyword_blacklist'], - '$ffi_keyword_blacklist' => ['ffi_keyword_blacklist', L10n::t('Blacklisted keywords'), $contact['ffi_keyword_blacklist'], L10n::t('Comma separated list of keywords that should not be converted to hashtags, when "Fetch information and keywords" is selected')], - '$photo' => $contact['photo'], - '$name' => htmlentities($contact['name']), - '$dir_icon' => $dir_icon, - '$sparkle' => $sparkle, - '$url' => $url, - '$profileurllabel' => L10n::t('Profile URL'), - '$profileurl' => $contact['url'], - '$account_type' => Contact::getAccountType($contact), - '$location' => BBCode::convert($contact["location"]), - '$location_label' => L10n::t("Location:"), - '$xmpp' => BBCode::convert($contact["xmpp"]), - '$xmpp_label' => L10n::t("XMPP:"), - '$about' => BBCode::convert($contact["about"], false), - '$about_label' => L10n::t("About:"), - '$keywords' => $contact["keywords"], - '$keywords_label' => L10n::t("Tags:"), - '$contact_action_button' => L10n::t("Actions"), - '$contact_actions' => $contact_actions, - '$contact_status' => L10n::t("Status"), - '$contact_settings_label' => $contact_settings_label, - '$contact_profile_label' => L10n::t("Profile"), - ]); - - $arr = ['contact' => $contact, 'output' => $o]; - - Addon::callHooks('contact_edit', $arr); - - return $arr['output']; - } - - $blocked = false; - $hidden = false; - $ignored = false; - $archived = false; - $all = false; - - if (($a->argc == 2) && ($a->argv[1] === 'all')) { - $sql_extra = ''; - $all = true; - } elseif (($a->argc == 2) && ($a->argv[1] === 'blocked')) { - $sql_extra = " AND `blocked` = 1 "; - $blocked = true; - } elseif (($a->argc == 2) && ($a->argv[1] === 'hidden')) { - $sql_extra = " AND `hidden` = 1 "; - $hidden = true; - } elseif (($a->argc == 2) && ($a->argv[1] === 'ignored')) { - $sql_extra = " AND `readonly` = 1 "; - $ignored = true; - } elseif (($a->argc == 2) && ($a->argv[1] === 'archived')) { - $sql_extra = " AND `archive` = 1 "; - $archived = true; - } else { - $sql_extra = " AND `blocked` = 0 "; - } - - $search = x($_GET, 'search') ? notags(trim($_GET['search'])) : ''; - $nets = x($_GET, 'nets' ) ? notags(trim($_GET['nets'])) : ''; - - $tabs = [ - [ - 'label' => L10n::t('Suggestions'), - 'url' => 'suggest', - 'sel' => '', - 'title' => L10n::t('Suggest potential friends'), - 'id' => 'suggestions-tab', - 'accesskey' => 'g', - ], - [ - 'label' => L10n::t('All Contacts'), - 'url' => 'contacts/all', - 'sel' => ($all) ? 'active' : '', - 'title' => L10n::t('Show all contacts'), - 'id' => 'showall-tab', - 'accesskey' => 'l', - ], - [ - 'label' => L10n::t('Unblocked'), - 'url' => 'contacts', - 'sel' => ((!$all) && (!$blocked) && (!$hidden) && (!$search) && (!$nets) && (!$ignored) && (!$archived)) ? 'active' : '', - 'title' => L10n::t('Only show unblocked contacts'), - 'id' => 'showunblocked-tab', - 'accesskey' => 'o', - ], - [ - 'label' => L10n::t('Blocked'), - 'url' => 'contacts/blocked', - 'sel' => ($blocked) ? 'active' : '', - 'title' => L10n::t('Only show blocked contacts'), - 'id' => 'showblocked-tab', - 'accesskey' => 'b', - ], - [ - 'label' => L10n::t('Ignored'), - 'url' => 'contacts/ignored', - 'sel' => ($ignored) ? 'active' : '', - 'title' => L10n::t('Only show ignored contacts'), - 'id' => 'showignored-tab', - 'accesskey' => 'i', - ], - [ - 'label' => L10n::t('Archived'), - 'url' => 'contacts/archived', - 'sel' => ($archived) ? 'active' : '', - 'title' => L10n::t('Only show archived contacts'), - 'id' => 'showarchived-tab', - 'accesskey' => 'y', - ], - [ - 'label' => L10n::t('Hidden'), - 'url' => 'contacts/hidden', - 'sel' => ($hidden) ? 'active' : '', - 'title' => L10n::t('Only show hidden contacts'), - 'id' => 'showhidden-tab', - 'accesskey' => 'h', - ], - ]; - - $tab_tpl = get_markup_template('common_tabs.tpl'); - $t = replace_macros($tab_tpl, ['$tabs' => $tabs]); - - $total = 0; - $searching = false; - $search_hdr = null; - if ($search) { - $searching = true; - $search_hdr = $search; - $search_txt = DBA::escape(protect_sprintf(preg_quote($search))); - $sql_extra .= " AND (name REGEXP '$search_txt' OR url REGEXP '$search_txt' OR nick REGEXP '$search_txt') "; - } - - if ($nets) { - $sql_extra .= sprintf(" AND network = '%s' ", DBA::escape($nets)); - } - - $sql_extra2 = ((($sort_type > 0) && ($sort_type <= Contact::FRIEND)) ? sprintf(" AND `rel` = %d ", intval($sort_type)) : ''); - - $r = q("SELECT COUNT(*) AS `total` FROM `contact` - WHERE `uid` = %d AND `self` = 0 AND `pending` = 0 $sql_extra $sql_extra2 ", - intval($_SESSION['uid']) - ); - if (DBA::isResult($r)) { - $a->set_pager_total($r[0]['total']); - $total = $r[0]['total']; - } - - $sql_extra3 = Widget::unavailableNetworks(); - - $contacts = []; - - $r = q("SELECT * FROM `contact` WHERE `uid` = %d AND `self` = 0 AND `pending` = 0 $sql_extra $sql_extra2 $sql_extra3 ORDER BY `name` ASC LIMIT %d , %d ", - intval($_SESSION['uid']), - intval($a->pager['start']), - intval($a->pager['itemspage']) - ); - if (DBA::isResult($r)) { - foreach ($r as $rr) { - $rr['blocked'] = Contact::isBlockedByUser($rr['id'], local_user()); - $rr['readonly'] = Contact::isIgnoredByUser($rr['id'], local_user()); - $contacts[] = _contact_detail_for_template($rr); - } - } - - $tpl = get_markup_template("contacts-template.tpl"); - $o .= replace_macros($tpl, [ - '$baseurl' => System::baseUrl(), - '$header' => L10n::t('Contacts') . (($nets) ? ' - ' . ContactSelector::networkToName($nets) : ''), - '$tabs' => $t, - '$total' => $total, - '$search' => $search_hdr, - '$desc' => L10n::t('Search your contacts'), - '$finding' => $searching ? L10n::t('Results for: %s', $search) : "", - '$submit' => L10n::t('Find'), - '$cmd' => $a->cmd, - '$contacts' => $contacts, - '$contact_drop_confirm' => L10n::t('Do you really want to delete this contact?'), - 'multiselect' => 1, - '$batch_actions' => [ - 'contacts_batch_update' => L10n::t('Update'), - 'contacts_batch_block' => L10n::t('Block') . "/" . L10n::t("Unblock"), - "contacts_batch_ignore" => L10n::t('Ignore') . "/" . L10n::t("Unignore"), - "contacts_batch_archive" => L10n::t('Archive') . "/" . L10n::t("Unarchive"), - "contacts_batch_drop" => L10n::t('Delete'), - ], - '$h_batch_actions' => L10n::t('Batch Actions'), - '$paginate' => paginate($a), - ]); - - return $o; -} - -/** - * @brief List of pages for the Contact TabBar - * - * Available Pages are 'Status', 'Profile', 'Contacts' and 'Common Friends' - * - * @param App $a - * @param array $contact The contact array - * @param int $active_tab 1 if tab should be marked as active - * - * @return string - */ -function contacts_tab($a, $contact, $active_tab) -{ - // tabs - $tabs = [ - [ - 'label' => L10n::t('Status'), - 'url' => "contacts/" . $contact['id'] . "/conversations", - 'sel' => (($active_tab == 1) ? 'active' : ''), - 'title' => L10n::t('Conversations started by this contact'), - 'id' => 'status-tab', - 'accesskey' => 'm', - ], - [ - 'label' => L10n::t('Posts and Comments'), - 'url' => "contacts/" . $contact['id'] . "/posts", - 'sel' => (($active_tab == 2) ? 'active' : ''), - 'title' => L10n::t('Status Messages and Posts'), - 'id' => 'posts-tab', - 'accesskey' => 'p', - ], - [ - 'label' => L10n::t('Profile'), - 'url' => "contacts/" . $contact['id'], - 'sel' => (($active_tab == 3) ? 'active' : ''), - 'title' => L10n::t('Profile Details'), - 'id' => 'profile-tab', - 'accesskey' => 'o', - ] - ]; - - // Show this tab only if there is visible friend list - $x = GContact::countAllFriends(local_user(), $contact['id']); - if ($x) { - $tabs[] = ['label' => L10n::t('Contacts'), - 'url' => "allfriends/" . $contact['id'], - 'sel' => (($active_tab == 4) ? 'active' : ''), - 'title' => L10n::t('View all contacts'), - 'id' => 'allfriends-tab', - 'accesskey' => 't']; - } - - // Show this tab only if there is visible common friend list - $common = GContact::countCommonFriends(local_user(), $contact['id']); - if ($common) { - $tabs[] = ['label' => L10n::t('Common Friends'), - 'url' => "common/loc/" . local_user() . "/" . $contact['id'], - 'sel' => (($active_tab == 5) ? 'active' : ''), - 'title' => L10n::t('View all common friends'), - 'id' => 'common-loc-tab', - 'accesskey' => 'd' - ]; - } - - if (!empty($contact['uid'])) { - $tabs[] = ['label' => L10n::t('Advanced'), - 'url' => 'crepair/' . $contact['id'], - 'sel' => (($active_tab == 6) ? 'active' : ''), - 'title' => L10n::t('Advanced Contact Settings'), - 'id' => 'advanced-tab', - 'accesskey' => 'r' - ]; - } - - $tab_tpl = get_markup_template('common_tabs.tpl'); - $tab_str = replace_macros($tab_tpl, ['$tabs' => $tabs]); - - return $tab_str; -} - -function contact_conversations(App $a, $contact_id, $update) -{ - $o = ''; - - if (!$update) { - // We need the editor here to be able to reshare an item. - if (local_user()) { - $x = [ - 'is_owner' => true, - 'allow_location' => $a->user['allow_location'], - 'default_location' => $a->user['default-location'], - 'nickname' => $a->user['nickname'], - 'lockstate' => (is_array($a->user) && (strlen($a->user['allow_cid']) || strlen($a->user['allow_gid']) || strlen($a->user['deny_cid']) || strlen($a->user['deny_gid'])) ? 'lock' : 'unlock'), - 'acl' => ACL::getFullSelectorHTML($a->user, true), - 'bang' => '', - 'visitor' => 'block', - 'profile_uid' => local_user(), - ]; - $o = status_editor($a, $x, 0, true); - } - } - - $contact = DBA::selectFirst('contact', ['uid', 'url', 'id'], ['id' => $contact_id]); - - if (!$update) { - $o .= contacts_tab($a, $contact, 1); - } - - if (DBA::isResult($contact)) { - $a->page['aside'] = ""; - - $profiledata = Contact::getDetailsByURL($contact["url"]); - - if (local_user()) { - if (in_array($profiledata["network"], [Protocol::DFRN, Protocol::DIASPORA, Protocol::OSTATUS])) { - $profiledata["remoteconnect"] = System::baseUrl()."/follow?url=".urlencode($profiledata["url"]); - } - } - - Profile::load($a, "", 0, $profiledata, true); - $o .= Contact::getPostsFromUrl($contact["url"], true, $update); - } - - return $o; -} - -function contact_posts(App $a, $contact_id) -{ - $contact = DBA::selectFirst('contact', ['uid', 'url', 'id'], ['id' => $contact_id]); - - $o = contacts_tab($a, $contact, 2); - - if (DBA::isResult($contact)) { - $a->page['aside'] = ""; - - $profiledata = Contact::getDetailsByURL($contact["url"]); - - if (local_user()) { - if (in_array($profiledata["network"], [Protocol::DFRN, Protocol::DIASPORA, Protocol::OSTATUS])) { - $profiledata["remoteconnect"] = System::baseUrl()."/follow?url=".urlencode($profiledata["url"]); - } - } - - Profile::load($a, "", 0, $profiledata, true); - $o .= Contact::getPostsFromUrl($contact["url"]); - } - - return $o; -} - -function _contact_detail_for_template(array $rr) -{ - $dir_icon = ''; - $alt_text = ''; - - switch ($rr['rel']) { - case Contact::FRIEND: - $dir_icon = 'images/lrarrow.gif'; - $alt_text = L10n::t('Mutual Friendship'); - break; - - case Contact::FOLLOWER; - $dir_icon = 'images/larrow.gif'; - $alt_text = L10n::t('is a fan of yours'); - break; - - case Contact::SHARING; - $dir_icon = 'images/rarrow.gif'; - $alt_text = L10n::t('you are a fan of'); - break; - - default: - break; - } - - $url = Contact::magicLink($rr['url']); - - if (strpos($url, 'redir/') === 0) { - $sparkle = ' class="sparkle" '; - } else { - $sparkle = ''; - } - - if ($rr['self']) { - $dir_icon = 'images/larrow.gif'; - $alt_text = L10n::t('This is you'); - $url = $rr['url']; - $sparkle = ''; - } - - return [ - 'img_hover' => L10n::t('Visit %s\'s profile [%s]', $rr['name'], $rr['url']), - 'edit_hover' => L10n::t('Edit contact'), - 'photo_menu' => Contact::photoMenu($rr), - 'id' => $rr['id'], - 'alt_text' => $alt_text, - 'dir_icon' => $dir_icon, - 'thumb' => ProxyUtils::proxifyUrl($rr['thumb'], false, ProxyUtils::SIZE_THUMB), - 'name' => htmlentities($rr['name']), - 'username' => htmlentities($rr['name']), - 'account_type' => Contact::getAccountType($rr), - 'sparkle' => $sparkle, - 'itemurl' => (($rr['addr'] != "") ? $rr['addr'] : $rr['url']), - 'url' => $url, - 'network' => ContactSelector::networkToName($rr['network'], $rr['url']), - 'nick' => htmlentities($rr['nick']), - ]; -} - -/** - * @brief Gives a array with actions which can performed to a given contact - * - * This includes actions like e.g. 'block', 'hide', 'archive', 'delete' and others - * - * @param array $contact Data about the Contact - * @return array with contact related actions - */ -function contact_actions($contact) -{ - $poll_enabled = in_array($contact['network'], [Protocol::DFRN, Protocol::OSTATUS, Protocol::FEED, Protocol::MAIL]); - $contact_actions = []; - - // Provide friend suggestion only for Friendica contacts - if ($contact['network'] === Protocol::DFRN) { - $contact_actions['suggest'] = [ - 'label' => L10n::t('Suggest friends'), - 'url' => 'fsuggest/' . $contact['id'], - 'title' => '', - 'sel' => '', - 'id' => 'suggest', - ]; - } - - if ($poll_enabled) { - $contact_actions['update'] = [ - 'label' => L10n::t('Update now'), - 'url' => 'contacts/' . $contact['id'] . '/update', - 'title' => '', - 'sel' => '', - 'id' => 'update', - ]; - } - - $contact_actions['block'] = [ - 'label' => (intval($contact['blocked']) ? L10n::t('Unblock') : L10n::t('Block') ), - 'url' => 'contacts/' . $contact['id'] . '/block', - 'title' => L10n::t('Toggle Blocked status'), - 'sel' => (intval($contact['blocked']) ? 'active' : ''), - 'id' => 'toggle-block', - ]; - - $contact_actions['ignore'] = [ - 'label' => (intval($contact['readonly']) ? L10n::t('Unignore') : L10n::t('Ignore') ), - 'url' => 'contacts/' . $contact['id'] . '/ignore', - 'title' => L10n::t('Toggle Ignored status'), - 'sel' => (intval($contact['readonly']) ? 'active' : ''), - 'id' => 'toggle-ignore', - ]; - - if ($contact['uid'] != 0) { - $contact_actions['archive'] = [ - 'label' => (intval($contact['archive']) ? L10n::t('Unarchive') : L10n::t('Archive') ), - 'url' => 'contacts/' . $contact['id'] . '/archive', - 'title' => L10n::t('Toggle Archive status'), - 'sel' => (intval($contact['archive']) ? 'active' : ''), - 'id' => 'toggle-archive', - ]; - - $contact_actions['delete'] = [ - 'label' => L10n::t('Delete'), - 'url' => 'contacts/' . $contact['id'] . '/drop', - 'title' => L10n::t('Delete contact'), - 'sel' => '', - 'id' => 'delete', - ]; - } - - return $contact_actions; -} diff --git a/mod/crepair.php b/mod/crepair.php index 076c611db4..1cf562d64c 100644 --- a/mod/crepair.php +++ b/mod/crepair.php @@ -8,10 +8,8 @@ use Friendica\Core\Config; use Friendica\Core\L10n; use Friendica\Core\Protocol; use Friendica\Database\DBA; -use Friendica\Model\Contact; -use Friendica\Model\Profile; - -require_once 'mod/contacts.php'; +use Friendica\Model; +use Friendica\Module; function crepair_init(App $a) { @@ -30,7 +28,7 @@ function crepair_init(App $a) if (DBA::isResult($contact)) { $a->data['contact'] = $contact; - Profile::load($a, "", 0, Contact::getDetailsByURL($contact["url"])); + Model\Profile::load($a, "", 0, Model\Contact::getDetailsByURL($contact["url"])); } } @@ -82,7 +80,7 @@ function crepair_post(App $a) if ($photo) { logger('mod-crepair: updating photo from ' . $photo); - Contact::updateAvatar($photo, local_user(), $contact['id']); + Model\Contact::updateAvatar($photo, local_user(), $contact['id']); } if ($r) { @@ -116,7 +114,7 @@ function crepair_content(App $a) $warning = L10n::t('WARNING: This is highly advanced and if you enter incorrect information your communications with this contact may stop working.'); $info = L10n::t('Please use your browser \'Back\' button now if you are uncertain what to do on this page.'); - $returnaddr = "contacts/$cid"; + $returnaddr = "contact/$cid"; $allow_remote_self = Config::get('system', 'allow_users_remote_self'); @@ -133,9 +131,9 @@ function crepair_content(App $a) $remote_self_options = ['0' => L10n::t('No mirroring'), '2' => L10n::t('Mirror as my own posting')]; } - $update_profile = in_array($contact['network'], [Protocol::DFRN, Protocol::DIASPORA, Protocol::OSTATUS]); + $update_profile = in_array($contact['network'], [Protocol::ACTIVITYPUB, Protocol::DFRN, Protocol::DIASPORA, Protocol::OSTATUS]); - $tab_str = contacts_tab($a, $contact, 5); + $tab_str = Module\Contact::getTabsHTML($a, $contact, 5); $tpl = get_markup_template('crepair.tpl'); $o = replace_macros($tpl, [ diff --git a/mod/dfrn_confirm.php b/mod/dfrn_confirm.php index 41b5e0ef54..48ce3c6aa6 100644 --- a/mod/dfrn_confirm.php +++ b/mod/dfrn_confirm.php @@ -28,6 +28,7 @@ use Friendica\Model\Group; use Friendica\Model\User; use Friendica\Network\Probe; use Friendica\Protocol\Diaspora; +use Friendica\Protocol\ActivityPub; use Friendica\Util\Crypto; use Friendica\Util\DateTimeFormat; use Friendica\Util\Network; @@ -220,7 +221,7 @@ function dfrn_confirm_post(App $a, $handsfree = null) * */ - $res = Network::post($dfrn_confirm, $params, null, $redirects, 120); + $res = Network::post($dfrn_confirm, $params, null, $redirects, 120)->getBody(); logger(' Confirm: received data: ' . $res, LOGGER_DATA); @@ -335,10 +336,17 @@ function dfrn_confirm_post(App $a, $handsfree = null) intval($contact_id) ); } else { + if ($network == Protocol::ACTIVITYPUB) { + ActivityPub\Transmitter::sendContactAccept($contact['url'], $contact['hub-verify'], $uid); + $pending = true; + } else { + $pending = false; + } + // $network !== Protocol::DFRN $network = defaults($contact, 'network', Protocol::OSTATUS); - $arr = Probe::uri($contact['url']); + $arr = Probe::uri($contact['url'], $network); $notify = defaults($contact, 'notify' , $arr['notify']); $poll = defaults($contact, 'poll' , $arr['poll']); @@ -348,7 +356,7 @@ function dfrn_confirm_post(App $a, $handsfree = null) $new_relation = $contact['rel']; $writable = $contact['writable']; - if ($network === Protocol::DIASPORA) { + if (in_array($network, [Protocol::DIASPORA, Protocol::ACTIVITYPUB])) { if ($duplex) { $new_relation = Contact::FRIEND; } else { @@ -362,30 +370,12 @@ function dfrn_confirm_post(App $a, $handsfree = null) DBA::delete('intro', ['id' => $intro_id]); - $r = q("UPDATE `contact` SET `name-date` = '%s', - `uri-date` = '%s', - `addr` = '%s', - `notify` = '%s', - `poll` = '%s', - `blocked` = 0, - `pending` = 0, - `network` = '%s', - `writable` = %d, - `hidden` = %d, - `rel` = %d - WHERE `id` = %d - ", - DBA::escape(DateTimeFormat::utcNow()), - DBA::escape(DateTimeFormat::utcNow()), - DBA::escape($addr), - DBA::escape($notify), - DBA::escape($poll), - DBA::escape($network), - intval($writable), - intval($hidden), - intval($new_relation), - intval($contact_id) - ); + $fields = ['name-date' => DateTimeFormat::utcNow(), + 'uri-date' => DateTimeFormat::utcNow(), 'addr' => $addr, + 'notify' => $notify, 'poll' => $poll, 'blocked' => false, + 'pending' => $pending, 'network' => $network, + 'writable' => $writable, 'hidden' => $hidden, 'rel' => $new_relation]; + DBA::update('contact', $fields, ['id' => $contact_id]); } if (!DBA::isResult($r)) { @@ -403,10 +393,14 @@ function dfrn_confirm_post(App $a, $handsfree = null) Group::addMember(User::getDefaultGroup($uid, $contact["network"]), $contact['id']); + if ($network == Protocol::ACTIVITYPUB && $duplex) { + ActivityPub\Transmitter::sendActivity('Follow', $contact['url'], $uid); + } + // Let's send our user to the contact editor in case they want to // do anything special with this new friend. if ($handsfree === null) { - goaway(System::baseUrl() . '/contacts/' . intval($contact_id)); + goaway(System::baseUrl() . '/contact/' . intval($contact_id)); } else { return; } @@ -610,7 +604,7 @@ function dfrn_confirm_post(App $a, $handsfree = null) 'to_name' => $combined['username'], 'to_email' => $combined['email'], 'uid' => $combined['uid'], - 'link' => System::baseUrl() . '/contacts/' . $dfrn_record, + 'link' => System::baseUrl() . '/contact/' . $dfrn_record, 'source_name' => ((strlen(stripslashes($combined['name']))) ? stripslashes($combined['name']) : L10n::t('[Name Withheld]')), 'source_link' => $combined['url'], 'source_photo' => $combined['photo'], diff --git a/mod/dfrn_notify.php b/mod/dfrn_notify.php index 88f706385b..8a53ac09b6 100644 --- a/mod/dfrn_notify.php +++ b/mod/dfrn_notify.php @@ -79,13 +79,13 @@ function dfrn_notify_post(App $a) { $condition = []; switch ($direction) { case (-1): - $condition = ["`issued-id` = ? OR `dfrn-id` = ?", $dfrn_id, $dfrn_id]; + $condition = ["(`issued-id` = ? OR `dfrn-id` = ?) AND `uid` = ?", $dfrn_id, $dfrn_id, $user['uid']]; break; case 0: - $condition = ['issued-id' => $dfrn_id, 'duplex' => true]; + $condition = ['issued-id' => $dfrn_id, 'duplex' => true, 'uid' => $user['uid']]; break; case 1: - $condition = ['dfrn-id' => $dfrn_id, 'duplex' => true]; + $condition = ['dfrn-id' => $dfrn_id, 'duplex' => true, 'uid' => $user['uid']]; break; default: System::xmlExit(3, 'Invalid direction'); @@ -182,7 +182,7 @@ function dfrn_notify_post(App $a) { function dfrn_dispatch_public($postdata) { - $msg = Diaspora::decodeRaw([], $postdata); + $msg = Diaspora::decodeRaw([], $postdata, true); if (!$msg) { // We have to fail silently to be able to hand it over to the salmon parser return false; @@ -287,15 +287,15 @@ function dfrn_notify_content(App $a) { $condition = []; switch ($direction) { case (-1): - $condition = ["`issued-id` = ? OR `dfrn-id` = ?", $dfrn_id, $dfrn_id]; + $condition = ["(`issued-id` = ? OR `dfrn-id` = ?) AND `uid` = ?", $dfrn_id, $dfrn_id, $user['uid']]; $my_id = $dfrn_id; break; case 0: - $condition = ['issued-id' => $dfrn_id, 'duplex' => true]; + $condition = ['issued-id' => $dfrn_id, 'duplex' => true, 'uid' => $user['uid']]; $my_id = '1:' . $dfrn_id; break; case 1: - $condition = ['dfrn-id' => $dfrn_id, 'duplex' => true]; + $condition = ['dfrn-id' => $dfrn_id, 'duplex' => true, 'uid' => $user['uid']]; $my_id = '0:' . $dfrn_id; break; default: @@ -322,8 +322,8 @@ function dfrn_notify_content(App $a) { $encrypted_id = ''; $id_str = $my_id . '.' . mt_rand(1000,9999); - $prv_key = trim($importer['prvkey']); - $pub_key = trim($importer['pubkey']); + $prv_key = trim($importer['cprvkey']); + $pub_key = trim($importer['cpubkey']); $dplx = intval($importer['duplex']); if (($dplx && strlen($prv_key)) || (strlen($prv_key) && !strlen($pub_key))) { diff --git a/mod/dfrn_poll.php b/mod/dfrn_poll.php index 54539ee03d..af597d76ff 100644 --- a/mod/dfrn_poll.php +++ b/mod/dfrn_poll.php @@ -502,7 +502,7 @@ function dfrn_poll_content(App $a) 'dfrn_version' => DFRN_PROTOCOL_VERSION, 'challenge' => $challenge, 'sec' => $sec - ]); + ])->getBody(); } $profile = ((DBA::isResult($r) && $r[0]['nickname']) ? $r[0]['nickname'] : $nickname); diff --git a/mod/dfrn_request.php b/mod/dfrn_request.php index 25fe69066f..67db2c6285 100644 --- a/mod/dfrn_request.php +++ b/mod/dfrn_request.php @@ -173,9 +173,9 @@ function dfrn_request_post(App $a) Contact::updateAvatar($photo, local_user(), $r[0]["id"], true); } - $forwardurl = System::baseUrl() . "/contacts/" . $r[0]['id']; + $forwardurl = System::baseUrl() . "/contact/" . $r[0]['id']; } else { - $forwardurl = System::baseUrl() . "/contacts"; + $forwardurl = System::baseUrl() . "/contact"; } // Allow the blocked remote notification to complete @@ -451,10 +451,10 @@ function dfrn_request_post(App $a) // Diaspora needs the uri in the format user@domain.tld // Diaspora will support the remote subscription in a future version if ($network == Protocol::DIASPORA) { - $uri = $nickname . '@' . $a->get_hostname(); + $uri = $nickname . '@' . $a->getHostName(); - if ($a->get_path()) { - $uri .= '/' . $a->get_path(); + if ($a->getURLPath()) { + $uri .= '/' . $a->getURLPath(); } $uri = urlencode($uri); @@ -609,7 +609,7 @@ function dfrn_request_content(App $a) } elseif (x($_GET, 'address') && ($_GET['address'] != "")) { $myaddr = $_GET['address']; } elseif (local_user()) { - if (strlen($a->urlpath)) { + if (strlen($a->getURLPath())) { $myaddr = System::baseUrl() . '/profile/' . $a->user['nickname']; } else { $myaddr = $a->user['nickname'] . '@' . substr(System::baseUrl(), strpos(System::baseUrl(), '://') + 3); diff --git a/mod/directory.php b/mod/directory.php index 411024dc1a..202132e366 100644 --- a/mod/directory.php +++ b/mod/directory.php @@ -16,7 +16,7 @@ use Friendica\Util\Proxy as ProxyUtils; function directory_init(App $a) { - $a->set_pager_itemspage(60); + $a->setPagerItemsPage(60); if (local_user()) { $a->page['aside'] .= Widget::findPeople(); @@ -87,7 +87,7 @@ function directory_content(App $a) LEFT JOIN `user` ON `user`.`uid` = `profile`.`uid` WHERE `is-default` $publish AND NOT `user`.`blocked` AND NOT `user`.`account_removed` $sql_extra"); if (DBA::isResult($cnt)) { - $a->set_pager_total($cnt['total']); + $a->setPagerTotal($cnt['total']); } $order = " ORDER BY `name` ASC "; diff --git a/mod/dirfind.php b/mod/dirfind.php index f4ddba45d4..3e5aa83a72 100644 --- a/mod/dirfind.php +++ b/mod/dirfind.php @@ -12,14 +12,13 @@ use Friendica\Core\Protocol; use Friendica\Core\System; use Friendica\Core\Worker; use Friendica\Database\DBA; -use Friendica\Model\Contact; -use Friendica\Model\GContact; +use Friendica\Model; +use Friendica\Module; use Friendica\Network\Probe; use Friendica\Protocol\PortableContact; use Friendica\Util\Network; use Friendica\Util\Proxy as ProxyUtils; -require_once 'mod/contacts.php'; function dirfind_init(App $a) { @@ -44,7 +43,7 @@ function dirfind_content(App $a, $prefix = "") { $local = Config::get('system','poco_local_search'); - $search = $prefix.notags(trim($_REQUEST['search'])); + $search = $prefix.notags(trim(defaults($_REQUEST, 'search', ''))); $header = ''; @@ -54,7 +53,7 @@ function dirfind_content(App $a, $prefix = "") { if ((valid_email($search) && Network::isEmailDomainValid($search)) || (substr(normalise_link($search), 0, 7) == "http://")) { $user_data = Probe::uri($search); - $discover_user = (in_array($user_data["network"], [Protocol::DFRN, Protocol::OSTATUS, Protocol::DIASPORA])); + $discover_user = (in_array($user_data["network"], [Protocol::ACTIVITYPUB, Protocol::DFRN, Protocol::OSTATUS, Protocol::DIASPORA])); } } @@ -83,7 +82,7 @@ function dirfind_content(App $a, $prefix = "") { $objresult->tags = ""; $objresult->network = $user_data["network"]; - $contact = Contact::getDetailsByURL($user_data["url"], local_user()); + $contact = Model\Contact::getDetailsByURL($user_data["url"], local_user()); $objresult->cid = $contact["cid"]; $objresult->pcid = $contact["zid"]; @@ -91,7 +90,7 @@ function dirfind_content(App $a, $prefix = "") { // Add the contact to the global contacts if it isn't already in our system if (($contact["cid"] == 0) && ($contact["zid"] == 0) && ($contact["gid"] == 0)) { - GContact::update($user_data); + Model\GContact::update($user_data); } } elseif ($local) { @@ -156,7 +155,7 @@ function dirfind_content(App $a, $prefix = "") { continue; } - $result = Contact::getDetailsByURL($result["nurl"], local_user()); + $result = Model\Contact::getDetailsByURL($result["nurl"], local_user()); if ($result["name"] == "") { $result["name"] = end(explode("/", $urlparts["path"])); @@ -188,8 +187,8 @@ function dirfind_content(App $a, $prefix = "") { } if ($j->total) { - $a->set_pager_total($j->total); - $a->set_pager_itemspage($j->items_page); + $a->setPagerTotal($j->total); + $a->setPagerItemsPage($j->items_page); } if (!empty($j->results)) { @@ -200,7 +199,7 @@ function dirfind_content(App $a, $prefix = "") { $alt_text = ""; - $contact_details = Contact::getDetailsByURL($jj->url, local_user()); + $contact_details = Model\Contact::getDetailsByURL($jj->url, local_user()); $itemurl = (($contact_details["addr"] != "") ? $contact_details["addr"] : $jj->url); @@ -210,8 +209,8 @@ function dirfind_content(App $a, $prefix = "") { $conntxt = ""; $contact = DBA::selectFirst('contact', [], ['id' => $jj->cid]); if (DBA::isResult($contact)) { - $photo_menu = Contact::photoMenu($contact); - $details = _contact_detail_for_template($contact); + $photo_menu = Model\Contact::photoMenu($contact); + $details = Module\Contact::getContactTemplateVars($contact); $alt_text = $details['alt_text']; } else { $photo_menu = []; @@ -222,12 +221,12 @@ function dirfind_content(App $a, $prefix = "") { $contact = DBA::selectFirst('contact', [], ['id' => $jj->pcid]); if (DBA::isResult($contact)) { - $photo_menu = Contact::photoMenu($contact); + $photo_menu = Model\Contact::photoMenu($contact); } else { $photo_menu = []; } - $photo_menu['profile'] = [L10n::t("View Profile"), Contact::magicLink($jj->url)]; + $photo_menu['profile'] = [L10n::t("View Profile"), Model\Contact::magicLink($jj->url)]; $photo_menu['follow'] = [L10n::t("Connect/Follow"), $connlnk]; } @@ -235,7 +234,7 @@ function dirfind_content(App $a, $prefix = "") { $entry = [ 'alt_text' => $alt_text, - 'url' => Contact::magicLink($jj->url), + 'url' => Model\Contact::magicLink($jj->url), 'itemurl' => $itemurl, 'name' => htmlentities($jj->name), 'thumb' => ProxyUtils::proxifyUrl($jj->photo, false, ProxyUtils::SIZE_THUMB), @@ -246,7 +245,7 @@ function dirfind_content(App $a, $prefix = "") { 'details' => $contact_details['location'], 'tags' => $contact_details['keywords'], 'about' => $contact_details['about'], - 'account_type' => Contact::getAccountType($contact_details), + 'account_type' => Model\Contact::getAccountType($contact_details), 'network' => ContactSelector::networkToName($jj->network, $jj->url), 'id' => ++$id, ]; diff --git a/mod/display.php b/mod/display.php index 907bf8ebba..a03b918372 100644 --- a/mod/display.php +++ b/mod/display.php @@ -17,6 +17,7 @@ use Friendica\Model\Group; use Friendica\Model\Item; use Friendica\Model\Profile; use Friendica\Protocol\DFRN; +use Friendica\Protocol\ActivityPub; function display_init(App $a) { @@ -43,7 +44,7 @@ function display_init(App $a) $item = null; - $fields = ['id', 'parent', 'author-id', 'body', 'uid']; + $fields = ['id', 'parent', 'author-id', 'body', 'uid', 'guid']; // If there is only one parameter, then check if this parameter could be a guid if ($a->argc == 2) { @@ -76,6 +77,10 @@ function display_init(App $a) displayShowFeed($item["id"], false); } + if (ActivityPub::isRequest()) { + goaway(str_replace('display/', 'objects/', $a->query_string)); + } + if ($item["id"] != $item["parent"]) { $item = Item::selectFirstForUser(local_user(), $fields, ['id' => $item["parent"]]); } @@ -360,7 +365,7 @@ function display_content(App $a, $update = false, $update_uid = 0) $title = trim(HTML::toPlaintext(BBCode::convert($item["title"], false), 0, true)); $author_name = $item["author-name"]; - $image = $a->remove_baseurl($item["author-avatar"]); + $image = $a->removeBaseURL($item["author-avatar"]); if ($title == "") { $title = $author_name; diff --git a/mod/editpost.php b/mod/editpost.php index 258585ef1c..780145ed3f 100644 --- a/mod/editpost.php +++ b/mod/editpost.php @@ -28,7 +28,7 @@ function editpost_content(App $a) } $fields = ['allow_cid', 'allow_gid', 'deny_cid', 'deny_gid', - 'type', 'body', 'title', 'file', 'wall', 'post-type']; + 'type', 'body', 'title', 'file', 'wall', 'post-type', 'guid']; $item = Item::selectFirstForUser(local_user(), $fields, ['id' => $post_id, 'uid' => local_user()]); @@ -51,15 +51,6 @@ function editpost_content(App $a) '$nickname' => $a->user['nickname'] ]); - $tpl = get_markup_template('jot-end.tpl'); - $a->page['end'] .= replace_macros($tpl, [ - '$baseurl' => System::baseUrl(), - '$ispublic' => ' ', // L10n::t('Visible to everybody'), - '$geotag' => $geotag, - '$nickname' => $a->user['nickname'] - ]); - - $tpl = get_markup_template("jot.tpl"); if (strlen($item['allow_cid']) || strlen($item['allow_gid']) || strlen($item['deny_cid']) || strlen($item['deny_gid'])) { @@ -95,7 +86,7 @@ function editpost_content(App $a) $o .= replace_macros($tpl, [ '$is_edit' => true, - '$return_path' => $_SESSION['return_url'], + '$return_path' => '/display/' . $item['guid'], '$action' => 'item', '$share' => L10n::t('Save'), '$upload' => L10n::t('Upload photo'), diff --git a/mod/events.php b/mod/events.php index 91474022fc..d6ad97eac6 100644 --- a/mod/events.php +++ b/mod/events.php @@ -17,10 +17,12 @@ use Friendica\Model\Item; use Friendica\Model\Profile; use Friendica\Util\DateTimeFormat; use Friendica\Util\Temporal; +use Friendica\Module\Login; require_once 'include/items.php'; -function events_init(App $a) { +function events_init(App $a) +{ if (!local_user()) { return; } @@ -42,7 +44,8 @@ function events_init(App $a) { return; } -function events_post(App $a) { +function events_post(App $a) +{ logger('post: ' . print_r($_REQUEST, true), LOGGER_DATA); @@ -50,15 +53,15 @@ function events_post(App $a) { return; } - $event_id = (x($_POST, 'event_id') ? intval($_POST['event_id']) : 0); - $cid = (x($_POST, 'cid') ? intval($_POST['cid']) : 0); + $event_id = !empty($_POST['event_id']) ? intval($_POST['event_id']) : 0; + $cid = !empty($_POST['cid']) ? intval($_POST['cid']) : 0; $uid = local_user(); - $start_text = escape_tags($_REQUEST['start_text']); - $finish_text = escape_tags($_REQUEST['finish_text']); + $start_text = escape_tags(defaults($_REQUEST, 'start_text', '')); + $finish_text = escape_tags(defaults($_REQUEST, 'finish_text', '')); - $adjust = intval($_POST['adjust']); - $nofinish = intval($_POST['nofinish']); + $adjust = intval(defaults($_POST, 'adjust', 0)); + $nofinish = intval(defaults($_POST, 'nofinish', 0)); // The default setting for the `private` field in event_store() is false, so mirror that $private_event = false; @@ -91,9 +94,9 @@ function events_post(App $a) { // and we'll waste a bunch of time responding to it. Time that // could've been spent doing something else. - $summary = escape_tags(trim($_POST['summary'])); - $desc = escape_tags(trim($_POST['desc'])); - $location = escape_tags(trim($_POST['location'])); + $summary = escape_tags(trim(defaults($_POST, 'summary', ''))); + $desc = escape_tags(trim(defaults($_POST, 'desc', ''))); + $location = escape_tags(trim(defaults($_POST, 'location', ''))); $type = 'event'; $action = ($event_id == '') ? 'new' : "event/" . $event_id; @@ -117,7 +120,7 @@ function events_post(App $a) { goaway($onerror_url); } - $share = (intval($_POST['share']) ? intval($_POST['share']) : 0); + $share = intval(defaults($_POST, 'share', 0)); $c = q("SELECT `id` FROM `contact` WHERE `uid` = %d AND `self` LIMIT 1", intval(local_user()) @@ -137,7 +140,7 @@ function events_post(App $a) { $str_contact_deny = !empty($_POST['contact_deny']) ? perms2str($_POST['contact_deny']) : ''; // Undo the pseudo-contact of self, since there are real contacts now - if (strpos($str_contact_allow, '<' . $self . '>') !== false ) { + if (strpos($str_contact_allow, '<' . $self . '>') !== false) { $str_contact_allow = str_replace('<' . $self . '>', '', $str_contact_allow); } // Make sure to set the `private` field as true. This is necessary to @@ -184,14 +187,14 @@ function events_post(App $a) { Worker::add(PRIORITY_HIGH, "Notifier", "event", $item_id); } - goaway($_SESSION['return_url']); + goaway('/events'); } -function events_content(App $a) { - +function events_content(App $a) +{ if (!local_user()) { notice(L10n::t('Permission denied.') . EOL); - return; + return Login::form(); } if ($a->argc == 1) { @@ -229,11 +232,6 @@ function events_content(App $a) { '$i18n' => $i18n, ]); - $etpl = get_markup_template('event_end.tpl'); - $a->page['end'] .= replace_macros($etpl, [ - '$baseurl' => System::baseUrl(), - ]); - $o = ''; $tabs = ''; // tabs @@ -244,7 +242,7 @@ function events_content(App $a) { $mode = 'view'; $y = 0; $m = 0; - $ignored = (x($_REQUEST, 'ignored') ? intval($_REQUEST['ignored']) : 0); + $ignored = !empty($_REQUEST['ignored']) ? intval($_REQUEST['ignored']) : 0; if ($a->argc > 1) { if ($a->argc > 2 && $a->argv[1] == 'event') { @@ -272,7 +270,6 @@ function events_content(App $a) { // The view mode part is similiar to /mod/cal.php if ($mode == 'view') { - $thisyear = DateTimeFormat::localNow('Y'); $thismonth = DateTimeFormat::localNow('m'); if (!$y) { @@ -312,10 +309,10 @@ function events_content(App $a) { $finish = sprintf('%d-%d-%d %d:%d:%d', $y, $m, $dim, 23, 59, 59); if ($a->argc > 1 && $a->argv[1] === 'json') { - if (x($_GET, 'start')) { - $start = $_GET['start']; + if (!empty($_GET['start'])) { + $start = $_GET['start']; } - if (x($_GET, 'end')) { + if (!empty($_GET['end'])) { $finish = $_GET['end']; } } @@ -349,7 +346,7 @@ function events_content(App $a) { $r = Event::sortByDate($r); foreach ($r as $rr) { $j = $rr['adjust'] ? DateTimeFormat::local($rr['start'], 'j') : DateTimeFormat::utc($rr['start'], 'j'); - if (!x($links,$j)) { + if (empty($links[$j])) { $links[$j] = System::baseUrl() . '/' . $a->cmd . '#link-' . $j; } } @@ -363,12 +360,12 @@ function events_content(App $a) { $events = Event::prepareListForTemplate($r); } - if ($a->argc > 1 && $a->argv[1] === 'json'){ + if ($a->argc > 1 && $a->argv[1] === 'json') { echo json_encode($events); killme(); } - if (x($_GET, 'id')) { + if (!empty($_GET['id'])) { $tpl = get_markup_template("event.tpl"); } else { $tpl = get_markup_template("events_js.tpl"); @@ -378,7 +375,7 @@ function events_content(App $a) { foreach ($events as $key => $event) { $event_item = []; foreach ($event['item'] as $k => $v) { - $k = str_replace('-' ,'_', $k); + $k = str_replace('-', '_', $k); $event_item[$k] = $v; } $events[$key]['item'] = $event_item; @@ -403,7 +400,7 @@ function events_content(App $a) { '$list' => L10n::t('list'), ]); - if (x($_GET, 'id')) { + if (!empty($_GET['id'])) { echo $o; killme(); } @@ -428,41 +425,45 @@ function events_content(App $a) { } // In case of an error the browser is redirected back here, with these parameters filled in with the previous values - if (x($_REQUEST, 'nofinish')) {$orig_event['nofinish'] = $_REQUEST['nofinish'];} - if (x($_REQUEST, 'adjust')) {$orig_event['adjust'] = $_REQUEST['adjust'];} - if (x($_REQUEST, 'summary')) {$orig_event['summary'] = $_REQUEST['summary'];} - if (x($_REQUEST, 'description')) {$orig_event['description'] = $_REQUEST['description'];} - if (x($_REQUEST, 'location')) {$orig_event['location'] = $_REQUEST['location'];} - if (x($_REQUEST, 'start')) {$orig_event['start'] = $_REQUEST['start'];} - if (x($_REQUEST, 'finish')) {$orig_event['finish'] = $_REQUEST['finish'];} - if (x($_REQUEST,'finish')) $orig_event['finish'] = $_REQUEST['finish']; + if (!empty($_REQUEST['nofinish'])) {$orig_event['nofinish'] = $_REQUEST['nofinish'];} + if (!empty($_REQUEST['adjust'])) {$orig_event['adjust'] = $_REQUEST['adjust'];} + if (!empty($_REQUEST['summary'])) {$orig_event['summary'] = $_REQUEST['summary'];} + if (!empty($_REQUEST['description'])) {$orig_event['description'] = $_REQUEST['description'];} + if (!empty($_REQUEST['location'])) {$orig_event['location'] = $_REQUEST['location'];} + if (!empty($_REQUEST['start'])) {$orig_event['start'] = $_REQUEST['start'];} + if (!empty($_REQUEST['finish'])) {$orig_event['finish'] = $_REQUEST['finish'];} - $n_checked = ((x($orig_event) && $orig_event['nofinish']) ? ' checked="checked" ' : ''); - $a_checked = ((x($orig_event) && $orig_event['adjust']) ? ' checked="checked" ' : ''); + $n_checked = (!empty($orig_event['nofinish']) ? ' checked="checked" ' : ''); + $a_checked = (!empty($orig_event['adjust']) ? ' checked="checked" ' : ''); - $t_orig = (x($orig_event) ? $orig_event['summary'] : ''); - $d_orig = (x($orig_event) ? $orig_event['desc'] : ''); - $l_orig = (x($orig_event) ? $orig_event['location'] : ''); - $eid = (x($orig_event) ? $orig_event['id'] : 0); - $cid = (x($orig_event) ? $orig_event['cid'] : 0); - $uri = (x($orig_event) ? $orig_event['uri'] : ''); + $t_orig = !empty($orig_event) ? $orig_event['summary'] : ''; + $d_orig = !empty($orig_event) ? $orig_event['desc'] : ''; + $l_orig = !empty($orig_event) ? $orig_event['location'] : ''; + $eid = !empty($orig_event) ? $orig_event['id'] : 0; + $cid = !empty($orig_event) ? $orig_event['cid'] : 0; + $uri = !empty($orig_event) ? $orig_event['uri'] : ''; $sh_disabled = ''; - $sh_checked = ''; + $sh_checked = ''; - if (x($orig_event)) { - $sh_checked = (($orig_event['allow_cid'] === '<' . local_user() . '>' && !$orig_event['allow_gid'] && !$orig_event['deny_cid'] && !$orig_event['deny_gid']) ? '' : ' checked="checked" '); + if (!empty($orig_event) + && ($orig_event['allow_cid'] !== '<' . local_user() . '>' + || $orig_event['allow_gid'] + || $orig_event['deny_cid'] + || $orig_event['deny_gid'])) + { + $sh_checked = ' checked="checked" '; } if ($cid || $mode === 'edit') { $sh_disabled = 'disabled="disabled"'; } - $sdt = (x($orig_event) ? $orig_event['start'] : 'now'); - $fdt = (x($orig_event) ? $orig_event['finish'] : 'now'); + $sdt = !empty($orig_event) ? $orig_event['start'] : 'now'; + $fdt = !empty($orig_event) ? $orig_event['finish'] : 'now'; $tz = date_default_timezone_get(); - if (x($orig_event)) { + if (!empty($orig_event)) { $tz = ($orig_event['adjust'] ? date_default_timezone_get() : 'UTC'); } @@ -470,20 +471,22 @@ function events_content(App $a) { $smonth = DateTimeFormat::convert($sdt, $tz, 'UTC', 'm'); $sday = DateTimeFormat::convert($sdt, $tz, 'UTC', 'd'); - $shour = (x($orig_event) ? DateTimeFormat::convert($sdt, $tz, 'UTC', 'H') : '00'); - $sminute = (x($orig_event) ? DateTimeFormat::convert($sdt, $tz, 'UTC', 'i') : '00'); + $shour = !empty($orig_event) ? DateTimeFormat::convert($sdt, $tz, 'UTC', 'H') : '00'; + $sminute = !empty($orig_event) ? DateTimeFormat::convert($sdt, $tz, 'UTC', 'i') : '00'; $fyear = DateTimeFormat::convert($fdt, $tz, 'UTC', 'Y'); $fmonth = DateTimeFormat::convert($fdt, $tz, 'UTC', 'm'); $fday = DateTimeFormat::convert($fdt, $tz, 'UTC', 'd'); - $fhour = (x($orig_event) ? DateTimeFormat::convert($fdt, $tz, 'UTC', 'H') : '00'); - $fminute = (x($orig_event) ? DateTimeFormat::convert($fdt, $tz, 'UTC', 'i') : '00'); + $fhour = !empty($orig_event) ? DateTimeFormat::convert($fdt, $tz, 'UTC', 'H') : '00'; + $fminute = !empty($orig_event) ? DateTimeFormat::convert($fdt, $tz, 'UTC', 'i') : '00'; $perms = ACL::getDefaultUserPermissions($orig_event); - if ($mode === 'new' || $mode === 'copy') { - $acl = ($cid ? '' : ACL::getFullSelectorHTML($a->user, false, $orig_event)); + if (!$cid && in_array($mode, ['new', 'copy'])) { + $acl = ACL::getFullSelectorHTML($a->user, false, $orig_event); + } else { + $acl = ''; } // If we copy an old event, we need to remove the ID and URI @@ -495,7 +498,7 @@ function events_content(App $a) { $tpl = get_markup_template('event_form.tpl'); - $o .= replace_macros($tpl,[ + $o .= replace_macros($tpl, [ '$post' => System::baseUrl() . '/events', '$eid' => $eid, '$cid' => $cid, @@ -509,11 +512,31 @@ function events_content(App $a) { '$title' => L10n::t('Event details'), '$desc' => L10n::t('Starting date and Title are required.'), '$s_text' => L10n::t('Event Starts:') . ' *', - '$s_dsel' => Temporal::getDateTimeField(new DateTime(), DateTime::createFromFormat('Y', $syear+5), DateTime::createFromFormat('Y-m-d H:i', "$syear-$smonth-$sday $shour:$sminute"), L10n::t('Event Starts:'), 'start_text', true, true, '', '', true), + '$s_dsel' => Temporal::getDateTimeField( + new DateTime(), + DateTime::createFromFormat('Y', $syear+5), + DateTime::createFromFormat('Y-m-d H:i', "$syear-$smonth-$sday $shour:$sminute"), + L10n::t('Event Starts:'), + 'start_text', + true, + true, + '', + '', + true + ), '$n_text' => L10n::t('Finish date/time is not known or not relevant'), '$n_checked' => $n_checked, '$f_text' => L10n::t('Event Finishes:'), - '$f_dsel' => Temporal::getDateTimeField(new DateTime(), DateTime::createFromFormat('Y', $fyear+5), DateTime::createFromFormat('Y-m-d H:i', "$fyear-$fmonth-$fday $fhour:$fminute"), L10n::t('Event Finishes:'), 'finish_text', true, true, 'start_text'), + '$f_dsel' => Temporal::getDateTimeField( + new DateTime(), + DateTime::createFromFormat('Y', $fyear+5), + DateTime::createFromFormat('Y-m-d H:i', "$fyear-$fmonth-$fday $fhour:$fminute"), + L10n::t('Event Finishes:'), + 'finish_text', + true, + true, + 'start_text' + ), '$a_text' => L10n::t('Adjust for viewer timezone'), '$a_checked' => $a_checked, '$d_text' => L10n::t('Description:'), @@ -534,7 +557,6 @@ function events_content(App $a) { '$basic' => L10n::t('Basic'), '$advanced' => L10n::t('Advanced'), '$permissions' => L10n::t('Permissions'), - ]); return $o; diff --git a/mod/feedtest.php b/mod/feedtest.php index d9a9abb91f..e75e7a1b8e 100644 --- a/mod/feedtest.php +++ b/mod/feedtest.php @@ -32,8 +32,7 @@ function feedtest_content(App $a) $contact = DBA::selectFirst('contact', [], ['id' => $contact_id]); - $ret = Network::curl($contact['poll']); - $xml = $ret['body']; + $xml = Network::fetchUrl($contact['poll']); $dummy = null; $import_result = Feed::import($xml, $importer, $contact, $dummy, true); diff --git a/mod/fetch.php b/mod/fetch.php index 35455e2822..4e7d8c751a 100644 --- a/mod/fetch.php +++ b/mod/fetch.php @@ -25,7 +25,7 @@ function fetch_init(App $a) // Fetch the item $fields = ['uid', 'title', 'body', 'guid', 'contact-id', 'private', 'created', 'app', 'location', 'coord', 'network', - 'event-id', 'resource-id', 'author-link', 'owner-link', 'attach']; + 'event-id', 'resource-id', 'author-link', 'author-avatar', 'author-name', 'plink', 'owner-link', 'attach']; $condition = ['wall' => true, 'private' => false, 'guid' => $guid, 'network' => [Protocol::DFRN, Protocol::DIASPORA]]; $item = Item::selectFirst($fields, $condition); if (!DBA::isResult($item)) { diff --git a/mod/filerm.php b/mod/filerm.php index bd46a8bfea..7fb978ae69 100644 --- a/mod/filerm.php +++ b/mod/filerm.php @@ -25,9 +25,7 @@ function filerm_content(App $a) { file_tag_unsave_file(local_user(),$item_id,$term, $category); } - if (x($_SESSION,'return_url')) { - goaway(System::baseUrl() . '/' . $_SESSION['return_url']); - } + //goaway('/network'); killme(); } diff --git a/mod/follow.php b/mod/follow.php index 627ab52033..70dfb627ed 100644 --- a/mod/follow.php +++ b/mod/follow.php @@ -20,12 +20,12 @@ function follow_post(App $a) } if (isset($_REQUEST['cancel'])) { - goaway($_SESSION['return_url']); + goaway('contacts'); } $uid = local_user(); $url = notags(trim($_REQUEST['url'])); - $return_url = $_SESSION['return_url']; + $return_url = 'contacts'; // Makes the connection request for friendica contacts easier // This is just a precaution if maybe this page is called somewhere directly via POST @@ -39,7 +39,7 @@ function follow_post(App $a) } goaway($return_url); } elseif ($result['cid']) { - goaway(System::baseUrl() . '/contacts/' . $result['cid']); + goaway('contact/' . $result['cid']); } info(L10n::t('The contact could not be added.')); @@ -50,9 +50,11 @@ function follow_post(App $a) function follow_content(App $a) { + $return_url = 'contacts'; + if (!local_user()) { notice(L10n::t('Permission denied.')); - goaway($_SESSION['return_url']); + goaway($return_url); // NOTREACHED } @@ -116,7 +118,7 @@ function follow_content(App $a) if (!$r) { notice(L10n::t('Permission denied.')); - goaway($_SESSION['return_url']); + goaway($return_url); // NOTREACHED } diff --git a/mod/fsuggest.php b/mod/fsuggest.php index 8fc0f07dee..35710bb338 100644 --- a/mod/fsuggest.php +++ b/mod/fsuggest.php @@ -36,7 +36,7 @@ function fsuggest_post(App $a) $hash = random_string(); - $note = escape_tags(trim($_POST['note'])); + $note = escape_tags(trim(defaults($_POST, 'note', ''))); if ($new_contact) { $r = q("SELECT * FROM `contact` WHERE `id` = %d AND `uid` = %d LIMIT 1", diff --git a/mod/group.php b/mod/group.php index 8f65eb643d..f8fefc78f9 100644 --- a/mod/group.php +++ b/mod/group.php @@ -11,12 +11,12 @@ use Friendica\Core\L10n; use Friendica\Core\PConfig; use Friendica\Core\System; use Friendica\Database\DBA; -use Friendica\Model\Contact; -use Friendica\Model\Group; +use Friendica\Model; +use Friendica\Module; function group_init(App $a) { if (local_user()) { - $a->page['aside'] = Group::sidebarWidget('contacts', 'group', 'extended', (($a->argc > 1) ? $a->argv[1] : 'everyone')); + $a->page['aside'] = Model\Group::sidebarWidget('contacts', 'group', 'extended', (($a->argc > 1) ? $a->argv[1] : 'everyone')); } } @@ -31,10 +31,10 @@ function group_post(App $a) { check_form_security_token_redirectOnErr('/group/new', 'group_edit'); $name = notags(trim($_POST['groupname'])); - $r = Group::create(local_user(), $name); + $r = Model\Group::create(local_user(), $name); if ($r) { info(L10n::t('Group created.') . EOL); - $r = Group::getIdByName(local_user(), $name); + $r = Model\Group::getIdByName(local_user(), $name); if ($r) { goaway(System::baseUrl() . '/group/' . $r); } @@ -54,7 +54,7 @@ function group_post(App $a) { ); if (!DBA::isResult($r)) { notice(L10n::t('Group not found.') . EOL); - goaway(System::baseUrl() . '/contacts'); + goaway(System::baseUrl() . '/contact'); return; // NOTREACHED } $group = $r[0]; @@ -71,7 +71,7 @@ function group_post(App $a) { } } - $a->page['aside'] = Group::sidebarWidget(); + $a->page['aside'] = Model\Group::sidebarWidget(); } return; } @@ -116,8 +116,6 @@ function group_content(App $a) { $nogroup = false; if (($a->argc == 2) && ($a->argv[1] === 'none')) { - require_once 'mod/contacts.php'; - $id = -1; $nogroup = true; $group = [ @@ -150,7 +148,7 @@ function group_content(App $a) { $result = null; if (DBA::isResult($r)) { - $result = Group::removeByName(local_user(), $r[0]['name']); + $result = Model\Group::removeByName(local_user(), $r[0]['name']); } if ($result) { @@ -176,8 +174,6 @@ function group_content(App $a) { } if (($a->argc > 1) && intval($a->argv[1])) { - require_once 'mod/contacts.php'; - $r = q("SELECT * FROM `group` WHERE `id` = %d AND `uid` = %d AND `deleted` = 0 LIMIT 1", intval($a->argv[1]), intval(local_user()) @@ -185,11 +181,11 @@ function group_content(App $a) { if (!DBA::isResult($r)) { notice(L10n::t('Group not found.') . EOL); - goaway(System::baseUrl() . '/contacts'); + goaway(System::baseUrl() . '/contact'); } $group = $r[0]; - $members = Contact::getByGroupId($group['id']); + $members = Model\Contact::getByGroupId($group['id']); $preselected = []; $entry = []; $id = 0; @@ -202,12 +198,12 @@ function group_content(App $a) { if ($change) { if (in_array($change, $preselected)) { - Group::removeMember($group['id'], $change); + Model\Group::removeMember($group['id'], $change); } else { - Group::addMember($group['id'], $change); + Model\Group::addMember($group['id'], $change); } - $members = Contact::getByGroupId($group['id']); + $members = Model\Contact::getByGroupId($group['id']); $preselected = []; if (count($members)) { foreach ($members as $member) { @@ -253,7 +249,7 @@ function group_content(App $a) { // Format the data of the group members foreach ($members as $member) { if ($member['url']) { - $entry = _contact_detail_for_template($member); + $entry = Module\Contact::getContactTemplateVars($member); $entry['label'] = 'members'; $entry['photo_menu'] = ''; $entry['change_member'] = [ @@ -265,12 +261,12 @@ function group_content(App $a) { $groupeditor['members'][] = $entry; } else { - Group::removeMember($group['id'], $member['id']); + Model\Group::removeMember($group['id'], $member['id']); } } if ($nogroup) { - $r = Contact::getUngroupedList(local_user()); + $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()) @@ -282,7 +278,7 @@ function group_content(App $a) { // Format the data of the contacts who aren't in the contact group foreach ($r as $member) { if (!in_array($member['id'], $preselected)) { - $entry = _contact_detail_for_template($member); + $entry = Module\Contact::getContactTemplateVars($member); $entry['label'] = 'contacts'; if (!$nogroup) $entry['photo_menu'] = []; diff --git a/mod/hcard.php b/mod/hcard.php index 0c046da540..7e5c2cc08a 100644 --- a/mod/hcard.php +++ b/mod/hcard.php @@ -50,7 +50,7 @@ function hcard_init(App $a) $a->page['htmlhead'] .= '' . "\r\n" ; $a->page['htmlhead'] .= '' . "\r\n" ; - $uri = urlencode('acct:' . $a->profile['nickname'] . '@' . $a->get_hostname() . (($a->urlpath) ? '/' . $a->urlpath : '')); + $uri = urlencode('acct:' . $a->profile['nickname'] . '@' . $a->getHostName() . (($a->getURLPath()) ? '/' . $a->getURLPath() : '')); $a->page['htmlhead'] .= '' . "\r\n"; header('Link: <' . System::baseUrl() . '/xrd/?uri=' . $uri . '>; rel="lrdd"; type="application/xrd+xml"', false); diff --git a/mod/help.php b/mod/help.php index 5db74c15e8..53118544fb 100644 --- a/mod/help.php +++ b/mod/help.php @@ -36,12 +36,12 @@ function help_content(App $a) $path = ''; // looping through the argv keys bigger than 0 to build // a path relative to /help - for ($x = 1; $x < argc(); $x ++) { + for ($x = 1; $x < $a->argc; $x ++) { if (strlen($path)) { $path .= '/'; } - $path .= argv($x); + $path .= $a->getArgumentValue($x); } $title = basename($path); $filename = $path; diff --git a/mod/home.php b/mod/home.php index d28bf3cb43..33d736a4e1 100644 --- a/mod/home.php +++ b/mod/home.php @@ -38,8 +38,8 @@ function home_content(App $a) { $customhome = false; $defaultheader = '

    ' . (Config::get('config', 'sitename') ? L10n::t('Welcome to %s', Config::get('config', 'sitename')) : '') . '

    '; - $homefilepath = $a->basepath . "/home.html"; - $cssfilepath = $a->basepath . "/home.css"; + $homefilepath = $a->getBasePath() . "/home.html"; + $cssfilepath = $a->getBasePath() . "/home.css"; if (file_exists($homefilepath)) { $customhome = $homefilepath; if (file_exists($cssfilepath)) { diff --git a/mod/hostxrd.php b/mod/hostxrd.php index 16f132fe09..30343381c3 100644 --- a/mod/hostxrd.php +++ b/mod/hostxrd.php @@ -23,7 +23,7 @@ function hostxrd_init(App $a) $tpl = get_markup_template('xrd_host.tpl'); echo replace_macros($tpl, [ - '$zhost' => $a->get_hostname(), + '$zhost' => $a->getHostName(), '$zroot' => System::baseUrl(), '$domain' => System::baseUrl(), '$bigkey' => Salmon::salmonKey(Config::get('system', 'site_pubkey'))] diff --git a/mod/install.php b/mod/install.php index d2d322b3b9..5a0794b354 100644 --- a/mod/install.php +++ b/mod/install.php @@ -8,6 +8,7 @@ use Friendica\Core\Install; use Friendica\Core\L10n; use Friendica\Core\System; use Friendica\Database\DBA; +use Friendica\Database\DBStructure; use Friendica\Util\Temporal; $install_wizard_pass = 1; @@ -42,7 +43,6 @@ function install_post(App $a) { return; break; // just in case return don't return :) case 3: - $urlpath = $a->get_path(); $dbhost = notags(trim($_POST['dbhost'])); $dbuser = notags(trim($_POST['dbuser'])); $dbpass = notags(trim($_POST['dbpass'])); @@ -57,7 +57,7 @@ function install_post(App $a) { return; break; case 4: - $urlpath = $a->get_path(); + $urlpath = $a->getURLPath(); $dbhost = notags(trim($_POST['dbhost'])); $dbuser = notags(trim($_POST['dbuser'])); $dbpass = notags(trim($_POST['dbpass'])); @@ -70,14 +70,16 @@ function install_post(App $a) { // connect to db DBA::connect($dbhost, $dbuser, $dbpass, $dbdata); - $errors = Install::createConfig($urlpath, $dbhost, $dbuser, $dbpass, $dbdata, $phpath, $timezone, $language, $adminmail); + $install = new Install(); - if ($errors) { - $a->data['db_failed'] = $errors; + $errors = $install->createConfig($phpath, $urlpath, $dbhost, $dbuser, $dbpass, $dbdata, $timezone, $language, $adminmail, $a->getBasePath()); + + if ($errors !== true) { + $a->data['data'] = $errors; return; } - $errors = Install::installDatabaseStructure(); + $errors = DBStructure::update(false, true, true); if ($errors) { $a->data['db_failed'] = $errors; @@ -97,8 +99,6 @@ function install_content(App $a) { $wizard_status = ""; $install_title = L10n::t('Friendica Communications Server - Setup'); - - if (x($a->data, 'db_conn_failed')) { $install_wizard_pass = 2; $wizard_status = L10n::t('Could not connect to database.'); @@ -125,13 +125,8 @@ function install_content(App $a) { if (DBA::$connected) { $r = q("SELECT COUNT(*) as `total` FROM `user`"); if (DBA::isResult($r) && $r[0]['total']) { - $tpl = get_markup_template('install.tpl'); - return replace_macros($tpl, [ - '$title' => $install_title, - '$pass' => '', - '$status' => L10n::t('Database already in use.'), - '$text' => '', - ]); + $install_wizard_pass = 2; + $wizard_status = L10n::t('Database already in use.'); } } @@ -153,19 +148,21 @@ function install_content(App $a) { $phpath = defaults($_POST, 'phpath', 'php'); - list($checks, $checkspassed) = Install::check($phpath); + $install = new Install($phpath); + + $status = $install->checkAll($a->getBasePath(), $a->getBaseURL()); $tpl = get_markup_template('install_checks.tpl'); $o .= replace_macros($tpl, [ '$title' => $install_title, '$pass' => L10n::t('System check'), - '$checks' => $checks, - '$passed' => $checkspassed, + '$checks' => $install->getChecks(), + '$passed' => $status, '$see_install' => L10n::t('Please see the file "INSTALL.txt".'), '$next' => L10n::t('Next'), '$reload' => L10n::t('Check again'), '$phpath' => $phpath, - '$baseurl' => System::baseUrl(), + '$baseurl' => $a->getBaseURL(), ]); return $o; }; break; @@ -197,7 +194,7 @@ function install_content(App $a) { '$lbl_10' => L10n::t('Please select a default timezone for your website'), - '$baseurl' => System::baseUrl(), + '$baseurl' => $a->getBaseURL(), '$phpath' => $phpath, @@ -235,9 +232,7 @@ function install_content(App $a) { '$timezone' => Temporal::getTimezoneField('timezone', L10n::t('Please select a default timezone for your website'), $timezone, ''), '$language' => ['language', L10n::t('System Language:'), 'en', L10n::t('Set the default language for your Friendica installation interface and to send emails.'), $lang_choices], - '$baseurl' => System::baseUrl(), - - + '$baseurl' => $a->getBaseURL(), '$submit' => L10n::t('Submit'), diff --git a/mod/invite.php b/mod/invite.php index 2a98d19ffc..7318b77ae9 100644 --- a/mod/invite.php +++ b/mod/invite.php @@ -58,14 +58,9 @@ function invite_post(App $a) } if ($invitation_only && ($invites_remaining || is_site_admin())) { - $code = autoname(8) . srand(1000, 9999); + $code = Friendica\Model\Register::createForInvitation(); $nmessage = str_replace('$invite_code', $code, $message); - $r = q("INSERT INTO `register` (`hash`,`created`) VALUES ('%s', '%s') ", - DBA::escape($code), - DBA::escape(DateTimeFormat::utcNow()) - ); - if (! is_site_admin()) { $invites_remaining --; if ($invites_remaining >= 0) { diff --git a/mod/item.php b/mod/item.php index 733c6aee85..4d798ac1e5 100644 --- a/mod/item.php +++ b/mod/item.php @@ -39,7 +39,7 @@ require_once 'include/items.php'; function item_post(App $a) { if (!local_user() && !remote_user()) { - return; + return 0; } require_once 'include/security.php'; @@ -154,12 +154,12 @@ function item_post(App $a) { if (($message_id != '') && ($profile_uid != 0)) { if (Item::exists(['uri' => $message_id, 'uid' => $profile_uid])) { logger("Message with URI ".$message_id." already exists for user ".$profile_uid, LOGGER_DEBUG); - return; + return 0; } } // 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::OSTATUS, Protocol::DIASPORA, Protocol::DFRN]); + $allow_comment = local_user() && ($profile_uid == 0) && $parent && in_array($parent_item['network'], [Protocol::ACTIVITYPUB, Protocol::OSTATUS, Protocol::DIASPORA, Protocol::DFRN]); // Now check that valid personal details have been provided if (!can_write_wall($profile_uid) && !$allow_comment) { @@ -183,7 +183,7 @@ function item_post(App $a) { $user = DBA::selectFirst('user', [], ['uid' => $profile_uid]); if (!DBA::isResult($user) && !$parent) { - return; + return 0; } $categories = ''; @@ -240,7 +240,7 @@ function item_post(App $a) { $emailcc = notags(trim(defaults($_REQUEST, 'emailcc' , ''))); $body = escape_tags(trim(defaults($_REQUEST, 'body' , ''))); $network = notags(trim(defaults($_REQUEST, 'network' , Protocol::DFRN))); - $guid = System::createGUID(32); + $guid = System::createUUID(); $postopts = defaults($_REQUEST, 'postopts', ''); @@ -343,20 +343,11 @@ function item_post(App $a) { $tags = get_tags($body); - // Add a tag if the parent contact is from OStatus (This will notify them during delivery) - if ($parent) { - if ($thr_parent_contact['network'] == Protocol::OSTATUS) { - $contact = '@[url=' . $thr_parent_contact['url'] . ']' . $thr_parent_contact['nick'] . '[/url]'; - if (!stripos(implode($tags), '[url=' . $thr_parent_contact['url'] . ']')) { - $tags[] = $contact; - } - } - - if ($parent_contact['network'] == Protocol::OSTATUS) { - $contact = '@[url=' . $parent_contact['url'] . ']' . $parent_contact['nick'] . '[/url]'; - if (!stripos(implode($tags), '[url=' . $parent_contact['url'] . ']')) { - $tags[] = $contact; - } + // 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; } } @@ -843,6 +834,10 @@ function item_post(App $a) { logger('post_complete'); + if ($api_source) { + return $post_id; + } + item_post_return(System::baseUrl(), $api_source, $return_path); // NOTREACHED } @@ -881,13 +876,13 @@ function item_content(App $a) $o = ''; if (($a->argc == 3) && ($a->argv[1] === 'drop') && intval($a->argv[2])) { - if (is_ajax()) { + if ($a->isAjax()) { $o = Item::deleteForUser(['id' => $a->argv[2]], local_user()); } else { $o = drop_item($a->argv[2]); } - if (is_ajax()) { + if ($a->isAjax()) { // ajax return: [, 0 (no perm) | ] echo json_encode([intval($a->argv[2]), intval($o)]); killme(); @@ -1020,12 +1015,7 @@ function handle_tag(App $a, &$body, &$inform, &$str_tags, $profile_uid, $tag, $n $profile = $contact["url"]; $alias = $contact["alias"]; - $newname = $contact["nick"]; - - if (($newname == "") || (($contact["network"] != Protocol::OSTATUS) && ($contact["network"] != Protocol::TWITTER) - && ($contact["network"] != Protocol::STATUSNET))) { - $newname = $contact["name"]; - } + $newname = defaults($contact, "name", $contact["nick"]); } //if there is an url for this persons profile diff --git a/mod/lockview.php b/mod/lockview.php index 893764c4d9..a2301b4ccb 100644 --- a/mod/lockview.php +++ b/mod/lockview.php @@ -8,27 +8,31 @@ use Friendica\Core\L10n; use Friendica\Database\DBA; use Friendica\Model\Item; -function lockview_content(App $a) { - +function lockview_content(App $a) +{ $type = (($a->argc > 1) ? $a->argv[1] : 0); if (is_numeric($type)) { $item_id = intval($type); - $type='item'; + $type = 'item'; } else { $item_id = (($a->argc > 2) ? intval($a->argv[2]) : 0); } - if (!$item_id) + if (!$item_id) { killme(); + } - if (!in_array($type, ['item','photo','event'])) + if (!in_array($type, ['item','photo','event'])) { killme(); + } - $fields = ['uid', 'private', 'allow_cid', 'allow_gid', 'deny_cid', 'deny_gid']; + $fields = ['uid', 'allow_cid', 'allow_gid', 'deny_cid', 'deny_gid']; $condition = ['id' => $item_id]; + if ($type != 'item') { $item = DBA::selectFirst($type, $fields, $condition); } else { + $fields[] = 'private'; $item = Item::selectFirst($fields, $condition); } @@ -43,18 +47,21 @@ function lockview_content(App $a) { killme(); } - - if (($item['private'] == 1) && empty($item['allow_cid']) && empty($item['allow_gid']) - && empty($item['deny_cid']) && empty($item['deny_gid'])) { - + if (isset($item['private']) + && $item['private'] == 1 + && empty($item['allow_cid']) + && empty($item['allow_gid']) + && empty($item['deny_cid']) + && empty($item['deny_gid'])) + { echo L10n::t('Remote privacy information not available.') . '
    '; killme(); } - $allowed_users = expand_acl($item['allow_cid']); + $allowed_users = expand_acl($item['allow_cid']); $allowed_groups = expand_acl($item['allow_gid']); - $deny_users = expand_acl($item['deny_cid']); - $deny_groups = expand_acl($item['deny_gid']); + $deny_users = expand_acl($item['deny_cid']); + $deny_groups = expand_acl($item['deny_gid']); $o = L10n::t('Visible to:') . '
    '; $l = []; @@ -63,36 +70,44 @@ function lockview_content(App $a) { $r = q("SELECT `name` FROM `group` WHERE `id` IN ( %s )", DBA::escape(implode(', ', $allowed_groups)) ); - if (DBA::isResult($r)) - foreach($r as $rr) + if (DBA::isResult($r)) { + foreach ($r as $rr) { $l[] = '' . $rr['name'] . ''; + } + } } + if (count($allowed_users)) { $r = q("SELECT `name` FROM `contact` WHERE `id` IN ( %s )", - DBA::escape(implode(', ',$allowed_users)) + DBA::escape(implode(', ', $allowed_users)) ); - if (DBA::isResult($r)) - foreach($r as $rr) + if (DBA::isResult($r)) { + foreach ($r as $rr) { $l[] = $rr['name']; - + } + } } if (count($deny_groups)) { $r = q("SELECT `name` FROM `group` WHERE `id` IN ( %s )", DBA::escape(implode(', ', $deny_groups)) ); - if (DBA::isResult($r)) - foreach($r as $rr) + if (DBA::isResult($r)) { + foreach ($r as $rr) { $l[] = '' . $rr['name'] . ''; + } + } } + if (count($deny_users)) { $r = q("SELECT `name` FROM `contact` WHERE `id` IN ( %s )", - DBA::escape(implode(', ',$deny_users)) + DBA::escape(implode(', ', $deny_users)) ); - if (DBA::isResult($r)) - foreach($r as $rr) + if (DBA::isResult($r)) { + foreach ($r as $rr) { $l[] = '' . $rr['name'] . ''; - + } + } } echo $o . implode(', ', $l); diff --git a/mod/match.php b/mod/match.php index caa4c944ca..7e805d5baf 100644 --- a/mod/match.php +++ b/mod/match.php @@ -59,16 +59,16 @@ function match_content(App $a) } if (strlen(Config::get('system', 'directory'))) { - $x = Network::post(get_server().'/msearch', $params); + $x = Network::post(get_server().'/msearch', $params)->getBody(); } else { - $x = Network::post(System::baseUrl() . '/msearch', $params); + $x = Network::post(System::baseUrl() . '/msearch', $params)->getBody(); } $j = json_decode($x); if ($j->total) { - $a->set_pager_total($j->total); - $a->set_pager_itemspage($j->items_page); + $a->setPagerTotal($j->total); + $a->setPagerItemsPage($j->items_page); } if (count($j->results)) { diff --git a/mod/message.php b/mod/message.php index 8c9aa657df..f9c5c29ec7 100644 --- a/mod/message.php +++ b/mod/message.php @@ -16,6 +16,7 @@ use Friendica\Model\Mail; use Friendica\Util\DateTimeFormat; use Friendica\Util\Proxy as ProxyUtils; use Friendica\Util\Temporal; +use Friendica\Module\Login; require_once 'include/conversation.php'; @@ -46,12 +47,6 @@ function message_init(App $a) '$baseurl' => System::baseUrl(true), '$base' => $base ]); - - $end_tpl = get_markup_template('message-end.tpl'); - $a->page['end'] .= replace_macros($end_tpl, [ - '$baseurl' => System::baseUrl(true), - '$base' => $base - ]); } function message_post(App $a) @@ -92,7 +87,7 @@ function message_post(App $a) $a->argc = 2; $a->argv[1] = 'new'; } else { - goaway($_SESSION['return_url']); + goaway($a->cmd . '/' . $ret); } } @@ -103,7 +98,7 @@ function message_content(App $a) if (!local_user()) { notice(L10n::t('Permission denied.') . EOL); - return; + return Login::form(); } $myprofile = System::baseUrl() . '/profile/' . $a->user['nickname']; @@ -160,17 +155,28 @@ function message_content(App $a) // Now check how the user responded to the confirmation query if (!empty($_REQUEST['canceled'])) { - goaway($_SESSION['return_url']); + goaway('/message'); } $cmd = $a->argv[1]; if ($cmd === 'drop') { + $message = DBA::selectFirst('mail', ['convid'], ['id' => $a->argv[2], 'uid' => local_user()]); + if(!DBA::isResult($message)){ + info(L10n::t('Conversation not found.') . EOL); + goaway('/message'); + } + if (DBA::delete('mail', ['id' => $a->argv[2], 'uid' => local_user()])) { info(L10n::t('Message deleted.') . EOL); } - //goaway(System::baseUrl(true) . '/message' ); - goaway($_SESSION['return_url']); + $conversation = DBA::selectFirst('mail', ['id'], ['convid' => $message['convid'], 'uid' => local_user()]); + if(!DBA::isResult($conversation)){ + info(L10n::t('Conversation removed.') . EOL); + goaway('/message'); + } + + goaway('/message/' . $conversation['id'] ); } else { $r = q("SELECT `parent-uri`,`convid` FROM `mail` WHERE `id` = %d AND `uid` = %d LIMIT 1", intval($a->argv[2]), @@ -184,8 +190,7 @@ function message_content(App $a) info(L10n::t('Conversation removed.') . EOL); } } - //goaway(System::baseUrl(true) . '/message' ); - goaway($_SESSION['return_url']); + goaway('/message' ); } } @@ -199,13 +204,6 @@ function message_content(App $a) '$linkurl' => L10n::t('Please enter a link URL:') ]); - $tpl = get_markup_template('msg-end.tpl'); - $a->page['end'] .= replace_macros($tpl, [ - '$baseurl' => System::baseUrl(true), - '$nickname' => $a->user['nickname'], - '$linkurl' => L10n::t('Please enter a link URL:') - ]); - $preselect = isset($a->argv[2]) ? [$a->argv[2]] : []; $prename = $preurl = $preid = ''; @@ -281,7 +279,7 @@ function message_content(App $a) ); if (DBA::isResult($r)) { - $a->set_pager_total($r[0]['total']); + $a->setPagerTotal($r[0]['total']); } $r = get_messages(local_user(), $a->pager['start'], $a->pager['itemspage']); @@ -344,13 +342,6 @@ function message_content(App $a) '$linkurl' => L10n::t('Please enter a link URL:') ]); - $tpl = get_markup_template('msg-end.tpl'); - $a->page['end'] .= replace_macros($tpl, [ - '$baseurl' => System::baseUrl(true), - '$nickname' => $a->user['nickname'], - '$linkurl' => L10n::t('Please enter a link URL:') - ]); - $mails = []; $seen = 0; $unknown = false; @@ -488,7 +479,7 @@ function render_messages(array $msg, $t) '$id' => $rr['id'], '$from_name' => $participants, '$from_url' => Contact::magicLink($rr['url']), - '$from_addr' => $contact['addr'], + '$from_addr' => defaults($contact, 'addr', ''), '$sparkle' => ' sparkle', '$from_photo' => ProxyUtils::proxifyUrl($from_photo, false, ProxyUtils::SIZE_THUMB), '$subject' => $subject_e, diff --git a/mod/network.php b/mod/network.php index c630beb25f..fb0093849e 100644 --- a/mod/network.php +++ b/mod/network.php @@ -302,7 +302,7 @@ function networkPager($a, $update) $itemspage_network = $a->force_max_items; } - $a->set_pager_itemspage($itemspage_network); + $a->setPagerItemsPage($itemspage_network); return sprintf(" LIMIT %d, %d ", intval($a->pager['start']), intval($a->pager['itemspage'])); } @@ -721,7 +721,7 @@ function networkThreadedView(App $a, $update, $parent) if ($last_received != '') { $last_date = $last_received; $sql_range .= sprintf(" AND $sql_table.`received` < '%s'", DBA::escape($last_received)); - $a->set_pager_page(1); + $a->setPagerPage(1); $pager_sql = sprintf(" LIMIT %d, %d ", intval($a->pager['start']), intval($a->pager['itemspage'])); } break; @@ -729,7 +729,7 @@ function networkThreadedView(App $a, $update, $parent) if ($last_commented != '') { $last_date = $last_commented; $sql_range .= sprintf(" AND $sql_table.`commented` < '%s'", DBA::escape($last_commented)); - $a->set_pager_page(1); + $a->setPagerPage(1); $pager_sql = sprintf(" LIMIT %d, %d ", intval($a->pager['start']), intval($a->pager['itemspage'])); } break; @@ -737,14 +737,14 @@ function networkThreadedView(App $a, $update, $parent) if ($last_created != '') { $last_date = $last_created; $sql_range .= sprintf(" AND $sql_table.`created` < '%s'", DBA::escape($last_created)); - $a->set_pager_page(1); + $a->setPagerPage(1); $pager_sql = sprintf(" LIMIT %d, %d ", intval($a->pager['start']), intval($a->pager['itemspage'])); } break; case 'id': if (($last_id > 0) && ($sql_table == '`thread`')) { $sql_range .= sprintf(" AND $sql_table.`iid` < '%s'", DBA::escape($last_id)); - $a->set_pager_page(1); + $a->setPagerPage(1); $pager_sql = sprintf(" LIMIT %d, %d ", intval($a->pager['start']), intval($a->pager['itemspage'])); } break; @@ -810,7 +810,7 @@ function networkThreadedView(App $a, $update, $parent) } // Only show it when unfiltered (no groups, no networks, ...) - if (in_array($nets, ['', Protocol::DFRN, Protocol::DIASPORA, Protocol::OSTATUS]) && (strlen($sql_extra . $sql_extra2 . $sql_extra3) == 0)) { + if (in_array($nets, ['', Protocol::ACTIVITYPUB, Protocol::DFRN, Protocol::DIASPORA, Protocol::OSTATUS]) && (strlen($sql_extra . $sql_extra2 . $sql_extra3) == 0)) { if (DBA::isResult($r)) { $top_limit = current($r)['order_date']; $bottom_limit = end($r)['order_date']; diff --git a/mod/newmember.php b/mod/newmember.php index b3bf310d5b..cd59cc780c 100644 --- a/mod/newmember.php +++ b/mod/newmember.php @@ -36,13 +36,13 @@ function newmember_content(App $a) $o .= '
  • ' . '' . L10n::t('Importing Emails') . '
    ' . L10n::t('Enter your email access information on your Connector Settings page if you wish to import and interact with friends or mailing lists from your email INBOX') . '
  • ' . EOL; } - $o .= '
  • ' . '' . L10n::t('Go to Your Contacts Page') . '
    ' . L10n::t('Your Contacts page is your gateway to managing friendships and connecting with friends on other networks. Typically you enter their address or site URL in the Add New Contact dialog.') . '
  • ' . EOL; + $o .= '
  • ' . '' . L10n::t('Go to Your Contacts Page') . '
    ' . L10n::t('Your Contacts page is your gateway to managing friendships and connecting with friends on other networks. Typically you enter their address or site URL in the Add New Contact dialog.') . '
  • ' . EOL; $o .= '
  • ' . '' . L10n::t("Go to Your Site's Directory") . '
    ' . L10n::t('The Directory page lets you find other people in this network or other federated sites. Look for a Connect or Follow link on their profile page. Provide your own Identity Address if requested.') . '
  • ' . EOL; - $o .= '
  • ' . '' . L10n::t('Finding New People') . '
    ' . L10n::t("On the side panel of the Contacts page are several tools to find new friends. We can match people by interest, look up people by name or interest, and provide suggestions based on network relationships. On a brand new site, friend suggestions will usually begin to be populated within 24 hours.") . '
  • ' . EOL; + $o .= '
  • ' . '' . L10n::t('Finding New People') . '
    ' . L10n::t("On the side panel of the Contacts page are several tools to find new friends. We can match people by interest, look up people by name or interest, and provide suggestions based on network relationships. On a brand new site, friend suggestions will usually begin to be populated within 24 hours.") . '
  • ' . EOL; $o .= ''; $o .= '

    ' . L10n::t('Groups') . '

    '; $o .= '
      '; - $o .= '
    • ' . '' . L10n::t('Group Your Contacts') . '
      ' . L10n::t('Once you have made some friends, organize them into private conversation groups from the sidebar of your Contacts page and then you can interact with each group privately on your Network page.') . '
    • ' . EOL; + $o .= '
    • ' . '' . L10n::t('Group Your Contacts') . '
      ' . L10n::t('Once you have made some friends, organize them into private conversation groups from the sidebar of your Contacts page and then you can interact with each group privately on your Network page.') . '
    • ' . EOL; if (Config::get('system', 'newuser_private')) { $o .= '
    • ' . '' . L10n::t("Why Aren't My Posts Public?") . '
      ' . L10n::t("Friendica respects your privacy. By default, your posts will only show up to people you've added as friends. For more information, see the help section from the link above.") . '
    • ' . EOL; diff --git a/mod/nodeinfo.php b/mod/nodeinfo.php index 072986cc5e..ed0166838f 100644 --- a/mod/nodeinfo.php +++ b/mod/nodeinfo.php @@ -215,7 +215,7 @@ function nodeinfo_cron() { logger('local_comments: ' . $local_comments, LOGGER_DEBUG); // Now trying to register - $url = 'http://the-federation.info/register/'.$a->get_hostname(); + $url = 'http://the-federation.info/register/'.$a->getHostName(); logger('registering url: '.$url, LOGGER_DEBUG); $ret = Network::fetchUrl($url); logger('registering answer: '.$ret, LOGGER_DEBUG); diff --git a/mod/notes.php b/mod/notes.php index 68a870e9d6..da8352966e 100644 --- a/mod/notes.php +++ b/mod/notes.php @@ -61,7 +61,7 @@ function notes_content(App $a, $update = false) $condition = ['uid' => local_user(), 'post-type' => Item::PT_PERSONAL_NOTE, 'gravity' => GRAVITY_PARENT, 'wall' => false, 'contact-id'=> $a->contact['id']]; - $a->set_pager_itemspage(40); + $a->setPagerItemsPage(40); $params = ['order' => ['created' => true], 'limit' => [$a->pager['start'], $a->pager['itemspage']]]; @@ -70,8 +70,11 @@ function notes_content(App $a, $update = false) $count = 0; if (DBA::isResult($r)) { - $count = count($r); - $o .= conversation($a, DBA::toArray($r), 'notes', $update); + $notes = DBA::toArray($r); + + $count = count($notes); + + $o .= conversation($a, $notes, 'notes', $update); } $o .= alt_pager($a, $count); diff --git a/mod/notifications.php b/mod/notifications.php index 145c384350..1885f96447 100644 --- a/mod/notifications.php +++ b/mod/notifications.php @@ -12,6 +12,7 @@ use Friendica\Core\NotificationsManager; use Friendica\Core\Protocol; use Friendica\Core\System; use Friendica\Database\DBA; +use Friendica\Module\Login; function notifications_post(App $a) { @@ -21,7 +22,7 @@ function notifications_post(App $a) $request_id = (($a->argc > 1) ? $a->argv[1] : 0); - if ($request_id === "all") { + if ($request_id === 'all') { return; } @@ -65,11 +66,11 @@ function notifications_content(App $a) { if (!local_user()) { notice(L10n::t('Permission denied.') . EOL); - return; + return Login::form(); } - $page = (x($_REQUEST,'page') ? $_REQUEST['page'] : 1); - $show = (x($_REQUEST,'show') ? $_REQUEST['show'] : 0); + $page = defaults($_REQUEST, 'page', 1); + $show = defaults($_REQUEST, 'show', 0); Nav::setSelected('notifications'); @@ -87,10 +88,11 @@ function notifications_content(App $a) $perpage = 20; $startrec = ($page * $perpage) - $perpage; + $notif_header = L10n::t('Notifications'); + // Get introductions if ((($a->argc > 1) && ($a->argv[1] == 'intros')) || (($a->argc == 1))) { Nav::setSelected('introductions'); - $notif_header = L10n::t('Notifications'); $all = (($a->argc > 2) && ($a->argv[2] == 'all')); @@ -115,12 +117,10 @@ function notifications_content(App $a) } elseif (($a->argc > 1) && ($a->argv[1] == 'home')) { $notif_header = L10n::t('Home Notifications'); $notifs = $nm->homeNotifs($show, $startrec, $perpage); - } - // Set the pager - $a->set_pager_itemspage($perpage); + $a->setPagerItemsPage($perpage); // Add additional informations (needed for json output) $notifs['items_page'] = $a->pager['itemspage']; @@ -133,14 +133,15 @@ function notifications_content(App $a) $notif_tpl = get_markup_template('notifications.tpl'); - if (!isset($notifs['ident'])) { - logger('Missing data in notifs: ' . System::callstack(20), LOGGER_DEBUG); - } + $notif_show_lnk = [ + 'href' => ($show ? 'notifications/' . $notifs['ident'] : 'notifications/' . $notifs['ident'] . '?show=all' ), + 'text' => ($show ? L10n::t('Show unread') : L10n::t('Show all')), + ]; // Process the data for template creation - if ($notifs['ident'] === 'introductions') { + if (defaults($notifs, 'ident', '') === 'introductions') { $sugg = get_markup_template('suggestions.tpl'); - $tpl = get_markup_template("intros.tpl"); + $tpl = get_markup_template('intros.tpl'); // The link to switch between ignored and normal connection requests $notif_show_lnk = [ @@ -150,127 +151,121 @@ function notifications_content(App $a) // Loop through all introduction notifications.This creates an array with the output html for each // introduction - foreach ($notifs['notifications'] as $it) { + foreach ($notifs['notifications'] as $notif) { // There are two kind of introduction. Contacts suggested by other contacts and normal connection requests. // We have to distinguish between these two because they use different data. - switch ($it['label']) { + switch ($notif['label']) { case 'friend_suggestion': $notif_content[] = replace_macros($sugg, [ - '$type' => $it['label'], + '$type' => $notif['label'], '$str_notifytype' => L10n::t('Notification type:'), - '$notify_type' => $it['notify_type'], - '$intro_id' => $it['intro_id'], + '$notify_type'=> $notif['notify_type'], + '$intro_id' => $notif['intro_id'], '$lbl_madeby' => L10n::t('Suggested by:'), - '$madeby' => $it['madeby'], - '$madeby_url' => $it['madeby_url'], - '$madeby_zrl' => $it['madeby_zrl'], - '$madeby_addr' => $it['madeby_addr'], - '$contact_id' => $it['contact_id'], - '$photo' => $it['photo'], - '$fullname' => $it['name'], - '$url' => $it['url'], - '$zrl' => $it['zrl'], - '$lbl_url' => L10n::t('Profile URL'), - '$addr' => $it['addr'], - '$hidden' => ['hidden', L10n::t('Hide this contact from others'), ($it['hidden'] == 1), ''], - - '$knowyou' => $it['knowyou'], - '$approve' => L10n::t('Approve'), - '$note' => $it['note'], - '$request' => $it['request'], - '$ignore' => L10n::t('Ignore'), - '$discard' => L10n::t('Discard'), + '$madeby' => $notif['madeby'], + '$madeby_url' => $notif['madeby_url'], + '$madeby_zrl' => $notif['madeby_zrl'], + '$madeby_addr'=> $notif['madeby_addr'], + '$contact_id' => $notif['contact_id'], + '$photo' => $notif['photo'], + '$fullname' => $notif['name'], + '$url' => $notif['url'], + '$zrl' => $notif['zrl'], + '$lbl_url' => L10n::t('Profile URL'), + '$addr' => $notif['addr'], + '$hidden' => ['hidden', L10n::t('Hide this contact from others'), ($notif['hidden'] == 1), ''], + '$knowyou' => $notif['knowyou'], + '$approve' => L10n::t('Approve'), + '$note' => $notif['note'], + '$request' => $notif['request'], + '$ignore' => L10n::t('Ignore'), + '$discard' => L10n::t('Discard'), ]); break; // Normal connection requests default: - $friend_selected = (($it['network'] !== Protocol::OSTATUS) ? ' checked="checked" ' : ' disabled '); - $fan_selected = (($it['network'] === Protocol::OSTATUS) ? ' checked="checked" disabled ' : ''); - $dfrn_tpl = get_markup_template('netfriend.tpl'); + $friend_selected = (($notif['network'] !== Protocol::OSTATUS) ? ' checked="checked" ' : ' disabled '); + $fan_selected = (($notif['network'] === Protocol::OSTATUS) ? ' checked="checked" disabled ' : ''); - $knowyou = ''; $lbl_knowyou = ''; - $dfrn_text = ''; - $helptext = ''; - $helptext2 = ''; - $helptext3 = ''; + $knowyou = ''; + $helptext = ''; + $helptext2 = ''; + $helptext3 = ''; - if ($it['network'] === Protocol::DFRN || $it['network'] === Protocol::DIASPORA) { - if ($it['network'] === Protocol::DFRN) { - $lbl_knowyou = L10n::t('Claims to be known to you: '); - $knowyou = (($it['knowyou']) ? L10n::t('yes') : L10n::t('no')); - $helptext = L10n::t('Shall your connection be bidirectional or not?'); - $helptext2 = L10n::t('Accepting %s as a friend allows %s to subscribe to your posts, and you will also receive updates from them in your news feed.', $it['name'], $it['name']); - $helptext3 = L10n::t('Accepting %s as a subscriber allows them to subscribe to your posts, but you will not receive updates from them in your news feed.', $it['name']); - } else { - $knowyou = ''; - $helptext = L10n::t('Shall your connection be bidirectional or not?'); - $helptext2 = L10n::t('Accepting %s as a friend allows %s to subscribe to your posts, and you will also receive updates from them in your news feed.', $it['name'], $it['name']); - $helptext3 = L10n::t('Accepting %s as a sharer allows them to subscribe to your posts, but you will not receive updates from them in your news feed.', $it['name']); - } + if ($notif['network'] === Protocol::DFRN) { + $lbl_knowyou = L10n::t('Claims to be known to you: '); + $knowyou = (($notif['knowyou']) ? L10n::t('yes') : L10n::t('no')); + $helptext = L10n::t('Shall your connection be bidirectional or not?'); + $helptext2 = L10n::t('Accepting %s as a friend allows %s to subscribe to your posts, and you will also receive updates from them in your news feed.', $notif['name'], $notif['name']); + $helptext3 = L10n::t('Accepting %s as a subscriber allows them to subscribe to your posts, but you will not receive updates from them in your news feed.', $notif['name']); + } elseif ($notif['network'] === Protocol::DIASPORA) { + $helptext = L10n::t('Shall your connection be bidirectional or not?'); + $helptext2 = L10n::t('Accepting %s as a friend allows %s to subscribe to your posts, and you will also receive updates from them in your news feed.', $notif['name'], $notif['name']); + $helptext3 = L10n::t('Accepting %s as a sharer allows them to subscribe to your posts, but you will not receive updates from them in your news feed.', $notif['name']); } - $dfrn_text = replace_macros($dfrn_tpl,[ - '$intro_id' => $it['intro_id'], + $dfrn_tpl = get_markup_template('netfriend.tpl'); + $dfrn_text = replace_macros($dfrn_tpl, [ + '$intro_id' => $notif['intro_id'], '$friend_selected' => $friend_selected, - '$fan_selected' => $fan_selected, + '$fan_selected'=> $fan_selected, '$approve_as1' => $helptext, '$approve_as2' => $helptext2, '$approve_as3' => $helptext3, - '$as_friend' => L10n::t('Friend'), - '$as_fan' => (($it['network'] == Protocol::DIASPORA) ? L10n::t('Sharer') : L10n::t('Subscriber')) + '$as_friend' => L10n::t('Friend'), + '$as_fan' => (($notif['network'] == Protocol::DIASPORA) ? L10n::t('Sharer') : L10n::t('Subscriber')) ]); - $header = $it["name"]; + $header = $notif['name']; - if ($it["addr"] != "") { - $header .= " <".$it["addr"].">"; + if ($notif['addr'] != '') { + $header .= ' <' . $notif['addr'] . '>'; } - $header .= " (".ContactSelector::networkToName($it['network'], $it['url']).")"; + $header .= ' (' . ContactSelector::networkToName($notif['network'], $notif['url']) . ')'; - if ($it['network'] != Protocol::DIASPORA) { + if ($notif['network'] != Protocol::DIASPORA) { $discard = L10n::t('Discard'); } else { $discard = ''; } $notif_content[] = replace_macros($tpl, [ - '$type' => $it['label'], - '$header' => htmlentities($header), + '$type' => $notif['label'], + '$header' => htmlentities($header), '$str_notifytype' => L10n::t('Notification type:'), - '$notify_type' => $it['notify_type'], - '$dfrn_text' => $dfrn_text, - '$dfrn_id' => $it['dfrn_id'], - '$uid' => $it['uid'], - '$intro_id' => $it['intro_id'], - '$contact_id' => $it['contact_id'], - '$photo' => $it['photo'], - '$fullname' => $it['name'], - '$location' => $it['location'], - '$lbl_location' => L10n::t('Location:'), - '$about' => $it['about'], - '$lbl_about' => L10n::t('About:'), - '$keywords' => $it['keywords'], - '$lbl_keywords' => L10n::t('Tags:'), - '$gender' => $it['gender'], - '$lbl_gender' => L10n::t('Gender:'), - '$hidden' => ['hidden', L10n::t('Hide this contact from others'), ($it['hidden'] == 1), ''], - '$url' => $it['url'], - '$zrl' => $it['zrl'], - '$lbl_url' => L10n::t('Profile URL'), - '$addr' => $it['addr'], + '$notify_type' => $notif['notify_type'], + '$dfrn_text' => $dfrn_text, + '$dfrn_id' => $notif['dfrn_id'], + '$uid' => $notif['uid'], + '$intro_id' => $notif['intro_id'], + '$contact_id' => $notif['contact_id'], + '$photo' => $notif['photo'], + '$fullname' => $notif['name'], + '$location' => $notif['location'], + '$lbl_location'=> L10n::t('Location:'), + '$about' => $notif['about'], + '$lbl_about' => L10n::t('About:'), + '$keywords' => $notif['keywords'], + '$lbl_keywords'=> L10n::t('Tags:'), + '$gender' => $notif['gender'], + '$lbl_gender' => L10n::t('Gender:'), + '$hidden' => ['hidden', L10n::t('Hide this contact from others'), ($notif['hidden'] == 1), ''], + '$url' => $notif['url'], + '$zrl' => $notif['zrl'], + '$lbl_url' => L10n::t('Profile URL'), + '$addr' => $notif['addr'], '$lbl_knowyou' => $lbl_knowyou, '$lbl_network' => L10n::t('Network:'), - '$network' => ContactSelector::networkToName($it['network'], $it['url']), - '$knowyou' => $knowyou, - '$approve' => L10n::t('Approve'), - '$note' => $it['note'], - '$ignore' => L10n::t('Ignore'), - '$discard' => $discard, - + '$network' => ContactSelector::networkToName($notif['network'], $notif['url']), + '$knowyou' => $knowyou, + '$approve' => L10n::t('Approve'), + '$note' => $notif['note'], + '$ignore' => L10n::t('Ignore'), + '$discard' => $discard, ]); break; } @@ -280,57 +275,47 @@ function notifications_content(App $a) info(L10n::t('No introductions.') . EOL); } - // Normal notifications (no introductions) - } else { - // The template files we need in different cases for formatting the content - $tpl_item_like = 'notifications_likes_item.tpl'; - $tpl_item_dislike = 'notifications_dislikes_item.tpl'; - $tpl_item_attend = 'notifications_attend_item.tpl'; - $tpl_item_attendno = 'notifications_attend_item.tpl'; - $tpl_item_attendmaybe = 'notifications_attend_item.tpl'; - $tpl_item_friend = 'notifications_friends_item.tpl'; - $tpl_item_comment = 'notifications_comments_item.tpl'; - $tpl_item_post = 'notifications_posts_item.tpl'; - $tpl_item_notify = 'notify.tpl'; - + // Normal notifications (no introductions) + } elseif (!empty($notifs['notifications'])) { // Loop trough ever notification This creates an array with the output html for each // notification and apply the correct template according to the notificationtype (label). - foreach ($notifs['notifications'] as $it) { + foreach ($notifs['notifications'] as $notif) { + $notification_templates = [ + 'like' => 'notifications_likes_item.tpl', + 'dislike' => 'notifications_dislikes_item.tpl', + 'attend' => 'notifications_attend_item.tpl', + 'attendno' => 'notifications_attend_item.tpl', + 'attendmaybe' => 'notifications_attend_item.tpl', + 'friend' => 'notifications_friends_item.tpl', + 'comment' => 'notifications_comments_item.tpl', + 'post' => 'notifications_posts_item.tpl', + 'notify' => 'notify.tpl', + ]; - // We use the notification label to get the correct template file - $tpl_var_name = 'tpl_item_'.$it['label']; - $tpl_notif = get_markup_template($$tpl_var_name); + $tpl_notif = get_markup_template($notification_templates[$notif['label']]); - $notif_content[] = replace_macros($tpl_notif,[ - '$item_label' => $it['label'], - '$item_link' => $it['link'], - '$item_image' => $it['image'], - '$item_url' => $it['url'], - '$item_text' => $it['text'], - '$item_when' => $it['when'], - '$item_ago' => $it['ago'], - '$item_seen' => $it['seen'], + $notif_content[] = replace_macros($tpl_notif, [ + '$item_label' => $notif['label'], + '$item_link' => $notif['link'], + '$item_image' => $notif['image'], + '$item_url' => $notif['url'], + '$item_text' => $notif['text'], + '$item_when' => $notif['when'], + '$item_ago' => $notif['ago'], + '$item_seen' => $notif['seen'], ]); } - - $notif_show_lnk = [ - 'href' => ($show ? 'notifications/'.$notifs['ident'] : 'notifications/'.$notifs['ident'].'?show=all' ), - 'text' => ($show ? L10n::t('Show unread') : L10n::t('Show all')), - ]; - - // Output if there aren't any notifications available - if (count($notifs['notifications']) == 0) { - $notif_nocontent = L10n::t('No more %s notifications.', $notifs['ident']); - } + } else { + $notif_nocontent = L10n::t('No more %s notifications.', $notifs['ident']); } $o .= replace_macros($notif_tpl, [ - '$notif_header' => $notif_header, - '$tabs' => $tabs, - '$notif_content' => $notif_content, + '$notif_header' => $notif_header, + '$tabs' => $tabs, + '$notif_content' => $notif_content, '$notif_nocontent' => $notif_nocontent, - '$notif_show_lnk' => $notif_show_lnk, - '$notif_paginate' => alt_pager($a, count($notif_content)) + '$notif_show_lnk' => $notif_show_lnk, + '$notif_paginate' => alt_pager($a, count($notif_content)) ]); return $o; diff --git a/mod/notify.php b/mod/notify.php index 458d0140a6..a277e59813 100644 --- a/mod/notify.php +++ b/mod/notify.php @@ -27,7 +27,7 @@ function notify_init(App $a) $nm->setSeen($note); // The friendica client has problems with the GUID. this is some workaround - if ($a->is_friendica_app()) { + if ($a->isFriendicaApp()) { require_once("include/items.php"); $urldata = parse_url($note['link']); $guid = basename($urldata["path"]); diff --git a/mod/openid.php b/mod/openid.php index 41d45c1f60..63b29684b3 100644 --- a/mod/openid.php +++ b/mod/openid.php @@ -19,7 +19,7 @@ function openid_content(App $a) { if((x($_GET,'openid_mode')) && (x($_SESSION,'openid'))) { - $openid = new LightOpenID($a->get_hostname()); + $openid = new LightOpenID($a->getHostName()); if($openid->validate()) { diff --git a/mod/opensearch.php b/mod/opensearch.php index 8a427908bc..5410024100 100644 --- a/mod/opensearch.php +++ b/mod/opensearch.php @@ -11,7 +11,7 @@ function opensearch_content(App $a) { $o = replace_macros($tpl, [ '$baseurl' => System::baseUrl(), - '$nodename' => $a->get_hostname(), + '$nodename' => $a->getHostName(), ]); echo $o; diff --git a/mod/ostatus_subscribe.php b/mod/ostatus_subscribe.php index 987f31699e..7012ecd4bc 100644 --- a/mod/ostatus_subscribe.php +++ b/mod/ostatus_subscribe.php @@ -15,7 +15,7 @@ function ostatus_subscribe_content(App $a) { if (! local_user()) { notice(L10n::t('Permission denied.') . EOL); - goaway($_SESSION['return_url']); + goaway('/ostatus_subscribe'); // NOTREACHED } @@ -44,14 +44,14 @@ function ostatus_subscribe_content(App $a) { $api = $contact["baseurl"]."/api/"; // Fetching friends - $data = Network::curl($api."statuses/friends.json?screen_name=".$contact["nick"]); + $curlResult = Network::curl($api."statuses/friends.json?screen_name=".$contact["nick"]); - if (!$data["success"]) { + if (!$curlResult->isSuccess()) { PConfig::delete($uid, "ostatus", "legacy_contact"); return $o.L10n::t("Couldn't fetch friends for contact."); } - PConfig::set($uid, "ostatus", "legacy_friends", $data["body"]); + PConfig::set($uid, "ostatus", "legacy_friends", $curlResult->getBody()); } $friends = json_decode(PConfig::get($uid, "ostatus", "legacy_friends")); @@ -72,8 +72,8 @@ function ostatus_subscribe_content(App $a) { $o .= "

      ".$counter."/".$total.": ".$url; - $data = Probe::uri($url); - if ($data["network"] == Protocol::OSTATUS) { + $curlResult = Probe::uri($url); + if ($curlResult["network"] == Protocol::OSTATUS) { $result = Contact::createFromProbe($uid, $url, true, Protocol::OSTATUS); if ($result["success"]) { $o .= " - ".L10n::t("success"); diff --git a/mod/parse_url.php b/mod/parse_url.php index 3309a74b9f..a14379e709 100644 --- a/mod/parse_url.php +++ b/mod/parse_url.php @@ -8,128 +8,128 @@ * information and does format this information to BBCode * * @see ParseUrl::getSiteinfo() for more information about scraping embeddable content -*/ - + */ use Friendica\App; use Friendica\Core\Addon; use Friendica\Util\Network; use Friendica\Util\ParseUrl; -require_once("include/items.php"); - -function parse_url_content(App $a) { +require_once 'include/items.php'; +function parse_url_content(App $a) +{ $text = null; - $str_tags = ""; + $str_tags = ''; $br = "\n"; - if (!empty($_GET["binurl"])) { - $url = trim(hex2bin($_GET["binurl"])); + if (!empty($_GET['binurl'])) { + $url = trim(hex2bin($_GET['binurl'])); } else { - $url = trim($_GET["url"]); + $url = trim($_GET['url']); } - if (!empty($_GET["title"])) { - $title = strip_tags(trim($_GET["title"])); + if (!empty($_GET['title'])) { + $title = strip_tags(trim($_GET['title'])); } - if (!empty($_GET["description"])) { - $text = strip_tags(trim($_GET["description"])); + if (!empty($_GET['description'])) { + $text = strip_tags(trim($_GET['description'])); } - if (!empty($_GET["tags"])) { - $arr_tags = ParseUrl::convertTagsToArray($_GET["tags"]); + if (!empty($_GET['tags'])) { + $arr_tags = ParseUrl::convertTagsToArray($_GET['tags']); if (count($arr_tags)) { - $str_tags = $br . implode(" ", $arr_tags) . $br; + $str_tags = $br . implode(' ', $arr_tags) . $br; } } // Add url scheme if it is missing $arrurl = parse_url($url); - if (!x($arrurl, "scheme")) { - if (x($arrurl, "host")) { - $url = "http:".$url; + if (!x($arrurl, 'scheme')) { + if (x($arrurl, 'host')) { + $url = 'http:' . $url; } else { - $url = "http://".$url; + $url = 'http://' . $url; } } - logger("prse_url: " . $url); + logger($url); // Check if the URL is an image, video or audio file. If so format // the URL with the corresponding BBCode media tag $redirects = 0; // Fetch the header of the URL - $result = Network::curl($url, false, $redirects, ["novalidate" => true, "nobody" => true]); - if($result["success"]) { + $curlResponse = Network::curl($url, false, $redirects, ['novalidate' => true, 'nobody' => true]); + + if ($curlResponse->isSuccess()) { // Convert the header fields into an array $hdrs = []; - $h = explode("\n", $result["header"]); + $h = explode("\n", $curlResponse->getHeader()); foreach ($h as $l) { - $header = array_map("trim", explode(":", trim($l), 2)); + $header = array_map('trim', explode(':', trim($l), 2)); if (count($header) == 2) { - list($k,$v) = $header; + list($k, $v) = $header; $hdrs[$k] = $v; } } - if (array_key_exists("Content-Type", $hdrs)) { - $type = $hdrs["Content-Type"]; + $type = null; + if (array_key_exists('Content-Type', $hdrs)) { + $type = $hdrs['Content-Type']; } if ($type) { - if(stripos($type, "image/") !== false) { - echo $br . "[img]" . $url . "[/img]" . $br; - killme(); + if (stripos($type, 'image/') !== false) { + echo $br . '[img]' . $url . '[/img]' . $br; + exit(); } - if (stripos($type, "video/") !== false) { - echo $br . "[video]" . $url . "[/video]" . $br; - killme(); + if (stripos($type, 'video/') !== false) { + echo $br . '[video]' . $url . '[/video]' . $br; + exit(); } - if (stripos($type, "audio/") !== false) { - echo $br . "[audio]" . $url . "[/audio]" . $br; - killme(); + if (stripos($type, 'audio/') !== false) { + echo $br . '[audio]' . $url . '[/audio]' . $br; + exit(); } } } - $template = "[bookmark=%s]%s[/bookmark]%s"; + $template = '[bookmark=%s]%s[/bookmark]%s'; - $arr = ["url" => $url, "text" => ""]; + $arr = ['url' => $url, 'text' => '']; - Addon::callHooks("parse_link", $arr); + Addon::callHooks('parse_link', $arr); - if (strlen($arr["text"])) { - echo $arr["text"]; - killme(); + if (strlen($arr['text'])) { + echo $arr['text']; + exit(); } // If there is already some content information submitted we don't // need to parse the url for content. if (!empty($url) && !empty($title) && !empty($text)) { + $title = str_replace(["\r", "\n"], ['', ''], $title); - $title = str_replace(["\r","\n"],["",""],$title); - - $text = "[quote]" . trim($text) . "[/quote]" . $br; + $text = '[quote]' . trim($text) . '[/quote]' . $br; $result = sprintf($template, $url, ($title) ? $title : $url, $text) . $str_tags; - logger("parse_url (unparsed): returns: " . $result); + logger('(unparsed): returns: ' . $result); echo $result; - killme(); + exit(); } // Fetch the information directly from the webpage $siteinfo = ParseUrl::getSiteinfo($url); - unset($siteinfo["keywords"]); + unset($siteinfo['keywords']); // Format it as BBCode attachment $info = add_page_info_data($siteinfo); echo $info; - killme(); + exit(); } /** @@ -151,7 +151,8 @@ function parse_url_content(App $a) { * @todo Remove this function after all Addons has been changed to use * ParseUrl::getSiteinfoCached */ -function parseurl_getsiteinfo_cached($url, $no_guessing = false, $do_oembed = true) { +function parseurl_getsiteinfo_cached($url, $no_guessing = false, $do_oembed = true) +{ $siteinfo = ParseUrl::getSiteinfoCached($url, $no_guessing, $do_oembed); return $siteinfo; } diff --git a/mod/photo.php b/mod/photo.php index 6d456b349e..b1dd9a5c3a 100644 --- a/mod/photo.php +++ b/mod/photo.php @@ -192,7 +192,7 @@ function photo_init(App $a) // If the photo is public and there is an existing photo directory store the photo there if ($public and $file != '') { // If the photo path isn't there, try to create it - $basepath = $a->get_basepath(); + $basepath = $a->getBasePath(); if (!is_dir($basepath . "/photo")) { if (is_writable($basepath)) { mkdir($basepath . "/photo"); diff --git a/mod/photos.php b/mod/photos.php index 5fb6ba3683..259209ed40 100644 --- a/mod/photos.php +++ b/mod/photos.php @@ -212,7 +212,7 @@ function photos_post(App $a) } // Check if the user has responded to a delete confirmation query - if ($_REQUEST['canceled']) { + if (!empty($_REQUEST['canceled'])) { goaway($_SESSION['photo_return']); } @@ -472,7 +472,7 @@ function photos_post(App $a) $uri = Item::newURI($page_owner_uid); $arr = []; - $arr['guid'] = System::createGUID(32); + $arr['guid'] = System::createUUID(); $arr['uid'] = $page_owner_uid; $arr['uri'] = $uri; $arr['parent-uri'] = $uri; @@ -651,7 +651,7 @@ function photos_post(App $a) $uri = Item::newURI($page_owner_uid); $arr = []; - $arr['guid'] = System::createGUID(32); + $arr['guid'] = System::createUUID(); $arr['uid'] = $page_owner_uid; $arr['uri'] = $uri; $arr['parent-uri'] = $uri; @@ -762,12 +762,14 @@ function photos_post(App $a) $filesize = $ret['filesize']; $type = $ret['type']; $error = UPLOAD_ERR_OK; - } else { + } elseif (!empty($_FILES['userfile'])) { $src = $_FILES['userfile']['tmp_name']; $filename = basename($_FILES['userfile']['name']); $filesize = intval($_FILES['userfile']['size']); $type = $_FILES['userfile']['type']; $error = $_FILES['userfile']['error']; + } else { + $error = UPLOAD_ERR_NO_FILE; } if ($error !== UPLOAD_ERR_OK) { @@ -887,7 +889,7 @@ function photos_post(App $a) $arr['coord'] = $lat . ' ' . $lon; } - $arr['guid'] = System::createGUID(32); + $arr['guid'] = System::createUUID(); $arr['uid'] = $page_owner_uid; $arr['uri'] = $uri; $arr['parent-uri'] = $uri; @@ -1141,8 +1143,8 @@ function photos_content(App $a) DBA::escape($album) ); if (DBA::isResult($r)) { - $a->set_pager_total(count($r)); - $a->set_pager_itemspage(20); + $a->setPagerTotal(count($r)); + $a->setPagerItemsPage(20); } /// @TODO I have seen this many times, maybe generalize it script-wide and encapsulate it? @@ -1391,7 +1393,7 @@ function photos_content(App $a) $link_item = Item::selectFirst([], ['id' => $linked_items[0]['id']]); $condition = ["`parent` = ? AND `parent` != `id`", $link_item['parent']]; - $a->set_pager_total(DBA::count('item', $condition)); + $a->setPagerTotal(DBA::count('item', $condition)); $params = ['order' => ['id'], 'limit' => [$a->pager['start'], $a->pager['itemspage']]]; $result = Item::selectForUser($link_item['uid'], Item::ITEM_FIELDLIST, $condition, $params); @@ -1633,7 +1635,7 @@ function photos_content(App $a) '$paginate' => $paginate, ]); - $a->page['htmlhead'] .= "\n" . '' . "\n"; + $a->page['htmlhead'] .= "\n" . '' . "\n"; $a->page['htmlhead'] .= '' . "\n"; $a->page['htmlhead'] .= '' . "\n"; $a->page['htmlhead'] .= '' . "\n"; @@ -1653,8 +1655,8 @@ function photos_content(App $a) ); if (DBA::isResult($r)) { - $a->set_pager_total(count($r)); - $a->set_pager_itemspage(20); + $a->setPagerTotal(count($r)); + $a->setPagerItemsPage(20); } $r = q("SELECT `resource-id`, ANY_VALUE(`id`) AS `id`, ANY_VALUE(`filename`) AS `filename`, diff --git a/mod/ping.php b/mod/ping.php index 99ebde70c1..5ea75727a1 100644 --- a/mod/ping.php +++ b/mod/ping.php @@ -202,11 +202,7 @@ function ping_init(App $a) $mail_count = count($mails); if (intval(Config::get('config', 'register_policy')) === REGISTER_APPROVE && is_site_admin()) { - $regs = q( - "SELECT `contact`.`name`, `contact`.`url`, `contact`.`micro`, `register`.`created` - FROM `contact` RIGHT JOIN `register` ON `register`.`uid` = `contact`.`uid` - WHERE `contact`.`self` = 1" - ); + $regs = Friendica\Model\Register::getPending(); if (DBA::isResult($regs)) { $register_count = count($regs); @@ -350,7 +346,7 @@ function ping_init(App $a) $regularnotifications = (!empty($_GET['uid']) && !empty($_GET['_'])); foreach ($notifs as $notif) { - if ($a->is_friendica_app() || !$regularnotifications) { + if ($a->isFriendicaApp() || !$regularnotifications) { $notif['message'] = str_replace("{0}", $notif['name'], $notif['message']); } @@ -510,16 +506,17 @@ function ping_get_notifications($uid) * @brief Backward-compatible XML formatting for ping.php output * @deprecated * - * @param array $data The initial ping data array - * @param int $sysnotify Number of unseen system notifications - * @param array $notifs Complete list of notification - * @param array $sysmsgs List of system notice messages - * @param array $sysmsgs_info List of system info messages - * @param int $groups_unseen Number of unseen group items - * @param int $forums_unseen Number of unseen forum items + * @param array $data The initial ping data array + * @param int $sysnotify_count Number of unseen system notifications + * @param array $notifs Complete list of notification + * @param array $sysmsgs List of system notice messages + * @param array $sysmsgs_info List of system info messages + * @param int $groups_unseen Number of unseen group items + * @param int $forums_unseen Number of unseen forum items + * * @return array XML-transform ready data array */ -function ping_format_xml_data($data, $sysnotify, $notifs, $sysmsgs, $sysmsgs_info, $groups_unseen, $forums_unseen) +function ping_format_xml_data($data, $sysnotify_count, $notifs, $sysmsgs, $sysmsgs_info, $groups_unseen, $forums_unseen) { $notifications = []; foreach ($notifs as $key => $notif) { diff --git a/mod/poke.php b/mod/poke.php index a9dfc73f4e..6ebb8632c1 100644 --- a/mod/poke.php +++ b/mod/poke.php @@ -24,19 +24,20 @@ use Friendica\Model\Item; require_once 'include/security.php'; require_once 'include/items.php'; -function poke_init(App $a) { - +function poke_init(App $a) +{ if (!local_user()) { return; } $uid = local_user(); - $verb = notags(trim($_GET['verb'])); - if (!$verb) { + if (empty($_GET['verb'])) { return; } + $verb = notags(trim($_GET['verb'])); + $verbs = get_poke_verbs(); if (!array_key_exists($verb, $verbs)) { @@ -96,10 +97,10 @@ function poke_init(App $a) { $arr = []; - $arr['guid'] = System::createGUID(32); + $arr['guid'] = System::createUUID(); $arr['uid'] = $uid; $arr['uri'] = $uri; - $arr['parent-uri'] = ($parent_uri ? $parent_uri : $uri); + $arr['parent-uri'] = (!empty($parent_uri) ? $parent_uri : $uri); $arr['wall'] = 1; $arr['contact-id'] = $poster['id']; $arr['owner-name'] = $poster['name']; @@ -121,7 +122,7 @@ function poke_init(App $a) { $arr['origin'] = 1; $arr['body'] = '[url=' . $poster['url'] . ']' . $poster['name'] . '[/url]' . ' ' . L10n::t($verbs[$verb][0]) . ' ' . '[url=' . $target['url'] . ']' . $target['name'] . '[/url]'; - $arr['object'] = '' . ACTIVITY_OBJ_PERSON . '' . $target['name'] . '' . System::baseUrl() . '/contact/' . $target['id'] . ''; + $arr['object'] = '' . ACTIVITY_OBJ_PERSON . '' . $target['name'] . '' . $target['url'] . ''; $arr['object'] .= '' . xmlify('' . "\n"); $arr['object'] .= xmlify('' . "\n"); @@ -137,10 +138,8 @@ function poke_init(App $a) { return; } - - -function poke_content(App $a) { - +function poke_content(App $a) +{ if (!local_user()) { notice(L10n::t('Permission denied.') . EOL); return; @@ -149,17 +148,17 @@ function poke_content(App $a) { $name = ''; $id = ''; - if (intval($_GET['c'])) { - $r = q("SELECT `id`,`name` FROM `contact` WHERE `id` = %d AND `uid` = %d LIMIT 1", - intval($_GET['c']), - intval(local_user()) - ); - if (DBA::isResult($r)) { - $name = $item['name']; - $id = $item['id']; - } + if (empty($_GET['c'])) { + return; } + $contact = DBA::selectFirst('contact', ['id', 'name'], ['id' => $_GET['c'], 'uid' => local_user()]); + if (!DBA::isResult($contact)) { + return; + } + + $name = $contact['name']; + $id = $contact['id']; $base = System::baseUrl(); diff --git a/mod/profile.php b/mod/profile.php index 2e3ccd28c5..aa284d1669 100644 --- a/mod/profile.php +++ b/mod/profile.php @@ -20,6 +20,7 @@ use Friendica\Model\Profile; use Friendica\Module\Login; use Friendica\Protocol\DFRN; use Friendica\Util\DateTimeFormat; +use Friendica\Protocol\ActivityPub; function profile_init(App $a) { @@ -49,6 +50,16 @@ function profile_init(App $a) DFRN::autoRedir($a, $which); } + if (ActivityPub::isRequest()) { + $user = DBA::selectFirst('user', ['uid'], ['nickname' => $which]); + if (DBA::isResult($user)) { + $data = ActivityPub\Transmitter::getProfile($user['uid']); + echo json_encode($data); + header('Content-Type: application/activity+json'); + exit(); + } + } + Profile::load($a, $which, $profile); $blocked = !local_user() && !remote_user() && Config::get('system', 'block_public'); @@ -80,7 +91,7 @@ function profile_init(App $a) $a->page['htmlhead'] .= '' . "\r\n"; $a->page['htmlhead'] .= '' . "\r\n"; $a->page['htmlhead'] .= '' . "\r\n"; - $uri = urlencode('acct:' . $a->profile['nickname'] . '@' . $a->get_hostname() . ($a->urlpath ? '/' . $a->urlpath : '')); + $uri = urlencode('acct:' . $a->profile['nickname'] . '@' . $a->getHostName() . ($a->getURLPath() ? '/' . $a->getURLPath() : '')); $a->page['htmlhead'] .= '' . "\r\n"; header('Link: <' . System::baseUrl() . '/xrd/?uri=' . $uri . '>; rel="lrdd"; type="application/xrd+xml"', false); @@ -296,7 +307,7 @@ function profile_content(App $a, $update = 0) $itemspage_network = $a->force_max_items; } - $a->set_pager_itemspage($itemspage_network); + $a->setPagerItemsPage($itemspage_network); $pager_sql = sprintf(" LIMIT %d, %d ", intval($a->pager['start']), intval($a->pager['itemspage'])); diff --git a/mod/profile_photo.php b/mod/profile_photo.php index 567a7f3a25..984ebfed6f 100644 --- a/mod/profile_photo.php +++ b/mod/profile_photo.php @@ -317,7 +317,6 @@ function profile_photo_crop_ui_head(App $a, Image $image) } $a->page['htmlhead'] .= replace_macros(get_markup_template("crophead.tpl"), []); - $a->page['end'] .= replace_macros(get_markup_template("cropend.tpl"), []); $imagecrop = [ 'hash' => $hash, diff --git a/mod/profiles.php b/mod/profiles.php index d951a470d7..3e6bd1cb0d 100644 --- a/mod/profiles.php +++ b/mod/profiles.php @@ -20,6 +20,7 @@ use Friendica\Model\Profile; use Friendica\Network\Probe; use Friendica\Util\DateTimeFormat; use Friendica\Util\Temporal; +use Friendica\Module\Login; function profiles_init(App $a) { @@ -509,7 +510,7 @@ function profiles_content(App $a) { if (! local_user()) { notice(L10n::t('Permission denied.') . EOL); - return; + return Login::form(); } $o = ''; @@ -527,9 +528,6 @@ function profiles_content(App $a) { $a->page['htmlhead'] .= replace_macros(get_markup_template('profed_head.tpl'), [ '$baseurl' => System::baseUrl(true), ]); - $a->page['end'] .= replace_macros(get_markup_template('profed_end.tpl'), [ - '$baseurl' => System::baseUrl(true), - ]); $opt_tpl = get_markup_template("profile-hide-friends.tpl"); $hide_friends = replace_macros($opt_tpl,[ @@ -618,10 +616,10 @@ function profiles_content(App $a) { '$country_name' => ['country_name', L10n::t('Country:'), $r[0]['country-name']], '$age' => ((intval($r[0]['dob'])) ? '(' . L10n::t('Age: ') . Temporal::getAgeByTimezone($r[0]['dob'],$a->user['timezone'],$a->user['timezone']) . ')' : ''), '$gender' => ContactSelector::gender($r[0]['gender']), - '$marital' => ContactSelector::maritalStatus($r[0]['marital']), + '$marital' => ['selector' => ContactSelector::maritalStatus($r[0]['marital']), 'value' => $r[0]['marital']], '$with' => ['with', L10n::t("Who: \x28if applicable\x29"), strip_tags($r[0]['with']), L10n::t('Examples: cathy123, Cathy Williams, cathy@example.com')], '$howlong' => ['howlong', L10n::t('Since [date]:'), ($r[0]['howlong'] <= NULL_DATE ? '' : DateTimeFormat::local($r[0]['howlong']))], - '$sexual' => ContactSelector::sexualPreference($r[0]['sexual']), + '$sexual' => ['selector' => ContactSelector::sexualPreference($r[0]['sexual']), 'value' => $r[0]['sexual']], '$about' => ['about', L10n::t('Tell us about yourself...'), $r[0]['about']], '$xmpp' => ['xmpp', L10n::t("XMPP \x28Jabber\x29 address:"), $r[0]['xmpp'], L10n::t("The XMPP address will be propagated to your contacts so that they can follow you.")], '$homepage' => ['homepage', L10n::t('Homepage URL:'), $r[0]['homepage']], @@ -669,7 +667,7 @@ function profiles_content(App $a) { $profiles = ''; foreach ($r as $rr) { $profiles .= replace_macros($tpl, [ - '$photo' => $a->remove_baseurl($rr['thumb']), + '$photo' => $a->removeBaseURL($rr['thumb']), '$id' => $rr['id'], '$alt' => L10n::t('Profile Image'), '$profile_name' => $rr['profile-name'], diff --git a/mod/pubsubhubbub.php b/mod/pubsubhubbub.php index 8f9478d8aa..d7b204e89c 100644 --- a/mod/pubsubhubbub.php +++ b/mod/pubsubhubbub.php @@ -104,8 +104,9 @@ function pubsubhubbub_init(App $a) { // we don't actually enforce the lease time because GNU // Social/StatusNet doesn't honour it (yet) - $body = Network::fetchUrl($hub_callback . "?" . $params); - $ret = $a->get_curl_code(); + $fetchResult = Network::fetchUrlFull($hub_callback . "?" . $params); + $body = $fetchResult->getBody(); + $ret = $fetchResult->getReturnCode(); // give up if the HTTP return code wasn't a success (2xx) if ($ret < 200 || $ret > 299) { diff --git a/mod/redir.php b/mod/redir.php index 3acf960dab..e989ad015a 100644 --- a/mod/redir.php +++ b/mod/redir.php @@ -57,7 +57,7 @@ function redir_init(App $a) { } if (remote_user()) { - $host = substr(System::baseUrl() . ($a->urlpath ? '/' . $a->urlpath : ''), strpos(System::baseUrl(), '://') + 3); + $host = substr(System::baseUrl() . ($a->getURLPath() ? '/' . $a->getURLPath() : ''), strpos(System::baseUrl(), '://') + 3); $remotehost = substr($contact['addr'], strpos($contact['addr'], '@') + 1); // On a local instance we have to check if the local user has already authenticated diff --git a/mod/register.php b/mod/register.php index b851faf2d6..48fe67afc5 100644 --- a/mod/register.php +++ b/mod/register.php @@ -11,10 +11,8 @@ use Friendica\Core\L10n; use Friendica\Core\PConfig; use Friendica\Core\System; use Friendica\Core\Worker; -use Friendica\Database\DBA; -use Friendica\Model\User; +use Friendica\Model; use Friendica\Module\Tos; -use Friendica\Util\DateTimeFormat; require_once 'include/enotify.php'; @@ -67,7 +65,7 @@ function register_post(App $a) $arr['language'] = L10n::getBrowserLanguage(); try { - $result = User::create($arr); + $result = Model\User::create($arr); } catch (Exception $e) { notice($e->getMessage()); return; @@ -76,7 +74,7 @@ function register_post(App $a) $user = $result['user']; if ($netpublish && intval(Config::get('config', 'register_policy')) !== REGISTER_APPROVE) { - $url = System::baseUrl() . '/profile/' . $user['nickname']; + $url = $a->getBaseUrl() . '/profile/' . $user['nickname']; Worker::add(PRIORITY_LOW, "Directory", $url); } @@ -86,18 +84,22 @@ function register_post(App $a) if (intval(Config::get('config', 'register_policy')) === REGISTER_OPEN) { if ($using_invites && $invite_id) { - q("delete * from register where hash = '%s' limit 1", DBA::escape($invite_id)); + Model\Register::deleteByHash($invite_id); PConfig::set($user['uid'], 'system', 'invites_remaining', $num_invites); } // Only send a password mail when the password wasn't manually provided if (!x($_POST, 'password1') || !x($_POST, 'confirm')) { - $res = User::sendRegisterOpenEmail( - $user['email'], Config::get('config', 'sitename'), System::baseUrl(), $user['username'], $result['password'], $user); + $res = Model\User::sendRegisterOpenEmail( + $user, + Config::get('config', 'sitename'), + $a->getBaseUrl(), + $result['password'] + ); if ($res) { info(L10n::t('Registration successful. Please check your email for further instructions.') . EOL); - goaway(System::baseUrl()); + goaway(); } else { notice( L10n::t('Failed to send email message. Here your accout details:
      login: %s
      password: %s

      You can change your password after login.', @@ -108,27 +110,19 @@ function register_post(App $a) } } else { info(L10n::t('Registration successful.') . EOL); - goaway(System::baseUrl()); + goaway(); } } elseif (intval(Config::get('config', 'register_policy')) === REGISTER_APPROVE) { if (!strlen(Config::get('config', 'admin_email'))) { notice(L10n::t('Your registration can not be processed.') . EOL); - goaway(System::baseUrl()); + goaway(); } - $hash = random_string(); - $r = q("INSERT INTO `register` ( `hash`, `created`, `uid`, `password`, `language`, `note` ) VALUES ( '%s', '%s', %d, '%s', '%s', '%s' ) ", - DBA::escape($hash), - DBA::escape(DateTimeFormat::utcNow()), - intval($user['uid']), - DBA::escape($result['password']), - DBA::escape(Config::get('system', 'language')), - DBA::escape($_POST['permonlybox']) - ); + Model\Register::createForApproval($user['uid'], Config::get('system', 'language'), $_POST['permonlybox']); // invite system if ($using_invites && $invite_id) { - q("DELETE * FROM `register` WHERE `hash` = '%s' LIMIT 1", DBA::escape($invite_id)); + Model\Register::deleteByHash($invite_id); PConfig::set($user['uid'], 'system', 'invites_remaining', $num_invites); } @@ -146,9 +140,9 @@ function register_post(App $a) 'source_name' => $user['username'], 'source_mail' => $user['email'], 'source_nick' => $user['nickname'], - 'source_link' => System::baseUrl() . "/admin/users/", - 'link' => System::baseUrl() . "/admin/users/", - 'source_photo' => System::baseUrl() . "/photo/avatar/" . $user['uid'] . ".jpg", + 'source_link' => $a->getBaseUrl() . "/admin/users/", + 'link' => $a->getBaseUrl() . "/admin/users/", + 'source_photo' => $a->getBaseUrl() . "/photo/avatar/" . $user['uid'] . ".jpg", 'to_email' => $admin['email'], 'uid' => $admin['uid'], 'language' => $admin['language'] ? $admin['language'] : 'en', @@ -156,11 +150,15 @@ function register_post(App $a) ]); } // send notification to the user, that the registration is pending - User::sendRegisterPendingEmail( - $user['email'], Config::get('config', 'sitename'), $user['username']); + Model\User::sendRegisterPendingEmail( + $user, + Config::get('config', 'sitename'), + $a->getBaseURL(), + $result['password'] + ); info(L10n::t('Your registration is pending approval by the site owner.') . EOL); - goaway(System::baseUrl()); + goaway(); } return; @@ -274,7 +272,7 @@ function register_content(App $a) '$passwords' => $passwords, '$password1' => ['password1', L10n::t('New Password:'), '', L10n::t('Leave empty for an auto generated password.')], '$password2' => ['confirm', L10n::t('Confirm:'), '', ''], - '$nickdesc' => L10n::t('Choose a profile nickname. This must begin with a text character. Your profile address on this site will then be \'nickname@%s\'.', $a->get_hostname()), + '$nickdesc' => L10n::t('Choose a profile nickname. This must begin with a text character. Your profile address on this site will then be \'nickname@%s\'.', $a->getHostName()), '$nicklabel' => L10n::t('Choose a nickname: '), '$photo' => $photo, '$publish' => $profile_publish, @@ -283,7 +281,7 @@ function register_content(App $a) '$email' => $email, '$nickname' => $nickname, '$license' => $license, - '$sitename' => $a->get_hostname(), + '$sitename' => $a->getHostName(), '$importh' => L10n::t('Import'), '$importt' => L10n::t('Import your profile to this friendica instance'), '$showtoslink' => Config::get('system', 'tosdisplay'), diff --git a/mod/regmod.php b/mod/regmod.php index 11d8eee412..3f6f0e04e3 100644 --- a/mod/regmod.php +++ b/mod/regmod.php @@ -9,6 +9,7 @@ use Friendica\Core\L10n; use Friendica\Core\System; use Friendica\Core\Worker; use Friendica\Database\DBA; +use Friendica\Model\Register; use Friendica\Model\User; use Friendica\Module\Login; @@ -18,51 +19,35 @@ function user_allow($hash) { $a = get_app(); - $register = q("SELECT * FROM `register` WHERE `hash` = '%s' LIMIT 1", - DBA::escape($hash) - ); - - + $register = Register::getByHash($hash); if (!DBA::isResult($register)) { return false; } - $user = q("SELECT * FROM `user` WHERE `uid` = %d LIMIT 1", - intval($register[0]['uid']) - ); - + $user = User::getById($register['uid']); if (!DBA::isResult($user)) { - killme(); + exit(); } - $r = q("DELETE FROM `register` WHERE `hash` = '%s'", - DBA::escape($register[0]['hash']) - ); + Register::deleteByHash($hash); + DBA::update('user', ['blocked' => false, 'verified' => true], ['uid' => $register['uid']]); - $r = q("UPDATE `user` SET `blocked` = 0, `verified` = 1 WHERE `uid` = %d", - intval($register[0]['uid']) - ); + $profile = DBA::selectFirst('profile', ['net-publish'], ['uid' => $register['uid'], 'is-default' => true]); - $r = q("SELECT * FROM `profile` WHERE `uid` = %d AND `is-default` = 1", - intval($user[0]['uid']) - ); - if (DBA::isResult($r) && $r[0]['net-publish']) { - $url = System::baseUrl() . '/profile/' . $user[0]['nickname']; - if ($url && strlen(Config::get('system', 'directory'))) { - Worker::add(PRIORITY_LOW, "Directory", $url); - } + if (DBA::isResult($profile) && $profile['net-publish'] && Config::get('system', 'directory')) { + $url = System::baseUrl() . '/profile/' . $user['nickname']; + Worker::add(PRIORITY_LOW, "Directory", $url); } - L10n::pushLang($register[0]['language']); + L10n::pushLang($register['language']); $res = User::sendRegisterOpenEmail( - $user[0]['email'], + $user, Config::get('config', 'sitename'), - System::baseUrl(), - $user[0]['username'], - $register[0]['password'], - $user[0]); + $a->getBaseUrl(), + defaults($register, 'password', 'Sent in a previous email') + ); L10n::popLang(); @@ -77,22 +62,21 @@ function user_allow($hash) // allowed to have friends on this system function user_deny($hash) { - $register = q("SELECT * FROM `register` WHERE `hash` = '%s' LIMIT 1", - DBA::escape($hash) - ); - + $register = Register::getByHash($hash); if (!DBA::isResult($register)) { return false; } - $user = q("SELECT * FROM `user` WHERE `uid` = %d LIMIT 1", - intval($register[0]['uid']) - ); + $user = User::getById($register['uid']); + if (!DBA::isResult($user)) { + exit(); + } - DBA::delete('user', ['uid' => $register[0]['uid']]); - DBA::delete('register', ['hash' => $register[0]['hash']]); + DBA::delete('user', ['uid' => $register['uid']]); - notice(L10n::t('Registration revoked for %s', $user[0]['username']) . EOL); + Register::deleteByHash($register['hash']); + + notice(L10n::t('Registration revoked for %s', $user['username']) . EOL); return true; } @@ -100,17 +84,16 @@ function regmod_content(App $a) { if (!local_user()) { info(L10n::t('Please login.') . EOL); - $o = '

      ' . Login::form($a->query_string, intval(Config::get('config', 'register_policy')) === REGISTER_CLOSED ? 0 : 1); - return $o; + return Login::form($a->query_string, intval(Config::get('config', 'register_policy')) === REGISTER_CLOSED ? 0 : 1); } - if ((!is_site_admin()) || (x($_SESSION, 'submanage') && intval($_SESSION['submanage']))) { + if (!is_site_admin() || !empty($_SESSION['submanage'])) { notice(L10n::t('Permission denied.') . EOL); return ''; } if ($a->argc != 3) { - killme(); + exit(); } $cmd = $a->argv[1]; @@ -118,13 +101,11 @@ function regmod_content(App $a) if ($cmd === 'deny') { user_deny($hash); - goaway(System::baseUrl() . "/admin/users/"); - killme(); + goaway('admin/users/'); } if ($cmd === 'allow') { user_allow($hash); - goaway(System::baseUrl() . "/admin/users/"); - killme(); + goaway('admin/users/'); } } diff --git a/mod/repair_ostatus.php b/mod/repair_ostatus.php index 3acaa687a7..4499220817 100644 --- a/mod/repair_ostatus.php +++ b/mod/repair_ostatus.php @@ -14,7 +14,7 @@ function repair_ostatus_content(App $a) { if (! local_user()) { notice(L10n::t('Permission denied.') . EOL); - goaway($_SESSION['return_url']); + goaway('/ostatus_repair'); // NOTREACHED } diff --git a/mod/salmon.php b/mod/salmon.php index d07b06004d..bd4b3773cb 100644 --- a/mod/salmon.php +++ b/mod/salmon.php @@ -41,14 +41,14 @@ function salmon_post(App $a, $xml = '') { $base = null; // figure out where in the DOM tree our data is hiding - if($dom->provenance->data) + if (!empty($dom->provenance->data)) $base = $dom->provenance; - elseif($dom->env->data) + elseif (!empty($dom->env->data)) $base = $dom->env; - elseif($dom->data) + elseif (!empty($dom->data)) $base = $dom; - if(! $base) { + if (empty($base)) { logger('unable to locate salmon data in xml '); System::httpExit(400); } diff --git a/mod/settings.php b/mod/settings.php index 84bc230e30..5632193e3b 100644 --- a/mod/settings.php +++ b/mod/settings.php @@ -22,6 +22,7 @@ use Friendica\Model\User; use Friendica\Protocol\Email; use Friendica\Util\Network; use Friendica\Util\Temporal; +use Friendica\Module\Login; function get_theme_config_file($theme) { @@ -546,7 +547,7 @@ function settings_post(App $a) if ($openid != $a->user['openid'] || (strlen($openid) && (!strlen($openidserver)))) { if (Network::isUrlValid($openid)) { logger('updating openidserver'); - $open_id_obj = new LightOpenID($a->get_hostname()); + $open_id_obj = new LightOpenID($a->getHostName()); $open_id_obj->identity = $openid; $openidserver = $open_id_obj->discover($open_id_obj->identity); } else { @@ -658,7 +659,7 @@ function settings_content(App $a) if (!local_user()) { //notice(L10n::t('Permission denied.') . EOL); - return; + return Login::form(); } if (x($_SESSION, 'submanage') && intval($_SESSION['submanage'])) { @@ -982,11 +983,6 @@ function settings_content(App $a) '$theme_config' => $theme_config, ]); - $tpl = get_markup_template('settings/display_end.tpl'); - $a->page['end'] .= replace_macros($tpl, [ - '$theme' => ['theme', L10n::t('Display Theme:'), $theme_selected, '', $themes] - ]); - return $o; } @@ -1140,8 +1136,8 @@ function settings_content(App $a) $tpl_addr = get_markup_template('settings/nick_set.tpl'); $prof_addr = replace_macros($tpl_addr,[ - '$desc' => L10n::t("Your Identity Address is '%s' or '%s'.", $nickname . '@' . $a->get_hostname() . $a->get_path(), System::baseUrl() . '/profile/' . $nickname), - '$basepath' => $a->get_hostname() + '$desc' => L10n::t("Your Identity Address is '%s' or '%s'.", $nickname . '@' . $a->getHostName() . $a->getURLPath(), System::baseUrl() . '/profile/' . $nickname), + '$basepath' => $a->getHostName() ]); $stpl = get_markup_template('settings/settings.tpl'); diff --git a/mod/subthread.php b/mod/subthread.php index 1153f2147d..105cf60feb 100644 --- a/mod/subthread.php +++ b/mod/subthread.php @@ -108,7 +108,7 @@ EOT; $arr = []; - $arr['guid'] = System::createGUID(32); + $arr['guid'] = System::createUUID(); $arr['uri'] = $uri; $arr['uid'] = $owner_uid; $arr['contact-id'] = $contact['id']; diff --git a/mod/tagger.php b/mod/tagger.php index 959394c078..fd79d54150 100644 --- a/mod/tagger.php +++ b/mod/tagger.php @@ -115,7 +115,7 @@ EOT; $arr = []; - $arr['guid'] = System::createGUID(32); + $arr['guid'] = System::createUUID(); $arr['uri'] = $uri; $arr['uid'] = $owner_uid; $arr['contact-id'] = $contact['id']; diff --git a/mod/unfollow.php b/mod/unfollow.php index 5c00726e27..6a058608e7 100644 --- a/mod/unfollow.php +++ b/mod/unfollow.php @@ -10,132 +10,144 @@ use Friendica\Core\System; use Friendica\Database\DBA; use Friendica\Model\Contact; use Friendica\Model\Profile; +use Friendica\Model\User; -function unfollow_post(App $a) +function unfollow_post() { + $return_url = 'contacts'; + if (!local_user()) { - notice(L10n::t('Permission denied.') . EOL); - goaway($_SESSION['return_url']); + notice(L10n::t('Permission denied.')); + goaway('/login'); // NOTREACHED } - if ($_REQUEST['cancel']) { - goaway($_SESSION['return_url']); - } - $uid = local_user(); - $url = notags(trim($_REQUEST['url'])); - $return_url = $_SESSION['return_url']; + $url = notags(trim(defaults($_REQUEST, 'url', ''))); - $condition = ["`uid` = ? AND `rel` = ? AND (`nurl` = ? OR `alias` = ? OR `alias` = ?) AND `network` != ?", - $uid, Contact::FRIEND, normalise_link($url), - normalise_link($url), $url, Protocol::STATUSNET]; + $condition = ["`uid` = ? AND (`rel` = ? OR `rel` = ?) AND (`nurl` = ? OR `alias` = ? OR `alias` = ?)", + $uid, Contact::SHARING, Contact::FRIEND, normalise_link($url), + normalise_link($url), $url]; $contact = DBA::selectFirst('contact', [], $condition); if (!DBA::isResult($contact)) { - notice(L10n::t("Contact wasn't found or can't be unfollowed.")); - } else { - if (in_array($contact['network'], [Protocol::OSTATUS, Protocol::DIASPORA, Protocol::DFRN])) { - $r = q("SELECT `contact`.*, `user`.* FROM `contact` INNER JOIN `user` ON `contact`.`uid` = `user`.`uid` - WHERE `user`.`uid` = %d AND `contact`.`self` LIMIT 1", - intval($uid) - ); - if (DBA::isResult($r)) { - Contact::terminateFriendship($r[0], $contact); - } - } - DBA::update('contact', ['rel' => Contact::FOLLOWER], ['id' => $contact['id']]); - - info(L10n::t('Contact unfollowed').EOL); - goaway(System::baseUrl().'/contacts/'.$contact['id']); + notice(L10n::t("You aren't following this contact.")); + goaway($return_url); + // NOTREACHED } - goaway($return_url); + + if (!empty($_REQUEST['cancel'])) { + goaway($return_url . '/' . $contact['id']); + } + + if (!in_array($contact['network'], Protocol::NATIVE_SUPPORT)) { + notice(L10n::t('Unfollowing is currently not supported by your network.')); + goaway($return_url . '/' . $contact['id']); + // NOTREACHED + } + + $dissolve = ($contact['rel'] == Contact::SHARING); + + $owner = User::getOwnerDataById($uid); + if ($owner) { + Contact::terminateFriendship($owner, $contact, $dissolve); + } + + // Sharing-only contacts get deleted as there no relationship any more + if ($dissolve) { + Contact::remove($contact['id']); + $return_path = 'contacts'; + } else { + DBA::update('contact', ['rel' => Contact::FOLLOWER], ['id' => $contact['id']]); + $return_path = 'contact/' . $contact['id']; + } + + info(L10n::t('Contact unfollowed')); + goaway($return_path); // NOTREACHED } function unfollow_content(App $a) { - if (! local_user()) { - notice(L10n::t('Permission denied.') . EOL); - goaway($_SESSION['return_url']); + $return_url = 'contacts'; + + if (!local_user()) { + notice(L10n::t('Permission denied.')); + goaway('/login'); // NOTREACHED } $uid = local_user(); $url = notags(trim($_REQUEST['url'])); - $submit = L10n::t('Submit Request'); - - $condition = ["`uid` = ? AND `rel` = ? AND (`nurl` = ? OR `alias` = ? OR `alias` = ?) AND `network` != ?", - local_user(), Contact::FRIEND, normalise_link($url), - normalise_link($url), $url, Protocol::STATUSNET]; + $condition = ["`uid` = ? AND (`rel` = ? OR `rel` = ?) AND (`nurl` = ? OR `alias` = ? OR `alias` = ?)", + local_user(), Contact::SHARING, Contact::FRIEND, normalise_link($url), + normalise_link($url), $url]; $contact = DBA::selectFirst('contact', ['url', 'network', 'addr', 'name'], $condition); if (!DBA::isResult($contact)) { - notice(L10n::t("You aren't a friend of this contact.").EOL); - $submit = ""; + notice(L10n::t("You aren't following this contact.")); + goaway($return_url); // NOTREACHED } - if (!in_array($contact['network'], [Protocol::DIASPORA, Protocol::OSTATUS, Protocol::DFRN])) { - notice(L10n::t("Unfollowing is currently not supported by your network.").EOL); - $submit = ""; + if (!in_array($contact['network'], Protocol::NATIVE_SUPPORT)) { + notice(L10n::t('Unfollowing is currently not supported by your network.')); + goaway('contact/' . $contact['id']); // NOTREACHED } - $request = System::baseUrl()."/unfollow"; + $request = System::baseUrl() . '/unfollow'; $tpl = get_markup_template('auto_request.tpl'); - $r = q("SELECT `url` FROM `contact` WHERE `uid` = %d AND `self` LIMIT 1", intval($uid)); + $self = DBA::selectFirst('contact', ['url'], ['uid' => $uid, 'self' => true]); - if (!$r) { - notice(L10n::t('Permission denied.') . EOL); - goaway($_SESSION['return_url']); + if (!DBA::isResult($self)) { + notice(L10n::t('Permission denied.')); + goaway($return_url); // NOTREACHED } - $myaddr = $r[0]["url"]; - // Makes the connection request for friendica contacts easier - $_SESSION["fastlane"] = $contact["url"]; + $_SESSION['fastlane'] = $contact['url']; - $header = L10n::t("Disconnect/Unfollow"); + $header = L10n::t('Disconnect/Unfollow'); - $o = replace_macros($tpl, [ - '$header' => htmlentities($header), - '$desc' => "", - '$pls_answer' => "", - '$does_know_you' => "", - '$add_note' => "", - '$page_desc' => "", - '$friendica' => "", - '$statusnet' => "", - '$diaspora' => "", - '$diasnote' => "", - '$your_address' => L10n::t('Your Identity Address:'), - '$invite_desc' => "", - '$emailnet' => "", - '$submit' => $submit, - '$cancel' => L10n::t('Cancel'), - '$nickname' => "", - '$name' => $contact["name"], - '$url' => $contact["url"], - '$zrl' => Contact::magicLink($contact["url"]), - '$url_label' => L10n::t("Profile URL"), - '$myaddr' => $myaddr, - '$request' => $request, - '$keywords' => "", - '$keywords_label' => "" + $o = replace_macros($tpl, [ + '$header' => htmlentities($header), + '$desc' => '', + '$pls_answer' => '', + '$does_know_you' => '', + '$add_note' => '', + '$page_desc' => '', + '$friendica' => '', + '$statusnet' => '', + '$diaspora' => '', + '$diasnote' => '', + '$your_address' => L10n::t('Your Identity Address:'), + '$invite_desc' => '', + '$emailnet' => '', + '$submit' => L10n::t('Submit Request'), + '$cancel' => L10n::t('Cancel'), + '$nickname' => '', + '$name' => $contact['name'], + '$url' => $contact['url'], + '$zrl' => Contact::magicLink($contact['url']), + '$url_label' => L10n::t('Profile URL'), + '$myaddr' => $self['url'], + '$request' => $request, + '$keywords' => '', + '$keywords_label'=> '' ]); - $a->page['aside'] = ""; - Profile::load($a, "", 0, Contact::getDetailsByURL($contact["url"])); + $a->page['aside'] = ''; + Profile::load($a, '', 0, Contact::getDetailsByURL($contact['url'])); $o .= replace_macros(get_markup_template('section_title.tpl'), ['$title' => L10n::t('Status Messages and Posts')]); // Show last public posts - $o .= Contact::getPostsFromUrl($contact["url"]); + $o .= Contact::getPostsFromUrl($contact['url']); return $o; } diff --git a/mod/update_contacts.php b/mod/update_contacts.php new file mode 100644 index 0000000000..1144ed1427 --- /dev/null +++ b/mod/update_contacts.php @@ -0,0 +1,38 @@ +\r\n"; + echo "
      "; + + if ($_GET["force"] == 1) { + $text = Contact::content($a, true); + } else { + $text = ''; + } + + if (PConfig::get(local_user(), "system", "bandwidth_saver")) { + $replace = "
      ".L10n::t("[Embedded content - reload page to view]")."
      "; + $pattern = "/<\s*audio[^>]*>(.*?)<\s*\/\s*audio>/i"; + $text = preg_replace($pattern, $replace, $text); + $pattern = "/<\s*video[^>]*>(.*?)<\s*\/\s*video>/i"; + $text = preg_replace($pattern, $replace, $text); + $pattern = "/<\s*embed[^>]*>(.*?)<\s*\/\s*embed>/i"; + $text = preg_replace($pattern, $replace, $text); + $pattern = "/<\s*iframe[^>]*>(.*?)<\s*\/\s*iframe>/i"; + $text = preg_replace($pattern, $replace, $text); + } + + echo str_replace("\t", " ", $text); + echo "
      "; + echo "\r\n"; + killme(); +} diff --git a/mod/videos.php b/mod/videos.php index e622e17f0f..e52c78cab1 100644 --- a/mod/videos.php +++ b/mod/videos.php @@ -105,12 +105,6 @@ function videos_init(App $a) $a->page['htmlhead'] .= replace_macros($tpl,[ '$baseurl' => System::baseUrl(), ]); - - $tpl = get_markup_template("videos_end.tpl"); - $a->page['end'] .= replace_macros($tpl,[ - '$baseurl' => System::baseUrl(), - ]); - } return; @@ -347,8 +341,8 @@ function videos_content(App $a) ); if (DBA::isResult($r)) { - $a->set_pager_total(count($r)); - $a->set_pager_itemspage(20); + $a->setPagerTotal(count($r)); + $a->setPagerItemsPage(20); } $r = q("SELECT hash, ANY_VALUE(`id`) AS `id`, ANY_VALUE(`created`) AS `created`, @@ -367,11 +361,12 @@ function videos_content(App $a) foreach ($r as $rr) { $alt_e = $rr['filename']; /// @todo The album isn't part of the above query. This seems to be some unfinished code that needs to be reworked completely. + $rr['album'] = ''; $name_e = $rr['album']; $videos[] = [ 'id' => $rr['id'], - 'link' => System::baseUrl() . '/videos/' . $a->data['user']['nickname'] . '/video/' . $rr['resource-id'], + 'link' => System::baseUrl() . '/videos/' . $a->data['user']['nickname'] . '/video/' . $rr['hash'], 'title' => L10n::t('View Video'), 'src' => System::baseUrl() . '/attach/' . $rr['id'] . '?attachment=0', 'alt' => $alt_e, diff --git a/mod/viewcontacts.php b/mod/viewcontacts.php index 9446470e1b..563c13c6d4 100644 --- a/mod/viewcontacts.php +++ b/mod/viewcontacts.php @@ -71,7 +71,7 @@ function viewcontacts_content(App $a) DBA::escape(Protocol::OSTATUS) ); if (DBA::isResult($r)) { - $a->set_pager_total($r[0]['total']); + $a->setPagerTotal($r[0]['total']); } $r = q("SELECT * FROM `contact` diff --git a/mod/viewsrc.php b/mod/viewsrc.php index afdcaada22..7ed029aa78 100644 --- a/mod/viewsrc.php +++ b/mod/viewsrc.php @@ -26,7 +26,7 @@ function viewsrc_content(App $a) $item = Item::selectFirst(['body'], ['uid' => local_user(), 'id' => $item_id]); if (DBA::isResult($item)) { - if (is_ajax()) { + if ($a->isAjax()) { echo str_replace("\n", '
      ', $item['body']); killme(); } else { diff --git a/mod/wallmessage.php b/mod/wallmessage.php index 5606b6feed..5e08420ecb 100644 --- a/mod/wallmessage.php +++ b/mod/wallmessage.php @@ -120,13 +120,6 @@ function wallmessage_content(App $a) { '$linkurl' => L10n::t('Please enter a link URL:') ]); - $tpl = get_markup_template('wallmsg-end.tpl'); - $a->page['end'] .= replace_macros($tpl, [ - '$baseurl' => System::baseUrl(true), - '$nickname' => $user['nickname'], - '$linkurl' => L10n::t('Please enter a link URL:') - ]); - $tpl = get_markup_template('wallmessage.tpl'); $o = replace_macros($tpl, [ '$header' => L10n::t('Send Private Message'), diff --git a/mod/webfinger.php b/mod/webfinger.php index 6f49a8f28c..4f23db6d8f 100644 --- a/mod/webfinger.php +++ b/mod/webfinger.php @@ -23,7 +23,7 @@ function webfinger_content(App $a) $o = '

      Webfinger Diagnostic

      '; $o .= ''; - $o .= 'Lookup address: '; + $o .= 'Lookup address: '; $o .= ''; $o .= '

      '; diff --git a/mod/xrd.php b/mod/xrd.php index 61505f2996..1d29d7904a 100644 --- a/mod/xrd.php +++ b/mod/xrd.php @@ -13,7 +13,7 @@ function xrd_init(App $a) { if ($a->argv[0] == 'xrd') { if (empty($_GET['uri'])) { - killme(); + System::httpExit(404); } $uri = urldecode(notags(trim($_GET['uri']))); @@ -24,7 +24,7 @@ function xrd_init(App $a) } } else { if (empty($_GET['resource'])) { - killme(); + System::httpExit(404); } $uri = urldecode(notags(trim($_GET['resource']))); @@ -48,16 +48,16 @@ function xrd_init(App $a) $user = DBA::selectFirst('user', [], ['nickname' => $name]); if (!DBA::isResult($user)) { - killme(); + System::httpExit(404); } $profile_url = System::baseUrl().'/profile/'.$user['nickname']; $alias = str_replace('/profile/', '/~', $profile_url); - $addr = 'acct:'.$user['nickname'].'@'.$a->get_hostname(); - if ($a->get_path()) { - $addr .= '/'.$a->get_path(); + $addr = 'acct:'.$user['nickname'].'@'.$a->getHostName(); + if ($a->getURLPath()) { + $addr .= '/'.$a->getURLPath(); } if ($mode == 'xml') { @@ -80,6 +80,7 @@ function xrd_json($a, $uri, $alias, $profile_url, $r) ['rel' => NAMESPACE_DFRN, 'href' => $profile_url], ['rel' => NAMESPACE_FEED, 'type' => 'application/atom+xml', 'href' => System::baseUrl().'/dfrn_poll/'.$r['nickname']], ['rel' => 'http://webfinger.net/rel/profile-page', 'type' => 'text/html', 'href' => $profile_url], + ['rel' => 'self', 'type' => 'application/activity+json', 'href' => $profile_url], ['rel' => 'http://microformats.org/profile/hcard', 'type' => 'text/html', 'href' => System::baseUrl().'/hcard/'.$r['nickname']], ['rel' => NAMESPACE_POCO, 'href' => System::baseUrl().'/poco/'.$r['nickname']], ['rel' => 'http://webfinger.net/rel/avatar', 'type' => 'image/jpeg', 'href' => System::baseUrl().'/photo/profile/'.$r['uid'].'.jpg'], @@ -92,6 +93,7 @@ function xrd_json($a, $uri, $alias, $profile_url, $r) ['rel' => 'http://purl.org/openwebauth/v1', 'type' => 'application/x-dfrn+json', 'href' => System::baseUrl().'/owa'] ] ]; + echo json_encode($json); killme(); } diff --git a/src/App.php b/src/App.php index 2a5fba8541..97c193b3b7 100644 --- a/src/App.php +++ b/src/App.php @@ -11,6 +11,7 @@ use Friendica\Core\L10n; use Friendica\Core\PConfig; use Friendica\Core\System; use Friendica\Database\DBA; +use Friendica\Network\HTTPException\InternalServerErrorException; require_once 'boot.php'; require_once 'include/dba.php'; @@ -31,21 +32,6 @@ require_once 'include/text.php'; */ class App { - const MODE_LOCALCONFIGPRESENT = 1; - const MODE_DBAVAILABLE = 2; - const MODE_DBCONFIGAVAILABLE = 4; - const MODE_MAINTENANCEDISABLED = 8; - - /** - * @deprecated since version 2008.08 Use App->isInstallMode() instead to check for install mode. - */ - const MODE_INSTALL = 0; - - /** - * @deprecated since version 2008.08 Use the precise mode constant to check for a specific capability instead. - */ - const MODE_NORMAL = App::MODE_LOCALCONFIGPRESENT | App::MODE_DBAVAILABLE | App::MODE_DBCONFIGAVAILABLE | App::MODE_MAINTENANCEDISABLED; - public $module_loaded = false; public $module_class = null; public $query_string = ''; @@ -67,10 +53,7 @@ class App public $argv; public $argc; public $module; - public $mode = App::MODE_INSTALL; public $strings; - public $basepath; - public $urlpath; public $hooks = []; public $timezone; public $interactive = true; @@ -80,11 +63,9 @@ class App public $identities; public $is_mobile = false; public $is_tablet = false; - public $is_friendica_app; public $performance = []; public $callstack = []; public $theme_info = []; - public $backend = true; public $nav_sel; public $category; // Allow themes to control internal parameters @@ -96,6 +77,76 @@ class App public $force_max_items = 0; public $theme_events_in_profile = true; + public $stylesheets = []; + public $footerScripts = []; + + /** + * @var App\Mode The Mode of the Application + */ + private $mode; + + /** + * @var string The App base path + */ + private $basePath; + + /** + * @var string The App URL path + */ + private $urlPath; + + /** + * @var bool true, if the call is from the Friendica APP, otherwise false + */ + private $isFriendicaApp; + + /** + * @var bool true, if the call is from an backend node (f.e. worker) + */ + private $isBackend; + + /** + * @var string The name of the current theme + */ + private $currentTheme; + + /** + * @var bool check if request was an AJAX (xmlhttprequest) request + */ + private $isAjax; + + /** + * Register a stylesheet file path to be included in the tag of every page. + * Inclusion is done in App->initHead(). + * The path can be absolute or relative to the Friendica installation base folder. + * + * @see App->initHead() + * + * @param string $path + */ + public function registerStylesheet($path) + { + $url = str_replace($this->getBasePath() . DIRECTORY_SEPARATOR, '', $path); + + $this->stylesheets[] = trim($url, '/'); + } + + /** + * Register a javascript file path to be included in the