MYSQL_DATABASE: friendica
MYSQL_HOST: mysql
+node:
+ test: db
+
services:
- name: mysql
image: mysql:8.0
MYSQL_DATABASE: friendica
MYSQL_HOST: mysql
+node:
+ test: db
+
services:
- name: mysql
image: mysql:8.0
MYSQL_DATABASE: friendica
MYSQL_HOST: mysql
+node:
+ test: db
+
services:
- name: mysql
image: mysql:8.0
MYSQL_DATABASE: friendica
MYSQL_HOST: mariadb
+node:
+ test: db
+
services:
- name: mariadb
image: mariadb:10.1
MYSQL_DATABASE: friendica
MYSQL_HOST: mariadb
+node:
+ test: db
+
services:
- name: mariadb
image: mariadb:10.1
MYSQL_DATABASE: friendica
MYSQL_HOST: mariadb
+node:
+ test: db
+
services:
- name: mariadb
image: mariadb:10.1
- mysql -utravis test < database.sql
- pecl channel-update pecl.php.net
- pecl config-set preferred_state beta
- - if [[ $TRAVIS_PHP_VERSION != "7.1" ]]; then echo yes | pecl upgrade apcu; fi
- - if [[ $TRAVIS_PHP_VERSION != "7.1" ]]; then phpenv config-add .travis/apcu.ini; fi
- phpenv config-add .travis/redis.ini
- phpenv config-add .travis/memcached.ini
/** @deprecated since 2019.03, use Term::OBJECT_TYPE_PHOTO instead */
define('TERM_OBJ_PHOTO', Term::OBJECT_TYPE_PHOTO);
-/**
- * @name Namespaces
- *
- * Various namespaces we may need to parse
- * @{
- */
-define('NAMESPACE_ZOT', 'http://purl.org/zot');
-define('NAMESPACE_DFRN', 'http://purl.org/macgirvin/dfrn/1.0');
-define('NAMESPACE_THREAD', 'http://purl.org/syndication/thread/1.0');
-define('NAMESPACE_TOMB', 'http://purl.org/atompub/tombstones/1.0');
-define('NAMESPACE_ACTIVITY2', 'https://www.w3.org/ns/activitystreams#');
-define('NAMESPACE_ACTIVITY', 'http://activitystrea.ms/spec/1.0/');
-define('NAMESPACE_ACTIVITY_SCHEMA', 'http://activitystrea.ms/schema/1.0/');
-define('NAMESPACE_MEDIA', 'http://purl.org/syndication/atommedia');
-define('NAMESPACE_SALMON_ME', 'http://salmon-protocol.org/ns/magic-env');
-define('NAMESPACE_OSTATUSSUB', 'http://ostatus.org/schema/1.0/subscribe');
-define('NAMESPACE_GEORSS', 'http://www.georss.org/georss');
-define('NAMESPACE_POCO', 'http://portablecontacts.net/spec/1.0');
-define('NAMESPACE_FEED', 'http://schemas.google.com/g/2010#updates-from');
-define('NAMESPACE_OSTATUS', 'http://ostatus.org/schema/1.0');
-define('NAMESPACE_STATUSNET', 'http://status.net/schema/api/1/');
-define('NAMESPACE_ATOM1', 'http://www.w3.org/2005/Atom');
-define('NAMESPACE_MASTODON', 'http://mastodon.social/schema/1.0');
-/* @}*/
-
-/**
- * @name Activity
- *
- * Activity stream defines
- * @{
- */
-define('ACTIVITY_LIKE', NAMESPACE_ACTIVITY_SCHEMA . 'like');
-define('ACTIVITY_DISLIKE', NAMESPACE_DFRN . '/dislike');
-define('ACTIVITY_ATTEND', NAMESPACE_ZOT . '/activity/attendyes');
-define('ACTIVITY_ATTENDNO', NAMESPACE_ZOT . '/activity/attendno');
-define('ACTIVITY_ATTENDMAYBE', NAMESPACE_ZOT . '/activity/attendmaybe');
-
-define('ACTIVITY_OBJ_HEART', NAMESPACE_DFRN . '/heart');
-
-define('ACTIVITY_FRIEND', NAMESPACE_ACTIVITY_SCHEMA . 'make-friend');
-define('ACTIVITY_REQ_FRIEND', NAMESPACE_ACTIVITY_SCHEMA . 'request-friend');
-define('ACTIVITY_UNFRIEND', NAMESPACE_ACTIVITY_SCHEMA . 'remove-friend');
-define('ACTIVITY_FOLLOW', NAMESPACE_ACTIVITY_SCHEMA . 'follow');
-define('ACTIVITY_UNFOLLOW', NAMESPACE_ACTIVITY_SCHEMA . 'stop-following');
-define('ACTIVITY_JOIN', NAMESPACE_ACTIVITY_SCHEMA . 'join');
-
-define('ACTIVITY_POST', NAMESPACE_ACTIVITY_SCHEMA . 'post');
-define('ACTIVITY_UPDATE', NAMESPACE_ACTIVITY_SCHEMA . 'update');
-define('ACTIVITY_TAG', NAMESPACE_ACTIVITY_SCHEMA . 'tag');
-define('ACTIVITY_FAVORITE', NAMESPACE_ACTIVITY_SCHEMA . 'favorite');
-define('ACTIVITY_UNFAVORITE', NAMESPACE_ACTIVITY_SCHEMA . 'unfavorite');
-define('ACTIVITY_SHARE', NAMESPACE_ACTIVITY_SCHEMA . 'share');
-define('ACTIVITY_DELETE', NAMESPACE_ACTIVITY_SCHEMA . 'delete');
-define('ACTIVITY2_ANNOUNCE', NAMESPACE_ACTIVITY2 . 'Announce');
-
-define('ACTIVITY_POKE', NAMESPACE_ZOT . '/activity/poke');
-
-define('ACTIVITY_OBJ_BOOKMARK', NAMESPACE_ACTIVITY_SCHEMA . 'bookmark');
-define('ACTIVITY_OBJ_COMMENT', NAMESPACE_ACTIVITY_SCHEMA . 'comment');
-define('ACTIVITY_OBJ_NOTE', NAMESPACE_ACTIVITY_SCHEMA . 'note');
-define('ACTIVITY_OBJ_PERSON', NAMESPACE_ACTIVITY_SCHEMA . 'person');
-define('ACTIVITY_OBJ_IMAGE', NAMESPACE_ACTIVITY_SCHEMA . 'image');
-define('ACTIVITY_OBJ_PHOTO', NAMESPACE_ACTIVITY_SCHEMA . 'photo');
-define('ACTIVITY_OBJ_VIDEO', NAMESPACE_ACTIVITY_SCHEMA . 'video');
-define('ACTIVITY_OBJ_P_PHOTO', NAMESPACE_ACTIVITY_SCHEMA . 'profile-photo');
-define('ACTIVITY_OBJ_ALBUM', NAMESPACE_ACTIVITY_SCHEMA . 'photo-album');
-define('ACTIVITY_OBJ_EVENT', NAMESPACE_ACTIVITY_SCHEMA . 'event');
-define('ACTIVITY_OBJ_GROUP', NAMESPACE_ACTIVITY_SCHEMA . 'group');
-define('ACTIVITY_OBJ_TAGTERM', NAMESPACE_DFRN . '/tagterm');
-define('ACTIVITY_OBJ_PROFILE', NAMESPACE_DFRN . '/profile');
-define('ACTIVITY_OBJ_QUESTION', 'http://activityschema.org/object/question');
-/* @}*/
-
/**
* @name Gravity
*
return BaseObject::getApp();
}
-/**
- * Return the provided variable value if it exists and is truthy or the provided
- * default value instead.
- *
- * Works with initialized variables and potentially uninitialized array keys
- *
- * Usages:
- * - defaults($var, $default)
- * - defaults($array, 'key', $default)
- *
- * @param array $args
- * @brief Returns a defaut value if the provided variable or array key is falsy
- * @return mixed
- * @deprecated since version 2019.06, use native coalesce operator (??) instead
- */
-function defaults(...$args)
-{
- if (count($args) < 2) {
- throw new BadFunctionCallException('defaults() requires at least 2 parameters');
- }
- if (count($args) > 3) {
- throw new BadFunctionCallException('defaults() cannot use more than 3 parameters');
- }
- if (count($args) === 3 && is_null($args[1])) {
- throw new BadFunctionCallException('defaults($arr, $key, $def) $key is null');
- }
-
- // The default value always is the last argument
- $return = array_pop($args);
-
- if (count($args) == 2 && is_array($args[0]) && !empty($args[0][$args[1]])) {
- $return = $args[0][$args[1]];
- }
-
- if (count($args) == 1 && !empty($args[0])) {
- $return = $args[0];
- }
-
- return $return;
-}
-
/**
* @brief Used to end the current process, after saving session state.
* @deprecated
$adminlist = explode(',', str_replace(' ', '', $admin_email));
- return local_user() && $admin_email && in_array(defaults($a->user, 'email', ''), $adminlist);
+ return local_user() && $admin_email && in_array($a->user['email'] ?? '', $adminlist);
}
function explode_querystring($query)
"ext-xml": "*",
"asika/simple-console": "^1.0",
"bacon/bacon-qr-code": "^1.0",
- "divineomega/password_exposed": "^2.4",
- "ezyang/htmlpurifier": "~4.7.0",
+ "divineomega/password_exposed": "^2.8",
+ "ezyang/htmlpurifier": "^4.7",
"friendica/json-ld": "^1.0",
- "league/html-to-markdown": "~4.8.0",
- "level-2/dice": ">1.0",
+ "league/html-to-markdown": "^4.8",
+ "level-2/dice": "^4",
"lightopenid/lightopenid": "dev-master",
"michelf/php-markdown": "^1.7",
- "mobiledetect/mobiledetectlib": "2.8.*",
- "monolog/monolog": "^1.24",
+ "mobiledetect/mobiledetectlib": "^2.8",
+ "monolog/monolog": "^1.25",
"nikic/fast-route": "^1.3",
"paragonie/hidden-string": "^1.0",
"pear/console_table": "^1.3",
"psr/container": "^1.0",
"seld/cli-prompt": "^1.0",
"smarty/smarty": "^3.1",
- "fxp/composer-asset-plugin": "~1.3",
+ "fxp/composer-asset-plugin": "^1.4",
"bower-asset/base64": "^1.0",
- "bower-asset/chart-js": "^2.7",
+ "bower-asset/chart-js": "^2.8",
"bower-asset/dompurify": "^1.0",
"bower-asset/perfect-scrollbar": "^0.6",
- "bower-asset/vue": "^2.5",
+ "bower-asset/vue": "^2.6",
"npm-asset/jquery": "^2.0",
"npm-asset/jquery-colorbox": "^1.6",
- "npm-asset/jquery-datetimepicker": "^2.4.0",
+ "npm-asset/jquery-datetimepicker": "^2.5",
"npm-asset/jgrowl": "^1.4",
- "npm-asset/moment": "^2.20.1",
- "npm-asset/fullcalendar": "^3.0.1",
+ "npm-asset/moment": "^2.24",
+ "npm-asset/fullcalendar": "^3.10",
"npm-asset/cropperjs": "1.2.2",
"npm-asset/imagesloaded": "4.1.4",
"npm-asset/typeahead.js": "^0.11.1",
"include/dba.php",
"include/enotify.php",
"include/items.php",
- "include/text.php",
"boot.php"
]
},
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
- "content-hash": "eda94f02683bea49b3d506d770749277",
+ "content-hash": "34ad225ce21474eb84ce78047d9f2c01",
"packages": [
{
"name": "asika/simple-console",
"dist": {
"type": "tar",
"url": "https://registry.npmjs.org/cropperjs/-/cropperjs-1.2.2.tgz",
+ "reference": null,
"shasum": "30dc7a7ce872155b23a33bd10ad4c76c0d613f55"
},
"require-dev": {
"dist": {
"type": "tar",
"url": "https://registry.npmjs.org/ev-emitter/-/ev-emitter-1.1.1.tgz",
+ "reference": null,
"shasum": "8f18b0ce5c76a5d18017f71c0a795c65b9138f2a"
},
"type": "npm-asset-library",
"dist": {
"type": "tar",
"url": "https://registry.npmjs.org/fullcalendar/-/fullcalendar-3.10.1.tgz",
+ "reference": null,
"shasum": "cca3f9a2656a7e978a3f3facb7f35934a91185db"
},
"type": "npm-asset-library",
"dist": {
"type": "tar",
"url": "https://registry.npmjs.org/imagesloaded/-/imagesloaded-4.1.4.tgz",
+ "reference": null,
"shasum": "1376efcd162bb768c34c3727ac89cc04051f3cc7"
},
"require": {
"dist": {
"type": "tar",
"url": "https://registry.npmjs.org/jgrowl/-/jgrowl-1.4.6.tgz",
+ "reference": null,
"shasum": "2736e332aaee73ccf0a14a5f0066391a0a13f4a3"
},
"require-dev": {
"dist": {
"type": "tar",
"url": "https://registry.npmjs.org/jquery/-/jquery-2.2.4.tgz",
+ "reference": null,
"shasum": "2c89d6889b5eac522a7eea32c14521559c6cbf02"
},
"require-dev": {
"dist": {
"type": "tar",
"url": "https://registry.npmjs.org/jquery-colorbox/-/jquery-colorbox-1.6.4.tgz",
+ "reference": null,
"shasum": "799452523a6c494839224ef702e807deb9c06cc5"
},
"require": {
"dist": {
"type": "tar",
"url": "https://registry.npmjs.org/jquery-datetimepicker/-/jquery-datetimepicker-2.5.21.tgz",
+ "reference": null,
"shasum": "00c388a78df2732fedfdb5c6529b6e84d53e0235"
},
"require": {
"dist": {
"type": "tar",
"url": "https://registry.npmjs.org/jquery-mousewheel/-/jquery-mousewheel-3.1.13.tgz",
+ "reference": null,
"shasum": "06f0335f16e353a695e7206bf50503cb523a6ee5"
},
"require-dev": {
"dist": {
"type": "tar",
"url": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz",
+ "reference": null,
"shasum": "0d055d53f5052aa653c9f6eb68bb5d12bf5c2b5b"
},
"type": "npm-asset-library",
"dist": {
"type": "tar",
"url": "https://registry.npmjs.org/typeahead.js/-/typeahead.js-0.11.1.tgz",
+ "reference": null,
"shasum": "4e64e671b22310a8606f4aec805924ba84b015b8"
},
"require": {
"packages-dev": [
{
"name": "doctrine/instantiator",
- "version": "1.2.0",
+ "version": "1.0.5",
"source": {
"type": "git",
"url": "https://github.com/doctrine/instantiator.git",
- "reference": "a2c590166b2133a4633738648b6b064edae0814a"
+ "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/doctrine/instantiator/zipball/a2c590166b2133a4633738648b6b064edae0814a",
- "reference": "a2c590166b2133a4633738648b6b064edae0814a",
+ "url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d",
+ "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d",
"shasum": ""
},
"require": {
- "php": "^7.1"
+ "php": ">=5.3,<8.0-DEV"
},
"require-dev": {
- "doctrine/coding-standard": "^6.0",
+ "athletic/athletic": "~0.1.8",
"ext-pdo": "*",
"ext-phar": "*",
- "phpbench/phpbench": "^0.13",
- "phpstan/phpstan-phpunit": "^0.11",
- "phpstan/phpstan-shim": "^0.11",
- "phpunit/phpunit": "^7.0"
+ "phpunit/phpunit": "~4.0",
+ "squizlabs/php_codesniffer": "~2.0"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.2.x-dev"
+ "dev-master": "1.0.x-dev"
}
},
"autoload": {
}
],
"description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors",
- "homepage": "https://www.doctrine-project.org/projects/instantiator.html",
+ "homepage": "https://github.com/doctrine/instantiator",
"keywords": [
"constructor",
"instantiate"
],
- "time": "2019-03-17T17:37:11+00:00"
+ "time": "2015-06-14T21:17:01+00:00"
},
{
"name": "hamcrest/hamcrest-php",
},
{
"name": "myclabs/deep-copy",
- "version": "1.9.3",
+ "version": "1.7.0",
"source": {
"type": "git",
"url": "https://github.com/myclabs/DeepCopy.git",
- "reference": "007c053ae6f31bba39dfa19a7726f56e9763bbea"
+ "reference": "3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/007c053ae6f31bba39dfa19a7726f56e9763bbea",
- "reference": "007c053ae6f31bba39dfa19a7726f56e9763bbea",
+ "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e",
+ "reference": "3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e",
"shasum": ""
},
"require": {
- "php": "^7.1"
- },
- "replace": {
- "myclabs/deep-copy": "self.version"
+ "php": "^5.6 || ^7.0"
},
"require-dev": {
"doctrine/collections": "^1.0",
"doctrine/common": "^2.6",
- "phpunit/phpunit": "^7.1"
+ "phpunit/phpunit": "^4.1"
},
"type": "library",
"autoload": {
"object",
"object graph"
],
- "time": "2019-08-09T12:45:53+00:00"
+ "time": "2017-10-19T19:58:43+00:00"
},
{
"name": "phpdocumentor/reflection-common",
}
],
"description": "Provides the functionality to compare PHP values for equality",
- "homepage": "http://www.github.com/sebastianbergmann/comparator",
+ "homepage": "https://github.com/sebastianbergmann/comparator",
"keywords": [
"comparator",
"compare",
}
],
"description": "Provides functionality to handle HHVM/PHP environments",
- "homepage": "http://www.github.com/sebastianbergmann/environment",
+ "homepage": "https://github.com/sebastianbergmann/environment",
"keywords": [
"Xdebug",
"environment",
}
],
"description": "Provides the functionality to export PHP variables for visualization",
- "homepage": "http://www.github.com/sebastianbergmann/exporter",
+ "homepage": "https://github.com/sebastianbergmann/exporter",
"keywords": [
"export",
"exporter"
}
],
"description": "Snapshotting of global state",
- "homepage": "http://www.github.com/sebastianbergmann/global-state",
+ "homepage": "https://github.com/sebastianbergmann/global-state",
"keywords": [
"global state"
],
}
],
"description": "Provides functionality to recursively process PHP variables",
- "homepage": "http://www.github.com/sebastianbergmann/recursion-context",
+ "homepage": "https://github.com/sebastianbergmann/recursion-context",
"time": "2016-11-19T07:33:16+00:00"
},
{
},
{
"name": "symfony/yaml",
- "version": "v4.3.4",
+ "version": "v3.4.32",
"source": {
"type": "git",
"url": "https://github.com/symfony/yaml.git",
- "reference": "5a0b7c32dc3ec56fd4abae8a4a71b0cf05013686"
+ "reference": "768f817446da74a776a31eea335540f9dcb53942"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/yaml/zipball/5a0b7c32dc3ec56fd4abae8a4a71b0cf05013686",
- "reference": "5a0b7c32dc3ec56fd4abae8a4a71b0cf05013686",
+ "url": "https://api.github.com/repos/symfony/yaml/zipball/768f817446da74a776a31eea335540f9dcb53942",
+ "reference": "768f817446da74a776a31eea335540f9dcb53942",
"shasum": ""
},
"require": {
- "php": "^7.1.3",
+ "php": "^5.5.9|>=7.0.8",
"symfony/polyfill-ctype": "~1.8"
},
"conflict": {
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "4.3-dev"
+ "dev-master": "3.4-dev"
}
},
"autoload": {
],
"description": "Symfony Yaml Component",
"homepage": "https://symfony.com",
- "time": "2019-08-20T14:27:59+00:00"
+ "time": "2019-09-10T10:38:46+00:00"
},
{
"name": "webmozart/assert",
Hook::callAll('item_photo_menu', $args);
Hook::callAll('jot_tool', $jotplugins);
-### include/text.php
-
- Hook::callAll('contact_block_end', $arr);
- Hook::callAll('poke_verbs', $arr);
- Hook::callAll('put_item_in_cache', $hook_data);
- Hook::callAll('prepare_body_init', $item);
- Hook::callAll('prepare_body_content_filter', $hook_data);
- Hook::callAll('prepare_body', $hook_data);
- Hook::callAll('prepare_body_final', $hook_data);
-
### include/items.php
Hook::callAll('page_info_data', $data);
Hook::callAll("parse_link", $arr);
-### mod/manage.php
+### src/Module/Delegation.php
Hook::callAll('home_init', $ret);
Hook::callAll('post_remote_end', $posted_item);
Hook::callAll('tagged', $arr);
Hook::callAll('post_local_end', $new_item);
+ Hook::callAll('put_item_in_cache', $hook_data);
+ Hook::callAll('prepare_body_init', $item);
+ Hook::callAll('prepare_body_content_filter', $hook_data);
+ Hook::callAll('prepare_body', $hook_data);
+ Hook::callAll('prepare_body_final', $hook_data);
### src/Model/Contact.php
Hook::callAll('register_account', $uid);
Hook::callAll('remove_user', $user);
+### src/Content/ContactBlock.php
+
+ Hook::callAll('contact_block_end', $arr);
+
### src/Content/Text/BBCode.php
Hook::callAll('bbcode', $text);
self::callSingle(self::getApp(), 'hook_fork', $fork_hook, $hookdata);
+### src/Core/L10n/L10n.php
+
+ Hook::callAll('poke_verbs', $arr);
+
### src/Core/Worker.php
Hook::callAll("proc_run", $arr);
* No closing PHP tag
* No trailing spaces
* Array declarations use the new square brackets syntax
+* Quoting style is single quotes by default, except for needed string interpolation, SQL query strings by convention and comments that should stay in natural language.
Don't worry, you don't have to know by heart the PSR-2 coding standards to start contributing to Friendica.
There are a few tools you can use to check or fix your files before you commit.
Hook::callAll('item_photo_menu', $args);
Hook::callAll('jot_tool', $jotplugins);
-### include/text.php
-
- Hook::callAll('contact_block_end', $arr);
- Hook::callAll('poke_verbs', $arr);
- Hook::callAll('put_item_in_cache', $hook_data);
- Hook::callAll('prepare_body_init', $item);
- Hook::callAll('prepare_body_content_filter', $hook_data);
- Hook::callAll('prepare_body', $hook_data);
- Hook::callAll('prepare_body_final', $hook_data);
-
### include/items.php
Hook::callAll('page_info_data', $data);
Hook::callAll("parse_link", $arr);
-### mod/manage.php
+### src/Module/Delegation.php
Hook::callAll('home_init', $ret);
Hook::callAll('post_remote_end', $posted_item);
Hook::callAll('tagged', $arr);
Hook::callAll('post_local_end', $new_item);
+ Hook::callAll('put_item_in_cache', $hook_data);
+ Hook::callAll('prepare_body_init', $item);
+ Hook::callAll('prepare_body_content_filter', $hook_data);
+ Hook::callAll('prepare_body', $hook_data);
+ Hook::callAll('prepare_body_final', $hook_data);
### src/Model/Contact.php
Hook::callAll('register_account', $uid);
Hook::callAll('remove_user', $user);
+
+### src/Content/ContactBlock.php
+
+ Hook::callAll('contact_block_end', $arr);
### src/Content/Text/BBCode.php
Hook::callAll($a->module.'_post_'.$selname, $o);
Hook::callAll('jot_networks', $jotnets);
+### src/Core/Authentication.php
+
+ Hook::callAll('logged_in', $a->user);
+
+### src/Core/Hook.php
+
+ self::callSingle(self::getApp(), 'hook_fork', $fork_hook, $hookdata);
+
+### src/Core/L10n/L10n.php
+
+ Hook::callAll('poke_verbs', $arr);
+
### src/Core/Worker.php
Hook::callAll("proc_run", $arr);
*/
use Friendica\App;
+use Friendica\BaseObject;
use Friendica\Content\ContactSelector;
use Friendica\Content\Feature;
use Friendica\Content\Text\BBCode;
use Friendica\Core\Hook;
use Friendica\Core\L10n;
use Friendica\Core\Logger;
-use Friendica\Core\NotificationsManager;
use Friendica\Core\PConfig;
use Friendica\Core\Protocol;
use Friendica\Core\Session;
use Friendica\Model\Group;
use Friendica\Model\Item;
use Friendica\Model\Mail;
+use Friendica\Model\Notify;
use Friendica\Model\Photo;
use Friendica\Model\Profile;
use Friendica\Model\User;
use Friendica\Network\HTTPException\TooManyRequestsException;
use Friendica\Network\HTTPException\UnauthorizedException;
use Friendica\Object\Image;
+use Friendica\Protocol\Activity;
use Friendica\Protocol\Diaspora;
use Friendica\Util\DateTimeFormat;
use Friendica\Util\Network;
throw new UnauthorizedException("This API requires login");
}
- $user = defaults($_SERVER, 'PHP_AUTH_USER', '');
- $password = defaults($_SERVER, 'PHP_AUTH_PW', '');
+ $user = $_SERVER['PHP_AUTH_USER'] ?? '';
+ $password = $_SERVER['PHP_AUTH_PW'] ?? '';
// allow "user@server" login (but ignore 'server' part)
$at = strstr($user, "@", true);
if ($method == "*") {
return true;
}
- return (stripos($method, defaults($_SERVER, 'REQUEST_METHOD', 'GET')) !== false);
+ return (stripos($method, $_SERVER['REQUEST_METHOD'] ?? 'GET') !== false);
}
/**
$stamp = microtime(true);
$return = call_user_func($info['func'], $type);
- $duration = (float) (microtime(true) - $stamp);
+ $duration = floatval(microtime(true) - $stamp);
Logger::info(API_LOG_PREFIX . 'username {username}', ['module' => 'api', 'action' => 'call', 'username' => $a->user['username'], 'duration' => round($duration, 2)]);
*/
function api_item_get_user(App $a, $item)
{
- $status_user = api_get_user($a, defaults($item, 'author-id', null));
+ $status_user = api_get_user($a, $item['author-id'] ?? null);
$author_user = $status_user;
- $status_user["protected"] = defaults($item, 'private', 0);
+ $status_user["protected"] = $item['private'] ?? 0;
- if (defaults($item, 'thr-parent', '') == defaults($item, 'uri', '')) {
- $owner_user = api_get_user($a, defaults($item, 'owner-id', null));
+ if (($item['thr-parent'] ?? '') == ($item['uri'] ?? '')) {
+ $owner_user = api_get_user($a, $item['owner-id'] ?? null);
} else {
$owner_user = $author_user;
}
unset($_REQUEST["screen_name"]);
unset($_GET["screen_name"]);
- $skip_status = defaults($_REQUEST, 'skip_status', false);
+ $skip_status = $_REQUEST['skip_status'] ?? false;
$user_info = api_get_user($a);
*/
function api_users_show($type)
{
- $a = \Friendica\BaseObject::getApp();
+ $a = BaseObject::getApp();
$user_info = api_get_user($a);
$count = $_REQUEST['count'];
}
- $since_id = defaults($_REQUEST, 'since_id', 0);
- $max_id = defaults($_REQUEST, 'max_id', 0);
- $page = (!empty($_REQUEST['page']) ? $_REQUEST['page'] - 1 : 0);
- $start = $page * $count;
+ $since_id = $_REQUEST['since_id'] ?? 0;
+ $max_id = $_REQUEST['max_id'] ?? 0;
+ $page = $_REQUEST['page'] ?? 1;
+
+ $start = max(0, ($page - 1) * $count);
+
$params = ['order' => ['id' => true], 'limit' => [$start, $count]];
if (preg_match('/^#(\w+)$/', $searchTerm, $matches) === 1 && isset($matches[1])) {
$searchTerm = $matches[1];
// get last network messages
// params
- $count = defaults($_REQUEST, 'count', 20);
- $page = (!empty($_REQUEST['page']) ? $_REQUEST['page'] - 1 : 0);
- if ($page < 0) {
- $page = 0;
- }
- $since_id = defaults($_REQUEST, 'since_id', 0);
- $max_id = defaults($_REQUEST, 'max_id', 0);
+ $count = $_REQUEST['count'] ?? 20;
+ $page = $_REQUEST['page']?? 0;
+ $since_id = $_REQUEST['since_id'] ?? 0;
+ $max_id = $_REQUEST['max_id'] ?? 0;
$exclude_replies = !empty($_REQUEST['exclude_replies']);
- $conversation_id = defaults($_REQUEST, 'conversation_id', 0);
+ $conversation_id = $_REQUEST['conversation_id'] ?? 0;
- $start = $page * $count;
+ $start = max(0, ($page - 1) * $count);
$condition = ["`uid` = ? AND `gravity` IN (?, ?) AND `item`.`id` > ?",
api_user(), GRAVITY_PARENT, GRAVITY_COMMENT, $since_id];
// get last network messages
// params
- $count = defaults($_REQUEST, 'count', 20);
- $page = (!empty($_REQUEST['page']) ? $_REQUEST['page'] -1 : 0);
- if ($page < 0) {
- $page = 0;
- }
- $since_id = defaults($_REQUEST, 'since_id', 0);
- $max_id = defaults($_REQUEST, 'max_id', 0);
+ $count = $_REQUEST['count'] ?? 20;
+ $page = $_REQUEST['page'] ?? 1;
+ $since_id = $_REQUEST['since_id'] ?? 0;
+ $max_id = $_REQUEST['max_id'] ?? 0;
$exclude_replies = (!empty($_REQUEST['exclude_replies']) ? 1 : 0);
- $conversation_id = defaults($_REQUEST, 'conversation_id', 0);
+ $conversation_id = $_REQUEST['conversation_id'] ?? 0;
- $start = $page * $count;
+ $start = max(0, ($page - 1) * $count);
if ($exclude_replies && !$conversation_id) {
$condition = ["`gravity` IN (?, ?) AND `iid` > ? AND NOT `private` AND `wall` AND NOT `user`.`hidewall` AND NOT `author`.`hidden`",
throw new ForbiddenException();
}
- $since_id = defaults($_REQUEST, 'since_id', 0);
- $max_id = defaults($_REQUEST, 'max_id', 0);
+ $since_id = $_REQUEST['since_id'] ?? 0;
+ $max_id = $_REQUEST['max_id'] ?? 0;
// pagination
- $count = defaults($_REQUEST, 'count', 20);
- $page = defaults($_REQUEST, 'page', 1);
- if ($page < 1) {
- $page = 1;
- }
- $start = ($page - 1) * $count;
+ $count = $_REQUEST['count'] ?? 20;
+ $page = $_REQUEST['page'] ?? 1;
+
+ $start = max(0, ($page - 1) * $count);
$condition = ["`uid` = 0 AND `gravity` IN (?, ?) AND `thread`.`iid` > ? AND NOT `private`",
GRAVITY_PARENT, GRAVITY_COMMENT, $since_id];
}
// params
- $id = intval(defaults($a->argv, 3, 0));
+ $id = intval($a->argv[3] ?? 0);
if ($id == 0) {
- $id = intval(defaults($_REQUEST, 'id', 0));
+ $id = intval($_REQUEST['id'] ?? 0);
}
// Hotot workaround
if ($id == 0) {
- $id = intval(defaults($a->argv, 4, 0));
+ $id = intval($a->argv[4] ?? 0);
}
Logger::log('API: api_statuses_show: ' . $id);
}
// params
- $id = intval(defaults($a->argv , 3 , 0));
- $since_id = intval(defaults($_REQUEST, 'since_id', 0));
- $max_id = intval(defaults($_REQUEST, 'max_id' , 0));
- $count = intval(defaults($_REQUEST, 'count' , 20));
- $page = intval(defaults($_REQUEST, 'page' , 1)) - 1;
- if ($page < 0) {
- $page = 0;
- }
+ $id = intval($a->argv[3] ?? 0);
+ $since_id = intval($_REQUEST['since_id'] ?? 0);
+ $max_id = intval($_REQUEST['max_id'] ?? 0);
+ $count = intval($_REQUEST['count'] ?? 20);
+ $page = intval($_REQUEST['page'] ?? 1);
- $start = $page * $count;
+ $start = max(0, ($page - 1) * $count);
if ($id == 0) {
- $id = intval(defaults($_REQUEST, 'id', 0));
+ $id = intval($_REQUEST['id'] ?? 0);
}
// Hotot workaround
if ($id == 0) {
- $id = intval(defaults($a->argv, 4, 0));
+ $id = intval($a->argv[4] ?? 0);
}
Logger::info(API_LOG_PREFIX . '{subaction}', ['module' => 'api', 'action' => 'conversation', 'subaction' => 'show', 'id' => $id]);
api_get_user($a);
// params
- $id = intval(defaults($a->argv, 3, 0));
+ $id = intval($a->argv[3] ?? 0);
if ($id == 0) {
- $id = intval(defaults($_REQUEST, 'id', 0));
+ $id = intval($_REQUEST['id'] ?? 0);
}
// Hotot workaround
if ($id == 0) {
- $id = intval(defaults($a->argv, 4, 0));
+ $id = intval($a->argv[4] ?? 0);
}
Logger::log('API: api_statuses_repeat: '.$id);
api_get_user($a);
// params
- $id = intval(defaults($a->argv, 3, 0));
+ $id = intval($a->argv[3] ?? 0);
if ($id == 0) {
- $id = intval(defaults($_REQUEST, 'id', 0));
+ $id = intval($_REQUEST['id'] ?? 0);
}
// Hotot workaround
if ($id == 0) {
- $id = intval(defaults($a->argv, 4, 0));
+ $id = intval($a->argv[4] ?? 0);
}
Logger::log('API: api_statuses_destroy: '.$id);
// get last network messages
// params
- $since_id = defaults($_REQUEST, 'since_id', 0);
- $max_id = defaults($_REQUEST, 'max_id' , 0);
- $count = defaults($_REQUEST, 'count' , 20);
- $page = defaults($_REQUEST, 'page' , 1);
- if ($page < 1) {
- $page = 1;
- }
+ $since_id = $_REQUEST['since_id'] ?? 0;
+ $max_id = $_REQUEST['max_id'] ?? 0;
+ $count = $_REQUEST['count'] ?? 20;
+ $page = $_REQUEST['page'] ?? 1;
- $start = ($page - 1) * $count;
+ $start = max(0, ($page - 1) * $count);
$condition = ["`uid` = ? AND `gravity` IN (?, ?) AND `item`.`id` > ? AND `author-id` != ?
AND `item`.`parent` IN (SELECT `iid` FROM `thread` WHERE `thread`.`uid` = ? AND `thread`.`mention` AND NOT `thread`.`ignored`)",
Logger::DEBUG
);
- $since_id = defaults($_REQUEST, 'since_id', 0);
- $max_id = defaults($_REQUEST, 'max_id', 0);
+ $since_id = $_REQUEST['since_id'] ?? 0;
+ $max_id = $_REQUEST['max_id'] ?? 0;
$exclude_replies = !empty($_REQUEST['exclude_replies']);
- $conversation_id = defaults($_REQUEST, 'conversation_id', 0);
+ $conversation_id = $_REQUEST['conversation_id'] ?? 0;
// pagination
- $count = defaults($_REQUEST, 'count', 20);
- $page = defaults($_REQUEST, 'page', 1);
- if ($page < 1) {
- $page = 1;
- }
- $start = ($page - 1) * $count;
+ $count = $_REQUEST['count'] ?? 20;
+ $page = $_REQUEST['page'] ?? 1;
+
+ $start = max(0, ($page - 1) * $count);
$condition = ["`uid` = ? AND `gravity` IN (?, ?) AND `item`.`id` > ? AND `item`.`contact-id` = ?",
api_user(), GRAVITY_PARENT, GRAVITY_COMMENT, $since_id, $user_info['cid']];
}
$action = str_replace("." . $type, "", $a->argv[$action_argv_id]);
if ($a->argc == $action_argv_id + 2) {
- $itemid = intval(defaults($a->argv, $action_argv_id + 1, 0));
+ $itemid = intval($a->argv[$action_argv_id + 1] ?? 0);
} else {
- $itemid = intval(defaults($_REQUEST, 'id', 0));
+ $itemid = intval($_REQUEST['id'] ?? 0);
}
$item = Item::selectFirstForUser(api_user(), [], ['id' => $itemid, 'uid' => api_user()]);
$ret = [];
} else {
// params
- $since_id = defaults($_REQUEST, 'since_id', 0);
- $max_id = defaults($_REQUEST, 'max_id', 0);
- $count = defaults($_GET, 'count', 20);
- $page = (!empty($_REQUEST['page']) ? $_REQUEST['page'] -1 : 0);
- if ($page < 0) {
- $page = 0;
- }
+ $since_id = $_REQUEST['since_id'] ?? 0;
+ $max_id = $_REQUEST['max_id'] ?? 0;
+ $count = $_GET['count'] ?? 20;
+ $page = $_REQUEST['page'] ?? 1;
- $start = $page*$count;
+ $start = max(0, ($page - 1) * $count);
$condition = ["`uid` = ? AND `gravity` IN (?, ?) AND `id` > ? AND `starred`",
api_user(), GRAVITY_PARENT, GRAVITY_COMMENT, $since_id];
'sender_id' => $sender['id'],
'text' => "",
'recipient_id' => $recipient['id'],
- 'created_at' => api_date(defaults($item, 'created', DateTimeFormat::utcNow())),
+ 'created_at' => api_date($item['created'] ?? DateTimeFormat::utcNow()),
'sender_screen_name' => $sender['screen_name'],
'recipient_screen_name' => $recipient['screen_name'],
'sender' => $sender,
'recipient' => $recipient,
'title' => "",
- 'friendica_seen' => defaults($item, 'seen', 0),
- 'friendica_parent_uri' => defaults($item, 'parent-uri', ''),
+ 'friendica_seen' => $item['seen'] ?? 0,
+ 'friendica_parent_uri' => $item['parent-uri'] ?? '',
];
// "uid" and "self" are only needed for some internal stuff, so remove it from here
$statustext = trim($statustitle."\n\n".$statusbody);
}
- if ((defaults($item, 'network', Protocol::PHANTOM) == Protocol::FEED) && (mb_strlen($statustext)> 1000)) {
- $statustext = mb_substr($statustext, 0, 1000) . "... \n" . defaults($item, 'plink', '');
+ if ((($item['network'] ?? Protocol::PHANTOM) == Protocol::FEED) && (mb_strlen($statustext)> 1000)) {
+ $statustext = mb_substr($statustext, 0, 1000) . "... \n" . ($item['plink'] ?? '');
}
$statushtml = BBCode::convert(api_clean_attachments($body), false);
}
// feeds without body should contain the link
- if ((defaults($item, 'network', Protocol::PHANTOM) == Protocol::FEED) && (strlen($item['body']) == 0)) {
+ if ((($item['network'] ?? Protocol::PHANTOM) == Protocol::FEED) && (strlen($item['body']) == 0)) {
$statushtml .= BBCode::convert($item['plink']);
}
}
}
- if (strstr(defaults($_SERVER, 'HTTP_USER_AGENT', ''), "AndStatus")) {
+ if (strstr($_SERVER['HTTP_USER_AGENT'] ?? '', 'AndStatus')) {
foreach ($images[0] as $orig) {
$body = str_replace($orig, "", $body);
}
*/
function api_get_entitities(&$text, $bbcode)
{
- $include_entities = strtolower(defaults($_REQUEST, 'include_entities', "false"));
+ $include_entities = strtolower($_REQUEST['include_entities'] ?? 'false');
if ($include_entities != "true") {
preg_match_all("/\[img](.*?)\[\/img\]/ism", $bbcode, $images);
// get user data and add it to the array of the activity
$user = api_get_user($a, $parent_item['author-id']);
switch ($parent_item['verb']) {
- case ACTIVITY_LIKE:
+ case Activity::LIKE:
$activities['like'][] = $user;
break;
- case ACTIVITY_DISLIKE:
+ case Activity::DISLIKE:
$activities['dislike'][] = $user;
break;
- case ACTIVITY_ATTEND:
+ case Activity::ATTEND:
$activities['attendyes'][] = $user;
break;
- case ACTIVITY_ATTENDNO:
+ case Activity::ATTENDNO:
$activities['attendno'][] = $user;
break;
- case ACTIVITY_ATTENDMAYBE:
+ case Activity::ATTENDMAYBE:
$activities['attendmaybe'][] = $user;
break;
default:
*/
function api_format_items($items, $user_info, $filter_user = false, $type = "json")
{
- $a = \Friendica\BaseObject::getApp();
+ $a = BaseObject::getApp();
$ret = [];
*/
function api_format_item($item, $type = "json", $status_user = null, $author_user = null, $owner_user = null)
{
- $a = \Friendica\BaseObject::getApp();
+ $a = BaseObject::getApp();
if (empty($status_user) || empty($author_user) || empty($owner_user)) {
list($status_user, $author_user, $owner_user) = api_item_get_user($a, $item);
}
// params
- $count = defaults($_REQUEST, 'count', 20);
- $page = (!empty($_REQUEST['page']) ? $_REQUEST['page'] - 1 : 0);
- if ($page < 0) {
- $page = 0;
- }
- $since_id = defaults($_REQUEST, 'since_id', 0);
- $max_id = defaults($_REQUEST, 'max_id', 0);
+ $count = $_REQUEST['count'] ?? 20;
+ $page = $_REQUEST['page'] ?? 1;
+ $since_id = $_REQUEST['since_id'] ?? 0;
+ $max_id = $_REQUEST['max_id'] ?? 0;
$exclude_replies = (!empty($_REQUEST['exclude_replies']) ? 1 : 0);
- $conversation_id = defaults($_REQUEST, 'conversation_id', 0);
+ $conversation_id = $_REQUEST['conversation_id'] ?? 0;
- $start = $page * $count;
+ $start = max(0, ($page - 1) * $count);
$condition = ["`uid` = ? AND `gravity` IN (?, ?) AND `id` > ? AND `group_member`.`gid` = ?",
api_user(), GRAVITY_PARENT, GRAVITY_COMMENT, $since_id, $_REQUEST['list_id']];
}
// pagination
- $count = defaults($_GET, 'count', 20);
- $page = defaults($_GET, 'page', 1);
- if ($page < 1) {
- $page = 1;
- }
- $start = ($page - 1) * $count;
+ $count = $_GET['count'] ?? 20;
+ $page = $_GET['page'] ?? 1;
+
+ $start = max(0, ($page - 1) * $count);
$user_info = api_get_user($a);
api_get_user($a);
- $stringify_ids = defaults($_REQUEST, 'stringify_ids', false);
+ $stringify_ids = $_REQUEST['stringify_ids'] ?? false;
$r = q(
"SELECT `pcontact`.`id` FROM `contact`
// params
$user_info = api_get_user($a);
//required
- $id = defaults($_REQUEST, 'id', 0);
+ $id = $_REQUEST['id'] ?? 0;
// optional
- $parenturi = defaults($_REQUEST, 'friendica_parenturi', "");
+ $parenturi = $_REQUEST['friendica_parenturi'] ?? '';
$verbose = (!empty($_GET['friendica_verbose']) ? strtolower($_GET['friendica_verbose']) : "false");
/// @todo optional parameter 'include_entities' from Twitter API not yet implemented
throw new ForbiddenException();
}
- $contact_id = defaults($_REQUEST, 'user_id');
+ $contact_id = $_REQUEST['user_id'] ?? 0;
if (empty($contact_id)) {
Logger::notice(API_LOG_PREFIX . 'No user_id specified', ['module' => 'api', 'action' => 'friendships_destroy']);
throw new ForbiddenException();
}
// params
- $count = defaults($_GET, 'count', 20);
- $page = defaults($_REQUEST, 'page', 1) - 1;
- if ($page < 0) {
- $page = 0;
- }
+ $count = $_GET['count'] ?? 20;
+ $page = $_REQUEST['page'] ?? 1;
- $since_id = defaults($_REQUEST, 'since_id', 0);
- $max_id = defaults($_REQUEST, 'max_id', 0);
+ $since_id = $_REQUEST['since_id'] ?? 0;
+ $max_id = $_REQUEST['max_id'] ?? 0;
- $user_id = defaults($_REQUEST, 'user_id', '');
- $screen_name = defaults($_REQUEST, 'screen_name', '');
+ $user_id = $_REQUEST['user_id'] ?? '';
+ $screen_name = $_REQUEST['screen_name'] ?? '';
// caller user info
unset($_REQUEST["user_id"]);
$profile_url = $user_info["url"];
// pagination
- $start = $page * $count;
+ $start = max(0, ($page - 1) * $count);
$sql_extra = "";
if ($box=="sentbox") {
$sql_extra = "`mail`.`from-url`='" . DBA::escape($profile_url) . "'";
} elseif ($box == "conversation") {
- $sql_extra = "`mail`.`parent-uri`='" . DBA::escape(defaults($_GET, 'uri', '')) . "'";
+ $sql_extra = "`mail`.`parent-uri`='" . DBA::escape($_GET['uri'] ?? '') . "'";
} elseif ($box == "all") {
$sql_extra = "true";
} elseif ($box == "inbox") {
throw new ForbiddenException();
}
// input params
- $album = defaults($_REQUEST, 'album', "");
+ $album = $_REQUEST['album'] ?? '';
// we do not allow calls without album string
if ($album == "") {
throw new ForbiddenException();
}
// input params
- $album = defaults($_REQUEST, 'album', "");
- $album_new = defaults($_REQUEST, 'album_new', "");
+ $album = $_REQUEST['album'] ?? '';
+ $album_new = $_REQUEST['album_new'] ?? '';
// we do not allow calls without album string
if ($album == "") {
throw new ForbiddenException();
}
// input params
- $photo_id = defaults($_REQUEST, 'photo_id', null);
- $desc = defaults($_REQUEST, 'desc', (array_key_exists('desc', $_REQUEST) ? "" : null)) ; // extra check necessary to distinguish between 'not provided' and 'empty string'
- $album = defaults($_REQUEST, 'album', null);
- $album_new = defaults($_REQUEST, 'album_new', null);
- $allow_cid = defaults($_REQUEST, 'allow_cid', (array_key_exists('allow_cid', $_REQUEST) ? " " : null));
- $deny_cid = defaults($_REQUEST, 'deny_cid' , (array_key_exists('deny_cid' , $_REQUEST) ? " " : null));
- $allow_gid = defaults($_REQUEST, 'allow_gid', (array_key_exists('allow_gid', $_REQUEST) ? " " : null));
- $deny_gid = defaults($_REQUEST, 'deny_gid' , (array_key_exists('deny_gid' , $_REQUEST) ? " " : null));
+ $photo_id = $_REQUEST['photo_id'] ?? null;
+ $desc = $_REQUEST['desc'] ?? null;
+ $album = $_REQUEST['album'] ?? null;
+ $album_new = $_REQUEST['album_new'] ?? null;
+ $allow_cid = $_REQUEST['allow_cid'] ?? null;
+ $deny_cid = $_REQUEST['deny_cid' ] ?? null;
+ $allow_gid = $_REQUEST['allow_gid'] ?? null;
+ $deny_gid = $_REQUEST['deny_gid' ] ?? null;
$visibility = !empty($_REQUEST['visibility']) && $_REQUEST['visibility'] !== "false";
// do several checks on input parameters
}
// input params
- $photo_id = defaults($_REQUEST, 'photo_id', null);
+ $photo_id = $_REQUEST['photo_id'] ?? null;
// do several checks on input parameters
// we do not allow calls without photo id
throw new ForbiddenException();
}
// input params
- $profile_id = defaults($_REQUEST, 'profile_id', 0);
+ $profile_id = $_REQUEST['profile_id'] ?? 0;
// error if image data is missing
if (empty($_FILES['image'])) {
*/
function check_acl_input($acl_string)
{
- if ($acl_string == null || $acl_string == " ") {
+ if (empty($acl_string)) {
return false;
}
+
$contact_not_found = false;
// split <x><y><z> into array of cid's
}
/**
- *
* @param string $mediatype
* @param array $media
* @param string $type
* @throws ImagickException
* @throws InternalServerErrorException
* @throws NotFoundException
+ * @throws UnauthorizedException
*/
function save_media_to_database($mediatype, $media, $type, $album, $allow_cid, $deny_cid, $allow_gid, $deny_gid, $desc, $profile = 0, $visibility = false, $photo_id = null)
{
*/
function api_friendica_remoteauth()
{
- $url = defaults($_GET, 'url', '');
- $c_url = defaults($_GET, 'c_url', '');
+ $url = $_GET['url'] ?? '';
+ $c_url = $_GET['c_url'] ?? '';
if ($url === '' || $c_url === '') {
throw new BadRequestException("Wrong parameters.");
$cid = $contact['id'];
- $dfrn_id = defaults($contact, 'issued-id', $contact['dfrn-id']);
+ $dfrn_id = $contact['issued-id'] ?? $contact['dfrn-id'];
if ($contact['duplex'] && $contact['issued-id']) {
$orig_id = $contact['issued-id'];
}
$fields = ['author-id', 'author-name', 'author-link', 'author-avatar'];
- $activity = Item::activityToIndex(ACTIVITY2_ANNOUNCE);
+ $activity = Item::activityToIndex(Activity::ANNOUNCE);
$condition = ['parent-uri' => $item['uri'], 'gravity' => GRAVITY_ACTIVITY, 'uid' => [0, $item['uid']], 'activity' => $activity];
$announce = Item::selectFirstForUser($item['uid'], $fields, $condition, ['order' => ['received' => true]]);
if (!DBA::isResult($announce)) {
*/
function api_clean_plain_items($text)
{
- $include_entities = strtolower(defaults($_REQUEST, 'include_entities', "false"));
+ $include_entities = strtolower($_REQUEST['include_entities'] ?? 'false');
$text = BBCode::cleanPictureLinks($text);
$URLSearchString = "^\[\]";
// params
$user_info = api_get_user($a);
- $gid = defaults($_REQUEST, 'gid', 0);
+ $gid = $_REQUEST['gid'] ?? 0;
$uid = $user_info['uid'];
// get data of the specified group id or all groups if not specified
// params
$user_info = api_get_user($a);
- $gid = defaults($_REQUEST, 'gid', 0);
- $name = defaults($_REQUEST, 'name', "");
+ $gid = $_REQUEST['gid'] ?? 0;
+ $name = $_REQUEST['name'] ?? '';
$uid = $user_info['uid'];
// error if no gid specified
// params
$user_info = api_get_user($a);
- $gid = defaults($_REQUEST, 'list_id', 0);
+ $gid = $_REQUEST['list_id'] ?? 0;
$uid = $user_info['uid'];
// error if no gid specified
// params
$user_info = api_get_user($a);
- $name = defaults($_REQUEST, 'name', "");
+ $name = $_REQUEST['name'] ?? '';
$uid = $user_info['uid'];
$json = json_decode($_POST['json'], true);
$users = $json['user'];
// params
$user_info = api_get_user($a);
- $name = defaults($_REQUEST, 'name', "");
+ $name = $_REQUEST['name'] ?? '';
$uid = $user_info['uid'];
$success = group_create($name, $uid);
// params
$user_info = api_get_user($a);
$uid = $user_info['uid'];
- $gid = defaults($_REQUEST, 'gid', 0);
- $name = defaults($_REQUEST, 'name', "");
+ $gid = $_REQUEST['gid'] ?? 0;
+ $name = $_REQUEST['name'] ?? '';
$json = json_decode($_POST['json'], true);
$users = $json['user'];
// params
$user_info = api_get_user($a);
- $gid = defaults($_REQUEST, 'list_id', 0);
- $name = defaults($_REQUEST, 'name', "");
+ $gid = $_REQUEST['list_id'] ?? 0;
+ $name = $_REQUEST['name'] ?? '';
$uid = $user_info['uid'];
// error if no gid specified
$verb = strtolower($a->argv[3]);
$verb = preg_replace("|\..*$|", "", $verb);
- $id = defaults($_REQUEST, 'id', 0);
+ $id = $_REQUEST['id'] ?? 0;
$res = Item::performLike($id, $verb);
if ($a->argc!==3) {
throw new BadRequestException("Invalid argument count");
}
- $nm = new NotificationsManager();
+ /** @var Notify $nm */
+ $nm = BaseObject::getClass(Notify::class);
$notes = $nm->getAll([], ['seen' => 'ASC', 'date' => 'DESC'], 50);
$id = (!empty($_REQUEST['id']) ? intval($_REQUEST['id']) : 0);
- $nm = new NotificationsManager();
+ /** @var Notify $nm */
+ $nm = BaseObject::getClass(Notify::class);
$note = $nm->getByID($id);
if (is_null($note)) {
throw new BadRequestException("Invalid argument");
// params
$user_info = api_get_user($a);
$uid = $user_info['uid'];
- $id = defaults($_REQUEST, 'id', 0);
+ $id = $_REQUEST['id'] ?? 0;
// return error if id is zero
if ($id == "") {
// params
$user_info = api_get_user($a);
- $searchstring = defaults($_REQUEST, 'searchstring', "");
+ $searchstring = $_REQUEST['searchstring'] ?? '';
$uid = $user_info['uid'];
// error if no searchstring specified
}
// input params
- $profile_id = defaults($_REQUEST, 'profile_id', 0);
+ $profile_id = $_REQUEST['profile_id'] ?? 0;
// retrieve general information about profiles for user
$multi_profiles = Feature::isEnabled(api_user(), 'multi_profiles');
*/
use Friendica\App;
+use Friendica\BaseObject;
use Friendica\Content\ContactSelector;
use Friendica\Content\Feature;
+use Friendica\Content\Item as ContentItem;
use Friendica\Content\Pager;
use Friendica\Content\Text\BBCode;
use Friendica\Core\Config;
use Friendica\Model\Term;
use Friendica\Object\Post;
use Friendica\Object\Thread;
+use Friendica\Protocol\Activity;
+use Friendica\Util\Crypto;
use Friendica\Util\DateTimeFormat;
use Friendica\Util\Proxy as ProxyUtils;
-use Friendica\Util\Temporal;
use Friendica\Util\Strings;
+use Friendica\Util\Temporal;
use Friendica\Util\XML;
-use Friendica\Util\Crypto;
function item_extract_images($body) {
During the further steps of the database restructuring I would like to address this issue.
*/
+ /** @var Activity $activity */
+ $activity = BaseObject::getClass(Activity::class);
+
$xmlhead = "<" . "?xml version='1.0' encoding='UTF-8' ?" . ">";
- if (activity_match($item['verb'], ACTIVITY_LIKE)
- || activity_match($item['verb'], ACTIVITY_DISLIKE)
- || activity_match($item['verb'], ACTIVITY_ATTEND)
- || activity_match($item['verb'], ACTIVITY_ATTENDNO)
- || activity_match($item['verb'], ACTIVITY_ATTENDMAYBE)) {
+ if ($activity->match($item['verb'], Activity::LIKE)
+ || $activity->match($item['verb'], Activity::DISLIKE)
+ || $activity->match($item['verb'], Activity::ATTEND)
+ || $activity->match($item['verb'], Activity::ATTENDNO)
+ || $activity->match($item['verb'], Activity::ATTENDMAYBE)) {
$fields = ['author-link', 'author-name', 'verb', 'object-type', 'resource-id', 'body', 'plink'];
$obj = Item::selectFirst($fields, ['uri' => $item['parent-uri']]);
$objauthor = '[url=' . $obj['author-link'] . ']' . $obj['author-name'] . '[/url]';
switch ($obj['verb']) {
- case ACTIVITY_POST:
+ case Activity::POST:
switch ($obj['object-type']) {
- case ACTIVITY_OBJ_EVENT:
+ case Activity\ObjectType::EVENT:
$post_type = L10n::t('event');
break;
default:
$plink = '[url=' . $obj['plink'] . ']' . $post_type . '[/url]';
$bodyverb = '';
- if (activity_match($item['verb'], ACTIVITY_LIKE)) {
+ if ($activity->match($item['verb'], Activity::LIKE)) {
$bodyverb = L10n::t('%1$s likes %2$s\'s %3$s');
- } elseif (activity_match($item['verb'], ACTIVITY_DISLIKE)) {
+ } elseif ($activity->match($item['verb'], Activity::DISLIKE)) {
$bodyverb = L10n::t('%1$s doesn\'t like %2$s\'s %3$s');
- } elseif (activity_match($item['verb'], ACTIVITY_ATTEND)) {
+ } elseif ($activity->match($item['verb'], Activity::ATTEND)) {
$bodyverb = L10n::t('%1$s attends %2$s\'s %3$s');
- } elseif (activity_match($item['verb'], ACTIVITY_ATTENDNO)) {
+ } elseif ($activity->match($item['verb'], Activity::ATTENDNO)) {
$bodyverb = L10n::t('%1$s doesn\'t attend %2$s\'s %3$s');
- } elseif (activity_match($item['verb'], ACTIVITY_ATTENDMAYBE)) {
+ } elseif ($activity->match($item['verb'], Activity::ATTENDMAYBE)) {
$bodyverb = L10n::t('%1$s attends maybe %2$s\'s %3$s');
}
$item['body'] = sprintf($bodyverb, $author, $objauthor, $plink);
}
- if (activity_match($item['verb'], ACTIVITY_FRIEND)) {
+ if ($activity->match($item['verb'], Activity::FRIEND)) {
- if ($item['object-type']=="" || $item['object-type']!== ACTIVITY_OBJ_PERSON) return;
+ if ($item['object-type']=="" || $item['object-type']!== Activity\ObjectType::PERSON) return;
$Aname = $item['author-name'];
$Alink = $item['author-link'];
$item['body'] = L10n::t('%1$s is now friends with %2$s', $A, $B)."\n\n\n".$Bphoto;
}
- if (stristr($item['verb'], ACTIVITY_POKE)) {
+ if (stristr($item['verb'], Activity::POKE)) {
$verb = urldecode(substr($item['verb'],strpos($item['verb'],'#')+1));
if (!$verb) {
return;
}
- if ($item['object-type']=="" || $item['object-type']!== ACTIVITY_OBJ_PERSON) {
+ if ($item['object-type']=="" || $item['object-type']!== Activity\ObjectType::PERSON) {
return;
}
}
- if (activity_match($item['verb'], ACTIVITY_TAG)) {
+ if ($activity->match($item['verb'], Activity::TAG)) {
$fields = ['author-id', 'author-link', 'author-name', 'author-network',
'verb', 'object-type', 'resource-id', 'body', 'plink'];
$obj = Item::selectFirst($fields, ['uri' => $item['parent-uri']]);
$objauthor = '[url=' . Contact::magicLinkByContact($author_arr) . ']' . $obj['author-name'] . '[/url]';
switch ($obj['verb']) {
- case ACTIVITY_POST:
+ case Activity::POST:
switch ($obj['object-type']) {
- case ACTIVITY_OBJ_EVENT:
+ case Activity\ObjectType::EVENT:
$post_type = L10n::t('event');
break;
default:
$item['body'] = L10n::t('%1$s tagged %2$s\'s %3$s with %4$s', $author, $objauthor, $plink, $tag);
}
- if (activity_match($item['verb'], ACTIVITY_FAVORITE)) {
+ if ($activity->match($item['verb'], Activity::FAVORITE)) {
if ($item['object-type'] == "") {
return;
}
function visible_activity($item) {
- /*
- * likes (etc.) can apply to other things besides posts. Check if they are post children,
- * in which case we handle them specially
- */
- $hidden_activities = [ACTIVITY_LIKE, ACTIVITY_DISLIKE, ACTIVITY_ATTEND, ACTIVITY_ATTENDNO, ACTIVITY_ATTENDMAYBE, ACTIVITY_FOLLOW, ACTIVITY2_ANNOUNCE];
- foreach ($hidden_activities as $act) {
- if (activity_match($item['verb'], $act)) {
- return false;
- }
+ /** @var Activity $activity */
+ $activity = BaseObject::getClass(Activity::class);
+
+ if ($activity->isHidden($item['verb'])) {
+ return false;
}
// @TODO below if() block can be rewritten to a single line: $isVisible = allConditionsHere;
- if (activity_match($item['verb'], ACTIVITY_FOLLOW) && $item['object-type'] === ACTIVITY_OBJ_NOTE && empty($item['self']) && $item['uid'] == local_user()) {
+ if ($activity->match($item['verb'], Activity::FOLLOW) &&
+ $item['object-type'] === Activity\ObjectType::NOTE &&
+ empty($item['self']) &&
+ $item['uid'] == local_user()) {
return false;
}
$body = Item::prepareBody($item, true, $preview);
- list($categories, $folders) = get_cats_and_terms($item);
+ /** @var ContentItem $contItem */
+ $contItem = BaseObject::getClass(ContentItem::class);
+
+ list($categories, $folders) = $contItem->determineCategoriesTerms($item);
if (!empty($item['content-warning']) && PConfig::get(local_user(), 'system', 'disable_cw', false)) {
$title = ucfirst($item['content-warning']);
$received = '';
while ($row = Item::fetch($thread_items)) {
- if (($row['verb'] == ACTIVITY2_ANNOUNCE) && !empty($row['contact-uid']) && ($row['received'] > $received) && ($row['thr-parent'] == $row['parent-uri'])) {
+ if (($row['verb'] == Activity::ANNOUNCE) && !empty($row['contact-uid']) && ($row['received'] > $received) && ($row['thr-parent'] == $row['parent-uri'])) {
$actor = ['link' => $row['author-link'], 'avatar' => $row['author-avatar'], 'name' => $row['author-name']];
$received = $row['received'];
}
switch ($mode) {
case 'like':
- $verb = ACTIVITY_LIKE;
+ $verb = Activity::LIKE;
break;
case 'dislike':
- $verb = ACTIVITY_DISLIKE;
+ $verb = Activity::DISLIKE;
break;
case 'attendyes':
- $verb = ACTIVITY_ATTEND;
+ $verb = Activity::ATTEND;
break;
case 'attendno':
- $verb = ACTIVITY_ATTENDNO;
+ $verb = Activity::ATTENDNO;
break;
case 'attendmaybe':
- $verb = ACTIVITY_ATTENDMAYBE;
+ $verb = Activity::ATTENDMAYBE;
break;
case 'announce':
- $verb = ACTIVITY2_ANNOUNCE;
+ $verb = Activity::ANNOUNCE;
break;
default:
return;
}
- if (activity_match($item['verb'], $verb) && ($item['id'] != $item['parent'])) {
+ /** @var Activity $activity */
+ $activity = BaseObject::getClass(Activity::class);
+
+ if ($activity->match($item['verb'], $verb) && ($item['id'] != $item['parent'])) {
$author = ['uid' => 0, 'id' => $item['author-id'],
'network' => $item['author-network'], 'url' => $item['author-link']];
$url = Contact::magicLinkByContact($author);
'$new_post' => L10n::t('New Post'),
'$return_path' => $query_str,
'$action' => 'item',
- '$share' => defaults($x, 'button', L10n::t('Share')),
+ '$share' => ($x['button'] ?? '') ?: L10n::t('Share'),
'$upload' => L10n::t('Upload photo'),
'$shortupload' => L10n::t('upload photo'),
'$attach' => L10n::t('Attach file'),
'$shortsetloc' => L10n::t('set location'),
'$noloc' => L10n::t('Clear browser location'),
'$shortnoloc' => L10n::t('clear location'),
- '$title' => defaults($x, 'title', ''),
+ '$title' => $x['title'] ?? '',
'$placeholdertitle' => L10n::t('Set title'),
- '$category' => defaults($x, 'category', ''),
+ '$category' => $x['category'] ?? '',
'$placeholdercategory' => Feature::isEnabled(local_user(), 'categories') ? L10n::t("Categories \x28comma-separated list\x29") : '',
'$wait' => L10n::t('Please wait'),
'$permset' => L10n::t('Permission settings'),
'$shortpermset' => L10n::t('permissions'),
'$wall' => $notes_cid ? 0 : 1,
'$posttype' => $notes_cid ? Item::PT_PERSONAL_NOTE : Item::PT_ARTICLE,
- '$content' => defaults($x, 'content', ''),
- '$post_id' => defaults($x, 'post_id', ''),
+ '$content' => $x['content'] ?? '',
+ '$post_id' => $x['post_id'] ?? '',
'$baseurl' => System::baseUrl(true),
'$defloc' => $x['default_location'],
'$visitor' => $x['visitor'],
if (isset($child['children']) && count($child['children'])) {
// This helps counting only the regular posts
$count_post_closure = function($var) {
- return $var['verb'] === ACTIVITY_POST;
+ return $var['verb'] === Activity::POST;
};
$child_post_count = count(array_filter($child['children'], $count_post_closure));
// Searches the post item in the children
$j = 0;
- while($child['children'][$j]['verb'] !== ACTIVITY_POST && $j < count($child['children'])) {
+ while($child['children'][$j]['verb'] !== Activity::POST && $j < count($child['children'])) {
$j ++;
}
$ret = [];
foreach ($response_verbs as $v) {
$ret[$v] = [];
- $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');
+ $ret[$v]['count'] = $conv_responses[$v][$item['uri']] ?? 0;
+ $ret[$v]['list'] = $conv_responses[$v][$item['uri'] . '-l'] ?? [];
+ $ret[$v]['self'] = $conv_responses[$v][$item['uri'] . '-self'] ?? '0';
if (count($ret[$v]['list']) > MAX_LIKERS) {
$ret[$v]['list_part'] = array_slice($ret[$v]['list'], 0, MAX_LIKERS);
array_push($ret[$v]['list_part'], '<a href="#" data-toggle="modal" data-target="#' . $v . 'Modal-'
use Friendica\Database\DBA;
use Friendica\Model\Item;
use Friendica\Model\User;
+use Friendica\Protocol\Activity;
use Friendica\Util\DateTimeFormat;
use Friendica\Util\Emailer;
use Friendica\Util\Strings;
return false;
}
- $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['notify_flags'] = ($params['notify_flags'] ?? '') ?: $user['notify-flags'];
+ $params['language'] = ($params['language'] ?? '') ?: $user['language'];
+ $params['to_name'] = ($params['to_name'] ?? '') ?: $user['username'];
+ $params['to_email'] = ($params['to_email'] ?? '') ?: $user['email'];
// from here on everything is in the recipients language
L10n::pushLang($params['language']);
$hsitelink = sprintf($sitelink, '<a href="'.$siteurl.'">'.$sitename.'</a>');
switch ($params['verb']) {
- case ACTIVITY_FRIEND:
+ case Activity::FRIEND:
// someone started to share with user (mostly OStatus)
$subject = L10n::t('[Friendica:Notify] A new person is sharing with you');
$sitename
);
break;
- case ACTIVITY_FOLLOW:
+ case Activity::FOLLOW:
// someone started to follow the user (mostly OStatus)
$subject = L10n::t('[Friendica:Notify] You have a new follower');
}
if ($params['type'] == NOTIFY_CONFIRM) {
- if ($params['verb'] == ACTIVITY_FRIEND) { // mutual connection
+ if ($params['verb'] == Activity::FRIEND) { // mutual connection
$itemlink = $params['link'];
$subject = L10n::t('[Friendica:Notify] Connection accepted');
if (!isset($params['subject'])) {
Logger::warning('subject isn\'t set.', ['type' => $params['type']]);
}
- $subject = defaults($params, 'subject', '');
+ $subject = $params['subject'] ?? '';
if (!isset($params['preamble'])) {
Logger::warning('preamble isn\'t set.', ['type' => $params['type'], 'subject' => $subject]);
}
- $preamble = defaults($params, 'preamble', '');
+ $preamble = $params['preamble'] ?? '';
if (!isset($params['body'])) {
Logger::warning('body isn\'t set.', ['type' => $params['type'], 'subject' => $subject, 'preamble' => $preamble]);
}
- $body = defaults($params, 'body', '');
+ $body = $params['body'] ?? '';
$show_in_notification_page = false;
}
$datarray['siteurl'] = $siteurl;
$datarray['type'] = $params['type'];
$datarray['parent'] = $parent_id;
- $datarray['source_name'] = defaults($params, 'source_name', '');
- $datarray['source_link'] = defaults($params, 'source_link', '');
- $datarray['source_photo'] = defaults($params, 'source_photo', '');
+ $datarray['source_name'] = $params['source_name'] ?? '';
+ $datarray['source_link'] = $params['source_link'] ?? '';
+ $datarray['source_photo'] = $params['source_photo'] ?? '';
$datarray['uid'] = $params['uid'];
- $datarray['username'] = defaults($params, 'to_name', '');
+ $datarray['username'] = $params['to_name'] ?? '';
$datarray['hsitelink'] = $hsitelink;
$datarray['tsitelink'] = $tsitelink;
$datarray['hitemlink'] = '<a href="'.$itemlink.'">'.$itemlink.'</a>';
if ($send_notification) {
$params["type"] = NOTIFY_SHARE;
- $params["verb"] = ACTIVITY_TAG;
+ $params["verb"] = Activity::TAG;
}
}
if ($item["mention"] || $tagged || ($defaulttype == NOTIFY_TAGSELF)) {
$params["type"] = NOTIFY_TAGSELF;
- $params["verb"] = ACTIVITY_TAG;
+ $params["verb"] = Activity::TAG;
}
// Is it a post that the user had started?
if ($thread['mention'] && !$thread['ignored'] && !isset($params["type"])) {
$params["type"] = NOTIFY_COMMENT;
- $params["verb"] = ACTIVITY_POST;
+ $params["verb"] = Activity::POST;
}
// And now we check for participation of one of our contacts in the thread
if (!$thread['ignored'] && !isset($params["type"]) && Item::exists($condition)) {
$params["type"] = NOTIFY_COMMENT;
- $params["verb"] = ACTIVITY_POST;
+ $params["verb"] = Activity::POST;
}
if (isset($params["type"])) {
$data["type"] = "link";
}
- $data["title"] = defaults($data, "title", "");
+ $data["title"] = $data["title"] ?? '';
if ((($data["type"] != "link") && ($data["type"] != "video") && ($data["type"] != "photo")) || ($data["title"] == $data["url"])) {
return "";
+++ /dev/null
-<?php
-/**
- * @file include/text.php
- */
-
-use Friendica\App;
-use Friendica\Content\Text\BBCode;
-use Friendica\Core\Protocol;
-use Friendica\Model\Contact;
-use Friendica\Model\FileTag;
-use Friendica\Model\Group;
-use Friendica\Util\Strings;
-
-/**
- * Turn user/group ACLs stored as angle bracketed text into arrays
- *
- * @param string $s
- * @return array
- */
-function expand_acl($s) {
- // turn string array of angle-bracketed elements into numeric array
- // e.g. "<1><2><3>" => array(1,2,3);
- preg_match_all('/<(' . Group::FOLLOWERS . '|'. Group::MUTUALS . '|[0-9]+)>/', $s, $matches, PREG_PATTERN_ORDER);
-
- return $matches[1];
-}
-
-
-/**
- * Wrap ACL elements in angle brackets for storage
- * @param string $item
- */
-function sanitise_acl(&$item) {
- if (intval($item)) {
- $item = '<' . intval(Strings::escapeTags(trim($item))) . '>';
- } elseif (in_array($item, [Group::FOLLOWERS, Group::MUTUALS])) {
- $item = '<' . $item . '>';
- } else {
- unset($item);
- }
-}
-
-
-/**
- * Convert an ACL array to a storable string
- *
- * Normally ACL permissions will be an array.
- * We'll also allow a comma-separated string.
- *
- * @param string|array $p
- * @return string
- */
-function perms2str($p) {
- $ret = '';
- if (is_array($p)) {
- $tmp = $p;
- } else {
- $tmp = explode(',', $p);
- }
-
- if (is_array($tmp)) {
- array_walk($tmp, 'sanitise_acl');
- $ret = implode('', $tmp);
- }
- return $ret;
-}
-
-/**
- * for html,xml parsing - let's say you've got
- * an attribute foobar="class1 class2 class3"
- * and you want to find out if it contains 'class3'.
- * you can't use a normal sub string search because you
- * might match 'notclass3' and a regex to do the job is
- * possible but a bit complicated.
- * pass the attribute string as $attr and the attribute you
- * are looking for as $s - returns true if found, otherwise false
- *
- * @param string $attr attribute value
- * @param string $s string to search
- * @return boolean True if found, False otherwise
- */
-function attribute_contains($attr, $s) {
- $a = explode(' ', $attr);
- return (count($a) && in_array($s,$a));
-}
-
-/**
- * Compare activity uri. Knows about activity namespace.
- *
- * @param string $haystack
- * @param string $needle
- * @return boolean
- */
-function activity_match($haystack,$needle) {
- return (($haystack === $needle) || ((basename($needle) === $haystack) && strstr($needle, NAMESPACE_ACTIVITY_SCHEMA)));
-}
-
-/**
- * quick and dirty quoted_printable encoding
- *
- * @param string $s
- * @return string
- */
-function qp($s) {
- return str_replace("%", "=", rawurlencode($s));
-}
-
-/**
- * @brief Find any non-embedded images in private items and add redir links to them
- *
- * @param App $a
- * @param array &$item The field array of an item row
- */
-function redir_private_images($a, &$item)
-{
- $matches = [];
- $cnt = preg_match_all('|\[img\](http[^\[]*?/photo/[a-fA-F0-9]+?(-[0-9]\.[\w]+?)?)\[\/img\]|', $item['body'], $matches, PREG_SET_ORDER);
- if ($cnt) {
- foreach ($matches as $mtch) {
- if (strpos($mtch[1], '/redir') !== false) {
- continue;
- }
-
- if ((local_user() == $item['uid']) && ($item['private'] == 1) && ($item['contact-id'] != $a->contact['id']) && ($item['network'] == Protocol::DFRN)) {
- $img_url = 'redir/' . $item['contact-id'] . '?url=' . urlencode($mtch[1]);
- $item['body'] = str_replace($mtch[0], '[img]' . $img_url . '[/img]', $item['body']);
- }
- }
- }
-}
-
-/**
- * @brief Given a text string, convert from bbcode to html and add smilie icons.
- *
- * @param string $text String with bbcode.
- * @return string Formatted HTML
- * @throws \Friendica\Network\HTTPException\InternalServerErrorException
- */
-function prepare_text($text)
-{
- $s = BBCode::convert($text);
- return trim($s);
-}
-
-/**
- * return array with details for categories and folders for an item
- *
- * @param array $item
- * @return array
- *
- * [
- * [ // categories array
- * {
- * 'name': 'category name',
- * 'removeurl': 'url to remove this category',
- * 'first': 'is the first in this array? true/false',
- * 'last': 'is the last in this array? true/false',
- * } ,
- * ....
- * ],
- * [ //folders array
- * {
- * 'name': 'folder name',
- * 'removeurl': 'url to remove this folder',
- * 'first': 'is the first in this array? true/false',
- * 'last': 'is the last in this array? true/false',
- * } ,
- * ....
- * ]
- * ]
- */
-function get_cats_and_terms($item)
-{
- $categories = [];
- $folders = [];
- $first = true;
-
- foreach (FileTag::fileToArray($item['file'] ?? '', 'category') as $savedFolderName) {
- $categories[] = [
- 'name' => $savedFolderName,
- 'url' => "#",
- 'removeurl' => ((local_user() == $item['uid']) ? 'filerm/' . $item['id'] . '?f=&cat=' . rawurlencode($savedFolderName) : ""),
- 'first' => $first,
- 'last' => false
- ];
- $first = false;
- }
-
- if (count($categories)) {
- $categories[count($categories) - 1]['last'] = true;
- }
-
- if (local_user() == $item['uid']) {
- foreach (FileTag::fileToArray($item['file'] ?? '') as $savedFolderName) {
- $folders[] = [
- 'name' => $savedFolderName,
- 'url' => "#",
- 'removeurl' => ((local_user() == $item['uid']) ? 'filerm/' . $item['id'] . '?f=&term=' . rawurlencode($savedFolderName) : ""),
- 'first' => $first,
- 'last' => false
- ];
- $first = false;
- }
- }
-
- if (count($folders)) {
- $folders[count($folders) - 1]['last'] = true;
- }
-
- return [$categories, $folders];
-}
-
-/**
- * return number of bytes in size (K, M, G)
- * @param string $size_str
- * @return int
- */
-function return_bytes($size_str) {
- switch (substr ($size_str, -1)) {
- case 'M': case 'm': return (int)$size_str * 1048576;
- case 'K': case 'k': return (int)$size_str * 1024;
- case 'G': case 'g': return (int)$size_str * 1073741824;
- default: return $size_str;
- }
-}
-
-function bb_translate_video($s) {
-
- $matches = null;
- $r = preg_match_all("/\[video\](.*?)\[\/video\]/ism",$s,$matches,PREG_SET_ORDER);
- if ($r) {
- foreach ($matches as $mtch) {
- if ((stristr($mtch[1], 'youtube')) || (stristr($mtch[1], 'youtu.be'))) {
- $s = str_replace($mtch[0], '[youtube]' . $mtch[1] . '[/youtube]', $s);
- } elseif (stristr($mtch[1], 'vimeo')) {
- $s = str_replace($mtch[0], '[vimeo]' . $mtch[1] . '[/vimeo]', $s);
- }
- }
- }
- return $s;
-}
-
-function undo_post_tagging($s) {
- $matches = null;
- $cnt = preg_match_all('/([!#@])\[url=(.*?)\](.*?)\[\/url\]/ism', $s, $matches, PREG_SET_ORDER);
- if ($cnt) {
- foreach ($matches as $mtch) {
- if (in_array($mtch[1], ['!', '@'])) {
- $contact = Contact::getDetailsByURL($mtch[2]);
- $mtch[3] = empty($contact['addr']) ? $mtch[2] : $contact['addr'];
- }
- $s = str_replace($mtch[0], $mtch[1] . $mtch[3],$s);
- }
- }
- return $s;
-}
-
-/// @TODO Rewrite this
-function is_a_date_arg($s) {
- $i = intval($s);
-
- if ($i > 1900) {
- $y = date('Y');
-
- if ($i <= $y + 1 && strpos($s, '-') == 4) {
- $m = intval(substr($s, 5));
-
- if ($m > 0 && $m <= 12) {
- return true;
- }
- }
- }
-
- return false;
-}
/* Generic exception class
*/
if (!class_exists('OAuthException', false)) {
- class OAuthException extends Exception {
- // pass
- }
+ class OAuthException extends Exception
+ { }
}
-class OAuthConsumer {
+class OAuthConsumer
+{
public $key;
public $secret;
- function __construct($key, $secret, $callback_url=NULL) {
+ function __construct($key, $secret, $callback_url = NULL)
+ {
$this->key = $key;
$this->secret = $secret;
$this->callback_url = $callback_url;
}
- function __toString() {
+ function __toString()
+ {
return "OAuthConsumer[key=$this->key,secret=$this->secret]";
}
}
-class OAuthToken {
+class OAuthToken
+{
// access tokens and request tokens
public $key;
public $secret;
* key = the token
* secret = the token secret
*/
- function __construct($key, $secret) {
+ function __construct($key, $secret)
+ {
$this->key = $key;
$this->secret = $secret;
}
* generates the basic string serialization of a token that a server
* would respond to request_token and access_token calls with
*/
- function to_string() {
+ function to_string()
+ {
return "oauth_token=" .
- OAuthUtil::urlencode_rfc3986($this->key) .
- "&oauth_token_secret=" .
- OAuthUtil::urlencode_rfc3986($this->secret);
+ OAuthUtil::urlencode_rfc3986($this->key) .
+ "&oauth_token_secret=" .
+ OAuthUtil::urlencode_rfc3986($this->secret);
}
- function __toString() {
+ function __toString()
+ {
return $this->to_string();
}
}
* A class for implementing a Signature Method
* See section 9 ("Signing Requests") in the spec
*/
-abstract class OAuthSignatureMethod {
+abstract class OAuthSignatureMethod
+{
/**
* Needs to return the name of the Signature Method (ie HMAC-SHA1)
* @return string
* @param string $signature
* @return bool
*/
- public function check_signature($request, $consumer, $token, $signature) {
+ public function check_signature($request, $consumer, $token, $signature)
+ {
$built = $this->build_signature($request, $consumer, $token);
return ($built == $signature);
}
}
/**
- * The HMAC-SHA1 signature method uses the HMAC-SHA1 signature algorithm as defined in [RFC2104]
- * where the Signature Base String is the text and the key is the concatenated values (each first
- * encoded per Parameter Encoding) of the Consumer Secret and Token Secret, separated by an '&'
+ * The HMAC-SHA1 signature method uses the HMAC-SHA1 signature algorithm as defined in [RFC2104]
+ * where the Signature Base String is the text and the key is the concatenated values (each first
+ * encoded per Parameter Encoding) of the Consumer Secret and Token Secret, separated by an '&'
* character (ASCII code 38) even if empty.
* - Chapter 9.2 ("HMAC-SHA1")
*/
-class OAuthSignatureMethod_HMAC_SHA1 extends OAuthSignatureMethod {
- function get_name() {
+class OAuthSignatureMethod_HMAC_SHA1 extends OAuthSignatureMethod
+{
+ function get_name()
+ {
return "HMAC-SHA1";
}
- public function build_signature($request, $consumer, $token) {
+ public function build_signature($request, $consumer, $token)
+ {
$base_string = $request->get_signature_base_string();
$request->base_string = $base_string;
}
/**
- * The PLAINTEXT method does not provide any security protection and SHOULD only be used
+ * The PLAINTEXT method does not provide any security protection and SHOULD only be used
* over a secure channel such as HTTPS. It does not use the Signature Base String.
* - Chapter 9.4 ("PLAINTEXT")
*/
-class OAuthSignatureMethod_PLAINTEXT extends OAuthSignatureMethod {
- public function get_name() {
+class OAuthSignatureMethod_PLAINTEXT extends OAuthSignatureMethod
+{
+ public function get_name()
+ {
return "PLAINTEXT";
}
/**
- * oauth_signature is set to the concatenated encoded values of the Consumer Secret and
- * Token Secret, separated by a '&' character (ASCII code 38), even if either secret is
+ * oauth_signature is set to the concatenated encoded values of the Consumer Secret and
+ * Token Secret, separated by a '&' character (ASCII code 38), even if either secret is
* empty. The result MUST be encoded again.
* - Chapter 9.4.1 ("Generating Signatures")
*
* Please note that the second encoding MUST NOT happen in the SignatureMethod, as
* OAuthRequest handles this!
*/
- public function build_signature($request, $consumer, $token) {
+ public function build_signature($request, $consumer, $token)
+ {
$key_parts = array(
$consumer->secret,
($token) ? $token->secret : ""
}
/**
- * The RSA-SHA1 signature method uses the RSASSA-PKCS1-v1_5 signature algorithm as defined in
- * [RFC3447] section 8.2 (more simply known as PKCS#1), using SHA-1 as the hash function for
- * EMSA-PKCS1-v1_5. It is assumed that the Consumer has provided its RSA public key in a
- * verified way to the Service Provider, in a manner which is beyond the scope of this
+ * The RSA-SHA1 signature method uses the RSASSA-PKCS1-v1_5 signature algorithm as defined in
+ * [RFC3447] section 8.2 (more simply known as PKCS#1), using SHA-1 as the hash function for
+ * EMSA-PKCS1-v1_5. It is assumed that the Consumer has provided its RSA public key in a
+ * verified way to the Service Provider, in a manner which is beyond the scope of this
* specification.
* - Chapter 9.3 ("RSA-SHA1")
*/
-abstract class OAuthSignatureMethod_RSA_SHA1 extends OAuthSignatureMethod {
- public function get_name() {
+abstract class OAuthSignatureMethod_RSA_SHA1 extends OAuthSignatureMethod
+{
+ public function get_name()
+ {
return "RSA-SHA1";
}
// Either way should return a string representation of the certificate
protected abstract function fetch_private_cert(&$request);
- public function build_signature($request, $consumer, $token) {
+ public function build_signature($request, $consumer, $token)
+ {
$base_string = $request->get_signature_base_string();
$request->base_string = $base_string;
return base64_encode($signature);
}
- public function check_signature($request, $consumer, $token, $signature) {
+ public function check_signature($request, $consumer, $token, $signature)
+ {
$decoded_sig = base64_decode($signature);
$base_string = $request->get_signature_base_string();
}
}
-class OAuthRequest {
+class OAuthRequest
+{
private $parameters;
private $http_method;
private $http_url;
public static $version = '1.0';
public static $POST_INPUT = 'php://input';
- function __construct($http_method, $http_url, $parameters=NULL) {
+ function __construct($http_method, $http_url, $parameters = NULL)
+ {
@$parameters or $parameters = array();
- $parameters = array_merge( OAuthUtil::parse_parameters(parse_url($http_url, PHP_URL_QUERY)), $parameters);
+ $parameters = array_merge(OAuthUtil::parse_parameters(parse_url($http_url, PHP_URL_QUERY)), $parameters);
$this->parameters = $parameters;
$this->http_method = $http_method;
$this->http_url = $http_url;
/**
* attempt to build up a request from what was passed to the server
*/
- public static function from_request($http_method=NULL, $http_url=NULL, $parameters=NULL) {
+ public static function from_request($http_method = NULL, $http_url = NULL, $parameters = NULL)
+ {
$scheme = (!isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] != "on")
- ? 'http'
- : 'https';
+ ? 'http'
+ : 'https';
@$http_url or $http_url = $scheme .
- '://' . $_SERVER['HTTP_HOST'] .
- ':' .
- $_SERVER['SERVER_PORT'] .
- $_SERVER['REQUEST_URI'];
+ '://' . $_SERVER['HTTP_HOST'] .
+ ':' .
+ $_SERVER['SERVER_PORT'] .
+ $_SERVER['REQUEST_URI'];
@$http_method or $http_method = $_SERVER['REQUEST_METHOD'];
// We weren't handed any parameters, so let's find the ones relevant to
// It's a POST request of the proper content-type, so parse POST
// parameters and add those overriding any duplicates from GET
- if ($http_method == "POST"
- && @strstr($request_headers["Content-Type"],
- "application/x-www-form-urlencoded")
- ) {
+ if (
+ $http_method == "POST"
+ && @strstr(
+ $request_headers["Content-Type"],
+ "application/x-www-form-urlencoded"
+ )
+ ) {
$post_data = OAuthUtil::parse_parameters(
file_get_contents(self::$POST_INPUT)
);
);
$parameters = array_merge($parameters, $header_parameters);
}
-
}
// fix for friendica redirect system
-
- $http_url = substr($http_url, 0, strpos($http_url,$parameters['pagename'])+strlen($parameters['pagename']));
- unset( $parameters['pagename'] );
-
+
+ $http_url = substr($http_url, 0, strpos($http_url, $parameters['pagename']) + strlen($parameters['pagename']));
+ unset($parameters['pagename']);
+
return new OAuthRequest($http_method, $http_url, $parameters);
}
/**
* pretty much a helper function to set up the request
*/
- public static function from_consumer_and_token($consumer, $token, $http_method, $http_url, $parameters=NULL) {
+ public static function from_consumer_and_token($consumer, $token, $http_method, $http_url, $parameters = NULL)
+ {
@$parameters or $parameters = array();
- $defaults = array("oauth_version" => OAuthRequest::$version,
- "oauth_nonce" => OAuthRequest::generate_nonce(),
- "oauth_timestamp" => OAuthRequest::generate_timestamp(),
- "oauth_consumer_key" => $consumer->key);
+ $defaults = array(
+ "oauth_version" => OAuthRequest::$version,
+ "oauth_nonce" => OAuthRequest::generate_nonce(),
+ "oauth_timestamp" => OAuthRequest::generate_timestamp(),
+ "oauth_consumer_key" => $consumer->key
+ );
if ($token)
$defaults['oauth_token'] = $token->key;
return new OAuthRequest($http_method, $http_url, $parameters);
}
- public function set_parameter($name, $value, $allow_duplicates = true) {
+ public function set_parameter($name, $value, $allow_duplicates = true)
+ {
if ($allow_duplicates && isset($this->parameters[$name])) {
// We have already added parameter(s) with this name, so add to the list
if (is_scalar($this->parameters[$name])) {
}
}
- public function get_parameter($name) {
+ public function get_parameter($name)
+ {
return isset($this->parameters[$name]) ? $this->parameters[$name] : null;
}
- public function get_parameters() {
+ public function get_parameters()
+ {
return $this->parameters;
}
- public function unset_parameter($name) {
+ public function unset_parameter($name)
+ {
unset($this->parameters[$name]);
}
* The request parameters, sorted and concatenated into a normalized string.
* @return string
*/
- public function get_signable_parameters() {
+ public function get_signable_parameters()
+ {
// Grab all parameters
$params = $this->parameters;
* and the parameters (normalized), each urlencoded
* and the concated with &.
*/
- public function get_signature_base_string() {
+ public function get_signature_base_string()
+ {
$parts = array(
$this->get_normalized_http_method(),
$this->get_normalized_http_url(),
/**
* just uppercases the http method
*/
- public function get_normalized_http_method() {
+ public function get_normalized_http_method()
+ {
return strtoupper($this->http_method);
}
* parses the url and rebuilds it to be
* scheme://host/path
*/
- public function get_normalized_http_url() {
+ public function get_normalized_http_url()
+ {
$parts = parse_url($this->http_url);
$port = @$parts['port'];
$port or $port = ($scheme == 'https') ? '443' : '80';
if (($scheme == 'https' && $port != '443')
- || ($scheme == 'http' && $port != '80')) {
+ || ($scheme == 'http' && $port != '80')
+ ) {
$host = "$host:$port";
}
return "$scheme://$host$path";
/**
* builds a url usable for a GET request
*/
- public function to_url() {
+ public function to_url()
+ {
$post_data = $this->to_postdata();
$out = $this->get_normalized_http_url();
if ($post_data) {
- $out .= '?'.$post_data;
+ $out .= '?' . $post_data;
}
return $out;
}
/**
* builds the data one would send in a POST request
*/
- public function to_postdata($raw = false) {
+ public function to_postdata($raw = false)
+ {
if ($raw)
- return($this->parameters);
+ return $this->parameters;
else
return OAuthUtil::build_http_query($this->parameters);
}
/**
* builds the Authorization: header
*/
- public function to_header($realm=null) {
+ public function to_header($realm = null)
+ {
$first = true;
- if($realm) {
+ if ($realm) {
$out = 'Authorization: OAuth realm="' . OAuthUtil::urlencode_rfc3986($realm) . '"';
$first = false;
} else
$out = 'Authorization: OAuth';
- $total = array();
foreach ($this->parameters as $k => $v) {
if (substr($k, 0, 5) != "oauth") continue;
if (is_array($v)) {
}
$out .= ($first) ? ' ' : ',';
$out .= OAuthUtil::urlencode_rfc3986($k) .
- '="' .
- OAuthUtil::urlencode_rfc3986($v) .
- '"';
+ '="' .
+ OAuthUtil::urlencode_rfc3986($v) .
+ '"';
$first = false;
}
return $out;
}
- public function __toString() {
+ public function __toString()
+ {
return $this->to_url();
}
- public function sign_request($signature_method, $consumer, $token) {
+ public function sign_request($signature_method, $consumer, $token)
+ {
$this->set_parameter(
"oauth_signature_method",
$signature_method->get_name(),
$this->set_parameter("oauth_signature", $signature, false);
}
- public function build_signature($signature_method, $consumer, $token) {
+ public function build_signature($signature_method, $consumer, $token)
+ {
$signature = $signature_method->build_signature($this, $consumer, $token);
return $signature;
}
/**
* util function: current timestamp
*/
- private static function generate_timestamp() {
+ private static function generate_timestamp()
+ {
return time();
}
/**
* util function: current nonce
*/
- private static function generate_nonce() {
- $mt = microtime();
- $rand = mt_rand();
-
- return md5($mt . $rand); // md5s look nicer than numbers
+ private static function generate_nonce()
+ {
+ return Friendica\Util\Strings::getRandomHex(32);
}
}
-class OAuthServer {
+class OAuthServer
+{
protected $timestamp_threshold = 300; // in seconds, five minutes
protected $version = '1.0'; // hi blaine
protected $signature_methods = array();
protected $data_store;
- function __construct($data_store) {
+ function __construct($data_store)
+ {
$this->data_store = $data_store;
}
- public function add_signature_method($signature_method) {
+ public function add_signature_method($signature_method)
+ {
$this->signature_methods[$signature_method->get_name()] =
$signature_method;
}
* process a request_token request
* returns the request token on success
*/
- public function fetch_request_token(&$request) {
+ public function fetch_request_token(&$request)
+ {
$this->get_version($request);
$consumer = $this->get_consumer($request);
* process an access_token request
* returns the access token on success
*/
- public function fetch_access_token(&$request) {
+ public function fetch_access_token(&$request)
+ {
$this->get_version($request);
$consumer = $this->get_consumer($request);
/**
* verify an api call, checks all the parameters
*/
- public function verify_request(&$request) {
+ public function verify_request(&$request)
+ {
$this->get_version($request);
$consumer = $this->get_consumer($request);
$token = $this->get_token($request, $consumer, "access");
$this->check_signature($request, $consumer, $token);
- return array($consumer, $token);
+ return [$consumer, $token];
}
// Internals from here
/**
* version 1
*/
- private function get_version(&$request) {
+ private function get_version(&$request)
+ {
$version = $request->get_parameter("oauth_version");
if (!$version) {
- // Service Providers MUST assume the protocol version to be 1.0 if this parameter is not present.
+ // Service Providers MUST assume the protocol version to be 1.0 if this parameter is not present.
// Chapter 7.0 ("Accessing Protected Ressources")
$version = '1.0';
}
/**
* figure out the signature with some defaults
*/
- private function get_signature_method(&$request) {
+ private function get_signature_method(&$request)
+ {
$signature_method =
- @$request->get_parameter("oauth_signature_method");
+ @$request->get_parameter("oauth_signature_method");
if (!$signature_method) {
// According to chapter 7 ("Accessing Protected Ressources") the signature-method
throw new OAuthException('No signature method parameter. This parameter is required');
}
- if (!in_array($signature_method,
- array_keys($this->signature_methods))) {
+ if (!in_array(
+ $signature_method,
+ array_keys($this->signature_methods)
+ )) {
throw new OAuthException(
"Signature method '$signature_method' not supported " .
- "try one of the following: " .
- implode(", ", array_keys($this->signature_methods))
+ "try one of the following: " .
+ implode(", ", array_keys($this->signature_methods))
);
}
return $this->signature_methods[$signature_method];
/**
* try to find the consumer for the provided request's consumer key
*/
- private function get_consumer(&$request) {
+ private function get_consumer(&$request)
+ {
$consumer_key = @$request->get_parameter("oauth_consumer_key");
if (!$consumer_key) {
throw new OAuthException("Invalid consumer key");
/**
* try to find the token for the provided request's token key
*/
- private function get_token(&$request, $consumer, $token_type="access") {
+ private function get_token(&$request, $consumer, $token_type = "access")
+ {
$token_field = @$request->get_parameter('oauth_token');
$token = $this->data_store->lookup_token(
- $consumer, $token_type, $token_field
+ $consumer,
+ $token_type,
+ $token_field
);
if (!$token) {
throw new OAuthException("Invalid $token_type token: $token_field");
* all-in-one function to check the signature on a request
* should guess the signature method appropriately
*/
- private function check_signature(&$request, $consumer, $token) {
+ private function check_signature(&$request, $consumer, $token)
+ {
// this should probably be in a different method
$timestamp = @$request->get_parameter('oauth_timestamp');
$nonce = @$request->get_parameter('oauth_nonce');
$token,
$signature
);
-
+
if (!$valid_sig) {
throw new OAuthException("Invalid signature");
/**
* check that the timestamp is new enough
*/
- private function check_timestamp($timestamp) {
- if( ! $timestamp )
+ private function check_timestamp($timestamp)
+ {
+ if (!$timestamp)
throw new OAuthException(
'Missing timestamp parameter. The parameter is required'
);
-
+
// verify that timestamp is recentish
$now = time();
if (abs($now - $timestamp) > $this->timestamp_threshold) {
/**
* check that the nonce is not repeated
*/
- private function check_nonce($consumer, $token, $nonce, $timestamp) {
- if( ! $nonce )
+ private function check_nonce($consumer, $token, $nonce, $timestamp)
+ {
+ if (!$nonce)
throw new OAuthException(
'Missing nonce parameter. The parameter is required'
);
throw new OAuthException("Nonce already used: $nonce");
}
}
-
}
-class OAuthDataStore {
- function lookup_consumer($consumer_key) {
+class OAuthDataStore
+{
+ function lookup_consumer($consumer_key)
+ {
// implement me
}
- function lookup_token($consumer, $token_type, $token) {
+ function lookup_token($consumer, $token_type, $token)
+ {
// implement me
}
- function lookup_nonce($consumer, $token, $nonce, $timestamp) {
+ function lookup_nonce($consumer, $token, $nonce, $timestamp)
+ {
// implement me
}
- function new_request_token($consumer, $callback = null) {
+ function new_request_token($consumer, $callback = null)
+ {
// return a new token attached to this consumer
}
- function new_access_token($token, $consumer, $verifier = null) {
+ function new_access_token($token, $consumer, $verifier = null)
+ {
// return a new access token attached to this consumer
// for the user associated with this token if the request token
// is authorized
// should also invalidate the request token
}
-
}
-class OAuthUtil {
- public static function urlencode_rfc3986($input) {
- if (is_array($input)) {
- return array_map(array('OAuthUtil', 'urlencode_rfc3986'), $input);
- } else if (is_scalar($input)) {
- return str_replace(
- '+',
- ' ',
- str_replace('%7E', '~', rawurlencode($input))
- );
- } else {
- return '';
+class OAuthUtil
+{
+ public static function urlencode_rfc3986($input)
+ {
+ if (is_array($input)) {
+ return array_map(['OAuthUtil', 'urlencode_rfc3986'], $input);
+ } else if (is_scalar($input)) {
+ return str_replace(
+ '+',
+ ' ',
+ str_replace('%7E', '~', rawurlencode($input))
+ );
+ } else {
+ return '';
+ }
}
-}
// This decode function isn't taking into consideration the above
// modifications to the encoding process. However, this method doesn't
// seem to be used anywhere so leaving it as is.
- public static function urldecode_rfc3986($string) {
+ public static function urldecode_rfc3986($string)
+ {
return urldecode($string);
}
// Utility function for turning the Authorization: header into
// parameters, has to do some unescaping
// Can filter out any non-oauth parameters if needed (default behaviour)
- public static function split_header($header, $only_allow_oauth_parameters = true) {
+ public static function split_header($header, $only_allow_oauth_parameters = true)
+ {
$pattern = '/(([-_a-z]*)=("([^"]*)"|([^,]*)),?)/';
$offset = 0;
- $params = array();
+ $params = [];
while (preg_match($pattern, $header, $matches, PREG_OFFSET_CAPTURE, $offset) > 0) {
$match = $matches[0];
$header_name = $matches[2][0];
}
// helper to try to sort out headers for people who aren't running apache
- public static function get_headers() {
+ public static function get_headers()
+ {
if (function_exists('apache_request_headers')) {
// we need this to get the actual Authorization: header
// because apache tends to tell us it doesn't exist
// we always want the keys to be Cased-Like-This and arh()
// returns the headers in the same case as they are in the
// request
- $out = array();
- foreach( $headers AS $key => $value ) {
+ $out = [];
+ foreach ($headers as $key => $value) {
$key = str_replace(
- " ",
- "-",
- ucwords(strtolower(str_replace("-", " ", $key)))
- );
+ " ",
+ "-",
+ ucwords(strtolower(str_replace("-", " ", $key)))
+ );
$out[$key] = $value;
}
} else {
// otherwise we don't have apache and are just going to have to hope
// that $_SERVER actually contains what we need
- $out = array();
- if( isset($_SERVER['CONTENT_TYPE']) )
+ $out = [];
+ if (isset($_SERVER['CONTENT_TYPE']))
$out['Content-Type'] = $_SERVER['CONTENT_TYPE'];
- if( isset($_ENV['CONTENT_TYPE']) )
+ if (isset($_ENV['CONTENT_TYPE']))
$out['Content-Type'] = $_ENV['CONTENT_TYPE'];
foreach ($_SERVER as $key => $value) {
// This function takes a input like a=b&a=c&d=e and returns the parsed
// parameters like this
// array('a' => array('b','c'), 'd' => 'e')
- public static function parse_parameters( $input ) {
+ public static function parse_parameters($input)
+ {
if (!isset($input) || !$input) return array();
$pairs = explode('&', $input);
- $parsed_parameters = array();
+ $parsed_parameters = [];
foreach ($pairs as $pair) {
$split = explode('=', $pair, 2);
$parameter = OAuthUtil::urldecode_rfc3986($split[0]);
if (is_scalar($parsed_parameters[$parameter])) {
// This is the first duplicate, so transform scalar (string) into an array
// so we can add the duplicates
- $parsed_parameters[$parameter] = array($parsed_parameters[$parameter]);
+ $parsed_parameters[$parameter] = [$parsed_parameters[$parameter]];
}
$parsed_parameters[$parameter][] = $value;
return $parsed_parameters;
}
- public static function build_http_query($params) {
+ public static function build_http_query($params)
+ {
if (!$params) return '';
// Urlencode both keys and values
// Ref: Spec: 9.1.1 (1)
uksort($params, 'strcmp');
- $pairs = array();
+ $pairs = [];
foreach ($params as $parameter => $value) {
if (is_array($value)) {
// If two or more parameters share the same name, they are sorted by their value
return implode('&', $pairs);
}
}
-
-?>
// put the event parametes in an array so we can better transmit them
$event_params = [
- 'event_id' => intval(defaults($_GET, 'id', 0)),
+ 'event_id' => intval($_GET['id'] ?? 0),
'start' => $start,
'finish' => $finish,
'adjust_start' => $adjust_start,
$entry = [
'url' => Model\Contact::magicLink($common_friend['url']),
- 'itemurl' => defaults($contact_details, 'addr', $common_friend['url']),
+ 'itemurl' => ($contact_details['addr'] ?? '') ?: $common_friend['url'],
'name' => $contact_details['name'],
'thumb' => ProxyUtils::proxifyUrl($contact_details['thumb'], false, ProxyUtils::SIZE_THUMB),
'img_hover' => $contact_details['name'],
return;
}
- $name = defaults($_POST, 'name' , $contact['name']);
- $nick = defaults($_POST, 'nick' , '');
- $url = defaults($_POST, 'url' , '');
- $alias = defaults($_POST, 'alias' , '');
- $request = defaults($_POST, 'request' , '');
- $confirm = defaults($_POST, 'confirm' , '');
- $notify = defaults($_POST, 'notify' , '');
- $poll = defaults($_POST, 'poll' , '');
- $attag = defaults($_POST, 'attag' , '');
- $photo = defaults($_POST, 'photo' , '');
- $remote_self = defaults($_POST, 'remote_self', false);
+ $name = ($_POST['name'] ?? '') ?: $contact['name'];
+ $nick = $_POST['nick'] ?? '';
+ $url = $_POST['url'] ?? '';
+ $alias = $_POST['alias'] ?? '';
+ $request = $_POST['request'] ?? '';
+ $confirm = $_POST['confirm'] ?? '';
+ $notify = $_POST['notify'] ?? '';
+ $poll = $_POST['poll'] ?? '';
+ $attag = $_POST['attag'] ?? '';
+ $photo = $_POST['photo'] ?? '';
+ $remote_self = $_POST['remote_self'] ?? false;
$nurl = Strings::normaliseLink($url);
$r = DBA::update(
use Friendica\Model\Group;
use Friendica\Model\User;
use Friendica\Network\Probe;
+use Friendica\Protocol\Activity;
use Friendica\Util\Crypto;
use Friendica\Util\DateTimeFormat;
use Friendica\Util\Network;
* since we are operating on behalf of our registered user to approve a friendship.
*/
if (empty($_POST['source_url'])) {
- $uid = defaults($handsfree, 'uid', local_user());
+ $uid = ($handsfree['uid'] ?? 0) ?: local_user();
if (!$uid) {
notice(L10n::t('Permission denied.') . EOL);
return;
$intro_id = $handsfree['intro_id'];
$duplex = $handsfree['duplex'];
$cid = 0;
- $hidden = intval(defaults($handsfree, 'hidden' , 0));
+ $hidden = intval($handsfree['hidden'] ?? 0);
} else {
- $dfrn_id = Strings::escapeTags(trim(defaults($_POST, 'dfrn_id' , '')));
- $intro_id = intval(defaults($_POST, 'intro_id' , 0));
- $duplex = intval(defaults($_POST, 'duplex' , 0));
- $cid = intval(defaults($_POST, 'contact_id', 0));
- $hidden = intval(defaults($_POST, 'hidden' , 0));
+ $dfrn_id = Strings::escapeTags(trim($_POST['dfrn_id'] ?? ''));
+ $intro_id = intval($_POST['intro_id'] ?? 0);
+ $duplex = intval($_POST['duplex'] ?? 0);
+ $cid = intval($_POST['contact_id'] ?? 0);
+ $hidden = intval($_POST['hidden'] ?? 0);
}
/*
*/
if (!empty($_POST['source_url'])) {
// We are processing an external confirmation to an introduction created by our user.
- $public_key = defaults($_POST, 'public_key', '');
- $dfrn_id = hex2bin(defaults($_POST, 'dfrn_id' , ''));
- $source_url = hex2bin(defaults($_POST, 'source_url', ''));
- $aes_key = defaults($_POST, 'aes_key' , '');
- $duplex = intval(defaults($_POST, 'duplex' , 0));
- $page = intval(defaults($_POST, 'page' , 0));
+ $public_key = $_POST['public_key'] ?? '';
+ $dfrn_id = hex2bin($_POST['dfrn_id'] ?? '');
+ $source_url = hex2bin($_POST['source_url'] ?? '');
+ $aes_key = $_POST['aes_key'] ?? '';
+ $duplex = intval($_POST['duplex'] ?? 0);
+ $page = intval($_POST['page'] ?? 0);
$forum = (($page == 1) ? 1 : 0);
$prv = (($page == 2) ? 1 : 0);
'source_name' => ((strlen(stripslashes($combined['name']))) ? stripslashes($combined['name']) : L10n::t('[Name Withheld]')),
'source_link' => $combined['url'],
'source_photo' => $combined['photo'],
- 'verb' => ($mutual?ACTIVITY_FRIEND:ACTIVITY_FOLLOW),
+ 'verb' => ($mutual ? Activity::FRIEND : Activity::FOLLOW),
'otype' => 'intro'
]);
}
use Friendica\Model\User;
use Friendica\Protocol\DFRN;
use Friendica\Protocol\Diaspora;
-use Friendica\Util\Strings;
use Friendica\Util\Network;
+use Friendica\Util\Strings;
function dfrn_notify_post(App $a) {
Logger::log(__function__, Logger::TRACE);
if (empty($_POST) || !empty($postdata)) {
$data = json_decode($postdata);
if (is_object($data)) {
- $nick = defaults($a->argv, 1, '');
+ $nick = $a->argv[1] ?? '';
$user = DBA::selectFirst('user', [], ['nickname' => $nick, 'account_expired' => false, 'account_removed' => false]);
if (!DBA::isResult($user)) {
$dfrn_id = (!empty($_POST['dfrn_id']) ? Strings::escapeTags(trim($_POST['dfrn_id'])) : '');
$dfrn_version = (!empty($_POST['dfrn_version']) ? (float) $_POST['dfrn_version'] : 2.0);
$challenge = (!empty($_POST['challenge']) ? Strings::escapeTags(trim($_POST['challenge'])) : '');
- $data = defaults($_POST, 'data', '');
- $key = defaults($_POST, 'key', '');
+ $data = $_POST['data'] ?? '';
+ $key = $_POST['key'] ?? '';
$rino_remote = (!empty($_POST['rino']) ? intval($_POST['rino']) : 0);
$dissolve = (!empty($_POST['dissolve']) ? intval($_POST['dissolve']) : 0);
$perm = (!empty($_POST['perm']) ? Strings::escapeTags(trim($_POST['perm'])) : 'r');
function dfrn_dispatch_public($postdata)
{
- $msg = Diaspora::decodeRaw([], $postdata, true);
+ $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;
function dfrn_dispatch_private($user, $postdata)
{
- $msg = Diaspora::decodeRaw($user, $postdata);
+ $msg = Diaspora::decodeRaw($postdata, $user['prvkey'] ?? '');
if (!$msg) {
System::xmlExit(4, 'Unable to parse message');
}
{
Login::sessionAuth();
- $dfrn_id = defaults($_GET, 'dfrn_id' , '');
- $type = defaults($_GET, 'type' , 'data');
- $last_update = defaults($_GET, 'last_update' , '');
- $destination_url = defaults($_GET, 'destination_url', '');
- $challenge = defaults($_GET, 'challenge' , '');
- $sec = defaults($_GET, 'sec' , '');
- $dfrn_version = (float) defaults($_GET, 'dfrn_version' , 2.0);
+ $dfrn_id = $_GET['dfrn_id'] ?? '';
+ $type = ($_GET['type'] ?? '') ?: 'data';
+ $last_update = $_GET['last_update'] ?? '';
+ $destination_url = $_GET['destination_url'] ?? '';
+ $challenge = $_GET['challenge'] ?? '';
+ $sec = $_GET['sec'] ?? '';
+ $dfrn_version = floatval(($_GET['dfrn_version'] ?? 0.0) ?: 2.0);
$quiet = !empty($_GET['quiet']);
// Possibly it is an OStatus compatible server that requests a user feed
- $user_agent = defaults($_SERVER, 'HTTP_USER_AGENT', '');
+ $user_agent = $_SERVER['HTTP_USER_AGENT'] ?? '';
if (($a->argc > 1) && ($dfrn_id == '') && !strstr($user_agent, 'Friendica')) {
$nickname = $a->argv[1];
header("Content-type: application/atom+xml");
function dfrn_poll_post(App $a)
{
- $dfrn_id = defaults($_POST, 'dfrn_id' , '');
- $challenge = defaults($_POST, 'challenge', '');
- $url = defaults($_POST, 'url' , '');
- $sec = defaults($_POST, 'sec' , '');
- $ptype = defaults($_POST, 'type' , '');
- $perm = defaults($_POST, 'perm' , 'r');
- $dfrn_version = !empty($_POST['dfrn_version']) ? (float) $_POST['dfrn_version'] : 2.0;
+ $dfrn_id = $_POST['dfrn_id'] ?? '';
+ $challenge = $_POST['challenge'] ?? '';
+ $url = $_POST['url'] ?? '';
+ $sec = $_POST['sec'] ?? '';
+ $ptype = $_POST['type'] ?? '';
+ $perm = ($_POST['perm'] ?? '') ?: 'r';
+ $dfrn_version = floatval(($_GET['dfrn_version'] ?? 0.0) ?: 2.0);
if ($ptype === 'profile-check') {
if (strlen($challenge) && strlen($sec)) {
function dfrn_poll_content(App $a)
{
- $dfrn_id = defaults($_GET, 'dfrn_id' , '');
- $type = defaults($_GET, 'type' , 'data');
- $last_update = defaults($_GET, 'last_update' , '');
- $destination_url = defaults($_GET, 'destination_url', '');
- $sec = defaults($_GET, 'sec' , '');
- $dfrn_version = !empty($_GET['dfrn_version']) ? (float) $_GET['dfrn_version'] : 2.0;
+ $dfrn_id = $_GET['dfrn_id'] ?? '';
+ $type = ($_GET['type'] ?? '') ?: 'data';
+ $last_update = $_GET['last_update'] ?? '';
+ $destination_url = $_GET['destination_url'] ?? '';
+ $sec = $_GET['sec'] ?? '';
+ $dfrn_version = floatval(($_GET['dfrn_version'] ?? 0.0) ?: 2.0);
$quiet = !empty($_GET['quiet']);
$direction = -1;
use Friendica\Model\User;
use Friendica\Module\Login;
use Friendica\Network\Probe;
+use Friendica\Protocol\Activity;
use Friendica\Util\DateTimeFormat;
use Friendica\Util\Network;
use Friendica\Util\Strings;
if (local_user() && ($a->user['nickname'] == $a->argv[1]) && !empty($_POST['dfrn_url'])) {
$dfrn_url = Strings::escapeTags(trim($_POST['dfrn_url']));
$aes_allow = !empty($_POST['aes_allow']);
- $confirm_key = defaults($_POST, 'confirm_key', "");
+ $confirm_key = $_POST['confirm_key'] ?? '';
$hidden = (!empty($_POST['hidden-contact']) ? intval($_POST['hidden-contact']) : 0);
$contact_record = null;
$blocked = 1;
$r = q("SELECT `id`, `network` FROM `contact` WHERE `uid` = %d AND `url` = '%s' AND `site-pubkey` = '%s' LIMIT 1",
intval(local_user()),
DBA::escape($dfrn_url),
- defaults($parms, 'key', '') // Potentially missing
+ $parms['key'] ?? '' // Potentially missing
);
if (DBA::isResult($r)) {
Group::addMember(User::getDefaultGroup(local_user(), $r[0]["network"]), $r[0]['id']);
intval($uid),
intval($contact_record['id']),
intval(!empty($_POST['knowyou'])),
- DBA::escape(Strings::escapeTags(trim(defaults($_POST, 'dfrn-request-message', '')))),
+ DBA::escape(Strings::escapeTags(trim($_POST['dfrn-request-message'] ?? ''))),
DBA::escape($hash),
DBA::escape(DateTimeFormat::utcNow())
);
$dfrn_url = Strings::escapeTags(trim(hex2bin($_GET['dfrn_url'])));
$aes_allow = !empty($_GET['aes_allow']);
- $confirm_key = defaults($_GET, 'confirm_key', "");
+ $confirm_key = $_GET['confirm_key'] ?? '';
// Checking fastlane for validity
if (!empty($_SESSION['fastlane']) && (Strings::normaliseLink($_SESSION["fastlane"]) == Strings::normaliseLink($dfrn_url))) {
'source_name' => ((strlen(stripslashes($r[0]['name']))) ? stripslashes($r[0]['name']) : L10n::t('[Name Withheld]')),
'source_link' => $r[0]['url'],
'source_photo' => $r[0]['photo'],
- 'verb' => ACTIVITY_REQ_FRIEND,
+ 'verb' => Activity::REQ_FRIEND,
'otype' => 'intro'
]);
}
if (isset($item_parent_uri)) {
$parent = Item::selectFirst(['uid'], ['uri' => $item_parent_uri, 'wall' => true]);
if (DBA::isResult($parent)) {
- $a->profile['uid'] = defaults($a->profile, 'uid', $parent['uid']);
- $a->profile['profile_uid'] = defaults($a->profile, 'profile_uid', $parent['uid']);
+ $a->profile['uid'] = ($a->profile['uid'] ?? 0) ?: $parent['uid'];
+ $a->profile['profile_uid'] = ($a->profile['profile_uid'] ?? 0) ?: $parent['uid'];
$is_remote_contact = Session::getRemoteContactID($a->profile['profile_uid']);
if ($is_remote_contact) {
$item_uid = $parent['uid'];
use Friendica\Core\Hook;
use Friendica\Core\L10n;
use Friendica\Core\Renderer;
+use Friendica\Database\DBA;
+use Friendica\Model\Contact;
use Friendica\Model\FileTag;
use Friendica\Model\Item;
-use Friendica\Database\DBA;
use Friendica\Util\Crypto;
function editpost_content(App $a)
return $o;
}
+
+function undo_post_tagging($s) {
+ $matches = null;
+ $cnt = preg_match_all('/([!#@])\[url=(.*?)\](.*?)\[\/url\]/ism', $s, $matches, PREG_SET_ORDER);
+ if ($cnt) {
+ foreach ($matches as $mtch) {
+ if (in_array($mtch[1], ['!', '@'])) {
+ $contact = Contact::getDetailsByURL($mtch[2]);
+ $mtch[3] = empty($contact['addr']) ? $mtch[2] : $contact['addr'];
+ }
+ $s = str_replace($mtch[0], $mtch[1] . $mtch[3],$s);
+ }
+ }
+ return $s;
+}
*/
use Friendica\App;
+use Friendica\BaseObject;
use Friendica\Content\Nav;
use Friendica\Content\Widget\CalendarExport;
use Friendica\Core\ACL;
use Friendica\Model\Item;
use Friendica\Model\Profile;
use Friendica\Module\Login;
+use Friendica\Util\ACLFormatter;
use Friendica\Util\DateTimeFormat;
use Friendica\Util\Strings;
use Friendica\Util\Temporal;
$cid = !empty($_POST['cid']) ? intval($_POST['cid']) : 0;
$uid = local_user();
- $start_text = Strings::escapeHtml(defaults($_REQUEST, 'start_text', ''));
- $finish_text = Strings::escapeHtml(defaults($_REQUEST, 'finish_text', ''));
+ $start_text = Strings::escapeHtml($_REQUEST['start_text'] ?? '');
+ $finish_text = Strings::escapeHtml($_REQUEST['finish_text'] ?? '');
- $adjust = intval(defaults($_POST, 'adjust', 0));
- $nofinish = intval(defaults($_POST, 'nofinish', 0));
+ $adjust = intval($_POST['adjust'] ?? 0);
+ $nofinish = intval($_POST['nofinish'] ?? 0);
// The default setting for the `private` field in event_store() is false, so mirror that
$private_event = false;
// and we'll waste a bunch of time responding to it. Time that
// could've been spent doing something else.
- $summary = trim(defaults($_POST, 'summary' , ''));
- $desc = trim(defaults($_POST, 'desc' , ''));
- $location = trim(defaults($_POST, 'location', ''));
+ $summary = trim($_POST['summary'] ?? '');
+ $desc = trim($_POST['desc'] ?? '');
+ $location = trim($_POST['location'] ?? '');
$type = 'event';
$params = [
$a->internalRedirect($onerror_path);
}
- $share = intval(defaults($_POST, 'share', 0));
+ $share = intval($_POST['share'] ?? 0);
$c = q("SELECT `id` FROM `contact` WHERE `uid` = %d AND `self` LIMIT 1",
intval(local_user())
if ($share) {
- $str_group_allow = perms2str(defaults($_POST, 'group_allow' , ''));
- $str_contact_allow = perms2str(defaults($_POST, 'contact_allow', ''));
- $str_group_deny = perms2str(defaults($_POST, 'group_deny' , ''));
- $str_contact_deny = perms2str(defaults($_POST, 'contact_deny' , ''));
+
+ /** @var ACLFormatter $aclFormatter */
+ $aclFormatter = BaseObject::getClass(ACLFormatter::class);
+
+ $str_group_allow = $aclFormatter->toString($_POST['group_allow'] ?? '');
+ $str_contact_allow = $aclFormatter->toString($_POST['contact_allow'] ?? '');
+ $str_group_deny = $aclFormatter->toString($_POST['group_deny'] ?? '');
+ $str_contact_deny = $aclFormatter->toString($_POST['contact_deny'] ?? '');
// Undo the pseudo-contact of self, since there are real contacts now
if (strpos($str_contact_allow, '<' . $self . '>') !== false) {
}
// Needed to match the correct template in a module that uses a different theme than the user/site/default
- $theme = Strings::sanitizeFilePathItem(defaults($_GET, 'theme', null));
+ $theme = Strings::sanitizeFilePathItem($_GET['theme'] ?? null);
if ($theme && is_file("view/theme/$theme/config.php")) {
$a->setCurrentTheme($theme);
}
$uid = local_user();
// Issue 4815: Silently removing a prefixing @
- $url = ltrim(Strings::escapeTags(trim(defaults($_REQUEST, 'url', ''))), '@!');
+ $url = ltrim(Strings::escapeTags(trim($_REQUEST['url'] ?? '')), '@!');
// Issue 6874: Allow remote following from Peertube
if (strpos($url, 'acct:') === 0) {
return;
}
- $note = Strings::escapeHtml(trim(defaults($_POST, 'note', '')));
+ $note = Strings::escapeHtml(trim($_POST['note'] ?? ''));
$fields = ['uid' => local_user(),'cid' => $contact_id, 'name' => $contact['name'],
'url' => $contact['url'], 'request' => $contact['request'],
}
if (!$blocked) {
- $keywords = defaults($a->profile, 'pub_keywords', '');
+ $keywords = $a->profile['pub_keywords'] ?? '';
$keywords = str_replace([',',' ',',,'], [' ',',',','], $keywords);
if (strlen($keywords)) {
$a->page['htmlhead'] .= '<meta name="keywords" content="' . $keywords . '" />' . "\r\n";
function hovercard_content()
{
- $profileurl = defaults($_REQUEST, 'profileurl', '');
- $datatype = defaults($_REQUEST, 'datatype' , 'json');
+ $profileurl = $_REQUEST['profileurl'] ?? '';
+ $datatype = ($_REQUEST['datatype'] ?? '') ?: 'json';
// Get out if the system doesn't have public access allowed
if (intval(Config::get('system', 'block_public'))) {
if (strpos($profileurl, 'redir/') === 0) {
$cid = intval(substr($profileurl, 6));
$remote_contact = DBA::selectFirst('contact', ['nurl'], ['id' => $cid]);
- $profileurl = defaults($remote_contact, 'nurl', '');
+ $profileurl = $remote_contact['nurl'] ?? '';
}
$contact = [];
$profile = [
'name' => $contact['name'],
'nick' => $contact['nick'],
- 'addr' => defaults($contact, 'addr', $contact['url']),
+ 'addr' => ($contact['addr'] ?? '') ?: $contact['url'],
'thumb' => ProxyUtils::proxifyUrl($contact['thumb'], false, ProxyUtils::SIZE_THUMB),
'url' => Contact::magicLink($contact['url']),
'nurl' => $contact['nurl'], // We additionally store the nurl as identifier
+++ /dev/null
-<?php
-
-use Friendica\App;
-use Friendica\Database\DBA;
-use Friendica\Model\Item;
-
-function ignored_init(App $a)
-{
- if (!local_user()) {
- exit();
- }
-
- if ($a->argc > 1) {
- $message_id = intval($a->argv[1]);
- }
-
- if (empty($message_id)) {
- exit();
- }
-
- $thread = Item::selectFirstThreadForUser(local_user(), ['uid', 'ignored'], ['iid' => $message_id]);
- if (!DBA::isResult($thread)) {
- exit();
- }
-
- // Numeric values are needed for the json output further below
- $ignored = ($thread['ignored'] ? 0 : 1);
-
- if ($thread['uid'] != 0) {
- DBA::update('thread', ['ignored' => $ignored], ['iid' => $message_id]);
- } else {
- DBA::update('user-item', ['ignored' => $ignored], ['iid' => $message_id, 'uid' => local_user()], true);
- }
-
- // See if we've been passed a return path to redirect to
- $return_path = defaults($_REQUEST, 'return', '');
- if ($return_path) {
- $rand = '_=' . time();
- if (strpos($return_path, '?')) {
- $rand = "&$rand";
- } else {
- $rand = "?$rand";
- }
-
- $a->internalRedirect($return_path . $rand);
- }
-
- // the json doesn't really matter, it will either be 0 or 1
-
- echo json_encode($ignored);
- exit();
-}
*/
use Friendica\App;
+use Friendica\BaseObject;
use Friendica\Content\Pager;
use Friendica\Content\Text\BBCode;
use Friendica\Content\Text\HTML;
use Friendica\Core\L10n;
use Friendica\Core\Logger;
use Friendica\Core\Protocol;
-use Friendica\Core\System;
use Friendica\Core\Session;
+use Friendica\Core\System;
use Friendica\Core\Worker;
use Friendica\Database\DBA;
use Friendica\Model\Attach;
use Friendica\Model\Item;
use Friendica\Model\Photo;
use Friendica\Model\Term;
+use Friendica\Protocol\Activity;
use Friendica\Protocol\Diaspora;
use Friendica\Protocol\Email;
+use Friendica\Util\ACLFormatter;
use Friendica\Util\DateTimeFormat;
use Friendica\Util\Emailer;
use Friendica\Util\Security;
Logger::log('postvars ' . print_r($_REQUEST, true), Logger::DATA);
- $api_source = defaults($_REQUEST, 'api_source', false);
+ $api_source = $_REQUEST['api_source'] ?? false;
$message_id = ((!empty($_REQUEST['message_id']) && $api_source) ? strip_tags($_REQUEST['message_id']) : '');
- $return_path = defaults($_REQUEST, 'return', '');
- $preview = intval(defaults($_REQUEST, 'preview', 0));
+ $return_path = $_REQUEST['return'] ?? '';
+ $preview = intval($_REQUEST['preview'] ?? 0);
/*
* Check for doubly-submitted posts, and reject duplicates
}
// Is this a reply to something?
- $toplevel_item_id = intval(defaults($_REQUEST, 'parent', 0));
- $thr_parent_uri = trim(defaults($_REQUEST, 'parent_uri', ''));
+ $toplevel_item_id = intval($_REQUEST['parent'] ?? 0);
+ $thr_parent_uri = trim($_REQUEST['parent_uri'] ?? '');
$thread_parent_id = 0;
$thread_parent_contact = null;
$parent_contact = null;
$objecttype = null;
- $profile_uid = defaults($_REQUEST, 'profile_uid', local_user());
- $posttype = defaults($_REQUEST, 'post_type', Item::PT_ARTICLE);
+ $profile_uid = ($_REQUEST['profile_uid'] ?? 0) ?: local_user();
+ $posttype = ($_REQUEST['post_type'] ?? '') ?: Item::PT_ARTICLE;
if ($toplevel_item_id || $thr_parent_uri) {
if ($toplevel_item_id) {
$toplevel_item_id = $toplevel_item['id'];
$parent_user = $toplevel_item['uid'];
- $objecttype = ACTIVITY_OBJ_COMMENT;
+ $objecttype = Activity\ObjectType::COMMENT;
}
if ($toplevel_item_id) {
Logger::info('mod_item: item_post parent=' . $toplevel_item_id);
}
- $post_id = intval(defaults($_REQUEST, 'post_id', 0));
- $app = strip_tags(defaults($_REQUEST, 'source', ''));
- $extid = strip_tags(defaults($_REQUEST, 'extid', ''));
- $object = defaults($_REQUEST, 'object', '');
+ $post_id = intval($_REQUEST['post_id'] ?? 0);
+ $app = strip_tags($_REQUEST['source'] ?? '');
+ $extid = strip_tags($_REQUEST['extid'] ?? '');
+ $object = $_REQUEST['object'] ?? '';
// Don't use "defaults" here. It would turn 0 to 1
if (!isset($_REQUEST['wall'])) {
$categories = '';
$postopts = '';
$emailcc = '';
- $body = defaults($_REQUEST, 'body', '');
- $has_attachment = defaults($_REQUEST, 'has_attachment', 0);
+ $body = $_REQUEST['body'] ?? '';
+ $has_attachment = $_REQUEST['has_attachment'] ?? 0;
// If we have a speparate attachment, we need to add it to the body.
if (!empty($has_attachment)) {
- $attachment_type = defaults($_REQUEST, 'attachment_type', '');
- $attachment_title = defaults($_REQUEST, 'attachment_title', '');
- $attachment_text = defaults($_REQUEST, 'attachment_text', '');
+ $attachment_type = $_REQUEST['attachment_type'] ?? '';
+ $attachment_title = $_REQUEST['attachment_title'] ?? '';
+ $attachment_text = $_REQUEST['attachment_text'] ?? '';
- $attachment_url = hex2bin(defaults($_REQUEST, 'attachment_url', ''));
- $attachment_img_src = hex2bin(defaults($_REQUEST, 'attachment_img_src', ''));
+ $attachment_url = hex2bin($_REQUEST['attachment_url'] ?? '');
+ $attachment_img_src = hex2bin($_REQUEST['attachment_img_src'] ?? '');
- $attachment_img_width = defaults($_REQUEST, 'attachment_img_width', 0);
- $attachment_img_height = defaults($_REQUEST, 'attachment_img_height', 0);
+ $attachment_img_width = $_REQUEST['attachment_img_width'] ?? 0;
+ $attachment_img_height = $_REQUEST['attachment_img_height'] ?? 0;
$attachment = [
'type' => $attachment_type,
'title' => $attachment_title,
$body .= $att_bbcode;
}
+ // Convert links with empty descriptions to links without an explicit description
+ $body = preg_replace('#\[url=([^\]]*?)\]\[/url\]#ism', '[url]$1[/url]', $body);
+
if (!empty($orig_post)) {
$str_group_allow = $orig_post['allow_gid'];
$str_contact_allow = $orig_post['allow_cid'];
$str_contact_deny = $user['deny_cid'];
} else {
// use the posted permissions
- $str_group_allow = perms2str(defaults($_REQUEST, 'group_allow', ''));
- $str_contact_allow = perms2str(defaults($_REQUEST, 'contact_allow', ''));
- $str_group_deny = perms2str(defaults($_REQUEST, 'group_deny', ''));
- $str_contact_deny = perms2str(defaults($_REQUEST, 'contact_deny', ''));
+
+ /** @var ACLFormatter $aclFormatter */
+ $aclFormatter = BaseObject::getClass(ACLFormatter::class);
+
+ $str_group_allow = $aclFormatter->toString($_REQUEST['group_allow'] ?? '');
+ $str_contact_allow = $aclFormatter->toString($_REQUEST['contact_allow'] ?? '');
+ $str_group_deny = $aclFormatter->toString($_REQUEST['group_deny'] ?? '');
+ $str_contact_deny = $aclFormatter->toString($_REQUEST['contact_deny'] ?? '');
}
- $title = Strings::escapeTags(trim(defaults($_REQUEST, 'title' , '')));
- $location = Strings::escapeTags(trim(defaults($_REQUEST, 'location', '')));
- $coord = Strings::escapeTags(trim(defaults($_REQUEST, 'coord' , '')));
- $verb = Strings::escapeTags(trim(defaults($_REQUEST, 'verb' , '')));
- $emailcc = Strings::escapeTags(trim(defaults($_REQUEST, 'emailcc' , '')));
+ $title = Strings::escapeTags(trim($_REQUEST['title'] ?? ''));
+ $location = Strings::escapeTags(trim($_REQUEST['location'] ?? ''));
+ $coord = Strings::escapeTags(trim($_REQUEST['coord'] ?? ''));
+ $verb = Strings::escapeTags(trim($_REQUEST['verb'] ?? ''));
+ $emailcc = Strings::escapeTags(trim($_REQUEST['emailcc'] ?? ''));
$body = Strings::escapeHtml(trim($body));
- $network = Strings::escapeTags(trim(defaults($_REQUEST, 'network' , Protocol::DFRN)));
+ $network = Strings::escapeTags(trim(($_REQUEST['network'] ?? '') ?: Protocol::DFRN));
$guid = System::createUUID();
- $postopts = defaults($_REQUEST, 'postopts', '');
+ $postopts = $_REQUEST['postopts'] ?? '';
$private = ((strlen($str_group_allow) || strlen($str_contact_allow) || strlen($str_group_deny) || strlen($str_contact_deny)) ? 1 : 0);
$wall = $toplevel_item['wall'];
}
- $pubmail_enabled = defaults($_REQUEST, 'pubmail_enable', false) && !$private;
+ $pubmail_enabled = ($_REQUEST['pubmail_enable'] ?? false) && !$private;
// if using the API, we won't see pubmail_enable - figure out if it should be set
if ($api_source && $profile_uid && $profile_uid == local_user() && !$private) {
// save old and new categories, so we can determine what needs to be deleted from pconfig
$categories_old = $categories;
- $categories = FileTag::listToFile(trim(defaults($_REQUEST, 'category', '')), 'category');
+ $categories = FileTag::listToFile(trim($_REQUEST['category'] ?? ''), 'category');
$categories_new = $categories;
if (!empty($filedas) && is_array($filedas)) {
$match = null;
if (!$preview && Photo::setPermissionFromBody($body, $profile_uid, $original_contact_id, $str_contact_allow, $str_group_allow, $str_contact_deny, $str_group_deny)) {
- $objecttype = ACTIVITY_OBJ_IMAGE;
+ $objecttype = Activity\ObjectType::IMAGE;
}
/*
if ((preg_match_all("/\[bookmark\=([^\]]*)\](.*?)\[\/bookmark\]/ism", $body, $match, PREG_SET_ORDER) || isset($data["type"]))
&& ($posttype != Item::PT_PERSONAL_NOTE)) {
$posttype = Item::PT_PAGE;
- $objecttype = ACTIVITY_OBJ_BOOKMARK;
+ $objecttype = Activity\ObjectType::BOOKMARK;
}
- $body = bb_translate_video($body);
-
+ /** @var BBCode\Video $bbCodeVideo */
+ $bbCodeVideo = BaseObject::getClass(BBCode\Video::class);
+ $body = $bbCodeVideo->transform($body);
// Fold multi-line [code] sequences
$body = preg_replace('/\[\/code\]\s*\[code\]/ism', "\n", $body);
// Setting the object type if not defined before
if (!$objecttype) {
- $objecttype = ACTIVITY_OBJ_NOTE; // Default value
+ $objecttype = Activity\ObjectType::NOTE; // Default value
$objectdata = BBCode::getAttachedData($body);
if ($objectdata["type"] == "link") {
- $objecttype = ACTIVITY_OBJ_BOOKMARK;
+ $objecttype = Activity\ObjectType::BOOKMARK;
} elseif ($objectdata["type"] == "video") {
- $objecttype = ACTIVITY_OBJ_VIDEO;
+ $objecttype = Activity\ObjectType::VIDEO;
} elseif ($objectdata["type"] == "photo") {
- $objecttype = ACTIVITY_OBJ_IMAGE;
+ $objecttype = Activity\ObjectType::IMAGE;
}
}
}
if (!strlen($verb)) {
- $verb = ACTIVITY_POST;
+ $verb = Activity::POST;
}
if ($network == "") {
'source_name' => $datarray['author-name'],
'source_link' => $datarray['author-link'],
'source_photo' => $datarray['author-avatar'],
- 'verb' => ACTIVITY_POST,
+ 'verb' => Activity::POST,
'otype' => 'item',
'parent' => $toplevel_item_id,
'parent_uri' => $toplevel_item['uri']
'source_name' => $datarray['author-name'],
'source_link' => $datarray['author-link'],
'source_photo' => $datarray['author-avatar'],
- 'verb' => ACTIVITY_POST,
+ 'verb' => Activity::POST,
'otype' => 'item'
]);
}
$profile = $contact["url"];
$alias = $contact["alias"];
- $newname = defaults($contact, "name", $contact["nick"]);
+ $newname = ($contact["name"] ?? '') ?: $contact["nick"];
}
//if there is an url for this persons profile
* @file mod/lockview.php
*/
use Friendica\App;
+use Friendica\BaseObject;
use Friendica\Core\Hook;
use Friendica\Core\L10n;
use Friendica\Database\DBA;
use Friendica\Model\Group;
use Friendica\Model\Item;
+use Friendica\Util\ACLFormatter;
function lockview_content(App $a)
{
exit();
}
- $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']);
+ /** @var ACLFormatter $aclFormatter */
+ $aclFormatter = BaseObject::getClass(ACLFormatter::class);
+
+ $allowed_users = $aclFormatter->expand($item['allow_cid']);
+ $allowed_groups = $aclFormatter->expand($item['allow_gid']);
+ $deny_users = $aclFormatter->expand($item['deny_cid']);
+ $deny_groups = $aclFormatter->expand($item['deny_gid']);
$o = L10n::t('Visible to:') . '<br />';
$l = [];
<?php
+
/**
* @file mod/lostpass.php
*/
$a->internalRedirect();
}
- $pwdreset_token = Strings::getRandomName(12) . mt_rand(1000, 9999);
+ $pwdreset_token = Strings::getRandomName(12) . random_int(1000, 9999);
$fields = [
'pwdreset' => $pwdreset_token,
+++ /dev/null
-<?php
-/**
- * @file mod/manage.php
- */
-
-use Friendica\App;
-use Friendica\Core\Hook;
-use Friendica\Core\L10n;
-use Friendica\Core\Renderer;
-use Friendica\Core\Session;
-use Friendica\Database\DBA;
-
-function manage_post(App $a) {
-
- if (!local_user()) {
- return;
- }
-
- $uid = local_user();
- $orig_record = $a->user;
-
- if(!empty($_SESSION['submanage'])) {
- $user = DBA::selectFirst('user', [], ['uid' => $_SESSION['submanage']]);
- if (DBA::isResult($user)) {
- $uid = intval($user['uid']);
- $orig_record = $user;
- }
- }
-
- $identity = (!empty($_POST['identity']) ? intval($_POST['identity']) : 0);
- if (!$identity) {
- return;
- }
-
- $limited_id = 0;
- $original_id = $uid;
-
- $manage = DBA::select('manage', ['mid'], ['uid' => $uid]);
- while ($m = DBA::fetch($manage)) {
- if ($identity == $m['mid']) {
- $limited_id = $m['mid'];
- break;
- }
- }
- DBA::close($manage);
-
- if ($limited_id) {
- $user = DBA::selectFirst('user', [], ['uid' => $limited_id]);
- } else {
- // Check if the target user is one of our children
- $user = DBA::selectFirst('user', [], ['uid' => $identity, 'parent-uid' => $orig_record['uid']]);
-
- // Check if the target user is one of our siblings
- if (!DBA::isResult($user) && ($orig_record['parent-uid'] != 0)) {
- $user = DBA::selectFirst('user', [], ['uid' => $identity, 'parent-uid' => $orig_record['parent-uid']]);
- }
-
- // Check if it's our parent
- if (!DBA::isResult($user) && ($orig_record['parent-uid'] != 0) && ($orig_record['parent-uid'] == $identity)) {
- $user = DBA::selectFirst('user', [], ['uid' => $identity]);
- }
-
- // Finally check if it's out own user
- if (!DBA::isResult($user) && ($orig_record['uid'] != 0) && ($orig_record['uid'] == $identity)) {
- $user = DBA::selectFirst('user', [], ['uid' => $identity]);
- }
-
- }
-
- if (!DBA::isResult($user)) {
- return;
- }
-
- Session::clear();
-
- Session::setAuthenticatedForUser($a, $user, true, true);
-
- if ($limited_id) {
- $_SESSION['submanage'] = $original_id;
- }
-
- $ret = [];
- Hook::callAll('home_init', $ret);
-
- $a->internalRedirect('profile/' . $a->user['nickname']);
- // NOTREACHED
-}
-
-function manage_content(App $a) {
-
- if (!local_user()) {
- notice(L10n::t('Permission denied.') . EOL);
- return;
- }
-
- if (!empty($_GET['identity'])) {
- $_POST['identity'] = $_GET['identity'];
- manage_post($a);
- return;
- }
-
- $identities = $a->identities;
-
- //getting additinal information for each identity
- foreach ($identities as $key => $id) {
- $thumb = DBA::selectFirst('contact', ['thumb'], ['uid' => $id['uid'] , 'self' => true]);
- if (!DBA::isResult($thumb)) {
- continue;
- }
-
- $identities[$key]['thumb'] = $thumb['thumb'];
-
- $identities[$key]['selected'] = ($id['nickname'] === $a->user['nickname']);
-
- $condition = ["`uid` = ? AND `msg` != '' AND NOT (`type` IN (?, ?)) AND NOT `seen`", $id['uid'], NOTIFY_INTRO, NOTIFY_MAIL];
- $params = ['distinct' => true, 'expression' => 'parent'];
- $notifications = DBA::count('notify', $condition, $params);
-
- $params = ['distinct' => true, 'expression' => 'convid'];
- $notifications += DBA::count('mail', ['uid' => $id['uid'], 'seen' => false], $params);
-
- $notifications += DBA::count('intro', ['blocked' => false, 'ignore' => false, 'uid' => $id['uid']]);
-
- $identities[$key]['notifications'] = $notifications;
- }
-
- $o = Renderer::replaceMacros(Renderer::getMarkupTemplate('manage.tpl'), [
- '$title' => L10n::t('Manage Identities and/or Pages'),
- '$desc' => L10n::t('Toggle between different identities or community/group pages which share your account details or which you have been granted "manage" permissions'),
- '$choose' => L10n::t('Select an identity to manage: '),
- '$identities' => $identities,
- '$submit' => L10n::t('Submit'),
- ]);
-
- return $o;
-
-}
$msearch = json_decode($msearch_json);
- $start = defaults($_GET, 'start', 0);
+ $start = $_GET['start'] ?? 0;
$entries = [];
$paginate = '';
$entry = [
'url' => Contact::magicLink($profile->url),
- 'itemurl' => defaults($contact_details, 'addr', $profile->url),
+ 'itemurl' => $contact_details['addr'] ?? $profile->url,
'name' => $profile->name,
- 'details' => defaults($contact_details, 'location', ''),
- 'tags' => defaults($contact_details, 'keywords', ''),
- 'about' => defaults($contact_details, 'about', ''),
+ 'details' => $contact_details['location'] ?? '',
+ 'tags' => $contact_details['keywords'] ?? '',
+ 'about' => $contact_details['about'] ?? '',
'account_type' => Contact::getAccountType($contact_details),
'thumb' => ProxyUtils::proxifyUrl($profile->photo, false, ProxyUtils::SIZE_THUMB),
'conntxt' => L10n::t('Connect'),
'$prefill' => $prefill,
'$preid' => $preid,
'$subject' => L10n::t('Subject:'),
- '$subjtxt' => defaults($_REQUEST, 'subject', ''),
- '$text' => defaults($_REQUEST, 'body', ''),
+ '$subjtxt' => $_REQUEST['subject'] ?? '',
+ '$text' => $_REQUEST['body'] ?? '',
'$readonly' => '',
'$yourmessage'=> L10n::t('Your message:'),
'$select' => $select,
'$id' => $rr['id'],
'$from_name' => $participants,
'$from_url' => Contact::magicLink($rr['url']),
- '$from_addr' => defaults($contact, 'addr', ''),
+ '$from_addr' => $contact['addr'] ?? '',
'$sparkle' => ' sparkle',
'$from_photo' => ProxyUtils::proxifyUrl($from_photo, false, ProxyUtils::SIZE_THUMB),
'$subject' => $rr['title'],
function msearch_post(App $a)
{
- $search = defaults($_POST, 's', '');
- $perpage = intval(defaults($_POST, 'n', 80));
- $page = intval(defaults($_POST, 'p', 1));
+ $search = $_POST['s'] ?? '';
+ $perpage = intval(($_POST['n'] ?? 0) ?: 80);
+ $page = intval(($_POST['p'] ?? 0) ?: 1);
$startrec = ($page - 1) * $perpage;
$total = 0;
*/
use Friendica\App;
+use Friendica\BaseObject;
use Friendica\Content\Feature;
use Friendica\Content\ForumManager;
use Friendica\Content\Nav;
$group_id = 0;
}
+ /** @var DateTimeFormat $dtFormat */
+ $dtFormat = BaseObject::getClass(DateTimeFormat::class);
+
if ($a->argc > 1) {
for ($x = 1; $x < $a->argc; $x ++) {
- if (is_a_date_arg($a->argv[$x])) {
+ if ($dtFormat->isYearMonth($a->argv[$x])) {
$is_a_date_query = true;
break;
}
// fetch last used network view and redirect if needed
if (!$is_a_date_query) {
- $sel_nets = defaults($_GET, 'nets', '');
+ $sel_nets = $_GET['nets'] ?? '';
$sel_tabs = network_query_get_sel_tab($a);
$sel_groups = network_query_get_sel_group($a);
$last_sel_tabs = PConfig::get(local_user(), 'network.view', 'tab.selected');
$a->page['aside'] .= Group::sidebarWidget('network/0', 'network', 'standard', $group_id);
$a->page['aside'] .= ForumManager::widget(local_user(), $cid);
$a->page['aside'] .= Widget::postedByYear('network', local_user(), false);
- $a->page['aside'] .= Widget::networks('network', defaults($_GET, 'nets', '') );
+ $a->page['aside'] .= Widget::networks('network', $_GET['nets'] ?? '');
$a->page['aside'] .= Widget\SavedSearches::getHTML($a->query_string);
- $a->page['aside'] .= Widget::fileAs('network', defaults($_GET, 'file', '') );
+ $a->page['aside'] .= Widget::fileAs('network', $_GET['file'] ?? '');
}
/**
$o = '';
- $file = defaults($_GET, 'file', '');
+ $file = $_GET['file'] ?? '';
if (!$update && !$rawmode) {
$tabs = network_tabs($a);
$default_permissions = [];
+ /** @var DateTimeFormat $dtFormat */
+ $dtFormat = BaseObject::getClass(DateTimeFormat::class);
+
if ($a->argc > 1) {
for ($x = 1; $x < $a->argc; $x ++) {
- if (is_a_date_arg($a->argv[$x])) {
+ if ($dtFormat->isYearMonth($a->argv[$x])) {
if ($datequery) {
$datequery2 = Strings::escapeHtml($a->argv[$x]);
} else {
$o = '';
- $cid = intval(defaults($_GET, 'cid' , 0));
- $star = intval(defaults($_GET, 'star' , 0));
- $bmark = intval(defaults($_GET, 'bmark', 0));
- $conv = intval(defaults($_GET, 'conv' , 0));
- $order = Strings::escapeTags(defaults($_GET, 'order', 'comment'));
- $nets = defaults($_GET, 'nets' , '');
+ $cid = intval($_GET['cid'] ?? 0);
+ $star = intval($_GET['star'] ?? 0);
+ $bmark = intval($_GET['bmark'] ?? 0);
+ $conv = intval($_GET['conv'] ?? 0);
+ $order = Strings::escapeTags(($_GET['order'] ?? '') ?: 'comment');
+ $nets = $_GET['nets'] ?? '';
$allowedCids = [];
if ($cid) {
$entries[0] = [
'id' => 'network',
'name' => $contact['name'],
- 'itemurl' => defaults($contact, 'addr', $contact['nurl']),
+ 'itemurl' => ($contact['addr'] ?? '') ?: $contact['nurl'],
'thumb' => ProxyUtils::proxifyUrl($contact['thumb'], false, ProxyUtils::SIZE_THUMB),
'details' => $contact['location'],
];
global $pager;
if (PConfig::get(local_user(), 'system', 'infinite_scroll')
- && defaults($_GET, 'mode', '') != 'minimal'
+ && ($_GET['mode'] ?? '') != 'minimal'
) {
$tpl = Renderer::getMarkupTemplate('infinite_scroll_head.tpl');
$htmlhead .= Renderer::replaceMacros($tpl, [
exit;
}
- $keywords = defaults($a->profile, 'pub_keywords', '');
+ $keywords = $a->profile['pub_keywords'] ?? '';
$keywords = str_replace(['#',',',' ',',,'], ['',' ',',',','], $keywords);
$keywords = explode(',', $keywords);
use Friendica\Content\Nav;
use Friendica\Content\Pager;
use Friendica\Core\L10n;
-use Friendica\Core\NotificationsManager;
use Friendica\Core\Protocol;
use Friendica\Core\Renderer;
-use Friendica\Core\Logger;
use Friendica\Core\System;
use Friendica\Database\DBA;
use Friendica\Module\Login;
use Friendica\Model\Contact;
+use Friendica\Model\Notify;
function notifications_post(App $a)
{
return Login::form();
}
- $page = defaults($_REQUEST, 'page', 1);
- $show = defaults($_REQUEST, 'show', 0);
+ $page = ($_REQUEST['page'] ?? 0) ?: 1;
+ $show = ($_REQUEST['show'] ?? '') === 'all';
Nav::setSelected('notifications');
$json = (($a->argc > 1 && $a->argv[$a->argc - 1] === 'json') ? true : false);
- $nm = new NotificationsManager();
+ /** @var Notify $nm */
+ $nm = \Friendica\BaseObject::getClass(Notify::class);
$o = '';
// Get the nav tabs for the notification pages
$all = (($a->argc > 2) && ($a->argv[2] == 'all'));
- $notifs = $nm->introNotifs($all, $startrec, $perpage, $id);
+ $notifs = $nm->getIntroList($all, $startrec, $perpage, $id);
// Get the network notifications
} elseif (($a->argc > 1) && ($a->argv[1] == 'network')) {
$notif_header = L10n::t('Network Notifications');
- $notifs = $nm->networkNotifs($show, $startrec, $perpage);
+ $notifs = $nm->getNetworkList($show, $startrec, $perpage);
// Get the system notifications
} elseif (($a->argc > 1) && ($a->argv[1] == 'system')) {
$notif_header = L10n::t('System Notifications');
- $notifs = $nm->systemNotifs($show, $startrec, $perpage);
+ $notifs = $nm->getSystemList($show, $startrec, $perpage);
// Get the personal notifications
} elseif (($a->argc > 1) && ($a->argv[1] == 'personal')) {
$notif_header = L10n::t('Personal Notifications');
- $notifs = $nm->personalNotifs($show, $startrec, $perpage);
+ $notifs = $nm->getPersonalList($show, $startrec, $perpage);
// Get the home notifications
} elseif (($a->argc > 1) && ($a->argv[1] == 'home')) {
$notif_header = L10n::t('Home Notifications');
- $notifs = $nm->homeNotifs($show, $startrec, $perpage);
+ $notifs = $nm->getHomeList($show, $startrec, $perpage);
// fallback - redirect to main page
} else {
$a->internalRedirect('notifications');
];
// Process the data for template creation
- if (defaults($notifs, 'ident', '') === 'introductions') {
+ if (($notifs['ident'] ?? '') == 'introductions') {
$sugg = Renderer::getMarkupTemplate('suggestions.tpl');
$tpl = Renderer::getMarkupTemplate('intros.tpl');
$openid = new LightOpenID($a->getHostName());
if ($openid->validate()) {
- $authid = $openid->identity;
+ $authid = $openid->data['openid_identity'];
if (empty($authid)) {
Logger::log(L10n::t('OpenID protocol error. No ID returned.') . EOL);
}
// Successful OpenID login - but we can't match it to an existing account.
- // New registration?
-
- if (intval(Config::get('config', 'register_policy')) === \Friendica\Module\Register::CLOSED) {
- notice(L10n::t('Account not found and OpenID registration is not permitted on this site.') . EOL);
- $a->internalRedirect();
- }
-
unset($_SESSION['register']);
- $args = '';
- $attr = $openid->getAttributes();
- if (is_array($attr) && count($attr)) {
- foreach ($attr as $k => $v) {
- if ($k === 'namePerson/friendly') {
- $nick = Strings::escapeTags(trim($v));
- }
- if ($k === 'namePerson/first') {
- $first = Strings::escapeTags(trim($v));
- }
- if ($k === 'namePerson') {
- $args .= '&username=' . urlencode(Strings::escapeTags(trim($v)));
- }
- if ($k === 'contact/email') {
- $args .= '&email=' . urlencode(Strings::escapeTags(trim($v)));
- }
- if ($k === 'media/image/aspect11') {
- $photosq = bin2hex(trim($v));
- }
- if ($k === 'media/image/default') {
- $photo = bin2hex(trim($v));
- }
- }
- }
- if (!empty($nick)) {
- $args .= '&nickname=' . urlencode($nick);
- } elseif (!empty($first)) {
- $args .= '&nickname=' . urlencode($first);
- }
-
- if (!empty($photosq)) {
- $args .= '&photo=' . urlencode($photosq);
- } elseif (!empty($photo)) {
- $args .= '&photo=' . urlencode($photo);
- }
+ Session::set('openid_attributes', $openid->getAttributes());
+ Session::set('openid_identity', $authid);
- $args .= '&openid_url=' . urlencode(Strings::escapeTags(trim($authid)));
+ // Detect the server URL
+ $open_id_obj = new LightOpenID($a->getHostName());
+ $open_id_obj->identity = $authid;
+ Session::set('openid_server', $open_id_obj->discover($open_id_obj->identity));
- $a->internalRedirect('register?' . $args);
+ if (intval(Config::get('config', 'register_policy')) === \Friendica\Module\Register::CLOSED) {
+ notice(L10n::t('Account not found. Please login to your existing account to add the OpenID to it.'));
+ } else {
+ notice(L10n::t('Account not found. Please register a new account or login to your existing account to add the OpenID to it.'));
+ }
- // NOTREACHED
+ $a->internalRedirect('login');
}
}
notice(L10n::t('Login failed.') . EOL);
*/
use Friendica\App;
+use Friendica\BaseObject;
use Friendica\Content\Feature;
use Friendica\Content\Nav;
use Friendica\Content\Pager;
use Friendica\Core\L10n;
use Friendica\Core\Logger;
use Friendica\Core\Renderer;
-use Friendica\Core\System;
use Friendica\Core\Session;
+use Friendica\Core\System;
use Friendica\Database\DBA;
use Friendica\Model\Contact;
-use Friendica\Model\Group;
use Friendica\Model\Item;
use Friendica\Model\Photo;
use Friendica\Model\Profile;
use Friendica\Model\User;
use Friendica\Network\Probe;
use Friendica\Object\Image;
-use Friendica\Protocol\DFRN;
+use Friendica\Protocol\Activity;
+use Friendica\Util\ACLFormatter;
use Friendica\Util\Crypto;
use Friendica\Util\DateTimeFormat;
use Friendica\Util\Map;
$vcard_widget = Renderer::replaceMacros($tpl, [
'$name' => $profile['name'],
'$photo' => $profile['photo'],
- '$addr' => defaults($profile, 'addr', ''),
+ '$addr' => $profile['addr'] ?? '',
'$account_type' => $account_type,
- '$pdesc' => defaults($profile, 'pdesc', ''),
+ '$pdesc' => $profile['pdesc'] ?? '',
]);
$albums = Photo::getAlbums($a->data['user']['uid']);
$albname = !empty($_POST['albname']) ? Strings::escapeTags(trim($_POST['albname'])) : '';
$origaname = !empty($_POST['origaname']) ? Strings::escapeTags(trim($_POST['origaname'])) : '';
- $str_group_allow = !empty($_POST['group_allow']) ? perms2str($_POST['group_allow']) : '';
- $str_contact_allow = !empty($_POST['contact_allow']) ? perms2str($_POST['contact_allow']) : '';
- $str_group_deny = !empty($_POST['group_deny']) ? perms2str($_POST['group_deny']) : '';
- $str_contact_deny = !empty($_POST['contact_deny']) ? perms2str($_POST['contact_deny']) : '';
+ /** @var ACLFormatter $aclFormatter */
+ $aclFormatter = BaseObject::getClass(ACLFormatter::class);
+
+ $str_group_allow = !empty($_POST['group_allow']) ? $aclFormatter->toString($_POST['group_allow']) : '';
+ $str_contact_allow = !empty($_POST['contact_allow']) ? $aclFormatter->toString($_POST['contact_allow']) : '';
+ $str_group_deny = !empty($_POST['group_deny']) ? $aclFormatter->toString($_POST['group_deny']) : '';
+ $str_contact_deny = !empty($_POST['contact_deny']) ? $aclFormatter->toString($_POST['contact_deny']) : '';
$resource_id = $a->argv[3];
$arr['deny_cid'] = $photo['deny_cid'];
$arr['deny_gid'] = $photo['deny_gid'];
$arr['visible'] = 1;
- $arr['verb'] = ACTIVITY_TAG;
+ $arr['verb'] = Activity::TAG;
$arr['gravity'] = GRAVITY_PARENT;
- $arr['object-type'] = ACTIVITY_OBJ_PERSON;
- $arr['target-type'] = ACTIVITY_OBJ_IMAGE;
+ $arr['object-type'] = Activity\ObjectType::PERSON;
+ $arr['target-type'] = Activity\ObjectType::IMAGE;
$arr['tag'] = $tagged[4];
$arr['inform'] = $tagged[2];
$arr['origin'] = 1;
$arr['body'] = L10n::t('%1$s was tagged in %2$s by %3$s', '[url=' . $tagged[1] . ']' . $tagged[0] . '[/url]', '[url=' . System::baseUrl() . '/photos/' . $owner_record['nickname'] . '/image/' . $photo['resource-id'] . ']' . L10n::t('a photo') . '[/url]', '[url=' . $owner_record['url'] . ']' . $owner_record['name'] . '[/url]') ;
$arr['body'] .= "\n\n" . '[url=' . System::baseUrl() . '/photos/' . $owner_record['nickname'] . '/image/' . $photo['resource-id'] . ']' . '[img]' . System::baseUrl() . "/photo/" . $photo['resource-id'] . '-' . $best . '.' . $ext . '[/img][/url]' . "\n" ;
- $arr['object'] = '<object><type>' . ACTIVITY_OBJ_PERSON . '</type><title>' . $tagged[0] . '</title><id>' . $tagged[1] . '/' . $tagged[0] . '</id>';
+ $arr['object'] = '<object><type>' . Activity\ObjectType::PERSON . '</type><title>' . $tagged[0] . '</title><id>' . $tagged[1] . '/' . $tagged[0] . '</id>';
$arr['object'] .= '<link>' . XML::escape('<link rel="alternate" type="text/html" href="' . $tagged[1] . '" />' . "\n");
if ($tagged[3]) {
$arr['object'] .= XML::escape('<link rel="photo" type="' . $photo['type'] . '" href="' . $tagged[3]['photo'] . '" />' . "\n");
}
$arr['object'] .= '</link></object>' . "\n";
- $arr['target'] = '<target><type>' . ACTIVITY_OBJ_IMAGE . '</type><title>' . $photo['desc'] . '</title><id>'
+ $arr['target'] = '<target><type>' . Activity\ObjectType::IMAGE . '</type><title>' . $photo['desc'] . '</title><id>'
. System::baseUrl() . '/photos/' . $owner_record['nickname'] . '/image/' . $photo['resource-id'] . '</id>';
$arr['target'] .= '<link>' . XML::escape('<link rel="alternate" type="text/html" href="' . System::baseUrl() . '/photos/' . $owner_record['nickname'] . '/image/' . $photo['resource-id'] . '" />' . "\n" . '<link rel="preview" type="' . $photo['type'] . '" href="' . System::baseUrl() . "/photo/" . $photo['resource-id'] . '-' . $best . '.' . $ext . '" />') . '</link></target>';
$visible = 0;
}
- $group_allow = defaults($_REQUEST, 'group_allow' , []);
- $contact_allow = defaults($_REQUEST, 'contact_allow', []);
- $group_deny = defaults($_REQUEST, 'group_deny' , []);
- $contact_deny = defaults($_REQUEST, 'contact_deny' , []);
+ $group_allow = $_REQUEST['group_allow'] ?? [];
+ $contact_allow = $_REQUEST['contact_allow'] ?? [];
+ $group_deny = $_REQUEST['group_deny'] ?? [];
+ $contact_deny = $_REQUEST['contact_deny'] ?? [];
- $str_group_allow = perms2str(is_array($group_allow) ? $group_allow : explode(',', $group_allow));
- $str_contact_allow = perms2str(is_array($contact_allow) ? $contact_allow : explode(',', $contact_allow));
- $str_group_deny = perms2str(is_array($group_deny) ? $group_deny : explode(',', $group_deny));
- $str_contact_deny = perms2str(is_array($contact_deny) ? $contact_deny : explode(',', $contact_deny));
+ /** @var ACLFormatter $aclFormatter */
+ $aclFormatter = BaseObject::getClass(ACLFormatter::class);
+
+ $str_group_allow = $aclFormatter->toString(is_array($group_allow) ? $group_allow : explode(',', $group_allow));
+ $str_contact_allow = $aclFormatter->toString(is_array($contact_allow) ? $contact_allow : explode(',', $contact_allow));
+ $str_group_deny = $aclFormatter->toString(is_array($group_deny) ? $group_deny : explode(',', $group_deny));
+ $str_contact_deny = $aclFormatter->toString(is_array($contact_deny) ? $contact_deny : explode(',', $contact_deny));
$ret = ['src' => '', 'filename' => '', 'filesize' => 0, 'type' => ''];
notice(L10n::t('Image exceeds size limit of %s', ini_get('upload_max_filesize')) . EOL);
break;
case UPLOAD_ERR_FORM_SIZE:
- notice(L10n::t('Image exceeds size limit of %s', Strings::formatBytes(defaults($_REQUEST, 'MAX_FILE_SIZE', 0))) . EOL);
+ notice(L10n::t('Image exceeds size limit of %s', Strings::formatBytes($_REQUEST['MAX_FILE_SIZE'] ?? 0)) . EOL);
break;
case UPLOAD_ERR_PARTIAL:
notice(L10n::t('Image upload didn\'t complete, please try again') . EOL);
$pager = new Pager($a->query_string, 20);
/// @TODO I have seen this many times, maybe generalize it script-wide and encapsulate it?
- $order_field = defaults($_GET, 'order', '');
+ $order_field = $_GET['order'] ?? '';
if ($order_field === 'posted') {
$order = 'ASC';
} else {
* By now we hide it if someone wants to.
*/
if ($cmd === 'view' && !Config::get('system', 'no_count', false)) {
- $order_field = defaults($_GET, 'order', '');
+ $order_field = $_GET['order'] ?? '';
if ($order_field === 'posted') {
$order = 'ASC';
$template = $tpl;
$sparkle = '';
- if ((activity_match($item['verb'], ACTIVITY_LIKE) || activity_match($item['verb'], ACTIVITY_DISLIKE)) && ($item['id'] != $item['parent'])) {
+ /** @var Activity $activity */
+ $activity = BaseObject::getClass(Activity::class);
+
+ if (($activity->match($item['verb'], Activity::LIKE) ||
+ $activity->match($item['verb'], Activity::DISLIKE)) &&
+ ($item['id'] != $item['parent'])) {
continue;
}
$system_mode = true;
}
- $format = defaults($_GET, 'format', 'json');
+ $format = ($_GET['format'] ?? '') ?: 'json';
$justme = false;
$global = false;
use Friendica\Core\System;
use Friendica\Database\DBA;
use Friendica\Model\Item;
+use Friendica\Protocol\Activity;
use Friendica\Util\Strings;
use Friendica\Util\XML;
return;
}
- $activity = ACTIVITY_POKE . '#' . urlencode($verbs[$verb][0]);
+ $activity = Activity::POKE . '#' . urlencode($verbs[$verb][0]);
$contact_id = intval($_GET['cid']);
if (!$contact_id) {
$arr['visible'] = 1;
$arr['verb'] = $activity;
$arr['private'] = $private;
- $arr['object-type'] = ACTIVITY_OBJ_PERSON;
+ $arr['object-type'] = Activity\ObjectType::PERSON;
$arr['origin'] = 1;
$arr['body'] = '[url=' . $poster['url'] . ']' . $poster['name'] . '[/url]' . ' ' . L10n::t($verbs[$verb][0]) . ' ' . '[url=' . $target['url'] . ']' . $target['name'] . '[/url]';
- $arr['object'] = '<object><type>' . ACTIVITY_OBJ_PERSON . '</type><title>' . $target['name'] . '</title><id>' . $target['url'] . '</id>';
+ $arr['object'] = '<object><type>' . Activity\ObjectType::PERSON . '</type><title>' . $target['name'] . '</title><id>' . $target['url'] . '</id>';
$arr['object'] .= '<link>' . XML::escape('<link rel="alternate" type="text/html" href="' . $target['url'] . '" />' . "\n");
$arr['object'] .= XML::escape('<link rel="photo" type="image/jpeg" href="' . $target['photo'] . '" />' . "\n");
$contact_id = (($a->argc > 2) ? intval($a->argv[2]) : 0 );
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
- $hub_mode = Strings::escapeTags(trim(defaults($_GET, 'hub_mode', '')));
- $hub_topic = Strings::escapeTags(trim(defaults($_GET, 'hub_topic', '')));
- $hub_challenge = Strings::escapeTags(trim(defaults($_GET, 'hub_challenge', '')));
- $hub_verify = Strings::escapeTags(trim(defaults($_GET, 'hub_verify_token', '')));
+ $hub_mode = Strings::escapeTags(trim($_GET['hub_mode'] ?? ''));
+ $hub_topic = Strings::escapeTags(trim($_GET['hub_topic'] ?? ''));
+ $hub_challenge = Strings::escapeTags(trim($_GET['hub_challenge'] ?? ''));
+ $hub_verify = Strings::escapeTags(trim($_GET['hub_verify_token'] ?? ''));
Logger::log('Subscription from ' . $_SERVER['REMOTE_ADDR'] . ' Mode: ' . $hub_mode . ' Nick: ' . $nick);
Logger::log('Data: ' . print_r($_GET,true), Logger::DATA);
+++ /dev/null
-<?php
-/**
- * @file mod/receive.php
- * @brief Diaspora endpoint
- */
-
-use Friendica\App;
-use Friendica\Core\Config;
-use Friendica\Core\Logger;
-use Friendica\Core\System;
-use Friendica\Database\DBA;
-use Friendica\Protocol\Diaspora;
-use Friendica\Util\Network;
-
-/**
- * @param App $a App
- * @return void
- * @throws ImagickException
- * @throws \Friendica\Network\HTTPException\InternalServerErrorException
- */
-function receive_post(App $a)
-{
- $enabled = intval(Config::get('system', 'diaspora_enabled'));
- if (!$enabled) {
- Logger::log('mod-diaspora: disabled');
- throw new \Friendica\Network\HTTPException\InternalServerErrorException();
- }
-
- if (($a->argc == 2) && ($a->argv[1] === 'public')) {
- $public = true;
- $importer = [];
- } else {
- $public = false;
-
- if ($a->argc != 3 || $a->argv[1] !== 'users') {
- throw new \Friendica\Network\HTTPException\InternalServerErrorException();
- }
- $guid = $a->argv[2];
-
- $importer = DBA::selectFirst('user', [], ['guid' => $guid, 'account_expired' => false, 'account_removed' => false]);
- if (!DBA::isResult($importer)) {
- throw new \Friendica\Network\HTTPException\InternalServerErrorException();
- }
- }
-
- // It is an application/x-www-form-urlencoded
-
- Logger::log('mod-diaspora: receiving post', Logger::DEBUG);
-
- if (empty($_POST['xml'])) {
- $postdata = Network::postdata();
- if ($postdata == '') {
- throw new \Friendica\Network\HTTPException\InternalServerErrorException();
- }
-
- Logger::log('mod-diaspora: message is in the new format', Logger::DEBUG);
- $msg = Diaspora::decodeRaw($importer, $postdata);
- } else {
- $xml = urldecode($_POST['xml']);
-
- Logger::log('mod-diaspora: decode message in the old format', Logger::DEBUG);
- $msg = Diaspora::decode($importer, $xml);
-
- if ($public && !$msg) {
- Logger::log('mod-diaspora: decode message in the new format', Logger::DEBUG);
- $msg = Diaspora::decodeRaw($importer, $xml);
- }
- }
-
- Logger::log('mod-diaspora: decoded', Logger::DEBUG);
-
- Logger::log('mod-diaspora: decoded msg: ' . print_r($msg, true), Logger::DATA);
-
- if (!is_array($msg)) {
- throw new \Friendica\Network\HTTPException\InternalServerErrorException();
- }
-
- Logger::log('mod-diaspora: dispatching', Logger::DEBUG);
-
- $ret = true;
- if ($public) {
- Diaspora::dispatchPublic($msg);
- } else {
- $ret = Diaspora::dispatch($importer, $msg);
- }
-
- if ($ret) {
- throw new \Friendica\Network\HTTPException\OKException();
- } else {
- throw new \Friendica\Network\HTTPException\InternalServerErrorException();
- }
-}
function redir_init(App $a) {
- $url = defaults($_GET, 'url', '');
+ $url = $_GET['url'] ?? '';
$quiet = !empty($_GET['quiet']) ? '&quiet=1' : '';
if ($a->argc > 1 && intval($a->argv[1])) {
if (!Session::isAuthenticated() // Visitors (not logged in or not remotes) can't authenticate.
|| (!empty($a->contact['id']) && $a->contact['id'] == $cid)) // Local user is already authenticated.
{
- $a->redirect(defaults($url, $contact_url));
+ $a->redirect($url ?: $contact_url);
}
if ($contact['uid'] == 0 && local_user()) {
if (!empty($a->contact['id']) && $a->contact['id'] == $cid) {
// Local user is already authenticated.
- $target_url = defaults($url, $contact_url);
+ $target_url = $url ?: $contact_url;
Logger::log($contact['name'] . " is already authenticated. Redirecting to " . $target_url, Logger::DEBUG);
$a->redirect($target_url);
}
// contact.
if (($host == $remotehost) && (Session::getRemoteContactID(Session::get('visitor_visiting')) == Session::get('visitor_id'))) {
// Remote user is already authenticated.
- $target_url = defaults($url, $contact_url);
+ $target_url = $url ?: $contact_url;
Logger::log($contact['name'] . " is already authenticated. Redirecting to " . $target_url, Logger::DEBUG);
$a->redirect($target_url);
}
. '&dfrn_version=' . DFRN_PROTOCOL_VERSION . '&type=profile&sec=' . $sec . $dest . $quiet);
}
- $url = defaults($url, $contact_url);
+ $url = $url ?: $contact_url;
}
// If we don't have a connected contact, redirect with
}
} else {
$contact_url = $contact['url'];
- $target_url = defaults($url, $contact_url);
+ $target_url = $url ?: $contact_url;
}
$basepath = Contact::getBasepath($contact_url);
$user,
Config::get('config', 'sitename'),
$a->getBaseUrl(),
- defaults($register, 'password', 'Sent in a previous email')
+ ($register['password'] ?? '') ?: 'Sent in a previous email'
);
L10n::popLang();
/**
* @file mod/salmon.php
*/
+
use Friendica\App;
use Friendica\Core\Logger;
use Friendica\Core\PConfig;
use Friendica\Core\Protocol;
-use Friendica\Core\System;
use Friendica\Database\DBA;
use Friendica\Model\Contact;
+use Friendica\Protocol\ActivityNamespace;
use Friendica\Protocol\OStatus;
use Friendica\Protocol\Salmon;
use Friendica\Util\Crypto;
-use Friendica\Util\Strings;
use Friendica\Util\Network;
+use Friendica\Util\Strings;
function salmon_post(App $a, $xml = '') {
// parse the xml
- $dom = simplexml_load_string($xml,'SimpleXMLElement',0,NAMESPACE_SALMON_ME);
+ $dom = simplexml_load_string($xml,'SimpleXMLElement',0, ActivityNamespace::SALMON_ME);
$base = null;
use Friendica\App;
use Friendica\BaseModule;
+use Friendica\BaseObject;
use Friendica\Content\Feature;
use Friendica\Content\Nav;
use Friendica\Core\ACL;
use Friendica\Model\User;
use Friendica\Module\Login;
use Friendica\Protocol\Email;
+use Friendica\Util\ACLFormatter;
use Friendica\Util\Network;
use Friendica\Util\Strings;
use Friendica\Util\Temporal;
$theme = Strings::sanitizeFilePathItem($theme);
$a = \get_app();
- $base_theme = defaults($a->theme_info, 'extends');
+ $base_theme = $a->theme_info['extends'] ?? '';
if (file_exists("view/theme/$theme/config.php")) {
return "view/theme/$theme/config.php";
if (($a->argc > 2) && ($a->argv[1] === 'oauth') && ($a->argv[2] === 'edit'||($a->argv[2] === 'add')) && !empty($_POST['submit'])) {
BaseModule::checkFormSecurityTokenRedirectOnError('/settings/oauth', 'settings_oauth');
- $name = defaults($_POST, 'name' , '');
- $key = defaults($_POST, 'key' , '');
- $secret = defaults($_POST, 'secret' , '');
- $redirect = defaults($_POST, 'redirect', '');
- $icon = defaults($_POST, 'icon' , '');
+ $name = $_POST['name'] ?? '';
+ $key = $_POST['key'] ?? '';
+ $secret = $_POST['secret'] ?? '';
+ $redirect = $_POST['redirect'] ?? '';
+ $icon = $_POST['icon'] ?? '';
if ($name == "" || $key == "" || $secret == "") {
notice(L10n::t("Missing some important data!"));
PConfig::set(local_user(), 'ostatus', 'default_group', $_POST['group-selection']);
PConfig::set(local_user(), 'ostatus', 'legacy_contact', $_POST['legacy_contact']);
} elseif (!empty($_POST['imap-submit'])) {
-
- $mail_server = defaults($_POST, 'mail_server', '');
- $mail_port = defaults($_POST, 'mail_port', '');
- $mail_ssl = (!empty($_POST['mail_ssl']) ? strtolower(trim($_POST['mail_ssl'])) : '');
- $mail_user = defaults($_POST, 'mail_user', '');
- $mail_pass = (!empty($_POST['mail_pass']) ? trim($_POST['mail_pass']) : '');
- $mail_action = (!empty($_POST['mail_action']) ? trim($_POST['mail_action']) : '');
- $mail_movetofolder = (!empty($_POST['mail_movetofolder']) ? trim($_POST['mail_movetofolder']) : '');
- $mail_replyto = defaults($_POST, 'mail_replyto', '');
- $mail_pubmail = defaults($_POST, 'mail_pubmail', '');
-
-
- $mail_disabled = ((function_exists('imap_open') && (!Config::get('system', 'imap_disabled'))) ? 0 : 1);
- if (Config::get('system', 'dfrn_only')) {
- $mail_disabled = 1;
- }
-
- if (!$mail_disabled) {
+ $mail_server = $_POST['mail_server'] ?? '';
+ $mail_port = $_POST['mail_port'] ?? '';
+ $mail_ssl = strtolower(trim($_POST['mail_ssl'] ?? ''));
+ $mail_user = $_POST['mail_user'] ?? '';
+ $mail_pass = trim($_POST['mail_pass'] ?? '');
+ $mail_action = trim($_POST['mail_action'] ?? '');
+ $mail_movetofolder = trim($_POST['mail_movetofolder'] ?? '');
+ $mail_replyto = $_POST['mail_replyto'] ?? '';
+ $mail_pubmail = $_POST['mail_pubmail'] ?? '';
+
+ if (
+ !Config::get('system', 'dfrn_only')
+ && function_exists('imap_open')
+ && !Config::get('system', 'imap_disabled')
+ ) {
$failed = false;
$r = q("SELECT * FROM `mailacct` WHERE `uid` = %d LIMIT 1",
intval(local_user())
$language = (!empty($_POST['language']) ? Strings::escapeTags(trim($_POST['language'])) : '');
$defloc = (!empty($_POST['defloc']) ? Strings::escapeTags(trim($_POST['defloc'])) : '');
- $openid = (!empty($_POST['openid_url']) ? Strings::escapeTags(trim($_POST['openid_url'])) : '');
$maxreq = (!empty($_POST['maxreq']) ? intval($_POST['maxreq']) : 0);
$expire = (!empty($_POST['expire']) ? intval($_POST['expire']) : 0);
$def_gid = (!empty($_POST['group-selection']) ? intval($_POST['group-selection']) : 0);
$expire_photos = (!empty($_POST['expire_photos'])? intval($_POST['expire_photos']) : 0);
$expire_network_only = (!empty($_POST['expire_network_only'])? intval($_POST['expire_network_only']) : 0);
+ $delete_openid = ((!empty($_POST['delete_openid']) && (intval($_POST['delete_openid']) == 1)) ? 1: 0);
+
$allow_location = ((!empty($_POST['allow_location']) && (intval($_POST['allow_location']) == 1)) ? 1: 0);
$publish = ((!empty($_POST['profile_in_directory']) && (intval($_POST['profile_in_directory']) == 1)) ? 1: 0);
$net_publish = ((!empty($_POST['profile_in_netdirectory']) && (intval($_POST['profile_in_netdirectory']) == 1)) ? 1: 0);
date_default_timezone_set($timezone);
}
- $str_group_allow = !empty($_POST['group_allow']) ? perms2str($_POST['group_allow']) : '';
- $str_contact_allow = !empty($_POST['contact_allow']) ? perms2str($_POST['contact_allow']) : '';
- $str_group_deny = !empty($_POST['group_deny']) ? perms2str($_POST['group_deny']) : '';
- $str_contact_deny = !empty($_POST['contact_deny']) ? perms2str($_POST['contact_deny']) : '';
-
- $openidserver = $a->user['openidserver'];
- //$openid = Strings::normaliseOpenID($openid);
-
- // If openid has changed or if there's an openid but no openidserver, try and discover it.
- if ($openid != $a->user['openid'] || (strlen($openid) && (!strlen($openidserver)))) {
- if (Network::isUrlValid($openid)) {
- Logger::log('updating openidserver');
- $open_id_obj = new LightOpenID($a->getHostName());
- $open_id_obj->identity = $openid;
- $openidserver = $open_id_obj->discover($open_id_obj->identity);
- } else {
- $openidserver = '';
- }
- }
+ /** @var ACLFormatter $aclFormatter */
+ $aclFormatter = BaseObject::getClass(ACLFormatter::class);
+
+ $str_group_allow = !empty($_POST['group_allow']) ? $aclFormatter->toString($_POST['group_allow']) : '';
+ $str_contact_allow = !empty($_POST['contact_allow']) ? $aclFormatter->toString($_POST['contact_allow']) : '';
+ $str_group_deny = !empty($_POST['group_deny']) ? $aclFormatter->toString($_POST['group_deny']) : '';
+ $str_contact_deny = !empty($_POST['contact_deny']) ? $aclFormatter->toString($_POST['contact_deny']) : '';
PConfig::set(local_user(), 'expire', 'items', $expire_items);
PConfig::set(local_user(), 'expire', 'notes', $expire_notes);
}
}
+ $fields = ['username' => $username, 'email' => $email, 'timezone' => $timezone,
+ 'allow_cid' => $str_contact_allow, 'allow_gid' => $str_group_allow, 'deny_cid' => $str_contact_deny, 'deny_gid' => $str_group_deny,
+ 'notify-flags' => $notify, 'page-flags' => $notify, 'account-type' => $account_type, 'default-location' => $defloc,
+ 'allow_location' => $allow_location, 'maxreq' => $maxreq, 'expire' => $expire, 'def_gid' => $def_gid, 'blockwall' => $blockwall,
+ 'hidewall' => $hide_wall, 'blocktags' => $blocktags, 'unkmail' => $unkmail, 'cntunkmail' => $cntunkmail, 'language' => $language];
- $r = q("UPDATE `user` SET `username` = '%s', `email` = '%s',
- `openid` = '%s', `timezone` = '%s',
- `allow_cid` = '%s', `allow_gid` = '%s', `deny_cid` = '%s', `deny_gid` = '%s',
- `notify-flags` = %d, `page-flags` = %d, `account-type` = %d, `default-location` = '%s',
- `allow_location` = %d, `maxreq` = %d, `expire` = %d, `openidserver` = '%s',
- `def_gid` = %d, `blockwall` = %d, `hidewall` = %d, `blocktags` = %d,
- `unkmail` = %d, `cntunkmail` = %d, `language` = '%s'
- WHERE `uid` = %d",
- DBA::escape($username),
- DBA::escape($email),
- DBA::escape($openid),
- DBA::escape($timezone),
- DBA::escape($str_contact_allow),
- DBA::escape($str_group_allow),
- DBA::escape($str_contact_deny),
- DBA::escape($str_group_deny),
- intval($notify),
- intval($page_flags),
- intval($account_type),
- DBA::escape($defloc),
- intval($allow_location),
- intval($maxreq),
- intval($expire),
- DBA::escape($openidserver),
- intval($def_gid),
- intval($blockwall),
- intval($hidewall),
- intval($blocktags),
- intval($unkmail),
- intval($cntunkmail),
- DBA::escape($language),
- intval(local_user())
- );
- if (DBA::isResult($r)) {
+ if ($delete_openid) {
+ $fields['openid'] = '';
+ $fields['openidserver'] = '';
+ }
+
+ if (DBA::update('user', $fields, ['uid' => local_user()])) {
info(L10n::t('Settings updated.') . EOL);
}
if ($noid) {
$openid_field = false;
} else {
- $openid_field = ['openid_url', L10n::t('OpenID:'), $openid, L10n::t("\x28Optional\x29 Allow this OpenID to login to this account."), "", "", "url"];
+ $openid_field = ['openid_url', L10n::t('OpenID:'), $openid, L10n::t("\x28Optional\x29 Allow this OpenID to login to this account."), "", "readonly", "url"];
}
$opt_tpl = Renderer::getMarkupTemplate("field_yesno.tpl");
'$password4'=> ['mpassword', L10n::t('Password:'), '', L10n::t('Your current password to confirm the changes')],
'$oid_enable' => (!Config::get('system', 'no_openid')),
'$openid' => $openid_field,
+ '$delete_openid' => ['delete_openid', L10n::t('Delete OpenID URL'), false, ''],
'$h_basic' => L10n::t('Basic Settings'),
'$username' => ['username', L10n::t('Full Name:'), $username, ''],
/**
* @file mod/subthread.php
*/
+
use Friendica\App;
use Friendica\Core\Hook;
use Friendica\Core\L10n;
use Friendica\Core\Logger;
+use Friendica\Core\Session;
use Friendica\Core\System;
use Friendica\Database\DBA;
use Friendica\Model\Item;
+use Friendica\Protocol\Activity;
use Friendica\Util\Security;
use Friendica\Util\Strings;
use Friendica\Util\XML;
return;
}
- $activity = ACTIVITY_FOLLOW;
+ $activity = Activity::FOLLOW;
$item_id = (($a->argc > 1) ? Strings::escapeTags(trim($a->argv[1])) : 0);
$uri = Item::newURI($owner_uid);
$post_type = (($item['resource-id']) ? L10n::t('photo') : L10n::t('status'));
- $objtype = (($item['resource-id']) ? ACTIVITY_OBJ_IMAGE : ACTIVITY_OBJ_NOTE );
+ $objtype = (($item['resource-id']) ? Activity\ObjectType::IMAGE : Activity\ObjectType::NOTE );
$link = XML::escape('<link rel="alternate" type="text/html" href="' . System::baseUrl() . '/display/' . $item['guid'] . '" />' . "\n");
$body = $item['body'];
/**
* @file mod/tagger.php
*/
+
use Friendica\App;
use Friendica\Core\Hook;
use Friendica\Core\L10n;
use Friendica\Core\Logger;
-use Friendica\Core\System;
use Friendica\Core\Session;
+use Friendica\Core\System;
use Friendica\Core\Worker;
use Friendica\Database\DBA;
use Friendica\Model\Item;
+use Friendica\Protocol\Activity;
use Friendica\Util\Strings;
use Friendica\Util\XML;
use Friendica\Worker\Delivery;
$uri = Item::newURI($owner_uid);
$xterm = XML::escape($term);
$post_type = (($item['resource-id']) ? L10n::t('photo') : L10n::t('status'));
- $targettype = (($item['resource-id']) ? ACTIVITY_OBJ_IMAGE : ACTIVITY_OBJ_NOTE );
+ $targettype = (($item['resource-id']) ? Activity\ObjectType::IMAGE : Activity\ObjectType::NOTE );
$href = System::baseUrl() . '/display/' . $item['guid'];
$link = XML::escape('<link rel="alternate" type="text/html" href="'. $href . '" />' . "\n");
EOT;
$tagid = System::baseUrl() . '/search?tag=' . $xterm;
- $objtype = ACTIVITY_OBJ_TAGTERM;
+ $objtype = Activity\ObjectType::TAGTERM;
$obj = <<< EOT
<object>
$plink = '[url=' . $item['plink'] . ']' . $post_type . '[/url]';
$arr['body'] = sprintf( $bodyverb, $ulink, $alink, $plink, $termlink );
- $arr['verb'] = ACTIVITY_TAG;
+ $arr['verb'] = Activity::TAG;
$arr['target-type'] = $targettype;
$arr['target'] = $target;
$arr['object-type'] = $objtype;
}
$tags = [];
- foreach (defaults($_POST, 'tag', []) as $tag) {
+ foreach ($_POST['tag'] ?? [] as $tag) {
$tags[] = hex2bin(Strings::escapeTags(trim($tag)));
}
- $item_id = defaults($_POST,'item', 0);
+ $item_id = $_POST['item'] ?? 0;
update_tags($item_id, $tags);
info(L10n::t('Tag(s) removed') . EOL);
}
$uid = local_user();
- $url = Strings::escapeTags(trim(defaults($_REQUEST, 'url', '')));
+ $url = Strings::escapeTags(trim($_REQUEST['url'] ?? ''));
$condition = ["`uid` = ? AND (`rel` = ? OR `rel` = ?) AND (`nurl` = ? OR `alias` = ? OR `alias` = ?)",
$uid, Contact::SHARING, Contact::FRIEND, Strings::normaliseLink($url),
$vcard_widget = Renderer::replaceMacros($tpl, [
'$name' => $profile['name'],
'$photo' => $profile['photo'],
- '$addr' => defaults($profile, 'addr', ''),
+ '$addr' => $profile['addr'] ?? '',
'$account_type' => $account_type,
- '$pdesc' => defaults($profile, 'pdesc', ''),
+ '$pdesc' => $profile['pdesc'] ?? '',
]);
// If not there, create 'aside' empty
'$subject' => L10n::t('Subject:'),
'$recipname' => $user['username'],
'$nickname' => $user['nickname'],
- '$subjtxt' => defaults($_REQUEST, 'subject', ''),
- '$text' => defaults($_REQUEST, 'body', ''),
+ '$subjtxt' => $_REQUEST['subject'] ?? '',
+ '$text' => $_REQUEST['body'] ?? '',
'$readonly' => '',
'$yourmessage'=> L10n::t('Your message:'),
'$parent' => '',
# Got the following 'Drupal Clean URL'after Mike suggested trying
# something along those lines, from http://drupal.org/node/1414950
url.rewrite-if-not-file = (
- "^\/([^\?]*)\?(.*)$" => "/index.php?q=$1&$2",
- "^\/(.*)$" => "/index.php?q=$1"
+ "^\/([^\?]*)\?(.*)$" => "/index.php?pagename=$1&$2",
+ "^\/(.*)$" => "/index.php?pagename=$1"
)
}
else $HTTP["host"] !~ "(friendica.example.com|wordpress.example.com)" {
/**
* Returns the value of a argv key
- * @todo there are a lot of $a->argv usages in combination with defaults() which can be replaced with this method
+ * @todo there are a lot of $a->argv usages in combination with ?? which can be replaced with this method
*
* @param int $position the position of the argument
* @param mixed $default the default value if not found
/* Relative script path to the web server root
* Not all of those $_SERVER properties can be present, so we do by inverse priority order
*/
- $relative_script_path = '';
- $relative_script_path = defaults($this->server, 'REDIRECT_URL', $relative_script_path);
- $relative_script_path = defaults($this->server, 'REDIRECT_URI', $relative_script_path);
- $relative_script_path = defaults($this->server, 'REDIRECT_SCRIPT_URL', $relative_script_path);
- $relative_script_path = defaults($this->server, 'SCRIPT_URL', $relative_script_path);
- $relative_script_path = defaults($this->server, 'REQUEST_URI', $relative_script_path);
+ $relative_script_path =
+ ($this->server['REDIRECT_URL'] ?? '') ?:
+ ($this->server['REDIRECT_URI'] ?? '') ?:
+ ($this->server['REDIRECT_SCRIPT_URL'] ?? '') ?:
+ ($this->server['SCRIPT_URL'] ?? '') ?:
+ $this->server['REQUEST_URI'] ?? '';
/* $relative_script_path gives /relative/path/to/friendica/module/parameter
* QUERY_STRING gives pagename=module/parameter
use Friendica\Core;
use Friendica\LegacyModule;
use Friendica\Module\Home;
-use Friendica\Module\PageNotFound;
+use Friendica\Module\HTTPException\MethodNotAllowed;
+use Friendica\Module\HTTPException\PageNotFound;
+use Friendica\Network\HTTPException\MethodNotAllowedException;
+use Friendica\Network\HTTPException\NotFoundException;
use Psr\Log\LoggerInterface;
/**
{
$printNotAllowedAddon = false;
+ $module_class = null;
/**
* ROUTING
*
* From the request URL, routing consists of obtaining the name of a BaseModule-extending class of which the
* post() and/or content() static methods can be respectively called to produce a data change or an output.
**/
- $module_class = $router->getModuleClass($args->getCommand());
-
- // Then we try addon-provided modules that we wrap in the LegacyModule class
- if (!$module_class && Core\Addon::isEnabled($this->module) && file_exists("addon/{$this->module}/{$this->module}.php")) {
- //Check if module is an app and if public access to apps is allowed or not
- $privateapps = $config->get('config', 'private_addons', false);
- if ((!local_user()) && Core\Hook::isAddonApp($this->module) && $privateapps) {
- $printNotAllowedAddon = true;
- } else {
- include_once "addon/{$this->module}/{$this->module}.php";
- if (function_exists($this->module . '_module')) {
- LegacyModule::setModuleFile("addon/{$this->module}/{$this->module}.php");
- $module_class = LegacyModule::class;
+ try {
+ $module_class = $router->getModuleClass($args->getCommand());
+ } catch (MethodNotAllowedException $e) {
+ $module_class = MethodNotAllowed::class;
+ } catch (NotFoundException $e) {
+ // Then we try addon-provided modules that we wrap in the LegacyModule class
+ if (Core\Addon::isEnabled($this->module) && file_exists("addon/{$this->module}/{$this->module}.php")) {
+ //Check if module is an app and if public access to apps is allowed or not
+ $privateapps = $config->get('config', 'private_addons', false);
+ if ((!local_user()) && Core\Hook::isAddonApp($this->module) && $privateapps) {
+ $printNotAllowedAddon = true;
+ } else {
+ include_once "addon/{$this->module}/{$this->module}.php";
+ if (function_exists($this->module . '_module')) {
+ LegacyModule::setModuleFile("addon/{$this->module}/{$this->module}.php");
+ $module_class = LegacyModule::class;
+ }
}
}
- }
- /* Finally, we look for a 'standard' program module in the 'mod' directory
- * We emulate a Module class through the LegacyModule class
- */
- if (!$module_class && file_exists("mod/{$this->module}.php")) {
- LegacyModule::setModuleFile("mod/{$this->module}.php");
- $module_class = LegacyModule::class;
- }
+ /* Finally, we look for a 'standard' program module in the 'mod' directory
+ * We emulate a Module class through the LegacyModule class
+ */
+ if (!$module_class && file_exists("mod/{$this->module}.php")) {
+ LegacyModule::setModuleFile("mod/{$this->module}.php");
+ $module_class = LegacyModule::class;
+ }
- $module_class = !isset($module_class) ? PageNotFound::class : $module_class;
+ $module_class = $module_class ?: PageNotFound::class;
+ }
return new Module($this->module, $module_class, $this->isBackend, $printNotAllowedAddon);
}
use FastRoute\RouteCollector;
use FastRoute\RouteParser\Std;
use Friendica\Core\Hook;
-use Friendica\Network\HTTPException\InternalServerErrorException;
+use Friendica\Core\L10n;
+use Friendica\Network\HTTPException;
/**
* Wrapper for FastRoute\Router
*
* @return self The router instance with the loaded routes
*
- * @throws InternalServerErrorException In case of invalid configs
+ * @throws HTTPException\InternalServerErrorException In case of invalid configs
*/
public function addRoutes(array $routes)
{
} elseif ($this->isRoute($config)) {
$routeCollector->addRoute($config[1], $route, $config[0]);
} else {
- throw new InternalServerErrorException("Wrong route config for route '" . print_r($route, true) . "'");
+ throw new HTTPException\InternalServerErrorException("Wrong route config for route '" . print_r($route, true) . "'");
}
}
} elseif ($this->isRoute($config)) {
$routeCollector->addRoute($config[1], $route, $config[0]);
}else {
- throw new InternalServerErrorException("Wrong route config for route '" . print_r($route, true) . "'");
+ throw new HTTPException\InternalServerErrorException("Wrong route config for route '" . print_r($route, true) . "'");
}
}
});
*
* @param string $cmd The path component of the request URL without the query string
*
- * @return string|null A Friendica\BaseModule-extending class name if a route rule matched
+ * @return string A Friendica\BaseModule-extending class name if a route rule matched
+ *
+ * @throws HTTPException\InternalServerErrorException
+ * @throws HTTPException\MethodNotAllowedException If a rule matched but the method didn't
+ * @throws HTTPException\NotFoundException If no rule matched
*/
public function getModuleClass($cmd)
{
$routeInfo = $dispatcher->dispatch($this->httpMethod, $cmd);
if ($routeInfo[0] === Dispatcher::FOUND) {
$moduleClass = $routeInfo[1];
+ } elseif ($routeInfo[0] === Dispatcher::METHOD_NOT_ALLOWED) {
+ throw new HTTPException\MethodNotAllowedException(L10n::t('Method not allowed for this module. Allowed method(s): %s', implode(', ', $routeInfo[1])));
+ } else {
+ throw new HTTPException\NotFoundException(L10n::t('Page not found.'));
}
return $moduleClass;
*
* @throws InternalServerErrorException
*/
- protected static function getClass(string $name)
+ public static function getClass(string $name)
{
if (empty(self::$dice)) {
throw new InternalServerErrorException('DICE isn\'t initialized.');
}
- if (class_exists($name) || interface_exists($name )) {
+ if (class_exists($name) || interface_exists($name)) {
return self::$dice->create($name);
} else {
throw new InternalServerErrorException('Class \'' . $name . '\' isn\'t valid.');
--- /dev/null
+<?php
+
+namespace Friendica\Content;
+
+use Friendica\Model\FileTag;
+
+/**
+ * A content helper class for displaying items
+ */
+final class Item
+{
+ /**
+ * Return array with details for categories and folders for an item
+ *
+ * @param array $item
+ * @return [array, array]
+ *
+ * [
+ * [ // categories array
+ * {
+ * 'name': 'category name',
+ * 'removeurl': 'url to remove this category',
+ * 'first': 'is the first in this array? true/false',
+ * 'last': 'is the last in this array? true/false',
+ * } ,
+ * ....
+ * ],
+ * [ //folders array
+ * {
+ * 'name': 'folder name',
+ * 'removeurl': 'url to remove this folder',
+ * 'first': 'is the first in this array? true/false',
+ * 'last': 'is the last in this array? true/false',
+ * } ,
+ * ....
+ * ]
+ * ]
+ */
+ public function determineCategoriesTerms(array $item)
+ {
+ $categories = [];
+ $folders = [];
+ $first = true;
+
+ foreach (FileTag::fileToArray($item['file'] ?? '', 'category') as $savedFolderName) {
+ $categories[] = [
+ 'name' => $savedFolderName,
+ 'url' => "#",
+ 'removeurl' => ((local_user() == $item['uid']) ? 'filerm/' . $item['id'] . '?f=&cat=' . rawurlencode($savedFolderName) : ""),
+ 'first' => $first,
+ 'last' => false
+ ];
+ $first = false;
+ }
+
+ if (count($categories)) {
+ $categories[count($categories) - 1]['last'] = true;
+ }
+
+ if (local_user() == $item['uid']) {
+ foreach (FileTag::fileToArray($item['file'] ?? '') as $savedFolderName) {
+ $folders[] = [
+ 'name' => $savedFolderName,
+ 'url' => "#",
+ 'removeurl' => ((local_user() == $item['uid']) ? 'filerm/' . $item['id'] . '?f=&term=' . rawurlencode($savedFolderName) : ""),
+ 'first' => $first,
+ 'last' => false
+ ];
+ $first = false;
+ }
+ }
+
+ if (count($folders)) {
+ $folders[count($folders) - 1]['last'] = true;
+ }
+
+ return [$categories, $folders];
+ }
+}
'directory' => null,
'settings' => null,
'contacts' => null,
- 'manage' => null,
+ 'delegation'=> null,
'events' => null,
'register' => null
];
$nav['messages']['new'] = ['message/new', L10n::t('New Message'), '', L10n::t('New Message')];
if (is_array($a->identities) && count($a->identities) > 1) {
- $nav['manage'] = ['manage', L10n::t('Manage'), '', L10n::t('Manage other pages')];
+ $nav['delegation'] = ['delegation', L10n::t('Delegation'), '', L10n::t('Manage other pages')];
}
- $nav['delegations'] = ['settings/delegation', L10n::t('Delegations'), '', L10n::t('Delegate Page Management')];
-
$nav['settings'] = ['settings', L10n::t('Settings'), '', L10n::t('Account settings')];
if (Feature::isEnabled(local_user(), 'multi_profiles')) {
{
$this->setQueryString($queryString);
$this->setItemsPerPage($itemsPerPage);
- $this->setPage(defaults($_GET, 'page', 1));
+ $this->setPage(($_GET['page'] ?? 0) ?: 1);
}
/**
use Friendica\Model\Photo;
use Friendica\Network\Probe;
use Friendica\Object\Image;
+use Friendica\Protocol\Activity;
use Friendica\Util\Map;
use Friendica\Util\Network;
use Friendica\Util\ParseUrl;
*
* @param string $body Message body
* @return array
- * 'type' -> Message type ("link", "video", "photo")
+ * 'type' -> Message type ('link', 'video', 'photo')
* 'text' -> Text before the shared message
* 'after' -> Text after the shared message
* 'image' -> Preview image of the message
if (preg_match_all("(\[class=(.*?)\](.*?)\[\/class\])ism", $body, $attached, PREG_SET_ORDER)) {
foreach ($attached as $data) {
- if (!in_array($data[1], ["type-link", "type-video", "type-photo"])) {
+ if (!in_array($data[1], ['type-link', 'type-video', 'type-photo'])) {
continue;
}
- $post["type"] = substr($data[1], 5);
+ $post['type'] = substr($data[1], 5);
$pos = strpos($body, $data[0]);
if ($pos > 0) {
- $post["text"] = trim(substr($body, 0, $pos));
- $post["after"] = trim(substr($body, $pos + strlen($data[0])));
+ $post['text'] = trim(substr($body, 0, $pos));
+ $post['after'] = trim(substr($body, $pos + strlen($data[0])));
} else {
- $post["text"] = trim(str_replace($data[0], "", $body));
- $post["after"] = '';
+ $post['text'] = trim(str_replace($data[0], '', $body));
+ $post['after'] = '';
}
$attacheddata = $data[2];
if ($picturedata) {
if (($picturedata[0] >= 500) && ($picturedata[0] >= $picturedata[1])) {
- $post["image"] = $matches[1];
+ $post['image'] = $matches[1];
} else {
- $post["preview"] = $matches[1];
+ $post['preview'] = $matches[1];
}
}
}
if (preg_match("/\[bookmark\=(.*?)\](.*?)\[\/bookmark\]/ism", $attacheddata, $matches)) {
- $post["url"] = $matches[1];
- $post["title"] = $matches[2];
+ $post['url'] = $matches[1];
+ $post['title'] = $matches[2];
}
- if (!empty($post["url"]) && (in_array($post["type"], ["link", "video"]))
+ if (!empty($post['url']) && (in_array($post['type'], ['link', 'video']))
&& preg_match("/\[url\=(.*?)\](.*?)\[\/url\]/ism", $attacheddata, $matches)) {
- $post["url"] = $matches[1];
+ $post['url'] = $matches[1];
}
// Search for description
if (preg_match("/\[quote\](.*?)\[\/quote\]/ism", $attacheddata, $matches)) {
- $post["description"] = $matches[1];
+ $post['description'] = $matches[1];
}
}
}
*
* @param string $body Message body
* @return array
- * 'type' -> Message type ("link", "video", "photo")
+ * 'type' -> Message type ('link', 'video', 'photo')
* 'text' -> Text before the shared message
* 'after' -> Text after the shared message
* 'image' -> Preview image of the message
$attributes = $match[2];
- $data["text"] = trim($match[1]);
+ $data['text'] = trim($match[1]);
- $type = "";
+ $type = '';
preg_match("/type='(.*?)'/ism", $attributes, $matches);
if (!empty($matches[1])) {
$type = strtolower($matches[1]);
$type = strtolower($matches[1]);
}
- if ($type == "") {
+ if ($type == '') {
return [];
}
- if (!in_array($type, ["link", "audio", "photo", "video"])) {
+ if (!in_array($type, ['link', 'audio', 'photo', 'video'])) {
return [];
}
- if ($type != "") {
- $data["type"] = $type;
+ if ($type != '') {
+ $data['type'] = $type;
}
- $url = "";
+ $url = '';
preg_match("/url='(.*?)'/ism", $attributes, $matches);
if (!empty($matches[1])) {
$url = $matches[1];
$url = $matches[1];
}
- if ($url != "") {
- $data["url"] = html_entity_decode($url, ENT_QUOTES, 'UTF-8');
+ if ($url != '') {
+ $data['url'] = html_entity_decode($url, ENT_QUOTES, 'UTF-8');
}
- $title = "";
+ $title = '';
preg_match("/title='(.*?)'/ism", $attributes, $matches);
if (!empty($matches[1])) {
$title = $matches[1];
$title = $matches[1];
}
- if ($title != "") {
+ if ($title != '') {
$title = self::convert(html_entity_decode($title, ENT_QUOTES, 'UTF-8'), false, true);
$title = html_entity_decode($title, ENT_QUOTES, 'UTF-8');
- $title = str_replace(["[", "]"], ["[", "]"], $title);
- $data["title"] = $title;
+ $title = str_replace(['[', ']'], ['[', ']'], $title);
+ $data['title'] = $title;
}
- $image = "";
+ $image = '';
preg_match("/image='(.*?)'/ism", $attributes, $matches);
if (!empty($matches[1])) {
$image = $matches[1];
$image = $matches[1];
}
- if ($image != "") {
- $data["image"] = html_entity_decode($image, ENT_QUOTES, 'UTF-8');
+ if ($image != '') {
+ $data['image'] = html_entity_decode($image, ENT_QUOTES, 'UTF-8');
}
- $preview = "";
+ $preview = '';
preg_match("/preview='(.*?)'/ism", $attributes, $matches);
if (!empty($matches[1])) {
$preview = $matches[1];
$preview = $matches[1];
}
- if ($preview != "") {
- $data["preview"] = html_entity_decode($preview, ENT_QUOTES, 'UTF-8');
+ if ($preview != '') {
+ $data['preview'] = html_entity_decode($preview, ENT_QUOTES, 'UTF-8');
}
- $data["description"] = trim($match[3]);
+ $data['description'] = trim($match[3]);
- $data["after"] = trim($match[4]);
+ $data['after'] = trim($match[4]);
return $data;
}
*/
$has_title = !empty($item['title']);
- $plink = defaults($item, 'plink', '');
+ $plink = $item['plink'] ?? '';
$post = self::getAttachmentData($body);
// Get all linked images with alternative image description
}
// if nothing is found, it maybe having an image.
- if (!isset($post["type"])) {
+ if (!isset($post['type'])) {
// Simplify image codes
$body = preg_replace("/\[img\=([0-9]*)x([0-9]*)\](.*?)\[\/img\]/ism", '[img]$3[/img]', $body);
$body = preg_replace("/\[img\=(.*?)\](.*?)\[\/img\]/ism", '[img]$1[/img]', $body);
- $post["text"] = $body;
+ $post['text'] = $body;
if (preg_match_all("(\[url=(.*?)\]\s*\[img\](.*?)\[\/img\]\s*\[\/url\])ism", $body, $pictures, PREG_SET_ORDER)) {
if ((count($pictures) == 1) && !$has_title) {
- if (!empty($item['object-type']) && ($item['object-type'] == ACTIVITY_OBJ_IMAGE)) {
+ if (!empty($item['object-type']) && ($item['object-type'] == Activity\ObjectType::IMAGE)) {
// Replace the preview picture with the real picture
$url = str_replace('-1.', '-0.', $pictures[0][2]);
$data = ['url' => $url, 'type' => 'photo'];
// Workaround:
// Sometimes photo posts to the own album are not detected at the start.
// So we seem to cannot use the cache for these cases. That's strange.
- if (($data["type"] != "photo") && strstr($pictures[0][1], "/photos/")) {
+ if (($data['type'] != 'photo') && strstr($pictures[0][1], "/photos/")) {
$data = ParseUrl::getSiteinfo($pictures[0][1], true);
}
- if ($data["type"] == "photo") {
- $post["type"] = "photo";
- if (isset($data["images"][0])) {
- $post["image"] = $data["images"][0]["src"];
- $post["url"] = $data["url"];
+ if ($data['type'] == 'photo') {
+ $post['type'] = 'photo';
+ if (isset($data['images'][0])) {
+ $post['image'] = $data['images'][0]['src'];
+ $post['url'] = $data['url'];
} else {
- $post["image"] = $data["url"];
+ $post['image'] = $data['url'];
}
- $post["preview"] = $pictures[0][2];
- $post["text"] = trim(str_replace($pictures[0][0], "", $body));
+ $post['preview'] = $pictures[0][2];
+ $post['text'] = trim(str_replace($pictures[0][0], '', $body));
} else {
$imgdata = Image::getInfoFromURL($pictures[0][1]);
- if ($imgdata && substr($imgdata["mime"], 0, 6) == "image/") {
- $post["type"] = "photo";
- $post["image"] = $pictures[0][1];
- $post["preview"] = $pictures[0][2];
- $post["text"] = trim(str_replace($pictures[0][0], "", $body));
+ if ($imgdata && substr($imgdata['mime'], 0, 6) == 'image/') {
+ $post['type'] = 'photo';
+ $post['image'] = $pictures[0][1];
+ $post['preview'] = $pictures[0][2];
+ $post['text'] = trim(str_replace($pictures[0][0], '', $body));
}
}
} elseif (count($pictures) > 0) {
- $post["type"] = "link";
- $post["url"] = $plink;
- $post["image"] = $pictures[0][2];
- $post["text"] = $body;
+ $post['type'] = 'link';
+ $post['url'] = $plink;
+ $post['image'] = $pictures[0][2];
+ $post['text'] = $body;
foreach ($pictures as $picture) {
- $post["text"] = trim(str_replace($picture[0], "", $post["text"]));
+ $post['text'] = trim(str_replace($picture[0], '', $post['text']));
}
}
} elseif (preg_match_all("(\[img\](.*?)\[\/img\])ism", $body, $pictures, PREG_SET_ORDER)) {
if ((count($pictures) == 1) && !$has_title) {
- $post["type"] = "photo";
- $post["image"] = $pictures[0][1];
- $post["text"] = str_replace($pictures[0][0], "", $body);
+ $post['type'] = 'photo';
+ $post['image'] = $pictures[0][1];
+ $post['text'] = str_replace($pictures[0][0], '', $body);
} elseif (count($pictures) > 0) {
- $post["type"] = "link";
- $post["url"] = $plink;
- $post["image"] = $pictures[0][1];
- $post["text"] = $body;
+ $post['type'] = 'link';
+ $post['url'] = $plink;
+ $post['image'] = $pictures[0][1];
+ $post['text'] = $body;
foreach ($pictures as $picture) {
- $post["text"] = trim(str_replace($picture[0], "", $post["text"]));
+ $post['text'] = trim(str_replace($picture[0], '', $post['text']));
}
}
}
// Test for the external links
- preg_match_all("(\[url\](.*?)\[\/url\])ism", $post["text"], $links1, PREG_SET_ORDER);
- preg_match_all("(\[url\=(.*?)\].*?\[\/url\])ism", $post["text"], $links2, PREG_SET_ORDER);
+ preg_match_all("(\[url\](.*?)\[\/url\])ism", $post['text'], $links1, PREG_SET_ORDER);
+ preg_match_all("(\[url\=(.*?)\].*?\[\/url\])ism", $post['text'], $links2, PREG_SET_ORDER);
$links = array_merge($links1, $links2);
// If there is only a single one, then use it.
// This should cover link posts via API.
- if ((count($links) == 1) && !isset($post["preview"]) && !$has_title) {
- $post["type"] = "link";
- $post["url"] = $links[0][1];
+ if ((count($links) == 1) && !isset($post['preview']) && !$has_title) {
+ $post['type'] = 'link';
+ $post['url'] = $links[0][1];
}
// Now count the number of external media links
- preg_match_all("(\[vimeo\](.*?)\[\/vimeo\])ism", $post["text"], $links1, PREG_SET_ORDER);
- preg_match_all("(\[youtube\\](.*?)\[\/youtube\\])ism", $post["text"], $links2, PREG_SET_ORDER);
- preg_match_all("(\[video\\](.*?)\[\/video\\])ism", $post["text"], $links3, PREG_SET_ORDER);
- preg_match_all("(\[audio\\](.*?)\[\/audio\\])ism", $post["text"], $links4, PREG_SET_ORDER);
+ preg_match_all("(\[vimeo\](.*?)\[\/vimeo\])ism", $post['text'], $links1, PREG_SET_ORDER);
+ preg_match_all("(\[youtube\\](.*?)\[\/youtube\\])ism", $post['text'], $links2, PREG_SET_ORDER);
+ preg_match_all("(\[video\\](.*?)\[\/video\\])ism", $post['text'], $links3, PREG_SET_ORDER);
+ preg_match_all("(\[audio\\](.*?)\[\/audio\\])ism", $post['text'], $links4, PREG_SET_ORDER);
// Add them to the other external links
$links = array_merge($links, $links1, $links2, $links3, $links4);
// Are there more than one?
if (count($links) > 1) {
// The post will be the type "text", which means a blog post
- unset($post["type"]);
- $post["url"] = $plink;
+ unset($post['type']);
+ $post['url'] = $plink;
}
- if (!isset($post["type"])) {
- $post["type"] = "text";
- $post["text"] = trim($body);
+ if (!isset($post['type'])) {
+ $post['type'] = "text";
+ $post['text'] = trim($body);
}
- } elseif (isset($post["url"]) && ($post["type"] == "video")) {
- $data = ParseUrl::getSiteinfoCached($post["url"], true);
+ } elseif (isset($post['url']) && ($post['type'] == 'video')) {
+ $data = ParseUrl::getSiteinfoCached($post['url'], true);
- if (isset($data["images"][0])) {
- $post["image"] = $data["images"][0]["src"];
+ if (isset($data['images'][0])) {
+ $post['image'] = $data['images'][0]['src'];
}
}
* Note: Can produce a [bookmark] tag in the returned string
*
* @brief Processes [attachment] tags
- * @param string $return
+ * @param string $text
* @param bool|int $simplehtml
* @param bool $tryoembed
* @return string
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
- private static function convertAttachment($return, $simplehtml = false, $tryoembed = true)
+ private static function convertAttachment($text, $simplehtml = false, $tryoembed = true)
{
- $data = self::getAttachmentData($return);
- if (empty($data) || empty($data["url"])) {
- return $return;
+ $data = self::getAttachmentData($text);
+ if (empty($data) || empty($data['url'])) {
+ return $text;
}
- if (isset($data["title"])) {
- $data["title"] = strip_tags($data["title"]);
- $data["title"] = str_replace(["http://", "https://"], "", $data["title"]);
+ if (isset($data['title'])) {
+ $data['title'] = strip_tags($data['title']);
+ $data['title'] = str_replace(['http://', 'https://'], '', $data['title']);
} else {
- $data["title"] = null;
+ $data['title'] = null;
}
- if (((strpos($data["text"], "[img=") !== false) || (strpos($data["text"], "[img]") !== false) || Config::get('system', 'always_show_preview')) && !empty($data["image"])) {
- $data["preview"] = $data["image"];
- $data["image"] = "";
+ if (((strpos($data['text'], "[img=") !== false) || (strpos($data['text'], "[img]") !== false) || Config::get('system', 'always_show_preview')) && !empty($data['image'])) {
+ $data['preview'] = $data['image'];
+ $data['image'] = '';
}
$return = '';
if (in_array($simplehtml, [7, 9])) {
- $return = self::convertUrlForOStatus($data["url"]);
+ // Only add the link when it isn't already part of the body
+ if (substr_count($text, $data['url']) == 1) {
+ $return = self::convertUrlForActivityPub($data['url']);
+ }
} elseif (($simplehtml != 4) && ($simplehtml != 0)) {
- $return = sprintf('<a href="%s" target="_blank">%s</a><br>', $data["url"], $data["title"]);
+ $return = sprintf('<a href="%s" target="_blank">%s</a><br>', $data['url'], $data['title']);
} else {
try {
if ($tryoembed && OEmbed::isAllowedURL($data['url'])) {
throw new Exception('OEmbed is disabled for this attachment.');
}
} catch (Exception $e) {
- $data["title"] = defaults($data, 'title', $data['url']);
+ $data['title'] = ($data['title'] ?? '') ?: $data['url'];
if ($simplehtml != 4) {
- $return = sprintf('<div class="type-%s">', $data["type"]);
+ $return = sprintf('<div class="type-%s">', $data['type']);
}
if (!empty($data['title']) && !empty($data['url'])) {
- if (!empty($data["image"]) && empty($data["text"]) && ($data["type"] == "photo")) {
- $return .= sprintf('<a href="%s" target="_blank"><img src="%s" alt="" title="%s" class="attachment-image" /></a>', $data["url"], self::proxyUrl($data["image"], $simplehtml), $data["title"]);
+ if (!empty($data['image']) && empty($data['text']) && ($data['type'] == 'photo')) {
+ $return .= sprintf('<a href="%s" target="_blank"><img src="%s" alt="" title="%s" class="attachment-image" /></a>', $data['url'], self::proxyUrl($data['image'], $simplehtml), $data['title']);
} else {
- if (!empty($data["image"])) {
- $return .= sprintf('<a href="%s" target="_blank"><img src="%s" alt="" title="%s" class="attachment-image" /></a><br />', $data["url"], self::proxyUrl($data["image"], $simplehtml), $data["title"]);
- } elseif (!empty($data["preview"])) {
- $return .= sprintf('<a href="%s" target="_blank"><img src="%s" alt="" title="%s" class="attachment-preview" /></a><br />', $data["url"], self::proxyUrl($data["preview"], $simplehtml), $data["title"]);
+ if (!empty($data['image'])) {
+ $return .= sprintf('<a href="%s" target="_blank"><img src="%s" alt="" title="%s" class="attachment-image" /></a><br />', $data['url'], self::proxyUrl($data['image'], $simplehtml), $data['title']);
+ } elseif (!empty($data['preview'])) {
+ $return .= sprintf('<a href="%s" target="_blank"><img src="%s" alt="" title="%s" class="attachment-preview" /></a><br />', $data['url'], self::proxyUrl($data['preview'], $simplehtml), $data['title']);
}
$return .= sprintf('<h4><a href="%s">%s</a></h4>', $data['url'], $data['title']);
}
}
- if (!empty($data["description"]) && $data["description"] != $data["title"]) {
+ if (!empty($data['description']) && $data['description'] != $data['title']) {
// Sanitize the HTML by converting it to BBCode
- $bbcode = HTML::toBBCode($data["description"]);
+ $bbcode = HTML::toBBCode($data['description']);
$return .= sprintf('<blockquote>%s</blockquote>', trim(self::convert($bbcode)));
}
}
}
- return trim(defaults($data, 'text', '') . ' ' . $return . ' ' . defaults($data, 'after', ''));
+ return trim(($data['text'] ?? '') . ' ' . $return . ' ' . ($data['after'] ?? ''));
}
public static function removeShareInformation($Text, $plaintext = false, $nolink = false)
if (!$data) {
return $Text;
} elseif ($nolink) {
- return $data["text"] . defaults($data, 'after', '');
+ return $data['text'] . ($data['after'] ?? '');
}
- $title = htmlentities(defaults($data, 'title', ''), ENT_QUOTES, 'UTF-8', false);
- $text = htmlentities($data["text"], ENT_QUOTES, 'UTF-8', false);
- if ($plaintext || (($title != "") && strstr($text, $title))) {
- $data["title"] = $data["url"];
- } elseif (($text != "") && strstr($title, $text)) {
- $data["text"] = $data["title"];
- $data["title"] = $data["url"];
+ $title = htmlentities($data['title'] ?? '', ENT_QUOTES, 'UTF-8', false);
+ $text = htmlentities($data['text'], ENT_QUOTES, 'UTF-8', false);
+ if ($plaintext || (($title != '') && strstr($text, $title))) {
+ $data['title'] = $data['url'];
+ } elseif (($text != '') && strstr($title, $text)) {
+ $data['text'] = $data['title'];
+ $data['title'] = $data['url'];
}
- if (empty($data["text"]) && !empty($data["title"]) && empty($data["url"])) {
- return $data["title"] . $data["after"];
+ if (empty($data['text']) && !empty($data['title']) && empty($data['url'])) {
+ return $data['title'] . $data['after'];
}
// If the link already is included in the post, don't add it again
- if (!empty($data["url"]) && strpos($data["text"], $data["url"])) {
- return $data["text"] . $data["after"];
+ if (!empty($data['url']) && strpos($data['text'], $data['url'])) {
+ return $data['text'] . $data['after'];
}
- $text = $data["text"];
+ $text = $data['text'];
- if (!empty($data["url"]) && !empty($data["title"])) {
- $text .= "\n[url=" . $data["url"] . "]" . $data["title"] . "[/url]";
- } elseif (!empty($data["url"])) {
- $text .= "\n[url]" . $data["url"] . "[/url]";
+ if (!empty($data['url']) && !empty($data['title'])) {
+ $text .= "\n[url=" . $data['url'] . ']' . $data['title'] . '[/url]';
+ } elseif (!empty($data['url'])) {
+ $text .= "\n[url]" . $data['url'] . '[/url]';
}
- return $text . "\n" . $data["after"];
+ return $text . "\n" . $data['after'];
}
/**
* @param array $match Array with the matching values
* @return string reformatted link including HTML codes
*/
- private static function convertUrlForOStatusCallback($match)
+ private static function convertUrlForActivityPubCallback($match)
{
$url = $match[1];
return $match[0];
}
- return self::convertUrlForOStatus($url);
+ return self::convertUrlForActivityPub($url);
}
/**
- * @brief Converts [url] BBCodes in a format that looks fine on OStatus systems.
+ * @brief Converts [url] BBCodes in a format that looks fine on ActivityPub systems.
* @param string $url URL that is about to be reformatted
* @return string reformatted link including HTML codes
*/
- private static function convertUrlForOStatus($url)
+ private static function convertUrlForActivityPub($url)
+ {
+ $html = '<a href="%s" target="_blank">%s</a>';
+ return sprintf($html, $url, self::getStyledURL($url));
+ }
+
+ /**
+ * Converts an URL in a nicer format (without the scheme and possibly shortened)
+ * @param string $url URL that is about to be reformatted
+ * @return string reformatted link
+ */
+ private static function getStyledURL($url)
{
$parts = parse_url($url);
$scheme = $parts['scheme'] . '://';
$styled_url = substr($styled_url, 0, 30) . "…";
}
- $html = '<a href="%s" target="_blank">%s</a>';
-
- return sprintf($html, $url, $styled_url);
+ return $styled_url;
}
/*
$attributes = [];
foreach(['author', 'profile', 'avatar', 'link', 'posted'] as $field) {
preg_match("/$field=(['\"])(.+?)\\1/ism", $attribute_string, $matches);
- $attributes[$field] = html_entity_decode(defaults($matches, 2, ''), ENT_QUOTES, 'UTF-8');
+ $attributes[$field] = html_entity_decode($matches[2] ?? '', ENT_QUOTES, 'UTF-8');
}
// We only call this so that a previously unknown contact can be added.
Contact::getIdForURL($attributes['profile'], 0, true, $default);
$author_contact = Contact::getDetailsByURL($attributes['profile']);
- $author_contact['addr'] = defaults($author_contact, 'addr' , Protocol::getAddrFromProfileUrl($attributes['profile']));
+ $author_contact['addr'] = ($author_contact['addr'] ?? '') ?: Protocol::getAddrFromProfileUrl($attributes['profile']);
- $attributes['author'] = defaults($author_contact, 'name' , $attributes['author']);
- $attributes['avatar'] = defaults($author_contact, 'micro', $attributes['avatar']);
- $attributes['profile'] = defaults($author_contact, 'url' , $attributes['profile']);
+ $attributes['author'] = ($author_contact['name'] ?? '') ?: $attributes['author'];
+ $attributes['avatar'] = ($author_contact['micro'] ?? '') ?: $attributes['avatar'];
+ $attributes['profile'] = ($author_contact['url'] ?? '') ?: $attributes['profile'];
if ($attributes['avatar']) {
$attributes['avatar'] = ProxyUtils::proxifyUrl($attributes['avatar'], false, ProxyUtils::SIZE_THUMB);
$a->getProfiler()->saveTimestamp($stamp1, "network", System::callstack());
- if (substr($curl_info["content_type"], 0, 6) == "image/") {
- $text = "[url=" . $match[1] . "]" . $match[1] . "[/url]";
+ if (substr($curl_info['content_type'], 0, 6) == 'image/') {
+ $text = "[url=" . $match[1] . ']' . $match[1] . "[/url]";
} else {
- $text = "[url=" . $match[2] . "]" . $match[2] . "[/url]";
+ $text = "[url=" . $match[2] . ']' . $match[2] . "[/url]";
// if its not a picture then look if its a page that contains a picture link
$body = Network::fetchUrl($match[1]);
}
}
- if (strtolower($attr["name"]) == "twitter:image") {
- $text = "[url=" . $attr["content"] . "]" . $attr["content"] . "[/url]";
+ if (strtolower($attr['name']) == 'twitter:image') {
+ $text = '[url=' . $attr['content'] . ']' . $attr['content'] . '[/url]';
}
}
}
private static function expandLinksCallback($match)
{
- if (($match[3] == "") || ($match[2] == $match[3]) || stristr($match[2], $match[3])) {
+ if (($match[3] == '') || ($match[2] == $match[3]) || stristr($match[2], $match[3])) {
return ($match[1] . "[url]" . $match[2] . "[/url]");
} else {
return ($match[1] . $match[3] . " [url]" . $match[2] . "[/url]");
$own_photo_url = preg_quote(Strings::normaliseLink($a->getBaseURL()) . '/photos/');
if (preg_match('|' . $own_photo_url . '.*?/image/|', Strings::normaliseLink($match[1]))) {
if (!empty($match[3])) {
- $text = "[img=" . str_replace('-1.', '-0.', $match[2]) . "]" . $match[3] . "[/img]";
+ $text = '[img=' . str_replace('-1.', '-0.', $match[2]) . ']' . $match[3] . '[/img]';
} else {
- $text = "[img]" . str_replace('-1.', '-0.', $match[2]) . "[/img]";
+ $text = '[img]' . str_replace('-1.', '-0.', $match[2]) . '[/img]';
}
return $text;
}
$a->getProfiler()->saveTimestamp($stamp1, "network", System::callstack());
// if its a link to a picture then embed this picture
- if (substr($curl_info["content_type"], 0, 6) == "image/") {
- $text = "[img]" . $match[1] . "[/img]";
+ if (substr($curl_info['content_type'], 0, 6) == 'image/') {
+ $text = '[img]' . $match[1] . '[/img]';
} else {
if (!empty($match[3])) {
- $text = "[img=" . $match[2] . "]" . $match[3] . "[/img]";
+ $text = '[img=' . $match[2] . ']' . $match[3] . '[/img]';
} else {
- $text = "[img]" . $match[2] . "[/img]";
+ $text = '[img]' . $match[2] . '[/img]';
}
// if its not a picture then look if its a page that contains a picture link
}
}
- if (strtolower($attr["name"]) == "twitter:image") {
+ if (strtolower($attr['name']) == "twitter:image") {
if (!empty($match[3])) {
- $text = "[img=" . $attr["content"] . "]" . $match[3] . "[/img]";
+ $text = "[img=" . $attr['content'] . "]" . $match[3] . "[/img]";
} else {
- $text = "[img]" . $attr["content"] . "[/img]";
+ $text = "[img]" . $attr['content'] . "[/img]";
}
}
}
$try_oembed_callback = function ($match)
{
$url = $match[1];
- $title = defaults($match, 2, null);
+ $title = $match[2] ?? null;
try {
$return = OEmbed::getHTML($url, $title);
$text = str_replace($search, $replace, $text);
// removing multiplicated newlines
- if (Config::get("system", "remove_multiplicated_lines")) {
+ if (Config::get('system', 'remove_multiplicated_lines')) {
$search = ["\n\n\n", "\n ", " \n", "[/quote]\n\n", "\n[/quote]", "[/li]\n", "\n[li]", "\n[ul]", "[/ul]\n", "\n\n[share ", "[/attachment]\n",
"\n[h1]", "[/h1]\n", "\n[h2]", "[/h2]\n", "\n[h3]", "[/h3]\n", "\n[h4]", "[/h4]\n", "\n[h5]", "[/h5]\n", "\n[h6]", "[/h6]\n"];
$replace = ["\n\n", "\n", "\n", "[/quote]\n", "[/quote]", "[/li]", "[li]", "[ul]", "[/ul]", "\n[share ", "[/attachment]",
function ($matches) use ($simple_html) {
$matches[1] = self::proxyUrl($matches[1], $simple_html);
$matches[2] = htmlspecialchars($matches[2], ENT_COMPAT);
- return '<img src="' . $matches[1] . '" alt="' . $matches[2] . '">';
+ return '<img src="' . $matches[1] . '" alt="' . $matches[2] . '" title="' . $matches[2] . '">';
},
$text);
if (!$for_plaintext) {
if (in_array($simple_html, [7, 9])) {
- $text = preg_replace_callback("/\[url\](.*?)\[\/url\]/ism", 'self::convertUrlForOStatusCallback', $text);
- $text = preg_replace_callback("/\[url\=(.*?)\](.*?)\[\/url\]/ism", 'self::convertUrlForOStatusCallback', $text);
+ $text = preg_replace_callback("/\[url\](.*?)\[\/url\]/ism", 'self::convertUrlForActivityPubCallback', $text);
+ $text = preg_replace_callback("/\[url\=(.*?)\](.*?)\[\/url\]/ism", 'self::convertUrlForActivityPubCallback', $text);
}
} else {
$text = preg_replace("(\[url\](.*?)\[\/url\])ism", " $1 ", $text);
$text = preg_replace_callback("/(?:#\[url\=.*?\]|\[url\=.*?\]#)(.*?)\[\/url\]/ism", function($matches) {
return '#<a href="'
. System::baseUrl() . '/search?tag=' . rawurlencode($matches[1])
- . '" class="tag" title="' . XML::escape($matches[1]) . '">'
+ . '" class="tag" rel="tag" title="' . XML::escape($matches[1]) . '">'
. XML::escape($matches[1])
. '</a>';
}, $text);
// Clean up the HTML by loading and saving the HTML with the DOM.
// Bad structured html can break a whole page.
// For performance reasons do it only with activated item cache or at export.
- if (!$try_oembed || (get_itemcachepath() != "")) {
+ if (!$try_oembed || (get_itemcachepath() != '')) {
$doc = new DOMDocument();
$doc->preserveWhiteSpace = false;
$doctype = '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">';
$encoding = '<?xml encoding="UTF-8">';
- @$doc->loadHTML($encoding.$doctype."<html><body>".$text."</body></html>");
+ @$doc->loadHTML($encoding . $doctype . '<html><body>' . $text . '</body></html>');
$doc->encoding = 'UTF-8';
$text = $doc->saveHTML();
- $text = str_replace(["<html><body>", "</body></html>", $doctype, $encoding], ["", "", "", ""], $text);
+ $text = str_replace(['<html><body>', '</body></html>', $doctype, $encoding], ['', '', '', ''], $text);
$text = str_replace('<br></li>', '</li>', $text);
* @param string $addon The addon for which the abstract is meant for
* @return string The abstract
*/
- public static function getAbstract($text, $addon = "")
+ public static function getAbstract($text, $addon = '')
{
- $abstract = "";
+ $abstract = '';
$abstracts = [];
$addon = strtolower($addon);
$abstract = $abstracts[$addon];
}
- if ($abstract == "" && preg_match("/\[abstract\](.*?)\[\/abstract\]/ism", $text, $result)) {
+ if ($abstract == '' && preg_match("/\[abstract\](.*?)\[\/abstract\]/ism", $text, $result)) {
$abstract = $result[1];
}
// Add all tags that maybe were removed
if (preg_match_all("/#\[url\=([$url_search_string]*)\](.*?)\[\/url\]/ism", $original_text, $tags)) {
- $tagline = "";
+ $tagline = '';
foreach ($tags[2] as $tag) {
$tag = html_entity_decode($tag, ENT_QUOTES, 'UTF-8');
if (!strpos(html_entity_decode($text, ENT_QUOTES, 'UTF-8'), '#' . $tag)) {
// If a link is followed by a quote then there should be a newline before it
// Maybe we should make this newline at every time before a quote.
- $text = str_replace(["</a><blockquote>"], ["</a><br><blockquote>"], $text);
+ $text = str_replace(['</a><blockquote>'], ['</a><br><blockquote>'], $text);
$stamp1 = microtime(true);
--- /dev/null
+<?php
+
+namespace Friendica\Content\Text\BBCode;
+
+/**
+ * Video specific BBCode util class
+ */
+final class Video
+{
+ /**
+ * Transforms video BBCode tagged links to youtube/vimeo tagged links
+ *
+ * @param string $bbCodeString The input BBCode styled string
+ *
+ * @return string The transformed text
+ */
+ public function transform(string $bbCodeString)
+ {
+ $matches = null;
+ $found = preg_match_all("/\[video\](.*?)\[\/video\]/ism",$bbCodeString,$matches,PREG_SET_ORDER);
+ if ($found) {
+ foreach ($matches as $match) {
+ if ((stristr($match[1], 'youtube')) || (stristr($match[1], 'youtu.be'))) {
+ $bbCodeString = str_replace($match[0], '[youtube]' . $match[1] . '[/youtube]', $bbCodeString);
+ } elseif (stristr($match[1], 'vimeo')) {
+ $bbCodeString = str_replace($match[0], '[vimeo]' . $match[1] . '[/vimeo]', $bbCodeString);
+ }
+ }
+ }
+ return $bbCodeString;
+ }
+}
$url = '';
}
- return Renderer::replaceMacros(Renderer::getMarkupTemplate(($textmode)?'micropro_txt.tpl':'micropro_img.tpl'), [
- '$click' => defaults($contact, 'click', ''),
+ return Renderer::replaceMacros(Renderer::getMarkupTemplate($textmode ? 'micropro_txt.tpl' : 'micropro_img.tpl'), [
+ '$click' => $contact['click'] ?? '',
'$class' => $class,
'$url' => $url,
'$photo' => ProxyUtils::proxifyUrl($contact['thumb'], false, ProxyUtils::SIZE_THUMB),
'$save_label' => $save_label,
'$search_hint' => L10n::t('@name, !forum, #tags, content'),
'$mode' => $mode,
- '$return_url' => urlencode('search?q=' . $s),
+ '$return_url' => urlencode('search?q=' . urlencode($s)),
];
if (!$aside) {
foreach (FileTag::fileToArray($saved) as $savedFolderName) {
$terms[] = ['ref' => $savedFolderName, 'name' => $savedFolderName];
}
+
+ usort($terms, function ($a, $b) {
+ return strcmp($a['name'], $b['name']);
+ });
return self::filter(
'file',
// $a->data is only available if the profile page is visited. If the visited page is not part
// of the profile page it should be the personal /events page. So we can use $a->user.
- $user = defaults($a->data['user'], 'nickname', $a->user['nickname']);
+ $user = ($a->data['user']['nickname'] ?? '') ?: $a->user['nickname'];
$tpl = Renderer::getMarkupTemplate("widget/events.tpl");
$return = Renderer::replaceMacros($tpl, [
if ($total) {
// Only show followed for personal accounts, followers for pages
- if (defaults($profile, 'account-type', User::ACCOUNT_TYPE_PERSON) == User::ACCOUNT_TYPE_PERSON) {
+ if ((($profile['account-type'] ?? '') ?: User::ACCOUNT_TYPE_PERSON) == User::ACCOUNT_TYPE_PERSON) {
$rel = [Contact::SHARING, Contact::FRIEND];
} else {
$rel = [Contact::FOLLOWER, Contact::FRIEND];
$networks = null;
- $size = defaults($options, 'size', 4);
+ $size = ($options['size'] ?? 0) ?: 4;
$mutual = !empty($options['mutual_friends']);
$single = !empty($options['single']) && empty($options['multiple']);
- $exclude = defaults($options, 'exclude', false);
+ $exclude = $options['exclude'] ?? false;
- switch (defaults($options, 'networks', Protocol::PHANTOM)) {
+ switch (($options['networks'] ?? '') ?: Protocol::PHANTOM) {
case 'DFRN_ONLY':
$networks = [Protocol::DFRN];
break;
$acl_regex = '/<([0-9]+)>/i';
- preg_match_all($acl_regex, defaults($user, 'allow_cid', ''), $matches);
+ preg_match_all($acl_regex, $user['allow_cid'] ?? '', $matches);
$allow_cid = $matches[1];
- preg_match_all($acl_regex, defaults($user, 'allow_gid', ''), $matches);
+ preg_match_all($acl_regex, $user['allow_gid'] ?? '', $matches);
$allow_gid = $matches[1];
- preg_match_all($acl_regex, defaults($user, 'deny_cid', ''), $matches);
+ preg_match_all($acl_regex, $user['deny_cid'] ?? '', $matches);
$deny_cid = $matches[1];
- preg_match_all($acl_regex, defaults($user, 'deny_gid', ''), $matches);
+ preg_match_all($acl_regex, $user['deny_gid'] ?? '', $matches);
$deny_gid = $matches[1];
// Reformats the ACL data so that it is accepted by the JS frontend
'$showall' => L10n::t('Visible to everybody'),
'$show' => L10n::t('show'),
'$hide' => L10n::t('don\'t show'),
- '$allowcid' => json_encode(defaults($default_permissions, 'allow_cid', [])), // we need arrays for Javascript since we call .remove() and .push() on this values
- '$allowgid' => json_encode(defaults($default_permissions, 'allow_gid', [])),
- '$denycid' => json_encode(defaults($default_permissions, 'deny_cid', [])),
- '$denygid' => json_encode(defaults($default_permissions, 'deny_gid', [])),
+ '$allowcid' => json_encode(($default_permissions['allow_cid'] ?? '') ?: []), // We need arrays for
+ '$allowgid' => json_encode(($default_permissions['allow_gid'] ?? '') ?: []), // Javascript since we
+ '$denycid' => json_encode(($default_permissions['deny_cid'] ?? '') ?: []), // call .remove() and
+ '$denygid' => json_encode(($default_permissions['deny_gid'] ?? '') ?: []), // .push() on these values
'$networks' => $show_jotnets,
'$emailcc' => L10n::t('CC: email addresses'),
'$emtitle' => L10n::t('Example: bob@example.com, mary@example.com'),
<?php
+
/**
* @file /src/Core/Authentication.php
*/
use Friendica\Network\HTTPException\ForbiddenException;
/**
-* Handle Authentification, Session and Cookies
-*/
+ * Handle Authentification, Session and Cookies
+ */
class Authentication extends BaseObject
{
/**
*/
public static function getCookieHashForUser($user)
{
- return(hash("sha256", Config::get("system", "site_prvkey") .
- $user["prvkey"] .
- $user["password"]));
+ return hash_hmac(
+ "sha256",
+ hash_hmac("sha256", $user["password"], $user["prvkey"]),
+ Config::get("system", "site_prvkey")
+ );
}
/**
}
if ($user) {
- $value = json_encode(["uid" => $user["uid"],
+ $value = json_encode([
+ "uid" => $user["uid"],
"hash" => self::getCookieHashForUser($user),
- "ip" => defaults($_SERVER, 'REMOTE_ADDR', '0.0.0.0')]);
+ "ip" => ($_SERVER['REMOTE_ADDR'] ?? '') ?: '0.0.0.0'
+ ]);
} else {
$value = "";
}
}
}
}
-
/**
* This class is responsible for all system-wide configuration values in Friendica
* There are two types of storage
- * - The Config-Files (loaded into the FileCache @see Cache\ConfigCache )
- * - The Config-DB-Table (per Config-DB-model @see Model\Config\Config )
+ * - The Config-Files (loaded into the FileCache @see Cache\ConfigCache)
+ * - The Config-DB-Table (per Config-DB-model @see Model\Config\Config)
*/
abstract class Configuration
{
*
* Get a particular config value from the given category ($cat)
* and the $key from a cached storage either from the $this->configAdapter
- * (@see IConfigAdapter ) or from the $this->configCache (@see ConfigCache ).
+ * (@see IConfigAdapter) or from the $this->configCache (@see ConfigCache).
*
* @param string $cat The category of the configuration value
* @param string $key The configuration key to query
* @brief Deletes the given key from the system configuration.
*
* Removes the configured value from the stored cache in $this->configCache
- * (@see ConfigCache ) and removes it from the database (@see IConfigAdapter ).
+ * (@see ConfigCache) and removes it from the database (@see IConfigAdapter).
*
* @param string $cat The category of the configuration value
* @param string $key The configuration key to delete
* This class is responsible for the user-specific configuration values in Friendica
* The values are set through the Config-DB-Table (per Config-DB-model @see Model\Config\PConfig)
*
- * The configuration cache (@see Cache\PConfigCache ) is used for temporary caching of database calls. This will
+ * The configuration cache (@see Cache\PConfigCache) is used for temporary caching of database calls. This will
* increase the performance.
*/
abstract class PConfiguration
* @param string $cat The category of the configuration value
*
* @return void
- * @see PConfigCache )
+ * @see PConfigCache
*
*/
abstract public function load(int $uid, string $cat = 'config');
*
* Get a particular user's config value from the given category ($cat)
* and the $key with the $uid from a cached storage either from the $this->configAdapter
- * (@see IConfigAdapter ) or from the $this->configCache (@see PConfigCache ).
+ * (@see IConfigAdapter) or from the $this->configCache (@see PConfigCache).
*
* @param int $uid The user_id
* @param string $cat The category of the configuration value
* Deletes the given key from the users's configuration.
*
* Removes the configured value from the stored cache in $this->configCache
- * (@see ConfigCache ) and removes it from the database (@see IConfigAdapter )
+ * (@see ConfigCache) and removes it from the database (@see IConfigAdapter)
* with the given $uid.
*
* @param int $uid The user_id
*/
private $logger;
- public function __construct(Configuration $config, Database $dba, LoggerInterface $logger)
+ public function __construct(Configuration $config, Database $dba, LoggerInterface $logger, array $server, array $get)
{
$this->dba = $dba;
$this->logger = $logger;
- $this->loadTranslationTable(L10n::detectLanguage($config->get('system', 'language', 'en')));
+ $this->loadTranslationTable(L10n::detectLanguage($server, $get, $config->get('system', 'language', 'en')));
}
/**
$this->lang = $this->langSave;
$this->stringsSave = null;
- $this->langSave = null;
+ $this->langSave = null;
}
/**
{
$lang = Strings::sanitizeFilePathItem($lang);
+ // Don't override the language setting with empty languages
+ if (empty($lang)) {
+ return;
+ }
+
$a = new \stdClass();
$a->strings = [];
while ($p = $this->dba->fetch($addons)) {
$name = Strings::sanitizeFilePathItem($p['name']);
if (file_exists("addon/$name/lang/$lang/strings.php")) {
- include "addon/$name/lang/$lang/strings.php";
+ include __DIR__ . "/../../../addon/$name/lang/$lang/strings.php";
}
}
- if (file_exists("view/lang/$lang/strings.php")) {
- include "view/lang/$lang/strings.php";
+ if (file_exists(__DIR__ . "/../../../view/lang/$lang/strings.php")) {
+ include __DIR__ . "/../../../view/lang/$lang/strings.php";
}
$this->lang = $lang;
* @brief Returns the preferred language from the HTTP_ACCEPT_LANGUAGE header
*
* @param string $sysLang The default fallback language
+ * @param array $server The $_SERVER array
+ * @param array $get The $_GET array
*
* @return string The two-letter language code
*/
- public static function detectLanguage(string $sysLang = 'en')
+ public static function detectLanguage(array $server, array $get, string $sysLang = 'en')
{
- $lang_list = [];
-
- if (!empty($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
- // break up string into pieces (languages and q factors)
- preg_match_all('/([a-z]{1,8}(-[a-z]{1,8})?)\s*(;\s*q\s*=\s*(1|0\.[0-9]+))?/i', $_SERVER['HTTP_ACCEPT_LANGUAGE'], $lang_parse);
-
- if (count($lang_parse[1])) {
- // go through the list of prefered languages and add a generic language
- // for sub-linguas (e.g. de-ch will add de) if not already in array
- for ($i = 0; $i < count($lang_parse[1]); $i++) {
- $lang_list[] = strtolower($lang_parse[1][$i]);
- if (strlen($lang_parse[1][$i]) > 3) {
- $dashpos = strpos($lang_parse[1][$i], '-');
- if (!in_array(substr($lang_parse[1][$i], 0, $dashpos), $lang_list)) {
- $lang_list[] = strtolower(substr($lang_parse[1][$i], 0, $dashpos));
- }
- }
- }
- }
+ $lang_variable = $server['HTTP_ACCEPT_LANGUAGE'] ?? null;
+
+ $acceptedLanguages = preg_split('/,\s*/', $lang_variable);
+
+ if (empty($acceptedLanguages)) {
+ $acceptedLanguages = [];
}
- if (isset($_GET['lang'])) {
- $lang_list = [$_GET['lang']];
+ // Add get as absolute quality accepted language (except this language isn't valid)
+ if (!empty($get['lang'])) {
+ $acceptedLanguages[] = $get['lang'];
}
- // check if we have translations for the preferred languages and pick the 1st that has
- foreach ($lang_list as $lang) {
- if ($lang === 'en' || (file_exists("view/lang/$lang") && is_dir("view/lang/$lang"))) {
- $preferred = $lang;
- break;
- }
+ // return the sys language in case there's nothing to do
+ if (empty($acceptedLanguages)) {
+ return $sysLang;
}
- if (isset($preferred)) {
- return $preferred;
+
+ // Set the syslang as default fallback
+ $current_lang = $sysLang;
+ // start with quality zero (every guessed language is more acceptable ..)
+ $current_q = 0;
+
+ foreach ($acceptedLanguages as $acceptedLanguage) {
+ $res = preg_match(
+ '/^([a-z]{1,8}(?:-[a-z]{1,8})*)(?:;\s*q=(0(?:\.[0-9]{1,3})?|1(?:\.0{1,3})?))?$/i',
+ $acceptedLanguage,
+ $matches
+ );
+
+ // Invalid language? -> skip
+ if (!$res) {
+ continue;
+ }
+
+ // split language codes based on it's "-"
+ $lang_code = explode('-', $matches[1]);
+
+ // determine the quality of the guess
+ if (isset($matches[2])) {
+ $lang_quality = (float)$matches[2];
+ } else {
+ // fallback so without a quality parameter, it's probably the best
+ $lang_quality = 1;
+ }
+
+ // loop through each part of the code-parts
+ while (count($lang_code)) {
+ // try to mix them so we can get double-code parts too
+ $match_lang = strtolower(join('-', $lang_code));
+ if (file_exists(__DIR__ . "/../../../view/lang/$match_lang") &&
+ is_dir(__DIR__ . "/../../../view/lang/$match_lang")) {
+ if ($lang_quality > $current_q) {
+ $current_lang = $match_lang;
+ $current_q = $lang_quality;
+ break;
+ }
+ }
+
+ // remove the most right code-part
+ array_pop($lang_code);
+ }
}
- // in case none matches, get the system wide configured language, or fall back to English
- return $sysLang;
+ return $current_lang;
}
/**
self::TRACE => 'Trace',
self::DEBUG => 'Debug',
self::DATA => 'Data',
- self::ALL => 'All',
];
/**
+++ /dev/null
-<?php
-/**
- * @file src/Core/NotificationsManager.php
- * @brief Methods for read and write notifications from/to database
- * or for formatting notifications
- */
-namespace Friendica\Core;
-
-use Friendica\BaseObject;
-use Friendica\Content\Text\BBCode;
-use Friendica\Content\Text\HTML;
-use Friendica\Database\DBA;
-use Friendica\Model\Contact;
-use Friendica\Model\Item;
-use Friendica\Util\DateTimeFormat;
-use Friendica\Util\Proxy as ProxyUtils;
-use Friendica\Util\Temporal;
-use Friendica\Util\XML;
-
-/**
- * @brief Methods for read and write notifications from/to database
- * or for formatting notifications
- */
-class NotificationsManager extends BaseObject
-{
- /**
- * @brief set some extra note properties
- *
- * @param array $notes array of note arrays from db
- * @return array Copy of input array with added properties
- *
- * Set some extra properties to note array from db:
- * - timestamp as int in default TZ
- * - date_rel : relative date string
- * - msg_html: message as html string
- * - msg_plain: message as plain text string
- * @throws \Friendica\Network\HTTPException\InternalServerErrorException
- */
- private function _set_extra(array $notes)
- {
- $rets = [];
- foreach ($notes as $n) {
- $local_time = DateTimeFormat::local($n['date']);
- $n['timestamp'] = strtotime($local_time);
- $n['date_rel'] = Temporal::getRelativeDate($n['date']);
- $n['msg_html'] = BBCode::convert($n['msg'], false);
- $n['msg_plain'] = explode("\n", trim(HTML::toPlaintext($n['msg_html'], 0)))[0];
-
- $rets[] = $n;
- }
- return $rets;
- }
-
- /**
- * @brief Get all notifications for local_user()
- *
- * @param array $filter optional Array "column name"=>value: filter query by columns values
- * @param array $order optional Array to order by
- * @param string $limit optional Query limits
- *
- * @return array|bool of results or false on errors
- * @throws \Friendica\Network\HTTPException\InternalServerErrorException
- */
- public function getAll($filter = [], $order = ['date' => 'DESC'], $limit = "")
- {
- $params = [];
-
- $params['order'] = $order;
-
- if (!empty($limit)) {
- $params['limit'] = $limit;
- }
-
- $dbFilter = array_merge($filter, ['uid' => local_user()]);
-
- $stmtNotifies = DBA::select('notify', [], $dbFilter, $params);
-
- if (DBA::isResult($stmtNotifies)) {
- return $this->_set_extra(DBA::toArray($stmtNotifies));
- }
-
- return false;
- }
-
- /**
- * @brief Get one note for local_user() by $id value
- *
- * @param int $id identity
- * @return array note values or null if not found
- * @throws \Friendica\Network\HTTPException\InternalServerErrorException
- */
- public function getByID($id)
- {
- $stmtNotify = DBA::selectFirst('notify', [], ['id' => $id, 'uid' => local_user()]);
- if (DBA::isResult($stmtNotify)) {
- return $this->_set_extra([$stmtNotify])[0];
- }
- return null;
- }
-
- /**
- * @brief set seen state of $note of local_user()
- *
- * @param array $note note array
- * @param bool $seen optional true or false, default true
- * @return bool true on success, false on errors
- * @throws \Exception
- */
- public function setSeen($note, $seen = true)
- {
- return DBA::update('notify', ['seen' => $seen], [
- '(`link` = ? OR (`parent` != 0 AND `parent` = ? AND `otype` = ?)) AND `uid` = ?',
- $note['link'],
- $note['parent'],
- $note['otype'],
- local_user()
- ]);
- }
-
- /**
- * @brief set seen state of all notifications of local_user()
- *
- * @param bool $seen optional true or false. default true
- * @return bool true on success, false on error
- * @throws \Exception
- */
- public function setAllSeen($seen = true)
- {
- return DBA::update('notify', ['seen' => $seen], ['uid' => local_user()]);
- }
-
- /**
- * @brief List of pages for the Notifications TabBar
- *
- * @return array with with notifications TabBar data
- * @throws \Exception
- */
- public function getTabs()
- {
- $selected = defaults(self::getApp()->argv, 1, '');
-
- $tabs = [
- [
- 'label' => L10n::t('System'),
- 'url' => 'notifications/system',
- 'sel' => (($selected == 'system') ? 'active' : ''),
- 'id' => 'system-tab',
- 'accesskey' => 'y',
- ],
- [
- 'label' => L10n::t('Network'),
- 'url' => 'notifications/network',
- 'sel' => (($selected == 'network') ? 'active' : ''),
- 'id' => 'network-tab',
- 'accesskey' => 'w',
- ],
- [
- 'label' => L10n::t('Personal'),
- 'url' => 'notifications/personal',
- 'sel' => (($selected == 'personal') ? 'active' : ''),
- 'id' => 'personal-tab',
- 'accesskey' => 'r',
- ],
- [
- 'label' => L10n::t('Home'),
- 'url' => 'notifications/home',
- 'sel' => (($selected == 'home') ? 'active' : ''),
- 'id' => 'home-tab',
- 'accesskey' => 'h',
- ],
- [
- 'label' => L10n::t('Introductions'),
- 'url' => 'notifications/intros',
- 'sel' => (($selected == 'intros') ? 'active' : ''),
- 'id' => 'intro-tab',
- 'accesskey' => 'i',
- ],
- ];
-
- return $tabs;
- }
-
- /**
- * @brief Format the notification query in an usable array
- *
- * @param array $notifs The array from the db query
- * @param string $ident The notifications identifier (e.g. network)
- * @return array
- * string 'label' => The type of the notification
- * string 'link' => URL to the source
- * string 'image' => The avatar image
- * string 'url' => The profile url of the contact
- * string 'text' => The notification text
- * string 'when' => The date of the notification
- * string 'ago' => T relative date of the notification
- * bool 'seen' => Is the notification marked as "seen"
- * @throws \Friendica\Network\HTTPException\InternalServerErrorException
- */
- private function formatNotifs(array $notifs, $ident = "")
- {
- $arr = [];
-
- if (DBA::isResult($notifs)) {
- foreach ($notifs as $it) {
- // Because we use different db tables for the notification query
- // we have sometimes $it['unseen'] and sometimes $it['seen].
- // So we will have to transform $it['unseen']
- if (array_key_exists('unseen', $it)) {
- $it['seen'] = ($it['unseen'] > 0 ? false : true);
- }
-
- // For feed items we use the user's contact, since the avatar is mostly self choosen.
- if (!empty($it['network']) && $it['network'] == Protocol::FEED) {
- $it['author-avatar'] = $it['contact-avatar'];
- }
-
- // Depending on the identifier of the notification we need to use different defaults
- switch ($ident) {
- case 'system':
- $default_item_label = 'notify';
- $default_item_link = System::baseUrl(true) . '/notify/view/' . $it['id'];
- $default_item_image = ProxyUtils::proxifyUrl($it['photo'], false, ProxyUtils::SIZE_MICRO);
- $default_item_url = $it['url'];
- $default_item_text = strip_tags(BBCode::convert($it['msg']));
- $default_item_when = DateTimeFormat::local($it['date'], 'r');
- $default_item_ago = Temporal::getRelativeDate($it['date']);
- break;
-
- case 'home':
- $default_item_label = 'comment';
- $default_item_link = System::baseUrl(true) . '/display/' . $it['parent-guid'];
- $default_item_image = ProxyUtils::proxifyUrl($it['author-avatar'], false, ProxyUtils::SIZE_MICRO);
- $default_item_url = $it['author-link'];
- $default_item_text = L10n::t("%s commented on %s's post", $it['author-name'], $it['parent-author-name']);
- $default_item_when = DateTimeFormat::local($it['created'], 'r');
- $default_item_ago = Temporal::getRelativeDate($it['created']);
- break;
-
- default:
- $default_item_label = (($it['id'] == $it['parent']) ? 'post' : 'comment');
- $default_item_link = System::baseUrl(true) . '/display/' . $it['parent-guid'];
- $default_item_image = ProxyUtils::proxifyUrl($it['author-avatar'], false, ProxyUtils::SIZE_MICRO);
- $default_item_url = $it['author-link'];
- $default_item_text = (($it['id'] == $it['parent'])
- ? L10n::t("%s created a new post", $it['author-name'])
- : L10n::t("%s commented on %s's post", $it['author-name'], $it['parent-author-name']));
- $default_item_when = DateTimeFormat::local($it['created'], 'r');
- $default_item_ago = Temporal::getRelativeDate($it['created']);
- }
-
- // Transform the different types of notification in an usable array
- switch ($it['verb']) {
- case ACTIVITY_LIKE:
- $notif = [
- 'label' => 'like',
- 'link' => System::baseUrl(true) . '/display/' . $it['parent-guid'],
- 'image' => ProxyUtils::proxifyUrl($it['author-avatar'], false, ProxyUtils::SIZE_MICRO),
- 'url' => $it['author-link'],
- 'text' => L10n::t("%s liked %s's post", $it['author-name'], $it['parent-author-name']),
- 'when' => $default_item_when,
- 'ago' => $default_item_ago,
- 'seen' => $it['seen']
- ];
- break;
-
- case ACTIVITY_DISLIKE:
- $notif = [
- 'label' => 'dislike',
- 'link' => System::baseUrl(true) . '/display/' . $it['parent-guid'],
- 'image' => ProxyUtils::proxifyUrl($it['author-avatar'], false, ProxyUtils::SIZE_MICRO),
- 'url' => $it['author-link'],
- 'text' => L10n::t("%s disliked %s's post", $it['author-name'], $it['parent-author-name']),
- 'when' => $default_item_when,
- 'ago' => $default_item_ago,
- 'seen' => $it['seen']
- ];
- break;
-
- case ACTIVITY_ATTEND:
- $notif = [
- 'label' => 'attend',
- 'link' => System::baseUrl(true) . '/display/' . $it['parent-guid'],
- 'image' => ProxyUtils::proxifyUrl($it['author-avatar'], false, ProxyUtils::SIZE_MICRO),
- 'url' => $it['author-link'],
- 'text' => L10n::t("%s is attending %s's event", $it['author-name'], $it['parent-author-name']),
- 'when' => $default_item_when,
- 'ago' => $default_item_ago,
- 'seen' => $it['seen']
- ];
- break;
-
- case ACTIVITY_ATTENDNO:
- $notif = [
- 'label' => 'attendno',
- 'link' => System::baseUrl(true) . '/display/' . $it['parent-guid'],
- 'image' => ProxyUtils::proxifyUrl($it['author-avatar'], false, ProxyUtils::SIZE_MICRO),
- 'url' => $it['author-link'],
- 'text' => L10n::t("%s is not attending %s's event", $it['author-name'], $it['parent-author-name']),
- 'when' => $default_item_when,
- 'ago' => $default_item_ago,
- 'seen' => $it['seen']
- ];
- break;
-
- case ACTIVITY_ATTENDMAYBE:
- $notif = [
- 'label' => 'attendmaybe',
- 'link' => System::baseUrl(true) . '/display/' . $it['parent-guid'],
- 'image' => ProxyUtils::proxifyUrl($it['author-avatar'], false, ProxyUtils::SIZE_MICRO),
- 'url' => $it['author-link'],
- 'text' => L10n::t("%s may attend %s's event", $it['author-name'], $it['parent-author-name']),
- 'when' => $default_item_when,
- 'ago' => $default_item_ago,
- 'seen' => $it['seen']
- ];
- break;
-
- case ACTIVITY_FRIEND:
- if (!isset($it['object'])) {
- $notif = [
- 'label' => 'friend',
- 'link' => $default_item_link,
- 'image' => $default_item_image,
- 'url' => $default_item_url,
- 'text' => $default_item_text,
- 'when' => $default_item_when,
- 'ago' => $default_item_ago,
- 'seen' => $it['seen']
- ];
- break;
- }
- /// @todo Check if this part here is used at all
- Logger::log('Complete data: ' . json_encode($it) . ' - ' . System::callstack(20), Logger::DEBUG);
-
- $xmlhead = "<" . "?xml version='1.0' encoding='UTF-8' ?" . ">";
- $obj = XML::parseString($xmlhead . $it['object']);
- $it['fname'] = $obj->title;
-
- $notif = [
- 'label' => 'friend',
- 'link' => System::baseUrl(true) . '/display/' . $it['parent-guid'],
- 'image' => ProxyUtils::proxifyUrl($it['author-avatar'], false, ProxyUtils::SIZE_MICRO),
- 'url' => $it['author-link'],
- 'text' => L10n::t("%s is now friends with %s", $it['author-name'], $it['fname']),
- 'when' => $default_item_when,
- 'ago' => $default_item_ago,
- 'seen' => $it['seen']
- ];
- break;
-
- default:
- $notif = [
- 'label' => $default_item_label,
- 'link' => $default_item_link,
- 'image' => $default_item_image,
- 'url' => $default_item_url,
- 'text' => $default_item_text,
- 'when' => $default_item_when,
- 'ago' => $default_item_ago,
- 'seen' => $it['seen']
- ];
- }
-
- $arr[] = $notif;
- }
- }
-
- return $arr;
- }
-
- /**
- * @brief Get network notifications
- *
- * @param int|string $seen If 0 only include notifications into the query
- * which aren't marked as "seen"
- * @param int $start Start the query at this point
- * @param int $limit Maximum number of query results
- *
- * @return array with
- * string 'ident' => Notification identifier
- * array 'notifications' => Network notifications
- * @throws \Friendica\Network\HTTPException\InternalServerErrorException
- */
- public function networkNotifs($seen = 0, $start = 0, $limit = 80)
- {
- $ident = 'network';
- $notifs = [];
-
- $condition = ['wall' => false, 'uid' => local_user()];
-
- if ($seen === 0) {
- $condition['unseen'] = true;
- }
-
- $fields = ['id', 'parent', 'verb', 'author-name', 'unseen', 'author-link', 'author-avatar', 'contact-avatar',
- 'network', 'created', 'object', 'parent-author-name', 'parent-author-link', 'parent-guid'];
- $params = ['order' => ['received' => true], 'limit' => [$start, $limit]];
-
- $items = Item::selectForUser(local_user(), $fields, $condition, $params);
-
- if (DBA::isResult($items)) {
- $notifs = $this->formatNotifs(Item::inArray($items), $ident);
- }
-
- $arr = [
- 'notifications' => $notifs,
- 'ident' => $ident,
- ];
-
- return $arr;
- }
-
- /**
- * @brief Get system notifications
- *
- * @param int|string $seen If 0 only include notifications into the query
- * which aren't marked as "seen"
- * @param int $start Start the query at this point
- * @param int $limit Maximum number of query results
- *
- * @return array with
- * string 'ident' => Notification identifier
- * array 'notifications' => System notifications
- * @throws \Friendica\Network\HTTPException\InternalServerErrorException
- */
- public function systemNotifs($seen = 0, $start = 0, $limit = 80)
- {
- $ident = 'system';
- $notifs = [];
- $sql_seen = "";
-
- $filter = ['uid' => local_user()];
- if ($seen === 0) {
- $filter['seen'] = false;
- }
-
- $params = [];
- $params['order'] = ['date' => 'DESC'];
- $params['limit'] = [$start, $limit];
-
- $stmtNotifies = DBA::select('notify',
- ['id', 'url', 'photo', 'msg', 'date', 'seen', 'verb'],
- $filter,
- $params);
-
- if (DBA::isResult($stmtNotifies)) {
- $notifs = $this->formatNotifs(DBA::toArray($stmtNotifies), $ident);
- }
-
- $arr = [
- 'notifications' => $notifs,
- 'ident' => $ident,
- ];
-
- return $arr;
- }
-
- /**
- * @brief Get personal notifications
- *
- * @param int|string $seen If 0 only include notifications into the query
- * which aren't marked as "seen"
- * @param int $start Start the query at this point
- * @param int $limit Maximum number of query results
- *
- * @return array with
- * string 'ident' => Notification identifier
- * array 'notifications' => Personal notifications
- * @throws \Exception
- */
- public function personalNotifs($seen = 0, $start = 0, $limit = 80)
- {
- $ident = 'personal';
- $notifs = [];
-
- $myurl = str_replace('http://', '', self::getApp()->contact['nurl']);
- $diasp_url = str_replace('/profile/', '/u/', $myurl);
-
- $condition = ["NOT `wall` AND `uid` = ? AND (`item`.`author-id` = ? OR `item`.`tag` REGEXP ? OR `item`.`tag` REGEXP ?)",
- local_user(), public_contact(), $myurl . '\\]', $diasp_url . '\\]'];
-
- if ($seen === 0) {
- $condition[0] .= " AND `unseen`";
- }
-
- $fields = ['id', 'parent', 'verb', 'author-name', 'unseen', 'author-link', 'author-avatar', 'contact-avatar',
- 'network', 'created', 'object', 'parent-author-name', 'parent-author-link', 'parent-guid'];
- $params = ['order' => ['received' => true], 'limit' => [$start, $limit]];
-
- $items = Item::selectForUser(local_user(), $fields, $condition, $params);
-
- if (DBA::isResult($items)) {
- $notifs = $this->formatNotifs(Item::inArray($items), $ident);
- }
-
- $arr = [
- 'notifications' => $notifs,
- 'ident' => $ident,
- ];
-
- return $arr;
- }
-
- /**
- * @brief Get home notifications
- *
- * @param int|string $seen If 0 only include notifications into the query
- * which aren't marked as "seen"
- * @param int $start Start the query at this point
- * @param int $limit Maximum number of query results
- *
- * @return array with
- * string 'ident' => Notification identifier
- * array 'notifications' => Home notifications
- * @throws \Friendica\Network\HTTPException\InternalServerErrorException
- */
- public function homeNotifs($seen = 0, $start = 0, $limit = 80)
- {
- $ident = 'home';
- $notifs = [];
-
- $condition = ['wall' => true, 'uid' => local_user()];
-
- if ($seen === 0) {
- $condition['unseen'] = true;
- }
-
- $fields = ['id', 'parent', 'verb', 'author-name', 'unseen', 'author-link', 'author-avatar', 'contact-avatar',
- 'network', 'created', 'object', 'parent-author-name', 'parent-author-link', 'parent-guid'];
- $params = ['order' => ['received' => true], 'limit' => [$start, $limit]];
- $items = Item::selectForUser(local_user(), $fields, $condition, $params);
-
- if (DBA::isResult($items)) {
- $notifs = $this->formatNotifs(Item::inArray($items), $ident);
- }
-
- $arr = [
- 'notifications' => $notifs,
- 'ident' => $ident,
- ];
-
- return $arr;
- }
-
- /**
- * @brief Get introductions
- *
- * @param bool $all If false only include introductions into the query
- * which aren't marked as ignored
- * @param int $start Start the query at this point
- * @param int $limit Maximum number of query results
- * @param int $id When set, only the introduction with this id is displayed
- *
- * @return array with
- * string 'ident' => Notification identifier
- * array 'notifications' => Introductions
- * @throws \Friendica\Network\HTTPException\InternalServerErrorException
- * @throws \ImagickException
- */
- public function introNotifs($all = false, $start = 0, $limit = 80, $id = 0)
- {
- $ident = 'introductions';
- $notifs = [];
- $sql_extra = "";
-
- if (empty($id)) {
- if (!$all) {
- $sql_extra = " AND NOT `ignore` ";
- }
-
- $sql_extra .= " AND NOT `intro`.`blocked` ";
- } else {
- $sql_extra = sprintf(" AND `intro`.`id` = %d ", intval($id));
- }
-
- /// @todo Fetch contact details by "Contact::getDetailsByUrl" instead of queries to contact, fcontact and gcontact
- $stmtNotifies = DBA::p(
- "SELECT `intro`.`id` AS `intro_id`, `intro`.*, `contact`.*,
- `fcontact`.`name` AS `fname`, `fcontact`.`url` AS `furl`, `fcontact`.`addr` AS `faddr`,
- `fcontact`.`photo` AS `fphoto`, `fcontact`.`request` AS `frequest`,
- `gcontact`.`location` AS `glocation`, `gcontact`.`about` AS `gabout`,
- `gcontact`.`keywords` AS `gkeywords`, `gcontact`.`gender` AS `ggender`,
- `gcontact`.`network` AS `gnetwork`, `gcontact`.`addr` AS `gaddr`
- FROM `intro`
- LEFT JOIN `contact` ON `contact`.`id` = `intro`.`contact-id`
- LEFT JOIN `gcontact` ON `gcontact`.`nurl` = `contact`.`nurl`
- LEFT JOIN `fcontact` ON `intro`.`fid` = `fcontact`.`id`
- WHERE `intro`.`uid` = ? $sql_extra
- LIMIT ?, ?",
- $_SESSION['uid'],
- $start,
- $limit
- );
- if (DBA::isResult($stmtNotifies)) {
- $notifs = $this->formatIntros(DBA::toArray($stmtNotifies));
- }
-
- $arr = [
- 'ident' => $ident,
- 'notifications' => $notifs,
- ];
-
- return $arr;
- }
-
- /**
- * @brief Format the notification query in an usable array
- *
- * @param array $intros The array from the db query
- * @return array with the introductions
- * @throws \Friendica\Network\HTTPException\InternalServerErrorException
- * @throws \ImagickException
- */
- private function formatIntros($intros)
- {
- $knowyou = '';
-
- $arr = [];
-
- foreach ($intros as $it) {
- // 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.
- // Contact suggestions
- if ($it['fid']) {
- $return_addr = bin2hex(self::getApp()->user['nickname'] . '@' . self::getApp()->getHostName() . ((self::getApp()->getURLPath()) ? '/' . self::getApp()->getURLPath() : ''));
-
- $intro = [
- 'label' => 'friend_suggestion',
- 'notify_type' => L10n::t('Friend Suggestion'),
- 'intro_id' => $it['intro_id'],
- 'madeby' => $it['name'],
- 'madeby_url' => $it['url'],
- 'madeby_zrl' => Contact::magicLink($it['url']),
- 'madeby_addr' => $it['addr'],
- 'contact_id' => $it['contact-id'],
- 'photo' => (!empty($it['fphoto']) ? ProxyUtils::proxifyUrl($it['fphoto'], false, ProxyUtils::SIZE_SMALL) : "images/person-300.jpg"),
- 'name' => $it['fname'],
- 'url' => $it['furl'],
- 'zrl' => Contact::magicLink($it['furl']),
- 'hidden' => $it['hidden'] == 1,
- 'post_newfriend' => (intval(PConfig::get(local_user(), 'system', 'post_newfriend')) ? '1' : 0),
- 'knowyou' => $knowyou,
- 'note' => $it['note'],
- 'request' => $it['frequest'] . '?addr=' . $return_addr,
- ];
-
- // Normal connection requests
- } else {
- $it = $this->getMissingIntroData($it);
-
- if (empty($it['url'])) {
- continue;
- }
-
- // Don't show these data until you are connected. Diaspora is doing the same.
- if ($it['gnetwork'] === Protocol::DIASPORA) {
- $it['glocation'] = "";
- $it['gabout'] = "";
- $it['ggender'] = "";
- }
- $intro = [
- 'label' => (($it['network'] !== Protocol::OSTATUS) ? 'friend_request' : 'follower'),
- 'notify_type' => (($it['network'] !== Protocol::OSTATUS) ? L10n::t('Friend/Connect Request') : L10n::t('New Follower')),
- 'dfrn_id' => $it['issued-id'],
- 'uid' => $_SESSION['uid'],
- 'intro_id' => $it['intro_id'],
- 'contact_id' => $it['contact-id'],
- 'photo' => (!empty($it['photo']) ? ProxyUtils::proxifyUrl($it['photo'], false, ProxyUtils::SIZE_SMALL) : "images/person-300.jpg"),
- 'name' => $it['name'],
- 'location' => BBCode::convert($it['glocation'], false),
- 'about' => BBCode::convert($it['gabout'], false),
- 'keywords' => $it['gkeywords'],
- 'gender' => $it['ggender'],
- 'hidden' => $it['hidden'] == 1,
- 'post_newfriend' => (intval(PConfig::get(local_user(), 'system', 'post_newfriend')) ? '1' : 0),
- 'url' => $it['url'],
- 'zrl' => Contact::magicLink($it['url']),
- 'addr' => $it['gaddr'],
- 'network' => $it['gnetwork'],
- 'knowyou' => $it['knowyou'],
- 'note' => $it['note'],
- ];
- }
-
- $arr[] = $intro;
- }
-
- return $arr;
- }
-
- /**
- * @brief Check for missing contact data and try to fetch the data from
- * from other sources
- *
- * @param array $arr The input array with the intro data
- *
- * @return array The array with the intro data
- * @throws \Friendica\Network\HTTPException\InternalServerErrorException
- */
- private function getMissingIntroData($arr)
- {
- // If the network and the addr isn't available from the gcontact
- // table entry, take the one of the contact table entry
- if (empty($arr['gnetwork']) && !empty($arr['network'])) {
- $arr['gnetwork'] = $arr['network'];
- }
- if (empty($arr['gaddr']) && !empty($arr['addr'])) {
- $arr['gaddr'] = $arr['addr'];
- }
-
- // If the network and addr is still not available
- // get the missing data data from other sources
- if (empty($arr['gnetwork']) || empty($arr['gaddr'])) {
- $ret = Contact::getDetailsByURL($arr['url']);
-
- if (empty($arr['gnetwork']) && !empty($ret['network'])) {
- $arr['gnetwork'] = $ret['network'];
- }
- if (empty($arr['gaddr']) && !empty($ret['addr'])) {
- $arr['gaddr'] = $ret['addr'];
- }
- }
-
- return $arr;
- }
-}
*/
public static function getTemplateEngine()
{
- $template_engine = defaults(self::$theme, 'template_engine', 'smarty3');
+ $template_engine = (self::$theme['template_engine'] ?? '') ?: 'smarty3';
if (isset(self::$template_engines[$template_engine])) {
if (isset(self::$template_engine_instance[$template_engine])) {
}
// Ensure that we do have a contact entry
- Contact::getIdForURL(defaults($user_data, 'url', ''));
+ Contact::getIdForURL($user_data['url'] ?? '');
- $contactDetails = Contact::getDetailsByURL(defaults($user_data, 'url', ''), local_user());
- $itemUrl = defaults($contactDetails, 'addr', defaults($user_data, 'url', ''));
+ $contactDetails = Contact::getDetailsByURL($user_data['url'] ?? '', local_user());
$result = new ContactResult(
- defaults($user_data, 'name', ''),
- defaults($user_data, 'addr', ''),
- $itemUrl,
- defaults($user_data, 'url', ''),
- defaults($user_data, 'photo', ''),
- defaults($user_data, 'network', ''),
- defaults($contactDetails, 'id', 0),
+ $user_data['name'] ?? '',
+ $user_data['addr'] ?? '',
+ ($contactDetails['addr'] ?? '') ?: ($user_data['url'] ?? ''),
+ $user_data['url'] ?? '',
+ $user_data['photo'] ?? '',
+ $user_data['network'] ?? '',
+ $contactDetails['id'] ?? 0,
0,
- defaults($user_data, 'tags', '')
+ $user_data['tags'] ?? ''
);
return new ResultList(1, 1, 1, [$result]);
$results = json_decode($resultJson, true);
$resultList = new ResultList(
- defaults($results, 'page', 1),
- defaults($results, 'count', 0),
- defaults($results, 'itemsperpage', 30)
+ ($results['page'] ?? 0) ?: 1,
+ $results['count'] ?? 0,
+ ($results['itemsperpage'] ?? 0) ?: 30
);
- $profiles = defaults($results, 'profiles', []);
+ $profiles = $results['profiles'] ?? [];
foreach ($profiles as $profile) {
- $contactDetails = Contact::getDetailsByURL(defaults($profile, 'profile_url', ''), local_user());
- $itemUrl = defaults($contactDetails, 'addr', defaults($profile, 'profile_url', ''));
+ $profile_url = $profile['profile_url'] ?? '';
+ $contactDetails = Contact::getDetailsByURL($profile_url, local_user());
$result = new ContactResult(
- defaults($profile, 'name', ''),
- defaults($profile, 'addr', ''),
- $itemUrl,
- defaults($profile, 'profile_url', ''),
- defaults($profile, 'photo', ''),
+ $profile['name'] ?? '',
+ $profile['addr'] ?? '',
+ ($contactDetails['addr'] ?? '') ?: $profile_url,
+ $profile_url,
+ $profile['photo'] ?? '',
Protocol::DFRN,
- defaults($contactDetails, 'cid', 0),
+ $contactDetails['cid'] ?? 0,
0,
- defaults($profile, 'tags', ''));
+ $profile['tags'] ?? ''
+ );
$resultList->addResult($result);
}
'page_flags' => $user_record['page-flags'],
'my_url' => $a->getBaseURL() . '/profile/' . $user_record['nickname'],
'my_address' => $user_record['nickname'] . '@' . substr($a->getBaseURL(), strpos($a->getBaseURL(), '://') + 3),
- 'addr' => defaults($_SERVER, 'REMOTE_ADDR', '0.0.0.0')
+ 'addr' => ($_SERVER['REMOTE_ADDR'] ?? '') ?: '0.0.0.0'
]);
self::setVisitorsContacts();
public static function getByName($name)
{
self::setup();
- return defaults(self::$backends, $name, '');
+ return self::$backends[$name] ?? '';
}
/**
}
if (isset($database[$name]["table_status"]["Comment"])) {
- $structurecomment = defaults($structure, "comment", "");
+ $structurecomment = $structure["comment"] ?? '';
if ($database[$name]["table_status"]["Comment"] != $structurecomment) {
$sql2 = "COMMENT = '" . DBA::escape($structurecomment) . "'";
// Compare the field structure field by field
foreach ($structure["fields"] AS $fieldname => $parameters) {
// Compare the field definition
- $field_definition = defaults($database[$name]["fields"], $fieldname, ['Collation' => '']);
+ $field_definition = ($database[$name]["fields"][$fieldname] ?? '') ?: ['Collation' => ''];
// Define the default collation if not given
if (!isset($parameters['Collation']) && !empty($field_definition['Collation'])) {
* @todo You cannot rename a primary key if "auto increment" is set
*
* @param string $table Table name
- * @param array $columns Columns Syntax for Rename: [ $old1 => [ $new1, $type1 ], $old2 => [ $new2, $type2 ], ... ] )
- * Syntax for Primary Key: [ $col1, $col2, ...] )
+ * @param array $columns Columns Syntax for Rename: [ $old1 => [ $new1, $type1 ], $old2 => [ $new2, $type2 ], ... ]
+ * Syntax for Primary Key: [ $col1, $col2, ...]
* @param int $type The type of renaming (Default is Column)
*
* @return boolean Was the renaming successful?
use Friendica\Core\Logger;
use Friendica\Database\Database;
use Friendica\Network\HTTPException\InternalServerErrorException;
+use Friendica\Util\FileSystem;
use Friendica\Util\Introspection;
use Friendica\Util\Logger\Monolog\DevelopHandler;
use Friendica\Util\Logger\Monolog\IntrospectionProcessor;
* @param Database $database The Friendica Database instance
* @param Configuration $config The config
* @param Profiler $profiler The profiler of the app
+ * @param FileSystem $fileSystem FileSystem utils
*
* @return LoggerInterface The PSR-3 compliant logger instance
- *
- * @throws \Exception
- * @throws InternalServerErrorException
*/
- public function create( Database $database, Configuration $config, Profiler $profiler)
+ public function create(Database $database, Configuration $config, Profiler $profiler, FileSystem $fileSystem)
{
if (empty($config->get('system', 'debugging', false))) {
$logger = new VoidLogger();
// just add a stream in case it's either writable or not file
if (!is_file($stream) || is_writable($stream)) {
- static::addStreamHandler($logger, $stream, $loglevel);
+ try {
+ static::addStreamHandler($logger, $stream, $loglevel);
+ } catch (\Throwable $e) {
+ // No Logger ..
+ $logger = new VoidLogger();
+ }
}
break;
case 'syslog':
- $logger = new SyslogLogger($this->channel, $introspection, $loglevel);
+ try {
+ $logger = new SyslogLogger($this->channel, $introspection, $loglevel);
+ } catch (\Throwable $e) {
+ // No logger ...
+ $logger = new VoidLogger();
+ }
break;
case 'stream':
$stream = $config->get('system', 'logfile');
// just add a stream in case it's either writable or not file
if (!is_file($stream) || is_writable($stream)) {
- $logger = new StreamLogger($this->channel, $stream, $introspection, $loglevel);
+ try {
+ $logger = new StreamLogger($this->channel, $stream, $introspection, $fileSystem, $loglevel);
+ } catch (\Throwable $t) {
+ // No logger ...
+ $logger = new VoidLogger();
+ }
} else {
$logger = new VoidLogger();
}
*
* @param Configuration $config The config
* @param Profiler $profiler The profiler of the app
+ * @param FileSystem $fileSystem FileSystem utils
*
* @return LoggerInterface The PSR-3 compliant logger instance
*
* @throws InternalServerErrorException
* @throws \Exception
*/
- public static function createDev(Configuration $config, Profiler $profiler)
+ public static function createDev(Configuration $config, Profiler $profiler, FileSystem $fileSystem)
{
$debugging = $config->get('system', 'debugging');
$stream = $config->get('system', 'dlogfile');
case 'stream':
default:
- $logger = new StreamLogger(self::DEV_CHANNEL, $stream, $introspection, LogLevel::DEBUG);
+ $logger = new StreamLogger(self::DEV_CHANNEL, $stream, $introspection, $fileSystem, LogLevel::DEBUG);
break;
}
return LogLevel::INFO;
// legacy DATA
case "4":
- return LogLevel::DEBUG;
// legacy ALL
case "5":
return LogLevel::DEBUG;
*
* @return void
*
- * @throws InternalServerErrorException if the logger is incompatible to the logger factory
* @throws \Exception in case of general failures
*/
public static function addStreamHandler($logger, $stream, $level = LogLevel::NOTICE)
$fileHandler->setFormatter($formatter);
$logger->pushHandler($fileHandler);
- } else {
- throw new InternalServerErrorException('Logger instance incompatible for MonologFactory');
}
}
use Friendica\Core\L10n;
use Friendica\Core\Logger;
use Friendica\Core\Protocol;
-use Friendica\Core\System;
use Friendica\Core\Session;
+use Friendica\Core\System;
use Friendica\Core\Worker;
use Friendica\Database\DBA;
use Friendica\Network\Probe;
use Friendica\Object\Image;
+use Friendica\Protocol\Activity;
use Friendica\Protocol\ActivityPub;
use Friendica\Protocol\DFRN;
use Friendica\Protocol\Diaspora;
use Friendica\Protocol\OStatus;
-use Friendica\Protocol\PortableContact;
use Friendica\Protocol\Salmon;
use Friendica\Util\DateTimeFormat;
use Friendica\Util\Network;
} elseif (in_array($protocol, [Protocol::OSTATUS, Protocol::DFRN])) {
// create an unfollow slap
$item = [];
- $item['verb'] = NAMESPACE_OSTATUS . "/unfollow";
+ $item['verb'] = Activity::O_UNFOLLOW;
$item['follow'] = $contact["url"];
$item['body'] = '';
$item['title'] = '';
$profile["micro"] = $profile["thumb"];
}
- if ((empty($profile["addr"]) || empty($profile["name"])) && (defaults($profile, "gid", 0) != 0)
+ if ((empty($profile["addr"]) || empty($profile["name"])) && !empty($profile["gid"])
&& in_array($profile["network"], Protocol::FEDERATED)
) {
Worker::add(PRIORITY_LOW, "UpdateGContact", $url);
}
// Show contact details of Diaspora contacts only if connected
- if ((defaults($profile, "cid", 0) == 0) && (defaults($profile, "network", "") == Protocol::DIASPORA)) {
+ if (empty($profile["cid"]) && ($profile["network"] ?? "") == Protocol::DIASPORA) {
$profile["location"] = "";
$profile["about"] = "";
$profile["gender"] = "";
'created' => DateTimeFormat::utcNow(),
'url' => $data['url'],
'nurl' => Strings::normaliseLink($data['url']),
- 'addr' => defaults($data, 'addr', ''),
- 'alias' => defaults($data, 'alias', ''),
- 'notify' => defaults($data, 'notify', ''),
- 'poll' => defaults($data, 'poll', ''),
- 'name' => defaults($data, 'name', ''),
- 'nick' => defaults($data, 'nick', ''),
- 'photo' => defaults($data, 'photo', ''),
- 'keywords' => defaults($data, 'keywords', ''),
- 'location' => defaults($data, 'location', ''),
- 'about' => defaults($data, 'about', ''),
+ 'addr' => $data['addr'] ?? '',
+ 'alias' => $data['alias'] ?? '',
+ 'notify' => $data['notify'] ?? '',
+ 'poll' => $data['poll'] ?? '',
+ 'name' => $data['name'] ?? '',
+ 'nick' => $data['nick'] ?? '',
+ 'photo' => $data['photo'] ?? '',
+ 'keywords' => $data['keywords'] ?? '',
+ 'location' => $data['location'] ?? '',
+ 'about' => $data['about'] ?? '',
'network' => $data['network'],
- 'pubkey' => defaults($data, 'pubkey', ''),
+ 'pubkey' => $data['pubkey'] ?? '',
'rel' => self::SHARING,
- 'priority' => defaults($data, 'priority', 0),
- 'batch' => defaults($data, 'batch', ''),
- 'request' => defaults($data, 'request', ''),
- 'confirm' => defaults($data, 'confirm', ''),
- 'poco' => defaults($data, 'poco', ''),
- 'baseurl' => defaults($data, 'baseurl', ''),
+ 'priority' => $data['priority'] ?? 0,
+ 'batch' => $data['batch'] ?? '',
+ 'request' => $data['request'] ?? '',
+ 'confirm' => $data['confirm'] ?? '',
+ 'poco' => $data['poco'] ?? '',
+ 'baseurl' => $data['baseurl'] ?? '',
'name-date' => DateTimeFormat::utcNow(),
'uri-date' => DateTimeFormat::utcNow(),
'avatar-date' => DateTimeFormat::utcNow(),
$fields = ['addr', 'alias', 'name', 'nick', 'keywords', 'location', 'about', 'baseurl'];
foreach ($fields as $field) {
- $updated[$field] = defaults($data, $field, $contact[$field]);
+ $updated[$field] = ($data[$field] ?? '') ?: $contact[$field];
}
if (($updated['addr'] != $contact['addr']) || (!empty($data['alias']) && ($data['alias'] != $contact['alias']))) {
if (in_array($protocol, [Protocol::OSTATUS, Protocol::DFRN])) {
// create a follow slap
$item = [];
- $item['verb'] = ACTIVITY_FOLLOW;
+ $item['verb'] = Activity::FOLLOW;
$item['follow'] = $contact["url"];
$item['body'] = '';
$item['title'] = '';
return false;
}
- $url = defaults($datarray, 'author-link', $pub_contact['url']);
+ $url = ($datarray['author-link'] ?? '') ?: $pub_contact['url'];
$name = $pub_contact['name'];
- $photo = defaults($pub_contact, 'avatar', $pub_contact["photo"]);
+ $photo = ($pub_contact['avatar'] ?? '') ?: $pub_contact["photo"];
$nick = $pub_contact['nick'];
$network = $pub_contact['network'];
'source_name' => ((strlen(stripslashes($contact_record['name']))) ? stripslashes($contact_record['name']) : L10n::t('[Name Withheld]')),
'source_link' => $contact_record['url'],
'source_photo' => $contact_record['photo'],
- 'verb' => ($sharing ? ACTIVITY_FRIEND : ACTIVITY_FOLLOW),
+ 'verb' => ($sharing ? Activity::FRIEND : Activity::FOLLOW),
'otype' => 'intro'
]);
}
*/
public static function insert(array $arr)
{
- if (in_array(defaults($arr, 'network', Protocol::PHANTOM),
+ if (in_array(($arr['network'] ?? '') ?: Protocol::PHANTOM,
[Protocol::ACTIVITYPUB, Protocol::DFRN, Protocol::DIASPORA, Protocol::OSTATUS, Protocol::TWITTER]) && !empty($arr['uri'])) {
$conversation = ['item-uri' => $arr['uri'], 'received' => DateTimeFormat::utcNow()];
unset($old_conv['source']);
}
// Update structure data all the time but the source only when its from a better protocol.
- if (empty($conversation['source']) || (!empty($old_conv['source']) &&
- ($old_conv['protocol'] < defaults($conversation, 'protocol', self::PARCEL_UNKNOWN)))) {
+ if (
+ empty($conversation['source'])
+ || (
+ !empty($old_conv['source'])
+ && ($old_conv['protocol'] < (($conversation['protocol'] ?? '') ?: self::PARCEL_UNKNOWN))
+ )
+ ) {
unset($conversation['protocol']);
unset($conversation['source']);
}
use Friendica\Core\Renderer;
use Friendica\Core\System;
use Friendica\Database\DBA;
+use Friendica\Protocol\Activity;
use Friendica\Util\DateTimeFormat;
use Friendica\Util\Map;
use Friendica\Util\Strings;
public static function store($arr)
{
$event = [];
- $event['id'] = intval(defaults($arr, 'id' , 0));
- $event['uid'] = intval(defaults($arr, 'uid' , 0));
- $event['cid'] = intval(defaults($arr, 'cid' , 0));
- $event['guid'] = defaults($arr, 'guid' , System::createUUID());
- $event['uri'] = defaults($arr, 'uri' , Item::newURI($event['uid'], $event['guid']));
- $event['type'] = defaults($arr, 'type' , 'event');
- $event['summary'] = defaults($arr, 'summary' , '');
- $event['desc'] = defaults($arr, 'desc' , '');
- $event['location'] = defaults($arr, 'location' , '');
- $event['allow_cid'] = defaults($arr, 'allow_cid', '');
- $event['allow_gid'] = defaults($arr, 'allow_gid', '');
- $event['deny_cid'] = defaults($arr, 'deny_cid' , '');
- $event['deny_gid'] = defaults($arr, 'deny_gid' , '');
- $event['adjust'] = intval(defaults($arr, 'adjust' , 0));
- $event['nofinish'] = intval(defaults($arr, 'nofinish' , !empty($event['start']) && empty($event['finish'])));
-
- $event['created'] = DateTimeFormat::utc(defaults($arr, 'created' , 'now'));
- $event['edited'] = DateTimeFormat::utc(defaults($arr, 'edited' , 'now'));
- $event['start'] = DateTimeFormat::utc(defaults($arr, 'start' , DBA::NULL_DATETIME));
- $event['finish'] = DateTimeFormat::utc(defaults($arr, 'finish' , DBA::NULL_DATETIME));
+ $event['id'] = intval($arr['id'] ?? 0);
+ $event['uid'] = intval($arr['uid'] ?? 0);
+ $event['cid'] = intval($arr['cid'] ?? 0);
+ $event['guid'] = ($arr['guid'] ?? '') ?: System::createUUID();
+ $event['uri'] = ($arr['uri'] ?? '') ?: Item::newURI($event['uid'], $event['guid']);
+ $event['type'] = ($arr['type'] ?? '') ?: 'event';
+ $event['summary'] = $arr['summary'] ?? '';
+ $event['desc'] = $arr['desc'] ?? '';
+ $event['location'] = $arr['location'] ?? '';
+ $event['allow_cid'] = $arr['allow_cid'] ?? '';
+ $event['allow_gid'] = $arr['allow_gid'] ?? '';
+ $event['deny_cid'] = $arr['deny_cid'] ?? '';
+ $event['deny_gid'] = $arr['deny_gid'] ?? '';
+ $event['adjust'] = intval($arr['adjust'] ?? 0);
+ $event['nofinish'] = intval(!empty($arr['nofinish'] || !empty($event['start']) && empty($event['finish'])));
+
+ $event['created'] = DateTimeFormat::utc(($arr['created'] ?? '') ?: 'now');
+ $event['edited'] = DateTimeFormat::utc(($arr['edited'] ?? '') ?: 'now');
+ $event['start'] = DateTimeFormat::utc(($arr['start'] ?? '') ?: DBA::NULL_DATETIME);
+ $event['finish'] = DateTimeFormat::utc(($arr['finish'] ?? '') ?: DBA::NULL_DATETIME);
if ($event['finish'] < DBA::NULL_DATETIME) {
$event['finish'] = DBA::NULL_DATETIME;
}
- $private = intval(defaults($arr, 'private', 0));
+ $private = intval($arr['private'] ?? 0);
$conditions = ['uid' => $event['uid']];
if ($event['cid']) {
$item = Item::selectFirst(['id'], ['event-id' => $event['id'], 'uid' => $event['uid']]);
if (DBA::isResult($item)) {
- $object = '<object><type>' . XML::escape(ACTIVITY_OBJ_EVENT) . '</type><title></title><id>' . XML::escape($event['uri']) . '</id>';
+ $object = '<object><type>' . XML::escape(Activity\ObjectType::EVENT) . '</type><title></title><id>' . XML::escape($event['uri']) . '</id>';
$object .= '<content>' . XML::escape(self::getBBCode($event)) . '</content>';
$object .= '</object>' . "\n";
$item_arr['uri'] = $event['uri'];
$item_arr['parent-uri'] = $event['uri'];
$item_arr['guid'] = $event['guid'];
- $item_arr['plink'] = defaults($arr, 'plink', '');
+ $item_arr['plink'] = $arr['plink'] ?? '';
$item_arr['post-type'] = Item::PT_EVENT;
$item_arr['wall'] = $event['cid'] ? 0 : 1;
$item_arr['contact-id'] = $contact['id'];
$item_arr['deny_gid'] = $event['deny_gid'];
$item_arr['private'] = $private;
$item_arr['visible'] = 1;
- $item_arr['verb'] = ACTIVITY_POST;
- $item_arr['object-type'] = ACTIVITY_OBJ_EVENT;
+ $item_arr['verb'] = Activity::POST;
+ $item_arr['object-type'] = Activity\ObjectType::EVENT;
$item_arr['origin'] = $event['cid'] === 0 ? 1 : 0;
$item_arr['body'] = self::getBBCode($event);
$item_arr['event-id'] = $event['id'];
- $item_arr['object'] = '<object><type>' . XML::escape(ACTIVITY_OBJ_EVENT) . '</type><title></title><id>' . XML::escape($event['uri']) . '</id>';
+ $item_arr['object'] = '<object><type>' . XML::escape(Activity\ObjectType::EVENT) . '</type><title></title><id>' . XML::escape($event['uri']) . '</id>';
$item_arr['object'] .= '<content>' . XML::escape(self::getBBCode($event)) . '</content>';
$item_arr['object'] .= '</object>' . "\n";
$tpl = Renderer::getMarkupTemplate('event_stream_item.tpl');
$return = Renderer::replaceMacros($tpl, [
'$id' => $item['event-id'],
- '$title' => prepare_text($item['event-summary']),
+ '$title' => BBCode::convert($item['event-summary']),
'$dtstart_label' => L10n::t('Starts:'),
'$dtstart_title' => $dtstart_title,
'$dtstart_dt' => $dtstart_dt,
'$author_name' => $item['author-name'],
'$author_link' => $profile_link,
'$author_avatar' => $item['author-avatar'],
- '$description' => prepare_text($item['event-desc']),
+ '$description' => BBCode::convert($item['event-desc']),
'$location_label' => L10n::t('Location:'),
'$show_map_label' => L10n::t('Show map'),
'$hide_map_label' => L10n::t('Hide map'),
}
}
- $location['name'] = prepare_text($location['name']);
+ $location['name'] = BBCode::convert($location['name']);
// Construct the map HTML.
if (isset($location['address'])) {
<?php
-
/**
* @file src/Model/GlobalContact.php
* @brief This file includes the GlobalContact class with directory related functions
}
// check if we search only communities or every contact
- if ($mode === "community") {
- $extra_sql = " AND `community`";
+ if ($mode === 'community') {
+ $extra_sql = ' AND `community`';
} else {
- $extra_sql = "";
+ $extra_sql = '';
}
- $search .= "%";
+ $search .= '%';
$results = DBA::p("SELECT `nurl` FROM `gcontact`
WHERE NOT `hide` AND `network` IN (?, ?, ?, ?) AND
$gcontacts = [];
while ($result = DBA::fetch($results)) {
- $urlparts = parse_url($result["nurl"]);
+ $urlparts = parse_url($result['nurl']);
// Ignore results that look strange.
// For historic reasons the gcontact table does contain some garbage.
continue;
}
- $gcontacts[] = Contact::getDetailsByURL($result["nurl"], local_user());
+ $gcontacts[] = Contact::getDetailsByURL($result['nurl'], local_user());
}
return $gcontacts;
}
*/
public static function sanitize($gcontact)
{
- if ($gcontact['url'] == "") {
+ if (empty($gcontact['url'])) {
throw new Exception('URL is empty');
}
+ $gcontact['server_url'] = $gcontact['server_url'] ?? '';
+
$urlparts = parse_url($gcontact['url']);
- if (!isset($urlparts["scheme"])) {
- throw new Exception("This (".$gcontact['url'].") doesn't seem to be an url.");
+ if (empty($urlparts['scheme'])) {
+ throw new Exception('This (' . $gcontact['url'] . ") doesn't seem to be an url.");
}
- if (in_array($urlparts["host"], ["twitter.com", "identi.ca"])) {
- throw new Exception('Contact from a non federated network ignored. ('.$gcontact['url'].')');
+ if (in_array($urlparts['host'], ['twitter.com', 'identi.ca'])) {
+ throw new Exception('Contact from a non federated network ignored. (' . $gcontact['url'] . ')');
}
// Don't store the statusnet connector as network
// We can't simply set this to Protocol::OSTATUS since the connector could have fetched posts from friendica as well
if ($gcontact['network'] == Protocol::STATUSNET) {
- $gcontact['network'] = "";
+ $gcontact['network'] = '';
}
// Assure that there are no parameter fragments in the profile url
- if (empty($gcontact["network"]) || in_array($gcontact["network"], Protocol::FEDERATED)) {
+ if (empty($gcontact['*network']) || in_array($gcontact['network'], Protocol::FEDERATED)) {
$gcontact['url'] = self::cleanContactUrl($gcontact['url']);
}
- $alternate = PortableContact::alternateOStatusUrl($gcontact['url']);
-
// The global contacts should contain the original picture, not the cached one
- if (($gcontact['generation'] != 1) && stristr(Strings::normaliseLink($gcontact['photo']), Strings::normaliseLink(System::baseUrl()."/photo/"))) {
- $gcontact['photo'] = "";
+ if (($gcontact['generation'] != 1) && stristr(Strings::normaliseLink($gcontact['photo']), Strings::normaliseLink(System::baseUrl() . '/photo/'))) {
+ $gcontact['photo'] = '';
}
- if (!isset($gcontact['network'])) {
+ if (empty($gcontact['network'])) {
+ $gcontact['network'] = '';
+
$condition = ["`uid` = 0 AND `nurl` = ? AND `network` != '' AND `network` != ?",
Strings::normaliseLink($gcontact['url']), Protocol::STATUSNET];
$contact = DBA::selectFirst('contact', ['network'], $condition);
if (DBA::isResult($contact)) {
- $gcontact['network'] = $contact["network"];
+ $gcontact['network'] = $contact['network'];
}
- if (($gcontact['network'] == "") || ($gcontact['network'] == Protocol::OSTATUS)) {
+ if (($gcontact['network'] == '') || ($gcontact['network'] == Protocol::OSTATUS)) {
$condition = ["`uid` = 0 AND `alias` IN (?, ?) AND `network` != '' AND `network` != ?",
$gcontact['url'], Strings::normaliseLink($gcontact['url']), Protocol::STATUSNET];
$contact = DBA::selectFirst('contact', ['network'], $condition);
if (DBA::isResult($contact)) {
- $gcontact['network'] = $contact["network"];
+ $gcontact['network'] = $contact['network'];
}
}
}
- $gcontact['server_url'] = '';
- $gcontact['network'] = '';
-
$fields = ['network', 'updated', 'server_url', 'url', 'addr'];
$gcnt = DBA::selectFirst('gcontact', $fields, ['nurl' => Strings::normaliseLink($gcontact['url'])]);
if (DBA::isResult($gcnt)) {
- if (!isset($gcontact['network']) && ($gcnt["network"] != Protocol::STATUSNET)) {
- $gcontact['network'] = $gcnt["network"];
+ if (!isset($gcontact['network']) && ($gcnt['network'] != Protocol::STATUSNET)) {
+ $gcontact['network'] = $gcnt['network'];
}
if ($gcontact['updated'] <= DBA::NULL_DATETIME) {
- $gcontact['updated'] = $gcnt["updated"];
+ $gcontact['updated'] = $gcnt['updated'];
}
- if (!isset($gcontact['server_url']) && (Strings::normaliseLink($gcnt["server_url"]) != Strings::normaliseLink($gcnt["url"]))) {
- $gcontact['server_url'] = $gcnt["server_url"];
+ if (!isset($gcontact['server_url']) && (Strings::normaliseLink($gcnt['server_url']) != Strings::normaliseLink($gcnt['url']))) {
+ $gcontact['server_url'] = $gcnt['server_url'];
}
if (!isset($gcontact['addr'])) {
- $gcontact['addr'] = $gcnt["addr"];
+ $gcontact['addr'] = $gcnt['addr'];
}
}
- if ((!isset($gcontact['network']) || !isset($gcontact['name']) || !isset($gcontact['addr']) || !isset($gcontact['photo']) || !isset($gcontact['server_url']) || $alternate)
+ if ((!isset($gcontact['network']) || !isset($gcontact['name']) || !isset($gcontact['addr']) || !isset($gcontact['photo']) || !isset($gcontact['server_url']))
&& GServer::reachable($gcontact['url'], $gcontact['server_url'], $gcontact['network'], false)
) {
$data = Probe::uri($gcontact['url']);
- if ($data["network"] == Protocol::PHANTOM) {
- throw new Exception('Probing for URL '.$gcontact['url'].' failed');
+ if ($data['network'] == Protocol::PHANTOM) {
+ throw new Exception('Probing for URL ' . $gcontact['url'] . ' failed');
}
$orig_profile = $gcontact['url'];
- $gcontact["server_url"] = $data["baseurl"];
+ $gcontact['server_url'] = $data['baseurl'];
$gcontact = array_merge($gcontact, $data);
-
- if ($alternate && ($gcontact['network'] == Protocol::OSTATUS)) {
- // Delete the old entry - if it exists
- if (DBA::exists('gcontact', ['nurl' => Strings::normaliseLink($orig_profile)])) {
- DBA::delete('gcontact', ['nurl' => Strings::normaliseLink($orig_profile)]);
- }
- }
}
if (!isset($gcontact['name']) || !isset($gcontact['photo'])) {
}
if (!in_array($gcontact['network'], Protocol::FEDERATED)) {
- throw new Exception('No federated network ('.$gcontact['network'].') detected for URL '.$gcontact['url']);
+ throw new Exception('No federated network (' . $gcontact['network'] . ') detected for URL ' . $gcontact['url']);
}
- if (!isset($gcontact['server_url'])) {
+ if (empty($gcontact['server_url'])) {
// We check the server url to be sure that it is a real one
$server_url = Contact::getBasepath($gcontact['url']);
// We are now sure that it is a correct URL. So we use it in the future
- if ($server_url != "") {
+ if ($server_url != '') {
$gcontact['server_url'] = $server_url;
}
}
// The server URL doesn't seem to be valid, so we don't store it.
if (!GServer::check($gcontact['server_url'], $gcontact['network'])) {
- $gcontact['server_url'] = "";
+ $gcontact['server_url'] = '';
}
return $gcontact;
WHERE `glink`.`cid` = %d AND `glink`.`uid` = %d AND
((`gcontact`.`last_contact` >= `gcontact`.`last_failure`) OR
(`gcontact`.`updated` >= `gcontact`.`last_failure`))
- AND `gcontact`.`nurl` IN (select nurl from contact where uid = %d and self = 0 and blocked = 0 and hidden = 0 and id != %d ) ",
+ AND `gcontact`.`nurl` IN (select nurl from contact where uid = %d and self = 0 and blocked = 0 and hidden = 0 and id != %d) ",
intval($cid),
intval($uid),
intval($uid),
intval($cid)
);
- // Logger::log("countCommonFriends: $uid $cid {$r[0]['total']}");
if (DBA::isResult($r)) {
return $r[0]['total'];
}
"SELECT count(*) as `total`
FROM `glink` INNER JOIN `gcontact` on `glink`.`gcid` = `gcontact`.`id`
where `glink`.`zcid` = %d
- and `gcontact`.`nurl` in (select nurl from contact where uid = %d and self = 0 and blocked = 0 and hidden = 0 ) ",
+ and `gcontact`.`nurl` in (select nurl from contact where uid = %d and self = 0 and blocked = 0 and hidden = 0) ",
intval($zcid),
intval($uid)
);
"SELECT `gcontact`.*
FROM `glink` INNER JOIN `gcontact` on `glink`.`gcid` = `gcontact`.`id`
where `glink`.`zcid` = %d
- and `gcontact`.`nurl` in (select nurl from contact where uid = %d and self = 0 and blocked = 0 and hidden = 0 )
+ and `gcontact`.`nurl` in (select nurl from contact where uid = %d and self = 0 and blocked = 0 and hidden = 0)
$sql_extra limit %d, %d",
intval($zcid),
intval($uid),
return [];
}
- /*
- * Uncommented because the result of the queries are to big to store it in the cache.
- * We need to decide if we want to change the db column type or if we want to delete it.
- */
- //$list = Cache::get("suggestion_query:".$uid.":".$start.":".$limit);
- //if (!is_null($list)) {
- // return $list;
- //}
-
$network = [Protocol::DFRN, Protocol::ACTIVITYPUB];
if (Config::get('system', 'diaspora_enabled')) {
$network[] = Protocol::OSTATUS;
}
- $sql_network = implode("', '", $network);
- $sql_network = "'".$sql_network."'";
+ $sql_network = "'" . implode("', '", $network) . "'";
/// @todo This query is really slow
// By now we cache the data for five minutes
);
if (DBA::isResult($r) && count($r) >= ($limit -1)) {
- /*
- * Uncommented because the result of the queries are to big to store it in the cache.
- * We need to decide if we want to change the db column type or if we want to delete it.
- */
- //Cache::set("suggestion_query:".$uid.":".$start.":".$limit, $r, Cache::FIVE_MINUTES);
-
return $r;
}
$list = [];
foreach ($r2 as $suggestion) {
- $list[$suggestion["nurl"]] = $suggestion;
+ $list[$suggestion['nurl']] = $suggestion;
}
foreach ($r as $suggestion) {
- $list[$suggestion["nurl"]] = $suggestion;
+ $list[$suggestion['nurl']] = $suggestion;
}
while (sizeof($list) > ($limit)) {
array_pop($list);
}
- /*
- * Uncommented because the result of the queries are to big to store it in the cache.
- * We need to decide if we want to change the db column type or if we want to delete it.
- */
- //Cache::set("suggestion_query:".$uid.":".$start.":".$limit, $list, Cache::FIVE_MINUTES);
return $list;
}
$done[] = System::baseUrl() . '/poco';
if (strlen(Config::get('system', 'directory'))) {
- $x = Network::fetchUrl(get_server()."/pubsites");
+ $x = Network::fetchUrl(get_server() . '/pubsites');
if (!empty($x)) {
$j = json_decode($x);
if (!empty($j->entries)) {
}
// Query your contacts from Friendica and Redmatrix/Hubzilla for their contacts
- $r = q(
- "SELECT DISTINCT(`poco`) AS `poco` FROM `contact` WHERE `network` IN ('%s', '%s')",
- DBA::escape(Protocol::DFRN),
- DBA::escape(Protocol::DIASPORA)
- );
-
- if (DBA::isResult($r)) {
- foreach ($r as $rr) {
- $base = substr($rr['poco'], 0, strrpos($rr['poco'], '/'));
- if (! in_array($base, $done)) {
- PortableContact::loadWorker(0, 0, 0, $base);
- }
+ $contacts = DBA::p("SELECT DISTINCT(`poco`) AS `poco` FROM `contact` WHERE `network` IN (?, ?)", Protocol::DFRN, Protocol::DIASPORA);
+ while ($contact = DBA::fetch($contacts)) {
+ $base = substr($contact['poco'], 0, strrpos($contact['poco'], '/'));
+ if (!in_array($base, $done)) {
+ PortableContact::loadWorker(0, 0, 0, $base);
}
}
}
{
$parts = parse_url($url);
- if (!isset($parts["scheme"]) || !isset($parts["host"])) {
+ if (empty($parts['scheme']) || empty($parts['host'])) {
return $url;
}
- $new_url = $parts["scheme"]."://".$parts["host"];
+ $new_url = $parts['scheme'] . '://' . $parts['host'];
- if (isset($parts["port"])) {
- $new_url .= ":".$parts["port"];
+ if (!empty($parts['port'])) {
+ $new_url .= ':' . $parts['port'];
}
- if (isset($parts["path"])) {
- $new_url .= $parts["path"];
+ if (!empty($parts['path'])) {
+ $new_url .= $parts['path'];
}
if ($new_url != $url) {
- Logger::log("Cleaned contact url ".$url." to ".$new_url." - Called by: ".System::callstack(), Logger::DEBUG);
+ Logger::info('Cleaned contact url', ['url' => $url, 'new_url' => $new_url, 'callstack' => System::callstack()]);
}
return $new_url;
}
- /**
- * @brief Replace alternate OStatus user format with the primary one
- *
- * @param array $contact contact array (called by reference)
- * @return void
- * @throws \Friendica\Network\HTTPException\InternalServerErrorException
- * @throws \ImagickException
- */
- public static function fixAlternateContactAddress(&$contact)
- {
- if (($contact["network"] == Protocol::OSTATUS) && PortableContact::alternateOStatusUrl($contact["url"])) {
- $data = Probe::uri($contact["url"]);
- if ($contact["network"] == Protocol::OSTATUS) {
- Logger::log("Fix primary url from ".$contact["url"]." to ".$data["url"]." - Called by: ".System::callstack(), Logger::DEBUG);
- $contact["url"] = $data["url"];
- $contact["addr"] = $data["addr"];
- $contact["alias"] = $data["alias"];
- $contact["server_url"] = $data["baseurl"];
- }
- }
- }
-
/**
* @brief Fetch the gcontact id, add an entry if not existed
*
$last_failure_str = '';
$last_contact_str = '';
- if (empty($contact["network"])) {
- Logger::log("Empty network for contact url ".$contact["url"]." - Called by: ".System::callstack(), Logger::DEBUG);
+ if (empty($contact['network'])) {
+ Logger::notice('Empty network', ['url' => $contact['url'], 'callstack' => System::callstack()]);
return false;
}
- if (in_array($contact["network"], [Protocol::PHANTOM])) {
- Logger::log("Invalid network for contact url ".$contact["url"]." - Called by: ".System::callstack(), Logger::DEBUG);
+ if (in_array($contact['network'], [Protocol::PHANTOM])) {
+ Logger::notice('Invalid network', ['url' => $contact['url'], 'callstack' => System::callstack()]);
return false;
}
- if ($contact["network"] == Protocol::STATUSNET) {
- $contact["network"] = Protocol::OSTATUS;
+ if ($contact['network'] == Protocol::STATUSNET) {
+ $contact['network'] = Protocol::OSTATUS;
}
// All new contacts are hidden by default
- if (!isset($contact["hide"])) {
- $contact["hide"] = true;
+ if (!isset($contact['hide'])) {
+ $contact['hide'] = true;
}
- // Replace alternate OStatus user format with the primary one
- self::fixAlternateContactAddress($contact);
-
- // Remove unwanted parts from the contact url (e.g. "?zrl=...")
- if (in_array($contact["network"], Protocol::FEDERATED)) {
- $contact["url"] = self::cleanContactUrl($contact["url"]);
+ // Remove unwanted parts from the contact url (e.g. '?zrl=...')
+ if (in_array($contact['network'], Protocol::FEDERATED)) {
+ $contact['url'] = self::cleanContactUrl($contact['url']);
}
DBA::lock('gcontact');
$fields = ['id', 'last_contact', 'last_failure', 'network'];
- $gcnt = DBA::selectFirst('gcontact', $fields, ['nurl' => Strings::normaliseLink($contact["url"])]);
+ $gcnt = DBA::selectFirst('gcontact', $fields, ['nurl' => Strings::normaliseLink($contact['url'])]);
if (DBA::isResult($gcnt)) {
- $gcontact_id = $gcnt["id"];
+ $gcontact_id = $gcnt['id'];
// Update every 90 days
- if (in_array($gcnt["network"], [Protocol::DFRN, Protocol::DIASPORA, Protocol::OSTATUS, ""])) {
- $last_failure_str = $gcnt["last_failure"];
- $last_failure = strtotime($gcnt["last_failure"]);
- $last_contact_str = $gcnt["last_contact"];
- $last_contact = strtotime($gcnt["last_contact"]);
+ if (empty($gcnt['network']) || in_array($gcnt['network'], Protocol::FEDERATED)) {
+ $last_failure_str = $gcnt['last_failure'];
+ $last_failure = strtotime($gcnt['last_failure']);
+ $last_contact_str = $gcnt['last_contact'];
+ $last_contact = strtotime($gcnt['last_contact']);
$doprobing = (((time() - $last_contact) > (90 * 86400)) && ((time() - $last_failure) > (90 * 86400)));
}
} else {
- $contact['location'] = defaults($contact, 'location', '');
- $contact['about'] = defaults($contact, 'about', '');
- $contact['generation'] = defaults($contact, 'generation', 0);
-
- q(
- "INSERT INTO `gcontact` (`name`, `nick`, `addr` , `network`, `url`, `nurl`, `photo`, `created`, `updated`, `location`, `about`, `hide`, `generation`)
- VALUES ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d)",
- DBA::escape($contact["name"]),
- DBA::escape($contact["nick"]),
- DBA::escape($contact["addr"]),
- DBA::escape($contact["network"]),
- DBA::escape($contact["url"]),
- DBA::escape(Strings::normaliseLink($contact["url"])),
- DBA::escape($contact["photo"]),
- DBA::escape(DateTimeFormat::utcNow()),
- DBA::escape(DateTimeFormat::utcNow()),
- DBA::escape($contact["location"]),
- DBA::escape($contact["about"]),
- intval($contact["hide"]),
- intval($contact["generation"])
- );
-
- $condition = ['nurl' => Strings::normaliseLink($contact["url"])];
+ $contact['location'] = $contact['location'] ?? '';
+ $contact['about'] = $contact['about'] ?? '';
+ $contact['generation'] = $contact['generation'] ?? 0;
+
+ $fields = ['name' => $contact['name'], 'nick' => $contact['nick'], 'addr' => $contact['addr'], 'network' => $contact['network'],
+ 'url' => $contact['url'], 'nurl' => Strings::normaliseLink($contact['url']), 'photo' => $contact['photo'],
+ 'created' => DateTimeFormat::utcNow(), 'updated' => DateTimeFormat::utcNow(), 'location' => $contact['location'],
+ 'about' => $contact['about'], 'hide' => $contact['hide'], 'generation' => $contact['generation']];
+ DBA::insert('gcontact', $fields);
+
+ $condition = ['nurl' => Strings::normaliseLink($contact['url'])];
$cnt = DBA::selectFirst('gcontact', ['id', 'network'], $condition, ['order' => ['id']]);
if (DBA::isResult($cnt)) {
- $gcontact_id = $cnt["id"];
- $doprobing = in_array($cnt["network"], [Protocol::DFRN, Protocol::DIASPORA, Protocol::OSTATUS, ""]);
+ $gcontact_id = $cnt['id'];
+ $doprobing = (empty($cnt['network']) || in_array($cnt['network'], Protocol::FEDERATED));
}
}
DBA::unlock();
if ($doprobing) {
- Logger::log("Last Contact: ". $last_contact_str." - Last Failure: ".$last_failure_str." - Checking: ".$contact["url"], Logger::DEBUG);
- Worker::add(PRIORITY_LOW, 'GProbe', $contact["url"]);
+ Logger::notice('Probing', ['contact' => $last_contact_str, "failure" => $last_failure_str, "checking" => $contact['url']]);
+ Worker::add(PRIORITY_LOW, 'GProbe', $contact['url']);
}
return $gcontact_id;
$contact['network'] = Protocol::OSTATUS;
}
- // Replace alternate OStatus user format with the primary one
- self::fixAlternateContactAddress($contact);
-
if (!isset($contact['updated'])) {
$contact['updated'] = DateTimeFormat::utcNow();
}
if ((($contact['generation'] > 0) && ($contact['generation'] <= $public_contact['generation'])) || ($public_contact['generation'] == 0)) {
foreach ($fields as $field => $data) {
if ($contact[$field] != $public_contact[$field]) {
- Logger::debug('Difference found.', ['contact' => $contact["url"], 'field' => $field, 'new' => $contact[$field], 'old' => $public_contact[$field]]);
+ Logger::debug('Difference found.', ['contact' => $contact['url'], 'field' => $field, 'new' => $contact[$field], 'old' => $public_contact[$field]]);
$update = true;
}
}
if ($contact['generation'] < $public_contact['generation']) {
- Logger::debug('Difference found.', ['contact' => $contact["url"], 'field' => 'generation', 'new' => $contact['generation'], 'old' => $public_contact['generation']]);
+ Logger::debug('Difference found.', ['contact' => $contact['url'], 'field' => 'generation', 'new' => $contact['generation'], 'old' => $public_contact['generation']]);
$update = true;
}
}
if ($update) {
Logger::debug('Update gcontact.', ['contact' => $contact['url']]);
- $condition = ['`nurl` = ? AND (`generation` = 0 OR `generation` >= ?)',
- Strings::normaliseLink($contact["url"]), $contact["generation"]];
- $contact["updated"] = DateTimeFormat::utc($contact["updated"]);
+ $condition = ["`nurl` = ? AND (`generation` = 0 OR `generation` >= ?)",
+ Strings::normaliseLink($contact['url']), $contact['generation']];
+ $contact['updated'] = DateTimeFormat::utc($contact['updated']);
$updated = [
'photo' => $contact['photo'], 'name' => $contact['name'],
return;
}
- // When the profile doesn't have got a feed, then we exit here
- if (empty($data['poll'])) {
- return;
- }
-
- if ($data['network'] == Protocol::ACTIVITYPUB) {
+ if (!empty($data['outbox'])) {
+ self::updateFromOutbox($data['outbox'], $data);
+ } elseif (!empty($data['poll']) && ($data['network'] == Protocol::ACTIVITYPUB)) {
self::updateFromOutbox($data['poll'], $data);
- } else {
+ } elseif (!empty($data['poll'])) {
self::updateFromFeed($data);
}
}
if ($curlResult->isSuccess() && !empty($curlResult->getBody())) {
$noscrape = json_decode($curlResult->getBody(), true);
- if (!empty($noscrape)) {
+ if (!empty($noscrape) && !empty($noscrape['updated'])) {
$noscrape['updated'] = DateTimeFormat::utc($noscrape['updated'], DateTimeFormat::MYSQL);
$fields = ['last_contact' => DateTimeFormat::utcNow(), 'updated' => $noscrape['updated']];
DBA::update('gcontact', $fields, ['nurl' => Strings::normaliseLink($data['url'])]);
/**
* Update a global contact via an ActivityPub Outbox
*
- * @param string $data Probing result
+ * @param string $feed
+ * @param array $data Probing result
+ * @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
private static function updateFromOutbox(string $feed, array $data)
{
$items = $outbox['orderedItems'];
} elseif (!empty($outbox['first']['orderedItems'])) {
$items = $outbox['first']['orderedItems'];
+ } elseif (!empty($outbox['first']['href'])) {
+ self::updateFromOutbox($outbox['first']['href'], $data);
+ return;
} elseif (!empty($outbox['first'])) {
self::updateFromOutbox($outbox['first'], $data);
return;
}
$last_updated = '';
-
foreach ($items as $activity) {
- if ($last_updated < $activity['published']) {
- $last_updated = $activity['published'];
+ if (!empty($activity['published'])) {
+ $published = DateTimeFormat::utc($activity['published']);
+ } elseif (!empty($activity['object']['published'])) {
+ $published = DateTimeFormat::utc($activity['object']['published']);
+ } else {
+ continue;
+ }
+
+ if ($last_updated < $published) {
+ $last_updated = $published;
}
}
{
$data = Probe::uri($url, $force);
- if (in_array($data["network"], [Protocol::PHANTOM])) {
+ if (in_array($data['network'], [Protocol::PHANTOM])) {
$fields = ['last_failure' => DateTimeFormat::utcNow()];
DBA::update('gcontact', $fields, ['nurl' => Strings::normaliseLink($url)]);
Logger::info('Invalid network for contact', ['url' => $data['url'], 'callstack' => System::callstack()]);
return false;
}
- $data["server_url"] = $data["baseurl"];
+ $data['server_url'] = $data['baseurl'];
self::update($data);
*/
public static function updateForUser($uid)
{
- $r = q(
- "SELECT `profile`.`locality`, `profile`.`region`, `profile`.`country-name`,
- `profile`.`name`, `profile`.`about`, `profile`.`gender`,
- `profile`.`pub_keywords`, `profile`.`dob`, `profile`.`photo`,
- `profile`.`net-publish`, `user`.`nickname`, `user`.`hidewall`,
- `contact`.`notify`, `contact`.`url`, `contact`.`addr`
- FROM `profile`
- INNER JOIN `user` ON `user`.`uid` = `profile`.`uid`
- INNER JOIN `contact` ON `contact`.`uid` = `profile`.`uid`
- WHERE `profile`.`uid` = %d AND `profile`.`is-default` AND `contact`.`self`",
- intval($uid)
- );
+ $profile = Profile::getByUID($uid);
+ if (empty($profile)) {
+ Logger::error('Cannot find profile', ['uid' => $uid]);
+ return false;
+ }
- if (!DBA::isResult($r)) {
- Logger::log('Cannot find user with uid=' . $uid, Logger::INFO);
+ $user = User::getOwnerDataById($uid);
+ if (empty($user)) {
+ Logger::error('Cannot find user', ['uid' => $uid]);
return false;
}
+ $userdata = array_merge($profile, $user);
+
$location = Profile::formatLocation(
- ["locality" => $r[0]["locality"], "region" => $r[0]["region"], "country-name" => $r[0]["country-name"]]
+ ['locality' => $userdata['locality'], 'region' => $userdata['region'], 'country-name' => $userdata['country-name']]
);
- // The "addr" field was added in 3.4.3 so it can be empty for older users
- if ($r[0]["addr"] != "") {
- $addr = $r[0]["nickname"].'@'.str_replace(["http://", "https://"], "", System::baseUrl());
- } else {
- $addr = $r[0]["addr"];
- }
-
- $gcontact = ["name" => $r[0]["name"], "location" => $location, "about" => $r[0]["about"],
- "gender" => $r[0]["gender"], "keywords" => $r[0]["pub_keywords"],
- "birthday" => $r[0]["dob"], "photo" => $r[0]["photo"],
- "notify" => $r[0]["notify"], "url" => $r[0]["url"],
- "hide" => ($r[0]["hidewall"] || !$r[0]["net-publish"]),
- "nick" => $r[0]["nickname"], "addr" => $addr,
- "connect" => $addr, "server_url" => System::baseUrl(),
- "generation" => 1, "network" => Protocol::DFRN];
+ $gcontact = ['name' => $userdata['name'], 'location' => $location, 'about' => $userdata['about'],
+ 'gender' => $userdata['gender'], 'keywords' => $userdata['pub_keywords'],
+ 'birthday' => $userdata['dob'], 'photo' => $userdata['photo'],
+ "notify" => $userdata['notify'], 'url' => $userdata['url'],
+ "hide" => ($userdata['hidewall'] || !$userdata['net-publish']),
+ 'nick' => $userdata['nickname'], 'addr' => $userdata['addr'],
+ "connect" => $userdata['addr'], "server_url" => System::baseUrl(),
+ "generation" => 1, 'network' => Protocol::DFRN];
self::update($gcontact);
}
*/
public static function fetchGsUsers($server)
{
- Logger::log("Fetching users from GNU Social server ".$server, Logger::DEBUG);
+ Logger::info('Fetching users from GNU Social server', ['server' => $server]);
- $url = $server."/main/statistics";
+ $url = $server . '/main/statistics';
$curlResult = Network::curl($url);
if (!$curlResult->isSuccess()) {
if (!empty($statistics->config->instance_address)) {
if (!empty($statistics->config->instance_with_ssl)) {
- $server = "https://";
+ $server = 'https://';
} else {
- $server = "http://";
+ $server = 'http://';
}
$server .= $statistics->config->instance_address;
$hostname = $statistics->config->instance_address;
} elseif (!empty($statistics->instance_address)) {
if (!empty($statistics->instance_with_ssl)) {
- $server = "https://";
+ $server = 'https://';
} else {
- $server = "http://";
+ $server = 'http://';
}
$server .= $statistics->instance_address;
if (!empty($statistics->users)) {
foreach ($statistics->users as $nick => $user) {
- $profile_url = $server."/".$user->nickname;
+ $profile_url = $server . '/' . $user->nickname;
- $contact = ["url" => $profile_url,
- "name" => $user->fullname,
- "addr" => $user->nickname."@".$hostname,
- "nick" => $user->nickname,
+ $contact = ['url' => $profile_url,
+ 'name' => $user->fullname,
+ 'addr' => $user->nickname . '@' . $hostname,
+ 'nick' => $user->nickname,
"network" => Protocol::OSTATUS,
- "photo" => System::baseUrl()."/images/person-300.jpg"];
+ 'photo' => System::baseUrl() . '/images/person-300.jpg'];
if (isset($user->bio)) {
- $contact["about"] = $user->bio;
+ $contact['about'] = $user->bio;
}
self::getId($contact);
*/
public static function discoverGsUsers()
{
- $requery_days = intval(Config::get("system", "poco_requery_days"));
+ $requery_days = intval(Config::get('system', 'poco_requery_days'));
$last_update = date("c", time() - (60 * 60 * 24 * $requery_days));
}
foreach ($r as $server) {
- self::fetchGsUsers($server["url"]);
- q("UPDATE `gserver` SET `last_poco_query` = '%s' WHERE `nurl` = '%s'", DBA::escape(DateTimeFormat::utcNow()), DBA::escape($server["nurl"]));
+ self::fetchGsUsers($server['url']);
+ DBA::update('gserver', ['last_poco_query' => DateTimeFormat::utcNow()], ['nurl' => $server['nurl']]);
}
}
if (!empty($data['version'])) {
$serverdata['platform'] = 'mastodon';
- $serverdata['version'] = defaults($data, 'version', '');
+ $serverdata['version'] = $data['version'] ?? '';
$serverdata['network'] = Protocol::ACTIVITYPUB;
}
$serverdata['info'] = trim($data['info']);
}
- $register_policy = defaults($data, 'register_policy', 'REGISTER_CLOSED');
+ $register_policy = ($data['register_policy'] ?? '') ?: 'REGISTER_CLOSED';
switch ($register_policy) {
case 'REGISTER_OPEN':
$serverdata['register_policy'] = Register::OPEN;
break;
}
- $serverdata['platform'] = defaults($data, 'platform', '');
+ $serverdata['platform'] = $data['platform'] ?? '';
return $serverdata;
}
use Friendica\Core\PConfig;
use Friendica\Core\Protocol;
use Friendica\Core\Renderer;
-use Friendica\Core\System;
use Friendica\Core\Session;
+use Friendica\Core\System;
use Friendica\Core\Worker;
use Friendica\Database\DBA;
+use Friendica\Protocol\Activity;
use Friendica\Protocol\ActivityPub;
use Friendica\Protocol\Diaspora;
use Friendica\Protocol\OStatus;
+use Friendica\Util\ACLFormatter;
use Friendica\Util\DateTimeFormat;
use Friendica\Util\Map;
use Friendica\Util\Network;
// Never reorder or remove entries from this list. Just add new ones at the end, if needed.
// The item-activity table only stores the index and needs this array to know the matching activity.
- const ACTIVITIES = [ACTIVITY_LIKE, ACTIVITY_DISLIKE, ACTIVITY_ATTEND, ACTIVITY_ATTENDNO, ACTIVITY_ATTENDMAYBE, ACTIVITY_FOLLOW, ACTIVITY2_ANNOUNCE];
+ const ACTIVITIES = [
+ Activity::LIKE, Activity::DISLIKE,
+ Activity::ATTEND, Activity::ATTENDNO, Activity::ATTENDMAYBE,
+ Activity::FOLLOW,
+ Activity::ANNOUNCE];
private static $legacy_mode = null;
$row['object'] = '';
}
if (array_key_exists('object-type', $row)) {
- $row['object-type'] = ACTIVITY_OBJ_NOTE;
+ $row['object-type'] = Activity\ObjectType::NOTE;
}
- } elseif (array_key_exists('verb', $row) && in_array($row['verb'], ['', ACTIVITY_POST, ACTIVITY_SHARE])) {
+ } elseif (array_key_exists('verb', $row) && in_array($row['verb'], ['', Activity::POST, Activity::SHARE])) {
// Posts don't have an object or target - but having tags or files.
// We safe some performance by building tag and file strings only here.
// We remove object and target since they aren't used for this type.
}
}
- if (!array_key_exists('verb', $row) || in_array($row['verb'], ['', ACTIVITY_POST, ACTIVITY_SHARE])) {
+ if (!array_key_exists('verb', $row) || in_array($row['verb'], ['', Activity::POST, Activity::SHARE])) {
// Build the tag string out of the term entries
if (array_key_exists('tag', $row) && empty($row['tag'])) {
$row['tag'] = Term::tagTextFromItemId($row['internal-iid']);
private static function deleteTagsFromItem($item)
{
- if (($item["verb"] != ACTIVITY_TAG) || ($item["object-type"] != ACTIVITY_OBJ_TAGTERM)) {
+ if (($item["verb"] != Activity::TAG) || ($item["object-type"] != Activity\ObjectType::TAGTERM)) {
return;
}
$xo = XML::parseString($item["object"], false);
$xt = XML::parseString($item["target"], false);
- if ($xt->type != ACTIVITY_OBJ_NOTE) {
+ if ($xt->type != Activity\ObjectType::NOTE) {
return;
}
$priority = $notify;
}
} else {
- $item['network'] = trim(defaults($item, 'network', Protocol::PHANTOM));
+ $item['network'] = trim(($item['network'] ?? '') ?: Protocol::PHANTOM);
}
$item['guid'] = self::guid($item, $notify);
- $item['uri'] = Strings::escapeTags(trim(defaults($item, 'uri', self::newURI($item['uid'], $item['guid']))));
+ $item['uri'] = Strings::escapeTags(trim(($item['uri'] ?? '') ?: self::newURI($item['uid'], $item['guid'])));
// Store URI data
$item['uri-id'] = ItemURI::insert(['uri' => $item['uri'], 'guid' => $item['guid']]);
$item['parent-uri'] = $item['thr-parent'];
}
+ /** @var Activity $activity */
+ $activity = self::getClass(Activity::class);
+
if (isset($item['gravity'])) {
$item['gravity'] = intval($item['gravity']);
} elseif ($item['parent-uri'] === $item['uri']) {
$item['gravity'] = GRAVITY_PARENT;
- } elseif (activity_match($item['verb'], ACTIVITY_POST)) {
+ } elseif ($activity->match($item['verb'], Activity::POST)) {
$item['gravity'] = GRAVITY_COMMENT;
- } elseif (activity_match($item['verb'], ACTIVITY_FOLLOW)) {
+ } elseif ($activity->match($item['verb'], Activity::FOLLOW)) {
$item['gravity'] = GRAVITY_ACTIVITY;
} else {
$item['gravity'] = GRAVITY_UNKNOWN; // Should not happen
}
}
- $item['wall'] = intval(defaults($item, 'wall', 0));
- $item['extid'] = trim(defaults($item, 'extid', ''));
- $item['author-name'] = trim(defaults($item, 'author-name', ''));
- $item['author-link'] = trim(defaults($item, 'author-link', ''));
- $item['author-avatar'] = trim(defaults($item, 'author-avatar', ''));
- $item['owner-name'] = trim(defaults($item, 'owner-name', ''));
- $item['owner-link'] = trim(defaults($item, 'owner-link', ''));
- $item['owner-avatar'] = trim(defaults($item, 'owner-avatar', ''));
+ $item['wall'] = intval($item['wall'] ?? 0);
+ $item['extid'] = trim($item['extid'] ?? '');
+ $item['author-name'] = trim($item['author-name'] ?? '');
+ $item['author-link'] = trim($item['author-link'] ?? '');
+ $item['author-avatar'] = trim($item['author-avatar'] ?? '');
+ $item['owner-name'] = trim($item['owner-name'] ?? '');
+ $item['owner-link'] = trim($item['owner-link'] ?? '');
+ $item['owner-avatar'] = trim($item['owner-avatar'] ?? '');
$item['received'] = (isset($item['received']) ? DateTimeFormat::utc($item['received']) : DateTimeFormat::utcNow());
$item['created'] = (isset($item['created']) ? DateTimeFormat::utc($item['created']) : $item['received']);
$item['edited'] = (isset($item['edited']) ? DateTimeFormat::utc($item['edited']) : $item['created']);
$item['changed'] = (isset($item['changed']) ? DateTimeFormat::utc($item['changed']) : $item['created']);
$item['commented'] = (isset($item['commented']) ? DateTimeFormat::utc($item['commented']) : $item['created']);
- $item['title'] = trim(defaults($item, 'title', ''));
- $item['location'] = trim(defaults($item, 'location', ''));
- $item['coord'] = trim(defaults($item, 'coord', ''));
+ $item['title'] = trim($item['title'] ?? '');
+ $item['location'] = trim($item['location'] ?? '');
+ $item['coord'] = trim($item['coord'] ?? '');
$item['visible'] = (isset($item['visible']) ? intval($item['visible']) : 1);
$item['deleted'] = 0;
- $item['parent-uri'] = trim(defaults($item, 'parent-uri', $item['uri']));
- $item['post-type'] = defaults($item, 'post-type', self::PT_ARTICLE);
- $item['verb'] = trim(defaults($item, 'verb', ''));
- $item['object-type'] = trim(defaults($item, 'object-type', ''));
- $item['object'] = trim(defaults($item, 'object', ''));
- $item['target-type'] = trim(defaults($item, 'target-type', ''));
- $item['target'] = trim(defaults($item, 'target', ''));
- $item['plink'] = trim(defaults($item, 'plink', ''));
- $item['allow_cid'] = trim(defaults($item, 'allow_cid', ''));
- $item['allow_gid'] = trim(defaults($item, 'allow_gid', ''));
- $item['deny_cid'] = trim(defaults($item, 'deny_cid', ''));
- $item['deny_gid'] = trim(defaults($item, 'deny_gid', ''));
- $item['private'] = intval(defaults($item, 'private', 0));
- $item['body'] = trim(defaults($item, 'body', ''));
- $item['tag'] = trim(defaults($item, 'tag', ''));
- $item['attach'] = trim(defaults($item, 'attach', ''));
- $item['app'] = trim(defaults($item, 'app', ''));
- $item['origin'] = intval(defaults($item, 'origin', 0));
- $item['postopts'] = trim(defaults($item, 'postopts', ''));
- $item['resource-id'] = trim(defaults($item, 'resource-id', ''));
- $item['event-id'] = intval(defaults($item, 'event-id', 0));
- $item['inform'] = trim(defaults($item, 'inform', ''));
- $item['file'] = trim(defaults($item, 'file', ''));
+ $item['parent-uri'] = trim(($item['parent-uri'] ?? '') ?: $item['uri']);
+ $item['post-type'] = ($item['post-type'] ?? '') ?: self::PT_ARTICLE;
+ $item['verb'] = trim($item['verb'] ?? '');
+ $item['object-type'] = trim($item['object-type'] ?? '');
+ $item['object'] = trim($item['object'] ?? '');
+ $item['target-type'] = trim($item['target-type'] ?? '');
+ $item['target'] = trim($item['target'] ?? '');
+ $item['plink'] = trim($item['plink'] ?? '');
+ $item['allow_cid'] = trim($item['allow_cid'] ?? '');
+ $item['allow_gid'] = trim($item['allow_gid'] ?? '');
+ $item['deny_cid'] = trim($item['deny_cid'] ?? '');
+ $item['deny_gid'] = trim($item['deny_gid'] ?? '');
+ $item['private'] = intval($item['private'] ?? 0);
+ $item['body'] = trim($item['body'] ?? '');
+ $item['tag'] = trim($item['tag'] ?? '');
+ $item['attach'] = trim($item['attach'] ?? '');
+ $item['app'] = trim($item['app'] ?? '');
+ $item['origin'] = intval($item['origin'] ?? 0);
+ $item['postopts'] = trim($item['postopts'] ?? '');
+ $item['resource-id'] = trim($item['resource-id'] ?? '');
+ $item['event-id'] = intval($item['event-id'] ?? 0);
+ $item['inform'] = trim($item['inform'] ?? '');
+ $item['file'] = trim($item['file'] ?? '');
// When there is no content then we don't post it
if ($item['body'].$item['title'] == '') {
$item['edited'] = DateTimeFormat::utcNow();
}
- $item['plink'] = defaults($item, 'plink', System::baseUrl() . '/display/' . urlencode($item['guid']));
+ $item['plink'] = ($item['plink'] ?? '') ?: System::baseUrl() . '/display/' . urlencode($item['guid']);
$default = ['url' => $item['author-link'], 'name' => $item['author-name'],
'photo' => $item['author-avatar'], 'network' => $item['network']];
- $item['author-id'] = defaults($item, 'author-id', Contact::getIdForURL($item['author-link'], 0, false, $default));
+ $item['author-id'] = ($item['author-id'] ?? 0) ?: Contact::getIdForURL($item['author-link'], 0, false, $default);
if (Contact::isBlocked($item['author-id'])) {
Logger::notice('Author is blocked node-wide', ['author-link' => $item['author-link'], 'item-uri' => $item['uri']]);
$default = ['url' => $item['owner-link'], 'name' => $item['owner-name'],
'photo' => $item['owner-avatar'], 'network' => $item['network']];
- $item['owner-id'] = defaults($item, 'owner-id', Contact::getIdForURL($item['owner-link'], 0, false, $default));
+ $item['owner-id'] = ($item['owner-id'] ?? 0) ?: Contact::getIdForURL($item['owner-link'], 0, false, $default);
if (Contact::isBlocked($item['owner-id'])) {
Logger::notice('Owner is blocked node-wide', ['owner-link' => $item['owner-link'], 'item-uri' => $item['uri']]);
return 0;
}
- if ($item['verb'] == ACTIVITY_FOLLOW) {
+ if ($item['verb'] == Activity::FOLLOW) {
if (!$item['origin'] && ($item['author-id'] == Contact::getPublicIdByUserId($uid))) {
// Our own follow request can be relayed to us. We don't store it to avoid notification chaos.
Logger::log("Follow: Don't store not origin follow request from us for " . $item['parent-uri'], Logger::DEBUG);
return 0;
}
- $condition = ['verb' => ACTIVITY_FOLLOW, 'uid' => $item['uid'],
+ $condition = ['verb' => Activity::FOLLOW, 'uid' => $item['uid'],
'parent-uri' => $item['parent-uri'], 'author-id' => $item['author-id']];
if (self::exists($condition)) {
// It happens that we receive multiple follow requests by the same author - we only store one.
}
}
- if (stristr($item['verb'], ACTIVITY_POKE)) {
+ if (stristr($item['verb'], Activity::POKE)) {
$notify_type = Delivery::POKE;
}
Contact::unmarkForArchival($contact);
}
- $update = (!$arr['private'] && ((defaults($arr, 'author-link', '') === defaults($arr, 'owner-link', '')) || ($arr["parent-uri"] === $arr["uri"])));
+ $update = (!$arr['private'] && ((($arr['author-link'] ?? '') === ($arr['owner-link'] ?? '')) || ($arr["parent-uri"] === $arr["uri"])));
// Is it a forum? Then we don't care about the rules from above
if (!$update && in_array($arr["network"], [Protocol::ACTIVITYPUB, Protocol::DFRN]) && ($arr["parent-uri"] === $arr["uri"])) {
}
// Only forward posts
- if ($datarray["verb"] != ACTIVITY_POST) {
+ if ($datarray["verb"] != Activity::POST) {
Logger::log('No post', Logger::DEBUG);
return false;
}
*/
public static function enumeratePermissions(array $obj, bool $check_dead = false)
{
- $allow_people = expand_acl($obj['allow_cid']);
- $allow_groups = Group::expand($obj['uid'], expand_acl($obj['allow_gid']), $check_dead);
- $deny_people = expand_acl($obj['deny_cid']);
- $deny_groups = Group::expand($obj['uid'], expand_acl($obj['deny_gid']), $check_dead);
+ /** @var ACLFormatter $aclFormater */
+ $aclFormater = self::getClass(ACLFormatter::class);
+
+ $allow_people = $aclFormater->expand($obj['allow_cid']);
+ $allow_groups = Group::expand($obj['uid'], $aclFormater->expand($obj['allow_gid']), $check_dead);
+ $deny_people = $aclFormater->expand($obj['deny_cid']);
+ $deny_groups = Group::expand($obj['uid'], $aclFormater->expand($obj['deny_gid']), $check_dead);
$recipients = array_unique(array_merge($allow_people, $allow_groups));
$deny = array_unique(array_merge($deny_people, $deny_groups));
$recipients = array_diff($recipients, $deny);
switch ($verb) {
case 'like':
case 'unlike':
- $activity = ACTIVITY_LIKE;
+ $activity = Activity::LIKE;
break;
case 'dislike':
case 'undislike':
- $activity = ACTIVITY_DISLIKE;
+ $activity = Activity::DISLIKE;
break;
case 'attendyes':
case 'unattendyes':
- $activity = ACTIVITY_ATTEND;
+ $activity = Activity::ATTEND;
break;
case 'attendno':
case 'unattendno':
- $activity = ACTIVITY_ATTENDNO;
+ $activity = Activity::ATTENDNO;
break;
case 'attendmaybe':
case 'unattendmaybe':
- $activity = ACTIVITY_ATTENDMAYBE;
+ $activity = Activity::ATTENDMAYBE;
break;
default:
Logger::log('like: unknown verb ' . $verb . ' for item ' . $item_id);
}
// Enable activity toggling instead of on/off
- $event_verb_flag = $activity === ACTIVITY_ATTEND || $activity === ACTIVITY_ATTENDNO || $activity === ACTIVITY_ATTENDMAYBE;
+ $event_verb_flag = $activity === Activity::ATTEND || $activity === Activity::ATTENDNO || $activity === Activity::ATTENDMAYBE;
Logger::log('like: verb ' . $verb . ' item ' . $item_id);
// event participation are essentially radio toggles. If you make a subsequent choice,
// we need to eradicate your first choice.
if ($event_verb_flag) {
- $verbs = [ACTIVITY_ATTEND, ACTIVITY_ATTENDNO, ACTIVITY_ATTENDMAYBE];
+ $verbs = [Activity::ATTEND, Activity::ATTENDNO, Activity::ATTENDMAYBE];
// Translate to the index based activity index
$activities = [];
return true;
}
- $objtype = $item['resource-id'] ? ACTIVITY_OBJ_IMAGE : ACTIVITY_OBJ_NOTE;
+ $objtype = $item['resource-id'] ? Activity\ObjectType::IMAGE : Activity\ObjectType::NOTE;
$new_item = [
'guid' => System::createUUID(),
return L10n::t('event');
} elseif (!empty($item['resource-id'])) {
return L10n::t('photo');
- } elseif (!empty($item['verb']) && $item['verb'] !== ACTIVITY_POST) {
+ } elseif (!empty($item['verb']) && $item['verb'] !== Activity::POST) {
return L10n::t('activity');
} elseif ($item['id'] != $item['parent']) {
return L10n::t('comment');
{
$body = $item["body"];
- $rendered_hash = defaults($item, 'rendered-hash', '');
- $rendered_html = defaults($item, 'rendered-html', '');
+ $rendered_hash = $item['rendered-hash'] ?? '';
+ $rendered_html = $item['rendered-html'] ?? '';
if ($rendered_hash == ''
|| $rendered_html == ""
|| $rendered_hash != hash("md5", $item["body"])
|| Config::get("system", "ignore_cache")
) {
- $a = self::getApp();
- redir_private_images($a, $item);
+ self::addRedirToImageTags($item);
- $item["rendered-html"] = prepare_text($item["body"]);
+ $item["rendered-html"] = BBCode::convert($item["body"]);
$item["rendered-hash"] = hash("md5", $item["body"]);
$hook_data = ['item' => $item, 'rendered-html' => $item['rendered-html'], 'rendered-hash' => $item['rendered-hash']];
$item["body"] = $body;
}
+ /**
+ * @brief Find any non-embedded images in private items and add redir links to them
+ *
+ * @param array &$item The field array of an item row
+ */
+ private static function addRedirToImageTags(array &$item)
+ {
+ $app = self::getApp();
+
+ $matches = [];
+ $cnt = preg_match_all('|\[img\](http[^\[]*?/photo/[a-fA-F0-9]+?(-[0-9]\.[\w]+?)?)\[\/img\]|', $item['body'], $matches, PREG_SET_ORDER);
+ if ($cnt) {
+ foreach ($matches as $mtch) {
+ if (strpos($mtch[1], '/redir') !== false) {
+ continue;
+ }
+
+ if ((local_user() == $item['uid']) && ($item['private'] == 1) && ($item['contact-id'] != $app->contact['id']) && ($item['network'] == Protocol::DFRN)) {
+ $img_url = 'redir/' . $item['contact-id'] . '?url=' . urlencode($mtch[1]);
+ $item['body'] = str_replace($mtch[0], '[img]' . $img_url . '[/img]', $item['body']);
+ }
+ }
+ }
+ }
+
/**
* @brief Given an item array, convert the body element from bbcode to html and add smilie icons.
* If attach is true, also add icons for item attachments.
// In order to provide theme developers more possibilities, event items
// are treated differently.
- if ($item['object-type'] === ACTIVITY_OBJ_EVENT && isset($item['event-id'])) {
+ if ($item['object-type'] === Activity\ObjectType::EVENT && isset($item['event-id'])) {
$ev = Event::getItemHTML($item);
return $ev;
}
$filesubtype = 'unkn';
}
- $title = Strings::escapeHtml(trim(defaults($mtch, 4, $mtch[1])));
+ $title = Strings::escapeHtml(trim(($mtch[4] ?? '') ?: $mtch[1]));
$title .= ' ' . $mtch[2] . ' ' . L10n::t('bytes');
$icon = '<div class="attachtype icon s22 type-' . $filetype . ' subtype-' . $filesubtype . '"></div>';
}
}
- $html = Text\BBCode::convert($post['text'] . defaults($post, 'after', ''), false, $htmlmode);
+ $html = Text\BBCode::convert($post['text'] . ($post['after'] ?? ''), false, $htmlmode);
$msg = Text\HTML::toPlaintext($html, 0, true);
$msg = trim(html_entity_decode($msg, ENT_QUOTES, 'UTF-8'));
if ($post['type'] == 'link') {
$link = $post['url'];
} elseif ($post['type'] == 'text') {
- $link = defaults($post, 'url', '');
+ $link = $post['url'] ?? '';
} elseif ($post['type'] == 'video') {
$link = $post['url'];
} elseif ($post['type'] == 'photo') {
use Friendica\Model\Photo;
use Friendica\Database\DBA;
use Friendica\Network\Probe;
+use Friendica\Protocol\Activity;
use Friendica\Util\DateTimeFormat;
use Friendica\Worker\Delivery;
'source_name' => $msg['from-name'],
'source_link' => $msg['from-url'],
'source_photo' => $msg['from-photo'],
- 'verb' => ACTIVITY_POST,
+ 'verb' => Activity::POST,
'otype' => 'mail'
];
--- /dev/null
+<?php
+
+namespace Friendica\Model;
+
+use Exception;
+use Friendica\App;
+use Friendica\BaseObject;
+use Friendica\Content\Text\BBCode;
+use Friendica\Content\Text\HTML;
+use Friendica\Core\Config\PConfiguration;
+use Friendica\Core\L10n\L10n;
+use Friendica\Core\Protocol;
+use Friendica\Core\System;
+use Friendica\Database\Database;
+use Friendica\Protocol\Activity;
+use Friendica\Util\DateTimeFormat;
+use Friendica\Util\Proxy as ProxyUtils;
+use Friendica\Util\Temporal;
+use Friendica\Util\XML;
+use ImagickException;
+use Psr\Log\LoggerInterface;
+use Friendica\Network\HTTPException;
+
+/**
+ * @brief Methods for read and write notifications from/to database
+ * or for formatting notifications
+ */
+final class Notify extends BaseObject
+{
+ /** @var int The default limit of notifies per page */
+ const DEFAULT_PAGE_LIMIT = 80;
+
+ const NETWORK = 'network';
+ const SYSTEM = 'system';
+ const PERSONAL = 'personal';
+ const HOME = 'home';
+ const INTRO = 'intro';
+
+ /** @var array Array of URL parameters */
+ const URL_TYPES = [
+ self::NETWORK => 'network',
+ self::SYSTEM => 'system',
+ self::HOME => 'home',
+ self::PERSONAL => 'personal',
+ self::INTRO => 'intros',
+ ];
+
+ /** @var array Array of the allowed notifies and their printable name */
+ const PRINT_TYPES = [
+ self::NETWORK => 'Network',
+ self::SYSTEM => 'System',
+ self::HOME => 'Home',
+ self::PERSONAL => 'Personal',
+ self::INTRO => 'Introductions',
+ ];
+
+ /** @var array The array of access keys for notify pages */
+ const ACCESS_KEYS = [
+ self::NETWORK => 'w',
+ self::SYSTEM => 'y',
+ self::HOME => 'h',
+ self::PERSONAL => 'r',
+ self::INTRO => 'i',
+ ];
+
+ /** @var Database */
+ private $dba;
+ /** @var L10n */
+ private $l10n;
+ /** @var App\Arguments */
+ private $args;
+ /** @var App\BaseURL */
+ private $baseUrl;
+ /** @var PConfiguration */
+ private $pConfig;
+ /** @var LoggerInterface */
+ private $logger;
+
+ public function __construct(Database $dba, L10n $l10n, App\Arguments $args, App\BaseURL $baseUrl,
+ PConfiguration $pConfig, LoggerInterface $logger)
+ {
+ $this->dba = $dba;
+ $this->l10n = $l10n;
+ $this->args = $args;
+ $this->baseUrl = $baseUrl;
+ $this->pConfig = $pConfig;
+ $this->logger = $logger;
+ }
+
+ /**
+ * Set some extra properties to note array from db:
+ * - timestamp as int in default TZ
+ * - date_rel : relative date string
+ * - msg_html: message as html string
+ * - msg_plain: message as plain text string
+ *
+ * @param array $notes array of note arrays from db
+ *
+ * @return array Copy of input array with added properties
+ *
+ * @throws Exception
+ */
+ private function setExtra(array $notes)
+ {
+ $retNotes = [];
+ foreach ($notes as $note) {
+ $local_time = DateTimeFormat::local($note['date']);
+ $note['timestamp'] = strtotime($local_time);
+ $note['date_rel'] = Temporal::getRelativeDate($note['date']);
+ $note['msg_html'] = BBCode::convert($note['msg'], false);
+ $note['msg_plain'] = explode("\n", trim(HTML::toPlaintext($note['msg_html'], 0)))[0];
+
+ $retNotes[] = $note;
+ }
+ return $retNotes;
+ }
+
+ /**
+ * Get all notifications for local_user()
+ *
+ * @param array $filter optional Array "column name"=>value: filter query by columns values
+ * @param array $order optional Array to order by
+ * @param string $limit optional Query limits
+ *
+ * @return array|bool of results or false on errors
+ * @throws Exception
+ */
+ public function getAll(array $filter = [], array $order = ['date' => 'DESC'], string $limit = "")
+ {
+ $params = [];
+
+ $params['order'] = $order;
+
+ if (!empty($limit)) {
+ $params['limit'] = $limit;
+ }
+
+ $dbFilter = array_merge($filter, ['uid' => local_user()]);
+
+ $stmtNotifies = $this->dba->select('notify', [], $dbFilter, $params);
+
+ if ($this->dba->isResult($stmtNotifies)) {
+ return $this->setExtra($this->dba->toArray($stmtNotifies));
+ }
+
+ return false;
+ }
+
+ /**
+ * Get one note for local_user() by $id value
+ *
+ * @param int $id identity
+ *
+ * @return array note values or null if not found
+ * @throws Exception
+ */
+ public function getByID(int $id)
+ {
+ $stmtNotify = $this->dba->selectFirst('notify', [], ['id' => $id, 'uid' => local_user()]);
+ if ($this->dba->isResult($stmtNotify)) {
+ return $this->setExtra([$stmtNotify])[0];
+ }
+ return null;
+ }
+
+ /**
+ * @brief set seen state of $note of local_user()
+ *
+ * @param array $note note array
+ * @param bool $seen optional true or false, default true
+ *
+ * @return bool true on success, false on errors
+ * @throws Exception
+ */
+ public function setSeen(array $note, bool $seen = true)
+ {
+ return $this->dba->update('notify', ['seen' => $seen], [
+ '(`link` = ? OR (`parent` != 0 AND `parent` = ? AND `otype` = ?)) AND `uid` = ?',
+ $note['link'],
+ $note['parent'],
+ $note['otype'],
+ local_user()
+ ]);
+ }
+
+ /**
+ * Set seen state of all notifications of local_user()
+ *
+ * @param bool $seen optional true or false. default true
+ *
+ * @return bool true on success, false on error
+ * @throws Exception
+ */
+ public function setAllSeen(bool $seen = true)
+ {
+ return $this->dba->update('notify', ['seen' => $seen], ['uid' => local_user()]);
+ }
+
+ /**
+ * @brief List of pages for the Notifications TabBar
+ *
+ * @return array with with notifications TabBar data
+ * @throws Exception
+ */
+ public function getTabs()
+ {
+ $selected = $this->args->get(1, '');
+
+ $tabs = [];
+
+ foreach (self::URL_TYPES as $type => $url) {
+ $tabs[] = [
+ 'label' => $this->l10n->t(self::PRINT_TYPES[$type]),
+ 'url' => 'notifications/' . $url,
+ 'sel' => (($selected == $url) ? 'active' : ''),
+ 'id' => $type . '-tab',
+ 'accesskey' => self::ACCESS_KEYS[$type],
+ ];
+ }
+
+ return $tabs;
+ }
+
+ /**
+ * Format the notification query in an usable array
+ *
+ * @param array $notifies The array from the db query
+ * @param string $ident The notifications identifier (e.g. network)
+ *
+ * @return array
+ * string 'label' => The type of the notification
+ * string 'link' => URL to the source
+ * string 'image' => The avatar image
+ * string 'url' => The profile url of the contact
+ * string 'text' => The notification text
+ * string 'when' => The date of the notification
+ * string 'ago' => T relative date of the notification
+ * bool 'seen' => Is the notification marked as "seen"
+ * @throws Exception
+ */
+ private function formatList(array $notifies, string $ident = "")
+ {
+ $formattedNotifies = [];
+
+ foreach ($notifies as $notify) {
+ // Because we use different db tables for the notification query
+ // we have sometimes $notify['unseen'] and sometimes $notify['seen].
+ // So we will have to transform $notify['unseen']
+ if (array_key_exists('unseen', $notify)) {
+ $notify['seen'] = ($notify['unseen'] > 0 ? false : true);
+ }
+
+ // For feed items we use the user's contact, since the avatar is mostly self choosen.
+ if (!empty($notify['network']) && $notify['network'] == Protocol::FEED) {
+ $notify['author-avatar'] = $notify['contact-avatar'];
+ }
+
+ // Depending on the identifier of the notification we need to use different defaults
+ switch ($ident) {
+ case self::SYSTEM:
+ $default_item_label = 'notify';
+ $default_item_link = $this->baseUrl->get(true) . '/notify/view/' . $notify['id'];
+ $default_item_image = ProxyUtils::proxifyUrl($notify['photo'], false, ProxyUtils::SIZE_MICRO);
+ $default_item_url = $notify['url'];
+ $default_item_text = strip_tags(BBCode::convert($notify['msg']));
+ $default_item_when = DateTimeFormat::local($notify['date'], 'r');
+ $default_item_ago = Temporal::getRelativeDate($notify['date']);
+ break;
+
+ case self::HOME:
+ $default_item_label = 'comment';
+ $default_item_link = $this->baseUrl->get(true) . '/display/' . $notify['parent-guid'];
+ $default_item_image = ProxyUtils::proxifyUrl($notify['author-avatar'], false, ProxyUtils::SIZE_MICRO);
+ $default_item_url = $notify['author-link'];
+ $default_item_text = $this->l10n->t("%s commented on %s's post", $notify['author-name'], $notify['parent-author-name']);
+ $default_item_when = DateTimeFormat::local($notify['created'], 'r');
+ $default_item_ago = Temporal::getRelativeDate($notify['created']);
+ break;
+
+ default:
+ $default_item_label = (($notify['id'] == $notify['parent']) ? 'post' : 'comment');
+ $default_item_link = $this->baseUrl->get(true) . '/display/' . $notify['parent-guid'];
+ $default_item_image = ProxyUtils::proxifyUrl($notify['author-avatar'], false, ProxyUtils::SIZE_MICRO);
+ $default_item_url = $notify['author-link'];
+ $default_item_text = (($notify['id'] == $notify['parent'])
+ ? $this->l10n->t("%s created a new post", $notify['author-name'])
+ : $this->l10n->t("%s commented on %s's post", $notify['author-name'], $notify['parent-author-name']));
+ $default_item_when = DateTimeFormat::local($notify['created'], 'r');
+ $default_item_ago = Temporal::getRelativeDate($notify['created']);
+ }
+
+ // Transform the different types of notification in an usable array
+ switch ($notify['verb']) {
+ case Activity::LIKE:
+ $formattedNotify = [
+ 'label' => 'like',
+ 'link' => $this->baseUrl->get(true) . '/display/' . $notify['parent-guid'],
+ 'image' => ProxyUtils::proxifyUrl($notify['author-avatar'], false, ProxyUtils::SIZE_MICRO),
+ 'url' => $notify['author-link'],
+ 'text' => $this->l10n->t("%s liked %s's post", $notify['author-name'], $notify['parent-author-name']),
+ 'when' => $default_item_when,
+ 'ago' => $default_item_ago,
+ 'seen' => $notify['seen']
+ ];
+ break;
+
+ case Activity::DISLIKE:
+ $formattedNotify = [
+ 'label' => 'dislike',
+ 'link' => $this->baseUrl->get(true) . '/display/' . $notify['parent-guid'],
+ 'image' => ProxyUtils::proxifyUrl($notify['author-avatar'], false, ProxyUtils::SIZE_MICRO),
+ 'url' => $notify['author-link'],
+ 'text' => $this->l10n->t("%s disliked %s's post", $notify['author-name'], $notify['parent-author-name']),
+ 'when' => $default_item_when,
+ 'ago' => $default_item_ago,
+ 'seen' => $notify['seen']
+ ];
+ break;
+
+ case Activity::ATTEND:
+ $formattedNotify = [
+ 'label' => 'attend',
+ 'link' => $this->baseUrl->get(true) . '/display/' . $notify['parent-guid'],
+ 'image' => ProxyUtils::proxifyUrl($notify['author-avatar'], false, ProxyUtils::SIZE_MICRO),
+ 'url' => $notify['author-link'],
+ 'text' => $this->l10n->t("%s is attending %s's event", $notify['author-name'], $notify['parent-author-name']),
+ 'when' => $default_item_when,
+ 'ago' => $default_item_ago,
+ 'seen' => $notify['seen']
+ ];
+ break;
+
+ case Activity::ATTENDNO:
+ $formattedNotify = [
+ 'label' => 'attendno',
+ 'link' => $this->baseUrl->get(true) . '/display/' . $notify['parent-guid'],
+ 'image' => ProxyUtils::proxifyUrl($notify['author-avatar'], false, ProxyUtils::SIZE_MICRO),
+ 'url' => $notify['author-link'],
+ 'text' => $this->l10n->t("%s is not attending %s's event", $notify['author-name'], $notify['parent-author-name']),
+ 'when' => $default_item_when,
+ 'ago' => $default_item_ago,
+ 'seen' => $notify['seen']
+ ];
+ break;
+
+ case Activity::ATTENDMAYBE:
+ $formattedNotify = [
+ 'label' => 'attendmaybe',
+ 'link' => $this->baseUrl->get(true) . '/display/' . $notify['parent-guid'],
+ 'image' => ProxyUtils::proxifyUrl($notify['author-avatar'], false, ProxyUtils::SIZE_MICRO),
+ 'url' => $notify['author-link'],
+ 'text' => $this->l10n->t("%s may attend %s's event", $notify['author-name'], $notify['parent-author-name']),
+ 'when' => $default_item_when,
+ 'ago' => $default_item_ago,
+ 'seen' => $notify['seen']
+ ];
+ break;
+
+ case Activity::FRIEND:
+ if (!isset($notify['object'])) {
+ $formattedNotify = [
+ 'label' => 'friend',
+ 'link' => $default_item_link,
+ 'image' => $default_item_image,
+ 'url' => $default_item_url,
+ 'text' => $default_item_text,
+ 'when' => $default_item_when,
+ 'ago' => $default_item_ago,
+ 'seen' => $notify['seen']
+ ];
+ break;
+ }
+ /// @todo Check if this part here is used at all
+ $this->logger->info('Complete data.', ['notify' => $notify, 'callStack' => System::callstack(20)]);
+
+ $xmlHead = "<" . "?xml version='1.0' encoding='UTF-8' ?" . ">";
+ $obj = XML::parseString($xmlHead . $notify['object']);
+ $notify['fname'] = $obj->title;
+
+ $formattedNotify = [
+ 'label' => 'friend',
+ 'link' => $this->baseUrl->get(true) . '/display/' . $notify['parent-guid'],
+ 'image' => ProxyUtils::proxifyUrl($notify['author-avatar'], false, ProxyUtils::SIZE_MICRO),
+ 'url' => $notify['author-link'],
+ 'text' => $this->l10n->t("%s is now friends with %s", $notify['author-name'], $notify['fname']),
+ 'when' => $default_item_when,
+ 'ago' => $default_item_ago,
+ 'seen' => $notify['seen']
+ ];
+ break;
+
+ default:
+ $formattedNotify = [
+ 'label' => $default_item_label,
+ 'link' => $default_item_link,
+ 'image' => $default_item_image,
+ 'url' => $default_item_url,
+ 'text' => $default_item_text,
+ 'when' => $default_item_when,
+ 'ago' => $default_item_ago,
+ 'seen' => $notify['seen']
+ ];
+ }
+
+ $formattedNotifies[] = $formattedNotify;
+ }
+
+ return $formattedNotifies;
+ }
+
+ /**
+ * Get network notifications
+ *
+ * @param bool $seen False => only include notifications into the query
+ * which aren't marked as "seen"
+ * @param int $start Start the query at this point
+ * @param int $limit Maximum number of query results
+ *
+ * @return array [string, array]
+ * string 'ident' => Notification identifier
+ * array 'notifications' => Network notifications
+ *
+ * @throws Exception
+ */
+ public function getNetworkList(bool $seen = false, int $start = 0, int $limit = self::DEFAULT_PAGE_LIMIT)
+ {
+ $ident = self::NETWORK;
+ $notifies = [];
+
+ $condition = ['wall' => false, 'uid' => local_user()];
+
+ if (!$seen) {
+ $condition['unseen'] = true;
+ }
+
+ $fields = ['id', 'parent', 'verb', 'author-name', 'unseen', 'author-link', 'author-avatar', 'contact-avatar',
+ 'network', 'created', 'object', 'parent-author-name', 'parent-author-link', 'parent-guid'];
+ $params = ['order' => ['received' => true], 'limit' => [$start, $limit]];
+
+ $items = Item::selectForUser(local_user(), $fields, $condition, $params);
+
+ if ($this->dba->isResult($items)) {
+ $notifies = $this->formatList(Item::inArray($items), $ident);
+ }
+
+ $arr = [
+ 'notifications' => $notifies,
+ 'ident' => $ident,
+ ];
+
+ return $arr;
+ }
+
+ /**
+ * Get system notifications
+ *
+ * @param bool $seen False => only include notifications into the query
+ * which aren't marked as "seen"
+ * @param int $start Start the query at this point
+ * @param int $limit Maximum number of query results
+ *
+ * @return array [string, array]
+ * string 'ident' => Notification identifier
+ * array 'notifications' => System notifications
+ *
+ * @throws Exception
+ */
+ public function getSystemList(bool $seen = false, int $start = 0, int $limit = self::DEFAULT_PAGE_LIMIT)
+ {
+ $ident = self::SYSTEM;
+ $notifies = [];
+
+ $filter = ['uid' => local_user()];
+ if (!$seen) {
+ $filter['seen'] = false;
+ }
+
+ $params = [];
+ $params['order'] = ['date' => 'DESC'];
+ $params['limit'] = [$start, $limit];
+
+ $stmtNotifies = $this->dba->select('notify',
+ ['id', 'url', 'photo', 'msg', 'date', 'seen', 'verb'],
+ $filter,
+ $params);
+
+ if ($this->dba->isResult($stmtNotifies)) {
+ $notifies = $this->formatList($this->dba->toArray($stmtNotifies), $ident);
+ }
+
+ $arr = [
+ 'notifications' => $notifies,
+ 'ident' => $ident,
+ ];
+
+ return $arr;
+ }
+
+ /**
+ * Get personal notifications
+ *
+ * @param bool $seen False => only include notifications into the query
+ * which aren't marked as "seen"
+ * @param int $start Start the query at this point
+ * @param int $limit Maximum number of query results
+ *
+ * @return array [string, array]
+ * string 'ident' => Notification identifier
+ * array 'notifications' => Personal notifications
+ *
+ * @throws Exception
+ */
+ public function getPersonalList(bool $seen = false, int $start = 0, int $limit = self::DEFAULT_PAGE_LIMIT)
+ {
+ $ident = self::PERSONAL;
+ $notifies = [];
+
+ $myurl = str_replace('http://', '', self::getApp()->contact['nurl']);
+ $diasp_url = str_replace('/profile/', '/u/', $myurl);
+
+ $condition = ["NOT `wall` AND `uid` = ? AND (`item`.`author-id` = ? OR `item`.`tag` REGEXP ? OR `item`.`tag` REGEXP ?)",
+ local_user(), public_contact(), $myurl . '\\]', $diasp_url . '\\]'];
+
+ if (!$seen) {
+ $condition[0] .= " AND `unseen`";
+ }
+
+ $fields = ['id', 'parent', 'verb', 'author-name', 'unseen', 'author-link', 'author-avatar', 'contact-avatar',
+ 'network', 'created', 'object', 'parent-author-name', 'parent-author-link', 'parent-guid'];
+ $params = ['order' => ['received' => true], 'limit' => [$start, $limit]];
+
+ $items = Item::selectForUser(local_user(), $fields, $condition, $params);
+
+ if ($this->dba->isResult($items)) {
+ $notifies = $this->formatList(Item::inArray($items), $ident);
+ }
+
+ $arr = [
+ 'notifications' => $notifies,
+ 'ident' => $ident,
+ ];
+
+ return $arr;
+ }
+
+ /**
+ * @brief Get home notifications
+ *
+ * @param bool $seen False => only include notifications into the query
+ * which aren't marked as "seen"
+ * @param int $start Start the query at this point
+ * @param int $limit Maximum number of query results
+ *
+ * @return array [string, array]
+ * string 'ident' => Notification identifier
+ * array 'notifications' => Home notifications
+ *
+ * @throws Exception
+ */
+ public function getHomeList(bool $seen = false, int $start = 0, int $limit = self::DEFAULT_PAGE_LIMIT)
+ {
+ $ident = self::HOME;
+ $notifies = [];
+
+ $condition = ['wall' => true, 'uid' => local_user()];
+
+ if (!$seen) {
+ $condition['unseen'] = true;
+ }
+
+ $fields = ['id', 'parent', 'verb', 'author-name', 'unseen', 'author-link', 'author-avatar', 'contact-avatar',
+ 'network', 'created', 'object', 'parent-author-name', 'parent-author-link', 'parent-guid'];
+ $params = ['order' => ['received' => true], 'limit' => [$start, $limit]];
+
+ $items = Item::selectForUser(local_user(), $fields, $condition, $params);
+
+ if ($this->dba->isResult($items)) {
+ $notifies = $this->formatList(Item::inArray($items), $ident);
+ }
+
+ $arr = [
+ 'notifications' => $notifies,
+ 'ident' => $ident,
+ ];
+
+ return $arr;
+ }
+
+ /**
+ * @brief Get introductions
+ *
+ * @param bool $all If false only include introductions into the query
+ * which aren't marked as ignored
+ * @param int $start Start the query at this point
+ * @param int $limit Maximum number of query results
+ * @param int $id When set, only the introduction with this id is displayed
+ *
+ * @return array [string, array]
+ * string 'ident' => Notification identifier
+ * array 'notifications' => Introductions
+ *
+ * @throws ImagickException
+ * @throws Exception
+ */
+ public function getIntroList(bool $all = false, int $start = 0, int $limit = self::DEFAULT_PAGE_LIMIT, int $id = 0)
+ {
+ /// @todo sanitize wording according to SELF::INTRO
+ $ident = 'introductions';
+ $notifies = [];
+ $sql_extra = "";
+
+ if (empty($id)) {
+ if (!$all) {
+ $sql_extra = " AND NOT `ignore` ";
+ }
+
+ $sql_extra .= " AND NOT `intro`.`blocked` ";
+ } else {
+ $sql_extra = sprintf(" AND `intro`.`id` = %d ", intval($id));
+ }
+
+ /// @todo Fetch contact details by "Contact::getDetailsByUrl" instead of queries to contact, fcontact and gcontact
+ $stmtNotifies = $this->dba->p(
+ "SELECT `intro`.`id` AS `intro_id`, `intro`.*, `contact`.*,
+ `fcontact`.`name` AS `fname`, `fcontact`.`url` AS `furl`, `fcontact`.`addr` AS `faddr`,
+ `fcontact`.`photo` AS `fphoto`, `fcontact`.`request` AS `frequest`,
+ `gcontact`.`location` AS `glocation`, `gcontact`.`about` AS `gabout`,
+ `gcontact`.`keywords` AS `gkeywords`, `gcontact`.`gender` AS `ggender`,
+ `gcontact`.`network` AS `gnetwork`, `gcontact`.`addr` AS `gaddr`
+ FROM `intro`
+ LEFT JOIN `contact` ON `contact`.`id` = `intro`.`contact-id`
+ LEFT JOIN `gcontact` ON `gcontact`.`nurl` = `contact`.`nurl`
+ LEFT JOIN `fcontact` ON `intro`.`fid` = `fcontact`.`id`
+ WHERE `intro`.`uid` = ? $sql_extra
+ LIMIT ?, ?",
+ $_SESSION['uid'],
+ $start,
+ $limit
+ );
+ if ($this->dba->isResult($stmtNotifies)) {
+ $notifies = $this->formatIntroList($this->dba->toArray($stmtNotifies));
+ }
+
+ $arr = [
+ 'ident' => $ident,
+ 'notifications' => $notifies,
+ ];
+
+ return $arr;
+ }
+
+ /**
+ * @brief Format the notification query in an usable array
+ *
+ * @param array $intros The array from the db query
+ *
+ * @return array with the introductions
+ * @throws HTTPException\InternalServerErrorException
+ * @throws ImagickException
+ */
+ private function formatIntroList(array $intros)
+ {
+ $knowyou = '';
+
+ $formattedIntros = [];
+
+ foreach ($intros as $intro) {
+ // 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.
+ // Contact suggestions
+ if ($intro['fid']) {
+ $return_addr = bin2hex(self::getApp()->user['nickname'] . '@' .
+ $this->baseUrl->getHostName() .
+ (($this->baseUrl->getURLPath()) ? '/' . $this->baseUrl->getURLPath() : ''));
+
+ $intro = [
+ 'label' => 'friend_suggestion',
+ 'notify_type' => $this->l10n->t('Friend Suggestion'),
+ 'intro_id' => $intro['intro_id'],
+ 'madeby' => $intro['name'],
+ 'madeby_url' => $intro['url'],
+ 'madeby_zrl' => Contact::magicLink($intro['url']),
+ 'madeby_addr' => $intro['addr'],
+ 'contact_id' => $intro['contact-id'],
+ 'photo' => (!empty($intro['fphoto']) ? ProxyUtils::proxifyUrl($intro['fphoto'], false, ProxyUtils::SIZE_SMALL) : "images/person-300.jpg"),
+ 'name' => $intro['fname'],
+ 'url' => $intro['furl'],
+ 'zrl' => Contact::magicLink($intro['furl']),
+ 'hidden' => $intro['hidden'] == 1,
+ 'post_newfriend' => (intval($this->pConfig->get(local_user(), 'system', 'post_newfriend')) ? '1' : 0),
+ 'knowyou' => $knowyou,
+ 'note' => $intro['note'],
+ 'request' => $intro['frequest'] . '?addr=' . $return_addr,
+ ];
+
+ // Normal connection requests
+ } else {
+ $intro = $this->getMissingIntroData($intro);
+
+ if (empty($intro['url'])) {
+ continue;
+ }
+
+ // Don't show these data until you are connected. Diaspora is doing the same.
+ if ($intro['gnetwork'] === Protocol::DIASPORA) {
+ $intro['glocation'] = "";
+ $intro['gabout'] = "";
+ $intro['ggender'] = "";
+ }
+ $intro = [
+ 'label' => (($intro['network'] !== Protocol::OSTATUS) ? 'friend_request' : 'follower'),
+ 'notify_type' => (($intro['network'] !== Protocol::OSTATUS) ? $this->l10n->t('Friend/Connect Request') : $this->l10n->t('New Follower')),
+ 'dfrn_id' => $intro['issued-id'],
+ 'uid' => $_SESSION['uid'],
+ 'intro_id' => $intro['intro_id'],
+ 'contact_id' => $intro['contact-id'],
+ 'photo' => (!empty($intro['photo']) ? ProxyUtils::proxifyUrl($intro['photo'], false, ProxyUtils::SIZE_SMALL) : "images/person-300.jpg"),
+ 'name' => $intro['name'],
+ 'location' => BBCode::convert($intro['glocation'], false),
+ 'about' => BBCode::convert($intro['gabout'], false),
+ 'keywords' => $intro['gkeywords'],
+ 'gender' => $intro['ggender'],
+ 'hidden' => $intro['hidden'] == 1,
+ 'post_newfriend' => (intval($this->pConfig->get(local_user(), 'system', 'post_newfriend')) ? '1' : 0),
+ 'url' => $intro['url'],
+ 'zrl' => Contact::magicLink($intro['url']),
+ 'addr' => $intro['gaddr'],
+ 'network' => $intro['gnetwork'],
+ 'knowyou' => $intro['knowyou'],
+ 'note' => $intro['note'],
+ ];
+ }
+
+ $formattedIntros[] = $intro;
+ }
+
+ return $formattedIntros;
+ }
+
+ /**
+ * @brief Check for missing contact data and try to fetch the data from
+ * from other sources
+ *
+ * @param array $intro The input array with the intro data
+ *
+ * @return array The array with the intro data
+ * @throws HTTPException\InternalServerErrorException
+ */
+ private function getMissingIntroData(array $intro)
+ {
+ // If the network and the addr isn't available from the gcontact
+ // table entry, take the one of the contact table entry
+ if (empty($intro['gnetwork']) && !empty($intro['network'])) {
+ $intro['gnetwork'] = $intro['network'];
+ }
+ if (empty($intro['gaddr']) && !empty($intro['addr'])) {
+ $intro['gaddr'] = $intro['addr'];
+ }
+
+ // If the network and addr is still not available
+ // get the missing data data from other sources
+ if (empty($intro['gnetwork']) || empty($intro['gaddr'])) {
+ $ret = Contact::getDetailsByURL($intro['url']);
+
+ if (empty($intro['gnetwork']) && !empty($ret['network'])) {
+ $intro['gnetwork'] = $ret['network'];
+ }
+ if (empty($intro['gaddr']) && !empty($ret['addr'])) {
+ $intro['gaddr'] = $ret['addr'];
+ }
+ }
+
+ return $intro;
+ }
+}
public static function fetchIDForPost(&$postarray)
{
$condition = ['uid' => $postarray['uid'],
- 'allow_cid' => self::sortPermissions(defaults($postarray, 'allow_cid', '')),
- 'allow_gid' => self::sortPermissions(defaults($postarray, 'allow_gid', '')),
- 'deny_cid' => self::sortPermissions(defaults($postarray, 'deny_cid', '')),
- 'deny_gid' => self::sortPermissions(defaults($postarray, 'deny_gid', ''))];
+ 'allow_cid' => self::sortPermissions($postarray['allow_cid'] ?? ''),
+ 'allow_gid' => self::sortPermissions($postarray['allow_gid'] ?? ''),
+ 'deny_cid' => self::sortPermissions($postarray['deny_cid'] ?? ''),
+ 'deny_gid' => self::sortPermissions($postarray['deny_gid'] ?? '')];
$set = DBA::selectFirst('permissionset', ['id'], $condition);
use Friendica\Core\Theme;
use Friendica\Core\Worker;
use Friendica\Database\DBA;
+use Friendica\Protocol\Activity;
use Friendica\Protocol\Diaspora;
use Friendica\Util\DateTimeFormat;
use Friendica\Util\Network;
$location .= $profile['locality'];
}
- if (!empty($profile['region']) && (defaults($profile, 'locality', '') != $profile['region'])) {
+ if (!empty($profile['region']) && (($profile['locality'] ?? '') != $profile['region'])) {
if ($location) {
$location .= ', ';
}
return $o;
}
- $profile['picdate'] = urlencode(defaults($profile, 'picdate', ''));
+ $profile['picdate'] = urlencode($profile['picdate'] ?? '');
if (($profile['network'] != '') && ($profile['network'] != Protocol::DFRN)) {
$profile['network_link'] = Strings::formatNetworkName($profile['network'], $profile['url']);
if (Contact::canReceivePrivateMessages($profile)) {
if ($visitor_is_followed || $visitor_is_following) {
- $wallmessage_link = $visitor_base_path . '/message/new/' . base64_encode(defaults($profile, 'addr', ''));
+ $wallmessage_link = $visitor_base_path . '/message/new/' . base64_encode($profile['addr'] ?? '');
} elseif ($visitor_is_authenticated && !empty($profile['unkmail'])) {
$wallmessage_link = 'wallmessage/' . $profile['nickname'];
}
$diaspora = [
'guid' => $profile['guid'],
'podloc' => System::baseUrl(),
- 'searchable' => (($profile['publish'] && $profile['net-publish']) ? 'true' : 'false' ),
+ 'searchable' => (($profile['publish'] && $profile['net-publish']) ? 'true' : 'false'),
'nickname' => $profile['nickname'],
'fullname' => $profile['name'],
'firstname' => $firstname,
'lastname' => $lastname,
- 'photo300' => defaults($profile, 'contact_photo', ''),
- 'photo100' => defaults($profile, 'contact_thumb', ''),
- 'photo50' => defaults($profile, 'contact_micro', ''),
+ 'photo300' => $profile['contact_photo'] ?? '',
+ 'photo100' => $profile['contact_thumb'] ?? '',
+ 'photo50' => $profile['contact_micro'] ?? '',
];
} else {
$diaspora = false;
$p['photo'] = ProxyUtils::proxifyUrl($p['photo'], false, ProxyUtils::SIZE_SMALL);
}
- $p['url'] = Contact::magicLink(defaults($p, 'url', $profile_url));
+ $p['url'] = Contact::magicLink(($p['url'] ?? '') ?: $profile_url);
$tpl = Renderer::getMarkupTemplate('profile_vcard.tpl');
$o .= Renderer::replaceMacros($tpl, [
while ($rr = DBA::fetch($s)) {
$condition = ['parent-uri' => $rr['uri'], 'uid' => $rr['uid'], 'author-id' => public_contact(),
- 'activity' => [Item::activityToIndex(ACTIVITY_ATTEND), Item::activityToIndex(ACTIVITY_ATTENDMAYBE)],
+ 'activity' => [Item::activityToIndex( Activity::ATTEND), Item::activityToIndex(Activity::ATTENDMAYBE)],
'visible' => true, 'deleted' => false];
if (!Item::exists($condition)) {
continue;
$profile['religion'] = [L10n::t('Religion:'), $a->profile['religion']];
}
- if ($txt = prepare_text($a->profile['about'])) {
+ if ($txt = BBCode::convert($a->profile['about'])) {
$profile['about'] = [L10n::t('About:'), $txt];
}
- if ($txt = prepare_text($a->profile['interest'])) {
+ if ($txt = BBCode::convert($a->profile['interest'])) {
$profile['interest'] = [L10n::t('Hobbies/Interests:'), $txt];
}
- if ($txt = prepare_text($a->profile['likes'])) {
+ if ($txt = BBCode::convert($a->profile['likes'])) {
$profile['likes'] = [L10n::t('Likes:'), $txt];
}
- if ($txt = prepare_text($a->profile['dislikes'])) {
+ if ($txt = BBCode::convert($a->profile['dislikes'])) {
$profile['dislikes'] = [L10n::t('Dislikes:'), $txt];
}
- if ($txt = prepare_text($a->profile['contact'])) {
+ if ($txt = BBCode::convert($a->profile['contact'])) {
$profile['contact'] = [L10n::t('Contact information and Social Networks:'), $txt];
}
- if ($txt = prepare_text($a->profile['music'])) {
+ if ($txt = BBCode::convert($a->profile['music'])) {
$profile['music'] = [L10n::t('Musical interests:'), $txt];
}
- if ($txt = prepare_text($a->profile['book'])) {
+ if ($txt = BBCode::convert($a->profile['book'])) {
$profile['book'] = [L10n::t('Books, literature:'), $txt];
}
- if ($txt = prepare_text($a->profile['tv'])) {
+ if ($txt = BBCode::convert($a->profile['tv'])) {
$profile['tv'] = [L10n::t('Television:'), $txt];
}
- if ($txt = prepare_text($a->profile['film'])) {
+ if ($txt = BBCode::convert($a->profile['film'])) {
$profile['film'] = [L10n::t('Film/dance/culture/entertainment:'), $txt];
}
- if ($txt = prepare_text($a->profile['romance'])) {
+ if ($txt = BBCode::convert($a->profile['romance'])) {
$profile['romance'] = [L10n::t('Love/Romance:'), $txt];
}
- if ($txt = prepare_text($a->profile['work'])) {
+ if ($txt = BBCode::convert($a->profile['work'])) {
$profile['work'] = [L10n::t('Work/employment:'), $txt];
}
- if ($txt = prepare_text($a->profile['education'])) {
+ if ($txt = BBCode::convert($a->profile['education'])) {
$profile['education'] = [L10n::t('School/education:'), $txt];
}
/**
* @file src/Model/Register.php
*/
+
namespace Friendica\Model;
use Friendica\Database\DBA;
*/
public static function createForInvitation()
{
- $code = Strings::getRandomName(8) . srand(1000, 9999);
+ $code = Strings::getRandomName(8) . random_int(1000, 9999);
$fields = [
'hash' => $code,
public static function saveOptions($data)
{
- $storagepath = defaults($data, 'storagepath', '');
+ $storagepath = $data['storagepath'] ?? '';
if ($storagepath === '' || !is_dir($storagepath)) {
return [
'storagepath' => L10n::t('Enter a valid existing folder')
{
$profile_base = System::baseUrl();
$profile_data = parse_url($profile_base);
- $profile_path = defaults($profile_data, 'path', '');
+ $profile_path = $profile_data['path'] ?? '';
$profile_base_friendica = $profile_data['host'] . $profile_path . '/profile/';
$profile_base_diaspora = $profile_data['host'] . $profile_path . '/u/';
<?php
+
/**
* @file src/Model/User.php
* @brief This file includes the User class with user related database functions
*/
+
namespace Friendica\Model;
use DivineOmega\PasswordExposed;
use Friendica\Core\System;
use Friendica\Core\Worker;
use Friendica\Database\DBA;
-use Friendica\Model\Photo;
use Friendica\Model\TwoFactor\AppSpecificPassword;
use Friendica\Object\Image;
use Friendica\Util\Crypto;
return DBA::selectFirst('user', $fields, ['uid' => $uid]);
}
+ /**
+ * Returns a user record based on it's GUID
+ *
+ * @param string $guid The guid of the user
+ * @param array $fields The fields to retrieve
+ * @param bool $active True, if only active records are searched
+ *
+ * @return array|boolean User record if it exists, false otherwise
+ * @throws Exception
+ */
+ public static function getByGuid(string $guid, array $fields = [], bool $active = true)
+ {
+ if ($active) {
+ $cond = ['guid' => $guid, 'account_expired' => false, 'account_removed' => false];
+ } else {
+ $cond = ['guid' => $guid];
+ }
+
+ return DBA::selectFirst('user', $fields, $cond);
+ }
+
/**
* @param string $nickname
* @param array $fields
* @return boolean|array
* @throws Exception
*/
- public static function getOwnerDataById($uid, $check_valid = true) {
- $r = DBA::fetchFirst("SELECT
+ public static function getOwnerDataById($uid, $check_valid = true)
+ {
+ $r = DBA::fetchFirst(
+ "SELECT
`contact`.*,
`user`.`prvkey` AS `uprvkey`,
`user`.`timezone`,
`user`.`page-flags`,
`user`.`account-type`,
`user`.`prvnets`,
- `user`.`account_removed`
+ `user`.`account_removed`,
+ `user`.`hidewall`
FROM `contact`
INNER JOIN `user`
ON `user`.`uid` = `contact`.`uid`
$user = $user_info;
}
- if (!isset($user['uid'])
+ if (
+ !isset($user['uid'])
|| !isset($user['password'])
|| !isset($user['legacy_password'])
) {
}
} elseif (is_int($user_info) || is_string($user_info)) {
if (is_int($user_info)) {
- $user = DBA::selectFirst('user', ['uid', 'password', 'legacy_password'],
+ $user = DBA::selectFirst(
+ 'user',
+ ['uid', 'password', 'legacy_password'],
[
'uid' => $user_info,
'blocked' => 0,
);
} else {
$fields = ['uid', 'password', 'legacy_password'];
- $condition = ["(`email` = ? OR `username` = ? OR `nickname` = ?)
+ $condition = [
+ "(`email` = ? OR `username` = ? OR `nickname` = ?)
AND NOT `blocked` AND NOT `account_expired` AND NOT `account_removed` AND `verified`",
- $user_info, $user_info, $user_info];
+ $user_info, $user_info, $user_info
+ ];
$user = DBA::selectFirst('user', $fields, $condition);
}
*/
public static function generateNewPassword()
{
- return ucfirst(Strings::getRandomName(8)) . mt_rand(1000, 9999);
+ return ucfirst(Strings::getRandomName(8)) . random_int(1000, 9999);
}
/**
*
* @param string $password
* @return bool
+ * @throws Exception
*/
public static function isPasswordExposed($password)
{
'cacheDirectory' => get_temppath() . '/password-exposed-cache/',
]);
- $PasswordExposedCHecker = new PasswordExposed\PasswordExposedChecker(null, $cache);
+ try {
+ $passwordExposedChecker = new PasswordExposed\PasswordExposedChecker(null, $cache);
+
+ return $passwordExposedChecker->passwordExposed($password) === PasswordExposed\PasswordStatus::EXPOSED;
+ } catch (\Exception $e) {
+ Logger::error('Password Exposed Exception: ' . $e->getMessage(), [
+ 'code' => $e->getCode(),
+ 'file' => $e->getFile(),
+ 'line' => $e->getLine(),
+ 'trace' => $e->getTraceAsString()
+ ]);
- return $PasswordExposedCHecker->passwordExposed($password) === PasswordExposed\PasswordStatus::EXPOSED;
+ return false;
+ }
}
/**
}
}
+ /// @todo Check if this part is really needed. We should have fetched all this data in advance
if (empty($username) || empty($email) || empty($nickname)) {
if ($openid_url) {
if (!Network::isUrlValid($openid_url)) {
}
// Check existing and deleted accounts for this nickname.
- if (DBA::exists('user', ['nickname' => $nickname])
+ if (
+ DBA::exists('user', ['nickname' => $nickname])
|| DBA::exists('userd', ['username' => $nickname])
) {
throw new Exception(L10n::t('Nickname is already registered. Please choose another.'));
*/
public static function sendRegisterPendingEmail($user, $sitename, $siteurl, $password)
{
- $body = Strings::deindent(L10n::t('
+ $body = Strings::deindent(L10n::t(
+ '
Dear %1$s,
Thank you for registering at %2$s. Your account is pending for approval by the administrator.
Login Name: %4$s
Password: %5$s
',
- $user['username'], $sitename, $siteurl, $user['nickname'], $password
+ $user['username'],
+ $sitename,
+ $siteurl,
+ $user['nickname'],
+ $password
));
return notification([
*/
public static function sendRegisterOpenEmail($user, $sitename, $siteurl, $password)
{
- $preamble = Strings::deindent(L10n::t('
- Dear %1$s,
+ $preamble = Strings::deindent(L10n::t(
+ '
+ Dear %1$s,
Thank you for registering at %2$s. Your account has been created.
- ',
- $user['username'], $sitename
+ ',
+ $user['username'],
+ $sitename
));
- $body = Strings::deindent(L10n::t('
+ $body = Strings::deindent(L10n::t(
+ '
The login details are as follows:
Site Location: %3$s
If you ever want to delete your account, you can do so at %3$s/removeme
Thank you and welcome to %2$s.',
- $user['nickname'], $sitename, $siteurl, $user['username'], $password
+ $user['nickname'],
+ $sitename,
+ $siteurl,
+ $user['username'],
+ $password
));
return notification([
if ($user['parent-uid'] == 0) {
// First add our own entry
- $identities = [['uid' => $user['uid'],
+ $identities = [[
+ 'uid' => $user['uid'],
'username' => $user['username'],
- 'nickname' => $user['nickname']]];
+ 'nickname' => $user['nickname']
+ ]];
// Then add all the children
- $r = DBA::select('user', ['uid', 'username', 'nickname'],
- ['parent-uid' => $user['uid'], 'account_removed' => false]);
+ $r = DBA::select(
+ 'user',
+ ['uid', 'username', 'nickname'],
+ ['parent-uid' => $user['uid'], 'account_removed' => false]
+ );
if (DBA::isResult($r)) {
$identities = array_merge($identities, DBA::toArray($r));
}
} else {
// First entry is our parent
- $r = DBA::select('user', ['uid', 'username', 'nickname'],
- ['uid' => $user['parent-uid'], 'account_removed' => false]);
+ $r = DBA::select(
+ 'user',
+ ['uid', 'username', 'nickname'],
+ ['uid' => $user['parent-uid'], 'account_removed' => false]
+ );
if (DBA::isResult($r)) {
$identities = DBA::toArray($r);
}
// Then add all siblings
- $r = DBA::select('user', ['uid', 'username', 'nickname'],
- ['parent-uid' => $user['parent-uid'], 'account_removed' => false]);
+ $r = DBA::select(
+ 'user',
+ ['uid', 'username', 'nickname'],
+ ['parent-uid' => $user['parent-uid'], 'account_removed' => false]
+ );
if (DBA::isResult($r)) {
$identities = array_merge($identities, DBA::toArray($r));
}
}
- $r = DBA::p("SELECT `user`.`uid`, `user`.`username`, `user`.`nickname`
+ $r = DBA::p(
+ "SELECT `user`.`uid`, `user`.`username`, `user`.`nickname`
FROM `manage`
INNER JOIN `user` ON `manage`.`mid` = `user`.`uid`
WHERE `user`.`account_removed` = 0 AND `manage`.`uid` = ?",
while ($user = DBA::fetch($userStmt)) {
$statistics['total_users']++;
- if ((strtotime($user['login_date']) > $halfyear) ||
- (strtotime($user['last-item']) > $halfyear)) {
+ if ((strtotime($user['login_date']) > $halfyear) || (strtotime($user['last-item']) > $halfyear)
+ ) {
$statistics['active_users_halfyear']++;
}
- if ((strtotime($user['login_date']) > $month) ||
- (strtotime($user['last-item']) > $month)) {
+ if ((strtotime($user['login_date']) > $month) || (strtotime($user['last-item']) > $month)
+ ) {
$statistics['active_users_monthly']++;
}
}
{
public static function content()
{
- $addr = defaults($_GET, 'addr', false);
+ $addr = trim($_GET['addr'] ?? '');
if ($addr) {
- $url = defaults(Probe::uri(trim($addr)), 'url', false);
+ $url = Probe::uri($addr)['url'] ?? '';
if ($url) {
System::externalRedirect($url);
$a->internalRedirect('admin/addons');
}
- if (defaults($_GET, 'action', '') == 'toggle') {
+ if (($_GET['action'] ?? '') == 'toggle') {
parent::checkFormSecurityTokenRedirectOnError('/admin/addons', 'admin_themes', 't');
// Toggle addon status
break;
case 'toggle' :
- $addon = defaults($_GET, 'addon', '');
+ $addon = $_GET['addon'] ?? '';
if (Addon::isEnabled($addon)) {
Addon::uninstall($addon);
info(L10n::t('Addon %s disabled.', $addon));
{
parent::post();
- $contact_url = defaults($_POST, 'contact_url', '');
- $block_reason = defaults($_POST, 'contact_block_reason', '');
- $contacts = defaults($_POST, 'contacts', []);
+ $contact_url = $_POST['contact_url'] ?? '';
+ $block_reason = $_POST['contact_block_reason'] ?? '';
+ $contacts = $_POST['contacts'] ?? [];
parent::checkFormSecurityTokenRedirectOnError('/admin/blocklist/contact', 'admin_contactblock');
$logfile = (!empty($_POST['logfile']) ? Strings::escapeTags(trim($_POST['logfile'])) : '');
$debugging = !empty($_POST['debugging']);
- $loglevel = defaults($_POST, 'loglevel', LogLevel::ERROR);
+ $loglevel = ($_POST['loglevel'] ?? '') ?: LogLevel::ERROR;
if (is_file($logfile) &&
!is_writeable($logfile)) {
/**
* @var $storagebackend \Friendica\Model\Storage\IStorage
*/
- $storagebackend = Strings::escapeTags(trim(defaults($_POST, 'storagebackend', '')));
+ $storagebackend = Strings::escapeTags(trim($_POST['storagebackend'] ?? ''));
// save storage backend form
if (!is_null($storagebackend) && $storagebackend != "") {
$value = !empty($_POST[$fieldname]);
break;
default:
- $value = defaults($_POST, $fieldname, '');
+ $value = $_POST[$fieldname] ?? '';
}
$storage_opts_data[$name] = $value;
}
use Friendica\Database\DBStructure;
use Friendica\Model\Register;
use Friendica\Module\BaseAdminModule;
+use Friendica\Network\HTTPException\InternalServerErrorException;
use Friendica\Util\ConfigFileLoader;
use Friendica\Util\DateTimeFormat;
+use Friendica\Util\FileSystem;
use Friendica\Util\Network;
class Summary extends BaseAdminModule
// Check logfile permission
if (Config::get('system', 'debugging')) {
- $stream = Config::get('system', 'logfile');
+ $file = Config::get('system', 'logfile');
- if (is_file($stream) &&
- !is_writeable($stream)) {
- $warningtext[] = L10n::t('The logfile \'%s\' is not writable. No logging possible', $stream);
+ /** @var FileSystem $fileSystem */
+ $fileSystem = self::getClass(FileSystem::class);
+
+ try {
+ $stream = $fileSystem->createStream($file);
+
+ if (!isset($stream)) {
+ throw new InternalServerErrorException('Stream is null.');
+ }
+
+ } catch (\Throwable $exception) {
+ $warningtext[] = L10n::t('The logfile \'%s\' is not usable. No logging possible (error: \'%s\')', $file, $exception->getMessage());
}
- $stream = Config::get('system', 'dlogfile');
+ $file = Config::get('system', 'dlogfile');
+
+ try {
+ if (!empty($file)) {
+ $stream = $fileSystem->createStream($file);
+
+ if (!isset($stream)) {
+ throw new InternalServerErrorException('Stream is null.');
+ }
+ }
- if (is_file($stream) &&
- !is_writeable($stream)) {
- $warningtext[] = L10n::t('The logfile \'%s\' is not writable. No logging possible', $stream);
+ } catch (\Throwable $exception) {
+ $warningtext[] = L10n::t('The debug logfile \'%s\' is not usable. No logging possible (error: \'%s\')', $file, $exception->getMessage());
}
}
break;
case 'toggle' :
- $theme = defaults($_GET, 'addon', '');
+ $theme = $_GET['addon'] ?? '';
if ($theme) {
$theme = Strings::sanitizeFilePathItem($theme);
if (!is_dir("view/theme/$theme")) {
$a = self::getApp();
- $pending = defaults($_POST, 'pending' , []);
- $users = defaults($_POST, 'user' , []);
- $nu_name = defaults($_POST, 'new_user_name' , '');
- $nu_nickname = defaults($_POST, 'new_user_nickname', '');
- $nu_email = defaults($_POST, 'new_user_email' , '');
+ $pending = $_POST['pending'] ?? [];
+ $users = $_POST['user'] ?? [];
+ $nu_name = $_POST['new_user_name'] ?? '';
+ $nu_nickname = $_POST['new_user_nickname'] ?? '';
+ $nu_email = $_POST['new_user_email'] ?? '';
$nu_language = Config::get('system', 'language');
parent::checkFormSecurityTokenRedirectOnError('/admin/users', 'admin_users');
$entry = [
'url' => Model\Contact::magicLinkbyId($friend['id'], $friend['url']),
- 'itemurl' => defaults($contactDetails, 'addr', $friend['url']),
+ 'itemurl' => ($contactDetails['addr'] ?? '') ?: $friend['url'],
'name' => $contactDetails['name'],
'thumb' => ProxyUtils::proxifyUrl($contactDetails['thumb'], false, ProxyUtils::SIZE_THUMB),
'img_hover' => $contactDetails['name'],
return $output;
}
- $referer = Strings::normaliseLink(defaults($_SERVER, 'HTTP_REFERER', ''));
+ $referer = Strings::normaliseLink($_SERVER['HTTP_REFERER'] ?? '');
$page = Strings::normaliseLink($app->getBaseURL() . "/bookmarklet");
if (!strstr($referer, $page)) {
'bang' => '',
'visitor' => 'block',
'profile_uid' => local_user(),
- 'title' => trim(defaults($_REQUEST, 'title', ''), '*'),
+ 'title' => trim($_REQUEST['title'] ?? '', '*'),
'content' => $content
];
$output = status_editor($app, $x, 0, false);
Hook::callAll('contact_edit_post', $_POST);
- $profile_id = intval(defaults($_POST, 'profile-assign', 0));
+ $profile_id = intval($_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);
$notify = !empty($_POST['notify']);
- $fetch_further_information = intval(defaults($_POST, 'fetch_further_information', 0));
+ $fetch_further_information = intval($_POST['fetch_further_information'] ?? 0);
- $ffi_keyword_blacklist = Strings::escapeHtml(trim(defaults($_POST, 'ffi_keyword_blacklist', '')));
+ $ffi_keyword_blacklist = Strings::escapeHtml(trim($_POST['ffi_keyword_blacklist'] ?? ''));
- $priority = intval(defaults($_POST, 'poll', 0));
+ $priority = intval($_POST['poll'] ?? 0);
if ($priority > 5 || $priority < 0) {
$priority = 0;
}
- $info = Strings::escapeHtml(trim(defaults($_POST, 'info', '')));
+ $info = Strings::escapeHtml(trim($_POST['info'] ?? ''));
$r = DBA::update('contact', [
'profile-id' => $profile_id,
Model\GContact::updateFromProbe($contact['url']);
}
+ /**
+ * Toggles the blocked status of a contact identified by id.
+ *
+ * @param $contact_id
+ * @throws \Exception
+ */
private static function blockContact($contact_id)
{
$blocked = !Model\Contact::isBlockedByUser($contact_id, local_user());
Model\Contact::setBlockedForUser($contact_id, local_user(), $blocked);
}
+ /**
+ * Toggles the ignored status of a contact identified by id.
+ *
+ * @param $contact_id
+ * @throws \Exception
+ */
private static function ignoreContact($contact_id)
{
$ignored = !Model\Contact::isIgnoredByUser($contact_id, local_user());
Model\Contact::setIgnoredForUser($contact_id, local_user(), $ignored);
}
+ /**
+ * Toggles the archived status of a contact identified by id.
+ * If the current status isn't provided, this will always archive the contact.
+ *
+ * @param $contact_id
+ * @param $orig_record
+ * @return bool
+ * @throws \Exception
+ */
private static function archiveContact($contact_id, $orig_record)
{
- $archived = (defaults($orig_record, 'archive', '') ? 0 : 1);
+ $archived = empty($orig_record['archive']);
$r = DBA::update('contact', ['archive' => $archived], ['id' => $contact_id, 'uid' => local_user()]);
return DBA::isResult($r);
$a = self::getApp();
- $nets = defaults($_GET, 'nets', '');
- $rel = defaults($_GET, 'rel' , '');
+ $nets = $_GET['nets'] ?? '';
+ $rel = $_GET['rel'] ?? '';
if (empty($a->page['aside'])) {
$a->page['aside'] = '';
'$name' => $contact['name'],
'$photo' => $contact['photo'],
'$url' => Model\Contact::magicLinkByContact($contact, $contact['url']),
- '$addr' => defaults($contact, 'addr', ''),
+ '$addr' => $contact['addr'] ?? '',
'$network_link' => $network_link,
'$network' => L10n::t('Network:'),
'$account_type' => Model\Contact::getAccountType($contact),
}
// @TODO: Replace with parameter from router
- $type = defaults($a->argv, 1, '');
+ $type = $a->argv[1] ?? '';
switch ($type) {
case 'blocked':
$sql_extra .= sprintf(" AND `network` != '%s' ", Protocol::PHANTOM);
- $search = Strings::escapeTags(trim(defaults($_GET, 'search', '')));
- $nets = Strings::escapeTags(trim(defaults($_GET, 'nets' , '')));
- $rel = Strings::escapeTags(trim(defaults($_GET, 'rel' , '')));
+ $search = Strings::escapeTags(trim($_GET['search'] ?? ''));
+ $nets = Strings::escapeTags(trim($_GET['nets'] ?? ''));
+ $rel = Strings::escapeTags(trim($_GET['rel'] ?? ''));
$tabs = [
[
'username' => $rr['name'],
'account_type' => Model\Contact::getAccountType($rr),
'sparkle' => $sparkle,
- 'itemurl' => defaults($rr, 'addr', $rr['url']),
+ 'itemurl' => ($rr['addr'] ?? '') ?: $rr['url'],
'url' => $url,
'network' => ContactSelector::networkToName($rr['network'], $rr['url']),
'nick' => $rr['nick'],
$results = [];
if (!empty($_REQUEST['text'])) {
- switch (defaults($_REQUEST, 'type', 'bbcode')) {
+ switch (($_REQUEST['type'] ?? '') ?: 'bbcode') {
case 'bbcode':
$bbcode = trim($_REQUEST['text']);
$results[] = [
$tpl = Renderer::getMarkupTemplate('babel.tpl');
$o = Renderer::replaceMacros($tpl, [
- '$text' => ['text', L10n::t('Source text'), 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'],
+ '$text' => ['text', L10n::t('Source text'), $_REQUEST['text'] ?? '', ''],
+ '$type_bbcode' => ['type', L10n::t('BBCode'), 'bbcode', '', (($_REQUEST['type'] ?? '') ?: 'bbcode') == 'bbcode'],
+ '$type_markdown' => ['type', L10n::t('Markdown'), 'markdown', '', (($_REQUEST['type'] ?? '') ?: 'bbcode') == 'markdown'],
+ '$type_html' => ['type', L10n::t('HTML'), 'html', '', (($_REQUEST['type'] ?? '') ?: 'bbcode') == 'html'],
'$results' => $results
]);
$tpl = Renderer::getMarkupTemplate('feedtest.tpl');
return Renderer::replaceMacros($tpl, [
- '$url' => ['url', L10n::t('Source URL'), defaults($_REQUEST, 'url', ''), ''],
+ '$url' => ['url', L10n::t('Source URL'), $_REQUEST['url'] ?? '', ''],
'$result' => $result
]);
}
{
public static function post()
{
- $time = defaults($_REQUEST, 'time', 'now');
+ $time = ($_REQUEST['time'] ?? '') ?: 'now';
$bd_format = L10n::t('l F d, Y \@ g:i A');
{
$app = self::getApp();
- $time = defaults($_REQUEST, 'time', 'now');
+ $time = ($_REQUEST['time'] ?? '') ?: 'now';
$output = '<h3>' . L10n::t('Time Conversion') . '</h3>';
$output .= '<p>' . L10n::t('Friendica provides this service for sharing events with other networks and friends in unknown timezones.') . '</p>';
$output .= '<form action ="' . $app->getBaseURL() . '/localtime?time=' . $time . '" method="post" >';
$output .= '<p>' . L10n::t('Please select your timezone:') . '</p>';
- $output .= Temporal::getTimezoneSelect(defaults($_REQUEST, 'timezone', Installer::DEFAULT_TZ));
+ $output .= Temporal::getTimezoneSelect(($_REQUEST['timezone'] ?? '') ?: Installer::DEFAULT_TZ);
$output .= '<input type="submit" name="submit" value="' . L10n::t('Submit') . '" /></form>';
return $output;
throw $e;
}
- $addr = defaults($_GET, 'addr', '');
+ $addr = $_GET['addr'] ?? '';
$res = '';
if (!empty($addr)) {
throw $e;
}
- $addr = defaults($_GET, 'addr', '');
+ $addr = $_GET['addr'] ?? '';
$res = '';
if (!empty($addr)) {
--- /dev/null
+<?php
+
+namespace Friendica\Module;
+
+use Friendica\BaseModule;
+use Friendica\Core\Hook;
+use Friendica\Core\L10n;
+use Friendica\Core\Renderer;
+use Friendica\Core\Session;
+use Friendica\Database\DBA;
+use Friendica\Model\Contact;
+use Friendica\Model\User;
+use Friendica\Network\HTTPException\ForbiddenException;
+
+/**
+ * Switches current user between delegates/parent user
+ */
+class Delegation extends BaseModule
+{
+ public static function post()
+ {
+ if (!local_user()) {
+ return;
+ }
+
+ $uid = local_user();
+ $orig_record = self::getApp()->user;
+
+ if (Session::get('submanage')) {
+ $user = User::getById(Session::get('submanage'));
+ if (DBA::isResult($user)) {
+ $uid = intval($user['uid']);
+ $orig_record = $user;
+ }
+ }
+
+ $identity = intval($_POST['identity'] ?? 0);
+ if (!$identity) {
+ return;
+ }
+
+ $limited_id = 0;
+ $original_id = $uid;
+
+ $manages = DBA::selectToArray('manage', ['mid'], ['uid' => $uid]);
+ foreach ($manages as $manage) {
+ if ($identity == $manage['mid']) {
+ $limited_id = $manage['mid'];
+ break;
+ }
+ }
+
+ if ($limited_id) {
+ $user = User::getById($limited_id);
+ } else {
+ // Check if the target user is one of our children
+ $user = DBA::selectFirst('user', [], ['uid' => $identity, 'parent-uid' => $orig_record['uid']]);
+
+ // Check if the target user is one of our siblings
+ if (!DBA::isResult($user) && ($orig_record['parent-uid'] != 0)) {
+ $user = DBA::selectFirst('user', [], ['uid' => $identity, 'parent-uid' => $orig_record['parent-uid']]);
+ }
+
+ // Check if it's our parent or our own user
+ if (!DBA::isResult($user)
+ && (
+ $orig_record['parent-uid'] != 0 && $orig_record['parent-uid'] == $identity
+ ||
+ $orig_record['uid'] != 0 && $orig_record['uid'] == $identity
+ )
+ ) {
+ $user = User::getById($identity);
+ }
+ }
+
+ if (!DBA::isResult($user)) {
+ return;
+ }
+
+ Session::clear();
+
+ Session::setAuthenticatedForUser(self::getApp(), $user, true, true);
+
+ if ($limited_id) {
+ Session::set('submanage', $original_id);
+ }
+
+ $ret = [];
+ Hook::callAll('home_init', $ret);
+
+ self::getApp()->internalRedirect('profile/' . self::getApp()->user['nickname']);
+ // NOTREACHED
+ }
+
+ public static function content()
+ {
+ if (!local_user()) {
+ throw new ForbiddenException(L10n::t('Permission denied.'));
+ }
+
+ $identities = self::getApp()->identities;
+
+ //getting additinal information for each identity
+ foreach ($identities as $key => $identity) {
+ $thumb = Contact::selectFirst(['thumb'], ['uid' => $identity['uid'], 'self' => true]);
+ if (!DBA::isResult($thumb)) {
+ continue;
+ }
+
+ $identities[$key]['thumb'] = $thumb['thumb'];
+
+ $identities[$key]['selected'] = ($identity['nickname'] === self::getApp()->user['nickname']);
+
+ $condition = ["`uid` = ? AND `msg` != '' AND NOT (`type` IN (?, ?)) AND NOT `seen`", $identity['uid'], NOTIFY_INTRO, NOTIFY_MAIL];
+ $params = ['distinct' => true, 'expression' => 'parent'];
+ $notifications = DBA::count('notify', $condition, $params);
+
+ $params = ['distinct' => true, 'expression' => 'convid'];
+ $notifications += DBA::count('mail', ['uid' => $identity['uid'], 'seen' => false], $params);
+
+ $notifications += DBA::count('intro', ['blocked' => false, 'ignore' => false, 'uid' => $identity['uid']]);
+
+ $identities[$key]['notifications'] = $notifications;
+ }
+
+ $o = Renderer::replaceMacros(Renderer::getMarkupTemplate('delegation.tpl'), [
+ '$title' => L10n::t('Manage Identities and/or Pages'),
+ '$desc' => L10n::t('Toggle between different identities or community/group pages which share your account details or which you have been granted "manage" permissions'),
+ '$choose' => L10n::t('Select an identity to manage: '),
+ '$identities' => $identities,
+ '$submit' => L10n::t('Submit'),
+ ]);
+
+ return $o;
+ }
+}
--- /dev/null
+<?php
+
+namespace Friendica\Module\Diaspora;
+
+use Friendica\App;
+use Friendica\BaseModule;
+use Friendica\Core\Config\Configuration;
+use Friendica\Core\L10n\L10n;
+use Friendica\Model\User;
+use Friendica\Network\HTTPException;
+use Friendica\Protocol\Diaspora;
+use Friendica\Util\Network;
+use Psr\Log\LoggerInterface;
+
+/**
+ * This module is part of the Diaspora protocol.
+ * It is used for receiving single posts either for public or for a specific user.
+ */
+class Receive extends BaseModule
+{
+ /** @var LoggerInterface */
+ private static $logger;
+
+ public static function init()
+ {
+ /** @var LoggerInterface $logger */
+ self::$logger = self::getClass(LoggerInterface::class);
+ }
+
+ public static function post()
+ {
+ /** @var Configuration $config */
+ $config = self::getClass(Configuration::class);
+
+ $enabled = $config->get('system', 'diaspora_enabled', false);
+ if (!$enabled) {
+ self::$logger->info('Diaspora disabled.');
+ $l10n = self::getClass(L10n::class);
+ throw new HTTPException\ForbiddenException($l10n->t('Access denied.'));
+ }
+
+ /** @var App\Arguments $args */
+ $args = self::getClass(App\Arguments::class);
+
+ $type = $args->get(1);
+
+ switch ($type) {
+ case 'public':
+ self::receivePublic();
+ break;
+ case 'users':
+ self::receiveUser($args->get(2));
+ break;
+ default:
+ self::$logger->info('Wrong call.');
+ throw new HTTPException\BadRequestException('wrong call.');
+ break;
+ }
+ }
+
+ /**
+ * Receive a public Diaspora posting
+ *
+ * @throws HTTPException\InternalServerErrorException
+ * @throws \ImagickException
+ */
+ private static function receivePublic()
+ {
+ self::$logger->info('Diaspora: Receiving post.');
+
+ $msg = self::decodePost();
+
+ self::$logger->info('Diaspora: Dispatching.');
+
+ Diaspora::dispatchPublic($msg);
+ }
+
+ /**
+ * Receive a Diaspora posting for a user
+ *
+ * @param string $guid The GUID of the importer
+ *
+ * @throws HTTPException\InternalServerErrorException
+ * @throws \ImagickException
+ */
+ private static function receiveUser(string $guid)
+ {
+ self::$logger->info('Diaspora: Receiving post.');
+
+ $importer = User::getByGuid($guid);
+
+ $msg = self::decodePost(false, $importer['prvkey'] ?? '');
+
+ self::$logger->info('Diaspora: Dispatching.');
+
+ if (Diaspora::dispatch($importer, $msg)) {
+ throw new HTTPException\OKException();
+ } else {
+ throw new HTTPException\InternalServerErrorException();
+ }
+ }
+
+ /**
+ * Decodes a Diaspora message based on the posted data
+ *
+ * @param string $privKey The private key of the importer
+ * @param bool $public True, if the post is public
+ *
+ * @return array
+ * @throws HTTPException\InternalServerErrorException
+ * @throws \ImagickException
+ */
+ private static function decodePost(bool $public = true, string $privKey = '')
+ {
+ if (empty($_POST['xml'])) {
+
+ $postdata = Network::postdata();
+
+ if (empty($postdata)) {
+ throw new HTTPException\InternalServerErrorException('Missing postdata.');
+ }
+
+ self::$logger->info('Diaspora: Message is in the new format.');
+
+ $msg = Diaspora::decodeRaw($postdata, $privKey);
+ } else {
+
+ $xml = urldecode($_POST['xml']);
+
+ self::$logger->info('Diaspora: Decode message in the old format.');
+ $msg = Diaspora::decode($xml, $privKey);
+
+ if ($public && !$msg) {
+ self::$logger->info('Diaspora: Decode message in the new format.');
+ $msg = Diaspora::decodeRaw($xml, $privKey);
+ }
+ }
+
+ self::$logger->info('Diaspora: Post decoded.');
+ self::$logger->debug('Diaspora: Decoded message.', ['msg' => print_r($msg, true)]);
+
+ if (!is_array($msg)) {
+ throw new HTTPException\InternalServerErrorException('Message is not an array.');
+ }
+
+ return $msg;
+ }
+}
{
$a = self::getApp();
- $last_update = defaults($_GET, 'last_update', '');
+ $last_update = $_GET['last_update'] ?? '';
$nocache = !empty($_GET['nocache']) && local_user();
// @TODO: Replace with parameter from router
$item_id = (($app->argc > 1) ? intval($app->argv[1]) : 0);
- $term = XML::unescape(trim(defaults($_GET, 'term', '')));
- $cat = XML::unescape(trim(defaults($_GET, 'cat', '')));
+ $term = XML::unescape(trim($_GET['term'] ?? ''));
+ $cat = XML::unescape(trim($_GET['cat'] ?? ''));
$category = (($cat) ? true : false);
$a = self::getApp();
$logger = $a->getLogger();
- $term = XML::unescape(trim(defaults($_GET, 'term', '')));
+ $term = XML::unescape(trim($_GET['term'] ?? ''));
// @TODO: Replace with parameter from router
$item_id = (($a->argc > 1) ? intval($a->argv[1]) : 0);
return;
}
- $intro_id = intval(defaults($_POST, 'intro_id' , 0));
- $duplex = intval(defaults($_POST, 'duplex' , 0));
- $cid = intval(defaults($_POST, 'contact_id', 0));
- $hidden = intval(defaults($_POST, 'hidden' , 0));
+ $intro_id = intval($_POST['intro_id'] ?? 0);
+ $duplex = intval($_POST['duplex'] ?? 0);
+ $cid = intval($_POST['contact_id'] ?? 0);
+ $hidden = intval($_POST['hidden'] ?? 0);
if (empty($cid)) {
notice(L10n::t('No given contact.') . EOL);
throw new \Friendica\Network\HTTPException\NotFoundException();
}
- $page = defaults($_REQUEST, 'page', null);
+ $page = $_REQUEST['page'] ?? null;
$followers = ActivityPub\Transmitter::getFollowers($owner, $page);
throw new \Friendica\Network\HTTPException\NotFoundException();
}
- $page = defaults($_REQUEST, 'page', null);
+ $page = $_REQUEST['page'] ?? null;
$Following = ActivityPub\Transmitter::getFollowing($owner, $page);
--- /dev/null
+<?php
+
+namespace Friendica\Module\HTTPException;
+
+use Friendica\BaseModule;
+use Friendica\Core\L10n;
+use Friendica\Network\HTTPException;
+
+class MethodNotAllowed extends BaseModule
+{
+ public static function content()
+ {
+ throw new HTTPException\MethodNotAllowedException(L10n::t('Method Not Allowed.'));
+ }
+}
--- /dev/null
+<?php
+
+namespace Friendica\Module\HTTPException;
+
+use Friendica\BaseModule;
+use Friendica\Core\L10n;
+use Friendica\Network\HTTPException;
+
+class PageNotFound extends BaseModule
+{
+ public static function content()
+ {
+ throw new HTTPException\NotFoundException(L10n::t('Page not found.'));
+ }
+}
// so we may not have a css at all. Here we set a static css file for the install procedure pages
Renderer::$theme['stylesheet'] = $a->getBaseURL() . '/view/install/style.css';
- self::$currentWizardStep = defaults($_POST, 'pass', self::SYSTEM_CHECK);
+ self::$currentWizardStep = ($_POST['pass'] ?? '') ?: self::SYSTEM_CHECK;
}
public static function post()
{
$configCache->set($cat, $key,
Strings::escapeTags(
- trim(defaults($post, sprintf('%s-%s', $cat, $key),
- (!isset($default) ? $configCache->get($cat, $key) : $default))
+ trim(($post[sprintf('%s-%s', $cat, $key)] ?? '') ?:
+ ($default ?? $configCache->get($cat, $key))
)
)
);
use Friendica\Model\User;
use Friendica\Module\Login;
use Friendica\Network\HTTPException\NotImplementedException;
+use Friendica\Util\ACLFormatter;
use Friendica\Util\Crypto;
class Compose extends BaseModule
$user = User::getById(local_user(), ['allow_cid', 'allow_gid', 'deny_cid', 'deny_gid', 'hidewall', 'default-location']);
+ /** @var ACLFormatter $aclFormatter */
+ $aclFormatter = self::getClass(ACLFormatter::class);
+
switch ($posttype) {
case Item::PT_PERSONAL_NOTE:
$compose_title = L10n::t('Compose new personal note');
$compose_title = L10n::t('Compose new post');
$type = 'post';
$doesFederate = true;
- $contact_allow = implode(',', expand_acl($user['allow_cid']));
- $group_allow = implode(',', expand_acl($user['allow_gid'])) ?: Group::FOLLOWERS;
+ $contact_allow = implode(',', $aclFormatter->expand($user['allow_cid']));
+ $group_allow = implode(',', $aclFormatter->expand($user['allow_gid'])) ?: Group::FOLLOWERS;
break;
}
$wall = $_REQUEST['wall'] ?? $type == 'post';
$contact_allow = $_REQUEST['contact_allow'] ?? $contact_allow;
$group_allow = $_REQUEST['group_allow'] ?? $group_allow;
- $contact_deny = $_REQUEST['contact_deny'] ?? implode(',', expand_acl($user['deny_cid']));
- $group_deny = $_REQUEST['group_deny'] ?? implode(',', expand_acl($user['deny_gid']));
+ $contact_deny = $_REQUEST['contact_deny'] ?? implode(',', $aclFormatter->expand($user['deny_cid']));
+ $group_deny = $_REQUEST['group_deny'] ?? implode(',', $aclFormatter->expand($user['deny_gid']));
$visibility = ($contact_allow . $user['allow_gid'] . $user['deny_cid'] . $user['deny_gid']) ? 'custom' : 'public';
$acl_contacts = Contact::selectToArray(['id', 'name', 'addr', 'micro'], ['uid' => local_user(), 'pending' => false, 'rel' => [Contact::FOLLOWER, Contact::FRIEND]]);
--- /dev/null
+<?php
+
+namespace Friendica\Module\Item;
+
+use Friendica\App;
+use Friendica\BaseModule;
+use Friendica\Core\L10n\L10n;
+use Friendica\Core\Session;
+use Friendica\Core\System;
+use Friendica\Database\Database;
+use Friendica\Model\Item;
+use Friendica\Network\HTTPException;
+
+/**
+ * Module for ignoring threads or user items
+ */
+class Ignore extends BaseModule
+{
+ public static function rawContent()
+ {
+ /** @var L10n $l10n */
+ $l10n = self::getClass(L10n::class);
+
+ if (!Session::isAuthenticated()) {
+ throw new HttpException\ForbiddenException($l10n->t('Access denied.'));
+ }
+
+ /** @var App\Arguments $args */
+ $args = self::getClass(App\Arguments::class);
+ /** @var Database $dba */
+ $dba = self::getClass(Database::class);
+
+ $message_id = intval($args->get(2));
+
+ if (empty($message_id) || !is_int($message_id)) {
+ throw new HTTPException\BadRequestException();
+ }
+
+ $thread = Item::selectFirstThreadForUser(local_user(), ['uid', 'ignored'], ['iid' => $message_id]);
+ if (!$dba->isResult($thread)) {
+ throw new HTTPException\BadRequestException();
+ }
+
+ // Numeric values are needed for the json output further below
+ $ignored = !empty($thread['ignored']) ? 0 : 1;
+
+ switch ($thread['uid'] ?? 0) {
+ // if the thread is from the current user
+ case local_user():
+ $dba->update('thread', ['ignored' => $ignored], ['iid' => $message_id]);
+ break;
+ // 0 (null will get transformed to 0) => it's a public post
+ case 0:
+ $dba->update('user-item', ['ignored' => $ignored], ['iid' => $message_id, 'uid' => local_user()], true);
+ break;
+ // Throws a BadRequestException and not a ForbiddenException on purpose
+ // Avoids harvesting existing, but forbidden IIDs (security issue)
+ default:
+ throw new HTTPException\BadRequestException();
+ }
+
+ // See if we've been passed a return path to redirect to
+ $return_path = $_REQUEST['return'] ?? '';
+ if (!empty($return_path)) {
+ $rand = '_=' . time();
+ if (strpos($return_path, '?')) {
+ $rand = "&$rand";
+ } else {
+ $rand = "?$rand";
+ }
+
+ self::getApp()->internalRedirect($return_path . $rand);
+ }
+
+ // the json doesn't really matter, it will either be 0 or 1
+ System::jsonExit([$ignored]);
+ }
+}
// Decide how to return. If we were called with a 'return' argument,
// then redirect back to the calling page. If not, just quietly end
- $returnPath = defaults($_REQUEST, 'return', '');
+ $returnPath = $_REQUEST['return'] ?? '';
if (!empty($returnPath)) {
$rand = '_=' . time();
<?php
+
/**
* @file src/Module/Login.php
*/
+
namespace Friendica\Module;
use Exception;
public static function post()
{
+ $openid_identity = Session::get('openid_identity');
+ $openid_server = Session::get('openid_server');
+
$return_path = Session::get('return_path');
session_unset();
Session::set('return_path', $return_path);
// OpenId Login
if (
empty($_POST['password'])
- && (
- !empty($_POST['openid_url'])
- || !empty($_POST['username'])
- )
+ && (!empty($_POST['openid_url'])
+ || !empty($_POST['username']))
) {
- $openid_url = trim(defaults($_POST, 'openid_url', $_POST['username']));
+ $openid_url = trim(($_POST['openid_url'] ?? '') ?: $_POST['username']);
self::openIdAuthentication($openid_url, !empty($_POST['remember']));
}
self::passwordAuthentication(
trim($_POST['username']),
trim($_POST['password']),
- !empty($_POST['remember'])
+ !empty($_POST['remember']),
+ $openid_identity,
+ $openid_server
);
}
}
try {
$openid = new LightOpenID($a->getHostName());
$openid->identity = $openid_url;
- $_SESSION['openid'] = $openid_url;
- $_SESSION['remember'] = $remember;
+ Session::set('openid', $openid_url);
+ Session::set('remember', $remember);
$openid->returnUrl = $a->getBaseURL(true) . '/openid';
+ $openid->optional = ['namePerson/friendly', 'contact/email', 'namePerson', 'namePerson/first', 'media/image/aspect11', 'media/image/default'];
System::externalRedirect($openid->authUrl());
} catch (Exception $e) {
notice(L10n::t('We encountered a problem while logging in with the OpenID you provided. Please check the correct spelling of the ID.') . '<br /><br >' . L10n::t('The error message was:') . ' ' . $e->getMessage());
/**
* Attempts to authenticate using login/password
*
- * @param string $username User name
- * @param string $password Clear password
- * @param bool $remember Whether to set the session remember flag
+ * @param string $username User name
+ * @param string $password Clear password
+ * @param bool $remember Whether to set the session remember flag
+ * @param string $openid_identity OpenID identity
+ * @param string $openid_server OpenID URL
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
- private static function passwordAuthentication($username, $password, $remember)
+ private static function passwordAuthentication($username, $password, $remember, $openid_identity, $openid_server)
{
$record = null;
throw new Exception(L10n::t('Login failed.'));
}
} else {
- $record = DBA::selectFirst('user', [],
+ $record = DBA::selectFirst(
+ 'user',
+ [],
['uid' => User::getIdFromPasswordAuthentication($username, $password)]
);
}
Session::set('remember', $remember);
Session::set('last_login_date', DateTimeFormat::utcNow());
+ if (!empty($openid_identity) || !empty($openid_server)) {
+ DBA::update('user', ['openid' => $openid_identity, 'openidserver' => $openid_server], ['uid' => $record['uid']]);
+ }
+
Session::setAuthenticatedForUser($a, $record, true, true);
$return_path = Session::get('return_path', '');
$data = json_decode($_COOKIE["Friendica"]);
if (isset($data->uid)) {
- $user = DBA::selectFirst('user', [],
+ $user = DBA::selectFirst(
+ 'user',
+ [],
[
'uid' => $data->uid,
'blocked' => false,
]
);
if (DBA::isResult($user)) {
- if ($data->hash != Authentication::getCookieHashForUser($user)) {
+ if (!hash_equals(
+ Authentication::getCookieHashForUser($user),
+ $data->hash
+ )) {
Logger::log("Hash for user " . $data->uid . " doesn't fit.");
Authentication::deleteSession();
$a->internalRedirect();
$a->internalRedirect();
}
- $user = DBA::selectFirst('user', [],
+ $user = DBA::selectFirst(
+ 'user',
+ [],
[
'uid' => $_SESSION['uid'],
'blocked' => false,
{
$a = self::getApp();
$o = '';
+
+ $noid = Config::get('system', 'no_openid');
+
+ if ($noid) {
+ Session::remove('openid_identity');
+ Session::remove('openid_attributes');
+ }
+
$reg = false;
if ($register && intval($a->getConfig()->get('config', 'register_policy')) !== Register::CLOSED) {
$reg = [
'title' => L10n::t('Create a New Account'),
- 'desc' => L10n::t('Register')
+ 'desc' => L10n::t('Register'),
+ 'url' => self::getRegisterURL()
];
}
- $noid = Config::get('system', 'no_openid');
-
if (is_null($return_path)) {
$return_path = $a->query_string;
}
$_SESSION['return_path'] = $return_path;
}
+ if (!empty(Session::get('openid_identity'))) {
+ $openid_title = L10n::t('Your OpenID: ');
+ $openid_readonly = true;
+ $identity = Session::get('openid_identity');
+ $username_desc = L10n::t('Please enter your username and password to add the OpenID to your existing account.');
+ } else {
+ $openid_title = L10n::t('Or login using OpenID: ');
+ $openid_readonly = false;
+ $identity = '';
+ $username_desc = '';
+ }
+
$o .= Renderer::replaceMacros(
$tpl,
[
'$logout' => L10n::t('Logout'),
'$login' => L10n::t('Login'),
- '$lname' => ['username', L10n::t('Nickname or Email: ') , '', ''],
+ '$lname' => ['username', L10n::t('Nickname or Email: '), '', $username_desc],
'$lpassword' => ['password', L10n::t('Password: '), '', ''],
'$lremember' => ['remember', L10n::t('Remember me'), 0, ''],
'$openid' => !$noid,
- '$lopenid' => ['openid_url', L10n::t('Or login using OpenID: '),'',''],
+ '$lopenid' => ['openid_url', $openid_title, $identity, '', $openid_readonly],
'$hiddens' => $hiddens,
return $o;
}
+
+ /**
+ * Get the URL to the register page and add OpenID parameters to it
+ */
+ private static function getRegisterURL()
+ {
+ if (empty(Session::get('openid_identity'))) {
+ return 'register';
+ }
+
+ $args = [];
+ $attr = Session::get('openid_attributes', []);
+
+ if (is_array($attr) && count($attr)) {
+ foreach ($attr as $k => $v) {
+ if ($k === 'namePerson/friendly') {
+ $nick = Strings::escapeTags(trim($v));
+ }
+ if ($k === 'namePerson/first') {
+ $first = Strings::escapeTags(trim($v));
+ }
+ if ($k === 'namePerson') {
+ $args['username'] = Strings::escapeTags(trim($v));
+ }
+ if ($k === 'contact/email') {
+ $args['email'] = Strings::escapeTags(trim($v));
+ }
+ if ($k === 'media/image/aspect11') {
+ $photosq = bin2hex(trim($v));
+ }
+ if ($k === 'media/image/default') {
+ $photo = bin2hex(trim($v));
+ }
+ }
+ }
+
+ if (!empty($nick)) {
+ $args['nickname'] = $nick;
+ } elseif (!empty($first)) {
+ $args['nickname'] = $first;
+ }
+
+ if (!empty($photosq)) {
+ $args['photo'] = $photosq;
+ } elseif (!empty($photo)) {
+ $args['photo'] = $photo;
+ }
+
+ $args['openid_url'] = Strings::escapeTags(trim(Session::get('openid_identity')));
+
+ return 'register?' . http_build_query($args);
+ }
}
Logger::log('args: ' . print_r($_REQUEST, true), Logger::DATA);
- $addr = defaults($_REQUEST, 'addr', '');
- $dest = defaults($_REQUEST, 'dest', '');
+ $addr = $_REQUEST['addr'] ?? '';
+ $dest = $_REQUEST['dest'] ?? '';
$test = (!empty($_REQUEST['test']) ? intval($_REQUEST['test']) : 0);
$owa = (!empty($_REQUEST['owa']) ? intval($_REQUEST['owa']) : 0);
$cid = 0;
namespace Friendica\Module\Notifications;
use Friendica\BaseModule;
+use Friendica\BaseObject;
use Friendica\Core\L10n;
-use Friendica\Core\NotificationsManager;
use Friendica\Core\System;
+use Friendica\Model\Notify as ModelNotify;
use Friendica\Network\HTTPException;
/**
// @TODO: Replace with parameter from router
if ($a->argc > 2 && $a->argv[1] === 'mark' && $a->argv[2] === 'all') {
- $notificationsManager = new NotificationsManager();
+ /** @var ModelNotify $notificationsManager */
+ $notificationsManager = self::getClass(ModelNotify::class);
$success = $notificationsManager->setAllSeen();
header('Content-type: application/json; charset=utf-8');
// @TODO: Replace with parameter from router
if ($a->argc > 2 && $a->argv[1] === 'view' && intval($a->argv[2])) {
- $notificationsManager = new NotificationsManager();
+ /** @var ModelNotify $notificationsManager */
+ $notificationsManager = BaseObject::getClass(ModelNotify::class);
// @TODO: Replace with parameter from router
$note = $notificationsManager->getByID($a->argv[2]);
if (!empty($note)) {
throw new \Friendica\Network\HTTPException\NotFoundException();
}
- $page = defaults($_REQUEST, 'page', null);
+ $page = $_REQUEST['page'] ?? null;
/// @todo Add Authentication to enable fetching of non public content
// $requester = HTTPSignature::getSigner('', $_SERVER);
+++ /dev/null
-<?php
-
-namespace Friendica\Module;
-
-use Friendica\BaseModule;
-use Friendica\Core\L10n;
-use Friendica\Network\HTTPException;
-
-class PageNotFound extends BaseModule
-{
- public static function content()
- {
- throw new HTTPException\NotFoundException(L10n::t('Page not found.'));
- }
-}
// site block
if (!$blocked && !$userblock) {
- $keywords = str_replace(['#', ',', ' ', ',,'], ['', ' ', ',', ','], defaults($a->profile, 'pub_keywords', ''));
+ $keywords = str_replace(['#', ',', ' ', ',,'], ['', ' ', ',', ','], $a->profile['pub_keywords'] ?? '');
if (strlen($keywords)) {
$a->page['htmlhead'] .= '<meta name="keywords" content="' . $keywords . '" />' . "\n";
}
$category = $datequery = $datequery2 = '';
+ /** @var DateTimeFormat $dtFormat */
+ $dtFormat = self::getClass(DateTimeFormat::class);
+
if ($a->argc > 2) {
for ($x = 2; $x < $a->argc; $x ++) {
- if (is_a_date_arg($a->argv[$x])) {
+ if ($dtFormat->isYearMonth($a->argv[$x])) {
if ($datequery) {
$datequery2 = Strings::escapeHtml($a->argv[$x]);
} else {
}
if (empty($category)) {
- $category = defaults($_GET, 'category', '');
+ $category = $_GET['category'] ?? '';
}
- $hashtags = defaults($_GET, 'tag', '');
+ $hashtags = $_GET['tag'] ?? '';
if (Config::get('system', 'block_public') && !local_user() && !Session::getRemoteContactID($a->profile['profile_uid'])) {
return Login::form();
}
if (!$update) {
- $tab = Strings::escapeTags(trim(defaults($_GET, 'tab', '')));
+ $tab = Strings::escapeTags(trim($_GET['tab'] ?? ''));
$o .= ProfileModel::getTabs($a, $tab, $is_owner, $a->profile['nickname']);
//@TODO: Get value from router parameters
$nickname = $a->argv[1];
- $type = defaults($a->argv, 3, 'all');
+ $type = ($a->argv[3] ?? '') ?: 'all';
Nav::setSelected('home');
$url = base64_decode(strtr($url, '-_', '+/'), true);
} else {
- $url = defaults($_REQUEST, 'url', '');
+ $url = $_REQUEST['url'] ?? '';
}
return [
namespace Friendica\Module;
+use Friendica\App\BaseURL;
use Friendica\BaseModule;
use Friendica\Content\Text\BBCode;
use Friendica\Core\Config;
}
}
- $username = defaults($_REQUEST, 'username' , '');
- $email = defaults($_REQUEST, 'email' , '');
- $openid_url = defaults($_REQUEST, 'openid_url', '');
- $nickname = defaults($_REQUEST, 'nickname' , '');
- $photo = defaults($_REQUEST, 'photo' , '');
- $invite_id = defaults($_REQUEST, 'invite_id' , '');
+ $username = $_REQUEST['username'] ?? '';
+ $email = $_REQUEST['email'] ?? '';
+ $openid_url = $_REQUEST['openid_url'] ?? '';
+ $nickname = $_REQUEST['nickname'] ?? '';
+ $photo = $_REQUEST['photo'] ?? '';
+ $invite_id = $_REQUEST['invite_id'] ?? '';
if (Config::get('system', 'no_openid')) {
$fillwith = '';
$arr['blocked'] = $blocked;
$arr['verified'] = $verified;
- $arr['language'] = L10nClass::detectLanguage($a->getConfig()->get('system', 'language'));
+ $arr['language'] = L10nClass::detectLanguage($_SERVER, $_GET, $a->getConfig()->get('system', 'language'));
try {
$result = Model\User::create($arr);
$user = $result['user'];
+ $base_url = self::getClass(BaseURL::class)->get();
+
if ($netpublish && intval(Config::get('config', 'register_policy')) !== self::APPROVE) {
- $url = $a->getBaseUrl() . '/profile/' . $user['nickname'];
+ $url = $base_url . '/profile/' . $user['nickname'];
Worker::add(PRIORITY_LOW, 'Directory', $url);
}
$res = Model\User::sendRegisterOpenEmail(
$user,
Config::get('config', 'sitename'),
- $a->getBaseUrl(),
+ $base_url,
$result['password']
);
L10n::t('Failed to send email message. Here your accout details:<br> login: %s<br> password: %s<br><br>You can change your password after login.',
$user['email'],
$result['password'])
- . EOL
);
}
} else {
'source_name' => $user['username'],
'source_mail' => $user['email'],
'source_nick' => $user['nickname'],
- 'source_link' => $a->getBaseUrl() . '/admin/users/',
- 'link' => $a->getBaseUrl() . '/admin/users/',
- 'source_photo' => $a->getBaseUrl() . '/photo/avatar/' . $user['uid'] . '.jpg',
+ 'source_link' => $base_url . '/admin/users/',
+ 'link' => $base_url . '/admin/users/',
+ 'source_photo' => $base_url . '/photo/avatar/' . $user['uid'] . '.jpg',
'to_email' => $admin['email'],
'uid' => $admin['uid'],
- 'language' => defaults($admin, 'language', 'en'),
+ 'language' => ($admin['language'] ?? '') ?: 'en',
'show_in_notification_page' => false
]);
}
Model\User::sendRegisterPendingEmail(
$user,
Config::get('config', 'sitename'),
- $a->getBaseURL(),
+ $base_url,
$result['password']
);
'id' => intval($g['id']),
'network' => $g['network'],
'link' => $g['url'],
- 'nick' => htmlentities(defaults($g, 'attag', $g['nick'])),
- 'addr' => htmlentities(defaults($g, 'addr', $g['url'])),
+ 'nick' => htmlentities(($g['attag'] ?? '') ?: $g['nick']),
+ 'addr' => htmlentities(($g['addr'] ?? '') ?: $g['url']),
'forum' => !empty($g['forum']) || !empty($g['prv']) ? 1 : 0,
];
if ($entry['forum']) {
'id' => intval($contact['cid']),
'network' => $contact['network'],
'link' => $contact['url'],
- 'nick' => htmlentities(defaults($contact, 'nick', $contact['addr'])),
- 'addr' => htmlentities(defaults($contact, 'addr', $contact['url'])),
+ 'nick' => htmlentities(($contact['nick'] ?? '') ?: $contact['addr']),
+ 'addr' => htmlentities(($contact['addr'] ?? '') ?: $contact['url']),
'forum' => $contact['forum']
];
}
}
if (local_user()) {
- self::getApp()->page['aside'] .= Widget\SavedSearches::getHTML('search?q=' . $search, $search);
+ self::getApp()->page['aside'] .= Widget\SavedSearches::getHTML('search?q=' . urlencode($search), $search);
}
Nav::setSelected('search');
class Saved extends BaseModule
{
- public static function rawContent()
+ public static function init()
{
/** @var Arguments $args */
$args = self::getClass(Arguments::class);
$action = $args->get(2, 'none');
- $search = Strings::escapeTags(trim(rawurldecode($args->get(3, ''))));
+ $search = Strings::escapeTags(trim(rawurldecode($_GET['term'] ?? '')));
$return_url = $_GET['return_url'] ?? 'search?q=' . urlencode($search);
- if (local_user()) {
+ if (local_user() && $search) {
switch ($action) {
case 'add':
$fields = ['uid' => local_user(), 'term' => $search];
self::checkFormSecurityTokenRedirectOnError('settings/2fa', 'settings_2fa');
try {
- User::getIdFromPasswordAuthentication(local_user(), defaults($_POST, 'password', ''));
+ User::getIdFromPasswordAuthentication(local_user(), $_POST['password'] ?? '');
$has_secret = (bool) PConfig::get(local_user(), '2fa', 'secret');
$verified = PConfig::get(local_user(), '2fa', 'verified');
- switch (defaults($_POST, 'action', '')) {
+ switch ($_POST['action'] ?? '') {
case 'enable':
if (!$has_secret && !$verified) {
$Google2FA = new Google2FA();
return;
}
- if (defaults($_POST, 'action', null) == 'verify') {
+ if (($_POST['action'] ?? '') == 'verify') {
self::checkFormSecurityTokenRedirectOnError('settings/2fa/verify', 'settings_2fa_verify');
$google2fa = new Google2FA();
- $valid = $google2fa->verifyKey(PConfig::get(local_user(), '2fa', 'secret'), defaults($_POST, 'verify_code', ''));
+ $valid = $google2fa->verifyKey(PConfig::get(local_user(), '2fa', 'secret'), $_POST['verify_code'] ?? '');
if ($valid) {
PConfig::set(local_user(), '2fa', 'verified', true);
public static function content()
{
$smilies = Content\Smilies::getList();
- $count = count(defaults($smilies, 'texts', []));
+ $count = count($smilies['texts'] ?? []);
$tpl = Renderer::getMarkupTemplate('smilies.tpl');
return Renderer::replaceMacros($tpl, [
500 => L10n::t('Internal Server Error'),
503 => L10n::t('Service Unavailable'),
];
- $title = defaults($titles, $e->getCode(), 'Error ' . $e->getCode());
+ $title = ($titles[$e->getCode()] ?? '') ?: 'Error ' . $e->getCode();
if (empty($message)) {
// Explanations are taken from https://en.wikipedia.org/wiki/List_of_HTTP_status_codes
503 => L10n::t('The server is currently unavailable (because it is overloaded or down for maintenance). Please try again later.'),
];
- $message = defaults($explanation, $e->getCode(), '');
+ $message = $explanation[$e->getCode()] ?? '';
}
return ['$title' => $title, '$message' => $message, '$back' => L10n::t('Go back')];
Item::update(['starred' => $starred], ['id' => $itemId]);
// See if we've been passed a return path to redirect to
- $returnPath = defaults($_REQUEST, 'return', '');
+ $returnPath = $_REQUEST['return'] ?? '';
if ($returnPath) {
$rand = '_=' . time();
if (strpos($returnPath, '?')) {
$info = Theme::getInfo($theme);
// Unfortunately there will be no translation for this string
- $description = defaults($info, 'description', '');
- $version = defaults($info, 'version' , '');
- $credits = defaults($info, 'credits' , '');
+ $description = $info['description'] ?? '';
+ $version = $info['version'] ?? '';
+ $credits = $info['credits'] ?? '';
echo json_encode([
'img' => Theme::getScreenshot($theme),
return;
}
- if (defaults($_POST, 'action', null) == 'recover') {
+ if (($_POST['action'] ?? '') == 'recover') {
self::checkFormSecurityTokenRedirectOnError('2fa', 'twofactor_recovery');
$a = self::getApp();
- $recovery_code = defaults($_POST, 'recovery_code', '');
+ $recovery_code = $_POST['recovery_code'] ?? '';
if (RecoveryCode::existsForUser(local_user(), $recovery_code)) {
RecoveryCode::markUsedForUser(local_user(), $recovery_code);
use Friendica\BaseModule;
use Friendica\Core\Hook;
-use Friendica\Database\DBA;
use Friendica\Core\Renderer;
-use Friendica\Core\System;
-use Friendica\Model\User;
+use Friendica\Database\DBA;
use Friendica\Model\Photo;
+use Friendica\Model\User;
+use Friendica\Protocol\ActivityNamespace;
use Friendica\Protocol\Salmon;
use Friendica\Util\Strings;
}
$uri = urldecode(Strings::escapeTags(trim($_GET['uri'])));
- if (defaults($_SERVER, 'HTTP_ACCEPT', '') == 'application/jrd+json') {
+ if (($_SERVER['HTTP_ACCEPT'] ?? '') == 'application/jrd+json') {
$mode = 'json';
} else {
$mode = 'xml';
}
$uri = urldecode(Strings::escapeTags(trim($_GET['resource'])));
- if (defaults($_SERVER, 'HTTP_ACCEPT', '') == 'application/xrd+xml') {
+ if (($_SERVER['HTTP_ACCEPT'] ?? '') == 'application/xrd+xml') {
$mode = 'xml';
} else {
$mode = 'json';
],
'links' => [
[
- 'rel' => NAMESPACE_DFRN,
+ 'rel' => ActivityNamespace::DFRN ,
'href' => $owner['url'],
],
[
- 'rel' => NAMESPACE_FEED,
+ 'rel' => ActivityNamespace::FEED,
'type' => 'application/atom+xml',
'href' => $owner['poll'],
],
'href' => $baseURL . '/hcard/' . $owner['nickname'],
],
[
- 'rel' => NAMESPACE_POCO,
+ 'rel' => ActivityNamespace::POCO,
'href' => $owner['poco'],
],
[
}
if ($this->returnCode == 301 || $this->returnCode == 302 || $this->returnCode == 303 || $this->returnCode== 307) {
- $redirect_parts = parse_url(defaults($this->info, 'redirect_url', ''));
+ $redirect_parts = parse_url($this->info['redirect_url'] ?? '');
if (empty($redirect_parts)) {
$redirect_parts = [];
}
}
}
- $parts = parse_url(defaults($this->info, 'url', ''));
+ $parts = parse_url($this->info['url'] ?? '');
if (empty($parts)) {
$parts = [];
}
*/
private static function genToken()
{
- return md5(base64_encode(pack('N6', mt_rand(), mt_rand(), mt_rand(), mt_rand(), mt_rand(), uniqid())));
+ return Friendica\Util\Strings::getRandomHex(32);
}
/**
'secret' => $sec,
'client_id' => $k,
'scope' => 'request',
- 'expires' => time() + REQUEST_TOKEN_DURATION]
+ 'expires' => time() + REQUEST_TOKEN_DURATION
+ ]
);
if (!$r) {
'client_id' => $consumer->key,
'scope' => 'access',
'expires' => time() + ACCESS_TOKEN_DURATION,
- 'uid' => $uverifier]
+ 'uid' => $uverifier
+ ]
);
if ($r) {
use Friendica\Core\System;
use Friendica\Database\DBA;
use Friendica\Model\Profile;
+use Friendica\Protocol\ActivityNamespace;
use Friendica\Protocol\ActivityPub;
use Friendica\Protocol\Email;
use Friendica\Protocol\Feed;
use Friendica\Util\Crypto;
-use Friendica\Util\DateTimeFormat;
use Friendica\Util\Network;
use Friendica\Util\Strings;
use Friendica\Util\XML;
Logger::log('webfingerDfrn: '.$webbie.':'.print_r($links, true), Logger::DATA);
if (!empty($links) && is_array($links)) {
foreach ($links as $link) {
- if ($link['@attributes']['rel'] === NAMESPACE_DFRN) {
+ if ($link['@attributes']['rel'] === ActivityNamespace::DFRN) {
$profile_link = $link['@attributes']['href'];
}
- if (($link['@attributes']['rel'] === NAMESPACE_OSTATUSSUB) && ($profile_link == "")) {
+ if (($link['@attributes']['rel'] === ActivityNamespace::OSTATUSSUB) && ($profile_link == "")) {
$profile_link = 'stat:'.$link['@attributes']['template'];
}
if ($link['@attributes']['rel'] === 'http://microformats.org/profile/hcard') {
if (!self::$istimeout) {
$ap_profile = ActivityPub::probeProfile($uri);
- if (empty($data) || (!empty($ap_profile) && empty($network) && (defaults($data, 'network', '') != Protocol::DFRN))) {
+ if (empty($data) || (!empty($ap_profile) && empty($network) && (($data['network'] ?? '') != Protocol::DFRN))) {
$data = $ap_profile;
} elseif (!empty($ap_profile)) {
$ap_profile['batch'] = '';
}
if (!empty($data['photo'])) {
- $data['baseurl'] = Network::getUrlMatch(Strings::normaliseLink(defaults($data, 'baseurl', '')), Strings::normaliseLink($data['photo']));
+ $data['baseurl'] = Network::getUrlMatch(Strings::normaliseLink($data['baseurl'] ?? ''), Strings::normaliseLink($data['photo']));
} else {
$data['photo'] = System::baseUrl() . '/images/person-300.jpg';
}
}
// If the file is too large then exit
- if (defaults($curlResult->getInfo(), 'download_content_length', 0) > 1000000) {
+ if (($curlResult->getInfo()['download_content_length'] ?? 0) > 1000000) {
return false;
}
$has_key = false;
foreach ($webfinger['links'] as $link) {
- if ($link['rel'] == NAMESPACE_OSTATUSSUB) {
+ if ($link['rel'] == ActivityNamespace::OSTATUSSUB) {
$is_ostatus = true;
}
if ($link['rel'] == 'magic-public-key') {
return [];
}
- $path_parts = explode("/", trim(defaults($parts, 'path', ''), "/"));
+ $path_parts = explode("/", trim($parts['path'] ?? '', "/"));
while (!$lrdd && (sizeof($path_parts) > 1)) {
$host .= "/".array_shift($path_parts);
if (empty($data["addr"]) || empty($data["nick"])) {
$probe_data = self::uri($profile_link);
- $data["addr"] = defaults($data, "addr", $probe_data["addr"]);
- $data["nick"] = defaults($data, "nick", $probe_data["nick"]);
+ $data["addr"] = ($data["addr"] ?? '') ?: $probe_data["addr"];
+ $data["nick"] = ($data["nick"] ?? '') ?: $probe_data["nick"];
}
$prof_data["addr"] = $data["addr"];
$prof_data["nick"] = $data["nick"];
- $prof_data["dfrn-request"] = defaults($data, 'request', null);
- $prof_data["dfrn-confirm"] = defaults($data, 'confirm', null);
- $prof_data["dfrn-notify"] = defaults($data, 'notify' , null);
- $prof_data["dfrn-poll"] = defaults($data, 'poll' , null);
- $prof_data["photo"] = defaults($data, 'photo' , null);
- $prof_data["fn"] = defaults($data, 'name' , null);
- $prof_data["key"] = defaults($data, 'pubkey' , null);
+ $prof_data["dfrn-request"] = $data['request'] ?? null;
+ $prof_data["dfrn-confirm"] = $data['confirm'] ?? null;
+ $prof_data["dfrn-notify"] = $data['notify'] ?? null;
+ $prof_data["dfrn-poll"] = $data['poll'] ?? null;
+ $prof_data["photo"] = $data['photo'] ?? null;
+ $prof_data["fn"] = $data['name'] ?? null;
+ $prof_data["key"] = $data['pubkey'] ?? null;
Logger::log("Result for profile ".$profile_link.": ".print_r($prof_data, true), Logger::DEBUG);
// The array is reversed to take into account the order of preference for same-rel links
// See: https://tools.ietf.org/html/rfc7033#section-4.4.4
foreach (array_reverse($webfinger["links"]) as $link) {
- if (($link["rel"] == NAMESPACE_DFRN) && !empty($link["href"])) {
+ if (($link["rel"] == ActivityNamespace::DFRN) && !empty($link["href"])) {
$data["network"] = Protocol::DFRN;
- } elseif (($link["rel"] == NAMESPACE_FEED) && !empty($link["href"])) {
+ } elseif (($link["rel"] == ActivityNamespace::FEED) && !empty($link["href"])) {
$data["poll"] = $link["href"];
- } elseif (($link["rel"] == "http://webfinger.net/rel/profile-page") && (defaults($link, "type", "") == "text/html") && !empty($link["href"])) {
+ } elseif (($link["rel"] == "http://webfinger.net/rel/profile-page") && (($link["type"] ?? "") == "text/html") && !empty($link["href"])) {
$data["url"] = $link["href"];
} elseif (($link["rel"] == "http://microformats.org/profile/hcard") && !empty($link["href"])) {
$hcard_url = $link["href"];
- } elseif (($link["rel"] == NAMESPACE_POCO) && !empty($link["href"])) {
+ } elseif (($link["rel"] == ActivityNamespace::POCO) && !empty($link["href"])) {
$data["poco"] = $link["href"];
} elseif (($link["rel"] == "http://webfinger.net/rel/avatar") && !empty($link["href"])) {
$data["photo"] = $link["href"];
$data["baseurl"] = trim($link["href"], '/');
} elseif (($link["rel"] == "http://joindiaspora.com/guid") && !empty($link["href"])) {
$data["guid"] = $link["href"];
- } elseif (($link["rel"] == "http://webfinger.net/rel/profile-page") && (defaults($link, "type", "") == "text/html") && !empty($link["href"])) {
+ } elseif (($link["rel"] == "http://webfinger.net/rel/profile-page") && (($link["type"] ?? "") == "text/html") && !empty($link["href"])) {
$data["url"] = $link["href"];
- } elseif (($link["rel"] == NAMESPACE_FEED) && !empty($link["href"])) {
+ } elseif (($link["rel"] == ActivityNamespace::FEED) && !empty($link["href"])) {
$data["poll"] = $link["href"];
- } elseif (($link["rel"] == NAMESPACE_POCO) && !empty($link["href"])) {
+ } elseif (($link["rel"] == ActivityNamespace::POCO) && !empty($link["href"])) {
$data["poco"] = $link["href"];
} elseif (($link["rel"] == "salmon") && !empty($link["href"])) {
$data["notify"] = $link["href"];
// See: https://tools.ietf.org/html/rfc7033#section-4.4.4
foreach (array_reverse($webfinger["links"]) as $link) {
if (($link["rel"] == "http://webfinger.net/rel/profile-page")
- && (defaults($link, "type", "") == "text/html")
+ && (($link["type"] ?? "") == "text/html")
&& ($link["href"] != "")
) {
$data["url"] = $link["href"];
} elseif (($link["rel"] == "salmon") && !empty($link["href"])) {
$data["notify"] = $link["href"];
- } elseif (($link["rel"] == NAMESPACE_FEED) && !empty($link["href"])) {
+ } elseif (($link["rel"] == ActivityNamespace::FEED) && !empty($link["href"])) {
$data["poll"] = $link["href"];
} elseif (($link["rel"] == "magic-public-key") && !empty($link["href"])) {
$pubkey = $link["href"];
// See: https://tools.ietf.org/html/rfc7033#section-4.4.4
foreach (array_reverse($webfinger["links"]) as $link) {
if (($link["rel"] == "http://webfinger.net/rel/profile-page")
- && (defaults($link, "type", "") == "text/html")
+ && (($link["type"] ?? "") == "text/html")
&& ($link["href"] != "")
) {
$data["url"] = $link["href"];
use Friendica\BaseObject;
use Friendica\Content\ContactSelector;
use Friendica\Content\Feature;
+use Friendica\Content\Item as ContentItem;
use Friendica\Core\Addon;
use Friendica\Core\Config;
use Friendica\Core\Hook;
use Friendica\Core\Logger;
use Friendica\Core\PConfig;
use Friendica\Core\Protocol;
-use Friendica\Core\Session;
use Friendica\Core\Renderer;
+use Friendica\Core\Session;
use Friendica\Database\DBA;
use Friendica\Model\Contact;
use Friendica\Model\Item;
use Friendica\Model\Term;
use Friendica\Model\User;
+use Friendica\Protocol\Activity;
use Friendica\Util\Crypto;
use Friendica\Util\DateTimeFormat;
use Friendica\Util\Proxy as ProxyUtils;
$isevent = false;
$attend = [];
- if ($item['object-type'] === ACTIVITY_OBJ_EVENT) {
+ if ($item['object-type'] === Activity\ObjectType::EVENT) {
$response_verbs[] = 'attendyes';
$response_verbs[] = 'attendno';
$response_verbs[] = 'attendmaybe';
$body = Item::prepareBody($item, true);
- list($categories, $folders) = get_cats_and_terms($item);
+ /** @var ContentItem $contItem */
+ $contItem = self::getClass(ContentItem::class);
+
+ list($categories, $folders) = $contItem->determineCategoriesTerms($item);
$body_e = $body;
$text_e = strip_tags($body);
Logger::log('[WARN] Post::addChild : Item already exists (' . $item->getId() . ').', Logger::DEBUG);
return false;
}
+
+ /** @var Activity $activity */
+ $activity = self::getClass(Activity::class);
+
/*
* Only add what will be displayed
*/
if ($item->getDataValue('network') === Protocol::MAIL && local_user() != $item->getDataValue('uid')) {
return false;
- } elseif (activity_match($item->getDataValue('verb'), ACTIVITY_LIKE) || activity_match($item->getDataValue('verb'), ACTIVITY_DISLIKE)) {
+ } elseif ($activity->match($item->getDataValue('verb'), Activity::LIKE) ||
+ $activity->match($item->getDataValue('verb'), Activity::DISLIKE)) {
return false;
}
$terms = Term::tagArrayFromItemId($this->getId(), [Term::MENTION, Term::IMPLICIT_MENTION]);
foreach ($terms as $term) {
$profile = Contact::getDetailsByURL($term['url']);
- if (!empty($profile['addr']) && (defaults($profile, 'contact-type', Contact::TYPE_UNKNOWN) != Contact::TYPE_COMMUNITY) &&
+ if (!empty($profile['addr']) && ((($profile['contact-type'] ?? '') ?: Contact::TYPE_UNKNOWN) != Contact::TYPE_COMMUNITY) &&
($profile['addr'] != $owner['addr']) && !strstr($text, $profile['addr'])) {
$text .= '@' . $profile['addr'] . ' ';
}
use Friendica\BaseObject;
use Friendica\Core\Logger;
use Friendica\Core\Protocol;
+use Friendica\Protocol\Activity;
use Friendica\Util\Security;
/**
return false;
}
- if ($item->getDataValue('verb') === ACTIVITY_LIKE || $item->getDataValue('verb') === ACTIVITY_DISLIKE) {
+ if ($item->getDataValue('verb') === Activity::LIKE || $item->getDataValue('verb') === Activity::DISLIKE) {
Logger::log('[WARN] Conversation::addThread : Thread is a (dis)like ('. $item->getId() .').', Logger::DEBUG);
return false;
}
--- /dev/null
+<?php
+
+namespace Friendica\Protocol;
+
+use Friendica\Protocol\ActivityNamespace;
+
+/**
+ * Base class for the Activity Verbs
+ */
+final class Activity
+{
+ /**
+ * Indicates that the actor marked the object as an item of special interest.
+ *
+ * @see http://activitystrea.ms/head/activity-schema.html#verbs
+ * @var string
+ */
+ const LIKE = ActivityNamespace::ACTIVITY_SCHEMA . 'like';
+ /**
+ * Dislike a message ("I don't like the post")
+ *
+ * @see http://purl.org/macgirvin/dfrn/1.0/dislike
+ * @var string
+ */
+ const DISLIKE = ActivityNamespace::DFRN . '/dislike';
+
+ /**
+ * Attend an event
+ *
+ * @see https://github.com/friendica/friendica/wiki/ActivityStreams#activity_attend
+ * @var string
+ */
+ const ATTEND = ActivityNamespace::ZOT . '/activity/attendyes';
+ /**
+ * Don't attend an event
+ *
+ * @see https://github.com/friendica/friendica/wiki/ActivityStreams#activity_attendno
+ * @var string
+ */
+ const ATTENDNO = ActivityNamespace::ZOT . '/activity/attendno';
+ /**
+ * Attend maybe an event
+ *
+ * @see https://github.com/friendica/friendica/wiki/ActivityStreams#activity_attendmaybe
+ * @var string
+ */
+ const ATTENDMAYBE = ActivityNamespace::ZOT . '/activity/attendmaybe';
+
+ /**
+ * Indicates the creation of a friendship that is reciprocated by the object.
+ *
+ * @see http://activitystrea.ms/head/activity-schema.html#verbs
+ * @var string
+ */
+ const FRIEND = ActivityNamespace::ACTIVITY_SCHEMA . 'make-friend';
+ /**
+ * Indicates the creation of a friendship that has not yet been reciprocated by the object.
+ *
+ * @see http://activitystrea.ms/head/activity-schema.html#verbs
+ * @var string
+ */
+ const REQ_FRIEND = ActivityNamespace::ACTIVITY_SCHEMA . 'request-friend';
+ /**
+ * Indicates that the actor has removed the object from the collection of friends.
+ *
+ * @see http://activitystrea.ms/head/activity-schema.html#verbs
+ * @var string
+ */
+ const UNFRIEND = ActivityNamespace::ACTIVITY_SCHEMA . 'remove-friend';
+ /**
+ * Indicates that the actor began following the activity of the object.
+ *
+ * @see http://activitystrea.ms/head/activity-schema.html#verbs
+ * @var string
+ */
+ const FOLLOW = ActivityNamespace::ACTIVITY_SCHEMA . 'follow';
+ /**
+ * Indicates that the actor has stopped following the object.
+ *
+ * @see http://activitystrea.ms/head/activity-schema.html#verbs
+ * @var string
+ */
+ const UNFOLLOW = ActivityNamespace::ACTIVITY_SCHEMA . 'stop-following';
+ /**
+ * Indicates that the actor has become a member of the object.
+ *
+ * @see http://activitystrea.ms/head/activity-schema.html#verbs
+ * @var string
+ */
+ const JOIN = ActivityNamespace::ACTIVITY_SCHEMA . 'join';
+ /**
+ * Implementors SHOULD use verbs such as post where the actor is adding new items to a collection or similar.
+ *
+ * @see http://activitystrea.ms/head/activity-schema.html#verbs
+ * @var string
+ */
+ const POST = ActivityNamespace::ACTIVITY_SCHEMA . 'post';
+ /**
+ * The "update" verb indicates that the actor has modified the object.
+ *
+ * @see http://activitystrea.ms/head/activity-schema.html#verbs
+ * @var string
+ */
+ const UPDATE = ActivityNamespace::ACTIVITY_SCHEMA . 'update';
+ /**
+ * Indicates that the actor has identified the presence of a target inside another object.
+ *
+ * @see http://activitystrea.ms/head/activity-schema.html#verbs
+ * @var string
+ */
+ const TAG = ActivityNamespace::ACTIVITY_SCHEMA . 'tag';
+ /**
+ * Indicates that the actor marked the object as an item of special interest.
+ *
+ * @see http://activitystrea.ms/head/activity-schema.html#verbs
+ * @var string
+ */
+ const FAVORITE = ActivityNamespace::ACTIVITY_SCHEMA . 'favorite';
+ /**
+ * Indicates that the actor has removed the object from the collection of favorited items.
+ *
+ * @see http://activitystrea.ms/head/activity-schema.html#verbs
+ * @var string
+ */
+ const UNFAVORITE = ActivityNamespace::ACTIVITY_SCHEMA . 'unfavorite';
+ /**
+ * Indicates that the actor has called out the object to readers.
+ *
+ * @see http://activitystrea.ms/head/activity-schema.html#verbs
+ * @var string
+ */
+ const SHARE = ActivityNamespace::ACTIVITY_SCHEMA . 'share';
+ /**
+ * Indicates that the actor has deleted the object.
+ *
+ * @see http://activitystrea.ms/head/activity-schema.html#verbs
+ * @var string
+ */
+ const DELETE = ActivityNamespace::ACTIVITY_SCHEMA . 'delete';
+ /**
+ * Indicates that the actor is calling the target's attention the object.
+ *
+ * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-announce
+ * @var string
+ */
+ const ANNOUNCE = ActivityNamespace::ACTIVITY2 . 'Announce';
+
+ /**
+ * Pokes an user.
+ *
+ * @see https://github.com/friendica/friendica/wiki/ActivityStreams#activity_poke
+ * @var string
+ */
+ const POKE = ActivityNamespace::ZOT . '/activity/poke';
+
+
+ const O_UNFOLLOW = ActivityNamespace::OSTATUS . '/unfollow';
+ const O_UNFAVOURITE = ActivityNamespace::OSTATUS . '/unfavorite';
+
+ /**
+ * likes (etc.) can apply to other things besides posts. Check if they are post children,
+ * in which case we handle them specially
+ *
+ * Hidden activities, which doesn't need to be shown
+ */
+ const HIDDEN_ACTIVITIES = [
+ Activity::LIKE, Activity::DISLIKE,
+ Activity::ATTEND, Activity::ATTENDNO, Activity::ATTENDMAYBE,
+ Activity::FOLLOW,
+ Activity::ANNOUNCE,
+ ];
+
+ /**
+ * Checks if the given activity is a hidden activity
+ *
+ * @param string $activity The current activity
+ *
+ * @return bool True, if the activity is hidden
+ */
+ public function isHidden(string $activity)
+ {
+ foreach (self::HIDDEN_ACTIVITIES as $hiddenActivity) {
+ if ($this->match($activity, $hiddenActivity)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Compare activity uri. Knows about activity namespace.
+ *
+ * @param string $haystack
+ * @param string $needle
+ *
+ * @return boolean
+ */
+ public function match(string $haystack, string $needle)
+ {
+ return (($haystack === $needle) ||
+ ((basename($needle) === $haystack) &&
+ strstr($needle, ActivityNamespace::ACTIVITY_SCHEMA)));
+ }
+}
--- /dev/null
+<?php
+
+namespace Friendica\Protocol\Activity;
+
+use Friendica\Protocol\ActivityNamespace;
+
+/**
+ * This class contains the different object types in activities
+ */
+final class ObjectType
+{
+ /**
+ * The "bookmark" object type represents a pointer to some URL -- typically a web page.
+ *
+ * @see http://activitystrea.ms/head/activity-schema.html#bookmark
+ * @var string
+ */
+ const BOOKMARK = ActivityNamespace::ACTIVITY_SCHEMA . 'bookmark';
+ /**
+ * The "comment" object type represents a textual response to another object.
+ *
+ * @see http://activitystrea.ms/head/activity-schema.html#comment
+ * @var string
+ */
+ const COMMENT = ActivityNamespace::ACTIVITY_SCHEMA . 'comment';
+ /**
+ * The "comment" object type represents a textual response to another object.
+ * (Default type for items)
+ *
+ * @see http://activitystrea.ms/head/activity-schema.html#note
+ * @var string
+ */
+ const NOTE = ActivityNamespace::ACTIVITY_SCHEMA . 'note';
+ /**
+ * The "person" object type represents a user account.
+ *
+ * @see http://activitystrea.ms/head/activity-schema.html#person
+ * @var string
+ */
+ const PERSON = ActivityNamespace::ACTIVITY_SCHEMA . 'person';
+ /**
+ * The "image" object type represents a graphical image.
+ *
+ * @see http://activitystrea.ms/head/activity-schema.html#image
+ * @var string
+ */
+ const IMAGE = ActivityNamespace::ACTIVITY_SCHEMA . 'image';
+ /**
+ * @var string
+ */
+ const PHOTO = ActivityNamespace::ACTIVITY_SCHEMA . 'photo';
+ /**
+ * The "video" object type represents video content,
+ * which usually consists of a motion picture track and an audio track.
+ *
+ * @see http://activitystrea.ms/head/activity-schema.html#video
+ * @var string
+ */
+ const VIDEO = ActivityNamespace::ACTIVITY_SCHEMA . 'video';
+ /**
+ * @var string
+ */
+ const PROFILE_PHOTO = ActivityNamespace::ACTIVITY_SCHEMA . 'profile-photo';
+ /**
+ * @var string
+ */
+ const ALBUM = ActivityNamespace::ACTIVITY_SCHEMA . 'photo-album';
+ /**
+ * The "event" object type represents an event that occurs in a certain place during a particular interval of time.
+ *
+ * @see http://activitystrea.ms/head/activity-schema.html#event
+ * @var string
+ */
+ const EVENT = ActivityNamespace::ACTIVITY_SCHEMA . 'event';
+ /**
+ * The "group" object type represents a grouping of objects in which member objects can join or leave.
+ *
+ * @see http://activitystrea.ms/head/activity-schema.html#group
+ * @var string
+ */
+ const GROUP = ActivityNamespace::ACTIVITY_SCHEMA . 'group';
+
+
+ /**
+ * @var string
+ */
+ const HEART = ActivityNamespace::DFRN . '/heart';
+ /**
+ * @var string
+ */
+ const TAGTERM = ActivityNamespace::DFRN . '/tagterm';
+ /**
+ * @var string
+ */
+ const PROFILE = ActivityNamespace::DFRN . '/profile';
+
+
+ /**
+ * The "question" object type represents a question or poll.
+ *
+ * @see http://activitystrea.ms/head/activity-schema.html#question
+ * @var string
+ */
+ const QUESTION = 'http://activityschema.org/object/question';
+}
--- /dev/null
+<?php
+
+namespace Friendica\Protocol;
+
+/**
+ * Activity namespaces constants
+ */
+final class ActivityNamespace
+{
+ /**
+ * Zot is a WebMTA which provides a decentralised identity and communications protocol using HTTPS/JSON.
+ *
+ * @var string
+ * @see https://zotlabs.org/page/zotlabs/specs+zot6+home
+ */
+ const ZOT = 'http://purl.org/zot';
+ /**
+ * Friendica is using ActivityStreams in version 1.0 for its activities and object types.
+ * Additional types are used for non standard activities.
+ *
+ * @var string
+ * @see https://github.com/friendica/friendica/wiki/ActivityStreams
+ */
+ const DFRN = 'http://purl.org/macgirvin/dfrn/1.0';
+ /**
+ * This namespace defines an extension for expressing threaded
+ * discussions within the Atom Syndication Format [RFC4287]
+ *
+ * @see https://tools.ietf.org/rfc/rfc4685.txt
+ * @var string
+ */
+ const THREAD = 'http://purl.org/syndication/thread/1.0';
+ /**
+ * This namespace adds mechanisms to the Atom Syndication Format
+ * that publishers of Atom Feed and Entry documents can use to
+ * explicitly identify Atom entries that have been removed.
+ *
+ * @see https://tools.ietf.org/html/rfc6721
+ * @var string
+ */
+ const TOMB = 'http://purl.org/atompub/tombstones/1.0';
+ /**
+ * This specification details a model for representing potential and completed activities
+ * using the JSON format.
+ *
+ * @see https://www.w3.org/ns/activitystreams
+ * @var string
+ */
+ const ACTIVITY2 = 'https://www.w3.org/ns/activitystreams#';
+ /**
+ * Atom Activities 1.0
+ *
+ * This namespace presents an XML format that allows activities on social objects
+ * to be expressed within the Atom Syndication Format.
+ *
+ * @see http://activitystrea.ms/spec/1.0
+ * @var string
+ */
+ const ACTIVITY = 'http://activitystrea.ms/spec/1.0/';
+ /**
+ * This namespace presents a base set of Object types and Verbs for use with Activity Streams.
+ *
+ * @see http://activitystrea.ms/head/activity-schema.html
+ * @var string
+ */
+ const ACTIVITY_SCHEMA = 'http://activitystrea.ms/schema/1.0/';
+ /**
+ * Atom Media Extensions
+ *
+ * @var string
+ */
+ const MEDIA = 'http://purl.org/syndication/atommedia';
+ /**
+ * The Salmon Protocol is an open, simple, standards-based solution that lets
+ * aggregators and sources unify the conversations.
+ *
+ * @see http://www.salmon-protocol.org/salmon-protocol-summary
+ * @var string
+ */
+ const SALMON_ME = 'http://salmon-protocol.org/ns/magic-env';
+ /**
+ * OStatus is a minimal specification for distributed status updates or microblogging.
+ *
+ * @see https://ostatus.github.io/spec/OStatus%201.0%20Draft%202.html
+ * @var string
+ */
+ const OSTATUSSUB = 'http://ostatus.org/schema/1.0/subscribe';
+ /**
+ * GeoRSS was designed as a lightweight, community driven way to extend existing feeds with geographic information.
+ *
+ * @see http://www.georss.org/
+ * @var string
+ */
+ const GEORSS = 'http://www.georss.org/georss';
+ /**
+ * The Portable Contacts specification is designed to make it easier for developers
+ * to give their users a secure way to access the address books and friends lists
+ * they have built up all over the web.
+ *
+ * @see http://portablecontacts.net/draft-spec/
+ * @var string
+ */
+ const POCO = 'http://portablecontacts.net/spec/1.0';
+ /**
+ * @var string
+ */
+ const FEED = 'http://schemas.google.com/g/2010#updates-from';
+ /**
+ * OStatus is a minimal specification for distributed status updates or microblogging.
+ *
+ * @see https://ostatus.github.io/spec/OStatus%201.0%20Draft%202.html
+ * @var string
+ */
+ const OSTATUS = 'http://ostatus.org/schema/1.0';
+ /**
+ * @var string
+ */
+ const STATUSNET = 'http://status.net/schema/api/1/';
+ /**
+ * This namespace describes the Atom Activity Streams in RDF Vocabulary (AAIR),
+ * defined as a dictionary of named properties and classes using W3C's RDF technology,
+ * and specifically a mapping of the Atom Activity Streams work to RDF.
+ *
+ * @see http://xmlns.notu.be/aair/#RFC4287
+ * @var string
+ */
+ const ATOM1 = 'http://www.w3.org/2005/Atom';
+ /**
+ * @var string
+ */
+ const MASTODON = 'http://mastodon.social/schema/1.0';
+}
*/
public static function isRequest()
{
- return stristr(defaults($_SERVER, 'HTTP_ACCEPT', ''), 'application/activity+json') ||
- stristr(defaults($_SERVER, 'HTTP_ACCEPT', ''), 'application/ld+json');
+ return stristr($_SERVER['HTTP_ACCEPT'] ?? '', 'application/activity+json') ||
+ stristr($_SERVER['HTTP_ACCEPT'] ?? '', 'application/ld+json');
}
/**
*/
namespace Friendica\Protocol\ActivityPub;
-use Friendica\Database\DBA;
use Friendica\Content\Text\BBCode;
use Friendica\Content\Text\HTML;
use Friendica\Core\Config;
-use Friendica\Core\PConfig;
use Friendica\Core\Logger;
+use Friendica\Core\PConfig;
use Friendica\Core\Protocol;
-use Friendica\Model\Contact;
+use Friendica\Database\DBA;
use Friendica\Model\APContact;
-use Friendica\Model\Item;
+use Friendica\Model\Contact;
use Friendica\Model\Event;
+use Friendica\Model\Item;
+use Friendica\Model\Mail;
use Friendica\Model\Term;
use Friendica\Model\User;
-use Friendica\Model\Mail;
+use Friendica\Protocol\Activity;
use Friendica\Protocol\ActivityPub;
use Friendica\Util\DateTimeFormat;
use Friendica\Util\JsonLD;
$tag_text = '';
foreach ($tags as $tag) {
- if (in_array(defaults($tag, 'type', ''), ['Mention', 'Hashtag'])) {
+ if (in_array($tag['type'] ?? '', ['Mention', 'Hashtag'])) {
if (!empty($tag_text)) {
$tag_text .= ',';
}
if (!isset($attach['length'])) {
$attach['length'] = "0";
}
- $item["attach"] .= '[attach]href="'.$attach['url'].'" length="'.$attach['length'].'" type="'.$attach['mediaType'].'" title="'.defaults($attach, 'name', '').'"[/attach]';
+ $item["attach"] .= '[attach]href="'.$attach['url'].'" length="'.$attach['length'].'" type="'.$attach['mediaType'].'" title="'.($attach['name'] ?? '') .'"[/attach]';
}
}
public static function createItem($activity)
{
$item = [];
- $item['verb'] = ACTIVITY_POST;
+ $item['verb'] = Activity::POST;
$item['thr-parent'] = $activity['reply-to-id'];
if ($activity['reply-to-id'] == $activity['id']) {
$item['gravity'] = GRAVITY_PARENT;
- $item['object-type'] = ACTIVITY_OBJ_NOTE;
+ $item['object-type'] = Activity\ObjectType::NOTE;
} else {
$item['gravity'] = GRAVITY_COMMENT;
- $item['object-type'] = ACTIVITY_OBJ_COMMENT;
+ $item['object-type'] = Activity\ObjectType::COMMENT;
}
if (empty($activity['directmessage']) && ($activity['id'] != $activity['reply-to-id']) && !Item::exists(['uri' => $activity['reply-to-id']])) {
self::fetchMissingActivity($activity['reply-to-id'], $activity);
}
- $item['diaspora_signed_text'] = defaults($activity, 'diaspora:comment', '');
+ $item['diaspora_signed_text'] = $activity['diaspora:comment'] ?? '';
self::postItem($activity, $item);
}
$item['verb'] = $verb;
$item['thr-parent'] = $activity['object_id'];
$item['gravity'] = GRAVITY_ACTIVITY;
- $item['object-type'] = ACTIVITY_OBJ_NOTE;
+ $item['object-type'] = Activity\ObjectType::NOTE;
- $item['diaspora_signed_text'] = defaults($activity, 'diaspora:like', '');
+ $item['diaspora_signed_text'] = $activity['diaspora:like'] ?? '';
self::postItem($activity, $item);
}
return;
}
- $item['plink'] = defaults($activity, 'alternate-url', $item['uri']);
+ $item['plink'] = $activity['alternate-url'] ?? $item['uri'];
$item = self::constructAttachList($activity['attachments'], $item, !empty($activity['source']));
$activity['@context'] = $object['@context'];
unset($object['@context']);
$activity['id'] = $object['id'];
- $activity['to'] = defaults($object, 'to', []);
- $activity['cc'] = defaults($object, 'cc', []);
+ $activity['to'] = $object['to'] ?? [];
+ $activity['cc'] = $object['cc'] ?? [];
$activity['actor'] = $actor;
$activity['object'] = $object;
$activity['published'] = $published;
$item = ['author-id' => Contact::getIdForURL($activity['actor']),
'author-link' => $activity['actor']];
- $note = Strings::escapeTags(trim(defaults($activity, 'content', '')));
+ $note = Strings::escapeTags(trim($activity['content'] ?? ''));
// Ensure that the contact has got the right network type
self::switchContact($item['author-id']);
// Extract one prepended mention at a time from the body
while(preg_match('#^(@\[url=([^\]]+)].*?\[\/url]\s)(.*)#is', $body, $matches)) {
- if (!in_array($matches[2], $potential_mentions) ) {
+ if (!in_array($matches[2], $potential_mentions)) {
$kept_mentions[] = $matches[1];
}
use Friendica\Model\Conversation;
use Friendica\Model\Item;
use Friendica\Model\User;
+use Friendica\Protocol\Activity;
use Friendica\Protocol\ActivityPub;
use Friendica\Util\DateTimeFormat;
use Friendica\Util\HTTPSignature;
*/
public static function isRequest()
{
- return stristr(defaults($_SERVER, 'HTTP_ACCEPT', ''), 'application/activity+json') ||
- stristr(defaults($_SERVER, 'HTTP_ACCEPT', ''), 'application/ld+json');
+ return stristr($_SERVER['HTTP_ACCEPT'] ?? '', 'application/activity+json') ||
+ stristr($_SERVER['HTTP_ACCEPT'] ?? '', 'application/ld+json');
}
/**
$object_data['type'] = $type;
$object_data['actor'] = $actor;
$object_data['item_receiver'] = $receivers;
- $object_data['receiver'] = array_merge(defaults($object_data, 'receiver', []), $receivers);
+ $object_data['receiver'] = array_merge($object_data['receiver'] ?? [], $receivers);
Logger::log('Processing ' . $object_data['type'] . ' ' . $object_data['object_type'] . ' ' . $object_data['id'], Logger::DEBUG);
$conversation = [
'protocol' => Conversation::PARCEL_ACTIVITYPUB,
'item-uri' => $activity['id'],
- 'reply-to-uri' => defaults($activity, 'reply-to-id', ''),
- 'conversation-href' => defaults($activity, 'context', ''),
- 'conversation-uri' => defaults($activity, 'conversation', ''),
+ 'reply-to-uri' => $activity['reply-to-id'] ?? '',
+ 'conversation-href' => $activity['context'] ?? '',
+ 'conversation-uri' => $activity['conversation'] ?? '',
'source' => $body,
'received' => DateTimeFormat::utcNow()];
$announce_object_data['object_id'] = $object_data['object_id'];
$announce_object_data['object_type'] = $object_data['object_type'];
- ActivityPub\Processor::createActivity($announce_object_data, ACTIVITY2_ANNOUNCE);
+ ActivityPub\Processor::createActivity($announce_object_data, Activity::ANNOUNCE);
}
}
break;
case 'as:Like':
if (in_array($object_data['object_type'], self::CONTENT_TYPES)) {
- ActivityPub\Processor::createActivity($object_data, ACTIVITY_LIKE);
+ ActivityPub\Processor::createActivity($object_data, Activity::LIKE);
}
break;
case 'as:Dislike':
if (in_array($object_data['object_type'], self::CONTENT_TYPES)) {
- ActivityPub\Processor::createActivity($object_data, ACTIVITY_DISLIKE);
+ ActivityPub\Processor::createActivity($object_data, Activity::DISLIKE);
}
break;
case 'as:TentativeAccept':
if (in_array($object_data['object_type'], self::CONTENT_TYPES)) {
- ActivityPub\Processor::createActivity($object_data, ACTIVITY_ATTENDMAYBE);
+ ActivityPub\Processor::createActivity($object_data, Activity::ATTENDMAYBE);
}
break;
ActivityPub\Processor::followUser($object_data);
} elseif (in_array($object_data['object_type'], self::CONTENT_TYPES)) {
$object_data['reply-to-id'] = $object_data['object_id'];
- ActivityPub\Processor::createActivity($object_data, ACTIVITY_FOLLOW);
+ ActivityPub\Processor::createActivity($object_data, Activity::FOLLOW);
}
break;
if ($object_data['object_type'] == 'as:Follow') {
ActivityPub\Processor::acceptFollowUser($object_data);
} elseif (in_array($object_data['object_type'], self::CONTENT_TYPES)) {
- ActivityPub\Processor::createActivity($object_data, ACTIVITY_ATTEND);
+ ActivityPub\Processor::createActivity($object_data, Activity::ATTEND);
}
break;
if ($object_data['object_type'] == 'as:Follow') {
ActivityPub\Processor::rejectFollowUser($object_data);
} elseif (in_array($object_data['object_type'], self::CONTENT_TYPES)) {
- ActivityPub\Processor::createActivity($object_data, ACTIVITY_ATTENDNO);
+ ActivityPub\Processor::createActivity($object_data, Activity::ATTENDNO);
}
break;
if (!empty($actor)) {
$profile = APContact::getByURL($actor);
- $followers = defaults($profile, 'followers', '');
+ $followers = $profile['followers'] ?? '';
Logger::log('Actor: ' . $actor . ' - Followers: ' . $followers, Logger::DEBUG);
} else {
use Friendica\Core\Config;
use Friendica\Core\Logger;
use Friendica\Core\System;
+use Friendica\Protocol\Activity;
use Friendica\Util\HTTPSignature;
use Friendica\Core\Protocol;
use Friendica\Model\Conversation;
if (empty($page)) {
$data['first'] = System::baseUrl() . '/followers/' . $owner['nickname'] . '?page=1';
} else {
+ $data['type'] = 'OrderedCollectionPage';
$list = [];
$contacts = DBA::select('contact', ['url'], $condition, ['limit' => [($page - 1) * 100, 100]]);
if (empty($page)) {
$data['first'] = System::baseUrl() . '/following/' . $owner['nickname'] . '?page=1';
} else {
+ $data['type'] = 'OrderedCollectionPage';
$list = [];
$contacts = DBA::select('contact', ['url'], $condition, ['limit' => [($page - 1) * 100, 100]]);
if (empty($page)) {
$data['first'] = System::baseUrl() . '/outbox/' . $owner['nickname'] . '?page=1';
} else {
+ $data['type'] = 'OrderedCollectionPage';
$list = [];
$condition['parent-network'] = Protocol::NATIVE_SUPPORT;
if ($reshared) {
$type = 'Announce';
- } elseif ($item['verb'] == ACTIVITY_POST) {
+ } elseif ($item['verb'] == Activity::POST) {
if ($item['created'] == $item['edited']) {
$type = 'Create';
} else {
$type = 'Update';
}
- } elseif ($item['verb'] == ACTIVITY_LIKE) {
+ } elseif ($item['verb'] == Activity::LIKE) {
$type = 'Like';
- } elseif ($item['verb'] == ACTIVITY_DISLIKE) {
+ } elseif ($item['verb'] == Activity::DISLIKE) {
$type = 'Dislike';
- } elseif ($item['verb'] == ACTIVITY_ATTEND) {
+ } elseif ($item['verb'] == Activity::ATTEND) {
$type = 'Accept';
- } elseif ($item['verb'] == ACTIVITY_ATTENDNO) {
+ } elseif ($item['verb'] == Activity::ATTENDNO) {
$type = 'Reject';
- } elseif ($item['verb'] == ACTIVITY_ATTENDMAYBE) {
+ } elseif ($item['verb'] == Activity::ATTENDMAYBE) {
$type = 'TentativeAccept';
- } elseif ($item['verb'] == ACTIVITY_FOLLOW) {
+ } elseif ($item['verb'] == Activity::FOLLOW) {
$type = 'Follow';
- } elseif ($item['verb'] == ACTIVITY_TAG) {
+ } elseif ($item['verb'] == Activity::TAG) {
$type = 'Add';
} else {
$type = '';
$uid = $first_user['uid'];
}
- $condition = ['verb' => ACTIVITY_FOLLOW, 'uid' => 0, 'parent-uri' => $object,
+ $condition = ['verb' => Activity::FOLLOW, 'uid' => 0, 'parent-uri' => $object,
'author-id' => Contact::getPublicIdByUserId($uid)];
if (Item::exists($condition)) {
Logger::log('Follow for ' . $object . ' for user ' . $uid . ' does already exist.', Logger::DEBUG);
use DOMDocument;
use DOMXPath;
-use Friendica\App;
use Friendica\App\BaseURL;
+use Friendica\BaseObject;
use Friendica\Content\OEmbed;
use Friendica\Content\Text\BBCode;
use Friendica\Content\Text\HTML;
use Friendica\Core\Logger;
use Friendica\Core\Protocol;
use Friendica\Core\System;
-use Friendica\Core\Session;
use Friendica\Database\DBA;
use Friendica\Model\Contact;
use Friendica\Model\Conversation;
use Friendica\Model\User;
use Friendica\Network\Probe;
use Friendica\Object\Image;
+use Friendica\Protocol\ActivityNamespace;
use Friendica\Util\Crypto;
use Friendica\Util\DateTimeFormat;
use Friendica\Util\Network;
foreach ($items as $item) {
// These values aren't sent when sending from the queue.
/// @todo Check if we can set these values from the queue or if they are needed at all.
- $item["entry:comment-allow"] = defaults($item, "entry:comment-allow", true);
- $item["entry:cid"] = defaults($item, "entry:cid", 0);
+ $item["entry:comment-allow"] = ($item["entry:comment-allow"] ?? '') ?: true;
+ $item["entry:cid"] = $item["entry:cid"] ?? 0;
$entry = self::entry($doc, "text", $item, $owner, $item["entry:comment-allow"], $item["entry:cid"]);
if (isset($entry)) {
$type = 'html';
if ($conversation) {
- $root = $doc->createElementNS(NAMESPACE_ATOM1, 'feed');
+ $root = $doc->createElementNS(ActivityNamespace::ATOM1, 'feed');
$doc->appendChild($root);
- $root->setAttribute("xmlns:thr", NAMESPACE_THREAD);
- $root->setAttribute("xmlns:at", NAMESPACE_TOMB);
- $root->setAttribute("xmlns:media", NAMESPACE_MEDIA);
- $root->setAttribute("xmlns:dfrn", NAMESPACE_DFRN);
- $root->setAttribute("xmlns:activity", NAMESPACE_ACTIVITY);
- $root->setAttribute("xmlns:georss", NAMESPACE_GEORSS);
- $root->setAttribute("xmlns:poco", NAMESPACE_POCO);
- $root->setAttribute("xmlns:ostatus", NAMESPACE_OSTATUS);
- $root->setAttribute("xmlns:statusnet", NAMESPACE_STATUSNET);
+ $root->setAttribute("xmlns:thr", ActivityNamespace::THREAD);
+ $root->setAttribute("xmlns:at", ActivityNamespace::TOMB);
+ $root->setAttribute("xmlns:media", ActivityNamespace::MEDIA);
+ $root->setAttribute("xmlns:dfrn", ActivityNamespace::DFRN);
+ $root->setAttribute("xmlns:activity", ActivityNamespace::ACTIVITY);
+ $root->setAttribute("xmlns:georss", ActivityNamespace::GEORSS);
+ $root->setAttribute("xmlns:poco", ActivityNamespace::POCO);
+ $root->setAttribute("xmlns:ostatus", ActivityNamespace::OSTATUS);
+ $root->setAttribute("xmlns:statusnet", ActivityNamespace::STATUSNET);
//$root = self::addHeader($doc, $owner, "dfrn:owner", "", false);
$alternatelink = $owner['url'];
}
- $root = $doc->createElementNS(NAMESPACE_ATOM1, 'feed');
+ $root = $doc->createElementNS(ActivityNamespace::ATOM1, 'feed');
$doc->appendChild($root);
- $root->setAttribute("xmlns:thr", NAMESPACE_THREAD);
- $root->setAttribute("xmlns:at", NAMESPACE_TOMB);
- $root->setAttribute("xmlns:media", NAMESPACE_MEDIA);
- $root->setAttribute("xmlns:dfrn", NAMESPACE_DFRN);
- $root->setAttribute("xmlns:activity", NAMESPACE_ACTIVITY);
- $root->setAttribute("xmlns:georss", NAMESPACE_GEORSS);
- $root->setAttribute("xmlns:poco", NAMESPACE_POCO);
- $root->setAttribute("xmlns:ostatus", NAMESPACE_OSTATUS);
- $root->setAttribute("xmlns:statusnet", NAMESPACE_STATUSNET);
+ $root->setAttribute("xmlns:thr", ActivityNamespace::THREAD);
+ $root->setAttribute("xmlns:at", ActivityNamespace::TOMB);
+ $root->setAttribute("xmlns:media", ActivityNamespace::MEDIA);
+ $root->setAttribute("xmlns:dfrn", ActivityNamespace::DFRN);
+ $root->setAttribute("xmlns:activity", ActivityNamespace::ACTIVITY);
+ $root->setAttribute("xmlns:georss", ActivityNamespace::GEORSS);
+ $root->setAttribute("xmlns:poco", ActivityNamespace::POCO);
+ $root->setAttribute("xmlns:ostatus", ActivityNamespace::OSTATUS);
+ $root->setAttribute("xmlns:statusnet", ActivityNamespace::STATUSNET);
XML::addElement($doc, $root, "id", System::baseUrl()."/profile/".$owner["nick"]);
XML::addElement($doc, $root, "title", $owner["name"]);
if (!$single) {
$entry = $doc->createElement("entry");
} else {
- $entry = $doc->createElementNS(NAMESPACE_ATOM1, 'entry');
+ $entry = $doc->createElementNS(ActivityNamespace::ATOM1, 'entry');
$doc->appendChild($entry);
- $entry->setAttribute("xmlns:thr", NAMESPACE_THREAD);
- $entry->setAttribute("xmlns:at", NAMESPACE_TOMB);
- $entry->setAttribute("xmlns:media", NAMESPACE_MEDIA);
- $entry->setAttribute("xmlns:dfrn", NAMESPACE_DFRN);
- $entry->setAttribute("xmlns:activity", NAMESPACE_ACTIVITY);
- $entry->setAttribute("xmlns:georss", NAMESPACE_GEORSS);
- $entry->setAttribute("xmlns:poco", NAMESPACE_POCO);
- $entry->setAttribute("xmlns:ostatus", NAMESPACE_OSTATUS);
- $entry->setAttribute("xmlns:statusnet", NAMESPACE_STATUSNET);
+ $entry->setAttribute("xmlns:thr", ActivityNamespace::THREAD);
+ $entry->setAttribute("xmlns:at", ActivityNamespace::TOMB);
+ $entry->setAttribute("xmlns:media", ActivityNamespace::MEDIA);
+ $entry->setAttribute("xmlns:dfrn", ActivityNamespace::DFRN);
+ $entry->setAttribute("xmlns:activity", ActivityNamespace::ACTIVITY);
+ $entry->setAttribute("xmlns:georss", ActivityNamespace::GEORSS);
+ $entry->setAttribute("xmlns:poco", ActivityNamespace::POCO);
+ $entry->setAttribute("xmlns:ostatus", ActivityNamespace::OSTATUS);
+ $entry->setAttribute("xmlns:statusnet", ActivityNamespace::STATUSNET);
}
if ($item['private']) {
if ($item['object-type'] != "") {
XML::addElement($doc, $entry, "activity:object-type", $item['object-type']);
} elseif ($item['id'] == $item['parent']) {
- XML::addElement($doc, $entry, "activity:object-type", ACTIVITY_OBJ_NOTE);
+ XML::addElement($doc, $entry, "activity:object-type", Activity\ObjectType::NOTE);
} else {
- XML::addElement($doc, $entry, "activity:object-type", ACTIVITY_OBJ_COMMENT);
+ XML::addElement($doc, $entry, "activity:object-type", Activity\ObjectType::COMMENT);
}
$actobj = self::createActivity($doc, "activity:object", $item['object']);
"link",
"",
["rel" => "mentioned",
- "ostatus:object-type" => ACTIVITY_OBJ_GROUP,
+ "ostatus:object-type" => Activity\ObjectType::GROUP,
"href" => $mention]
);
} else {
"link",
"",
["rel" => "mentioned",
- "ostatus:object-type" => ACTIVITY_OBJ_PERSON,
+ "ostatus:object-type" => Activity\ObjectType::PERSON,
"href" => $mention]
);
}
$sent_dfrn_id = hex2bin((string) $res->dfrn_id);
$challenge = hex2bin((string) $res->challenge);
$perm = (($res->perm) ? $res->perm : null);
- $dfrn_version = (float) (($res->dfrn_version) ? $res->dfrn_version : 2.0);
+ $dfrn_version = floatval($res->dfrn_version ?: 2.0);
$rino_remote_version = intval($res->rino);
$page = (($owner['page-flags'] == User::PAGE_FLAGS_COMMUNITY) ? 1 : 0);
$obj_doc = new DOMDocument("1.0", "utf-8");
$obj_doc->formatOutput = true;
- $obj_element = $obj_doc->createElementNS(NAMESPACE_ATOM1, $element);
+ $obj_element = $obj_doc->createElementNS( ActivityNamespace::ATOM1, $element);
$activity_type = $xpath->query("activity:object-type/text()", $activity)->item(0)->nodeValue;
XML::addElement($obj_doc, $obj_element, "type", $activity_type);
'source_name' => $importer['name'],
'source_link' => $importer['url'],
'source_photo' => $importer['photo'],
- 'verb' => ACTIVITY_REQ_FRIEND,
+ 'verb' => Activity::REQ_FRIEND,
'otype' => 'intro']
);
return false;
}
- $fields = ['title' => defaults($item, 'title', ''), 'body' => defaults($item, 'body', ''),
- 'tag' => defaults($item, 'tag', ''), 'changed' => DateTimeFormat::utcNow(),
+ $fields = ['title' => $item['title'] ?? '', 'body' => $item['body'] ?? '',
+ 'tag' => $item['tag'] ?? '', 'changed' => DateTimeFormat::utcNow(),
'edited' => DateTimeFormat::utc($item["edited"])];
$condition = ["`uri` = ? AND `uid` IN (0, ?)", $item["uri"], $importer["importer_uid"]];
}
$xo = XML::parseString($item["object"], false);
- if (($xo->type == ACTIVITY_OBJ_PERSON) && ($xo->id)) {
+ if (($xo->type == Activity\ObjectType::PERSON) && ($xo->id)) {
// somebody was poked/prodded. Was it me?
$Blink = '';
foreach ($xo->link as $l) {
// The functions below are partly used by ostatus.php as well - where we have this variable
$contact = Contact::selectFirst([], ['id' => $importer['id']]);
+ /** @var Activity $activity */
+ $activity = BaseObject::getClass(Activity::class);
+
// Big question: Do we need these functions? They were part of the "consume_feed" function.
// This function once was responsible for DFRN and OStatus.
- if (activity_match($item["verb"], ACTIVITY_FOLLOW)) {
+ if ($activity->match($item["verb"], Activity::FOLLOW)) {
Logger::log("New follower");
Contact::addRelationship($importer, $contact, $item);
return false;
}
- if (activity_match($item["verb"], ACTIVITY_UNFOLLOW)) {
+ if ($activity->match($item["verb"], Activity::UNFOLLOW)) {
Logger::log("Lost follower");
Contact::removeFollower($importer, $contact, $item);
return false;
}
- if (activity_match($item["verb"], ACTIVITY_REQ_FRIEND)) {
+ if ($activity->match($item["verb"], Activity::REQ_FRIEND)) {
Logger::log("New friend request");
Contact::addRelationship($importer, $contact, $item, true);
return false;
}
- if (activity_match($item["verb"], ACTIVITY_UNFRIEND)) {
+ if ($activity->match($item["verb"], Activity::UNFRIEND)) {
Logger::log("Lost sharer");
Contact::removeSharer($importer, $contact, $item);
return false;
}
} else {
- if (($item["verb"] == ACTIVITY_LIKE)
- || ($item["verb"] == ACTIVITY_DISLIKE)
- || ($item["verb"] == ACTIVITY_ATTEND)
- || ($item["verb"] == ACTIVITY_ATTENDNO)
- || ($item["verb"] == ACTIVITY_ATTENDMAYBE)
+ if (($item["verb"] == Activity::LIKE)
+ || ($item["verb"] == Activity::DISLIKE)
+ || ($item["verb"] == Activity::ATTEND)
+ || ($item["verb"] == Activity::ATTENDNO)
+ || ($item["verb"] == Activity::ATTENDMAYBE)
) {
$is_like = true;
$item["gravity"] = GRAVITY_ACTIVITY;
$is_like = false;
}
- if (($item["verb"] == ACTIVITY_TAG) && ($item["object-type"] == ACTIVITY_OBJ_TAGTERM)) {
+ if (($item["verb"] == Activity::TAG) && ($item["object-type"] == Activity\ObjectType::TAGTERM)) {
$xo = XML::parseString($item["object"], false);
$xt = XML::parseString($item["target"], false);
- if ($xt->type == ACTIVITY_OBJ_NOTE) {
+ if ($xt->type == Activity\ObjectType::NOTE) {
$item_tag = Item::selectFirst(['id', 'tag'], ['uri' => $xt->id, 'uid' => $importer["importer_uid"]]);
if (!DBA::isResult($item_tag)) {
// Now assign the rest of the values that depend on the type of the message
if (in_array($entrytype, [DFRN::REPLY, DFRN::REPLY_RC])) {
if (!isset($item["object-type"])) {
- $item["object-type"] = ACTIVITY_OBJ_COMMENT;
+ $item["object-type"] = Activity\ObjectType::COMMENT;
}
if ($item["contact-id"] != $owner["contact-id"]) {
$item["wall"] = 1;
} elseif ($entrytype == DFRN::TOP_LEVEL) {
if (!isset($item["object-type"])) {
- $item["object-type"] = ACTIVITY_OBJ_NOTE;
+ $item["object-type"] = Activity\ObjectType::NOTE;
}
// Is it an event?
- if (($item["object-type"] == ACTIVITY_OBJ_EVENT) && !$owner_unknown) {
+ if (($item["object-type"] == Activity\ObjectType::EVENT) && !$owner_unknown) {
Logger::log("Item ".$item["uri"]." seems to contain an event.", Logger::DEBUG);
$ev = Event::fromBBCode($item["body"]);
if ((!empty($ev['desc']) || !empty($ev['summary'])) && !empty($ev['start'])) {
Item::distribute($posted_id);
}
- if (stristr($item["verb"], ACTIVITY_POKE)) {
+ if (stristr($item["verb"], Activity::POKE)) {
$item['id'] = $posted_id;
self::doPoke($item, $importer);
}
@$doc->loadXML($xml);
$xpath = new DOMXPath($doc);
- $xpath->registerNamespace("atom", NAMESPACE_ATOM1);
- $xpath->registerNamespace("thr", NAMESPACE_THREAD);
- $xpath->registerNamespace("at", NAMESPACE_TOMB);
- $xpath->registerNamespace("media", NAMESPACE_MEDIA);
- $xpath->registerNamespace("dfrn", NAMESPACE_DFRN);
- $xpath->registerNamespace("activity", NAMESPACE_ACTIVITY);
- $xpath->registerNamespace("georss", NAMESPACE_GEORSS);
- $xpath->registerNamespace("poco", NAMESPACE_POCO);
- $xpath->registerNamespace("ostatus", NAMESPACE_OSTATUS);
- $xpath->registerNamespace("statusnet", NAMESPACE_STATUSNET);
+ $xpath->registerNamespace("atom", ActivityNamespace::ATOM1);
+ $xpath->registerNamespace("thr", ActivityNamespace::THREAD);
+ $xpath->registerNamespace("at", ActivityNamespace::TOMB);
+ $xpath->registerNamespace("media", ActivityNamespace::MEDIA);
+ $xpath->registerNamespace("dfrn", ActivityNamespace::DFRN);
+ $xpath->registerNamespace("activity", ActivityNamespace::ACTIVITY);
+ $xpath->registerNamespace("georss", ActivityNamespace::GEORSS);
+ $xpath->registerNamespace("poco", ActivityNamespace::POCO);
+ $xpath->registerNamespace("ostatus", ActivityNamespace::OSTATUS);
+ $xpath->registerNamespace("statusnet", ActivityNamespace::STATUSNET);
$header = [];
$header["uid"] = $importer["importer_uid"];
if ($item['verb']) {
return $item['verb'];
}
- return ACTIVITY_POST;
+ return Activity::POST;
}
private static function tgroupCheck($uid, $item)
use Friendica\Model\Profile;
use Friendica\Model\User;
use Friendica\Network\Probe;
+use Friendica\Protocol\ActivityNamespace;
use Friendica\Util\Crypto;
use Friendica\Util\DateTimeFormat;
use Friendica\Util\Map;
* @return array with the contact
* @throws \Exception
*/
- private static function getRelayContact(string $server_url, array $fields = ['batch', 'id', 'name', 'network', 'protocol', 'archive', 'blocked'])
+ private static function getRelayContact(string $server_url, array $fields = ['batch', 'id', 'url', 'name', 'network', 'protocol', 'archive', 'blocked'])
{
// Fetch the relay contact
$condition = ['uid' => 0, 'nurl' => Strings::normaliseLink($server_url),
*/
public static function participantsForThread($thread, array $contacts)
{
- $r = DBA::p("SELECT `contact`.`batch`, `contact`.`id`, `contact`.`name`, `contact`.`network`, `contact`.`protocol`,
+ $r = DBA::p("SELECT `contact`.`batch`, `contact`.`id`, `contact`.`url`, `contact`.`name`, `contact`.`network`, `contact`.`protocol`,
`fcontact`.`batch` AS `fbatch`, `fcontact`.`network` AS `fnetwork` FROM `participation`
INNER JOIN `contact` ON `contact`.`id` = `participation`.`cid`
INNER JOIN `fcontact` ON `fcontact`.`id` = `participation`.`fid`
/**
* @brief: Decodes incoming Diaspora message in the new format
*
- * @param array $importer Array of the importer user
* @param string $raw raw post message
+ * @param string $privKey The private key of the importer
* @param boolean $no_exit Don't do an http exit on error
*
* @return array
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
* @throws \ImagickException
*/
- public static function decodeRaw(array $importer, $raw, $no_exit = false)
+ public static function decodeRaw(string $raw, string $privKey = '', bool $no_exit = false)
{
$data = json_decode($raw);
$ciphertext = base64_decode($data->encrypted_magic_envelope);
$outer_key_bundle = '';
- @openssl_private_decrypt($encrypted_aes_key_bundle, $outer_key_bundle, $importer['prvkey']);
+ @openssl_private_decrypt($encrypted_aes_key_bundle, $outer_key_bundle, $privKey);
$j_outer_key_bundle = json_decode($outer_key_bundle);
if (!is_object($j_outer_key_bundle)) {
}
}
- $base = $basedom->children(NAMESPACE_SALMON_ME);
+ $base = $basedom->children(ActivityNamespace::SALMON_ME);
// Not sure if this cleaning is needed
$data = str_replace([" ", "\t", "\r", "\n"], ["", "", "", ""], $base->data);
/**
* @brief: Decodes incoming Diaspora message in the deprecated format
*
- * @param array $importer Array of the importer user
* @param string $xml urldecoded Diaspora salmon
+ * @param string $privKey The private key of the importer
*
* @return array
* 'message' -> decoded Diaspora XML message
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
* @throws \ImagickException
*/
- public static function decode(array $importer, $xml)
+ public static function decode(string $xml, string $privKey = '')
{
$public = false;
$basedom = XML::parseString($xml);
$author_link = str_replace('acct:', '', $children->header->author_id);
} else {
// This happens with posts from a relais
- if (!$importer) {
+ if (empty($privKey)) {
Logger::log("This is no private post in the old format", Logger::DEBUG);
return false;
}
$ciphertext = base64_decode($encrypted_header->ciphertext);
$outer_key_bundle = '';
- openssl_private_decrypt($encrypted_aes_key_bundle, $outer_key_bundle, $importer['prvkey']);
+ openssl_private_decrypt($encrypted_aes_key_bundle, $outer_key_bundle, $privKey);
$j_outer_key_bundle = json_decode($outer_key_bundle);
$author_link = str_replace('acct:', '', $idom->author_id);
}
- $dom = $basedom->children(NAMESPACE_SALMON_ME);
+ $dom = $basedom->children(ActivityNamespace::SALMON_ME);
// figure out where in the DOM tree our data is hiding
$datarray["guid"] = $guid;
$datarray["uri"] = self::getUriFromGuid($author, $guid);
- $datarray["verb"] = ACTIVITY_POST;
+ $datarray["verb"] = Activity::POST;
$datarray["gravity"] = GRAVITY_COMMENT;
if ($thr_uri != "") {
$datarray["parent-uri"] = $parent_item["uri"];
}
- $datarray["object-type"] = ACTIVITY_OBJ_COMMENT;
+ $datarray["object-type"] = Activity\ObjectType::COMMENT;
$datarray["protocol"] = Conversation::PARCEL_DIASPORA;
$datarray["source"] = $xml;
// "positive" = "false" would be a Dislike - wich isn't currently supported by Diaspora
// We would accept this anyhow.
if ($positive == "true") {
- $verb = ACTIVITY_LIKE;
+ $verb = Activity::LIKE;
} else {
- $verb = ACTIVITY_DISLIKE;
+ $verb = Activity::DISLIKE;
}
$datarray = [];
$datarray["gravity"] = GRAVITY_ACTIVITY;
$datarray["parent-uri"] = $parent_item["uri"];
- $datarray["object-type"] = ACTIVITY_OBJ_NOTE;
+ $datarray["object-type"] = Activity\ObjectType::NOTE;
$datarray["body"] = $verb;
$datarray['uri'] = self::getUriFromGuid($author, $datarray['guid']);
$datarray['parent-uri'] = $parent['uri'];
- $datarray['verb'] = $datarray['body'] = ACTIVITY2_ANNOUNCE;
+ $datarray['verb'] = $datarray['body'] = Activity::ANNOUNCE;
$datarray['gravity'] = GRAVITY_ACTIVITY;
- $datarray['object-type'] = ACTIVITY_OBJ_NOTE;
+ $datarray['object-type'] = Activity\ObjectType::NOTE;
$datarray['protocol'] = $item['protocol'];
$datarray["guid"] = $guid;
$datarray["uri"] = $datarray["parent-uri"] = self::getUriFromGuid($author, $guid);
- $datarray["verb"] = ACTIVITY_POST;
+ $datarray["verb"] = Activity::POST;
$datarray["gravity"] = GRAVITY_PARENT;
$datarray["protocol"] = Conversation::PARCEL_DIASPORA;
XML::unescape($photo->remote_photo_name)."[/img]\n".$body;
}
- $datarray["object-type"] = ACTIVITY_OBJ_IMAGE;
+ $datarray["object-type"] = Activity\ObjectType::IMAGE;
} else {
- $datarray["object-type"] = ACTIVITY_OBJ_NOTE;
+ $datarray["object-type"] = Activity\ObjectType::NOTE;
// Add OEmbed and other information to the body
if (!self::isRedmatrix($contact["url"])) {
$datarray["guid"] = $guid;
$datarray["uri"] = $datarray["parent-uri"] = self::getUriFromGuid($author, $guid);
- $datarray["verb"] = ACTIVITY_POST;
+ $datarray["verb"] = Activity::POST;
$datarray["gravity"] = GRAVITY_PARENT;
$datarray["protocol"] = Conversation::PARCEL_DIASPORA;
$target_type = ($parent["uri"] === $parent["parent-uri"] ? "Post" : "Comment");
$positive = null;
- if ($item['verb'] === ACTIVITY_LIKE) {
+ if ($item['verb'] === Activity::LIKE) {
$positive = "true";
- } elseif ($item['verb'] === ACTIVITY_DISLIKE) {
+ } elseif ($item['verb'] === Activity::DISLIKE) {
$positive = "false";
}
}
switch ($item['verb']) {
- case ACTIVITY_ATTEND:
+ case Activity::ATTEND:
$attend_answer = 'accepted';
break;
- case ACTIVITY_ATTENDNO:
+ case Activity::ATTENDNO:
$attend_answer = 'declined';
break;
- case ACTIVITY_ATTENDMAYBE:
+ case Activity::ATTENDMAYBE:
$attend_answer = 'tentative';
break;
default:
*/
public static function sendFollowup(array $item, array $owner, array $contact, $public_batch = false)
{
- if (in_array($item['verb'], [ACTIVITY_ATTEND, ACTIVITY_ATTENDNO, ACTIVITY_ATTENDMAYBE])) {
+ if (in_array($item['verb'], [Activity::ATTEND, Activity::ATTENDNO, Activity::ATTENDMAYBE])) {
$message = self::constructAttend($item, $owner);
$type = "event_participation";
- } elseif (in_array($item["verb"], [ACTIVITY_LIKE, ACTIVITY_DISLIKE])) {
+ } elseif (in_array($item["verb"], [Activity::LIKE, Activity::DISLIKE])) {
$message = self::constructLike($item, $owner);
$type = "like";
- } elseif (!in_array($item["verb"], [ACTIVITY_FOLLOW, ACTIVITY_TAG])) {
+ } elseif (!in_array($item["verb"], [Activity::FOLLOW, Activity::TAG])) {
$message = self::constructComment($item, $owner);
$type = "comment";
}
$message = ["author" => $item['signer'],
"target_guid" => $signed_parts[0],
"target_type" => $signed_parts[1]];
- } elseif (in_array($item["verb"], [ACTIVITY_LIKE, ACTIVITY_DISLIKE])) {
+ } elseif (in_array($item["verb"], [Activity::LIKE, Activity::DISLIKE])) {
$message = ["author" => $signed_parts[4],
"guid" => $signed_parts[1],
"parent_guid" => $signed_parts[3],
{
if ($item["deleted"]) {
return self::sendRetraction($item, $owner, $contact, $public_batch, true);
- } elseif (in_array($item["verb"], [ACTIVITY_LIKE, ACTIVITY_DISLIKE])) {
+ } elseif (in_array($item["verb"], [Activity::LIKE, Activity::DISLIKE])) {
$type = "like";
} else {
$type = "comment";
if ($item['id'] == $item['parent']) {
$target_type = "Post";
- } elseif (in_array($item["verb"], [ACTIVITY_LIKE, ACTIVITY_DISLIKE])) {
+ } elseif (in_array($item["verb"], [Activity::LIKE, Activity::DISLIKE])) {
$target_type = "Like";
} else {
$target_type = "Comment";
return false;
}
- if (!in_array($item["verb"], [ACTIVITY_LIKE, ACTIVITY_DISLIKE])) {
+ if (!in_array($item["verb"], [Activity::LIKE, Activity::DISLIKE])) {
return false;
}
}
$quotelevel = 0;
- $nextline = trim(defaults($arrbody, $i + 1, ''));
+ $nextline = trim($arrbody[$i + 1] ?? '');
while ((strlen($nextline)>0) && ((substr($nextline, 0, 1) == '>')
|| (substr($nextline, 0, 1) == ' '))) {
if (substr($nextline, 0, 1) == '>') {
use Friendica\Core\System;
use Friendica\Database\DBA;
use Friendica\Model\Item;
+use Friendica\Protocol\ActivityNamespace;
use Friendica\Util\Network;
use Friendica\Util\XML;
$doc = new DOMDocument();
@$doc->loadXML(trim($xml));
$xpath = new DOMXPath($doc);
- $xpath->registerNamespace('atom', NAMESPACE_ATOM1);
+ $xpath->registerNamespace('atom', ActivityNamespace::ATOM1);
$xpath->registerNamespace('dc', "http://purl.org/dc/elements/1.1/");
$xpath->registerNamespace('content', "http://purl.org/rss/1.0/modules/content/");
$xpath->registerNamespace('rdf', "http://www.w3.org/1999/02/22-rdf-syntax-ns#");
$xpath->registerNamespace('rss', "http://purl.org/rss/1.0/");
$xpath->registerNamespace('media', "http://search.yahoo.com/mrss/");
- $xpath->registerNamespace('poco', NAMESPACE_POCO);
+ $xpath->registerNamespace('poco', ActivityNamespace::POCO);
$author = [];
$entries = null;
$header["origin"] = 0;
$header["gravity"] = GRAVITY_PARENT;
$header["private"] = 2;
- $header["verb"] = ACTIVITY_POST;
- $header["object-type"] = ACTIVITY_OBJ_NOTE;
+ $header["verb"] = Activity::POST;
+ $header["object-type"] = Activity\ObjectType::NOTE;
$header["contact-id"] = $contact["id"];
$item["title"] = "";
$item["body"] = $item["body"].add_page_info($item["plink"], false, $preview, ($contact["fetch_further_information"] == 2), $contact["ffi_keyword_blacklist"]);
$item["tag"] = add_page_keywords($item["plink"], $preview, ($contact["fetch_further_information"] == 2), $contact["ffi_keyword_blacklist"]);
- $item["object-type"] = ACTIVITY_OBJ_BOOKMARK;
+ $item["object-type"] = Activity\ObjectType::BOOKMARK;
unset($item["attach"]);
} else {
if (!empty($summary)) {
use Friendica\Content\Text\HTML;
use Friendica\Core\Cache;
use Friendica\Core\Config;
-use Friendica\Core\PConfig;
use Friendica\Core\L10n;
-use Friendica\Core\Logger;
use Friendica\Core\Lock;
+use Friendica\Core\Logger;
+use Friendica\Core\PConfig;
use Friendica\Core\Protocol;
use Friendica\Core\System;
use Friendica\Database\DBA;
+use Friendica\Model\APContact;
use Friendica\Model\Contact;
use Friendica\Model\Conversation;
use Friendica\Model\GContact;
-use Friendica\Model\APContact;
use Friendica\Model\Item;
use Friendica\Model\User;
use Friendica\Network\Probe;
use Friendica\Object\Image;
+use Friendica\Protocol\ActivityNamespace;
use Friendica\Util\DateTimeFormat;
use Friendica\Util\Network;
use Friendica\Util\Proxy as ProxyUtils;
}
$author["author-id"] = Contact::getIdForURL($author["author-link"]);
- $author['contact-id'] = defaults($contact, 'id', $author['author-id']);
+ $author['contact-id'] = ($contact['id'] ?? 0) ?: $author['author-id'];
$contact = [];
@$doc->loadXML($xml);
$xpath = new DOMXPath($doc);
- $xpath->registerNamespace('atom', NAMESPACE_ATOM1);
- $xpath->registerNamespace('thr', NAMESPACE_THREAD);
- $xpath->registerNamespace('georss', NAMESPACE_GEORSS);
- $xpath->registerNamespace('activity', NAMESPACE_ACTIVITY);
- $xpath->registerNamespace('media', NAMESPACE_MEDIA);
- $xpath->registerNamespace('poco', NAMESPACE_POCO);
- $xpath->registerNamespace('ostatus', NAMESPACE_OSTATUS);
- $xpath->registerNamespace('statusnet', NAMESPACE_STATUSNET);
+ $xpath->registerNamespace('atom', ActivityNamespace::ATOM1);
+ $xpath->registerNamespace('thr', ActivityNamespace::THREAD);
+ $xpath->registerNamespace('georss', ActivityNamespace::GEORSS);
+ $xpath->registerNamespace('activity', ActivityNamespace::ACTIVITY);
+ $xpath->registerNamespace('media', ActivityNamespace::MEDIA);
+ $xpath->registerNamespace('poco', ActivityNamespace::POCO);
+ $xpath->registerNamespace('ostatus', ActivityNamespace::OSTATUS);
+ $xpath->registerNamespace('statusnet', ActivityNamespace::STATUSNET);
$contact = ["id" => 0];
@$doc->loadXML($xml);
$xpath = new DOMXPath($doc);
- $xpath->registerNamespace('atom', NAMESPACE_ATOM1);
- $xpath->registerNamespace('thr', NAMESPACE_THREAD);
- $xpath->registerNamespace('georss', NAMESPACE_GEORSS);
- $xpath->registerNamespace('activity', NAMESPACE_ACTIVITY);
- $xpath->registerNamespace('media', NAMESPACE_MEDIA);
- $xpath->registerNamespace('poco', NAMESPACE_POCO);
- $xpath->registerNamespace('ostatus', NAMESPACE_OSTATUS);
- $xpath->registerNamespace('statusnet', NAMESPACE_STATUSNET);
+ $xpath->registerNamespace('atom', ActivityNamespace::ATOM1);
+ $xpath->registerNamespace('thr', ActivityNamespace::THREAD);
+ $xpath->registerNamespace('georss', ActivityNamespace::GEORSS);
+ $xpath->registerNamespace('activity', ActivityNamespace::ACTIVITY);
+ $xpath->registerNamespace('media', ActivityNamespace::MEDIA);
+ $xpath->registerNamespace('poco', ActivityNamespace::POCO);
+ $xpath->registerNamespace('ostatus', ActivityNamespace::OSTATUS);
+ $xpath->registerNamespace('statusnet', ActivityNamespace::STATUSNET);
$hub = "";
$hub_items = $xpath->query("/atom:feed/atom:link[@rel='hub']")->item(0);
$item["verb"] = XML::getFirstNodeValue($xpath, 'activity:verb/text()', $entry);
// Delete a message
- if (in_array($item["verb"], ['qvitter-delete-notice', ACTIVITY_DELETE, 'delete'])) {
+ if (in_array($item["verb"], ['qvitter-delete-notice', Activity::DELETE, 'delete'])) {
self::deleteNotice($item);
continue;
}
- if (in_array($item["verb"], [NAMESPACE_OSTATUS."/unfavorite", ACTIVITY_UNFAVORITE])) {
+ if (in_array($item["verb"], [Activity::O_UNFAVOURITE, Activity::UNFAVORITE])) {
// Ignore "Unfavorite" message
Logger::log("Ignore unfavorite message ".print_r($item, true), Logger::DEBUG);
continue;
Logger::log('Processing post with URI '.$item["uri"].' for user '.$importer["uid"].'.', Logger::DEBUG);
}
- if ($item["verb"] == ACTIVITY_JOIN) {
+ if ($item["verb"] == Activity::JOIN) {
// ignore "Join" messages
Logger::log("Ignore join message ".print_r($item, true), Logger::DEBUG);
continue;
continue;
}
- if ($item["verb"] == ACTIVITY_FOLLOW) {
+ if ($item["verb"] == Activity::FOLLOW) {
Contact::addRelationship($importer, $contact, $item);
continue;
}
- if ($item["verb"] == NAMESPACE_OSTATUS."/unfollow") {
+ if ($item["verb"] == Activity::O_UNFOLLOW) {
$dummy = null;
Contact::removeFollower($importer, $contact, $item, $dummy);
continue;
}
- if ($item["verb"] == ACTIVITY_FAVORITE) {
+ if ($item["verb"] == Activity::FAVORITE) {
$orig_uri = $xpath->query("activity:object/atom:id", $entry)->item(0)->nodeValue;
Logger::log("Favorite ".$orig_uri." ".print_r($item, true));
- $item["verb"] = ACTIVITY_LIKE;
+ $item["verb"] = Activity::LIKE;
$item["parent-uri"] = $orig_uri;
$item["gravity"] = GRAVITY_ACTIVITY;
- $item["object-type"] = ACTIVITY_OBJ_NOTE;
+ $item["object-type"] = Activity\ObjectType::NOTE;
}
// http://activitystrea.ms/schema/1.0/rsvp-yes
- if (!in_array($item["verb"], [ACTIVITY_POST, ACTIVITY_LIKE, ACTIVITY_SHARE])) {
+ if (!in_array($item["verb"], [Activity::POST, Activity::LIKE, Activity::SHARE])) {
Logger::log("Unhandled verb ".$item["verb"]." ".print_r($item, true), Logger::DEBUG);
}
if ($valid) {
// Never post a thread when the only interaction by our contact was a like
$valid = false;
- $verbs = [ACTIVITY_POST, ACTIVITY_SHARE];
+ $verbs = [Activity::POST, Activity::SHARE];
foreach (self::$itemlist as $item) {
if (in_array($item['verb'], $verbs) && Contact::isSharingByURL($item['author-link'], $item['uid'])) {
$valid = true;
{
$item["body"] = HTML::toBBCode(XML::getFirstNodeValue($xpath, 'atom:content/text()', $entry));
$item["object-type"] = XML::getFirstNodeValue($xpath, 'activity:object-type/text()', $entry);
- if (($item["object-type"] == ACTIVITY_OBJ_BOOKMARK) || ($item["object-type"] == ACTIVITY_OBJ_EVENT)) {
+ if (($item["object-type"] == Activity\ObjectType::BOOKMARK) || ($item["object-type"] == Activity\ObjectType::EVENT)) {
$item["title"] = XML::getFirstNodeValue($xpath, 'atom:title/text()', $entry);
$item["body"] = XML::getFirstNodeValue($xpath, 'atom:summary/text()', $entry);
- } elseif ($item["object-type"] == ACTIVITY_OBJ_QUESTION) {
+ } elseif ($item["object-type"] == Activity\ObjectType::QUESTION) {
$item["title"] = XML::getFirstNodeValue($xpath, 'atom:title/text()', $entry);
}
}
}
// Is it a repeated post?
- if (($repeat_of != "") || ($item["verb"] == ACTIVITY_SHARE)) {
+ if (($repeat_of != "") || ($item["verb"] == Activity::SHARE)) {
$link_data = self::processRepeatedItem($xpath, $entry, $item, $importer);
if (!empty($link_data['add_body'])) {
$add_body .= $link_data['add_body'];
}
// Mastodon Content Warning
- if (($item["verb"] == ACTIVITY_POST) && $xpath->evaluate('boolean(atom:summary)', $entry)) {
+ if (($item["verb"] == Activity::POST) && $xpath->evaluate('boolean(atom:summary)', $entry)) {
$clear_text = XML::getFirstNodeValue($xpath, 'atom:summary/text()', $entry);
if (!empty($clear_text)) {
$item['content-warning'] = HTML::toBBCode($clear_text);
@$doc->loadXML($xml);
$xpath = new DOMXPath($doc);
- $xpath->registerNamespace('atom', NAMESPACE_ATOM1);
- $xpath->registerNamespace('thr', NAMESPACE_THREAD);
- $xpath->registerNamespace('ostatus', NAMESPACE_OSTATUS);
+ $xpath->registerNamespace('atom', ActivityNamespace::ATOM1);
+ $xpath->registerNamespace('thr', ActivityNamespace::THREAD);
+ $xpath->registerNamespace('ostatus', ActivityNamespace::OSTATUS);
$entries = $xpath->query('/atom:feed/atom:entry');
$item["object-type"] = XML::getFirstNodeValue($xpath, 'activity:object-type/text()', $activityobject);
// Mastodon Content Warning
- if (($item["verb"] == ACTIVITY_POST) && $xpath->evaluate('boolean(atom:summary)', $activityobject)) {
+ if (($item["verb"] == Activity::POST) && $xpath->evaluate('boolean(atom:summary)', $activityobject)) {
$clear_text = XML::getFirstNodeValue($xpath, 'atom:summary/text()', $activityobject);
if (!empty($clear_text)) {
$item['content-warning'] = HTML::toBBCode($clear_text);
switch ($attribute['rel']) {
case "alternate":
$item["plink"] = $attribute['href'];
- if (($item["object-type"] == ACTIVITY_OBJ_QUESTION)
- || ($item["object-type"] == ACTIVITY_OBJ_EVENT)
+ if (($item["object-type"] == Activity\ObjectType::QUESTION)
+ || ($item["object-type"] == Activity\ObjectType::EVENT)
) {
$item["body"] .= add_page_info($attribute['href']);
}
if (!isset($attribute['length'])) {
$attribute['length'] = "0";
}
- $item["attach"] .= '[attach]href="'.$attribute['href'].'" length="'.$attribute['length'].'" type="'.$attribute['type'].'" title="'.defaults($attribute, 'title', '').'"[/attach]';
+ $item["attach"] .= '[attach]href="'.$attribute['href'].'" length="'.$attribute['length'].'" type="'.$attribute['type'].'" title="'.($attribute['title'] ?? '') .'"[/attach]';
}
break;
case "related":
- if ($item["object-type"] != ACTIVITY_OBJ_BOOKMARK) {
+ if ($item["object-type"] != Activity\ObjectType::BOOKMARK) {
if (!isset($item["parent-uri"])) {
$item["parent-uri"] = $attribute['href'];
}
*/
private static function addHeader(DOMDocument $doc, array $owner, $filter, $feed_mode = false)
{
- $root = $doc->createElementNS(NAMESPACE_ATOM1, 'feed');
+ $root = $doc->createElementNS(ActivityNamespace::ATOM1, 'feed');
$doc->appendChild($root);
- $root->setAttribute("xmlns:thr", NAMESPACE_THREAD);
- $root->setAttribute("xmlns:georss", NAMESPACE_GEORSS);
- $root->setAttribute("xmlns:activity", NAMESPACE_ACTIVITY);
- $root->setAttribute("xmlns:media", NAMESPACE_MEDIA);
- $root->setAttribute("xmlns:poco", NAMESPACE_POCO);
- $root->setAttribute("xmlns:ostatus", NAMESPACE_OSTATUS);
- $root->setAttribute("xmlns:statusnet", NAMESPACE_STATUSNET);
- $root->setAttribute("xmlns:mastodon", NAMESPACE_MASTODON);
+ $root->setAttribute("xmlns:thr", ActivityNamespace::THREAD);
+ $root->setAttribute("xmlns:georss", ActivityNamespace::GEORSS);
+ $root->setAttribute("xmlns:activity", ActivityNamespace::ACTIVITY);
+ $root->setAttribute("xmlns:media", ActivityNamespace::MEDIA);
+ $root->setAttribute("xmlns:poco", ActivityNamespace::POCO);
+ $root->setAttribute("xmlns:ostatus", ActivityNamespace::OSTATUS);
+ $root->setAttribute("xmlns:statusnet", ActivityNamespace::STATUSNET);
+ $root->setAttribute("xmlns:mastodon", ActivityNamespace::MASTODON);
$title = '';
$selfUri = '/feed/' . $owner["nick"] . '/';
"href" => $siteinfo["url"],
"type" => "text/html; charset=UTF-8",
"length" => "",
- "title" => defaults($siteinfo, "title", $siteinfo["url"])];
+ "title" => ($siteinfo["title"] ?? '') ?: $siteinfo["url"],
+ ];
XML::addElement($doc, $root, "link", "", $attributes);
break;
default:
$author = $doc->createElement("author");
XML::addElement($doc, $author, "id", $owner["url"]);
if ($owner['account-type'] == User::ACCOUNT_TYPE_COMMUNITY) {
- XML::addElement($doc, $author, "activity:object-type", ACTIVITY_OBJ_GROUP);
+ XML::addElement($doc, $author, "activity:object-type", Activity\ObjectType::GROUP);
} else {
- XML::addElement($doc, $author, "activity:object-type", ACTIVITY_OBJ_PERSON);
+ XML::addElement($doc, $author, "activity:object-type", Activity\ObjectType::PERSON);
}
XML::addElement($doc, $author, "uri", $owner["url"]);
XML::addElement($doc, $author, "name", $owner["nick"]);
return $item['verb'];
}
- return ACTIVITY_POST;
+ return Activity::POST;
}
/**
*/
private static function constructObjecttype(array $item)
{
- if (!empty($item['object-type']) && in_array($item['object-type'], [ACTIVITY_OBJ_NOTE, ACTIVITY_OBJ_COMMENT])) {
+ if (!empty($item['object-type']) && in_array($item['object-type'], [Activity\ObjectType::NOTE, Activity\ObjectType::COMMENT])) {
return $item['object-type'];
}
- return ACTIVITY_OBJ_NOTE;
+ return Activity\ObjectType::NOTE;
}
/**
return $xml;
}
- if ($item["verb"] == ACTIVITY_LIKE) {
+ if ($item["verb"] == Activity::LIKE) {
return self::likeEntry($doc, $item, $owner, $toplevel);
- } elseif (in_array($item["verb"], [ACTIVITY_FOLLOW, NAMESPACE_OSTATUS."/unfollow"])) {
+ } elseif (in_array($item["verb"], [Activity::FOLLOW, Activity::O_UNFOLLOW])) {
return self::followEntry($doc, $item, $owner, $toplevel);
} else {
return self::noteEntry($doc, $item, $owner, $toplevel, $feed_mode);
$title = $owner["nick"]." repeated a notice by ".$contact["nick"];
- self::entryContent($doc, $entry, $item, $owner, $title, ACTIVITY_SHARE, false);
+ self::entryContent($doc, $entry, $item, $owner, $title, Activity::SHARE, false);
$as_object = $doc->createElement("activity:object");
- XML::addElement($doc, $as_object, "activity:object-type", NAMESPACE_ACTIVITY_SCHEMA."activity");
+ XML::addElement($doc, $as_object, "activity:object-type", ActivityNamespace::ACTIVITY_SCHEMA . "activity");
self::entryContent($doc, $as_object, $repeated_item, $owner, "", "", false);
$entry = self::entryHeader($doc, $owner, $item, $toplevel);
- $verb = NAMESPACE_ACTIVITY_SCHEMA."favorite";
+ $verb = ActivityNamespace::ACTIVITY_SCHEMA . "favorite";
self::entryContent($doc, $entry, $item, $owner, "Favorite", $verb, false);
$parent = Item::selectFirst([], ['uri' => $item["thr-parent"], 'uid' => $item["uid"]]);
private static function addPersonObject(DOMDocument $doc, array $owner, array $contact)
{
$object = $doc->createElement("activity:object");
- XML::addElement($doc, $object, "activity:object-type", ACTIVITY_OBJ_PERSON);
+ XML::addElement($doc, $object, "activity:object-type", Activity\ObjectType::PERSON);
if ($contact['network'] == Protocol::PHANTOM) {
XML::addElement($doc, $object, "id", $contact['url']);
$connect_id = 0;
}
- if ($item['verb'] == ACTIVITY_FOLLOW) {
+ if ($item['verb'] == Activity::FOLLOW) {
$message = L10n::t('%s is now following %s.');
$title = L10n::t('following');
$action = "subscription";
$entry = self::entryHeader($doc, $owner, $item, $toplevel);
- XML::addElement($doc, $entry, "activity:object-type", ACTIVITY_OBJ_NOTE);
+ XML::addElement($doc, $entry, "activity:object-type", Activity\ObjectType::NOTE);
self::entryContent($doc, $entry, $item, $owner, $title, '', true, $feed_mode);
$entry->appendChild($author);
}
} else {
- $entry = $doc->createElementNS(NAMESPACE_ATOM1, "entry");
+ $entry = $doc->createElementNS(ActivityNamespace::ATOM1, "entry");
- $entry->setAttribute("xmlns:thr", NAMESPACE_THREAD);
- $entry->setAttribute("xmlns:georss", NAMESPACE_GEORSS);
- $entry->setAttribute("xmlns:activity", NAMESPACE_ACTIVITY);
- $entry->setAttribute("xmlns:media", NAMESPACE_MEDIA);
- $entry->setAttribute("xmlns:poco", NAMESPACE_POCO);
- $entry->setAttribute("xmlns:ostatus", NAMESPACE_OSTATUS);
- $entry->setAttribute("xmlns:statusnet", NAMESPACE_STATUSNET);
- $entry->setAttribute("xmlns:mastodon", NAMESPACE_MASTODON);
+ $entry->setAttribute("xmlns:thr", ActivityNamespace::THREAD);
+ $entry->setAttribute("xmlns:georss", ActivityNamespace::GEORSS);
+ $entry->setAttribute("xmlns:activity", ActivityNamespace::ACTIVITY);
+ $entry->setAttribute("xmlns:media", ActivityNamespace::MEDIA);
+ $entry->setAttribute("xmlns:poco", ActivityNamespace::POCO);
+ $entry->setAttribute("xmlns:ostatus", ActivityNamespace::OSTATUS);
+ $entry->setAttribute("xmlns:statusnet", ActivityNamespace::STATUSNET);
+ $entry->setAttribute("xmlns:mastodon", ActivityNamespace::MASTODON);
$author = self::addAuthor($doc, $owner);
$entry->appendChild($author);
XML::addElement($doc, $entry, "link", "",
[
"rel" => "mentioned",
- "ostatus:object-type" => ACTIVITY_OBJ_GROUP,
+ "ostatus:object-type" => Activity\ObjectType::GROUP,
"href" => $mention]
);
} else {
XML::addElement($doc, $entry, "link", "",
[
"rel" => "mentioned",
- "ostatus:object-type" => ACTIVITY_OBJ_PERSON,
+ "ostatus:object-type" => Activity\ObjectType::PERSON,
"href" => $mention]
);
}
if ($filter === 'comments') {
$condition[0] .= " AND `object-type` = ? ";
- $condition[] = ACTIVITY_OBJ_COMMENT;
+ $condition[] = Activity\ObjectType::COMMENT;
}
if ($owner['account-type'] != User::ACCOUNT_TYPE_COMMUNITY) {
--- /dev/null
+<?php
+
+namespace Friendica\Util;
+
+use Friendica\Model\Group;
+
+/**
+ * Util class for ACL formatting
+ */
+final class ACLFormatter
+{
+ /**
+ * Turn user/group ACLs stored as angle bracketed text into arrays
+ *
+ * @param string|null $ids A angle-bracketed list of IDs
+ *
+ * @return array The array based on the IDs (empty in case there is no list)
+ */
+ public function expand(string $ids = null)
+ {
+ // In case there is no ID list, return empty array (=> no ACL set)
+ if (!isset($ids)) {
+ return [];
+ }
+
+ // turn string array of angle-bracketed elements into numeric array
+ // e.g. "<1><2><3>" => array(1,2,3);
+ preg_match_all('/<(' . Group::FOLLOWERS . '|'. Group::MUTUALS . '|[0-9]+)>/', $ids, $matches, PREG_PATTERN_ORDER);
+
+ return $matches[1];
+ }
+
+ /**
+ * Wrap ACL elements in angle brackets for storage
+ *
+ * @param string $item The item to sanitise
+ */
+ private function sanitize(string &$item) {
+ // The item is an ACL int value
+ if (intval($item)) {
+ $item = '<' . intval(Strings::escapeTags(trim($item))) . '>';
+ // The item is a allowed ACL character
+ } elseif (in_array($item, [Group::FOLLOWERS, Group::MUTUALS])) {
+ $item = '<' . $item . '>';
+ // The item is already a ACL string
+ } elseif (preg_match('/<\d+?>/', $item)) {
+ unset($item);
+ // The item is not supported, so remove it (cleanup)
+ } else {
+ $item = '';
+ }
+ }
+
+ /**
+ * Convert an ACL array to a storable string
+ *
+ * Normally ACL permissions will be an array.
+ * We'll also allow a comma-separated string.
+ *
+ * @param string|array $permissions
+ *
+ * @return string
+ */
+ function toString($permissions) {
+ $return = '';
+ if (is_array($permissions)) {
+ $item = $permissions;
+ } else {
+ $item = explode(',', $permissions);
+ }
+
+ if (is_array($item)) {
+ array_walk($item, [$this, 'sanitize']);
+ $return = implode('', $item);
+ }
+ return $return;
+ }
+}
return $d->format($format);
}
+
+ /**
+ * Checks, if the given string is a date with the pattern YYYY-MM
+ *
+ * @param string $dateString The given date
+ *
+ * @return boolean True, if the date is a valid pattern
+ */
+ public function isYearMonth(string $dateString)
+ {
+ // Check format (2019-01, 2019-1, 2019-10)
+ if (!preg_match('/^([12]\d{3}-(1[0-2]|0[1-9]|\d))$/', $dateString)) {
+ return false;
+ }
+
+ $date = DateTime::createFromFormat('Y-m', $dateString);
+
+ if (!$date) {
+ return false;
+ }
+
+ try {
+ $now = new DateTime();
+ } catch (\Throwable $t) {
+ return false;
+ }
+
+ if ($date > $now) {
+ return false;
+ }
+
+ return true;
+ }
}
.rand(10000, 99999);
// generate a multipart/alternative message header
- $messageHeader = defaults($params, 'additionalMailHeader', '') .
+ $messageHeader = ($params['additionalMailHeader'] ?? '') .
"From: $fromName <{$params['fromEmail']}>\n" .
"Reply-To: $fromName <{$params['replyTo']}>\n" .
"MIME-Version: 1.0\n" .
--- /dev/null
+<?php
+
+namespace Friendica\Util;
+
+/**
+ * Util class for filesystem manipulation
+ */
+final class FileSystem
+{
+ /**
+ * @var string a error message
+ */
+ private $errorMessage;
+
+ /**
+ * Creates a directory based on a file, which gets accessed
+ *
+ * @param string $file The file
+ *
+ * @return string The directory name (empty if no directory is found, like urls)
+ */
+ public function createDir(string $file)
+ {
+ $dirname = null;
+ $pos = strpos($file, '://');
+
+ if (!$pos) {
+ $dirname = realpath(dirname($file));
+ }
+
+ if (substr($file, 0, 7) === 'file://') {
+ $dirname = realpath(dirname(substr($file, 7)));
+ }
+
+ if (isset($dirname) && !is_dir($dirname)) {
+ set_error_handler([$this, 'customErrorHandler']);
+ $status = mkdir($dirname, 0777, true);
+ restore_error_handler();
+
+ if (!$status && !is_dir($dirname)) {
+ throw new \UnexpectedValueException(sprintf('Directory "%s" cannot get created: ' . $this->errorMessage, $dirname));
+ }
+
+ return $dirname;
+ } elseif (isset($dirname) && is_dir($dirname)) {
+ return $dirname;
+ } else {
+ return '';
+ }
+ }
+
+ /**
+ * Creates a stream based on a URL (could be a local file or a real URL)
+ *
+ * @param string $url The file/url
+ *
+ * @return false|resource the open stream ressource
+ */
+ public function createStream(string $url)
+ {
+ $directory = $this->createDir($url);
+ set_error_handler([$this, 'customErrorHandler']);
+ if (!empty($directory)) {
+ $url = $directory . DIRECTORY_SEPARATOR . pathinfo($url, PATHINFO_BASENAME);
+ }
+
+ $stream = fopen($url, 'ab');
+ restore_error_handler();
+
+ if (!is_resource($stream)) {
+ throw new \UnexpectedValueException(sprintf('The stream or file "%s" could not be opened: ' . $this->errorMessage, $url));
+ }
+
+ return $stream;
+ }
+
+ private function customErrorHandler($code, $msg)
+ {
+ $this->errorMessage = preg_replace('{^(fopen|mkdir)\(.*?\): }', '', $msg);
+ }
+}
namespace Friendica\Util\Logger;
use Friendica\Util\DateTimeFormat;
+use Friendica\Util\FileSystem;
use Friendica\Util\Introspection;
use Psr\Log\LogLevel;
private $pid;
/**
- * An error message
- * @var string
+ * @var FileSystem
*/
- private $errorMessage;
+ private $fileSystem;
/**
* Translates LogLevel log levels to integer values
*
* @throws \Exception
*/
- public function __construct($channel, $stream, Introspection $introspection, $level = LogLevel::DEBUG)
+ public function __construct($channel, $stream, Introspection $introspection, FileSystem $fileSystem, $level = LogLevel::DEBUG)
{
+ $this->fileSystem = $fileSystem;
+
parent::__construct($channel, $introspection);
if (is_resource($stream)) {
} else {
throw new \InvalidArgumentException(sprintf('The level "%s" is not valid.', $level));
}
+
+ $this->checkStream();
}
public function close()
throw new \LogicException('Missing stream URL.');
}
- $this->createDir();
- set_error_handler([$this, 'customErrorHandler']);
- $this->stream = fopen($this->url, 'ab');
- restore_error_handler();
-
- if (!is_resource($this->stream)) {
- $this->stream = null;
-
- throw new \UnexpectedValueException(sprintf('The stream or file "%s" could not be opened: ' . $this->errorMessage, $this->url));
- }
- }
-
- private function createDir()
- {
- $dirname = null;
- $pos = strpos($this->url, '://');
- if (!$pos) {
- $dirname = dirname($this->url);
- }
-
- if (substr($this->url, 0, 7) === 'file://') {
- $dirname = dirname(substr($this->url, 7));
- }
-
- if (isset($dirname) && !is_dir($dirname)) {
- set_error_handler([$this, 'customErrorHandler']);
- $status = mkdir($dirname, 0777, true);
- restore_error_handler();
-
- if (!$status && !is_dir($dirname)) {
- throw new \UnexpectedValueException(sprintf('Directory "%s" cannot get created: ' . $this->errorMessage, $dirname));
- }
- }
- }
-
- private function customErrorHandler($code, $msg)
- {
- $this->errorMessage = preg_replace('{^(fopen|mkdir)\(.*?\): }', '', $msg);
+ $this->stream = $this->fileSystem->createStream($this->url);
}
}
}
/**
- * Maps the LogLevel (@see LogLevel ) to a SysLog priority (@see http://php.net/manual/en/function.syslog.php#refsect1-function.syslog-parameters )
+ * Maps the LogLevel (@see LogLevel) to a SysLog priority (@see http://php.net/manual/en/function.syslog.php#refsect1-function.syslog-parameters)
*
* @param string $level A LogLevel
*
$parts2 = [];
$parts = parse_url($url);
- $path_parts = explode('/', defaults($parts, 'path', ''));
+ $path_parts = explode('/', $parts['path'] ?? '');
foreach ($path_parts as $part) {
if (strlen($part) <> mb_strlen($part)) {
$parts2[] = rawurlencode($part);
curl_setopt($ch, CURLOPT_TIMEOUT, intval($curl_time));
}
- if (defined('LIGHTTPD')) {
- if (empty($headers)) {
- $headers = ['Expect:'];
- } else {
- if (!in_array('Expect:', $headers)) {
- array_push($headers, 'Expect:');
- }
- }
- }
-
if (!empty($headers)) {
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
}
$a->getProfiler()->saveTimestamp($stamp1, 'network', System::callstack());
+ // Very old versions of Lighttpd don't like the "Expect" header, so we remove it when needed
+ if ($curlResponse->getReturnCode() == 417) {
+ $redirects++;
+
+ if (empty($headers)) {
+ $headers = ['Expect:'];
+ } else {
+ if (!in_array('Expect:', $headers)) {
+ array_push($headers, 'Expect:');
+ }
+ }
+ Logger::info('Server responds with 417, applying workaround', ['url' => $url]);
+ return self::post($url, $params, $headers, $redirects, $timeout);
+ }
+
Logger::log('post_url: end ' . $url, Logger::DATA);
return $curlResponse;
/// @TODO Really suppress function outcomes? Why not find them + debug them?
$h = @parse_url($url);
- if (!empty($h['host']) && (@dns_get_record($h['host'], DNS_A + DNS_CNAME) || filter_var($h['host'], FILTER_VALIDATE_IP) )) {
+ if (!empty($h['host']) && (@dns_get_record($h['host'], DNS_A + DNS_CNAME) || filter_var($h['host'], FILTER_VALIDATE_IP))) {
return $url;
}
$h = substr($addr, strpos($addr, '@') + 1);
// Concerning the @ see here: https://stackoverflow.com/questions/36280957/dns-get-record-a-temporary-server-error-occurred
- if ($h && (@dns_get_record($h, DNS_A + DNS_MX) || filter_var($h, FILTER_VALIDATE_IP) )) {
+ if ($h && (@dns_get_record($h, DNS_A + DNS_MX) || filter_var($h, FILTER_VALIDATE_IP))) {
return true;
}
if ($h && @dns_get_record($h, DNS_CNAME + DNS_MX)) {
$i = 0;
$path = "";
do {
- $path1 = defaults($pathparts1, $i, '');
- $path2 = defaults($pathparts2, $i, '');
+ $path1 = $pathparts1[$i] ?? '';
+ $path2 = $pathparts2[$i] ?? '';
if ($path1 == $path2) {
$path .= $path1."/";
}
// If the file is too large then exit
- if (defaults($curlResult->getInfo(), 'download_content_length', 0) > 1000000) {
+ if (($curlResult->getInfo()['download_content_length'] ?? 0) > 1000000) {
return $siteinfo;
}
* A class to store profiling data
* It can handle different logging data for specific functions or global performance measures
*
- * It stores the data as log entries (@see LoggerInterface )
+ * It stores the data as log entries (@see LoggerInterface)
*/
class Profiler implements ContainerInterface
{
return;
}
- $duration = (float) (microtime(true) - $timestamp);
+ $duration = floatval(microtime(true) - $timestamp);
if (!isset($this->performance[$value])) {
// Prevent ugly E_NOTICE
<?php
+
/**
* @file src/Util/Strings.php
*/
* @return string
* @throws \Exception
*/
- public static function getRandomHex($size = 64)
- {
- $byte_size = ceil($size / 2);
+ public static function getRandomHex($size = 64)
+ {
+ $byte_size = ceil($size / 2);
- $bytes = random_bytes($byte_size);
+ $bytes = random_bytes($byte_size);
- $return = substr(bin2hex($bytes), 0, $size);
+ $return = substr(bin2hex($bytes), 0, $size);
- return $return;
- }
+ return $return;
+ }
/**
* Checks, if the given string is a valid hexadecimal code
*
* @return bool
*/
- public static function isHex($hexCode)
- {
- return !empty($hexCode) ? @preg_match("/^[a-f0-9]{2,}$/i", $hexCode) && !(strlen($hexCode) & 1) : false;
- }
-
- /**
- * @brief This is our primary input filter.
- *
- * Use this on any text input where angle chars are not valid or permitted
- * They will be replaced with safer brackets. This may be filtered further
- * if these are not allowed either.
- *
- * @param string $string Input string
- * @return string Filtered string
- */
- public static function escapeTags($string)
- {
- return str_replace(["<", ">"], ['[', ']'], $string);
- }
-
- /**
- * @brief Use this on "body" or "content" input where angle chars shouldn't be removed,
- * and allow them to be safely displayed.
- * @param string $string
- *
- * @return string
- */
- public static function escapeHtml($string)
- {
- return htmlspecialchars($string, ENT_COMPAT, 'UTF-8', false);
- }
-
- /**
- * @brief Generate a string that's random, but usually pronounceable. Used to generate initial passwords
- *
- * @param int $len length
- *
- * @return string
- */
- public static function getRandomName($len)
- {
- if ($len <= 0) {
- return '';
- }
-
- $vowels = ['a', 'a', 'ai', 'au', 'e', 'e', 'e', 'ee', 'ea', 'i', 'ie', 'o', 'ou', 'u'];
-
- if (mt_rand(0, 5) == 4) {
- $vowels[] = 'y';
- }
-
- $cons = [
- 'b', 'bl', 'br',
- 'c', 'ch', 'cl', 'cr',
- 'd', 'dr',
- 'f', 'fl', 'fr',
- 'g', 'gh', 'gl', 'gr',
- 'h',
- 'j',
- 'k', 'kh', 'kl', 'kr',
- 'l',
- 'm',
- 'n',
- 'p', 'ph', 'pl', 'pr',
- 'qu',
- 'r', 'rh',
- 's' ,'sc', 'sh', 'sm', 'sp', 'st',
- 't', 'th', 'tr',
- 'v',
- 'w', 'wh',
- 'x',
- 'z', 'zh'
- ];
-
- $midcons = ['ck', 'ct', 'gn', 'ld', 'lf', 'lm', 'lt', 'mb', 'mm', 'mn', 'mp',
- 'nd', 'ng', 'nk', 'nt', 'rn', 'rp', 'rt'];
-
- $noend = ['bl', 'br', 'cl', 'cr', 'dr', 'fl', 'fr', 'gl', 'gr',
- 'kh', 'kl', 'kr', 'mn', 'pl', 'pr', 'rh', 'tr', 'qu', 'wh', 'q'];
-
- $start = mt_rand(0, 2);
- if ($start == 0) {
- $table = $vowels;
- } else {
- $table = $cons;
- }
-
- $word = '';
-
- for ($x = 0; $x < $len; $x ++) {
- $r = mt_rand(0, count($table) - 1);
- $word .= $table[$r];
-
- if ($table == $vowels) {
- $table = array_merge($cons, $midcons);
- } else {
- $table = $vowels;
- }
-
- }
-
- $word = substr($word, 0, $len);
-
- foreach ($noend as $noe) {
- $noelen = strlen($noe);
- if ((strlen($word) > $noelen) && (substr($word, -$noelen) == $noe)) {
- $word = self::getRandomName($len);
- break;
- }
- }
-
- return $word;
- }
+ public static function isHex($hexCode)
+ {
+ return !empty($hexCode) ? @preg_match("/^[a-f0-9]{2,}$/i", $hexCode) && !(strlen($hexCode) & 1) : false;
+ }
+
+ /**
+ * @brief This is our primary input filter.
+ *
+ * Use this on any text input where angle chars are not valid or permitted
+ * They will be replaced with safer brackets. This may be filtered further
+ * if these are not allowed either.
+ *
+ * @param string $string Input string
+ * @return string Filtered string
+ */
+ public static function escapeTags($string)
+ {
+ return str_replace(["<", ">"], ['[', ']'], $string);
+ }
+
+ /**
+ * @brief Use this on "body" or "content" input where angle chars shouldn't be removed,
+ * and allow them to be safely displayed.
+ * @param string $string
+ *
+ * @return string
+ */
+ public static function escapeHtml($string)
+ {
+ return htmlspecialchars($string, ENT_COMPAT, 'UTF-8', false);
+ }
+
+ /**
+ * @brief Generate a string that's random, but usually pronounceable. Used to generate initial passwords
+ *
+ * @param int $len length
+ *
+ * @return string
+ */
+ public static function getRandomName($len)
+ {
+ if ($len <= 0) {
+ return '';
+ }
+
+ $vowels = ['a', 'a', 'ai', 'au', 'e', 'e', 'e', 'ee', 'ea', 'i', 'ie', 'o', 'ou', 'u'];
+
+ if (mt_rand(0, 5) == 4) {
+ $vowels[] = 'y';
+ }
+
+ $cons = [
+ 'b', 'bl', 'br',
+ 'c', 'ch', 'cl', 'cr',
+ 'd', 'dr',
+ 'f', 'fl', 'fr',
+ 'g', 'gh', 'gl', 'gr',
+ 'h',
+ 'j',
+ 'k', 'kh', 'kl', 'kr',
+ 'l',
+ 'm',
+ 'n',
+ 'p', 'ph', 'pl', 'pr',
+ 'qu',
+ 'r', 'rh',
+ 's', 'sc', 'sh', 'sm', 'sp', 'st',
+ 't', 'th', 'tr',
+ 'v',
+ 'w', 'wh',
+ 'x',
+ 'z', 'zh'
+ ];
+
+ $midcons = [
+ 'ck', 'ct', 'gn', 'ld', 'lf', 'lm', 'lt', 'mb', 'mm', 'mn', 'mp',
+ 'nd', 'ng', 'nk', 'nt', 'rn', 'rp', 'rt'
+ ];
+
+ $noend = [
+ 'bl', 'br', 'cl', 'cr', 'dr', 'fl', 'fr', 'gl', 'gr',
+ 'kh', 'kl', 'kr', 'mn', 'pl', 'pr', 'rh', 'tr', 'qu', 'wh', 'q'
+ ];
+
+ $start = mt_rand(0, 2);
+ if ($start == 0) {
+ $table = $vowels;
+ } else {
+ $table = $cons;
+ }
+
+ $word = '';
+
+ for ($x = 0; $x < $len; $x++) {
+ $r = mt_rand(0, count($table) - 1);
+ $word .= $table[$r];
+
+ if ($table == $vowels) {
+ $table = array_merge($cons, $midcons);
+ } else {
+ $table = $vowels;
+ }
+ }
+
+ $word = substr($word, 0, $len);
+
+ foreach ($noend as $noe) {
+ $noelen = strlen($noe);
+ if ((strlen($word) > $noelen) && (substr($word, -$noelen) == $noe)) {
+ $word = self::getRandomName($len);
+ break;
+ }
+ }
+
+ return $word;
+ }
/**
* Translate and format the network name of a contact
*
* @param string $network Network name of the contact (e.g. dfrn, rss and so on)
- * @param string $url The contact url
+ * @param string $url The contact url
*
* @return string Formatted network name
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
- public static function formatNetworkName($network, $url = '')
- {
- if ($network != '') {
- if ($url != '') {
- $network_name = '<a href="' . $url .'">' . ContactSelector::networkToName($network, $url) . '</a>';
- } else {
- $network_name = ContactSelector::networkToName($network);
- }
-
- return $network_name;
- }
- }
-
- /**
- * @brief Remove indentation from a text
- *
- * @param string $text String to be transformed.
- * @param string $chr Optional. Indentation tag. Default tab (\t).
- * @param int $count Optional. Default null.
- *
- * @return string Transformed string.
- */
- public static function deindent($text, $chr = "[\t ]", $count = NULL)
- {
- $lines = explode("\n", $text);
-
- if (is_null($count)) {
- $m = [];
- $k = 0;
- while ($k < count($lines) && strlen($lines[$k]) == 0) {
- $k++;
- }
- preg_match("|^" . $chr . "*|", $lines[$k], $m);
- $count = strlen($m[0]);
- }
-
- for ($k = 0; $k < count($lines); $k++) {
- $lines[$k] = preg_replace("|^" . $chr . "{" . $count . "}|", "", $lines[$k]);
- }
-
- return implode("\n", $lines);
- }
-
- /**
- * @brief Get byte size returned in a Data Measurement (KB, MB, GB)
- *
- * @param int $bytes The number of bytes to be measured
- * @param int $precision Optional. Default 2.
- *
- * @return string Size with measured units.
- */
- public static function formatBytes($bytes, $precision = 2)
- {
- $units = ['B', 'KB', 'MB', 'GB', 'TB'];
- $bytes = max($bytes, 0);
- $pow = floor(($bytes ? log($bytes) : 0) / log(1024));
- $pow = min($pow, count($units) - 1);
- $bytes /= pow(1024, $pow);
-
- return round($bytes, $precision) . ' ' . $units[$pow];
- }
-
- /**
- * @brief Protect percent characters in sprintf calls
- *
- * @param string $s String to transform.
- *
- * @return string Transformed string.
- */
- public static function protectSprintf($s)
- {
- return str_replace('%', '%%', $s);
- }
-
- /**
- * @brief Base64 Encode URL and translate +/ to -_ Optionally strip padding.
- *
- * @param string $s URL to encode
- * @param boolean $strip_padding Optional. Default false
- *
- * @return string Encoded URL
- */
- public static function base64UrlEncode($s, $strip_padding = false)
- {
- $s = strtr(base64_encode($s), '+/', '-_');
-
- if ($strip_padding) {
- $s = str_replace('=', '', $s);
- }
-
- return $s;
- }
+ public static function formatNetworkName($network, $url = '')
+ {
+ if ($network != '') {
+ if ($url != '') {
+ $network_name = '<a href="' . $url . '">' . ContactSelector::networkToName($network, $url) . '</a>';
+ } else {
+ $network_name = ContactSelector::networkToName($network);
+ }
+
+ return $network_name;
+ }
+ }
+
+ /**
+ * @brief Remove indentation from a text
+ *
+ * @param string $text String to be transformed.
+ * @param string $chr Optional. Indentation tag. Default tab (\t).
+ * @param int $count Optional. Default null.
+ *
+ * @return string Transformed string.
+ */
+ public static function deindent($text, $chr = "[\t ]", $count = NULL)
+ {
+ $lines = explode("\n", $text);
+
+ if (is_null($count)) {
+ $m = [];
+ $k = 0;
+ while ($k < count($lines) && strlen($lines[$k]) == 0) {
+ $k++;
+ }
+ preg_match("|^" . $chr . "*|", $lines[$k], $m);
+ $count = strlen($m[0]);
+ }
+
+ for ($k = 0; $k < count($lines); $k++) {
+ $lines[$k] = preg_replace("|^" . $chr . "{" . $count . "}|", "", $lines[$k]);
+ }
+
+ return implode("\n", $lines);
+ }
+
+ /**
+ * @brief Get byte size returned in a Data Measurement (KB, MB, GB)
+ *
+ * @param int $bytes The number of bytes to be measured
+ * @param int $precision Optional. Default 2.
+ *
+ * @return string Size with measured units.
+ */
+ public static function formatBytes($bytes, $precision = 2)
+ {
+ $units = ['B', 'KB', 'MB', 'GB', 'TB'];
+ $bytes = max($bytes, 0);
+ $pow = floor(($bytes ? log($bytes) : 0) / log(1024));
+ $pow = min($pow, count($units) - 1);
+ $bytes /= pow(1024, $pow);
+
+ return round($bytes, $precision) . ' ' . $units[$pow];
+ }
+
+ /**
+ * @brief Protect percent characters in sprintf calls
+ *
+ * @param string $s String to transform.
+ *
+ * @return string Transformed string.
+ */
+ public static function protectSprintf($s)
+ {
+ return str_replace('%', '%%', $s);
+ }
+
+ /**
+ * @brief Base64 Encode URL and translate +/ to -_ Optionally strip padding.
+ *
+ * @param string $s URL to encode
+ * @param boolean $strip_padding Optional. Default false
+ *
+ * @return string Encoded URL
+ */
+ public static function base64UrlEncode($s, $strip_padding = false)
+ {
+ $s = strtr(base64_encode($s), '+/', '-_');
+
+ if ($strip_padding) {
+ $s = str_replace('=', '', $s);
+ }
+
+ return $s;
+ }
/**
* @brief Decode Base64 Encoded URL and translate -_ to +/
* @param string $s URL to decode
*
- * @return string Decoded URL
+ * @return string Decoded URL
* @throws \Exception
*/
- public static function base64UrlDecode($s)
- {
- if (is_array($s)) {
- Logger::log('base64url_decode: illegal input: ' . print_r(debug_backtrace(), true));
- return $s;
- }
-
- /*
- * // Placeholder for new rev of salmon which strips base64 padding.
- * // PHP base64_decode handles the un-padded input without requiring this step
- * // Uncomment if you find you need it.
- *
- * $l = strlen($s);
- * if (!strpos($s,'=')) {
- * $m = $l % 4;
- * if ($m == 2)
- * $s .= '==';
- * if ($m == 3)
- * $s .= '=';
- * }
- *
- */
-
- return base64_decode(strtr($s, '-_', '+/'));
- }
-
- /**
- * @brief Normalize url
- *
- * @param string $url URL to be normalized.
- *
- * @return string Normalized URL.
- */
- public static function normaliseLink($url)
- {
- $ret = str_replace(['https:', '//www.'], ['http:', '//'], $url);
- return rtrim($ret, '/');
- }
-
- /**
- * @brief Normalize OpenID identity
- *
- * @param string $s OpenID Identity
- *
- * @return string normalized OpenId Identity
- */
- public static function normaliseOpenID($s)
- {
- return trim(str_replace(['http://', 'https://'], ['', ''], $s), '/');
- }
-
- /**
- * @brief Compare two URLs to see if they are the same, but ignore
- * slight but hopefully insignificant differences such as if one
- * is https and the other isn't, or if one is www.something and
- * the other isn't - and also ignore case differences.
- *
- * @param string $a first url
- * @param string $b second url
- * @return boolean True if the URLs match, otherwise False
- *
- */
- public static function compareLink($a, $b)
- {
- return (strcasecmp(self::normaliseLink($a), self::normaliseLink($b)) === 0);
- }
+ public static function base64UrlDecode($s)
+ {
+ if (is_array($s)) {
+ Logger::log('base64url_decode: illegal input: ' . print_r(debug_backtrace(), true));
+ return $s;
+ }
+
+ /*
+ * // Placeholder for new rev of salmon which strips base64 padding.
+ * // PHP base64_decode handles the un-padded input without requiring this step
+ * // Uncomment if you find you need it.
+ *
+ * $l = strlen($s);
+ * if (!strpos($s,'=')) {
+ * $m = $l % 4;
+ * if ($m == 2)
+ * $s .= '==';
+ * if ($m == 3)
+ * $s .= '=';
+ * }
+ *
+ */
+
+ return base64_decode(strtr($s, '-_', '+/'));
+ }
+
+ /**
+ * @brief Normalize url
+ *
+ * @param string $url URL to be normalized.
+ *
+ * @return string Normalized URL.
+ */
+ public static function normaliseLink($url)
+ {
+ $ret = str_replace(['https:', '//www.'], ['http:', '//'], $url);
+ return rtrim($ret, '/');
+ }
+
+ /**
+ * @brief Normalize OpenID identity
+ *
+ * @param string $s OpenID Identity
+ *
+ * @return string normalized OpenId Identity
+ */
+ public static function normaliseOpenID($s)
+ {
+ return trim(str_replace(['http://', 'https://'], ['', ''], $s), '/');
+ }
+ /**
+ * @brief Compare two URLs to see if they are the same, but ignore
+ * slight but hopefully insignificant differences such as if one
+ * is https and the other isn't, or if one is www.something and
+ * the other isn't - and also ignore case differences.
+ *
+ * @param string $a first url
+ * @param string $b second url
+ * @return boolean True if the URLs match, otherwise False
+ *
+ */
+ public static function compareLink($a, $b)
+ {
+ return (strcasecmp(self::normaliseLink($a), self::normaliseLink($b)) === 0);
+ }
/**
* Ensures the provided URI has its query string punctuation in order.
return $uri;
}
-
/**
* Check if the trimmed provided string is starting with one of the provided characters
*
* @param string $string
- * @param array $chars
+ * @param array $chars
* @return bool
*/
public static function startsWith($string, array $chars)
public static function autoLinkRegEx()
{
return '@
-(?<![=\'\]"/]) # Not preceded by [, =, \', ], ", /
+(?<![=\'\]"/]) # Not preceded by [, =, \', ], ", /
\b
-( # Capture 1: entire matched URL
- https?:// # http or https protocol
+( # Capture 1: entire matched URL
+ https?:// # http or https protocol
(?:
- [^/\s\xA0`!()\[\]{};:\'",<>?«»“”‘’.] # Domain can\'t start with a .
- [^/\s\xA0`!()\[\]{};:\'",<>?«»“”‘’]+ # Domain can\'t end with a .
- \.
- [^/\s\xA0`!()\[\]{};:\'".,<>?«»“”‘’]+/? # Followed by a slash
+ [^/\s\xA0`!()\[\]{};:\'",<>?«»“”‘’.] # Domain can\'t start with a .
+ [^/\s\xA0`!()\[\]{};:\'",<>?«»“”‘’]+ # Domain can\'t end with a .
+ \.
+ [^/\s\xA0`!()\[\]{};:\'".,<>?«»“”‘’]+/? # Followed by a slash
)
- (?: # One or more:
- [^\s\xA0()<>]+ # Run of non-space, non-()<>
- | # or
- \(([^\s\xA0()<>]+|(\([^\s()<>]+\)))*\) # balanced parens, up to 2 levels
- | # or
- [^\s\xA0`!()\[\]{};:\'".,<>?«»“”‘’] # not a space or one of these punct chars
+ (?: # One or more:
+ [^\s\xA0()<>]+ # Run of non-space, non-()<>
+ | # or
+ \(([^\s\xA0()<>]+|(\([^\s()<>]+\)))*\) # balanced parens, up to 2 levels
+ | # or
+ [^\s\xA0`!()\[\]{};:\'".,<>?«»“”‘’] # not a space or one of these punct chars
)*
)@xiu';
}
*/
private static function deliverDFRN($cmd, $contact, $owner, $items, $target_item, $public_message, $top_level, $followup)
{
- Logger::log('Deliver ' . defaults($target_item, 'guid', $target_item['id']) . ' via DFRN to ' . (empty($contact['addr']) ? $contact['url'] : $contact['addr']));
+ Logger::info('Deliver ' . (($target_item['guid'] ?? '') ?: $target_item['id']) . ' via DFRN to ' . (($contact['addr'] ?? '') ?: $contact['url']));
if ($cmd == self::MAIL) {
$item = $target_item;
$atom = DFRN::entries($msgitems, $owner);
}
- Logger::log('Notifier entry: ' . $contact["url"] . ' ' . defaults($target_item, 'guid', $target_item['id']) . ' entry: ' . $atom, Logger::DATA);
+ Logger::debug('Notifier entry: ' . $contact["url"] . ' ' . (($target_item['guid'] ?? '') ?: $target_item['id']) . ' entry: ' . $atom);
$basepath = implode('/', array_slice(explode('/', $contact['url']), 0, 3));
// We never spool failed relay deliveries
if ($public_dfrn) {
- Logger::log('Relay delivery to ' . $contact["url"] . ' with guid ' . $target_item["guid"] . ' returns ' . $deliver_status);
+ Logger::info('Relay delivery to ' . $contact["url"] . ' with guid ' . $target_item["guid"] . ' returns ' . $deliver_status);
if (in_array($cmd, [Delivery::POST, Delivery::POKE])) {
if (($deliver_status >= 200) && ($deliver_status <= 299)) {
$protocol = Model\ItemDeliveryData::LEGACY_DFRN;
}
- Logger::info('DFRN Delivery', ['cmd' => $cmd, 'url' => $contact['url'], 'guid' => defaults($target_item, 'guid', $target_item['id']), 'return' => $deliver_status]);
+ Logger::info('DFRN Delivery', ['cmd' => $cmd, 'url' => $contact['url'], 'guid' => ($target_item['guid'] ?? '') ?: $target_item['id'], 'return' => $deliver_status]);
if (($deliver_status >= 200) && ($deliver_status <= 299)) {
// We successfully delivered a message, the contact is alive
// The message could not be delivered. We mark the contact as "dead"
Model\Contact::markForArchival($contact);
- Logger::info('Delivery failed: defer message', ['id' => defaults($target_item, 'guid', $target_item['id'])]);
+ Logger::info('Delivery failed: defer message', ['id' => ($target_item['guid'] ?? '') ?: $target_item['id']]);
if (!Worker::defer() && in_array($cmd, [Delivery::POST, Delivery::POKE])) {
Model\ItemDeliveryData::incrementQueueFailed($target_item['id']);
}
}
if (empty($contact['contact-type']) || ($contact['contact-type'] != Model\Contact::TYPE_RELAY)) {
- Logger::info('Delivery failed: defer message', ['id' => defaults($target_item, 'guid', $target_item['id'])]);
+ Logger::info('Delivery failed: defer message', ['id' => ($target_item['guid'] ?? '') ?: $target_item['id']]);
// defer message for redelivery
if (!Worker::defer() && in_array($cmd, [Delivery::POST, Delivery::POKE])) {
Model\ItemDeliveryData::incrementQueueFailed($target_item['id']);
$result = Cache::get("gprobe:".$urlparts["host"]);
if (!is_null($result)) {
if (in_array($result["network"], [Protocol::FEED, Protocol::PHANTOM])) {
- Logger::log("DDoS attempt detected for ".$urlparts["host"]." by ".defaults($_SERVER, "REMOTE_ADDR", '').". server data: ".print_r($_SERVER, true), Logger::DEBUG);
+ Logger::debug("DDoS attempt detected for " . $urlparts["host"] . " by " . ($_SERVER["REMOTE_ADDR"] ?? ''), ['$_SERVER' => $_SERVER]);
return;
}
}
use Friendica\Protocol\Diaspora;
use Friendica\Protocol\OStatus;
use Friendica\Protocol\Salmon;
+use Friendica\Util\ACLFormatter;
require_once 'include/items.php';
$fields = ['network', 'author-id', 'author-link', 'owner-id'];
$condition = ['uri' => $target_item["thr-parent"], 'uid' => $target_item["uid"]];
$thr_parent = Item::selectFirst($fields, $condition);
+ if (empty($thr_parent)) {
+ $thr_parent = $parent;
+ }
Logger::log('GUID: ' . $target_item["guid"] . ': Parent is ' . $parent['network'] . '. Thread parent is ' . $thr_parent['network'], Logger::DEBUG);
$public_message = false; // private recipients, not public
}
- $allow_people = expand_acl($parent['allow_cid']);
- $allow_groups = Group::expand($uid, expand_acl($parent['allow_gid']),true);
- $deny_people = expand_acl($parent['deny_cid']);
- $deny_groups = Group::expand($uid, expand_acl($parent['deny_gid']));
+ /** @var ACLFormatter $aclFormatter */
+ $aclFormatter = BaseObject::getClass(ACLFormatter::class);
+
+ $allow_people = $aclFormatter->expand($parent['allow_cid']);
+ $allow_groups = Group::expand($uid, $aclFormatter->expand($parent['allow_gid']),true);
+ $deny_people = $aclFormatter->expand($parent['deny_cid']);
+ $deny_groups = Group::expand($uid, $aclFormatter->expand($parent['deny_gid']));
// if our parent is a public forum (forum_mode == 1), uplink to the origional author causing
// a delivery fork. private groups (forum_mode == 2) do not uplink
"SELECT
`batch`,
ANY_VALUE(`id`) AS `id`,
+ ANY_VALUE(`url`) AS `url`,
ANY_VALUE(`name`) AS `name`,
ANY_VALUE(`network`) AS `network`,
ANY_VALUE(`protocol`) AS `protocol`
}
if (self::skipDFRN($contact, $target_item, $parent, $thr_parent, $cmd)) {
- Logger::info('Contact can be delivered via AP, so skip delivery via legacy DFRN/Diaspora', ['target' => $target_id, 'url' => contact['url']]);
+ Logger::info('Contact can be delivered via AP, so skip delivery via legacy DFRN/Diaspora', ['target' => $target_id, 'url' => $contact['url']]);
continue;
}
use Friendica\Model\Contact;
use Friendica\Model\Item;
use Friendica\Model\User;
+use Friendica\Protocol\Activity;
use Friendica\Protocol\ActivityPub;
use Friendica\Protocol\Email;
use Friendica\Protocol\PortableContact;
Logger::log("Mail: Parsing mail ".$msg_uid, Logger::DATA);
$datarray = [];
- $datarray['verb'] = ACTIVITY_POST;
- $datarray['object-type'] = ACTIVITY_OBJ_NOTE;
+ $datarray['verb'] = Activity::POST;
+ $datarray['object-type'] = Activity\ObjectType::NOTE;
$datarray['network'] = Protocol::MAIL;
// $meta = Email::messageMeta($mbox, $msg_uid);
use Friendica\App;
use Friendica\Core\Cache;
use Friendica\Core\Config;
+use Friendica\Core\L10n\L10n;
use Friendica\Core\Lock\ILock;
use Friendica\Database\Database;
use Friendica\Factory;
['addRoutes', [include __DIR__ . '/routes.config.php'], Dice::CHAIN_CALL],
],
],
+ L10n::class => [
+ 'constructParams' => [
+ $_SERVER, $_GET
+ ],
+ ],
];
'/ignored' => [Module\Contact::class, [R::GET]],
],
'/credits' => [Module\Credits::class, [R::GET]],
+ '/delegation'=> [Module\Delegation::class, [R::GET, R::POST]],
'/dirfind' => [Module\Search\Directory::class, [R::GET]],
'/directory' => [Module\Directory::class, [R::GET]],
'/{group:\d+}/add/{contact:\d+}' => [Module\Group::class, [R::GET, R::POST]],
'/{group:\d+}/remove/{contact:\d+}' => [Module\Group::class, [R::GET, R::POST]],
],
- '/hashtag' => [Module\Hashtag::class, [R::GET]],
- '/home' => [Module\Home::class, [R::GET]],
- '/help[/{doc:.+}]' => [Module\Help::class, [R::GET]],
- '/inbox[/{nickname}]' => [Module\Inbox::class, [R::GET, R::POST]],
- '/invite' => [Module\Invite::class, [R::GET, R::POST]],
+ '/hashtag' => [Module\Hashtag::class, [R::GET]],
+ '/home' => [Module\Home::class, [R::GET]],
+ '/help[/{doc:.+}]' => [Module\Help::class, [R::GET]],
+ '/inbox[/{nickname}]' => [Module\Inbox::class, [R::GET, R::POST]],
+ '/invite' => [Module\Invite::class, [R::GET, R::POST]],
'/install' => [
'[/]' => [Module\Install::class, [R::GET, R::POST]],
'/testrewrite' => [Module\Install::class, [R::GET]],
],
+
+ '/item' => [
+ '/ignore/{id}' => [Module\Item\Ignore::class, [R::GET]],
+ ],
+
'/like/{item:\d+}' => [Module\Like::class, [R::GET]],
'/localtime' => [Module\Debug\Localtime::class, [R::GET, R::POST]],
'/login' => [Module\Login::class, [R::GET, R::POST]],
'/search' => [
'[/]' => [Module\Search\Index::class, [R::GET]],
'/acl' => [Module\Search\Acl::class, [R::GET, R::POST]],
- '/saved/add/{term}' => [Module\Search\Saved::class, [R::GET]],
- '/saved/remove/{term}' => [Module\Search\Saved::class, [R::GET]],
+ '/saved/add' => [Module\Search\Saved::class, [R::GET]],
+ '/saved/remove' => [Module\Search\Saved::class, [R::GET]],
+ ],
+
+ '/receive' => [
+ '/public' => [Module\Diaspora\Receive::class, [R::POST]],
+ '/users/{guid}' => [Module\Diaspora\Receive::class, [R::POST]],
],
'/settings' => [
+++ /dev/null
-<?php
-/**
- * TextTest class.
- */
-
-namespace Friendica\Test;
-
-use Friendica\Model\Group;
-use PHPUnit\Framework\TestCase;
-
-/**
- * Tests for text functions.
- */
-class TextTest extends TestCase
-{
- /**
- * test attribute contains
- */
- public function testAttributeContains1()
- {
- $testAttr="class1 notclass2 class3";
- $this->assertTrue(attribute_contains($testAttr, "class3"));
- $this->assertFalse(attribute_contains($testAttr, "class2"));
- }
-
- /**
- * test attribute contains
- */
- public function testAttributeContains2()
- {
- $testAttr="class1 not-class2 class3";
- $this->assertTrue(attribute_contains($testAttr, "class3"));
- $this->assertFalse(attribute_contains($testAttr, "class2"));
- }
-
- /**
- * test with empty input
- */
- public function testAttributeContainsEmpty()
- {
- $testAttr="";
- $this->assertFalse(attribute_contains($testAttr, "class2"));
- }
-
- /**
- * test input with special chars
- */
- public function testAttributeContainsSpecialChars()
- {
- $testAttr="--... %\$ä() /(=?}";
- $this->assertFalse(attribute_contains($testAttr, "class2"));
- }
-
- /**
- * test expand_acl, perfect input
- */
- public function testExpandAclNormal()
- {
- $text='<1><2><3><' . Group::FOLLOWERS . '><' . Group::MUTUALS . '>';
- $this->assertEquals(array('1', '2', '3', Group::FOLLOWERS, Group::MUTUALS), expand_acl($text));
- }
-
- /**
- * test with a big number
- */
- public function testExpandAclBigNumber()
- {
- $text='<1><' . PHP_INT_MAX . '><15>';
- $this->assertEquals(array('1', (string)PHP_INT_MAX, '15'), expand_acl($text));
- }
-
- /**
- * test with a string in it.
- *
- * @todo is this valid input? Otherwise: should there be an exception?
- */
- public function testExpandAclString()
- {
- $text="<1><279012><tt>";
- $this->assertEquals(array('1', '279012'), expand_acl($text));
- }
-
- /**
- * test with a ' ' in it.
- *
- * @todo is this valid input? Otherwise: should there be an exception?
- */
- public function testExpandAclSpace()
- {
- $text="<1><279 012><32>";
- $this->assertEquals(array('1', '32'), expand_acl($text));
- }
-
- /**
- * test empty input
- */
- public function testExpandAclEmpty()
- {
- $text="";
- $this->assertEquals(array(), expand_acl($text));
- }
-
- /**
- * test invalid input, no < at all
- *
- * @todo should there be an exception?
- */
- public function testExpandAclNoBrackets()
- {
- $text="According to documentation, that's invalid. "; //should be invalid
- $this->assertEquals(array(), expand_acl($text));
- }
-
- /**
- * test invalid input, just open <
- *
- * @todo should there be an exception?
- */
- public function testExpandAclJustOneBracket1()
- {
- $text="<Another invalid string"; //should be invalid
- $this->assertEquals(array(), expand_acl($text));
- }
-
- /**
- * test invalid input, just close >
- *
- * @todo should there be an exception?
- */
- public function testExpandAclJustOneBracket2()
- {
- $text="Another invalid> string"; //should be invalid
- $this->assertEquals(array(), expand_acl($text));
- }
-
- /**
- * test invalid input, just close >
- *
- * @todo should there be an exception?
- */
- public function testExpandAclCloseOnly()
- {
- $text="Another> invalid> string>"; //should be invalid
- $this->assertEquals(array(), expand_acl($text));
- }
-
- /**
- * test invalid input, just open <
- *
- * @todo should there be an exception?
- */
- public function testExpandAclOpenOnly()
- {
- $text="<Another< invalid string<"; //should be invalid
- $this->assertEquals(array(), expand_acl($text));
- }
-
- /**
- * test invalid input, open and close do not match
- *
- * @todo should there be an exception?
- */
- public function testExpandAclNoMatching1()
- {
- $text="<Another<> invalid <string>"; //should be invalid
- $this->assertEquals(array(), expand_acl($text));
- }
-
- /**
- * test invalid input, empty <>
- *
- * @todo should there be an exception? Or array(1, 3)
- * (This should be array(1,3) - mike)
- */
- public function testExpandAclEmptyMatch()
- {
- $text="<1><><3>";
- $this->assertEquals(array('1', '3'), expand_acl($text));
- }
-
- /**
- * test hex2bin and reverse
- */
- public function testHex2Bin()
- {
- $this->assertEquals(-3, hex2bin(bin2hex(-3)));
- $this->assertEquals(0, hex2bin(bin2hex(0)));
- $this->assertEquals(12, hex2bin(bin2hex(12)));
- $this->assertEquals(PHP_INT_MAX, hex2bin(bin2hex(PHP_INT_MAX)));
- }
-}
use Friendica\App;
use Friendica\Core\Config\Configuration;
use Friendica\LegacyModule;
-use Friendica\Module\PageNotFound;
+use Friendica\Module\HTTPException\PageNotFound;
use Friendica\Module\WellKnown\HostMeta;
use Friendica\Test\DatabaseTest;
{
$module = new App\Module();
- $moduleNew = $module->determineModule(new App\Arguments(), []);
+ $moduleNew = $module->determineModule(new App\Arguments());
$this->assertNotSame($moduleNew, $module);
}
use Friendica\App\Router;
use Friendica\Module;
+use Friendica\Network\HTTPException\MethodNotAllowedException;
+use Friendica\Network\HTTPException\NotFoundException;
use PHPUnit\Framework\TestCase;
class RouterTest extends TestCase
{
public function testGetModuleClass()
{
- $router = new Router(['GET']);
+ $router = new Router(['REQUEST_METHOD' => Router::GET]);
$routeCollector = $router->getRouteCollector();
- $routeCollector->addRoute(['GET'], '/', 'IndexModuleClassName');
- $routeCollector->addRoute(['GET'], '/test', 'TestModuleClassName');
- $routeCollector->addRoute(['GET'], '/test/sub', 'TestSubModuleClassName');
- $routeCollector->addRoute(['GET'], '/optional[/option]', 'OptionalModuleClassName');
- $routeCollector->addRoute(['GET'], '/variable/{var}', 'VariableModuleClassName');
- $routeCollector->addRoute(['GET'], '/optionalvariable[/{option}]', 'OptionalVariableModuleClassName');
- $routeCollector->addRoute(['POST', 'PUT', 'PATCH', 'DELETE', 'HEAD'], '/unsupported', 'UnsupportedMethodModuleClassName');
+ $routeCollector->addRoute([Router::GET], '/', 'IndexModuleClassName');
+ $routeCollector->addRoute([Router::GET], '/test', 'TestModuleClassName');
+ $routeCollector->addRoute([Router::GET, Router::POST], '/testgetpost', 'TestGetPostModuleClassName');
+ $routeCollector->addRoute([Router::GET], '/test/sub', 'TestSubModuleClassName');
+ $routeCollector->addRoute([Router::GET], '/optional[/option]', 'OptionalModuleClassName');
+ $routeCollector->addRoute([Router::GET], '/variable/{var}', 'VariableModuleClassName');
+ $routeCollector->addRoute([Router::GET], '/optionalvariable[/{option}]', 'OptionalVariableModuleClassName');
$this->assertEquals('IndexModuleClassName', $router->getModuleClass('/'));
-
$this->assertEquals('TestModuleClassName', $router->getModuleClass('/test'));
- $this->assertNull($router->getModuleClass('/tes'));
-
+ $this->assertEquals('TestGetPostModuleClassName', $router->getModuleClass('/testgetpost'));
$this->assertEquals('TestSubModuleClassName', $router->getModuleClass('/test/sub'));
-
$this->assertEquals('OptionalModuleClassName', $router->getModuleClass('/optional'));
$this->assertEquals('OptionalModuleClassName', $router->getModuleClass('/optional/option'));
- $this->assertNull($router->getModuleClass('/optional/opt'));
-
$this->assertEquals('VariableModuleClassName', $router->getModuleClass('/variable/123abc'));
- $this->assertNull($router->getModuleClass('/variable'));
+ $this->assertEquals('OptionalVariableModuleClassName', $router->getModuleClass('/optionalvariable'));
+ $this->assertEquals('OptionalVariableModuleClassName', $router->getModuleClass('/optionalvariable/123abc'));
+ }
+ public function testPostModuleClass()
+ {
+ $router = new Router(['REQUEST_METHOD' => Router::POST]);
+
+ $routeCollector = $router->getRouteCollector();
+ $routeCollector->addRoute([Router::POST], '/', 'IndexModuleClassName');
+ $routeCollector->addRoute([Router::POST], '/test', 'TestModuleClassName');
+ $routeCollector->addRoute([Router::GET, Router::POST], '/testgetpost', 'TestGetPostModuleClassName');
+ $routeCollector->addRoute([Router::POST], '/test/sub', 'TestSubModuleClassName');
+ $routeCollector->addRoute([Router::POST], '/optional[/option]', 'OptionalModuleClassName');
+ $routeCollector->addRoute([Router::POST], '/variable/{var}', 'VariableModuleClassName');
+ $routeCollector->addRoute([Router::POST], '/optionalvariable[/{option}]', 'OptionalVariableModuleClassName');
+
+ $this->assertEquals('IndexModuleClassName', $router->getModuleClass('/'));
+ $this->assertEquals('TestModuleClassName', $router->getModuleClass('/test'));
+ $this->assertEquals('TestGetPostModuleClassName', $router->getModuleClass('/testgetpost'));
+ $this->assertEquals('TestSubModuleClassName', $router->getModuleClass('/test/sub'));
+ $this->assertEquals('OptionalModuleClassName', $router->getModuleClass('/optional'));
+ $this->assertEquals('OptionalModuleClassName', $router->getModuleClass('/optional/option'));
+ $this->assertEquals('VariableModuleClassName', $router->getModuleClass('/variable/123abc'));
$this->assertEquals('OptionalVariableModuleClassName', $router->getModuleClass('/optionalvariable'));
$this->assertEquals('OptionalVariableModuleClassName', $router->getModuleClass('/optionalvariable/123abc'));
+ }
+
+ public function testGetModuleClassNotFound()
+ {
+ $this->expectException(NotFoundException::class);
+
+ $router = new Router(['REQUEST_METHOD' => Router::GET]);
+
+ $router->getModuleClass('/unsupported');
+ }
+
+ public function testGetModuleClassNotFoundTypo()
+ {
+ $this->expectException(NotFoundException::class);
+
+ $router = new Router(['REQUEST_METHOD' => Router::GET]);
+
+ $routeCollector = $router->getRouteCollector();
+ $routeCollector->addRoute([Router::GET], '/test', 'TestModuleClassName');
+
+ $router->getModuleClass('/tes');
+ }
+
+ public function testGetModuleClassNotFoundOptional()
+ {
+ $this->expectException(NotFoundException::class);
+
+ $router = new Router(['REQUEST_METHOD' => Router::GET]);
+
+ $routeCollector = $router->getRouteCollector();
+ $routeCollector->addRoute([Router::GET], '/optional[/option]', 'OptionalModuleClassName');
+
+ $router->getModuleClass('/optional/opt');
+ }
+
+ public function testGetModuleClassNotFoundVariable()
+ {
+ $this->expectException(NotFoundException::class);
+
+ $router = new Router(['REQUEST_METHOD' => Router::GET]);
+
+ $routeCollector = $router->getRouteCollector();
+ $routeCollector->addRoute([Router::GET], '/variable/{var}', 'VariableModuleClassName');
+
+ $router->getModuleClass('/variable');
+ }
+
+ public function testGetModuleClassMethodNotAllowed()
+ {
+ $this->expectException(MethodNotAllowedException::class);
+
+ $router = new Router(['REQUEST_METHOD' => Router::POST]);
+
+ $routeCollector = $router->getRouteCollector();
+ $routeCollector->addRoute([Router::GET], '/test', 'TestModuleClassName');
+
+ $router->getModuleClass('/test');
+ }
+
+ public function testPostModuleClassMethodNotAllowed()
+ {
+ $this->expectException(MethodNotAllowedException::class);
+
+ $router = new Router(['REQUEST_METHOD' => Router::GET]);
+
+ $routeCollector = $router->getRouteCollector();
+ $routeCollector->addRoute([Router::POST], '/test', 'TestModuleClassName');
- $this->assertNull($router->getModuleClass('/unsupported'));
+ $router->getModuleClass('/test');
}
public function dataRoutes()
$this->assertEquals(Module\Home::class, $router->getModuleClass('/'));
$this->assertEquals(Module\Friendica::class, $router->getModuleClass('/group/route'));
$this->assertEquals(Module\Xrd::class, $router->getModuleClass('/group2/group3/route'));
- $this->assertNull($router->getModuleClass('/post/it'));
$this->assertEquals(Module\Profile::class, $router->getModuleClass('/double'));
}
]))->addRoutes($routes);
// Don't find GET
- $this->assertNull($router->getModuleClass('/'));
- $this->assertNull($router->getModuleClass('/group/route'));
- $this->assertNull($router->getModuleClass('/group2/group3/route'));
$this->assertEquals(Module\NodeInfo::class, $router->getModuleClass('/post/it'));
$this->assertEquals(Module\Profile::class, $router->getModuleClass('/double'));
}
--- /dev/null
+<?php
+
+namespace Friendica\Test\src\Content;
+
+use Friendica\Test\MockedTest;
+
+class ItemTest extends MockedTest
+{
+ public function testDetermineCategoriesTerms()
+ {
+ $this->markTestIncomplete('Test data needed.');
+ }
+}
--- /dev/null
+<?php
+
+namespace Friendica\Test\Content\Text\BBCode;
+
+use Friendica\Content\Text\BBCode\Video;
+use Friendica\Test\MockedTest;
+
+class VideoTest extends MockedTest
+{
+ public function dataVideo()
+ {
+ return [
+ 'youtube' => [
+ 'input' => '[video]https://youtube.link/4523[/video]',
+ 'assert' => '[youtube]https://youtube.link/4523[/youtube]',
+ ],
+ 'youtu.be' => [
+ 'input' => '[video]https://youtu.be.link/4523[/video]',
+ 'assert' => '[youtube]https://youtu.be.link/4523[/youtube]',
+ ],
+ 'vimeo' => [
+ 'input' => '[video]https://vimeo.link/2343[/video]',
+ 'assert' => '[vimeo]https://vimeo.link/2343[/vimeo]',
+ ],
+ 'mixed' => [
+ 'input' => '[video]https://vimeo.link/2343[/video] With other [b]string[/b] [video]https://youtu.be/blaa[/video]',
+ 'assert' => '[vimeo]https://vimeo.link/2343[/vimeo] With other [b]string[/b] [youtube]https://youtu.be/blaa[/youtube]',
+ ]
+ ];
+ }
+
+ /**
+ * Test if the BBCode is successfully transformed for video links
+ *
+ * @dataProvider dataVideo
+ */
+ public function testTransform(string $input, string $assert)
+ {
+ $bbCodeVideo = new Video();
+
+ $this->assertEquals($assert, $bbCodeVideo->transform($input));
+ }
+}
// Mocking that we can use CURL
$this->setFunctions(['curl_init' => true]);
- // needed because of "normalise_link"
- require_once __DIR__ . '/../../../include/text.php';
-
$install = new Installer();
$this->assertTrue($install->checkHtAccess('https://test'));
--- /dev/null
+<?php
+
+namespace src\Core\L10n;
+
+use Friendica\Core\L10n\L10n;
+use Friendica\Test\MockedTest;
+
+class L10nTest extends MockedTest
+{
+ public function dataDetectLanguage()
+ {
+ return [
+ 'empty' => [
+ 'server' => [],
+ 'get' => [],
+ 'default' => 'en',
+ 'assert' => 'en',
+ ],
+ 'withGet' => [
+ 'server' => [],
+ 'get' => ['lang' => 'de'],
+ 'default' => 'en',
+ 'assert' => 'de',
+ ],
+ 'withPipe' => [
+ 'server' => ['HTTP_ACCEPT_LANGUAGE' => 'en-gb'],
+ 'get' => [],
+ 'default' => 'en',
+ 'assert' => 'en-gb',
+ ],
+ 'withoutPipe' => [
+ 'server' => ['HTTP_ACCEPT_LANGUAGE' => 'fr'],
+ 'get' => [],
+ 'default' => 'en',
+ 'assert' => 'fr',
+ ],
+ 'withQuality1' => [
+ 'server' => ['HTTP_ACCEPT_LANGUAGE' => 'fr;q=0.5,de'],
+ 'get' => [],
+ 'default' => 'en',
+ 'assert' => 'de',
+ ],
+ 'withQuality2' => [
+ 'server' => ['HTTP_ACCEPT_LANGUAGE' => 'fr;q=0.5,de;q=0.2'],
+ 'get' => [],
+ 'default' => 'en',
+ 'assert' => 'fr',
+ ],
+ 'withLangOverride' => [
+ 'server' => ['HTTP_ACCEPT_LANGUAGE' => 'fr;q=0.5,de;q=0.2'],
+ 'get' => ['lang' => 'it'],
+ 'default' => 'en',
+ 'assert' => 'it',
+ ],
+ 'withQualityAndPipe' => [
+ 'server' => ['HTTP_ACCEPT_LANGUAGE' => 'fr;q=0.5,de;q=0.2,nb-no;q=0.7'],
+ 'get' => [],
+ 'default' => 'en',
+ 'assert' => 'nb-no',
+ ],
+ 'withQualityAndInvalid' => [
+ 'server' => ['HTTP_ACCEPT_LANGUAGE' => 'fr;q=0.5,bla;q=0.2,nb-no;q=0.7'],
+ 'get' => [],
+ 'default' => 'en',
+ 'assert' => 'nb-no',
+ ],
+ 'withQualityAndInvalid2' => [
+ 'server' => ['HTTP_ACCEPT_LANGUAGE' => 'blu;q=0.9,bla;q=0.2,nb-no;q=0.7'],
+ 'get' => [],
+ 'default' => 'en',
+ 'assert' => 'nb-no',
+ ],
+ 'withQualityAndInvalidAndAbsolute' => [
+ 'server' => ['HTTP_ACCEPT_LANGUAGE' => 'blu;q=0.9,de,nb-no;q=0.7'],
+ 'get' => [],
+ 'default' => 'en',
+ 'assert' => 'de',
+ ],
+ 'withInvalidGet' => [
+ 'server' => ['HTTP_ACCEPT_LANGUAGE' => 'blu;q=0.9,nb-no;q=0.7'],
+ 'get' => ['lang' => 'blu'],
+ 'default' => 'en',
+ 'assert' => 'nb-no',
+ ],
+ ];
+ }
+
+ /**
+ * @dataProvider dataDetectLanguage
+ */
+ public function testDetectLanguage(array $server, array $get, string $default, string $assert)
+ {
+ $this->assertEquals($assert, L10n::detectLanguage($server, $get, $default));
+ }
+}
--- /dev/null
+<?php
+
+namespace Friendica\Test\Protocol;
+
+use Friendica\Protocol\Activity;
+use Friendica\Protocol\ActivityNamespace;
+use Friendica\Test\MockedTest;
+
+class ActivityTest extends MockedTest
+{
+ public function dataMatch()
+ {
+ return [
+ 'empty' => [
+ 'haystack' => '',
+ 'needle' => '',
+ 'assert' => true,
+ ],
+ 'simple' => [
+ 'haystack' => Activity\ObjectType::TAGTERM,
+ 'needle' => Activity\ObjectType::TAGTERM,
+ 'assert' => true,
+ ],
+ 'withNamespace' => [
+ 'haystack' => 'tagterm',
+ 'needle' => ActivityNamespace::ACTIVITY_SCHEMA . Activity\ObjectType::TAGTERM,
+ 'assert' => true,
+ ],
+ 'invalidSimple' => [
+ 'haystack' => 'tagterm',
+ 'needle' => '',
+ 'assert' => false,
+ ],
+ 'invalidWithOutNamespace' => [
+ 'haystack' => 'tagterm',
+ 'needle' => Activity\ObjectType::TAGTERM,
+ 'assert' => false,
+ ],
+ 'withSubPath' => [
+ 'haystack' => 'tagterm',
+ 'needle' => ActivityNamespace::ACTIVITY_SCHEMA . '/bla/' . Activity\ObjectType::TAGTERM,
+ 'assert' => true,
+ ],
+ ];
+ }
+
+ /**
+ * Test the different, possible matchings
+ *
+ * @dataProvider dataMatch
+ */
+ public function testMatch(string $haystack, string $needle, bool $assert)
+ {
+ $activity = new Activity();
+
+ $this->assertEquals($assert, $activity->match($haystack, $needle));
+ }
+
+ public function testIsHidden()
+ {
+ $activity = new Activity();
+
+ $this->assertTrue($activity->isHidden(Activity::LIKE));
+ $this->assertFalse($activity->isHidden(Activity\ObjectType::BOOKMARK));
+ }
+}
--- /dev/null
+<?php
+
+namespace Friendica\Test\src\Util;
+
+use Error;
+use Friendica\Model\Group;
+use Friendica\Util\ACLFormatter;
+use PHPUnit\Framework\TestCase;
+
+/**
+ * @brief ACLFormater utility testing class
+ */
+class ACLFormaterTest extends TestCase
+{
+ public function assertAcl($text, array $assert = [])
+ {
+ $aclFormatter = new ACLFormatter();
+
+ $acl = $aclFormatter->expand($text);
+
+ $this->assertEquals($assert, $acl);
+
+ $this->assertMergable($acl);
+ }
+
+ public function assertMergable(array $aclOne, array $aclTwo = [])
+ {
+ $this->assertTrue(is_array($aclOne));
+ $this->assertTrue(is_array($aclTwo));
+
+ $aclMerged = array_unique(array_merge($aclOne, $aclTwo));
+ $this->assertTrue(is_array($aclMerged));
+
+ return $aclMerged;
+ }
+
+ public function dataExpand()
+ {
+ return [
+ 'normal' => [
+ 'input' => '<1><2><3><' . Group::FOLLOWERS . '><' . Group::MUTUALS . '>',
+ 'assert' => ['1', '2', '3', Group::FOLLOWERS, Group::MUTUALS],
+ ],
+ 'nigNumber' => [
+ 'input' => '<1><' . PHP_INT_MAX . '><15>',
+ 'assert' => ['1', (string)PHP_INT_MAX, '15'],
+ ],
+ 'string' => [
+ 'input' => '<1><279012><tt>',
+ 'assert' => ['1', '279012'],
+ ],
+ 'space' => [
+ 'input' => '<1><279 012><32>',
+ 'assert' => ['1', '32'],
+ ],
+ 'empty' => [
+ 'input' => '',
+ 'assert' => [],
+ ],
+ /// @todo should there be an exception?
+ 'noBrackets' => [
+ 'input' => 'According to documentation, that\'s invalid. ', //should be invalid
+ 'assert' => [],
+ ],
+ /// @todo should there be an exception?
+ 'justOneBracket' => [
+ 'input' => '<Another invalid string', //should be invalid
+ 'assert' => [],
+ ],
+ /// @todo should there be an exception?
+ 'justOneBracket2' => [
+ 'input' => 'Another invalid> string', //should be invalid
+ 'assert' => [],
+ ],
+ /// @todo should there be an exception?
+ 'closeOnly' => [
+ 'input' => 'Another> invalid> string>', //should be invalid
+ 'assert' => [],
+ ],
+ /// @todo should there be an exception?
+ 'openOnly' => [
+ 'input' => '<Another< invalid string<', //should be invalid
+ 'assert' => [],
+ ],
+ /// @todo should there be an exception?
+ 'noMatching1' => [
+ 'input' => '<Another<> invalid <string>', //should be invalid
+ 'assert' => [],
+ ],
+ 'emptyMatch' => [
+ 'input' => '<1><><3>',
+ 'assert' => ['1', '3'],
+ ],
+ ];
+ }
+
+ /**
+ * @dataProvider dataExpand
+ */
+ public function testExpand($input, array $assert)
+ {
+ $this->assertAcl($input, $assert);
+ }
+
+ /**
+ * Test nullable expand (=> no ACL set)
+ */
+ public function testExpandNull()
+ {
+ $aclFormatter = new ACLFormatter();
+
+ $allow_people = $aclFormatter->expand();
+ $allow_groups = $aclFormatter->expand();
+
+ $this->assertEmpty($aclFormatter->expand(null));
+ $this->assertEmpty($aclFormatter->expand());
+
+ $recipients = array_unique(array_merge($allow_people, $allow_groups));
+ $this->assertEmpty($recipients);
+ }
+
+ public function dataAclToString()
+ {
+ return [
+ 'empty' => [
+ 'input' => '',
+ 'assert' => '',
+ ],
+ 'string' => [
+ 'input' => '1,2,3,4',
+ 'assert' => '<1><2><3><4>',
+ ],
+ 'array' => [
+ 'input' => [1, 2, 3, 4],
+ 'assert' => '<1><2><3><4>',
+ ],
+ 'invalid' => [
+ 'input' => [1, 'a', 3, 4],
+ 'assert' => '<1><3><4>',
+ ],
+ 'invalidString' => [
+ 'input' => 'a,bsd23,4',
+ 'assert' => '<4>',
+ ],
+ /** @see https://github.com/friendica/friendica/pull/7787 */
+ 'bug-7778-angle-brackets' => [
+ 'input' => ["<40195>"],
+ 'assert' => "<40195>",
+ ],
+ Group::FOLLOWERS => [
+ 'input' => [Group::FOLLOWERS, 1],
+ 'assert' => '<' . Group::FOLLOWERS . '><1>',
+ ],
+ Group::MUTUALS => [
+ 'input' => [Group::MUTUALS, 1],
+ 'assert' => '<' . Group::MUTUALS . '><1>',
+ ],
+ 'wrong-angle-brackets' => [
+ 'input' => ["<asd>","<123>"],
+ 'assert' => "<123>",
+ ],
+ ];
+ }
+
+ /**
+ * @dataProvider dataAclToString
+ */
+ public function testAclToString($input, string $assert)
+ {
+ $aclFormatter = new ACLFormatter();
+
+ $this->assertEquals($assert, $aclFormatter->toString($input));
+ }
+}
--- /dev/null
+<?php
+
+namespace Friendica\Test\src\Util;
+
+use Friendica\Test\MockedTest;
+use Friendica\Util\DateTimeFormat;
+
+class DateTimeFormatTest extends MockedTest
+{
+ public function dataYearMonth()
+ {
+ return [
+ 'validNormal' => [
+ 'input' => '1990-10',
+ 'assert' => true,
+ ],
+ 'validOneCharMonth' => [
+ 'input' => '1990-1',
+ 'assert' => true,
+ ],
+ 'validTwoCharMonth' => [
+ 'input' => '1990-01',
+ 'assert' => true,
+ ],
+ 'invalidFormat' => [
+ 'input' => '199-11',
+ 'assert' => false,
+ ],
+ 'invalidFormat2' => [
+ 'input' => '1990-15',
+ 'assert' => false,
+ ],
+ 'invalidFormat3' => [
+ 'input' => '99-101',
+ 'assert' => false,
+ ],
+ 'invalidFormat4' => [
+ 'input' => '11-1990',
+ 'assert' => false,
+ ],
+ 'invalidFuture' => [
+ 'input' => '3030-12',
+ 'assert' => false,
+ ],
+ 'invalidYear' => [
+ 'input' => '-100-10',
+ 'assert' => false,
+ ],
+ ];
+ }
+
+ /**
+ * @dataProvider dataYearMonth
+ */
+ public function testIsYearMonth(string $input, bool $assert)
+ {
+ $dtFormat = new DateTimeFormat();
+
+ $this->assertEquals($assert, $dtFormat->isYearMonth($input));
+ }
+}
namespace Friendica\Test\src\Util\Logger;
+use Friendica\Util\FileSystem;
use Friendica\Test\Util\VFSTrait;
use Friendica\Util\Logger\StreamLogger;
use org\bovigo\vfs\vfsStream;
*/
private $logfile;
+ /**
+ * @var Filesystem
+ */
+ private $fileSystem;
+
protected function setUp()
{
parent::setUp();
$this->setUpVfsDir();
+
+ $this->fileSystem = new Filesystem();
}
/**
$this->logfile = vfsStream::newFile('friendica.log')
->at($this->root);
- $this->logger = new StreamLogger('test', $this->logfile->url(), $this->introspection, $level);
+ $this->logger = new StreamLogger('test', $this->logfile->url(), $this->introspection, $this->fileSystem, $level);
return $this->logger;
}
$filehandler = fopen($logfile->url(), 'ab');
- $logger = new StreamLogger('test', $filehandler, $this->introspection);
+ $logger = new StreamLogger('test', $filehandler, $this->introspection, $this->fileSystem);
$logger->emergency('working');
$text = $logfile->getContent();
$logfile = vfsStream::newFile('friendica.log')
->at($this->root);
- $logger = new StreamLogger('test', $logfile->url(), $this->introspection);
+ $logger = new StreamLogger('test', $logfile->url(), $this->introspection, $this->fileSystem);
$logger->emergency('working');
$logger->close();
// close doesn't affect
*/
public function testNoUrl()
{
- $logger = new StreamLogger('test', '', $this->introspection);
+ $logger = new StreamLogger('test', '', $this->introspection, $this->fileSystem);
$logger->emergency('not working');
}
$logfile = vfsStream::newFile('friendica.log')
->at($this->root)->chmod(0);
- $logger = new StreamLogger('test', $logfile->url(), $this->introspection);
+ $logger = new StreamLogger('test', $logfile->url(), $this->introspection, $this->fileSystem);
$logger->emergency('not working');
}
{
$this->markTestIncomplete('We need a platform independent way to set directory to readonly');
- $logger = new StreamLogger('test', '/$%/wrong/directory/file.txt', $this->introspection);
+ $logger = new StreamLogger('test', '/$%/wrong/directory/file.txt', $this->introspection, $this->fileSystem);
$logger->emergency('not working');
}
*/
public function testWrongMinimumLevel()
{
- $logger = new StreamLogger('test', 'file.text', $this->introspection, 'NOPE');
+ $logger = new StreamLogger('test', 'file.text', $this->introspection, $this->fileSystem, 'NOPE');
}
/**
$logfile = vfsStream::newFile('friendica.log')
->at($this->root);
- $logger = new StreamLogger('test', $logfile->url(), $this->introspection);
+ $logger = new StreamLogger('test', $logfile->url(), $this->introspection, $this->fileSystem);
$logger->log('NOPE', 'a test');
}
*/
public function testWrongFile()
{
- $logger = new StreamLogger('test', null, $this->introspection);
+ $logger = new StreamLogger('test', null, $this->introspection, $this->fileSystem);
+ }
+
+ /**
+ * Test a relative path
+ */
+ public function testRealPath()
+ {
+ $this->markTestSkipped('vfsStream isn\'t compatible with chdir, so not testable.');
+
+ $logfile = vfsStream::newFile('friendica.log')
+ ->at($this->root);
+
+ chdir($this->root->getChild('logs')->url());
+
+ $logger = new StreamLogger('test', '../friendica.log' , $this->introspection, $this->fileSystem);
+
+ $logger->info('Test');
}
}
*/
class StringsTest extends TestCase
{
- /**
+ /**
* randomnames should be random, even length
*/
public function testRandomEven()
$randomname2 = Strings::getRandomName(1);
$this->assertEquals(1, strlen($randomname2));
- }
-
- /**
+ }
+
+ /**
* test, that tags are escaped
*/
public function testEscapeHtml()
<div class="clear"></div>\
<hr class="previewseparator">';
var text;
- var urlRegex = /^(?:https?\:\/\/|\s)[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,4})(?:\/+[a-z0-9_.\:\;-]*)*(?:\?[\&\%\|\+a-z0-9_=,\.\:\;-]*)?(?:[\&\%\|\+&a-z0-9_=,\:\;\.-]*)(?:[\!\#\/\&\%\|\+a-z0-9_=,\:\;\.-]*)}*$/i;
var binurl;
var block = false;
var blockTitle = false;
var last_popup_button = null;
var lockLoadContent = false;
+const urlRegex = /^(?:https?:\/\/|\s)[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,4})(?:\/+[a-z0-9_.:;-]*)*(?:\?[&%|+a-z0-9_=,.:;-]*)?(?:[&%|+&a-z0-9_=,:;.-]*)(?:[!#\/&%|+a-z0-9_=,:;.-]*)}*$/i;
+
$(function() {
$.ajaxSetup({cache: false});
}
});
+/**
+ * Inserts a BBCode tag in the comment textarea identified by id
+ *
+ * @param {string} BBCode
+ * @param {int} id
+ * @returns {boolean}
+ */
+function insertFormatting(BBCode, id) {
+ let textarea = document.getElementById('comment-edit-text-' + id);
+
+ if (textarea.value === '') {
+ $(textarea)
+ .addClass("comment-edit-text-full")
+ .removeClass("comment-edit-text-empty");
+ closeMenu("comment-fake-form-" + id);
+ openMenu("item-comments-" + id);
+ }
+
+ insertBBCodeInTextarea(BBCode, textarea);
+
+ return true;
+}
+
+/**
+ * Inserts a BBCode tag in the provided textarea element, wrapping the currently selected text.
+ * For URL BBCode, it discriminates between link text and non-link text to determine where to insert the selected text.
+ *
+ * @param {string} BBCode
+ * @param {HTMLTextAreaElement} textarea
+ */
+function insertBBCodeInTextarea(BBCode, textarea) {
+ let selectionStart = textarea.selectionStart;
+ let selectionEnd = textarea.selectionEnd;
+ let selectedText = textarea.value.substring(selectionStart, selectionEnd);
+ let openingTag = '[' + BBCode + ']';
+ let closingTag = '[/' + BBCode + ']';
+ let cursorPosition = selectionStart + openingTag.length + selectedText.length;
+
+ if (BBCode === 'url') {
+ if (urlRegex.test(selectedText)) {
+ openingTag = '[' + BBCode + '=' + selectedText + ']';
+ selectedText = '';
+ cursorPosition = selectionStart + openingTag.length;
+ } else {
+ openingTag = '[' + BBCode + '=]';
+ cursorPosition = selectionStart + openingTag.length - 1;
+ }
+ }
+
+ textarea.value = textarea.value.substring(0, selectionStart) + openingTag + selectedText + closingTag + textarea.value.substring(selectionEnd, textarea.value.length);
+ textarea.setSelectionRange(cursorPosition, cursorPosition);
+ textarea.dispatchEvent(new Event('change'));
+ textarea.focus();
+}
+
function NavUpdate() {
if (!stopped) {
var pingCmd = 'ping?format=json' + ((localUser != 0) ? '&f=&uid=' + localUser : '');
function doignore(ident) {
ident = ident.toString();
$('#like-rotator-' + ident).show();
- $.get('ignored/' + ident, function(data) {
+ $.get('item/ignore/' + ident, function(data) {
if (data.match(/1/)) {
$('#ignored-' + ident).addClass('ignored');
$('#ignored-' + ident).removeClass('unignored');
--- /dev/null
+
+<h3>{{$title}}</h3>
+<div id="identity-delegation-desc">{{$desc nofilter}}</div>
+<div id="identity-delegation-choose">{{$choose}}</div>
+
+<div id="identity-selector-wrapper" role="menu">
+ <form action="delegation" method="post">
+
+ {{foreach $identities as $identity}}
+ <div class="itentity-match-wrapper {{if $identity.selected}}selected-identity{{/if}}" id="identity-match-{{$identity.uid}}">
+ <div class="identity-match-photo" id="identity-match-photo-{{$identity.uid}}">
+ <button type="submit" name="identity" value="{{$identity.uid}}" title="{{$identity.username}}">
+ <img src="{{$identity.thumb}}" alt="{{$identity.username}}" />
+ {{if $identity.notifications}}<span class="delegation-notify badge">{{$identity.notifications}}</span>{{/if}}
+ </button>
+ </div>
+
+ <div class="identity-match-break"></div>
+
+ <div class="identity-match-desc">
+ <div class="identity-match-name" id="identity-match-name-{{$identity.uid}}">
+ {{if $identity.selected}}
+ {{$identity.username}}
+ {{else}}
+ <button type="submit" name="identity" class="btn-link" value="{{$identity.uid}}">{{$identity.username}}</button>
+ {{/if}}
+ </div>
+ <div class="identity-match-details" id="identity-match-nick-{{$identity.uid}}">({{$identity.nickname}})</div>
+ </div>
+ <div class="identity-match-end"></div>
+ </div>
+ {{/foreach}}
+
+ <div class="identity-match-break"></div>
+
+ </form>
+</div>
<div class='field input openid' id='wrapper_{{$field.0}}'>
<label for='id_{{$field.0}}'>{{$field.1}}</label>
- <input name='{{$field.0}}' id='id_{{$field.0}}' type="text" value="{{$field.2 nofilter}}" aria-describedby='{{$field.0}}_tip'>
+ <input name='{{$field.0}}' id='id_{{$field.0}}' type="text" value="{{$field.2 nofilter}}" {{if $field.4}} readonly="readonly" {{/if}} aria-describedby='{{$field.0}}_tip'>
{{if $field.3}}
<span class="field_help" role="tooltip" id="{{$field.0}}_tip">{{$field.3 nofilter}}</span>
{{/if}}
{{if $register}}
<div id="login-extra-links">
<h3 id="login-head" class="sr-only">{{$register.title}}</h3>
- <a href="register" title="{{$register.title}}" id="register-link">{{$register.desc}}</a>
+ <a href="{{$register.url}}" title="{{$register.title}}" id="register-link">{{$register.desc}}</a>
</div>
{{/if}}
+++ /dev/null
-
-<h3>{{$title}}</h3>
-<div id="identity-manage-desc">{{$desc nofilter}}</div>
-<div id="identity-manage-choose">{{$choose}}</div>
-
-<div id="identity-selector-wrapper" role="menu">
- <form action="manage" method="post" >
-
- {{foreach $identities as $id}}
- <div class="itentity-match-wrapper {{if $id.selected}}selected-identity{{/if}}" id="identity-match-{{$id.uid}}">
- <div class="identity-match-photo" id="identity-match-photo-{{$id.uid}}">
- <button name="identity" value="{{$id.uid}}" onclick="this.form.submit();" title="{{$id.username}}">
- <img src="{{$id.thumb}}" alt="{{$id.username}}" />
- {{if $id.notifications}}<span class="manage-notify badge">{{$id.notifications}}</span>{{/if}}
- </button>
- </div>
-
- <div class="identity-match-break"></div>
-
- <div class="identity-match-desc">
- <div class="identity-match-name" id="identity-match-name-{{$id.uid}}">
- {{if $id.selected}}{{$id.username}}{{else}}<a role="menuitem" href="manage?identity={{$id.uid}}">{{$id.username}}</a>{{/if}}
- </div>
- <div class="identity-match-details" id="identity-match-nick-{{$id.uid}}">({{$id.nickname}})</div>
- </div>
- <div class="identity-match-end"></div>
- </div>
- {{/foreach}}
-
- <div class="identity-match-break"></div>
-
- </form>
-</div>
- {{if $nav.manage}}<a id="nav-manage-link" class="nav-commlink {{$nav.manage.2}} {{$sel.manage}}" href="{{$nav.manage.0}}" title="{{$nav.manage.3}}">{{$nav.manage.1}}</a>{{/if}}
+ {{if $nav.delegation}}<a id="nav-delegation-link" class="nav-commlink {{$nav.delegation.2}} {{$sel.delegation}}" href="{{$nav.delegation.0}}" title="{{$nav.delegation.3}}">{{$nav.delegation.1}}</a>{{/if}}
{{if $nav.notifications}}
{{/if}}
<input type="submit" name="submit" id="search-submit" value="{{$search_label}}"/>
{{if $s}}
- <a href="search/saved/add/{{$q}}?return_url={{$return_url}}">{{$save_label}}</a>
+ <a href="search/saved/add?term={{$q}}&return_url={{$return_url}}">{{$save_label}}</a>
{{/if}}
{{/strip}}
</form>
<ul role="menu" id="saved-search-ul">
{{foreach $saved as $search}}
<li role="menuitem" class="saved-search-li clear">
- <a href="search/saved/remove/{{$search.encodedterm}}?return_url={{$return_url}}" title="{{$search.delete}}" onclick="return confirmDelete();" id="drop-saved-search-term-{{$search.id}}" class="iconspacer savedsearchdrop"></a>
+ <a href="search/saved/remove?term={{$search.encodedterm}}&return_url={{$return_url}}" title="{{$search.delete}}" onclick="return confirmDelete();" id="drop-saved-search-term-{{$search.id}}" class="iconspacer savedsearchdrop"></a>
<a href="search?q={{$search.encodedterm}}" id="saved-search-term-{{$search.id}}" class="savedsearchterm">{{$search.term}}</a>
</li>
{{/foreach}}
margin: 10px;
}
-#identity-manage-desc {
+#identity-delegation-desc {
margin-top:15px;
margin-bottom: 15px;
}
-#identity-manage-choose {
+#identity-delegation-choose {
margin-bottom: 15px;
}
}
/* notifications popup menu */
-.manage-notify {
+.delegation-notify {
font-size: 10px;
padding: 1px 3px;
top: 0px;
echo file_get_contents("$THEMEPATH/style.css");
}
-$uid = defaults($_REQUEST, 'puid', 0);
+$uid = $_REQUEST['puid'] ?? 0;
$s_colorset = Config::get('duepuntozero', 'colorset');
$colorset = PConfig::get($uid, 'duepuntozero', 'colorset');
{{if $nav.contacts}}<a id="nav-contacts-link" class="nav-link {{$nav.contacts.2}}" href="{{$nav.contacts.0}}" title="{{$nav.contacts.3}}" >{{$nav.contacts.1}}</a>{{/if}}
- {{if $nav.manage}}<a id="nav-manage-link" class="nav-link {{$nav.manage.2}} {{$sel.manage}}" href="{{$nav.manage.0}}" title="{{$nav.manage.3}}">{{$nav.manage.1}}</a>{{/if}}
+ {{if $nav.delegation}}<a id="nav-delegation-link" class="nav-link {{$nav.delegation.2}} {{$sel.delegation}}" href="{{$nav.delegation.0}}" title="{{$nav.delegation.3}}">{{$nav.delegation.1}}</a>{{/if}}
</span>
<span id="nav-end"></span>
<span id="banner">{{$banner nofilter}}</span>
}
$a->page['htmlhead'] .= <<< EOT
<script>
-function insertFormatting(BBcode, id) {
- var tmpStr = $("#comment-edit-text-" + id).val();
- if (tmpStr == "") {
- $("#comment-edit-text-" + id).addClass("comment-edit-text-full");
- $("#comment-edit-text-" + id).removeClass("comment-edit-text-empty");
- openMenu("comment-edit-submit-wrapper-" + id);
- }
-
- textarea = document.getElementById("comment-edit-text-" +id);
- if (document.selection) {
- textarea.focus();
- selected = document.selection.createRange();
- selected.text = "["+BBcode+"]" + selected.text + "[/"+BBcode+"]";
- } else if (textarea.selectionStart || textarea.selectionStart == "0") {
- var start = textarea.selectionStart;
- var end = textarea.selectionEnd;
- textarea.value = textarea.value.substring(0, start) + "["+BBcode+"]" + textarea.value.substring(start, end) + "[/"+BBcode+"]" + textarea.value.substring(end, textarea.value.length);
- }
-
- return true;
-}
-
function cmtBbOpen(comment, id) {
if ($(comment).hasClass('comment-edit-text-full')) {
$(".comment-edit-bb-" + id).show();
'$nav_icon_color' => array_key_exists('nav_icon_color', $disable) ? '' : ['frio_nav_icon_color', L10n::t('Navigation bar icon color '), $arr['nav_icon_color'], '', false],
'$link_color' => array_key_exists('link_color', $disable) ? '' : ['frio_link_color', L10n::t('Link color'), $arr['link_color'], '', false],
'$background_color' => array_key_exists('background_color', $disable) ? '' : ['frio_background_color', L10n::t('Set the background color'), $arr['background_color'], '', false],
- '$contentbg_transp' => array_key_exists('contentbg_transp', $disable) ? '' : ['frio_contentbg_transp', L10n::t('Content background opacity'), defaults($arr, 'contentbg_transp', 100), ''],
+ '$contentbg_transp' => array_key_exists('contentbg_transp', $disable) ? '' : ['frio_contentbg_transp', L10n::t('Content background opacity'), ($arr['contentbg_transp'] ?? 0) ?: 100, ''],
'$background_image' => array_key_exists('background_image', $disable) ? '' : ['frio_background_image', L10n::t('Set the background image'), $arr['background_image'], $background_image_help, false],
'$bg_image_options_title' => L10n::t('Background image style'),
'$bg_image_options' => Image::get_options($arr),
.search-content-wrapper > .section-title-wrapper {
display: none;
}
-#navbar-button > #search-save-form > #search-save {
+#navbar-button > #search-save {
margin-top: 3px;
}
/* Section-Content-Wrapper */
.generic-page-wrapper, .profile_photo-content-wrapper, .videos-content-wrapper,
.suggest-content-wrapper, .common-content-wrapper, .help-content-wrapper,
.allfriends-content-wrapper, .match-content-wrapper, .dirfind-content-wrapper,
-.manage-content-wrapper, .notes-content-wrapper,
+.delegation-content-wrapper, .notes-content-wrapper,
.message-content-wrapper, .apps-content-wrapper,
#adminpage, .delegate-content-wrapper, .uexport-content-wrapper,
.dfrn_request-content-wrapper,
right: 10px;
}
- .generic-page-wrapper, .profile_photo-content-wrapper, .videos-content-wrapper, .suggest-content-wrapper, .common-content-wrapper, .help-content-wrapper, .allfriends-content-wrapper, .match-content-wrapper, .dirfind-content-wrapper, .directory-content-wrapper, .manage-content-wrapper, .notes-content-wrapper, .message-content-wrapper, .apps-content-wrapper, #adminpage, .delegate-content-wrapper, .uexport-content-wrapper, .dfrn_request-content-wrapper, .friendica-content-wrapper, .credits-content-wrapper, .nogroup-content-wrapper, .profperm-content-wrapper, .invite-content-wrapper, .tos-content-wrapper, .fsuggest-content-wrapper {
+ .generic-page-wrapper, .profile_photo-content-wrapper, .videos-content-wrapper, .suggest-content-wrapper, .common-content-wrapper, .help-content-wrapper, .allfriends-content-wrapper, .match-content-wrapper, .dirfind-content-wrapper, .directory-content-wrapper, .delegation-content-wrapper, .notes-content-wrapper, .message-content-wrapper, .apps-content-wrapper, #adminpage, .delegate-content-wrapper, .uexport-content-wrapper, .dfrn_request-content-wrapper, .friendica-content-wrapper, .credits-content-wrapper, .nogroup-content-wrapper, .profperm-content-wrapper, .invite-content-wrapper, .tos-content-wrapper, .fsuggest-content-wrapper {
border-radius: 0;
padding: 10px;
}
}
}
-
-function insertFormatting(BBcode, id) {
- var tmpStr = $("#comment-edit-text-" + id).val();
- if (tmpStr == '') {
- $("#comment-edit-text-" + id).addClass("comment-edit-text-full");
- $("#comment-edit-text-" + id).removeClass("comment-edit-text-empty");
- closeMenu("comment-fake-form-" + id);
- openMenu("item-comments-" + id);
- }
-
- textarea = document.getElementById("comment-edit-text-" + id);
- if (document.selection) {
- textarea.focus();
- selected = document.selection.createRange();
- selected.text = "[" + BBcode + "]" + selected.text + "[/" + BBcode + "]";
- } else if (textarea.selectionStart || textarea.selectionStart == "0") {
- var start = textarea.selectionStart;
- var end = textarea.selectionEnd;
- textarea.value = textarea.value.substring(0, start) + "[" + BBcode + "]" + textarea.value.substring(start, end) + "[/" + BBcode + "]" + textarea.value.substring(end, textarea.value.length);
- }
-
- $(textarea).trigger('change');
-
- return true;
-}
-
-function insertFormattingToPost(BBcode) {
+function insertFormattingToPost(BBCode) {
textarea = document.getElementById("profile-jot-text");
- if (document.selection) {
- textarea.focus();
- selected = document.selection.createRange();
- selected.text = "[" + BBcode + "]" + selected.text + "[/" + BBcode + "]";
- } else if (textarea.selectionStart || textarea.selectionStart == "0") {
- var start = textarea.selectionStart;
- var end = textarea.selectionEnd;
- textarea.value = textarea.value.substring(0, start) + "[" + BBcode + "]" + textarea.value.substring(start, end) + "[/" + BBcode + "]" + textarea.value.substring(end, textarea.value.length);
- }
- $(textarea).trigger('change');
+ insertBBCodeInTextarea(BBCode, textarea);
return true;
}
}
// move the "Save the search" button to the second navbar
- $(".search-content-wrapper #search-save-form ").appendTo("#topbar-second > .container > #navbar-button");
+ $(".search-content-wrapper #search-save").appendTo("#topbar-second > .container > #navbar-button");
// append the vcard-short-info to the second nav after passing the element
// with .fn (vcard username). Use scrollspy to get the scroll position.
<html>
<head>
<title><?php if (!empty($page['title'])) echo $page['title'] ?></title>
- <meta request="<?php echo htmlspecialchars(defaults($_REQUEST, 'pagename', '')) ?>">
+ <meta request="<?php echo htmlspecialchars($_REQUEST['pagename'] ?? '') ?>">
<script type="text/javascript">var baseurl = "<?php echo System::baseUrl(); ?>";</script>
<script type="text/javascript">var frio = "<?php echo 'view/theme/frio'; ?>";</script>
<?php
</main>
<footer>
- <?php echo defaults($page, 'footer', ''); ?>
+ <?php echo $page['footer'] ?? ''; ?>
</footer>
<?php } ?> <!-- End of condition if $minimal else the rest -->
</body>
require 'view/theme/frio/none.php';
} else {
$template = 'view/theme/' . $a->getCurrentTheme() . '/'
- . defaults($a->page, 'template', 'default' ) . '.php';
+ . (($a->page['template'] ?? '') ?: 'default' ) . '.php';
if (file_exists($template)) {
require_once $template;
} else {
<div id="page-footer"></div>\r
</section>\r
<!-- Modal -->\r
- <div id="modal" class="modal fade" tabindex="-1" role="dialog" aria-hidden="true">\r
+ <div id="modal" class="modal fade" tabindex="-1" role="dialog">\r
<div class="modal-dialog modal-full-screen">\r
<div class="modal-content">\r
<div id="modal-header" class="modal-header">\r
- <button id="modal-cloase" type="button" class="close" data-dismiss="modal" aria-hidden="true">\r
+ <button id="modal-cloase" type="button" class="close" data-dismiss="modal">\r
×\r
</button>\r
<h4 id="modal-title" class="modal-title"></h4>\r
<script src="<?=$frio?>/frameworks/justifiedGallery/jquery.justifiedGallery.min.js"></script>
<!-- Modal -->
-<div id="modal" class="modal fade" tabindex="-1" role="dialog" aria-hidden="true">
+<div id="modal" class="modal fade" tabindex="-1" role="dialog">
<div class="modal-dialog modal-full-screen">
<div class="modal-content">
<div id="modal-header" class="modal-header">
- <button id="modal-cloase" type="button" class="close" data-dismiss="modal" aria-hidden="true">
+ <button id="modal-cloase" type="button" class="close" data-dismiss="modal">
×
</button>
<h4 id="modal-title" class="modal-title"></h4>
<div class="field checkbox" id="div_id_{{$field.0}}">
<input type="hidden" name="{{$field.0}}" value="0">
- <input type="checkbox" name="{{$field.0}}" id="id_{{$field.0}}" value="1" {{if $field.2}}checked="checked"{{/if}} aria-checked="{{if $field.2}}true{{else}}false{{/if}}" aria-describedby="{{$field.0}}_tip" {{if $field.4}}{{$field.4}}{{/if}}>
+ <input type="checkbox" name="{{$field.0}}" id="id_{{$field.0}}" value="1" {{if $field.2}}checked="checked"{{/if}} aria-checked="{{if $field.2}}true{{else}}false{{/if}}" {{if $field.3}}aria-describedby="{{$field.0}}_tip"{{/if}} {{if $field.4}}{{$field.4}}{{/if}}>
<label for="id_{{$field.0}}">
{{$field.1}}
{{if $field.3}}
<div id="id_{{$field.0}}_wrapper" class="form-group field input openid">
<label for="id_{{$field.0}}" id="label_{{$field.0}}">{{$field.1}}</label>
- <input class="form-control" name="{{$field.0}}" id="id_{{$field.0}}" type="text" value="{{$field.2 nofilter}}" aria-describedby="{{$field.0}}_tip">
+ <input class="form-control" name="{{$field.0}}" id="id_{{$field.0}}" type="text" value="{{$field.2 nofilter}}" {{if $field.4}} readonly="readonly" {{/if}} aria-describedby="{{$field.0}}_tip">
{{if $field.3}}
<span class="help-block" id="{{$field.0}}_tip" role="tooltip">{{$field.3 nofilter}}</span>
{{/if}}
<!-- Modal -->
- <div id="modal" class="modal fade" tabindex="-1" role="dialog" aria-hidden="true">
+ <div id="modal" class="modal fade" tabindex="-1" role="dialog">
<div class="modal-dialog modal-full-screen">
<div class="modal-content">
<div id="modal-header" class="modal-header">
- <button id="modal-cloase" type="button" class="close" data-dismiss="modal" aria-hidden="true">
+ <button id="modal-cloase" type="button" class="close" data-dismiss="modal">
×
</button>
<h4 id="modal-title" class="modal-title"></h4>
{{if $register}}
<div id="login-extra-links">
<h3 id="login-head" class="sr-only">{{$register.title}}</h3>
- <a href="register" title="{{$register.title}}" id="register-link" class="btn btn-default">{{$register.desc}}</a>
+ <a href="{{$register.url}}" title="{{$register.title}}" id="register-link" class="btn btn-default">{{$register.desc}}</a>
</div>
{{/if}}
{{* The notifications dropdown *}}
{{if $nav.notifications}}
<li id="nav-notification" class="nav-segment" role="presentation">
- <a href="{{$nav.notifications.0}}" rel="#nav-notifications-menu" data-toggle="tooltip" aria-label="{{$nav.notifications.1}}" title="{{$nav.notifications.1}}" role="button" id="dropdownMenu1" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
+ <a href="{{$nav.notifications.0}}" rel="#nav-notifications-menu" data-toggle="tooltip" aria-label="{{$nav.notifications.1}}" title="{{$nav.notifications.1}}" role="button" id="dropdownMenu1" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" aria-controls="nav-notifications-menu">
<i class="fa fa-bell fa-lg" aria-hidden="true"></i>
<span role="menuitem" class="sr-only">{{$nav.notifications.1}}</span>
<span id="notify-update" class="nav-notify-badge badge nav-notify dropdown" data-toggle="dropdown"></span>
<form class="navbar-form" role="search" method="get" action="{{$nav.search.0}}">
<!-- <img class="hidden-xs" src="{{$nav.userinfo.icon}}" alt="{{$nav.userinfo.name}}" style="max-width:33px; max-height:33px; min-width:33px; min-height:33px; width:33px; height:33px;"> -->
<div class="form-group form-group-search">
- <input accesskey="s" id="nav-search-input-field" class="form-control form-search" type="text" name="search" data-toggle="tooltip" title="{{$search_hint}}" placeholder="{{$nav.search.1}}">
+ <input accesskey="s" id="nav-search-input-field" class="form-control form-search" type="text" name="q" data-toggle="tooltip" title="{{$search_hint}}" placeholder="{{$nav.search.1}}">
<button class="btn btn-default btn-sm form-button-search" type="submit">{{$nav.search.1}}</button>
</div>
</form>
{{if $nav.remote}}<span class="trunctate">{{$nav.remote}}</span>{{/if}}
</div>
- <img id="avatar" src="{{$nav.userinfo.icon}}" alt="{{$nav.userinfo.name}}">
+ <img id="avatar" src="{{$nav.userinfo.icon}}" alt="{{$nav.userinfo.name}}">
<span class="caret"></span>
</button>
{{if $nav.contacts}}
<li role="presentation"><a role="menuitem" id="nav-menu-contacts-link" class="nav-link {{$nav.contacts.2}}" href="{{$nav.contacts.0}}" title="{{$nav.contacts.3}}"><i class="fa fa-users fa-fw" aria-hidden="true"></i> {{$nav.contacts.1}}</a><span id="intro-update-li" class="nav-intro-badge badge nav-notify"></span></li>
{{/if}}
- {{if $nav.manage}}
- <li role="presentation"><a role="menuitem" id="nav-manage-link" class="nav-commlink {{$nav.manage.2}} {{$sel.manage}}" href="{{$nav.manage.0}}" title="{{$nav.manage.3}}"><i class="fa fa-flag fa-fw" aria-hidden="true"></i> {{$nav.manage.1}}</a></li>
+ {{if $nav.delegation}}
+ <li role="presentation"><a role="menuitem" id="nav-delegation-link" class="nav-commlink {{$nav.delegation.2}} {{$sel.delegation}}" href="{{$nav.delegation.0}}" title="{{$nav.delegation.3}}"><i class="fa fa-flag fa-fw" aria-hidden="true"></i> {{$nav.delegation.1}}</a></li>
{{/if}}
<li role="presentation"><a role="menuitem" id="nav-directory-link" class="nav-link {{$nav.directory.2}}" href="{{$nav.directory.0}}" title="{{$nav.directory.3}}"><i class="fa fa-sitemap fa-fw" aria-hidden="true"></i>{{$nav.directory.1}}</a></li>
<li role="presentation" class="divider"></li>
{{if $nav.apps}}
- <li role="presentation"><a role="menuitem" id="nav-apps-link" class="nav-link {{$nav.apps.2}} {{$sel.manage}}" href="{{$nav.apps.0}}" title="{{$nav.apps.3}}" ><i class="fa fa-puzzle-piece fa-fw" aria-hidden="true"></i> {{$nav.apps.1}}</a>
+ <li role="presentation"><a role="menuitem" id="nav-apps-link" class="nav-link {{$nav.apps.2}}" href="{{$nav.apps.0}}" title="{{$nav.apps.3}}" ><i class="fa fa-puzzle-piece fa-fw" aria-hidden="true"></i> {{$nav.apps.1}}</a>
<li role="presentation" class="divider"></li>
{{/if}}
{{if $nav.help}}
{{if $nav.messages}}
<li role="presentation" class="list-group-item"><a role="menuitem" class="nav-link {{$nav.messages.2}} {{$sel.messages}}" href="{{$nav.messages.0}}" title="{{$nav.messages.3}}" ><i class="fa fa-envelope fa-fw" aria-hidden="true"></i> {{$nav.messages.1}}</a></li>
{{/if}}
- {{if $nav.manage}}
- <li role="presentation" class="list-group-item"><a role="menuitem" class="nav-commlink {{$nav.manage.2}} {{$sel.manage}}" href="{{$nav.manage.0}}" title="{{$nav.manage.3}}"><i class="fa fa-flag fa-fw" aria-hidden="true"></i> {{$nav.manage.1}}</a></li>
+ {{if $nav.delegation}}
+ <li role="presentation" class="list-group-item"><a role="menuitem" class="nav-commlink {{$nav.delegation.2}} {{$sel.delegation}}" href="{{$nav.delegation.0}}" title="{{$nav.delegation.3}}"><i class="fa fa-flag fa-fw" aria-hidden="true"></i> {{$nav.delegation.1}}</a></li>
{{/if}}
{{if $nav.settings}}
<li role="presentation" class="list-group-item"><a role="menuitem" class="nav-link {{$nav.settings.2}}" href="{{$nav.settings.0}}" title="{{$nav.settings.3}}"><i class="fa fa-cog fa-fw" aria-hidden="true"></i> {{$nav.settings.1}}</a></li>
<div class="col-md-8">
{{* The button to save searches *}}
{{if $s}}
- <a href="search/saved/add/{{$q}}?return_url={{$return_url}}" class="btn btn-primary btn-small pull-right">{{$save_label}}</a>
+ <a href="search/saved/add?term={{$q}}&return_url={{$return_url}}" class="btn btn-primary btn-small pull-right">{{$save_label}}</a>
{{/if}}
{{* The select popup menu to select what kind of results the user would like to search for *}}
</div>
{{if $s}}
- <form id="search-save-form" action="search/saved/add/{{$q}}" method="get">
- <input type="hidden" name="return_url" value="{{$return_url}}">
- <button class="btn btn-sm btn-main pull-right" type="submit" id="search-save" title="{{$save_label}}" aria-label="{{$save_label}}" value="{{$save_label}}" data-toggle="tooltip">
+ <a href="search/saved/add?term={{$q}}&return_url={{$return_url}}" class="btn btn-sm btn-main pull-right" id="search-save" title="{{$save_label}}" aria-label="{{$save_label}}" value="{{$save_label}}" data-toggle="tooltip">
{{if $mode == "tag"}}
- <i class="fa fa-plus fa-2x" aria-hidden="true"></i>
+ <i class="fa fa-plus fa-2x" aria-hidden="true"></i>
{{else}}
- <i class="fa fa-floppy-o fa-2x" aria-hidden="true"></i>
+ <i class="fa fa-floppy-o fa-2x" aria-hidden="true"></i>
{{/if}}
- <span class="sr-only">{{$save_label}}</span>
- </button>
- </form>
+ <span class="sr-only">{{$save_label}}</span>
+ </a>
{{/if}}
</div>
{{if $oid_enable}}
{{include file="field_input.tpl" field=$openid}}
+ {{include file="field_checkbox.tpl" field=$delete_openid}}
{{/if}}
<div class="form-group pull-right settings-submit-wrapper" >
<ul role="menu" id="saved-search-ul">
{{foreach $saved as $search}}
<li role="menuitem" class="saved-search-li clear">
- <a href="search/saved/remove/{{$search.encodedterm}}?return_url={{$return_url}}" title="{{$search.delete}}" onclick="return confirmDelete();" id="drop-saved-search-term-{{$search.id}}" class="savedsearchdrop pull-right widget-action faded-icon">
+ <a href="search/saved/remove?term={{$search.encodedterm}}&return_url={{$return_url}}" title="{{$search.delete}}" onclick="return confirmDelete();" id="drop-saved-search-term-{{$search.id}}" class="savedsearchdrop pull-right widget-action faded-icon">
<i class="fa fa-trash" aria-hidden="true"></i>
</a>
<a href="search?q={{$search.encodedterm}}" id="saved-search-term-{{$search.id}}" class="savedsearchterm">{{$search.term}}</a>
.identity-match-photo {
position: relative;
}
-.identity-match-photo .manage-notify {
+.identity-match-photo .delegation-notify {
background-color: #19AEFF;
border-radius: 5px;
font-size: 10px;
.identity-match-photo {
position: relative;
}
-.identity-match-photo .manage-notify {
+.identity-match-photo .delegation-notify {
background-color: #19AEFF;
border-radius: 5px;
font-size: 10px;
});
});
-function insertFormatting(BBcode, id) {
- var tmpStr = $("#comment-edit-text-" + id).val();
- if (tmpStr == "") {
- $("#comment-edit-text-" + id).addClass("comment-edit-text-full");
- $("#comment-edit-text-" + id).removeClass("comment-edit-text-empty");
- openMenu("comment-edit-submit-wrapper-" + id);
- }
-
- textarea = document.getElementById("comment-edit-text-" +id);
- if (document.selection) {
- textarea.focus();
- selected = document.selection.createRange();
- selected.text = "["+BBcode+"]" + selected.text + "[/"+BBcode+"]";
- } else if (textarea.selectionStart || textarea.selectionStart == "0") {
- var start = textarea.selectionStart;
- var end = textarea.selectionEnd;
- textarea.value = textarea.value.substring(0, start) + "["+BBcode+"]" + textarea.value.substring(start, end) + "[/"+BBcode+"]" + textarea.value.substring(end, textarea.value.length);
- }
-
- return true;
-}
-
function showThread(id) {
$("#collapsed-comments-" + id).show()
$("#collapsed-comments-" + id + " .collapsed-comments").show()
.identity-match-photo {
position: relative;
}
-.identity-match-photo .manage-notify {
+.identity-match-photo .delegation-notify {
background-color: #19AEFF;
border-radius: 5px;
font-size: 10px;
/* manage page */
.identity-match-photo {
position: relative;
- .manage-notify {
+ .delegation-notify {
background-color: #19AEFF;
border-radius: 5px;
font-size: 10px;
use Friendica\Core\PConfig;
use Friendica\Model\Profile;
-$uid = defaults($_REQUEST, 'puid', 0);
+$uid = $_REQUEST['puid'] ?? 0;
$color = false;
$quattro_align = false;
<li id="nav-site-linkmenu" class="nav-menu-icon"><a href="#" rel="#nav-site-menu"><span class="icon s22 gear">Site</span></a>
<ul id="nav-site-menu" class="menu-popup">
- {{if $nav.manage}}<li><a class="{{$nav.manage.2}}" href="{{$nav.manage.0}}" title="{{$nav.manage.3}}">{{$nav.manage.1}}</a></li>{{/if}}
+ {{if $nav.delegation}}<li><a class="{{$nav.delegation.2}}" href="{{$nav.delegation.0}}" title="{{$nav.delegation.3}}">{{$nav.delegation.1}}</a></li>{{/if}}
{{if $nav.settings}}<li><a class="{{$nav.settings.2}}" href="{{$nav.settings.0}}" title="{{$nav.settings.3}}">{{$nav.settings.1}}</a></li>{{/if}}
{{if $nav.admin}}<li><a accesskey="a" class="{{$nav.admin.2}}" href="{{$nav.admin.0}}" title="{{$nav.admin.3}}" >{{$nav.admin.1}}</a></li>{{/if}}
{{foreach $saved as $search}}
<li class="tool {{if $search.selected}}selected{{/if}}">
<a href="search?q={{$search.encodedterm}}" class="label">{{$search.term}}</a>
- <a href="search/saved/remove/{{$search.encodedterm}}?return_url={{$return_url}}" class="action icon s10 delete" title="{{$search.delete}}" onclick="return confirmDelete();"></a>
+ <a href="search/saved/remove?term={{$search.encodedterm}}&return_url={{$return_url}}" class="action icon s10 delete" title="{{$search.delete}}" onclick="return confirmDelete();"></a>
</li>
{{/foreach}}
</ul>
}
/* notifications popup menu */
-.manage-notify {
+.delegation-notify {
font-size: 10px;
padding: 1px 3px;
top: 0px;
<script type="text/javascript" src="{{$baseurl}}/view/theme/smoothly/js/jquery.autogrow.textarea.js"></script>
<script type="text/javascript">
-$(document).ready(function() {
-
-});
function tautogrow(id) {
$("textarea#comment-edit-text-" + id).autogrow();
-};
-
-function insertFormatting(BBcode, id) {
- var tmpStr = $("#comment-edit-text-" + id).val();
- if (tmpStr == "") {
- $("#comment-edit-text-" + id).addClass("comment-edit-text-full");
- $("#comment-edit-text-" + id).removeClass("comment-edit-text-empty");
- openMenu("comment-edit-submit-wrapper-" + id);
- }
-
- textarea = document.getElementById("comment-edit-text-" + id);
- if (document.selection) {
- textarea.focus();
- selected = document.selection.createRange();
- selected.text = "["+BBcode+"]" + selected.text + "[/"+BBcode+"]";
- } else if (textarea.selectionStart || textarea.selectionStart == "0") {
- var start = textarea.selectionStart;
- var end = textarea.selectionEnd;
- textarea.value = textarea.value.substring(0, start)
- + "["+BBcode+"]" + textarea.value.substring(start, end) + "[/"+BBcode+"]"
- + textarea.value.substring(end, textarea.value.length);
- }
-
- return true;
-}
-
-function cmtBbOpen(id) {
- $(".comment-edit-bb-" + id).show();
-}
-function cmtBbClose(id) {
- $(".comment-edit-bb-" + id).hide();
}
</script>
{{if $nav.profiles}}<li><a id="nav-profiles-link" class="nav-commlink nav-sep {{$nav.profiles.2}}" href="{{$nav.profiles.0}}">{{$nav.profiles.1}}</a></li>{{/if}}
{{if $nav.settings}}<li><a id="nav-settings-link" class="nav-commlink {{$nav.settings.2}}" href="{{$nav.settings.0}}">{{$nav.settings.1}}</a></li>{{/if}}
- {{if $nav.manage}}<li><a id="nav-manage-link" class="nav-commlink {{$nav.manage.2}}" href="{{$nav.manage.0}}">{{$nav.manage.1}}</a></li>{{/if}}
+ {{if $nav.delegation}}<li><a id="nav-delegation-link" class="nav-commlink {{$nav.delegation.2}}" href="{{$nav.delegation.0}}">{{$nav.delegation.1}}</a></li>{{/if}}
{{if $nav.admin}}<li><a id="nav-admin-link" class="nav-commlink {{$nav.admin.2}}" href="{{$nav.admin.0}}">{{$nav.admin.1}}</a></li>{{/if}}
$a->page['htmlhead'] .= <<< EOT
<script>
-function insertFormatting(BBcode, id) {
- var tmpStr = $("#comment-edit-text-" + id).val();
- if (tmpStr == "") {
- $("#comment-edit-text-" + id).addClass("comment-edit-text-full");
- $("#comment-edit-text-" + id).removeClass("comment-edit-text-empty");
- openMenu("comment-edit-submit-wrapper-" + id);
- }
-
- textarea = document.getElementById("comment-edit-text-" +id);
- if (document.selection) {
- textarea.focus();
- selected = document.selection.createRange();
- selected.text = "["+BBcode+"]" + selected.text + "[/"+BBcode+"]";
- } else if (textarea.selectionStart || textarea.selectionStart == "0") {
- var start = textarea.selectionStart;
- var end = textarea.selectionEnd;
- textarea.value = textarea.value.substring(0, start) + "["+BBcode+"]" + textarea.value.substring(start, end) + "[/"+BBcode+"]" + textarea.value.substring(end, textarea.value.length);
- }
-
- return true;
-}
-
function cmtBbOpen(id) {
$(".comment-edit-bb-" + id).show();
}
color: #000;
}
-.manage-notify {
+.delegation-notify {
background-color: #CB4437;
border-radius: 10px;
font: bold 11px/16px Arial;
color: #000;
}
-.manage-notify {
+.delegation-notify {
background-color: #CB4437;
border-radius: 10px;
font: bold 11px/16px Arial;
text-decoration: none;
}
-.manage-notify {
+.delegation-notify {
background-color: #F80;
-moz-border-radius: 5px 5px 5px 5px;
-webkit-border-radius: 5px 5px 5px 5px;
margin: 0px;
}
-#identity-manage-desc {
+#identity-delegation-desc {
margin-top:15px;
margin-bottom: 15px;
}
-#identity-manage-choose {
+#identity-delegation-choose {
margin-bottom: 15px;
}
use Friendica\Core\PConfig;
use Friendica\Model\Profile;
-$uid = defaults($_REQUEST, 'puid', 0);
+$uid = $_REQUEST['puid'] ?? 0;
$style = PConfig::get($uid, 'vier', 'style');
{{if $nav.introductions}}<li role="menuitem"><a class="{{$nav.introductions.2}}" href="{{$nav.introductions.0}}" title="{{$nav.introductions.3}}" >{{$nav.introductions.1}}</a><span id="intro-update-li" class="nav-notify"></span></li>{{/if}}
{{if $nav.contacts}}<li role="menuitem"><a class="{{$nav.contacts.2}}" href="{{$nav.contacts.0}}" title="{{$nav.contacts.3}}" >{{$nav.contacts.1}}</a></li>{{/if}}
{{if $nav.messages}}<li role="menuitem"><a class="{{$nav.messages.2}}" href="{{$nav.messages.0}}" title="{{$nav.messages.3}}" >{{$nav.messages.1}} <span id="mail-update-li" class="nav-notify"></span></a></li>{{/if}}
- {{if $nav.manage}}<li role="menuitem"><a class="{{$nav.manage.2}}" href="{{$nav.manage.0}}" title="{{$nav.manage.3}}">{{$nav.manage.1}}</a></li>{{/if}}
+ {{if $nav.delegation}}<li role="menuitem"><a class="{{$nav.delegation.2}}" href="{{$nav.delegation.0}}" title="{{$nav.delegation.3}}">{{$nav.delegation.1}}</a></li>{{/if}}
{{if $nav.usermenu.1}}<li role="menuitem"><a class="{{$nav.usermenu.1.2}}" href="{{$nav.usermenu.1.0}}" title="{{$nav.usermenu.1.3}}">{{$nav.usermenu.1.1}}</a></li>{{/if}}
{{if $nav.settings}}<li role="menuitem"><a class="{{$nav.settings.2}}" href="{{$nav.settings.0}}" title="{{$nav.settings.3}}">{{$nav.settings.1}}</a></li>{{/if}}
{{if $nav.admin}}
Renderer::setActiveTemplateEngine('smarty3');
- if (!empty($a->argv[0]) && $a->argv[0] . defaults($a->argv, 1, '') === "profile".$a->user['nickname'] || $a->argv[0] === "network" && local_user()) {
+ if (!empty($a->argv[0]) && ($a->argv[0] . ($a->argv[1] ?? '')) === ('profile' . $a->user['nickname']) || $a->argv[0] === 'network' && local_user()) {
vier_community_info();
$a->page['htmlhead'] .= "<link rel='stylesheet' type='text/css' href='view/theme/vier/wide.css' media='screen and (min-width: 1300px)'/>\n";
$a->page['htmlhead'] .= <<< EOT
<link rel='stylesheet' type='text/css' href='view/theme/vier/narrow.css' media='screen and (max-width: 1100px)' />
<script type="text/javascript">
-
-function insertFormatting(BBcode, id) {
- var tmpStr = $("#comment-edit-text-" + id).val();
- if (tmpStr == "") {
- $("#comment-edit-text-" + id).addClass("comment-edit-text-full");
- $("#comment-edit-text-" + id).removeClass("comment-edit-text-empty");
- openMenu("comment-edit-submit-wrapper-" + id);
- }
-
- textarea = document.getElementById("comment-edit-text-" +id);
- if (document.selection) {
- textarea.focus();
- selected = document.selection.createRange();
- selected.text = "["+BBcode+"]" + selected.text + "[/"+BBcode+"]";
- } else if (textarea.selectionStart || textarea.selectionStart == "0") {
- var start = textarea.selectionStart;
- var end = textarea.selectionEnd;
- textarea.value = textarea.value.substring(0, start) + "["+BBcode+"]" + textarea.value.substring(start, end) + "[/"+BBcode+"]" + textarea.value.substring(end, textarea.value.length);
- }
-
- return true;
-}
-
function showThread(id) {
$("#collapsed-comments-" + id).show()
$("#collapsed-comments-" + id + " .collapsed-comments").show()
// Hide the left menu bar
/// @TODO maybe move this static array out where it should belong?
- if (empty($a->page['aside']) && in_array($a->argv[0], ["community", "events", "help", "manage", "notifications",
+ if (empty($a->page['aside']) && in_array($a->argv[0], ["community", "events", "help", "delegation", "notifications",
"probe", "webfinger", "login", "invite", "credits"])) {
$a->page['htmlhead'] .= "<link rel='stylesheet' href='view/theme/vier/hide.css' />";
}
//Community_Pages at right_aside
if ($show_pages && local_user()) {
- $cid = defaults($_GET, 'cid', null);
+ $cid = $_GET['cid'] ?? null;
//sort by last updated item
$lastitem = true;