diff --git a/.woodpecker/.code_standards_check.yml b/.woodpecker/.code_standards_check.yml index fb5be33c..60a1bd2a 100644 --- a/.woodpecker/.code_standards_check.yml +++ b/.woodpecker/.code_standards_check.yml @@ -1,6 +1,6 @@ skip_clone: true -pipeline: +steps: clone_friendica_base: image: alpine/git commands: @@ -56,6 +56,10 @@ pipeline: - /tmp/drone-cache:/tmp/cache when: event: pull_request + phpstan: + image: friendicaci/php8.3:php8.3.3 + commands: + - ./bin/composer.phar run phpstan; check: image: friendicaci/php-cs commands: diff --git a/.woodpecker/.continuous-deployment.yml b/.woodpecker/.continuous-deployment.yml index 4d3bc5b7..d6d8a22a 100644 --- a/.woodpecker/.continuous-deployment.yml +++ b/.woodpecker/.continuous-deployment.yml @@ -5,7 +5,7 @@ labels: skip_clone: true -pipeline: +steps: clone_friendica_base: image: alpine/git commands: @@ -48,7 +48,7 @@ pipeline: branch: [ develop, '*-rc' ] event: push composer_install: - image: friendicaci/php8.2:php8.2.16 + image: friendicaci/php8.2:php8.2.28 commands: - export COMPOSER_HOME=.composer - composer validate diff --git a/.woodpecker/.messages.po_check.yml b/.woodpecker/.messages.po_check.yml index aa40ab4e..e0239dcd 100644 --- a/.woodpecker/.messages.po_check.yml +++ b/.woodpecker/.messages.po_check.yml @@ -1,6 +1,6 @@ skip_clone: true -pipeline: +steps: clone_friendica_base: image: alpine/git commands: diff --git a/.woodpecker/.phpunit.yml b/.woodpecker/.phpunit.yml index 887e897e..b0745ad0 100644 --- a/.woodpecker/.phpunit.yml +++ b/.woodpecker/.phpunit.yml @@ -5,11 +5,13 @@ matrix: - PHP_MAJOR_VERSION: 8.0 PHP_VERSION: 8.0.30 - PHP_MAJOR_VERSION: 8.1 - PHP_VERSION: 8.1.27 + PHP_VERSION: 8.1.31 - PHP_MAJOR_VERSION: 8.2 - PHP_VERSION: 8.2.16 + PHP_VERSION: 8.2.28 - PHP_MAJOR_VERSION: 8.3 - PHP_VERSION: 8.3.3 + PHP_VERSION: 8.3.17 + - PHP_MAJOR_VERSION: 8.4 + PHP_VERSION: 8.4.5 # This forces PHP Unit executions at the "opensocial" labeled location (because of much more power...) labels: @@ -17,7 +19,7 @@ labels: skip_clone: true -pipeline: +steps: clone_friendica_base: image: alpine/git commands: @@ -98,9 +100,9 @@ pipeline: - friendica/friendica-addons commands: - codecov -R '.' -Z -f 'clover.xml' - secrets: - - source: codecov-token - target: codecov_token + environment: + CODECOV_TOKEN: + from_secret: codecov-token services: mariadb: diff --git a/.woodpecker/.releaser.yml b/.woodpecker/.releaser.yml index f12697b9..7407f2bc 100644 --- a/.woodpecker/.releaser.yml +++ b/.woodpecker/.releaser.yml @@ -5,7 +5,7 @@ labels: skip_clone: true -pipeline: +steps: clone_friendica_base: image: alpine/git commands: @@ -45,7 +45,7 @@ pipeline: repo: friendica/friendica-addons event: tag composer_install: - image: friendicaci/php8.2:php8.2.16 + image: friendicaci/php8.2:php8.2.28 commands: - export COMPOSER_HOME=.composer - composer validate diff --git a/advancedcontentfilter/advancedcontentfilter.php b/advancedcontentfilter/advancedcontentfilter.php index 84eb468c..53cb9ebe 100644 --- a/advancedcontentfilter/advancedcontentfilter.php +++ b/advancedcontentfilter/advancedcontentfilter.php @@ -33,16 +33,13 @@ * */ -use Friendica\App; use Friendica\BaseModule; use Friendica\Content\Text\Markdown; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\Database\DBA; use Friendica\Database\DBStructure; use Friendica\DI; -use Friendica\Model\Item; use Friendica\Model\Post; use Friendica\Model\Tag; use Friendica\Model\User; @@ -64,7 +61,7 @@ function advancedcontentfilter_install() Hook::add('dbstructure_definition' , __FILE__, 'advancedcontentfilter_dbstructure_definition'); DBStructure::performUpdate(); - Logger::notice('installed advancedcontentfilter'); + DI::logger()->notice('installed advancedcontentfilter'); } /* @@ -123,21 +120,22 @@ function advancedcontentfilter_prepare_body_content_filter(&$hook_data) $expressionLanguage = new ExpressionLanguage\ExpressionLanguage(); } - if (!DI::userSession()->getLocalUserId()) { + $uid = $hook_data['uid'] ?? DI::userSession()->getLocalUserId(); + if (!$uid) { return; } $vars = advancedcontentfilter_get_filter_fields($hook_data['item']); - $rules = DI::cache()->get('rules_' . DI::userSession()->getLocalUserId()); + $rules = DI::cache()->get('rules_' . $uid); if (!isset($rules)) { $rules = DBA::toArray(DBA::select( 'advancedcontentfilter_rules', ['name', 'expression', 'serialized'], - ['uid' => DI::userSession()->getLocalUserId(), 'active' => true] + ['uid' => $uid, 'active' => true] )); - DI::cache()->set('rules_' . DI::userSession()->getLocalUserId(), $rules); + DI::cache()->set('rules_' . $uid, $rules); } if ($rules) { @@ -273,7 +271,7 @@ function advancedcontentfilter_content() 'rule_expression' => DI::l10n()->t('Rule Expression'), 'cancel' => DI::l10n()->t('Cancel'), ], - '$current_theme' => DI::app()->getCurrentTheme(), + '$current_theme' => DI::appHelper()->getCurrentTheme(), '$rules' => DBA::toArray(DBA::select('advancedcontentfilter_rules', [], ['uid' => DI::userSession()->getLocalUserId()])), '$form_security_token' => BaseModule::getFormSecurityToken() ]); diff --git a/birdavatar/birdavatar.php b/birdavatar/birdavatar.php index 4841ba52..cd49b183 100644 --- a/birdavatar/birdavatar.php +++ b/birdavatar/birdavatar.php @@ -6,9 +6,7 @@ * Author: Fabio */ -use Friendica\App; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\Database\DBA; use Friendica\DI; @@ -28,7 +26,7 @@ function birdavatar_install() Hook::register('addon_settings', __FILE__, 'birdavatar_addon_settings'); Hook::register('addon_settings_post', __FILE__, 'birdavatar_addon_settings_post'); - Logger::info('registered birdavatar'); + DI::logger()->info('registered birdavatar'); } /** diff --git a/blackout/blackout.php b/blackout/blackout.php index 55fb8d32..ac1ee3e6 100644 --- a/blackout/blackout.php +++ b/blackout/blackout.php @@ -44,9 +44,7 @@ * THE SOFTWARE. */ -use Friendica\App; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\Core\System; use Friendica\DI; @@ -78,7 +76,7 @@ function blackout_redirect ($b) } if (( $date1 <= $now ) && ( $now <= $date2 )) { - Logger::notice('redirecting user to blackout page'); + DI::logger()->notice('redirecting user to blackout page'); System::externalRedirect($myurl); } } diff --git a/blockbot/blockbot.php b/blockbot/blockbot.php index 022f188d..71e35c93 100644 --- a/blockbot/blockbot.php +++ b/blockbot/blockbot.php @@ -11,7 +11,6 @@ use Friendica\Core\Hook; use Friendica\DI; use Jaybizzle\CrawlerDetect\CrawlerDetect; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\Core\System; use Friendica\Network\HTTPException\ForbiddenException; @@ -70,7 +69,7 @@ function blockbot_init_1() } if (empty($parts)) { - Logger::debug('Known frontend found - accept', $logdata); + DI::logger()->debug('Known frontend found - accept', $logdata); if ($isCrawler) { blockbot_save('badly-parsed-agents', $_SERVER['HTTP_USER_AGENT']); } @@ -80,66 +79,66 @@ function blockbot_init_1() blockbot_log_activitypub($_SERVER['REQUEST_URI'], $_SERVER['HTTP_USER_AGENT']); if (blockbot_is_crawler($parts)) { - Logger::debug('Crawler found - reject', $logdata); + DI::logger()->debug('Crawler found - reject', $logdata); blockbot_reject(); } if (blockbot_is_searchbot($parts)) { - Logger::debug('Search bot found - reject', $logdata); + DI::logger()->debug('Search bot found - reject', $logdata); blockbot_reject(); } if (blockbot_is_unwanted($parts)) { - Logger::debug('Uncategorized unwanted agent found - reject', $logdata); + DI::logger()->debug('Uncategorized unwanted agent found - reject', $logdata); blockbot_reject(); } if (blockbot_is_security_checker($parts)) { if (!DI::config()->get('blockbot', 'security_checker')) { - Logger::debug('Security checker found - reject', $logdata); + DI::logger()->debug('Security checker found - reject', $logdata); blockbot_reject(); } - Logger::debug('Security checker found - accept', $logdata); + DI::logger()->debug('Security checker found - accept', $logdata); return; } if (blockbot_is_social_media($parts)) { - Logger::debug('Social media service found - accept', $logdata); + DI::logger()->debug('Social media service found - accept', $logdata); return; } if (blockbot_is_fediverse_client($parts)) { - Logger::debug('Fediverse client found - accept', $logdata); + DI::logger()->debug('Fediverse client found - accept', $logdata); return; } if (blockbot_is_feed_reader($parts)) { - Logger::debug('Feed reader found - accept', $logdata); + DI::logger()->debug('Feed reader found - accept', $logdata); return; } if (blockbot_is_fediverse_tool($parts)) { - Logger::debug('Fediverse tool found - accept', $logdata); + DI::logger()->debug('Fediverse tool found - accept', $logdata); return; } if (blockbot_is_service_agent($parts)) { - Logger::debug('Service agent found - accept', $logdata); + DI::logger()->debug('Service agent found - accept', $logdata); return; } if (blockbot_is_monitor($parts)) { - Logger::debug('Monitoring service found - accept', $logdata); + DI::logger()->debug('Monitoring service found - accept', $logdata); return; } if (blockbot_is_validator($parts)) { - Logger::debug('Validation service found - accept', $logdata); + DI::logger()->debug('Validation service found - accept', $logdata); return; } if (blockbot_is_good_tool($parts)) { - Logger::debug('Uncategorized helpful service found - accept', $logdata); + DI::logger()->debug('Uncategorized helpful service found - accept', $logdata); return; } @@ -147,10 +146,10 @@ function blockbot_init_1() if (blockbot_is_http_library($parts)) { blockbot_check_login_attempt($_SERVER['REQUEST_URI'], $logdata); if (!DI::config()->get('blockbot', 'http_libraries')) { - Logger::debug('HTTP Library found - reject', $logdata); + DI::logger()->debug('HTTP Library found - reject', $logdata); blockbot_reject(); } - Logger::debug('HTTP Library found - accept', $logdata); + DI::logger()->debug('HTTP Library found - accept', $logdata); return; } @@ -161,12 +160,12 @@ function blockbot_init_1() if (!$isCrawler) { blockbot_save('good-agents', $_SERVER['HTTP_USER_AGENT']); - Logger::debug('Non-bot user agent detected', $logdata); + DI::logger()->debug('Non-bot user agent detected', $logdata); return; } blockbot_save('bad-agents', $_SERVER['HTTP_USER_AGENT']); - Logger::notice('Possible bot found - reject', $logdata); + DI::logger()->notice('Possible bot found - reject', $logdata); blockbot_reject(); } @@ -209,7 +208,7 @@ function blockbot_log_activitypub(string $url, string $agent) blockbot_save('activitypub-inbox-agents', $agent); } - if (!empty($_SERVER['HTTP_SIGNATURE']) && !empty(HTTPSignature::getSigner('', $_SERVER))) { + if (!empty($_SERVER['HTTP_SIGNATURE']) && !empty(HTTPSignature::getSigner('', $_SERVER, false))) { blockbot_save('activitypub-signature-agents', $agent); } } @@ -217,7 +216,7 @@ function blockbot_log_activitypub(string $url, string $agent) function blockbot_check_login_attempt(string $url, array $logdata) { if (in_array(trim(parse_url($url, PHP_URL_PATH), '/'), ['login', 'lostpass', 'register'])) { - Logger::debug('Login attempt detected - reject', $logdata); + DI::logger()->debug('Login attempt detected - reject', $logdata); blockbot_reject(); } } @@ -443,7 +442,7 @@ function blockbot_is_monitor(array $parts): bool } /** - * Services in the centralized and decentralized social media environment + * Services in the centralized and decentralized social media environment * * @param array $parts * @return boolean diff --git a/bluesky/bluesky.php b/bluesky/bluesky.php index 91e524fe..aef7156c 100644 --- a/bluesky/bluesky.php +++ b/bluesky/bluesky.php @@ -26,12 +26,10 @@ */ use Friendica\Content\Text\BBCode; -use Friendica\Content\Text\HTML; use Friendica\Content\Text\Plaintext; use Friendica\Core\Cache\Enum\Duration; use Friendica\Core\Config\Util\ConfigFileManager; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Protocol; use Friendica\Core\Renderer; use Friendica\Core\Worker; @@ -39,42 +37,20 @@ use Friendica\Database\DBA; use Friendica\DI; use Friendica\Model\Contact; use Friendica\Model\Conversation; -use Friendica\Model\GServer; use Friendica\Model\Item; -use Friendica\Model\ItemURI; use Friendica\Model\Photo; use Friendica\Model\Post; -use Friendica\Model\Tag; use Friendica\Model\User; -use Friendica\Network\HTTPClient\Client\HttpClientAccept; -use Friendica\Network\HTTPClient\Client\HttpClientOptions; -use Friendica\Network\HTTPClient\Client\HttpClientRequest; use Friendica\Object\Image; use Friendica\Protocol\Activity; +use Friendica\Protocol\ATProtocol; use Friendica\Protocol\Relay; use Friendica\Util\DateTimeFormat; -use Friendica\Util\Network; use Friendica\Util\Strings; const BLUESKY_DEFAULT_POLL_INTERVAL = 10; // given in minutes const BLUESKY_IMAGE_SIZE = [1000000, 500000, 100000, 50000]; -const BLUEKSY_STATUS_UNKNOWN = 0; -const BLUEKSY_STATUS_TOKEN_OK = 1; -const BLUEKSY_STATUS_SUCCESS = 2; -const BLUEKSY_STATUS_API_FAIL = 10; -const BLUEKSY_STATUS_DID_FAIL = 11; -const BLUEKSY_STATUS_PDS_FAIL = 12; -const BLUEKSY_STATUS_TOKEN_FAIL = 13; - -/* - * (Currently) hard wired paths for Bluesky services - */ -const BLUESKY_DIRECTORY = 'https://plc.directory'; // Path to the directory server service to fetch the PDS of a given DID -const BLUESKY_PDS = 'https://bsky.social'; // Path to the personal data server service (PDS) to fetch the DID for a given handle -const BLUESKY_WEB = 'https://bsky.app'; // Path to the web interface with the user profile and posts -const BLUESKY_HOSTNAME = 'bsky.social'; // Host name to be added to the handle if incomplete - function bluesky_install() { Hook::register('load_config', __FILE__, 'bluesky_load_config'); @@ -86,19 +62,17 @@ function bluesky_install() Hook::register('connector_settings_post', __FILE__, 'bluesky_settings_post'); Hook::register('cron', __FILE__, 'bluesky_cron'); Hook::register('support_follow', __FILE__, 'bluesky_support_follow'); - Hook::register('support_probe', __FILE__, 'bluesky_support_probe'); Hook::register('follow', __FILE__, 'bluesky_follow'); Hook::register('unfollow', __FILE__, 'bluesky_unfollow'); Hook::register('block', __FILE__, 'bluesky_block'); Hook::register('unblock', __FILE__, 'bluesky_unblock'); Hook::register('check_item_notification', __FILE__, 'bluesky_check_item_notification'); - Hook::register('probe_detect', __FILE__, 'bluesky_probe_detect'); Hook::register('item_by_link', __FILE__, 'bluesky_item_by_link'); } function bluesky_load_config(ConfigFileManager $loader) { - DI::app()->getConfigCache()->load($loader->loadAddonConfig('bluesky'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); + DI::appHelper()->getConfigCache()->load($loader->loadAddonConfig('bluesky'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); } function bluesky_check_item_notification(array &$notification_data) @@ -107,7 +81,7 @@ function bluesky_check_item_notification(array &$notification_data) return; } - $did = bluesky_get_user_did($notification_data['uid']); + $did = DI::atProtocol()->getUserDid($notification_data['uid']); if (empty($did)) { return; } @@ -115,61 +89,6 @@ function bluesky_check_item_notification(array &$notification_data) $notification_data['profiles'][] = $did; } -function bluesky_probe_detect(array &$hookData) -{ - // Don't overwrite an existing result - if (isset($hookData['result'])) { - return; - } - - // Avoid a lookup for the wrong network - if (!in_array($hookData['network'], ['', Protocol::BLUESKY])) { - return; - } - - $pconfig = DBA::selectFirst('pconfig', ['uid'], ["`cat` = ? AND `k` = ? AND `v` != ?", 'bluesky', 'access_token', '']); - if (empty($pconfig['uid'])) { - return; - } - - if (parse_url($hookData['uri'], PHP_URL_SCHEME) == 'did') { - $did = $hookData['uri']; - } elseif (parse_url($hookData['uri'], PHP_URL_PATH) == $hookData['uri'] && strpos($hookData['uri'], '@') === false) { - $did = bluesky_get_did($hookData['uri'], $pconfig['uid']); - if (empty($did)) { - return; - } - } elseif (Network::isValidHttpUrl($hookData['uri'])) { - $did = bluesky_get_did_by_profile($hookData['uri'], $pconfig['uid']); - if (empty($did)) { - return; - } - } else { - return; - } - - $token = bluesky_get_token($pconfig['uid']); - if (empty($token)) { - return; - } - - $data = bluesky_xrpc_get($pconfig['uid'], 'app.bsky.actor.getProfile', ['actor' => $did]); - if (empty($data) || empty($data->did)) { - return; - } - - $hookData['result'] = bluesky_get_contact_fields($data, 0, $pconfig['uid'], true); - - // Preparing probe data. This differs slightly from the contact array - $hookData['result']['photo'] = $data->avatar ?? ''; - $hookData['result']['batch'] = ''; - $hookData['result']['notify'] = ''; - $hookData['result']['poll'] = ''; - $hookData['result']['poco'] = ''; - $hookData['result']['priority'] = 0; - $hookData['result']['guid'] = ''; -} - function bluesky_item_by_link(array &$hookData) { // Don't overwrite an existing result @@ -177,26 +96,25 @@ function bluesky_item_by_link(array &$hookData) return; } - $token = bluesky_get_token($hookData['uid']); - if (empty($token)) { - return; + if (substr($hookData['uri'], 0, 5) != 'at://') { + if (!preg_match('#^' . ATProtocol::WEB . '/profile/(.+)/post/(.+)#', $hookData['uri'], $matches)) { + return; + } + + $did = DI::atProtocol()->getDid($matches[1]); + if (empty($did)) { + return; + } + + DI::logger()->debug('Found bluesky post', ['uri' => $hookData['uri'], 'did' => $did, 'cid' => $matches[2]]); + + $uri = 'at://' . $did . '/app.bsky.feed.post/' . $matches[2]; + } else { + $uri = $hookData['uri']; } - if (!preg_match('#^' . BLUESKY_WEB . '/profile/(.+)/post/(.+)#', $hookData['uri'], $matches)) { - return; - } - - $did = bluesky_get_did($matches[1], $hookData['uid']); - if (empty($did)) { - return; - } - - Logger::debug('Found bluesky post', ['url' => $hookData['uri'], 'did' => $did, 'cid' => $matches[2]]); - - $uri = 'at://' . $did . '/app.bsky.feed.post/' . $matches[2]; - - $uri = bluesky_fetch_missing_post($uri, $hookData['uid'], $hookData['uid'], Item::PR_FETCHED, 0, 0, 0); - Logger::debug('Got post', ['did' => $did, 'cid' => $matches[2], 'result' => $uri]); + $uri = DI::atpProcessor()->fetchMissingPost($uri, $hookData['uid'], Item::PR_FETCHED, 0, 0); + DI::logger()->debug('Got post', ['uri' => $uri]); if (!empty($uri)) { $item = Post::selectFirst(['id'], ['uri' => $uri, 'uid' => $hookData['uid']]); if (!empty($item['id'])) { @@ -212,21 +130,14 @@ function bluesky_support_follow(array &$data) } } -function bluesky_support_probe(array &$data) -{ - if ($data['protocol'] == Protocol::BLUESKY) { - $data['result'] = true; - } -} - function bluesky_follow(array &$hook_data) { - $token = bluesky_get_token($hook_data['uid']); + $token = DI::atProtocol()->getUserToken($hook_data['uid']); if (empty($token)) { return; } - Logger::debug('Check if contact is bluesky', ['data' => $hook_data]); + DI::logger()->debug('Check if contact is bluesky', ['data' => $hook_data]); $contact = DBA::selectFirst('contact', [], ['network' => Protocol::BLUESKY, 'url' => $hook_data['url'], 'uid' => [0, $hook_data['uid']]]); if (empty($contact)) { return; @@ -240,20 +151,20 @@ function bluesky_follow(array &$hook_data) $post = [ 'collection' => 'app.bsky.graph.follow', - 'repo' => bluesky_get_user_did($hook_data['uid']), + 'repo' => DI::atProtocol()->getUserDid($hook_data['uid']), 'record' => $record ]; - $activity = bluesky_xrpc_post($hook_data['uid'], 'com.atproto.repo.createRecord', $post); + $activity = DI::atProtocol()->XRPCPost($hook_data['uid'], 'com.atproto.repo.createRecord', $post); if (!empty($activity->uri)) { $hook_data['contact'] = $contact; - Logger::debug('Successfully start following', ['url' => $contact['url'], 'uri' => $activity->uri]); + DI::logger()->debug('Successfully start following', ['url' => $contact['url'], 'uri' => $activity->uri]); } } function bluesky_unfollow(array &$hook_data) { - $token = bluesky_get_token($hook_data['uid']); + $token = DI::atProtocol()->getUserToken($hook_data['uid']); if (empty($token)) { return; } @@ -262,7 +173,7 @@ function bluesky_unfollow(array &$hook_data) return; } - $data = bluesky_xrpc_get($hook_data['uid'], 'app.bsky.actor.getProfile', ['actor' => $hook_data['contact']['url']]); + $data = DI::atProtocol()->XRPCGet('app.bsky.actor.getProfile', ['actor' => $hook_data['contact']['url']], $hook_data['uid']); if (empty($data->viewer) || empty($data->viewer->following)) { return; } @@ -274,7 +185,7 @@ function bluesky_unfollow(array &$hook_data) function bluesky_block(array &$hook_data) { - $token = bluesky_get_token($hook_data['uid']); + $token = DI::atProtocol()->getUserToken($hook_data['uid']); if (empty($token)) { return; } @@ -291,23 +202,23 @@ function bluesky_block(array &$hook_data) $post = [ 'collection' => 'app.bsky.graph.block', - 'repo' => bluesky_get_user_did($hook_data['uid']), + 'repo' => DI::atProtocol()->getUserDid($hook_data['uid']), 'record' => $record ]; - $activity = bluesky_xrpc_post($hook_data['uid'], 'com.atproto.repo.createRecord', $post); + $activity = DI::atProtocol()->XRPCPost($hook_data['uid'], 'com.atproto.repo.createRecord', $post); if (!empty($activity->uri)) { $ucid = Contact::getUserContactId($hook_data['contact']['id'], $hook_data['uid']); if ($ucid) { Contact::remove($ucid); } - Logger::debug('Successfully blocked contact', ['url' => $hook_data['contact']['url'], 'uri' => $activity->uri]); + DI::logger()->debug('Successfully blocked contact', ['url' => $hook_data['contact']['url'], 'uri' => $activity->uri]); } } function bluesky_unblock(array &$hook_data) { - $token = bluesky_get_token($hook_data['uid']); + $token = DI::atProtocol()->getUserToken($hook_data['uid']); if (empty($token)) { return; } @@ -316,7 +227,7 @@ function bluesky_unblock(array &$hook_data) return; } - $data = bluesky_xrpc_get($hook_data['uid'], 'app.bsky.actor.getProfile', ['actor' => $hook_data['contact']['url']]); + $data = DI::atProtocol()->XRPCGet('app.bsky.actor.getProfile', ['actor' => $hook_data['contact']['url']], $hook_data['uid']); if (empty($data->viewer) || empty($data->viewer->blocking)) { return; } @@ -351,7 +262,7 @@ function bluesky_settings(array &$data) $def_enabled = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'post_by_default') ?? false; $pds = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'pds'); $handle = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'handle'); - $did = bluesky_get_user_did(DI::userSession()->getLocalUserId()); + $did = DI::atProtocol()->getUserDid(DI::userSession()->getLocalUserId()); $token = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'access_token'); $import = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'import') ?? false; $import_feeds = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'import_feeds') ?? false; @@ -399,33 +310,34 @@ function bluesky_get_status(string $handle = null, string $did = null, string $p return DI::l10n()->t('You are not authenticated. Please enter your handle and the app password.'); } - $status = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'status') ?? BLUEKSY_STATUS_UNKNOWN; + $status = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'status') ?? ATProtocol::STATUS_UNKNOWN; + $message = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'status-message') ?? ''; // Fallback mechanism for connection that had been established before the introduction of the status - if ($status == BLUEKSY_STATUS_UNKNOWN) { + if ($status == ATProtocol::STATUS_UNKNOWN) { if (empty($did)) { - $status = BLUEKSY_STATUS_DID_FAIL; + $status = ATProtocol::STATUS_DID_FAIL; } elseif (empty($pds)) { - $status = BLUEKSY_STATUS_PDS_FAIL; + $status = ATProtocol::STATUS_PDS_FAIL; } elseif (!empty($token)) { - $status = BLUEKSY_STATUS_TOKEN_OK; + $status = ATProtocol::STATUS_TOKEN_OK; } else { - $status = BLUEKSY_STATUS_TOKEN_FAIL; + $status = ATProtocol::STATUS_TOKEN_FAIL; } } switch ($status) { - case BLUEKSY_STATUS_TOKEN_OK: + case ATProtocol::STATUS_TOKEN_OK: return DI::l10n()->t("You are authenticated to Bluesky. For security reasons the password isn't stored."); - case BLUEKSY_STATUS_SUCCESS: + case ATProtocol::STATUS_SUCCESS: return DI::l10n()->t('The communication with the personal data server service (PDS) is established.'); - case BLUEKSY_STATUS_API_FAIL; - return DI::l10n()->t('Communication issues with the personal data server service (PDS).'); - case BLUEKSY_STATUS_DID_FAIL: + case ATProtocol::STATUS_API_FAIL; + return DI::l10n()->t('Communication issues with the personal data server service (PDS): %s', $message); + case ATProtocol::STATUS_DID_FAIL: return DI::l10n()->t('The DID for the provided handle could not be detected. Please check if you entered the correct handle.'); - case BLUEKSY_STATUS_PDS_FAIL: + case ATProtocol::STATUS_PDS_FAIL: return DI::l10n()->t('The personal data server service (PDS) could not be detected.'); - case BLUEKSY_STATUS_TOKEN_FAIL: + case ATProtocol::STATUS_TOKEN_FAIL: return DI::l10n()->t('The authentication with the provided handle and password failed. Please check if you entered the correct password.'); default: return ''; @@ -453,11 +365,11 @@ function bluesky_settings_post(array &$b) DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'bluesky', 'friendica_handle', intval($_POST['bluesky_friendica_handle'] ?? false)); if (!empty($handle)) { - $did = bluesky_get_user_did(DI::userSession()->getLocalUserId(), empty($old_did) || $old_handle != $handle); + $did = DI::atProtocol()->getUserDid(DI::userSession()->getLocalUserId(), empty($old_did) || $old_handle != $handle); if (!empty($did) && (empty($old_pds) || $old_handle != $handle)) { - $pds = bluesky_get_pds($did); + $pds = DI::atProtocol()->getPdsOfDid($did); if (empty($pds)) { - DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'bluesky', 'status', BLUEKSY_STATUS_PDS_FAIL); + DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'bluesky', 'status', ATProtocol::STATUS_PDS_FAIL); } DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'bluesky', 'pds', $pds); } else { @@ -466,6 +378,7 @@ function bluesky_settings_post(array &$b) } else { DI::pConfig()->delete(DI::userSession()->getLocalUserId(), 'bluesky', 'did'); DI::pConfig()->delete(DI::userSession()->getLocalUserId(), 'bluesky', 'pds'); + DI::pConfig()->delete(DI::userSession()->getLocalUserId(), 'bluesky', 'password'); DI::pConfig()->delete(DI::userSession()->getLocalUserId(), 'bluesky', 'access_token'); DI::pConfig()->delete(DI::userSession()->getLocalUserId(), 'bluesky', 'refresh_token'); DI::pConfig()->delete(DI::userSession()->getLocalUserId(), 'bluesky', 'token_created'); @@ -473,7 +386,7 @@ function bluesky_settings_post(array &$b) } if (!empty($did) && !empty($pds) && !empty($_POST['bluesky_password'])) { - bluesky_create_token(DI::userSession()->getLocalUserId(), $_POST['bluesky_password']); + DI::atProtocol()->createUserToken(DI::userSession()->getLocalUserId(), $_POST['bluesky_password']); } } @@ -507,11 +420,11 @@ function bluesky_cron() if ($last) { $next = $last + ($poll_interval * 60); if ($next > time()) { - Logger::notice('poll interval not reached'); + DI::logger()->notice('poll interval not reached'); return; } } - Logger::notice('cron_start'); + DI::logger()->notice('cron_start'); $abandon_days = intval(DI::config()->get('system', 'account_abandon_days')); if ($abandon_days < 1) { @@ -522,53 +435,59 @@ function bluesky_cron() $pconfigs = DBA::selectToArray('pconfig', [], ["`cat` = ? AND `k` IN (?, ?) AND `v`", 'bluesky', 'import', 'import_feeds']); foreach ($pconfigs as $pconfig) { - if (empty(bluesky_get_user_did($pconfig['uid']))) { - Logger::debug('User has got no valid DID', ['uid' => $pconfig['uid']]); + if (empty(DI::atProtocol()->getUserDid($pconfig['uid']))) { + DI::logger()->debug('User has got no valid DID', ['uid' => $pconfig['uid']]); continue; } if ($abandon_days != 0) { if (!DBA::exists('user', ["`uid` = ? AND `login_date` >= ?", $pconfig['uid'], $abandon_limit])) { - Logger::notice('abandoned account: timeline from user will not be imported', ['user' => $pconfig['uid']]); + DI::logger()->notice('abandoned account: timeline from user will not be imported', ['user' => $pconfig['uid']]); continue; } } // Refresh the token now, so that it doesn't need to be refreshed in parallel by the following workers - Logger::debug('Refresh the token', ['uid' => $pconfig['uid']]); - bluesky_get_token($pconfig['uid']); + DI::logger()->debug('Refresh the token', ['uid' => $pconfig['uid']]); + DI::atProtocol()->getUserToken($pconfig['uid']); + + $last_sync = DI::pConfig()->get($pconfig['uid'], 'bluesky', 'last_contact_sync'); + if ($last_sync < (time() - 86400)) { + DI::atpActor()->syncContacts($pconfig['uid']); + DI::pConfig()->set($pconfig['uid'], 'bluesky', 'last_contact_sync', time()); + } Worker::add(['priority' => Worker::PRIORITY_MEDIUM, 'force_priority' => true], 'addon/bluesky/bluesky_notifications.php', $pconfig['uid']); if (DI::pConfig()->get($pconfig['uid'], 'bluesky', 'import')) { Worker::add(['priority' => Worker::PRIORITY_MEDIUM, 'force_priority' => true], 'addon/bluesky/bluesky_timeline.php', $pconfig['uid']); } if (DI::pConfig()->get($pconfig['uid'], 'bluesky', 'import_feeds')) { - Logger::debug('Fetch feeds for user', ['uid' => $pconfig['uid']]); + DI::logger()->debug('Fetch feeds for user', ['uid' => $pconfig['uid']]); $feeds = bluesky_get_feeds($pconfig['uid']); foreach ($feeds as $feed) { Worker::add(['priority' => Worker::PRIORITY_MEDIUM, 'force_priority' => true], 'addon/bluesky/bluesky_feed.php', $pconfig['uid'], $feed); } } - Logger::debug('Polling done for user', ['uid' => $pconfig['uid']]); + DI::logger()->debug('Polling done for user', ['uid' => $pconfig['uid']]); } - Logger::notice('Polling done for all users'); + DI::logger()->notice('Polling done for all users'); DI::keyValue()->set('bluesky_last_poll', time()); $last_clean = DI::keyValue()->get('bluesky_last_clean'); if (empty($last_clean) || ($last_clean + 86400 < time())) { - Logger::notice('Start contact cleanup'); + DI::logger()->notice('Start contact cleanup'); $contacts = DBA::select('account-user-view', ['id', 'pid'], ["`network` = ? AND `uid` != ? AND `rel` = ?", Protocol::BLUESKY, 0, Contact::NOTHING]); while ($contact = DBA::fetch($contacts)) { Worker::add(Worker::PRIORITY_LOW, 'MergeContact', $contact['pid'], $contact['id'], 0); } DBA::close($contacts); DI::keyValue()->set('bluesky_last_clean', time()); - Logger::notice('Contact cleanup done'); + DI::logger()->notice('Contact cleanup done'); } - Logger::notice('cron_end'); + DI::logger()->notice('cron_end'); } function bluesky_hook_fork(array &$b) @@ -588,7 +507,7 @@ function bluesky_hook_fork(array &$b) if (DI::pConfig()->get($post['uid'], 'bluesky', 'import')) { // Don't post if it isn't a reply to a bluesky post if (($post['gravity'] != Item::GRAVITY_PARENT) && !Post::exists(['id' => $post['parent'], 'network' => Protocol::BLUESKY])) { - Logger::notice('No bluesky parent found', ['item' => $post['id']]); + DI::logger()->notice('No bluesky parent found', ['item' => $post['id']]); $b['execute'] = false; return; } @@ -635,28 +554,28 @@ function bluesky_send(array &$b) } if ($b['gravity'] != Item::GRAVITY_PARENT) { - Logger::debug('Got comment', ['item' => $b]); + DI::logger()->debug('Got comment', ['item' => $b]); if ($b['deleted']) { - $uri = bluesky_get_uri_class($b['uri']); + $uri = DI::atpProcessor()->getUriClass($b['uri']); if (empty($uri)) { - Logger::debug('Not a bluesky post', ['uri' => $b['uri']]); + DI::logger()->debug('Not a bluesky post', ['uri' => $b['uri']]); return; } bluesky_delete_post($b['uri'], $b['uid']); return; } - $root = bluesky_get_uri_class($b['parent-uri']); - $parent = bluesky_get_uri_class($b['thr-parent']); + $root = DI::atpProcessor()->getUriClass($b['parent-uri']); + $parent = DI::atpProcessor()->getUriClass($b['thr-parent']); if (empty($root) || empty($parent)) { - Logger::debug('No bluesky post', ['parent' => $b['parent'], 'thr-parent' => $b['thr-parent']]); + DI::logger()->debug('No bluesky post', ['parent' => $b['parent'], 'thr-parent' => $b['thr-parent']]); return; } if ($b['gravity'] == Item::GRAVITY_COMMENT) { - Logger::debug('Posting comment', ['root' => $root, 'parent' => $parent]); + DI::logger()->debug('Posting comment', ['root' => $root, 'parent' => $parent]); bluesky_create_post($b, $root, $parent); return; } elseif (in_array($b['verb'], [Activity::LIKE, Activity::ANNOUNCE])) { @@ -673,12 +592,12 @@ function bluesky_send(array &$b) function bluesky_create_activity(array $item, stdClass $parent = null) { $uid = $item['uid']; - $token = bluesky_get_token($uid); + $token = DI::atProtocol()->getUserToken($uid); if (empty($token)) { return; } - $did = bluesky_get_user_did($uid); + $did = DI::atProtocol()->getUserDid($uid); if (empty($did)) { return; } @@ -711,20 +630,20 @@ function bluesky_create_activity(array $item, stdClass $parent = null) ]; } - $activity = bluesky_xrpc_post($uid, 'com.atproto.repo.createRecord', $post); + $activity = DI::atProtocol()->XRPCPost($uid, 'com.atproto.repo.createRecord', $post); if (empty($activity->uri)) { return; } - Logger::debug('Activity done', ['return' => $activity]); - $uri = bluesky_get_uri($activity); - Item::update(['extid' => $uri], ['id' => $item['id']]); - Logger::debug('Set extid', ['id' => $item['id'], 'extid' => $activity]); + DI::logger()->debug('Activity done', ['return' => $activity]); + $uri = DI::atpProcessor()->getUri($activity); + Item::update(['extid' => $uri], ['guid' => $item['guid']]); + DI::logger()->debug('Set extid', ['id' => $item['id'], 'extid' => $activity]); } function bluesky_create_post(array $item, stdClass $root = null, stdClass $parent = null) { $uid = $item['uid']; - $token = bluesky_get_token($uid); + $token = DI::atProtocol()->getUserToken($uid); if (empty($token)) { return; } @@ -753,6 +672,8 @@ function bluesky_create_post(array $item, stdClass $root = null, stdClass $paren } } + $item['body'] = bluesky_set_mentions($item['body']); + $urls = bluesky_get_urls($item['body']); $item['body'] = $urls['body']; @@ -791,37 +712,64 @@ function bluesky_create_post(array $item, stdClass $root = null, stdClass $paren $post = [ 'collection' => 'app.bsky.feed.post', - 'repo' => bluesky_get_user_did($uid), + 'repo' => DI::atProtocol()->getUserDid($uid), 'record' => $record ]; - $parent = bluesky_xrpc_post($uid, 'com.atproto.repo.createRecord', $post); + $parent = DI::atProtocol()->XRPCPost($uid, 'com.atproto.repo.createRecord', $post); if (empty($parent->uri)) { if ($part == 0) { Worker::defer(); } return; } - Logger::debug('Posting done', ['return' => $parent]); + DI::logger()->debug('Posting done', ['return' => $parent]); if (empty($root)) { $root = $parent; } if (($key == 0) && ($item['gravity'] != Item::GRAVITY_PARENT)) { - $uri = bluesky_get_uri($parent); - Item::update(['extid' => $uri], ['id' => $item['id']]); - Logger::debug('Set extid', ['id' => $item['id'], 'extid' => $uri]); + $uri = DI::atpProcessor()->getUri($parent); + Item::update(['extid' => $uri], ['guid' => $item['guid']]); + DI::logger()->debug('Set extid', ['id' => $item['id'], 'extid' => $uri]); } } } -function bluesky_get_urls(string $body): array +function bluesky_set_mentions(string $body): string { - // Remove all hashtag and mention links + // Remove all url based mention links $body = preg_replace("/([@!])\[url\=(.*?)\](.*?)\[\/url\]/ism", '$1$3', $body); + if (!preg_match_all("/[@!]\[url\=(did:.*?)\](.*?)\[\/url\]/ism", $body, $matches, PREG_SET_ORDER)) { + return $body; + } + + foreach ($matches as $match) { + $contact = Contact::selectFirst(['addr'], ['nurl' => $match[1]]); + if (!empty($contact['addr'])) { + $body = str_replace($match[0], '@[url=' . $match[1] . ']' . $contact['addr'] . '[/url]', $body); + } else { + $body = str_replace($match[0], '@' . $match[2], $body); + } + } + + return $body; +} + +function bluesky_get_urls(string $body): array +{ $body = BBCode::expandVideoLinks($body); $urls = []; + // Search for Mentions + if (preg_match_all("/[@!]\[url\=(did:.*?)\](.*?)\[\/url\]/ism", $body, $matches, PREG_SET_ORDER)) { + foreach ($matches as $match) { + $text = '@' . $match[2]; + $urls[strpos($body, $match[0])] = ['mention' => $match[1], 'text' => $text, 'hash' => $text]; + $body = str_replace($match[0], $text, $body); + } + } + // Search for hash tags if (preg_match_all("/#\[url\=(https?:.*?)\](.*?)\[\/url\]/ism", $body, $matches, PREG_SET_ORDER)) { foreach ($matches as $match) { @@ -906,6 +854,9 @@ function bluesky_get_facets(string $body, array $urls): array } elseif (!empty($url['url'])) { $feature->uri = $url['url']; $feature->$type = 'app.bsky.richtext.facet#link'; + } elseif (!empty($url['mention'])) { + $feature->did = $url['mention']; + $feature->$type = 'app.bsky.richtext.facet#mention'; } else { continue; } @@ -930,7 +881,14 @@ function bluesky_add_embed(int $uid, array $msg, array $record): array if (empty($blob)) { return []; } - $images[] = ['alt' => $image['description'] ?? '', 'image' => $blob]; + $images[] = [ + 'alt' => $image['description'] ?? '', + 'image' => $blob, + 'aspectRatio' => [ + 'width' => $photo['width'], + 'height' => $photo['height'], + ] + ]; } if (!empty($images)) { $record['embed'] = ['$type' => 'app.bsky.embed.images', 'images' => $images]; @@ -968,36 +926,41 @@ function bluesky_upload_blob(int $uid, array $photo): ?stdClass $picture = Photo::resizeToFileSize($picture, BLUESKY_IMAGE_SIZE[$retrial]); $new_height = $picture->getHeight(); $new_width = $picture->getWidth(); - $content = $picture->asString(); + $content = (string)$picture->asString(); $new_size = strlen($content); - Logger::info('Uploading', ['uid' => $uid, 'retrial' => $retrial, 'height' => $new_height, 'width' => $new_width, 'size' => $new_size, 'orig-height' => $height, 'orig-width' => $width, 'orig-size' => $size]); + if (($size != 0) && ($new_size == 0) && ($retrial == 0)) { + DI::logger()->warning('Size is empty after resize, uploading original file', ['uid' => $uid, 'retrial' => $retrial, 'height' => $new_height, 'width' => $new_width, 'size' => $new_size, 'orig-height' => $height, 'orig-width' => $width, 'orig-size' => $size]); + $content = Photo::getImageForPhoto($photo); + } else { + DI::logger()->info('Uploading', ['uid' => $uid, 'retrial' => $retrial, 'height' => $new_height, 'width' => $new_width, 'size' => $new_size, 'orig-height' => $height, 'orig-width' => $width, 'orig-size' => $size]); + } - $data = bluesky_post($uid, '/xrpc/com.atproto.repo.uploadBlob', $content, ['Content-type' => $photo['type'], 'Authorization' => ['Bearer ' . bluesky_get_token($uid)]]); + $data = DI::atProtocol()->post($uid, '/xrpc/com.atproto.repo.uploadBlob', $content, ['Content-type' => $photo['type'], 'Authorization' => ['Bearer ' . DI::atProtocol()->getUserToken($uid)]]); if (empty($data) || empty($data->blob)) { - Logger::info('Uploading failed', ['uid' => $uid, 'retrial' => $retrial, 'height' => $new_height, 'width' => $new_width, 'size' => $new_size, 'orig-height' => $height, 'orig-width' => $width, 'orig-size' => $size]); + DI::logger()->info('Uploading failed', ['uid' => $uid, 'retrial' => $retrial, 'height' => $new_height, 'width' => $new_width, 'size' => $new_size, 'orig-height' => $height, 'orig-width' => $width, 'orig-size' => $size]); return null; } Item::incrementOutbound(Protocol::BLUESKY); - Logger::debug('Uploaded blob', ['return' => $data, 'uid' => $uid, 'retrial' => $retrial, 'height' => $new_height, 'width' => $new_width, 'size' => $new_size, 'orig-height' => $height, 'orig-width' => $width, 'orig-size' => $size]); + DI::logger()->debug('Uploaded blob', ['return' => $data, 'uid' => $uid, 'retrial' => $retrial, 'height' => $new_height, 'width' => $new_width, 'size' => $new_size, 'orig-height' => $height, 'orig-width' => $width, 'orig-size' => $size]); return $data->blob; } function bluesky_delete_post(string $uri, int $uid) { - $parts = bluesky_get_uri_parts($uri); + $parts = DI::atpProcessor()->getUriParts($uri); if (empty($parts)) { - Logger::debug('No uri delected', ['uri' => $uri]); + DI::logger()->debug('No uri delected', ['uri' => $uri]); return; } - bluesky_xrpc_post($uid, 'com.atproto.repo.deleteRecord', $parts); - Logger::debug('Deleted', ['parts' => $parts]); + DI::atProtocol()->XRPCPost($uid, 'com.atproto.repo.deleteRecord', $parts); + DI::logger()->debug('Deleted', ['parts' => $parts]); } function bluesky_fetch_timeline(int $uid) { - $data = bluesky_xrpc_get($uid, 'app.bsky.feed.getTimeline'); + $data = DI::atProtocol()->XRPCGet('app.bsky.feed.getTimeline', [], $uid); if (empty($data)) { return; } @@ -1006,42 +969,39 @@ function bluesky_fetch_timeline(int $uid) return; } - $last_post = DBA::selectFirst('post-thread-user', ['received'], ['network' => Protocol::BLUESKY, 'uid' => $uid], ['order' => ['received' => true]]); - $last_poll = !empty($last_post['received']) ? strtotime($last_post['received']) : 0; - foreach (array_reverse($data->feed) as $entry) { - $causer = bluesky_get_contact($entry->post->author, 0, $uid); + $causer = DI::atpActor()->getContactByDID($entry->post->author->did, $uid, 0, true); if (!empty($entry->reply)) { if (!empty($entry->reply->root)) { - bluesky_complete_post($entry->reply->root, $uid, Item::PR_COMMENT, $causer['id'], $last_poll, Conversation::PARCEL_CONNECTOR); + bluesky_complete_post($entry->reply->root, $uid, Item::PR_COMMENT, $causer['id'], Conversation::PARCEL_CONNECTOR); } if (!empty($entry->reply->parent)) { - bluesky_complete_post($entry->reply->parent, $uid, Item::PR_COMMENT, $causer['id'], $last_poll, Conversation::PARCEL_CONNECTOR); + bluesky_complete_post($entry->reply->parent, $uid, Item::PR_COMMENT, $causer['id'], Conversation::PARCEL_CONNECTOR); } } - bluesky_process_post($entry->post, $uid, $uid, Item::PR_NONE, 0, 0, $last_poll, Conversation::PARCEL_CONNECTOR); + DI::atpProcessor()->processPost($entry->post, $uid, Item::PR_NONE, 0, 0, Conversation::PARCEL_CONNECTOR); if (!empty($entry->reason)) { - bluesky_process_reason($entry->reason, bluesky_get_uri($entry->post), $uid); + bluesky_process_reason($entry->reason, DI::atpProcessor()->getUri($entry->post), $uid); } } } -function bluesky_complete_post(stdClass $post, int $uid, int $post_reason, int $causer, int $last_poll, int $protocol): int +function bluesky_complete_post(stdClass $post, int $uid, int $post_reason, int $causer, int $protocol): int { $complete = DI::pConfig()->get($uid, 'bluesky', 'complete_threads'); - $existing_uri = bluesky_fetch_post(bluesky_get_uri($post), $uid); + $existing_uri = DI::atpProcessor()->getPostUri(DI::atpProcessor()->getUri($post), $uid); if (!empty($existing_uri)) { $comments = Post::countPosts(['thr-parent' => $existing_uri, 'gravity' => Item::GRAVITY_COMMENT]); if (($post->replyCount <= $comments) || !$complete) { - return bluesky_fetch_uri_id($existing_uri, $uid); + return DI::atpProcessor()->fetchUriId($existing_uri, $uid); } } if ($complete) { - $uri = bluesky_fetch_missing_post(bluesky_get_uri($post), $uid, $uid, $post_reason, $causer, 0, $last_poll, '', true); - $uri_id = bluesky_fetch_uri_id($uri, $uid); + $uri = DI::atpProcessor()->fetchMissingPost(DI::atpProcessor()->getUri($post), $uid, $post_reason, $causer, 0, '', true, $protocol); + $uri_id = DI::atpProcessor()->fetchUriId($uri, $uid); } else { - $uri_id = bluesky_process_post($post, $uid, $uid, $post_reason, $causer, 0, $last_poll, $protocol); + $uri_id = DI::atpProcessor()->processPost($post, $uid, $post_reason, $causer, 0, $protocol); } return $uri_id; } @@ -1053,7 +1013,7 @@ function bluesky_process_reason(stdClass $reason, string $uri, int $uid) return; } - $contact = bluesky_get_contact($reason->by, $uid, $uid); + $contact = DI::atpActor()->getContactByDID($reason->by->did, $uid, 0); $item = [ 'network' => Protocol::BLUESKY, @@ -1077,6 +1037,10 @@ function bluesky_process_reason(stdClass $reason, string $uri, int $uid) return; } + if (Post::exists(['uid' => $item['uid'], 'thr-parent' => $item['thr-parent'], 'verb' => $item['verb'], 'contact-id' => $item['contact-id']])) { + return; + } + $item['guid'] = Item::guidFromUri($item['uri'], $contact['alias']); $item['owner-name'] = $item['author-name']; $item['owner-link'] = $item['author-link']; @@ -1089,75 +1053,72 @@ function bluesky_process_reason(stdClass $reason, string $uri, int $uid) function bluesky_fetch_notifications(int $uid) { - $data = bluesky_xrpc_get($uid, 'app.bsky.notification.listNotifications'); + $data = DI::atProtocol()->XRPCGet('app.bsky.notification.listNotifications', [], $uid); if (empty($data->notifications)) { return; } - $last_post = DBA::selectFirst('post-thread-user', ['received'], ['network' => Protocol::BLUESKY, 'uid' => $uid], ['order' => ['received' => true]]); - $last_poll = !empty($last_post['received']) ? strtotime($last_post['received']) : 0; - foreach ($data->notifications as $notification) { - $uri = bluesky_get_uri($notification); + $uri = DI::atpProcessor()->getUri($notification); if (Post::exists(['uri' => $uri, 'uid' => $uid]) || Post::exists(['extid' => $uri, 'uid' => $uid])) { - Logger::debug('Notification already processed', ['uid' => $uid, 'reason' => $notification->reason, 'uri' => $uri, 'indexedAt' => $notification->indexedAt]); + DI::logger()->debug('Notification already processed', ['uid' => $uid, 'reason' => $notification->reason, 'uri' => $uri, 'indexedAt' => $notification->indexedAt]); continue; } - Logger::debug('Process notification', ['uid' => $uid, 'reason' => $notification->reason, 'uri' => $uri, 'indexedAt' => $notification->indexedAt]); + DI::logger()->debug('Process notification', ['uid' => $uid, 'reason' => $notification->reason, 'uri' => $uri, 'indexedAt' => $notification->indexedAt]); switch ($notification->reason) { case 'like': - $item = bluesky_get_header($notification, $uri, $uid, $uid, $last_poll, Conversation::PARCEL_CONNECTOR); + $item = DI::atpProcessor()->getHeaderFromPost($notification, $uri, $uid, Conversation::PARCEL_CONNECTOR); $item['gravity'] = Item::GRAVITY_ACTIVITY; $item['body'] = $item['verb'] = Activity::LIKE; - $item['thr-parent'] = bluesky_get_uri($notification->record->subject); - $item['thr-parent'] = bluesky_fetch_missing_post($item['thr-parent'], $uid, $uid, Item::PR_FETCHED, $item['contact-id'], 0, $last_poll); + $item['thr-parent'] = DI::atpProcessor()->getUri($notification->record->subject); + $item['thr-parent'] = DI::atpProcessor()->fetchMissingPost($item['thr-parent'], $uid, Item::PR_FETCHED, $item['contact-id'], 0); if (!empty($item['thr-parent'])) { $data = Item::insert($item); - Logger::debug('Got like', ['uid' => $uid, 'result' => $data, 'uri' => $uri]); + DI::logger()->debug('Got like', ['uid' => $uid, 'result' => $data, 'uri' => $uri]); } else { - Logger::info('Thread parent not found', ['uid' => $uid, 'parent' => $item['thr-parent'], 'uri' => $uri]); + DI::logger()->info('Thread parent not found', ['uid' => $uid, 'parent' => $item['thr-parent'], 'uri' => $uri]); } break; case 'repost': - $item = bluesky_get_header($notification, $uri, $uid, $uid, $last_poll, Conversation::PARCEL_CONNECTOR); + $item = DI::atpProcessor()->getHeaderFromPost($notification, $uri, $uid, Conversation::PARCEL_CONNECTOR); $item['gravity'] = Item::GRAVITY_ACTIVITY; $item['body'] = $item['verb'] = Activity::ANNOUNCE; - $item['thr-parent'] = bluesky_get_uri($notification->record->subject); - $item['thr-parent'] = bluesky_fetch_missing_post($item['thr-parent'], $uid, $uid, Item::PR_FETCHED, $item['contact-id'], 0, $last_poll); + $item['thr-parent'] = DI::atpProcessor()->getUri($notification->record->subject); + $item['thr-parent'] = DI::atpProcessor()->fetchMissingPost($item['thr-parent'], $uid, Item::PR_FETCHED, $item['contact-id'], 0); if (!empty($item['thr-parent'])) { $data = Item::insert($item); - Logger::debug('Got repost', ['uid' => $uid, 'result' => $data, 'uri' => $uri]); + DI::logger()->debug('Got repost', ['uid' => $uid, 'result' => $data, 'uri' => $uri]); } else { - Logger::info('Thread parent not found', ['uid' => $uid, 'parent' => $item['thr-parent'], 'uri' => $uri]); + DI::logger()->info('Thread parent not found', ['uid' => $uid, 'parent' => $item['thr-parent'], 'uri' => $uri]); } break; case 'follow': - $contact = bluesky_get_contact($notification->author, $uid, $uid); - Logger::debug('New follower', ['uid' => $uid, 'nick' => $contact['nick'], 'uri' => $uri]); + $contact = DI::atpActor()->getContactByDID($notification->author->did, $uid, $uid); + DI::logger()->debug('New follower', ['uid' => $uid, 'nick' => $contact['nick'], 'uri' => $uri]); break; case 'mention': - $contact = bluesky_get_contact($notification->author, 0, $uid); - $result = bluesky_fetch_missing_post($uri, $uid, $uid, Item::PR_TO, $contact['id'], 0, $last_poll); - Logger::debug('Got mention', ['uid' => $uid, 'nick' => $contact['nick'], 'result' => $result, 'uri' => $uri]); + $contact = DI::atpActor()->getContactByDID($notification->author->did, $uid, 0); + $result = DI::atpProcessor()->fetchMissingPost($uri, $uid, Item::PR_TO, $contact['id'], 0); + DI::logger()->debug('Got mention', ['uid' => $uid, 'nick' => $contact['nick'], 'result' => $result, 'uri' => $uri]); break; case 'reply': - $contact = bluesky_get_contact($notification->author, 0, $uid); - $result = bluesky_fetch_missing_post($uri, $uid, $uid, Item::PR_COMMENT, $contact['id'], 0, $last_poll); - Logger::debug('Got reply', ['uid' => $uid, 'nick' => $contact['nick'], 'result' => $result, 'uri' => $uri]); + $contact = DI::atpActor()->getContactByDID($notification->author->did, $uid, 0); + $result = DI::atpProcessor()->fetchMissingPost($uri, $uid, Item::PR_COMMENT, $contact['id'], 0); + DI::logger()->debug('Got reply', ['uid' => $uid, 'nick' => $contact['nick'], 'result' => $result, 'uri' => $uri]); break; case 'quote': - $contact = bluesky_get_contact($notification->author, 0, $uid); - $result = bluesky_fetch_missing_post($uri, $uid, $uid, Item::PR_PUSHED, $contact['id'], 0, $last_poll); - Logger::debug('Got quote', ['uid' => $uid, 'nick' => $contact['nick'], 'result' => $result, 'uri' => $uri]); + $contact = DI::atpActor()->getContactByDID($notification->author->did, $uid, 0); + $result = DI::atpProcessor()->fetchMissingPost($uri, $uid, Item::PR_PUSHED, $contact['id'], 0); + DI::logger()->debug('Got quote', ['uid' => $uid, 'nick' => $contact['nick'], 'result' => $result, 'uri' => $uri]); break; default: - Logger::notice('Unhandled reason', ['reason' => $notification->reason, 'uri' => $uri]); + DI::logger()->notice('Unhandled reason', ['reason' => $notification->reason, 'uri' => $uri]); break; } } @@ -1165,7 +1126,7 @@ function bluesky_fetch_notifications(int $uid) function bluesky_fetch_feed(int $uid, string $feed) { - $data = bluesky_xrpc_get($uid, 'app.bsky.feed.getFeed', ['feed' => $feed]); + $data = DI::atProtocol()->XRPCGet('app.bsky.feed.getFeed', ['feed' => $feed], $uid); if (empty($data)) { return; } @@ -1174,10 +1135,7 @@ function bluesky_fetch_feed(int $uid, string $feed) return; } - $last_post = DBA::selectFirst('post-thread-user', ['received'], ['network' => Protocol::BLUESKY, 'uid' => $uid], ['order' => ['received' => true]]); - $last_poll = !empty($last_post['received']) ? strtotime($last_post['received']) : 0; - - $feeddata = bluesky_xrpc_get($uid, 'app.bsky.feed.getFeedGenerator', ['feed' => $feed]); + $feeddata = DI::atProtocol()->XRPCGet('app.bsky.feed.getFeedGenerator', ['feed' => $feed], $uid); if (!empty($feeddata) && !empty($feeddata->view)) { $feedurl = $feeddata->view->uri; $feedname = $feeddata->view->displayName; @@ -1187,657 +1145,27 @@ function bluesky_fetch_feed(int $uid, string $feed) } foreach (array_reverse($data->feed) as $entry) { - $contact = bluesky_get_contact($entry->post->author, 0, $uid); + $contact = DI::atpActor()->getContactByDID($entry->post->author->did, $uid, 0); $languages = $entry->post->record->langs ?? []; if (!Relay::isWantedLanguage($entry->post->record->text, 0, $contact['id'] ?? 0, $languages)) { - Logger::debug('Unwanted language detected', ['languages' => $languages, 'text' => $entry->post->record->text]); + DI::logger()->debug('Unwanted language detected', ['languages' => $languages, 'text' => $entry->post->record->text]); continue; } - $causer = bluesky_get_contact($entry->post->author, 0, $uid); - $uri_id = bluesky_complete_post($entry->post, $uid, Item::PR_TAG, $causer['id'], $last_poll, Conversation::PARCEL_CONNECTOR); + $causer = DI::atpActor()->getContactByDID($entry->post->author->did, $uid, 0); + $uri_id = bluesky_complete_post($entry->post, $uid, Item::PR_TAG, $causer['id'], Conversation::PARCEL_CONNECTOR); if (!empty($uri_id)) { $stored = Post\Category::storeFileByURIId($uri_id, $uid, Post\Category::SUBCRIPTION, $feedname, $feedurl); - Logger::debug('Stored tag subscription for user', ['uri-id' => $uri_id, 'uid' => $uid, 'name' => $feedname, 'url' => $feedurl, 'stored' => $stored]); + DI::logger()->debug('Stored tag subscription for user', ['uri-id' => $uri_id, 'uid' => $uid, 'name' => $feedname, 'url' => $feedurl, 'stored' => $stored]); } else { - Logger::notice('Post not found', ['entry' => $entry]); + DI::logger()->notice('Post not found', ['entry' => $entry]); } if (!empty($entry->reason)) { - bluesky_process_reason($entry->reason, bluesky_get_uri($entry->post), $uid); + bluesky_process_reason($entry->reason, DI::atpProcessor()->getUri($entry->post), $uid); } } } -function bluesky_process_post(stdClass $post, int $uid, int $fetch_uid, int $post_reason, int $causer, int $level, int $last_poll, int $protocol): int -{ - $uri = bluesky_get_uri($post); - - if ($uri_id = bluesky_fetch_uri_id($uri, $uid)) { - return $uri_id; - } - - if (empty($post->record)) { - Logger::debug('Invalid post', ['uri' => $uri]); - return 0; - } - - Logger::debug('Importing post', ['uid' => $uid, 'indexedAt' => $post->indexedAt, 'uri' => $post->uri, 'cid' => $post->cid, 'root' => $post->record->reply->root ?? '']); - - $item = bluesky_get_header($post, $uri, $uid, $fetch_uid, $last_poll, $protocol); - $item = bluesky_get_content($item, $post->record, $uri, $uid, $fetch_uid, $level, $last_poll); - if (empty($item)) { - return 0; - } - - if (!empty($post->embed)) { - $item = bluesky_add_media($post->embed, $item, $uid, $level, $last_poll); - } - - $item['restrictions'] = bluesky_get_restrictions_for_user($post, $item, $post_reason); - - if (empty($item['post-reason'])) { - $item['post-reason'] = $post_reason; - } - - if ($causer != 0) { - $item['causer-id'] = $causer; - } - - Item::insert($item); - return bluesky_fetch_uri_id($uri, $uid); -} - -function bluesky_get_header(stdClass $post, string $uri, int $uid, int $fetch_uid, int $last_poll, int $protocol): array -{ - $parts = bluesky_get_uri_parts($uri); - if (empty($post->author) || empty($post->cid) || empty($parts->rkey)) { - return []; - } - $contact = bluesky_get_contact($post->author, $uid, $fetch_uid); - $item = [ - 'network' => Protocol::BLUESKY, - 'protocol' => $protocol, - 'uid' => $uid, - 'wall' => false, - 'uri' => $uri, - 'guid' => $post->cid, - 'received' => DateTimeFormat::utc($post->indexedAt, DateTimeFormat::MYSQL), - 'private' => Item::UNLISTED, - 'verb' => Activity::POST, - 'contact-id' => $contact['id'], - 'author-name' => $contact['name'], - 'author-link' => $contact['url'], - 'author-avatar' => $contact['avatar'], - 'plink' => $contact['alias'] . '/post/' . $parts->rkey, - 'source' => json_encode($post), - ]; - - if (($last_poll != 0) && strtotime($item['received']) < $last_poll) { - unset($item['received']); - } - - $account = Contact::selectFirstAccountUser(['pid'], ['id' => $contact['id']]); - - $item['author-id'] = $account['pid']; - $item['uri-id'] = ItemURI::getIdByURI($uri); - $item['owner-id'] = $item['author-id']; - $item['owner-name'] = $item['author-name']; - $item['owner-link'] = $item['author-link']; - $item['owner-avatar'] = $item['author-avatar']; - - if (in_array($contact['rel'], [Contact::SHARING, Contact::FRIEND])) { - $item['post-reason'] = Item::PR_FOLLOWER; - } - - if (!empty($post->labels)) { - foreach ($post->labels as $label) { - // Only flag posts as sensitive based on labels that had been provided by the author. - // When "ver" is set to "1" it was flagged by some automated process. - if (empty($label->ver)) { - $item['sensitive'] = true; - $item['content-warning'] = $label->val ?? ''; - Logger::debug('Sensitive content', ['uri-id' => $item['uri-id'], 'label' => $label]); - } - } - } - - return $item; -} - -function bluesky_get_restrictions_for_user(stdClass $post, array $item, int $post_reason): ?int -{ - if (!empty($post->viewer->replyDisabled)) { - return Item::CANT_REPLY; - } - - if (empty($post->threadgate)) { - return null; - } - - if (!isset($post->threadgate->record->allow)) { - return null; - } - - if ($item['uid'] == 0) { - return Item::CANT_REPLY; - } - - $restrict = true; - $type = '$type'; - foreach ($post->threadgate->record->allow as $allow) { - switch ($allow->$type) { - case 'app.bsky.feed.threadgate#followingRule': - // Only followers can reply. - if (Contact::isFollower($item['author-id'], $item['uid'])) { - $restrict = false; - } - break; - case 'app.bsky.feed.threadgate#mentionRule': - // Only mentioned accounts can reply. - if ($post_reason == Item::PR_TO) { - $restrict = false; - } - break; - case 'app.bsky.feed.threadgate#listRule'; - // Only accounts in the provided list can reply. We don't support this at the moment. - break; - } - } - - return $restrict ? Item::CANT_REPLY : null; -} - -function bluesky_get_content(array $item, stdClass $record, string $uri, int $uid, int $fetch_uid, int $level, int $last_poll): array -{ - if (empty($item)) { - return []; - } - - if (!empty($record->reply)) { - $item['parent-uri'] = bluesky_get_uri($record->reply->root); - if ($item['parent-uri'] != $uri) { - $item['parent-uri'] = bluesky_fetch_missing_post($item['parent-uri'], $uid, $fetch_uid, Item::PR_FETCHED, $item['contact-id'], $level, $last_poll); - if (empty($item['parent-uri'])) { - return []; - } - } - - $item['thr-parent'] = bluesky_get_uri($record->reply->parent); - if (!in_array($item['thr-parent'], [$uri, $item['parent-uri']])) { - $item['thr-parent'] = bluesky_fetch_missing_post($item['thr-parent'], $uid, $fetch_uid, Item::PR_FETCHED, $item['contact-id'], $level, $last_poll, $item['parent-uri']); - if (empty($item['thr-parent'])) { - return []; - } - } - } - - $item['body'] = bluesky_get_text($record, $item['uri-id']); - $item['created'] = DateTimeFormat::utc($record->createdAt, DateTimeFormat::MYSQL); - $item['transmitted-languages'] = $record->langs ?? []; - - return $item; -} - -function bluesky_get_text(stdClass $record, int $uri_id): string -{ - $text = $record->text ?? ''; - - if (empty($record->facets)) { - return $text; - } - - $facets = []; - foreach ($record->facets as $facet) { - $facets[$facet->index->byteStart] = $facet; - } - krsort($facets); - - foreach ($facets as $facet) { - $prefix = substr($text, 0, $facet->index->byteStart); - $linktext = substr($text, $facet->index->byteStart, $facet->index->byteEnd - $facet->index->byteStart); - $suffix = substr($text, $facet->index->byteEnd); - - $url = ''; - $type = '$type'; - foreach ($facet->features as $feature) { - - switch ($feature->$type) { - case 'app.bsky.richtext.facet#link': - $url = $feature->uri; - break; - - case 'app.bsky.richtext.facet#mention': - $contact = Contact::getByURL($feature->did, null, ['id']); - if (!empty($contact['id'])) { - $url = DI::baseUrl() . '/contact/' . $contact['id']; - if (substr($linktext, 0, 1) == '@') { - $prefix .= '@'; - $linktext = substr($linktext, 1); - } - } - break; - - case 'app.bsky.richtext.facet#tag'; - Tag::store($uri_id, Tag::HASHTAG, $feature->tag); - $url = DI::baseUrl() . '/search?tag=' . urlencode($feature->tag); - $linktext = '#' . $feature->tag; - break; - - default: - Logger::notice('Unhandled feature type', ['type' => $feature->$type, 'feature' => $feature, 'record' => $record]); - break; - } - } - if (!empty($url)) { - $text = $prefix . '[url=' . $url . ']' . $linktext . '[/url]' . $suffix; - } - } - return $text; -} - -function bluesky_add_media(stdClass $embed, array $item, int $fetch_uid, int $level, int $last_poll): array -{ - $type = '$type'; - switch ($embed->$type) { - case 'app.bsky.embed.images#view': - foreach ($embed->images as $image) { - $media = [ - 'uri-id' => $item['uri-id'], - 'type' => Post\Media::IMAGE, - 'url' => $image->fullsize, - 'preview' => $image->thumb, - 'description' => $image->alt, - ]; - Post\Media::insert($media); - } - break; - - case 'app.bsky.embed.video#view': - $media = [ - 'uri-id' => $item['uri-id'], - 'type' => Post\Media::HLS, - 'url' => $embed->playlist, - 'preview' => $embed->thumbnail, - 'description' => $embed->alt ?? '', - 'height' => $embed->aspectRatio->height ?? null, - 'width' => $embed->aspectRatio->width ?? null, - ]; - Post\Media::insert($media); - break; - - case 'app.bsky.embed.external#view': - $media = [ - 'uri-id' => $item['uri-id'], - 'type' => Post\Media::HTML, - 'url' => $embed->external->uri, - 'name' => $embed->external->title, - 'description' => $embed->external->description, - ]; - Post\Media::insert($media); - break; - - case 'app.bsky.embed.record#view': - $original_uri = $uri = bluesky_get_uri($embed->record); - $type = '$type'; - if (!empty($embed->record->record->$type)) { - $embed_type = $embed->record->record->$type; - if ($embed_type == 'app.bsky.graph.starterpack') { - bluesky_add_starterpack($item, $embed->record); - break; - } - } - $fetched_uri = bluesky_fetch_post($uri, $item['uid']); - if (!$fetched_uri) { - $uri = bluesky_fetch_missing_post($uri, 0, $fetch_uid, Item::PR_FETCHED, $item['contact-id'], $level, $last_poll); - } else { - $uri = $fetched_uri; - } - if ($uri) { - $shared = Post::selectFirst(['uri-id'], ['uri' => $uri, 'uid' => [$item['uid'], 0]]); - $uri_id = $shared['uri-id'] ?? 0; - } - if (!empty($uri_id)) { - $item['quote-uri-id'] = $uri_id; - } else { - Logger::debug('Quoted post could not be fetched', ['original-uri' => $original_uri, 'uri' => $uri]); - } - break; - - case 'app.bsky.embed.recordWithMedia#view': - bluesky_add_media($embed->media, $item, $fetch_uid, $level, $last_poll); - $original_uri = $uri = bluesky_get_uri($embed->record->record); - $uri = bluesky_fetch_missing_post($uri, $item['uid'], $fetch_uid, Item::PR_FETCHED, $item['contact-id'], $level, $last_poll); - if ($uri) { - $shared = Post::selectFirst(['uri-id'], ['uri' => $uri, 'uid' => [$item['uid'], 0]]); - $uri_id = $shared['uri-id'] ?? 0; - } - if (!empty($uri_id)) { - $item['quote-uri-id'] = $uri_id; - } else { - Logger::debug('Quoted post could not be fetched', ['original-uri' => $original_uri, 'uri' => $uri]); - } - break; - - default: - Logger::notice('Unhandled embed type', ['uri-id' => $item['uri-id'], 'type' => $embed->$type, 'embed' => $embed]); - break; - } - return $item; -} - -function bluesky_add_starterpack(array $item, stdClass $record) -{ - Logger::debug('Received starterpack', ['uri-id' => $item['uri-id'], 'guid' => $item['guid'], 'uri' => $record->uri]); - if (!preg_match('#^at://(.+)/app.bsky.graph.starterpack/(.+)#', $record->uri, $matches)) { - return; - } - - $media = [ - 'uri-id' => $item['uri-id'], - 'type' => Post\Media::HTML, - 'url' => 'https://bsky.app/starter-pack/' . $matches[1] . '/' . $matches[2], - 'name' => $record->record->name, - 'description' => $record->record->description, - ]; - - Post\Media::insert($media); - - $fields = [ - 'name' => $record->record->name, - 'description' => $record->record->description, - ]; - Post\Media::update($fields, ['uri-id' => $media['uri-id'], 'url' => $media['url']]); -} - -function bluesky_get_uri(stdClass $post): string -{ - if (empty($post->cid)) { - Logger::info('Invalid URI', ['post' => $post]); - return ''; - } - return $post->uri . ':' . $post->cid; -} - -function bluesky_get_uri_class(string $uri): ?stdClass -{ - if (empty($uri)) { - return null; - } - - $elements = explode(':', $uri); - if ($elements[0] !== 'at') { - $post = Post::selectFirstPost(['extid'], ['uri' => $uri]); - return bluesky_get_uri_class($post['extid'] ?? ''); - } - - $class = new stdClass; - - $class->cid = array_pop($elements); - $class->uri = implode(':', $elements); - - if ((substr_count($class->uri, '/') == 2) && (substr_count($class->cid, '/') == 2)) { - $class->uri .= ':' . $class->cid; - $class->cid = ''; - } - - return $class; -} - -function bluesky_get_uri_parts(string $uri): ?stdClass -{ - $class = bluesky_get_uri_class($uri); - if (empty($class)) { - return null; - } - - $parts = explode('/', substr($class->uri, 5)); - - $class = new stdClass; - - $class->repo = $parts[0]; - $class->collection = $parts[1]; - $class->rkey = $parts[2]; - - return $class; -} - -function bluesky_fetch_missing_post(string $uri, int $uid, int $fetch_uid, int $post_reason, int $causer, int $level, int $last_poll, string $fallback = '', bool $always_fetch = false, int $Protocol = Conversation::PARCEL_CONNECTOR): string -{ - $fetched_uri = bluesky_fetch_post($uri, $uid); - if (!$always_fetch && !empty($fetched_uri)) { - return $fetched_uri; - } - - if (++$level > 100) { - Logger::info('Recursion level too deep', ['level' => $level, 'uid' => $uid, 'uri' => $uri, 'fallback' => $fallback]); - // When the level is too deep we will fallback to the parent uri. - // Allthough the threading won't be correct, we at least had stored all posts and won't try again - return $fallback; - } - - $class = bluesky_get_uri_class($uri); - if (empty($class)) { - return $fallback; - } - - $fetch_uri = $class->uri; - - Logger::debug('Fetch missing post', ['level' => $level, 'uid' => $uid, 'uri' => $uri]); - $data = bluesky_xrpc_get($fetch_uid, 'app.bsky.feed.getPostThread', ['uri' => $fetch_uri]); - if (empty($data) || empty($data->thread)) { - Logger::info('Thread was not fetched', ['level' => $level, 'uid' => $uid, 'uri' => $uri, 'fallback' => $fallback]); - return $fallback; - } - - Logger::debug('Reply count', ['level' => $level, 'uid' => $uid, 'uri' => $uri]); - - if ($causer != 0) { - $causer = Contact::getPublicContactId($causer, $uid); - } - - if (!empty($data->thread->parent)) { - $parents = bluesky_fetch_parents($data->thread->parent, $uid); - - foreach ($parents as $parent) { - $uri_id = bluesky_process_post($parent, $uid, $fetch_uid, Item::PR_FETCHED, $causer, $level, $last_poll, $Protocol); - Logger::debug('Parent created', ['uri-id' => $uri_id]); - } - } - - return bluesky_process_thread($data->thread, $uid, $fetch_uid, $post_reason, $causer, $level, $last_poll, $Protocol); -} - -function bluesky_fetch_parents(stdClass $parent, int $uid, array $parents = []): array -{ - if (!empty($parent->parent)) { - $parents = bluesky_fetch_parents($parent->parent, $uid, $parents); - } - - if (!empty($parent->post) && empty(bluesky_fetch_post(bluesky_get_uri($parent->post), $uid))) { - $parents[] = $parent->post; - } - - return $parents; -} - -function bluesky_fetch_post(string $uri, int $uid): string -{ - if (Post::exists(['uri' => $uri, 'uid' => [$uid, 0]])) { - Logger::debug('Post exists', ['uri' => $uri]); - return $uri; - } - - $reply = Post::selectFirst(['uri'], ['extid' => $uri, 'uid' => [$uid, 0]]); - if (!empty($reply['uri'])) { - Logger::debug('Post with extid exists', ['uri' => $uri]); - return $reply['uri']; - } - return ''; -} - -function bluesky_fetch_uri_id(string $uri, int $uid): string -{ - $reply = Post::selectFirst(['uri-id'], ['uri' => $uri, 'uid' => [$uid, 0]]); - if (!empty($reply['uri-id'])) { - Logger::debug('Post with extid exists', ['uri' => $uri]); - return $reply['uri-id']; - } - $reply = Post::selectFirst(['uri-id'], ['extid' => $uri, 'uid' => [$uid, 0]]); - if (!empty($reply['uri-id'])) { - Logger::debug('Post with extid exists', ['uri' => $uri]); - return $reply['uri-id']; - } - return 0; -} - -function bluesky_process_thread(stdClass $thread, int $uid, int $fetch_uid, int $post_reason, int $causer, int $level, int $last_poll, int $protocol): string -{ - if (empty($thread->post)) { - Logger::info('Invalid post', ['post' => $thread]); - return ''; - } - $uri = bluesky_get_uri($thread->post); - - $fetched_uri = bluesky_fetch_post($uri, $uid); - if (empty($fetched_uri)) { - $uri_id = bluesky_process_post($thread->post, $uid, $fetch_uid, $post_reason, $causer, $level, $last_poll, $protocol); - if ($uri_id) { - Logger::debug('Post has been processed and stored', ['uri-id' => $uri_id, 'uri' => $uri]); - return $uri; - } else { - Logger::info('Post has not not been stored', ['uri' => $uri]); - return ''; - } - } else { - Logger::debug('Post exists', ['uri' => $uri]); - $uri = $fetched_uri; - } - - foreach ($thread->replies ?? [] as $reply) { - $reply_uri = bluesky_process_thread($reply, $uid, $fetch_uid, Item::PR_FETCHED, $causer, $level, $last_poll, $protocol); - Logger::debug('Reply has been processed', ['uri' => $uri, 'reply' => $reply_uri]); - } - - return $uri; -} - -function bluesky_get_contact(stdClass $author, int $uid, int $fetch_uid): array -{ - $condition = ['network' => Protocol::BLUESKY, 'uid' => 0, 'nurl' => $author->did]; - $contact = Contact::selectFirst(['id', 'updated'], $condition); - - $update = empty($contact) || $contact['updated'] < DateTimeFormat::utc('now -24 hours'); - - $public_fields = $fields = bluesky_get_contact_fields($author, $uid, $fetch_uid, $update); - - $public_fields['uid'] = 0; - $public_fields['rel'] = Contact::NOTHING; - - if (empty($contact)) { - $cid = Contact::insert($public_fields); - } else { - $cid = $contact['id']; - Logger::debug('Update contact', ['fields' => $public_fields, 'id' => $cid]); - Contact::update($public_fields, ['id' => $cid], true); - } - - if ($uid != 0) { - $condition = ['network' => Protocol::BLUESKY, 'uid' => $uid, 'nurl' => $author->did]; - - $contact = Contact::selectFirst(['id', 'rel', 'uid'], $condition); - if (!isset($fields['rel']) && isset($contact['rel'])) { - $fields['rel'] = $contact['rel']; - } elseif (!isset($fields['rel'])) { - $fields['rel'] = Contact::NOTHING; - } - } - - if (($uid != 0) && ($fields['rel'] != Contact::NOTHING)) { - if (empty($contact)) { - $cid = Contact::insert($fields); - } else { - $cid = $contact['id']; - Logger::debug('Update contact', ['fields' => $fields, 'id' => $cid]); - Contact::update($fields, ['id' => $cid], true); - } - Logger::debug('Get user contact', ['id' => $cid, 'uid' => $uid, 'update' => $update]); - } else { - Logger::debug('Get public contact', ['id' => $cid, 'uid' => $uid, 'update' => $update]); - } - if (!empty($author->avatar)) { - Contact::updateAvatar($cid, $author->avatar); - } - - return Contact::getById($cid); -} - -function bluesky_get_contact_fields(stdClass $author, int $uid, int $fetch_uid, bool $update): array -{ - $nick = $author->handle ?? $author->did; - $name = $author->displayName ?? $nick; - $fields = [ - 'uid' => $uid, - 'network' => Protocol::BLUESKY, - 'priority' => 1, - 'writable' => true, - 'blocked' => false, - 'readonly' => false, - 'pending' => false, - 'url' => $author->did, - 'nurl' => $author->did, - 'alias' => BLUESKY_WEB . '/profile/' . $nick, - 'name' => $name ?: $nick, - 'nick' => $nick, - 'addr' => $nick, - ]; - - if (!$update) { - Logger::debug('Got contact fields', ['uid' => $uid, 'url' => $fields['url'], 'fields' => $fields]); - return $fields; - } - - $data = bluesky_get(BLUESKY_DIRECTORY . '/' . $author->did); - if (!empty($data)) { - $fields['baseurl'] = bluesky_get_pds('', $data); - if (!empty($fields['baseurl'])) { - GServer::check($fields['baseurl'], Protocol::BLUESKY); - $fields['gsid'] = GServer::getID($fields['baseurl'], true); - } - $fields['pubkey'] = bluesky_get_public_key('', $data); - } - - $data = bluesky_xrpc_get($fetch_uid, 'app.bsky.actor.getProfile', ['actor' => $author->did]); - if (empty($data)) { - Logger::debug('Error fetching contact fields', ['uid' => $uid, 'url' => $fields['url']]); - return $fields; - } - - $fields['updated'] = DateTimeFormat::utcNow(DateTimeFormat::MYSQL); - - if (!empty($data->description)) { - $fields['about'] = HTML::toBBCode($data->description); - } - - if (!empty($data->banner)) { - $fields['header'] = $data->banner; - } - - if (!empty($data->viewer)) { - if (!empty($data->viewer->following) && !empty($data->viewer->followedBy)) { - $fields['rel'] = Contact::FRIEND; - } elseif (!empty($data->viewer->following) && empty($data->viewer->followedBy)) { - $fields['rel'] = Contact::SHARING; - } elseif (empty($data->viewer->following) && !empty($data->viewer->followedBy)) { - $fields['rel'] = Contact::FOLLOWER; - } else { - $fields['rel'] = Contact::NOTHING; - } - } - - Logger::debug('Got updated contact fields', ['uid' => $uid, 'url' => $fields['url']]); - return $fields; -} - function bluesky_get_feeds(int $uid): array { $type = '$type'; @@ -1846,8 +1174,14 @@ function bluesky_get_feeds(int $uid): array return []; } foreach ($preferences->preferences as $preference) { - if ($preference->$type == 'app.bsky.actor.defs#savedFeedsPref') { - return $preference->pinned ?? []; + if ($preference->$type == 'app.bsky.actor.defs#savedFeedsPrefV2') { + $pinned = []; + foreach ($preference->items as $item) { + if (($item->type == 'feed') && $item->pinned) { + $pinned[] = $item->value; + } + } + return $pinned; } } return []; @@ -1861,7 +1195,7 @@ function bluesky_get_preferences(int $uid): ?stdClass return $data; } - $data = bluesky_xrpc_get($uid, 'app.bsky.actor.getPreferences'); + $data = DI::atProtocol()->XRPCGet('app.bsky.actor.getPreferences', [], $uid); if (empty($data)) { return null; } @@ -1869,353 +1203,3 @@ function bluesky_get_preferences(int $uid): ?stdClass DI::cache()->set($cachekey, $data, Duration::HOUR); return $data; } - -function bluesky_get_did_by_profile(string $url, int $uid): string -{ - if (preg_match('#^' . BLUESKY_WEB . '/profile/(.+)#', $url, $matches)) { - $did = bluesky_get_did($matches[1], $uid); - if (!empty($did)) { - return $did; - } - } - try { - $curlResult = DI::httpClient()->get($url, HttpClientAccept::HTML, [HttpClientOptions::REQUEST => HttpClientRequest::CONTACTINFO]); - } catch (\Throwable $th) { - return ''; - } - if (!$curlResult->isSuccess()) { - return ''; - } - $profile = $curlResult->getBodyString(); - if (empty($profile)) { - return ''; - } - - $doc = new DOMDocument(); - try { - @$doc->loadHTML($profile); - } catch (\Throwable $th) { - return ''; - } - $xpath = new DOMXPath($doc); - $list = $xpath->query('//p[@id]'); - foreach ($list as $node) { - foreach ($node->attributes as $attribute) { - if ($attribute->name == 'id') { - $ids[$attribute->value] = $node->textContent; - } - } - } - - if (empty($ids['bsky_handle']) || empty($ids['bsky_did'])) { - return ''; - } - - if (!bluesky_valid_did($ids['bsky_did'], $ids['bsky_handle'])) { - Logger::notice('Invalid DID', ['handle' => $ids['bsky_handle'], 'did' => $ids['bsky_did']]); - return ''; - } - - return $ids['bsky_did']; -} - -function bluesky_get_did_by_wellknown(string $handle): string -{ - $curlResult = DI::httpClient()->get('http://' . $handle . '/.well-known/atproto-did'); - if ($curlResult->isSuccess() && substr($curlResult->getBodyString(), 0, 4) == 'did:') { - $did = $curlResult->getBodyString(); - if (!bluesky_valid_did($did, $handle)) { - Logger::notice('Invalid DID', ['handle' => $handle, 'did' => $did]); - return ''; - } - return $did; - } - return ''; -} - -function bluesky_get_did_by_dns(string $handle): string -{ - $records = @dns_get_record('_atproto.' . $handle . '.', DNS_TXT); - if (empty($records)) { - return ''; - } - foreach ($records as $record) { - if (!empty($record['txt']) && substr($record['txt'], 0, 4) == 'did=') { - $did = substr($record['txt'], 4); - if (!bluesky_valid_did($did, $handle)) { - Logger::notice('Invalid DID', ['handle' => $handle, 'did' => $did]); - return ''; - } - return $did; - } - } - return ''; -} - -function bluesky_get_did(string $handle, int $uid): string -{ - if ($handle == '') { - return ''; - } - - if (strpos($handle, '.') === false) { - $handle .= '.' . BLUESKY_HOSTNAME; - } - - // At first we use the user PDS. That should cover most cases. - $pds = DI::pConfig()->get($uid, 'bluesky', 'pds'); - if (!empty($pds)) { - $data = bluesky_get($pds . '/xrpc/com.atproto.identity.resolveHandle?handle=' . urlencode($handle)); - if (!empty($data) && !empty($data->did)) { - Logger::debug('Got DID by user PDS call', ['handle' => $handle, 'did' => $data->did]); - return $data->did; - } - } - - // Then we query the DNS, which is used for third party handles (DNS should be faster than wellknown) - $did = bluesky_get_did_by_dns($handle); - if ($did != '') { - Logger::debug('Got DID by DNS', ['handle' => $handle, 'did' => $did]); - return $did; - } - - // Then we query wellknown, which should mostly cover the rest. - $did = bluesky_get_did_by_wellknown($handle); - if ($did != '') { - Logger::debug('Got DID by wellknown', ['handle' => $handle, 'did' => $did]); - return $did; - } - - // And finally we use the default PDS from Bluesky. - $data = bluesky_get(BLUESKY_PDS . '/xrpc/com.atproto.identity.resolveHandle?handle=' . urlencode($handle)); - if (!empty($data) && !empty($data->did)) { - Logger::debug('Got DID by system PDS call', ['handle' => $handle, 'did' => $data->did]); - return $data->did; - } - - Logger::notice('No DID detected', ['handle' => $handle]); - return ''; -} - -function bluesky_get_user_did(int $uid, bool $refresh = false): ?string -{ - if (!$refresh) { - $did = DI::pConfig()->get($uid, 'bluesky', 'did'); - if (!empty($did)) { - return $did; - } - } - - $handle = DI::pConfig()->get($uid, 'bluesky', 'handle'); - if (empty($handle)) { - return null; - } - - $did = bluesky_get_did($handle, $uid); - if (empty($did)) { - return null; - } - - Logger::debug('Got DID for user', ['uid' => $uid, 'handle' => $handle, 'did' => $did]); - DI::pConfig()->set($uid, 'bluesky', 'did', $did); - return $did; -} - -function bluesky_get_user_pds(int $uid): ?string -{ - $pds = DI::pConfig()->get($uid, 'bluesky', 'pds'); - if (!empty($pds)) { - return $pds; - } - - $did = bluesky_get_user_did($uid); - if (empty($did)) { - return null; - } - - $pds = bluesky_get_pds($did); - if (empty($pds)) { - return null; - } - - DI::pConfig()->set($uid, 'bluesky', 'pds', $pds); - return $pds; -} - -function bluesky_get_pds(string $did, stdClass $data = null): ?string -{ - if (empty($data)) { - $data = bluesky_get(BLUESKY_DIRECTORY . '/' . $did); - } - if (empty($data) || empty($data->service)) { - return null; - } - - foreach ($data->service as $service) { - if (($service->id == '#atproto_pds') && ($service->type == 'AtprotoPersonalDataServer') && !empty($service->serviceEndpoint)) { - return $service->serviceEndpoint; - } - } - - return null; -} - -function bluesky_get_public_key(string $did, stdClass $data = null): ?string -{ - if (empty($data)) { - $data = bluesky_get(BLUESKY_DIRECTORY . '/' . $did); - } - if (empty($data) || empty($data->verificationMethod)) { - return null; - } - foreach ($data->verificationMethod as $method) { - if (!empty($method->publicKeyMultibase)) { - return $method->publicKeyMultibase; - } - } - return null; -} - -function bluesky_valid_did(string $did, string $handle): bool -{ - $data = bluesky_get(BLUESKY_DIRECTORY . '/' . $did); - if (empty($data) || empty($data->alsoKnownAs)) { - return false; - } - - return in_array('at://' . $handle, $data->alsoKnownAs); -} - -function bluesky_get_token(int $uid): string -{ - $token = DI::pConfig()->get($uid, 'bluesky', 'access_token'); - $created = DI::pConfig()->get($uid, 'bluesky', 'token_created'); - if (empty($token)) { - return ''; - } - - if ($created + 300 < time()) { - return bluesky_refresh_token($uid); - } - return $token; -} - -function bluesky_refresh_token(int $uid): string -{ - $token = DI::pConfig()->get($uid, 'bluesky', 'refresh_token'); - - $data = bluesky_post($uid, '/xrpc/com.atproto.server.refreshSession', '', ['Authorization' => ['Bearer ' . $token]]); - if (empty($data) || empty($data->accessJwt)) { - return ''; - } - - Logger::debug('Refreshed token', ['return' => $data]); - DI::pConfig()->set($uid, 'bluesky', 'access_token', $data->accessJwt); - DI::pConfig()->set($uid, 'bluesky', 'refresh_token', $data->refreshJwt); - DI::pConfig()->set($uid, 'bluesky', 'token_created', time()); - return $data->accessJwt; -} - -function bluesky_create_token(int $uid, string $password): string -{ - $did = bluesky_get_user_did($uid); - if (empty($did)) { - return ''; - } - - $data = bluesky_post($uid, '/xrpc/com.atproto.server.createSession', json_encode(['identifier' => $did, 'password' => $password]), ['Content-type' => 'application/json']); - if (empty($data) || empty($data->accessJwt)) { - DI::pConfig()->set($uid, 'bluesky', 'status', BLUEKSY_STATUS_TOKEN_FAIL); - return ''; - } - - Logger::debug('Created token', ['return' => $data]); - DI::pConfig()->set($uid, 'bluesky', 'access_token', $data->accessJwt); - DI::pConfig()->set($uid, 'bluesky', 'refresh_token', $data->refreshJwt); - DI::pConfig()->set($uid, 'bluesky', 'token_created', time()); - DI::pConfig()->set($uid, 'bluesky', 'status', BLUEKSY_STATUS_TOKEN_OK); - return $data->accessJwt; -} - -function bluesky_xrpc_post(int $uid, string $url, $parameters): ?stdClass -{ - $data = bluesky_post($uid, '/xrpc/' . $url, json_encode($parameters), ['Content-type' => 'application/json', 'Authorization' => ['Bearer ' . bluesky_get_token($uid)]]); - if (!empty($data)) { - Item::incrementOutbound(Protocol::BLUESKY); - } - return $data; -} - -function bluesky_post(int $uid, string $url, string $params, array $headers): ?stdClass -{ - $pds = bluesky_get_user_pds($uid); - if (empty($pds)) { - return null; - } - - try { - $curlResult = DI::httpClient()->post($pds . $url, $params, $headers); - } catch (\Exception $e) { - Logger::notice('Exception on post', ['exception' => $e]); - DI::pConfig()->set($uid, 'bluesky', 'status', BLUEKSY_STATUS_API_FAIL); - return null; - } - - $data = json_decode($curlResult->getBodyString()); - if (!$curlResult->isSuccess()) { - Logger::notice('API Error', ['url' => $url, 'code' => $curlResult->getReturnCode(), 'error' => $data ?: $curlResult->getBodyString()]); - if (!$data) { - DI::pConfig()->set($uid, 'bluesky', 'status', BLUEKSY_STATUS_API_FAIL); - return null; - } - $data->code = $curlResult->getReturnCode(); - } - - DI::pConfig()->set($uid, 'bluesky', 'status', BLUEKSY_STATUS_SUCCESS); - return $data; -} - -function bluesky_xrpc_get(int $uid, string $url, array $parameters = []): ?stdClass -{ - if (!empty($parameters)) { - $url .= '?' . http_build_query($parameters); - } - - $pds = bluesky_get_user_pds($uid); - if (empty($pds)) { - return null; - } - - $headers = ['Authorization' => ['Bearer ' . bluesky_get_token($uid)]]; - - $languages = User::getWantedLanguages($uid); - if (!empty($languages)) { - $headers['Accept-Language'] = implode(',', $languages); - } - - $data = bluesky_get($pds . '/xrpc/' . $url, HttpClientAccept::JSON, [HttpClientOptions::HEADERS => $headers]); - DI::pConfig()->set($uid, 'bluesky', 'status', is_null($data) ? BLUEKSY_STATUS_API_FAIL : BLUEKSY_STATUS_SUCCESS); - return $data; -} - -function bluesky_get(string $url, string $accept_content = HttpClientAccept::DEFAULT, array $opts = []): ?stdClass -{ - try { - $curlResult = DI::httpClient()->get($url, $accept_content, $opts); - } catch (\Exception $e) { - Logger::notice('Exception on get', ['url' => $url, 'exception' => $e]); - return null; - } - - $data = json_decode($curlResult->getBodyString()); - if (!$curlResult->isSuccess()) { - Logger::notice('API Error', ['url' => $url, 'code' => $curlResult->getReturnCode(), 'error' => $data ?: $curlResult->getBodyString()]); - if (!$data) { - return null; - } - $data->code = $curlResult->getReturnCode(); - } - - Item::incrementInbound(Protocol::BLUESKY); - return $data; -} diff --git a/bluesky/bluesky_feed.php b/bluesky/bluesky_feed.php index a20ef1b9..e4aa3fdc 100644 --- a/bluesky/bluesky_feed.php +++ b/bluesky/bluesky_feed.php @@ -1,6 +1,6 @@ $argv[1], 'feed' => $argv[2]]); + DI::logger()->debug('Importing feed - start', ['user' => $argv[1], 'feed' => $argv[2]]); bluesky_fetch_feed($argv[1], $argv[2]); - Logger::debug('Importing feed - done', ['user' => $argv[1], 'feed' => $argv[2]]); + DI::logger()->debug('Importing feed - done', ['user' => $argv[1], 'feed' => $argv[2]]); } diff --git a/bluesky/bluesky_notifications.php b/bluesky/bluesky_notifications.php index 1fbc8f67..e1bf2047 100644 --- a/bluesky/bluesky_notifications.php +++ b/bluesky/bluesky_notifications.php @@ -1,6 +1,6 @@ $argv[1]]); + DI::logger()->notice('importing notifications - start', ['user' => $argv[1]]); bluesky_fetch_notifications($argv[1]); - Logger::notice('importing notifications - done', ['user' => $argv[1]]); + DI::logger()->notice('importing notifications - done', ['user' => $argv[1]]); } diff --git a/bluesky/bluesky_timeline.php b/bluesky/bluesky_timeline.php index fda846ba..37b22d99 100644 --- a/bluesky/bluesky_timeline.php +++ b/bluesky/bluesky_timeline.php @@ -1,6 +1,6 @@ $argv[1]]); + DI::logger()->notice('importing timeline - start', ['user' => $argv[1]]); bluesky_fetch_timeline($argv[1]); - Logger::notice('importing timeline - done', ['user' => $argv[1]]); + DI::logger()->notice('importing timeline - done', ['user' => $argv[1]]); } diff --git a/buglink/buglink.php b/buglink/buglink.php index 78fb8bef..b7dd6504 100644 --- a/buglink/buglink.php +++ b/buglink/buglink.php @@ -6,7 +6,6 @@ * Author: Mike Macgirvin */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\DI; diff --git a/calc/calc.php b/calc/calc.php index a8a340c4..76d1805c 100644 --- a/calc/calc.php +++ b/calc/calc.php @@ -6,7 +6,6 @@ * Author: Mike Macgirvin */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\DI; @@ -16,7 +15,7 @@ function calc_install() { function calc_app_menu(array &$b) { - $b['app_menu'][] = ''; + $b['app_menu'][] = ''; } /** @@ -296,7 +295,7 @@ $o .= <<< EOT

Calculator



-
+
@@ -323,7 +322,7 @@ $o .= <<< EOT - + @@ -345,13 +344,13 @@ $o .= <<< EOT - +
diff --git a/catavatar/catavatar.php b/catavatar/catavatar.php index 2116ac44..7b5f05c0 100644 --- a/catavatar/catavatar.php +++ b/catavatar/catavatar.php @@ -6,11 +6,8 @@ * Author: Fabio */ -use Friendica\App; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; -use Friendica\Core\Worker; use Friendica\Database\DBA; use Friendica\DI; use Friendica\Model\Contact; @@ -29,7 +26,7 @@ function catavatar_install() Hook::register('addon_settings', __FILE__, 'catavatar_addon_settings'); Hook::register('addon_settings_post', __FILE__, 'catavatar_addon_settings_post'); - Logger::notice('registered catavatar'); + DI::logger()->notice('registered catavatar'); } /** diff --git a/cld/cld.php b/cld/cld.php index 83361e2b..d4fef6c5 100644 --- a/cld/cld.php +++ b/cld/cld.php @@ -7,7 +7,6 @@ */ use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\DI; function cld_install() @@ -18,17 +17,17 @@ function cld_install() function cld_detect_languages(array &$data) { if (!in_array('cld2', get_loaded_extensions())) { - Logger::warning('CLD2 is not installed.'); + DI::logger()->warning('CLD2 is not installed.'); return; } if (!class_exists('CLD2Detector')) { - Logger::warning('CLD2Detector class does not exist.'); + DI::logger()->warning('CLD2Detector class does not exist.'); return; } if (!class_exists('CLD2Encoding')) { - Logger::warning('CLD2Encoding class does not exist.'); + DI::logger()->warning('CLD2Encoding class does not exist.'); return; } @@ -53,7 +52,7 @@ function cld_detect_languages(array &$data) } if (!$result['is_reliable']) { - Logger::debug('Unreliable detection', ['uri-id' => $data['uri-id'], 'original' => $original, 'detected' => $detected, 'name' => $result['language_name'], 'probability' => $result['language_probability'], 'text' => $data['text']]); + DI::logger()->debug('Unreliable detection', ['uri-id' => $data['uri-id'], 'original' => $original, 'detected' => $detected, 'name' => $result['language_name'], 'probability' => $result['language_probability'], 'text' => $data['text']]); if (($original == $detected) && ($data['detected'][$original] < $result['language_probability'] / 100)) { $data['detected'][$original] = $result['language_probability'] / 100; } @@ -63,12 +62,12 @@ function cld_detect_languages(array &$data) $available = array_keys(DI::l10n()->getLanguageCodes()); if (!in_array($detected, $available)) { - Logger::debug('Unsupported language', ['uri-id' => $data['uri-id'], 'original' => $original, 'detected' => $detected, 'name' => $result['language_name'], 'probability' => $result['language_probability'], 'text' => $data['text']]); + DI::logger()->debug('Unsupported language', ['uri-id' => $data['uri-id'], 'original' => $original, 'detected' => $detected, 'name' => $result['language_name'], 'probability' => $result['language_probability'], 'text' => $data['text']]); return; } if ($original != $detected) { - Logger::debug('Detected different language', ['uri-id' => $data['uri-id'], 'original' => $original, 'detected' => $detected, 'name' => $result['language_name'], 'probability' => $result['language_probability'], 'text' => $data['text']]); + DI::logger()->debug('Detected different language', ['uri-id' => $data['uri-id'], 'original' => $original, 'detected' => $detected, 'name' => $result['language_name'], 'probability' => $result['language_probability'], 'text' => $data['text']]); } $length = count($data['detected']); diff --git a/cookienotice/cookienotice.php b/cookienotice/cookienotice.php index 2bd6f9b1..bc9d2416 100644 --- a/cookienotice/cookienotice.php +++ b/cookienotice/cookienotice.php @@ -7,7 +7,6 @@ * Author: Peter Liebetrau */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\Core\Renderer; use Friendica\DI; diff --git a/diaspora/Diaspora_Connection.php b/diaspora/Diaspora_Connection.php index d8390d70..05c21eb0 100644 --- a/diaspora/Diaspora_Connection.php +++ b/diaspora/Diaspora_Connection.php @@ -33,7 +33,6 @@ class Diaspora_Connection { } $this->cookiejar = tempnam(System::getTempPath(), 'cookies'); - return $this; } public function __destruct() { diff --git a/diaspora/diaspora.php b/diaspora/diaspora.php index 979204ba..3c4b4c0e 100644 --- a/diaspora/diaspora.php +++ b/diaspora/diaspora.php @@ -9,10 +9,8 @@ require_once 'addon/diaspora/Diaspora_Connection.php'; -use Friendica\App; use Friendica\Content\Text\BBCode; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\Database\DBA; use Friendica\Core\Worker; @@ -187,7 +185,7 @@ function diaspora_send(array &$b) { $hostname = DI::baseUrl()->getHost(); - Logger::notice('diaspora_send: invoked'); + DI::logger()->notice('diaspora_send: invoked'); if ($b['deleted'] || ($b['private'] == Item::PRIVATE) || ($b['created'] !== $b['edited'])) { return; @@ -211,14 +209,14 @@ function diaspora_send(array &$b) return; } - Logger::info('diaspora_send: prepare posting'); + DI::logger()->info('diaspora_send: prepare posting'); $handle = DI::pConfig()->get($b['uid'], 'diaspora', 'handle'); $password = DI::pConfig()->get($b['uid'], 'diaspora', 'password'); $aspect = DI::pConfig()->get($b['uid'], 'diaspora', 'aspect'); if ($handle && $password) { - Logger::info('diaspora_send: all values seem to be okay'); + DI::logger()->info('diaspora_send: all values seem to be okay'); $title = $b['title']; $body = $b['body']; @@ -249,20 +247,20 @@ function diaspora_send(array &$b) require_once "addon/diaspora/diasphp.php"; try { - Logger::info('diaspora_send: prepare'); + DI::logger()->info('diaspora_send: prepare'); $conn = new Diaspora_Connection($handle, $password); - Logger::info('diaspora_send: try to log in ' . $handle); + DI::logger()->info('diaspora_send: try to log in ' . $handle); $conn->logIn(); - Logger::info('diaspora_send: try to send ' . $body); + DI::logger()->info('diaspora_send: try to send ' . $body); $conn->provider = $hostname; $conn->postStatusMessage($body, $aspect); - Logger::notice('diaspora_send: success'); + DI::logger()->notice('diaspora_send: success'); } catch (Exception $e) { - Logger::notice("diaspora_send: Error submitting the post: " . $e->getMessage()); + DI::logger()->notice("diaspora_send: Error submitting the post: " . $e->getMessage()); - Logger::info('diaspora_send: requeueing ' . $b['uid']); + DI::logger()->info('diaspora_send: requeueing ' . $b['uid']); Worker::defer(); } diff --git a/discourse/discourse.php b/discourse/discourse.php index 298b3f3e..b8d0d996 100644 --- a/discourse/discourse.php +++ b/discourse/discourse.php @@ -8,10 +8,8 @@ * */ -use Friendica\App; use Friendica\Content\Text\Markdown; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Protocol; use Friendica\Core\Renderer; use Friendica\Database\DBA; @@ -80,13 +78,13 @@ function discourse_email_getmessage(&$message) // We do assume that all Discourse servers are running with SSL if (preg_match('=topic/(.*\d)/(.*\d)@(.*)=', $message['item']['uri'], $matches) && discourse_fetch_post_from_api($message, $matches[2], $matches[3])) { - Logger::info('Fetched comment via API (message-id mode)', ['host' => $matches[3], 'topic' => $matches[1], 'post' => $matches[2]]); + DI::logger()->info('Fetched comment via API (message-id mode)', ['host' => $matches[3], 'topic' => $matches[1], 'post' => $matches[2]]); return; } if (preg_match('=topic/(.*\d)@(.*)=', $message['item']['uri'], $matches) && discourse_fetch_topic_from_api($message, 'https://' . $matches[2], $matches[1], 1)) { - Logger::info('Fetched starting post via API (message-id mode)', ['host' => $matches[2], 'topic' => $matches[1]]); + DI::logger()->info('Fetched starting post via API (message-id mode)', ['host' => $matches[2], 'topic' => $matches[1]]); return; } @@ -96,16 +94,16 @@ function discourse_email_getmessage(&$message) } if (empty($message['item']['plink']) || !preg_match('=(http.*)/t/.*/(.*\d)/(.*\d)=', $message['item']['plink'], $matches)) { - Logger::info('This is no Discourse post'); + DI::logger()->info('This is no Discourse post'); return; } if (discourse_fetch_topic_from_api($message, $matches[1], $matches[2], $matches[3])) { - Logger::info('Fetched post via API (plink mode)', ['host' => $matches[1], 'topic' => $matches[2], 'id' => $matches[3]]); + DI::logger()->info('Fetched post via API (plink mode)', ['host' => $matches[1], 'topic' => $matches[2], 'id' => $matches[3]]); return; } - Logger::info('Fallback mode', ['plink' => $message['item']['plink']]); + DI::logger()->info('Fallback mode', ['plink' => $message['item']['plink']]); // Search in the HTML part for the discourse entry and the author profile if (!empty($message['html'])) { $message = discourse_get_html($message); @@ -122,7 +120,7 @@ function discourse_fetch_post($host, $topic, $pid) $url = $host . '/t/' . $topic . '/' . $pid . '.json'; $curlResult = DI::httpClient()->get($url); if (!$curlResult->isSuccess()) { - Logger::info('No success', ['url' => $url]); + DI::logger()->info('No success', ['url' => $url]); return false; } @@ -134,11 +132,11 @@ function discourse_fetch_post($host, $topic, $pid) /// @todo Possibly fetch missing posts here continue; } - Logger::info('Got post data from topic', $post); + DI::logger()->info('Got post data from topic', $post); return $post; } - Logger::info('Post not found', ['host' => $host, 'topic' => $topic, 'pid' => $pid]); + DI::logger()->info('Post not found', ['host' => $host, 'topic' => $topic, 'pid' => $pid]); return false; } @@ -170,7 +168,7 @@ function discourse_fetch_post_from_api(&$message, $post, $host) $message = discourse_process_post($message, $data, $hostaddr); - Logger::info('Got API data', $message); + DI::logger()->info('Got API data', $message); return true; } @@ -203,7 +201,7 @@ function discourse_get_user($post, $hostaddr) $contact['url'] = $hostaddr . '/u/' . $contact['nick']; $contact['nurl'] = Strings::normaliseLink($contact['url']); $contact['baseurl'] = $hostaddr; - Logger::info('Contact', $contact); + DI::logger()->info('Contact', $contact); $contact['id'] = Contact::getIdForURL($contact['url'], 0, false, $contact); if (!empty($contact['id'])) { $avatar = $contact['photo']; @@ -269,11 +267,11 @@ function discourse_get_html($message) $div = $doc2->importNode($result->item(0), true); $doc2->appendChild($div); $message['html'] = $doc2->saveHTML(); - Logger::info('Found html body', ['html' => $message['html']]); + DI::logger()->info('Found html body', ['html' => $message['html']]); $profile = discourse_get_profile($xpath); if (!empty($profile['url'])) { - Logger::info('Found profile', $profile); + DI::logger()->info('Found profile', $profile); $message['item']['author-id'] = Contact::getIdForURL($profile['url'], 0, false, $profile); $message['item']['author-link'] = $profile['url']; $message['item']['author-name'] = $profile['name']; @@ -289,21 +287,21 @@ function discourse_get_text($message) $text = str_replace("\r", '', $text); $pos = strpos($text, "\n---\n"); if ($pos == 0) { - Logger::info('No separator found', ['text' => $text]); + DI::logger()->info('No separator found', ['text' => $text]); return $message; } $message['text'] = trim(substr($text, 0, $pos)); - Logger::info('Found text body', ['text' => $message['text']]); + DI::logger()->info('Found text body', ['text' => $message['text']]); $message['text'] = Markdown::toBBCode($message['text']); $text = substr($text, $pos); - Logger::info('Found footer', ['text' => $text]); + DI::logger()->info('Found footer', ['text' => $text]); if (preg_match('=\((http.*/t/.*/.*\d/.*\d)\)=', $text, $link)) { $message['item']['plink'] = $link[1]; - Logger::info('Found plink', ['plink' => $message['item']['plink']]); + DI::logger()->info('Found plink', ['plink' => $message['item']['plink']]); } return $message; } diff --git a/dwpost/dwpost.php b/dwpost/dwpost.php index 1ecd9764..7bad85dc 100644 --- a/dwpost/dwpost.php +++ b/dwpost/dwpost.php @@ -8,10 +8,8 @@ * Author: Cat Gray */ -use Friendica\App; use Friendica\Content\Text\BBCode; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\DI; use Friendica\Model\Item; @@ -186,12 +184,12 @@ function dwpost_send(array &$b) EOT; - Logger::debug('dwpost: data: ' . $xml); + DI::logger()->debug('dwpost: data: ' . $xml); if ($dw_blog !== 'test') { $x = DI::httpClient()->post($dw_blog, $xml, ['Content-Type' => 'text/xml'])->getBodyString(); } - Logger::info('posted to dreamwidth: ' . ($x) ? $x : ''); + DI::logger()->info('posted to dreamwidth: ' . ($x) ? $x : ''); } } diff --git a/fancybox/fancybox.php b/fancybox/fancybox.php index 73bbdab9..b1a1ff35 100644 --- a/fancybox/fancybox.php +++ b/fancybox/fancybox.php @@ -7,7 +7,6 @@ * Status: Unsupported */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\DI; @@ -40,7 +39,7 @@ function fancybox_render(array &$b){ function ($text) use ($gallery) { // This processes images inlined in posts // Frio / Vier hooks für lightbox are un-hooked in fancybox-config.js. So this works for them, too! - //if (!in_array(DI::app()->getCurrentTheme(),['vier','frio'])) + //if (!in_array(DI::appHelper()->getCurrentTheme(),['vier','frio'])) $text = preg_replace( '#]*href="([^"]*)"[^>]*>(]*src="[^"]*"[^>]*>)#', '$2', diff --git a/fromapp/fromapp.php b/fromapp/fromapp.php index 0d5a5b16..bb8a4fe6 100644 --- a/fromapp/fromapp.php +++ b/fromapp/fromapp.php @@ -7,9 +7,7 @@ * */ -use Friendica\App; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\DI; @@ -18,7 +16,7 @@ function fromapp_install() Hook::register('post_local', 'addon/fromapp/fromapp.php', 'fromapp_post_hook'); Hook::register('addon_settings', 'addon/fromapp/fromapp.php', 'fromapp_settings'); Hook::register('addon_settings_post', 'addon/fromapp/fromapp.php', 'fromapp_settings_post'); - Logger::notice("installed fromapp"); + DI::logger()->notice("installed fromapp"); } function fromapp_settings_post($post) @@ -76,6 +74,6 @@ function fromapp_post_hook(&$item) $apps = explode(',', $app); $item['app'] = trim($apps[mt_rand(0, count($apps)-1)]); - + return; } diff --git a/geocoordinates/geocoordinates.php b/geocoordinates/geocoordinates.php index 5cb90efd..5af1defc 100644 --- a/geocoordinates/geocoordinates.php +++ b/geocoordinates/geocoordinates.php @@ -6,9 +6,7 @@ * Author: Michael Vogel */ -use Friendica\App; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\DI; @@ -52,25 +50,25 @@ function geocoordinates_resolve_item(array &$item) $s = DI::httpClient()->fetch('https://api.opencagedata.com/geocode/v1/json?q=' . $coords[0] . ',' . $coords[1] . '&key=' . $key . '&language=' . $language); if (!$s) { - Logger::info('API could not be queried'); + DI::logger()->info('API could not be queried'); return; } $data = json_decode($s); if ($data->status->code != '200') { - Logger::info('API returned error ' . $data->status->code . ' ' . $data->status->message); + DI::logger()->info('API returned error ' . $data->status->code . ' ' . $data->status->message); return; } if (($data->total_results == 0) || (count($data->results) == 0)) { - Logger::info('No results found for coordinates ' . $item['coord']); + DI::logger()->info('No results found for coordinates ' . $item['coord']); return; } $item['location'] = $data->results[0]->formatted; - Logger::info('Got location for coordinates ' . $coords[0] . '-' . $coords[1] . ': ' . $item['location']); + DI::logger()->info('Got location for coordinates ' . $coords[0] . '-' . $coords[1] . ': ' . $item['location']); if ($item['location'] != '') { DI::cache()->set('geocoordinates:' . $language.':' . $coords[0] . '-' . $coords[1], $item['location']); diff --git a/geonames/geonames.php b/geonames/geonames.php index dcbd65f8..4c5e54d8 100644 --- a/geonames/geonames.php +++ b/geonames/geonames.php @@ -6,9 +6,7 @@ * Author: Mike Macgirvin */ -use Friendica\App; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\DI; use Friendica\Core\Config\Util\ConfigFileManager; @@ -35,7 +33,7 @@ function geonames_install() function geonames_load_config(ConfigFileManager $loader) { - DI::app()->getConfigCache()->load($loader->loadAddonConfig('geonames'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); + DI::appHelper()->getConfigCache()->load($loader->loadAddonConfig('geonames'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); } function geonames_post_hook(array &$item) @@ -46,7 +44,7 @@ function geonames_post_hook(array &$item) * - The profile owner must have allowed our addon */ - Logger::notice('geonames invoked'); + DI::logger()->notice('geonames invoked'); if (!DI::userSession()->getLocalUserId()) { /* non-zero if this is a logged in user of this system */ return; diff --git a/gnot/gnot.php b/gnot/gnot.php index 15fb4da0..3801a210 100644 --- a/gnot/gnot.php +++ b/gnot/gnot.php @@ -4,13 +4,11 @@ * Description: Thread email comment notifications on Gmail and anonymise them * Version: 1.0 * Author: Mike Macgirvin - * + * * */ -use Friendica\App; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\DI; use Friendica\Model\Notification; @@ -21,7 +19,7 @@ function gnot_install() Hook::register('addon_settings_post', 'addon/gnot/gnot.php', 'gnot_settings_post'); Hook::register('enotify_mail', 'addon/gnot/gnot.php', 'gnot_enotify_mail'); - Logger::notice("installed gnot"); + DI::logger()->notice("installed gnot"); } /** @@ -38,7 +36,7 @@ function gnot_settings_post($post) { } /** - * Called from the Addon Setting form. + * Called from the Addon Setting form. * Add our own settings info to the page. */ function gnot_settings(array &$data) diff --git a/googlemaps/googlemaps.php b/googlemaps/googlemaps.php index 356ce68c..94a3a96b 100644 --- a/googlemaps/googlemaps.php +++ b/googlemaps/googlemaps.php @@ -7,15 +7,14 @@ * */ -use Friendica\App; use Friendica\Core\Hook; -use Friendica\Core\Logger; +use Friendica\DI; function googlemaps_install() { Hook::register('render_location', 'addon/googlemaps/googlemaps.php', 'googlemaps_location'); - Logger::notice('installed googlemaps'); + DI::logger()->notice('installed googlemaps'); } function googlemaps_location(&$item) diff --git a/gravatar/gravatar.php b/gravatar/gravatar.php index 83a8fbb9..7fe0d955 100644 --- a/gravatar/gravatar.php +++ b/gravatar/gravatar.php @@ -6,15 +6,11 @@ * Author: Klaus Weidenbach */ -use Friendica\App; use Friendica\BaseModule; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; -use Friendica\Database\DBA; use Friendica\DI; use Friendica\Core\Config\Util\ConfigFileManager; -use Friendica\Util\Strings; /** * Installs the addon hook @@ -23,12 +19,12 @@ function gravatar_install() { Hook::register('load_config', 'addon/gravatar/gravatar.php', 'gravatar_load_config'); Hook::register('avatar_lookup', 'addon/gravatar/gravatar.php', 'gravatar_lookup'); - Logger::notice("registered gravatar in avatar_lookup hook"); + DI::logger()->notice("registered gravatar in avatar_lookup hook"); } function gravatar_load_config(ConfigFileManager $loader) { - DI::app()->getConfigCache()->load($loader->loadAddonConfig('gravatar'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); + DI::appHelper()->getConfigCache()->load($loader->loadAddonConfig('gravatar'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); } /** diff --git a/group_text/group_text.php b/group_text/group_text.php index 02e9fd0a..e5067fb5 100644 --- a/group_text/group_text.php +++ b/group_text/group_text.php @@ -8,9 +8,7 @@ * Note: Please use Circle Text instead */ -use Friendica\App; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\DI; diff --git a/highlightjs/highlightjs.php b/highlightjs/highlightjs.php index 097d34c7..762f4117 100644 --- a/highlightjs/highlightjs.php +++ b/highlightjs/highlightjs.php @@ -6,7 +6,6 @@ * Author: Hypolite Petovan */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\DI; @@ -18,7 +17,7 @@ function highlightjs_install() function highlightjs_head(string &$str) { - if (DI::app()->getCurrentTheme() == 'frio') { + if (DI::appHelper()->getCurrentTheme() == 'frio') { $style = 'bootstrap'; } else { $style = 'default'; diff --git a/ifttt/ifttt.php b/ifttt/ifttt.php index 6d4f402c..cb23032b 100644 --- a/ifttt/ifttt.php +++ b/ifttt/ifttt.php @@ -6,10 +6,8 @@ * Version: 0.1 * Author: Michael Vogel */ -use Friendica\App; use Friendica\Content\PageInfo; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\Core\Worker; use Friendica\Database\DBA; @@ -87,16 +85,16 @@ function ifttt_post() $user = DBA::selectFirst('user', ['uid'], ['nickname' => $nickname]); if (!DBA::isResult($user)) { - Logger::info('User ' . $nickname . ' not found.'); + DI::logger()->info('User ' . $nickname . ' not found.'); return; } $uid = $user['uid']; - Logger::info('Received a post for user ' . $uid . ' from ifttt ' . print_r($_REQUEST, true)); + DI::logger()->info('Received a post for user ' . $uid . ' from ifttt ' . print_r($_REQUEST, true)); if (!isset($_REQUEST['key'])) { - Logger::notice('No key found.'); + DI::logger()->notice('No key found.'); return; } @@ -104,7 +102,7 @@ function ifttt_post() // Check the key if ($key != DI::pConfig()->get($uid, 'ifttt', 'key')) { - Logger::info('Invalid key for user ' . $uid); + DI::logger()->info('Invalid key for user ' . $uid); return; } @@ -115,7 +113,7 @@ function ifttt_post() } if (!in_array($item['type'], ['status', 'link', 'photo'])) { - Logger::info('Unknown item type ' . $item['type']); + DI::logger()->info('Unknown item type ' . $item['type']); return; } diff --git a/ijpost/ijpost.php b/ijpost/ijpost.php index f22dfff2..9fe502af 100644 --- a/ijpost/ijpost.php +++ b/ijpost/ijpost.php @@ -8,10 +8,8 @@ * Author: Cat Gray */ -use Friendica\App; use Friendica\Content\Text\BBCode; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\DI; use Friendica\Model\Item; @@ -179,11 +177,11 @@ function ijpost_send(array &$b) EOT; - Logger::debug('ijpost: data: ' . $xml); + DI::logger()->debug('ijpost: data: ' . $xml); if ($ij_blog !== 'test') { $x = DI::httpClient()->post($ij_blog, $xml, ['Content-Type' => 'text/xml'])->getBodyString(); } - Logger::info('posted to insanejournal: ' . $x ? $x : ''); + DI::logger()->info('posted to insanejournal: ' . $x ? $x : ''); } } diff --git a/impressum/impressum.php b/impressum/impressum.php index 754cb828..0ad34e40 100644 --- a/impressum/impressum.php +++ b/impressum/impressum.php @@ -7,10 +7,8 @@ * License: 3-clause BSD license */ -use Friendica\App; use Friendica\Content\Text\BBCode; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\DI; use Friendica\Core\Config\Util\ConfigFileManager; @@ -21,7 +19,7 @@ function impressum_install() Hook::register('load_config', 'addon/impressum/impressum.php', 'impressum_load_config'); Hook::register('about_hook', 'addon/impressum/impressum.php', 'impressum_show'); Hook::register('page_end', 'addon/impressum/impressum.php', 'impressum_footer'); - Logger::notice("installed impressum Addon"); + DI::logger()->notice("installed impressum Addon"); } /** @@ -56,7 +54,7 @@ function impressum_footer(string &$body) function impressum_load_config(ConfigFileManager $loader) { - DI::app()->getConfigCache()->load($loader->loadAddonConfig('impressum'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); + DI::appHelper()->getConfigCache()->load($loader->loadAddonConfig('impressum'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); } function impressum_show(string &$body) diff --git a/infiniteimprobabilitydrive/infiniteimprobabilitydrive.php b/infiniteimprobabilitydrive/infiniteimprobabilitydrive.php index aff7aec0..9eb6ab36 100644 --- a/infiniteimprobabilitydrive/infiniteimprobabilitydrive.php +++ b/infiniteimprobabilitydrive/infiniteimprobabilitydrive.php @@ -6,7 +6,6 @@ * Author: Thomas Willingham */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\DI; diff --git a/invidious/invidious.php b/invidious/invidious.php index 033ecce5..5fa2eca9 100644 --- a/invidious/invidious.php +++ b/invidious/invidious.php @@ -54,8 +54,8 @@ function invidious_settings(array &$data) $t = Renderer::getMarkupTemplate('settings.tpl', 'addon/invidious/'); $html = Renderer::replaceMacros($t, [ - '$enabled' => ['enabled', DI::l10n()->t('Replace Youtube links with links to an Invidious server'), $enabled, DI::l10n()->t('If enabled, Youtube links are replaced with the links to the specified Invidious server.')], - '$server' => ['server', DI::l10n()->t('Invidious server'), $server, DI::l10n()->t('See %s for a list of available Invidious servers.', 'https://api.invidious.io/')], + '$enabled' => ['invidious-enabled', DI::l10n()->t('Replace Youtube links with links to an Invidious server'), $enabled, DI::l10n()->t('If enabled, Youtube links are replaced with the links to the specified Invidious server.')], + '$server' => ['invidious-server', DI::l10n()->t('Invidious server'), $server, DI::l10n()->t('See %s for a list of available Invidious servers.', 'https://api.invidious.io/')], ]); $data = [ @@ -71,9 +71,9 @@ function invidious_settings_post(array &$b) return; } - DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'invidious', 'enabled', (bool)$_POST['enabled']); + DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'invidious', 'enabled', (bool)$_POST['invidious-enabled']); - $server = trim($_POST['server'], " \n\r\t\v\x00/"); + $server = trim($_POST['invidious-server'], " \n\r\t\v\x00/"); if ($server != DI::config()->get('invidious', 'server', INVIDIOUS_DEFAULT) && !empty($server)) { DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'invidious', 'server', $server); } else { diff --git a/irc/irc.php b/irc/irc.php index d4435851..db808a99 100644 --- a/irc/irc.php +++ b/irc/irc.php @@ -7,7 +7,6 @@ * Author: Tobias Diekershoff */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\Core\Renderer; use Friendica\DI; diff --git a/js_upload/js_upload.php b/js_upload/js_upload.php index f1d85aa3..4bf91de1 100644 --- a/js_upload/js_upload.php +++ b/js_upload/js_upload.php @@ -8,7 +8,6 @@ */ use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\DI; use Friendica\Util\Images; @@ -68,7 +67,7 @@ function js_upload_post_init(array &$b) $js_upload_jsonresponse = htmlspecialchars(json_encode($result), ENT_NOQUOTES); if (isset($result['error'])) { - Logger::info('mod/photos.php: photos_post(): error uploading photo: ' . $result['error']); + DI::logger()->info('mod/photos.php: photos_post(): error uploading photo: ' . $result['error']); echo json_encode($result); exit(); } @@ -91,7 +90,7 @@ function js_upload_post_end(int &$b) { global $js_upload_jsonresponse; - Logger::notice('upload_post_end'); + DI::logger()->notice('upload_post_end'); if (!empty($js_upload_jsonresponse)) { echo $js_upload_jsonresponse; exit(); @@ -187,6 +186,10 @@ class js_upload_qqFileUploader { private $allowedExtensions; private $sizeLimit; + + /** + * @var js_upload_qqUploadedFileXhr|js_upload_qqUploadedFileForm|false + */ private $file; function __construct(array $allowedExtensions = [], $sizeLimit) @@ -234,7 +237,7 @@ class js_upload_qqFileUploader $filename = $pathinfo['filename']; if (!isset($pathinfo['extension'])) { - Logger::warning('extension isn\'t set.', ['filename' => $filename]); + DI::logger()->warning('extension isn\'t set.', ['filename' => $filename]); } $ext = $pathinfo['extension'] ?? ''; diff --git a/keycloakpassword/keycloakpassword.php b/keycloakpassword/keycloakpassword.php index e9809f86..11034ffe 100644 --- a/keycloakpassword/keycloakpassword.php +++ b/keycloakpassword/keycloakpassword.php @@ -7,7 +7,6 @@ */ use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\Database\DBA; use Friendica\DI; @@ -37,7 +36,7 @@ function keycloakpassword_request($client_id, $secret, $url, $params = []) $res = curl_exec($ch); if (curl_errno($ch)) { - Logger::error(curl_error($ch)); + DI::logger()->error(curl_error($ch)); } curl_close($ch); diff --git a/krynn/krynn.php b/krynn/krynn.php index f7e77c26..b57d827e 100644 --- a/krynn/krynn.php +++ b/krynn/krynn.php @@ -10,9 +10,7 @@ *"My body was my sacrifice... for my magic. This damage is permanent." - Raistlin Majere */ -use Friendica\App; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\DI; @@ -32,7 +30,7 @@ function krynn_install() Hook::register('addon_settings', 'addon/krynn/krynn.php', 'krynn_settings'); Hook::register('addon_settings_post', 'addon/krynn/krynn.php', 'krynn_settings_post'); - Logger::notice("installed krynn"); + DI::logger()->notice("installed krynn"); } function krynn_post_hook(&$item) diff --git a/langfilter/langfilter.php b/langfilter/langfilter.php index 2bf986f0..3a202fcd 100644 --- a/langfilter/langfilter.php +++ b/langfilter/langfilter.php @@ -99,8 +99,8 @@ function langfilter_addon_settings_post(array &$b) function langfilter_prepare_body_content_filter(&$hook_data) { - $logged_user = DI::userSession()->getLocalUserId(); - if (!$logged_user) { + $uid = $hook_data['uid'] ?? DI::userSession()->getLocalUserId(); + if (!$uid) { return; } @@ -112,8 +112,8 @@ function langfilter_prepare_body_content_filter(&$hook_data) } // Don't filter if language filter is disabled - if (!DI::pConfig()->get($logged_user, 'langfilter', 'enable', - !DI::pConfig()->get($logged_user, 'langfilter', 'disable')) + if (!DI::pConfig()->get($uid, 'langfilter', 'enable', + !DI::pConfig()->get($uid, 'langfilter', 'disable')) ) { return; } @@ -127,7 +127,7 @@ function langfilter_prepare_body_content_filter(&$hook_data) $naked_body = preg_replace('#\s+#', ' ', trim($naked_body)); // Don't filter if body lenght is below minimum - $minlen = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'langfilter', 'minlength', 32); + $minlen = DI::pConfig()->get($uid, 'langfilter', 'minlength', 32); if (!$minlen) { $minlen = 32; } @@ -136,8 +136,8 @@ function langfilter_prepare_body_content_filter(&$hook_data) return; } - $read_languages_string = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'langfilter', 'languages'); - $minconfidence = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'langfilter', 'minconfidence'); + $read_languages_string = DI::pConfig()->get($uid, 'langfilter', 'languages'); + $minconfidence = DI::pConfig()->get($uid, 'langfilter', 'minconfidence'); // Don't filter if no spoken languages are configured if (!$read_languages_string) { diff --git a/ldapauth/ldapauth.php b/ldapauth/ldapauth.php index 38e2d6a1..b80c5226 100644 --- a/ldapauth/ldapauth.php +++ b/ldapauth/ldapauth.php @@ -29,9 +29,7 @@ * The configuration options for this module are described in the config/ldapauth.config.php file */ -use Friendica\App; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Database\DBA; use Friendica\DI; use Friendica\Model\User; @@ -45,7 +43,7 @@ function ldapauth_install() function ldapauth_load_config(ConfigFileManager $loader) { - DI::app()->getConfigCache()->load($loader->loadAddonConfig('ldapauth'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); + DI::appHelper()->getConfigCache()->load($loader->loadAddonConfig('ldapauth'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); } function ldapauth_hook_authenticate(array &$b) @@ -70,54 +68,54 @@ function ldapauth_authenticate($username, $password) $ldap_autocreateaccount_nameattribute = DI::config()->get('ldapauth', 'ldap_autocreateaccount_nameattribute'); if (!extension_loaded('ldap') || !strlen($ldap_server)) { - Logger::error('Addon not configured or missing php-ldap extension', ['extension_loaded' => extension_loaded('ldap'), 'server' => $ldap_server]); + DI::logger()->error('Addon not configured or missing php-ldap extension', ['extension_loaded' => extension_loaded('ldap'), 'server' => $ldap_server]); return false; } if (!strlen($password)) { - Logger::error('Empty password disallowed', ['provided_password_length' => strlen($password)]); + DI::logger()->error('Empty password disallowed', ['provided_password_length' => strlen($password)]); return false; } $connect = @ldap_connect($ldap_server); if ($connect === false) { - Logger::warning('Could not connect to LDAP server', ['server' => $ldap_server]); + DI::logger()->warning('Could not connect to LDAP server', ['server' => $ldap_server]); return false; } @ldap_set_option($connect, LDAP_OPT_PROTOCOL_VERSION, 3); @ldap_set_option($connect, LDAP_OPT_REFERRALS, 0); if ((@ldap_bind($connect, $ldap_binddn, $ldap_bindpw)) === false) { - Logger::warning('Could not bind to LDAP server', ['server' => $ldap_server, 'binddn' => $ldap_binddn, 'errno' => ldap_errno($connect), 'error' => ldap_error($connect)]); + DI::logger()->warning('Could not bind to LDAP server', ['server' => $ldap_server, 'binddn' => $ldap_binddn, 'errno' => ldap_errno($connect), 'error' => ldap_error($connect)]); return false; } $res = @ldap_search($connect, $ldap_searchdn, $ldap_userattr . '=' . $username); if (!$res) { - Logger::notice('LDAP user not found.', ['searchdn' => $ldap_searchdn, 'userattr' => $ldap_userattr, 'username' => $username, 'errno' => ldap_errno($connect), 'error' => ldap_error($connect)]); + DI::logger()->notice('LDAP user not found.', ['searchdn' => $ldap_searchdn, 'userattr' => $ldap_userattr, 'username' => $username, 'errno' => ldap_errno($connect), 'error' => ldap_error($connect)]); return false; } $id = @ldap_first_entry($connect, $res); if (!$id) { - Logger::notice('Could not retrieve first LDAP entry.', ['searchdn' => $ldap_searchdn, 'userattr' => $ldap_userattr, 'username' => $username, 'errno' => ldap_errno($connect), 'error' => ldap_error($connect)]); + DI::logger()->notice('Could not retrieve first LDAP entry.', ['searchdn' => $ldap_searchdn, 'userattr' => $ldap_userattr, 'username' => $username, 'errno' => ldap_errno($connect), 'error' => ldap_error($connect)]); return false; } $dn = @ldap_get_dn($connect, $id); if (!@ldap_bind($connect, $dn, $password)) { - Logger::notice('Could not authenticate LDAP user with provided password', ['errno' => ldap_errno($connect), 'error' => ldap_error($connect)]); + DI::logger()->notice('Could not authenticate LDAP user with provided password', ['errno' => ldap_errno($connect), 'error' => ldap_error($connect)]); return false; } if (strlen($ldap_group) && @ldap_compare($connect, $ldap_group, 'member', $dn) !== true) { $errno = @ldap_errno($connect); if ($errno === 32) { - Logger::notice('LDAP Access Control Group does not exist', ['errno' => $errno, 'error' => ldap_error($connect)]); + DI::logger()->notice('LDAP Access Control Group does not exist', ['errno' => $errno, 'error' => ldap_error($connect)]); } elseif ($errno === 16) { - Logger::notice('LDAP membership attribute does not exist in access control group', ['errno' => $errno, 'error' => ldap_error($connect)]); + DI::logger()->notice('LDAP membership attribute does not exist in access control group', ['errno' => $errno, 'error' => ldap_error($connect)]); } else { - Logger::notice('LDAP user isn\'t part of the authorized group', ['dn' => $dn]); + DI::logger()->notice('LDAP user isn\'t part of the authorized group', ['dn' => $dn]); } @ldap_close($connect); @@ -141,7 +139,7 @@ function ldapauth_authenticate($username, $password) $authentication = User::getAuthenticationInfo($username); return User::getById($authentication['uid']); } catch (Exception $e) { - Logger::notice('LDAP authentication error: ' . $e->getMessage()); + DI::logger()->notice('LDAP authentication error: ' . $e->getMessage()); return false; } } @@ -149,7 +147,7 @@ function ldapauth_authenticate($username, $password) function ldap_createaccount($username, $password, $email, $name) { if (!strlen($email) || !strlen($name)) { - Logger::notice('Could not create local user from LDAP data, no email or nickname provided'); + DI::logger()->notice('Could not create local user from LDAP data, no email or nickname provided'); return false; } @@ -161,10 +159,10 @@ function ldap_createaccount($username, $password, $email, $name) 'password' => $password, 'verified' => 1 ]); - Logger::info('Local user created from LDAP data', ['username' => $username, 'name' => $name]); + DI::logger()->info('Local user created from LDAP data', ['username' => $username, 'name' => $name]); return $user; } catch (Exception $ex) { - Logger::error('Could not create local user from LDAP data', ['username' => $username, 'exception' => $ex->getMessage()]); + DI::logger()->error('Could not create local user from LDAP data', ['username' => $username, 'exception' => $ex->getMessage()]); } return false; diff --git a/leistungsschutzrecht/leistungsschutzrecht.php b/leistungsschutzrecht/leistungsschutzrecht.php index ec8091ac..891cb6ca 100644 --- a/leistungsschutzrecht/leistungsschutzrecht.php +++ b/leistungsschutzrecht/leistungsschutzrecht.php @@ -7,7 +7,6 @@ */ use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\DI; function leistungsschutzrecht_install() @@ -168,7 +167,7 @@ function leistungsschutzrecht_cron($b) if ($last) { $next = $last + 86400; if ($next > time()) { - Logger::notice('poll intervall not reached'); + DI::logger()->notice('poll intervall not reached'); return; } } diff --git a/libertree/libertree.php b/libertree/libertree.php index 1d997123..1489a029 100644 --- a/libertree/libertree.php +++ b/libertree/libertree.php @@ -6,10 +6,8 @@ * Author: Tony Baldwin */ -use Friendica\App; use Friendica\Content\Text\BBCode; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\Database\DBA; use Friendica\DI; @@ -131,7 +129,7 @@ function libertree_post_local(array &$b) function libertree_send(array &$b) { - Logger::notice('libertree_send: invoked'); + DI::logger()->notice('libertree_send: invoked'); if ($b['deleted'] || ($b['private'] == Item::PRIVATE) || ($b['created'] !== $b['edited'])) { return; @@ -197,6 +195,6 @@ function libertree_send(array &$b) ]; $result = DI::httpClient()->post($ltree_blog, $params)->getBodyString(); - Logger::notice('libertree: ' . $result); + DI::logger()->notice('libertree: ' . $result); } } diff --git a/libravatar/Services/Libravatar.php b/libravatar/Services/Libravatar.php index e51ef070..8b3dd493 100644 --- a/libravatar/Services/Libravatar.php +++ b/libravatar/Services/Libravatar.php @@ -361,7 +361,7 @@ class Services_Libravatar protected function domainGet($identifier) { if ($identifier === null) { - return null; + return ''; } // What are we, email or openid? Split ourself up and get the diff --git a/libravatar/libravatar.php b/libravatar/libravatar.php index 54594b88..6f47bf51 100644 --- a/libravatar/libravatar.php +++ b/libravatar/libravatar.php @@ -6,10 +6,7 @@ * Author: Klaus Weidenbach */ -use Friendica\App; -use Friendica\Core\Addon; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\DI; use Friendica\Core\Config\Util\ConfigFileManager; @@ -21,12 +18,12 @@ function libravatar_install() { Hook::register('load_config', 'addon/libravatar/libravatar.php', 'libravatar_load_config'); Hook::register('avatar_lookup', 'addon/libravatar/libravatar.php', 'libravatar_lookup'); - Logger::notice("registered libravatar in avatar_lookup hook"); + DI::logger()->notice("registered libravatar in avatar_lookup hook"); } function libravatar_load_config(ConfigFileManager $loader) { - DI::app()->getConfigCache()->load($loader->loadAddonConfig('libravatar'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); + DI::appHelper()->getConfigCache()->load($loader->loadAddonConfig('libravatar'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); } /** @@ -73,7 +70,9 @@ function libravatar_addon_admin(string &$o) 'pagan' => DI::l10n()->t('retro adventure game character'), ]; - if (Addon::isEnabled('gravatar')) { + $addonHelper = DI::addonHelper(); + + if ($addonHelper->isAddonEnabled('gravatar')) { $o = '
' .DI::l10n()->t('Information') .'

' .DI::l10n()->t('Gravatar addon is installed. Please disable the Gravatar addon.
The Libravatar addon will fall back to Gravatar if nothing was found at Libravatar.') .'



'; } diff --git a/ljpost/ljpost.php b/ljpost/ljpost.php index b416c605..fd7d1bd8 100644 --- a/ljpost/ljpost.php +++ b/ljpost/ljpost.php @@ -10,7 +10,6 @@ use Friendica\Content\Text\BBCode; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\DI; use Friendica\Model\Item; @@ -200,7 +199,7 @@ function ljpost_send(array &$b) EOT; - Logger::debug('ljpost: data: ' . $xml); + DI::logger()->debug('ljpost: data: ' . $xml); $x = ''; @@ -208,6 +207,6 @@ EOT; $x = DI::httpClient()->post($lj_blog, $xml, ['Content-Type' => 'text/xml'])->getBodyString(); } - Logger::info('posted to livejournal: ' . $x); + DI::logger()->info('posted to livejournal: ' . $x); } } diff --git a/mailstream/mailstream.php b/mailstream/mailstream.php index 9910a63d..98654831 100644 --- a/mailstream/mailstream.php +++ b/mailstream/mailstream.php @@ -8,7 +8,6 @@ use Friendica\Content\Text\BBCode; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\Core\System; use Friendica\Core\Worker; @@ -32,7 +31,7 @@ function mailstream_install() Hook::register('post_remote_end', 'addon/mailstream/mailstream.php', 'mailstream_post_hook'); Hook::register('mailstream_send_hook', 'addon/mailstream/mailstream.php', 'mailstream_send_hook'); - Logger::info("installed mailstream"); + DI::logger()->info("installed mailstream"); } /** @@ -86,7 +85,7 @@ function mailstream_generate_id(string $uri): string $host = DI::baseUrl()->getHost(); $resource = hash('md5', $uri); $message_id = "<" . $resource . "@" . $host . ">"; - Logger::debug('generated message ID', ['id' => $message_id, 'uri' => $uri]); + DI::logger()->debug('generated message ID', ['id' => $message_id, 'uri' => $uri]); return $message_id; } @@ -95,20 +94,20 @@ function mailstream_send_hook(array $data) $criteria = array('uid' => $data['uid'], 'contact-id' => $data['contact-id'], 'uri' => $data['uri']); $item = Post::selectFirst([], $criteria); if (empty($item)) { - Logger::error('could not find item'); + DI::logger()->error('could not find item'); return; } $user = User::getById($item['uid']); if (empty($user)) { - Logger::error('could not find user', ['uid' => $item['uid']]); + DI::logger()->error('could not find user', ['uid' => $item['uid']]); return; } if (!mailstream_send($data['message_id'], $item, $user)) { - Logger::debug('send failed, will retry', $data); + DI::logger()->debug('send failed, will retry', $data); if (!Worker::defer()) { - Logger::error('failed and could not defer', $data); + DI::logger()->error('failed and could not defer', $data); } } } @@ -124,32 +123,32 @@ function mailstream_send_hook(array $data) function mailstream_post_hook(array &$item) { if ($item['uid'] === 0) { - Logger::debug('mailstream: root user, skipping item ' . $item['id']); + DI::logger()->debug('mailstream: root user, skipping item ' . $item['id']); return; } if (!DI::pConfig()->get($item['uid'], 'mailstream', 'enabled')) { - Logger::debug('mailstream: not enabled.', ['item' => $item['id'], ' uid ' => $item['uid']]); + DI::logger()->debug('mailstream: not enabled.', ['item' => $item['id'], ' uid ' => $item['uid']]); return; } if (!$item['contact-id']) { - Logger::debug('no contact-id', ['item' => $item['id']]); + DI::logger()->debug('no contact-id', ['item' => $item['id']]); return; } if (!$item['uri']) { - Logger::debug('no uri', ['item' => $item['id']]); + DI::logger()->debug('no uri', ['item' => $item['id']]); return; } if ($item['verb'] == Activity::ANNOUNCE) { - Logger::debug('ignoring announce', ['item' => $item['id']]); + DI::logger()->debug('ignoring announce', ['item' => $item['id']]); return; } if (DI::pConfig()->get($item['uid'], 'mailstream', 'nolikes')) { if ($item['verb'] == Activity::LIKE) { - Logger::debug('ignoring like', ['item' => $item['id']]); + DI::logger()->debug('ignoring like', ['item' => $item['id']]); return; } if ($item['verb'] == Activity::DISLIKE) { - Logger::debug('ignoring dislike', ['item' => $item['id']]); + DI::logger()->debug('ignoring dislike', ['item' => $item['id']]); return; } } @@ -180,7 +179,7 @@ function mailstream_post_hook(array &$item) function mailstream_do_images(array &$item, array &$attachments) { if (!DI::pConfig()->get($item['uid'], 'mailstream', 'attachimg')) { - return; + return $attachments; } $attachments = []; @@ -200,7 +199,7 @@ function mailstream_do_images(array &$item, array &$attachments) try { $curlResult = DI::httpClient()->get($url, HttpClientAccept::DEFAULT, [HttpClientOptions::COOKIEJAR => $cookiejar]); if (!$curlResult->isSuccess()) { - Logger::debug('mailstream: fetch image url failed', [ + DI::logger()->debug('mailstream: fetch image url failed', [ 'url' => $url, 'item_id' => $item['id'], 'return_code' => $curlResult->getReturnCode() @@ -208,7 +207,7 @@ function mailstream_do_images(array &$item, array &$attachments) continue; } } catch (InvalidArgumentException $e) { - Logger::error('exception fetching url', ['url' => $url, 'item_id' => $item['id']]); + DI::logger()->error('exception fetching url', ['url' => $url, 'item_id' => $item['id']]); continue; } $attachments[$url] = [ @@ -309,7 +308,7 @@ function mailstream_subject(array $item): string } $contact = Contact::selectFirst([], ['id' => $item['contact-id'], 'uid' => $item['uid']]); if (!DBA::isResult($contact)) { - Logger::error('no contact', [ + DI::logger()->error('no contact', [ 'item' => $item['id'], 'plink' => $item['plink'], 'contact id' => $item['contact-id'], @@ -351,16 +350,16 @@ function mailstream_subject(array $item): string function mailstream_send(string $message_id, array $item, array $user): bool { if (!is_array($item)) { - Logger::error('item is empty', ['message_id' => $message_id]); + DI::logger()->error('item is empty', ['message_id' => $message_id]); return false; } if (!$item['visible']) { - Logger::debug('item not yet visible', ['item uri' => $item['uri']]); + DI::logger()->debug('item not yet visible', ['item uri' => $item['uri']]); return false; } if (!$message_id) { - Logger::error('no message ID supplied', ['item uri' => $item['uri'], 'user email' => $user['email']]); + DI::logger()->error('no message ID supplied', ['item uri' => $item['uri'], 'user email' => $user['email']]); return true; } @@ -418,15 +417,15 @@ function mailstream_send(string $message_id, array $item, array $user): bool if (!$mail->Send()) { throw new Exception($mail->ErrorInfo); } - Logger::debug('sent message', [ + DI::logger()->debug('sent message', [ 'message ID' => $mail->MessageID, 'subject' => $mail->Subject, 'address' => $address ]); } catch (phpmailerException $e) { - Logger::debug('PHPMailer exception sending message', ['id' => $message_id, 'error' => $e->errorMessage()]); + DI::logger()->debug('PHPMailer exception sending message', ['id' => $message_id, 'error' => $e->errorMessage()]); } catch (Exception $e) { - Logger::debug('exception sending message', ['id' => $message_id, 'error' => $e->getMessage()]); + DI::logger()->debug('exception sending message', ['id' => $message_id, 'error' => $e->getMessage()]); } return true; diff --git a/markdown/markdown.php b/markdown/markdown.php index 6f459244..1ef6cd9a 100644 --- a/markdown/markdown.php +++ b/markdown/markdown.php @@ -5,7 +5,6 @@ * Version: 0.1 * Author: Michael Vogel */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\Content\Text\Markdown; use Friendica\Core\Renderer; @@ -27,7 +26,7 @@ function markdown_addon_settings(array &$data) $t = Renderer::getMarkupTemplate('settings.tpl', 'addon/markdown/'); $html = Renderer::replaceMacros($t, [ - '$enabled' => ['enabled', DI::l10n()->t('Enable Markdown parsing'), $enabled, DI::l10n()->t('If enabled, adds Markdown support to the Compose Post form.')], + '$enabled' => ['markdown-enabled', DI::l10n()->t('Enable Markdown parsing'), $enabled, DI::l10n()->t('If enabled, adds Markdown support to the Compose Post form.')], ]); $data = [ @@ -43,7 +42,7 @@ function markdown_addon_settings_post(array &$b) return; } - DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'markdown', 'enabled', intval($_POST['enabled'])); + DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'markdown', 'enabled', intval($_POST['markdown-enabled'])); } function markdown_post_local_start(&$request) { diff --git a/mathjax/mathjax.php b/mathjax/mathjax.php index d0046cf7..e96aaddf 100644 --- a/mathjax/mathjax.php +++ b/mathjax/mathjax.php @@ -8,7 +8,6 @@ * License: 3-clause BSD license */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\Core\Renderer; use Friendica\DI; diff --git a/membersince/membersince.php b/membersince/membersince.php index 448b8cf2..df6388c6 100644 --- a/membersince/membersince.php +++ b/membersince/membersince.php @@ -17,7 +17,11 @@ function membersince_install() Hook::register('profile_advanced', 'addon/membersince/membersince.php', 'membersince_display'); } -function membersince_display(array &$b) +/** + * @param array|string|null $b + * @return void + */ +function membersince_display(&$b) { $uid = DI::userSession()->getLocalUserId(); @@ -59,7 +63,7 @@ function membersince_display(array &$b) $div->appendChild($entry); $elm->parentNode->insertBefore($div, $elm->nextSibling); - $b = $doc->saveHTML(); + $b = (string) $doc->saveHTML(); } else { // Works in Vier. $b = preg_replace('/<\/dl>/', "\n\n\n
\n
" . DI::l10n()->t('Member since:') . "
\n
" . DateTimeFormat::local($user['register_date']) . "
\n
", $b, 1); diff --git a/monolog/README.md b/monolog/README.md new file mode 100644 index 00000000..efb7959a --- /dev/null +++ b/monolog/README.md @@ -0,0 +1,4 @@ +# Monolog Addon + +A Logging framework with lots of additions (see [Monolog](https://github.com/Seldaek/monolog/)). +There are just Friendica additions inside the src directory. diff --git a/monolog/monolog.php b/monolog/monolog.php index b13efff9..f194aac4 100644 --- a/monolog/monolog.php +++ b/monolog/monolog.php @@ -1,7 +1,7 @@ introspection = $introspection; + $this->config = $config; + } + + /** + * Creates and returns a PSR-3 Logger instance. + * + * Calling this method multiple times with the same parameters SHOULD return the same object. + * + * @param \Psr\Log\LogLevel::* $logLevel The log level + * @param \Friendica\Core\Logger\Capability\LogChannel::* $logChannel The log channel + */ + public function createLogger(string $logLevel, string $logChannel): LoggerInterface { $loggerTimeZone = new \DateTimeZone('UTC'); - $logger = new Logger($this->channel); + $logger = new Logger($logChannel); $logger->setTimezone($loggerTimeZone); $logger->pushProcessor(new PsrLogMessageProcessor()); $logger->pushProcessor(new ProcessIdProcessor()); $logger->pushProcessor(new UidProcessor()); $logger->pushProcessor(new IntrospectionProcessor($this->introspection, LogLevel::DEBUG)); - $logfile = $config->get('system', 'logfile'); + $logfile = $this->config->get('system', 'logfile'); // just add a stream in case it's either writable or not file if (is_writable($logfile)) { - $loglevel = $loglevel ?? static::mapLegacyConfigDebugLevel($config->get('system', 'loglevel')); - $loglevel = Logger::toMonologLevel($loglevel); + $logLevel = Logger::toMonologLevel($logLevel); // fallback to notice if an invalid loglevel is set - if (!is_int($loglevel)) { - $loglevel = LogLevel::NOTICE; + if (!is_int($logLevel)) { + $logLevel = LogLevel::NOTICE; } - $fileHandler = new StreamHandler($logfile, $loglevel); + $fileHandler = new StreamHandler($logfile, $logLevel); $formatter = new LineFormatter("%datetime% %channel% [%level_name%]: %message% %context% %extra%\n"); $fileHandler->setFormatter($formatter); diff --git a/monolog/static/dependencies.config.php b/monolog/static/dependencies.config.php index e3066594..f992d69c 100644 --- a/monolog/static/dependencies.config.php +++ b/monolog/static/dependencies.config.php @@ -20,10 +20,8 @@ */ return [ - \Monolog\Logger::class => [ - 'instanceOf' => \Friendica\Addon\monolog\src\Factory\Monolog::class, - 'call' => [ - ['create', [], \Dice\Dice::CHAIN_CALL], - ], + \Friendica\Core\Logger\Factory\LoggerFactory::class => [ + 'instanceOf' => \Friendica\Addon\monolog\src\Factory\MonologFactory::class, + 'call' => null, ], ]; diff --git a/monolog/static/strategies.config.php b/monolog/static/strategies.config.php deleted file mode 100644 index 87153839..00000000 --- a/monolog/static/strategies.config.php +++ /dev/null @@ -1,26 +0,0 @@ -. - * - */ - -return [ - \Psr\Log\LoggerInterface::class => [ - \Monolog\Logger::class => ['monolog'], - ], -]; diff --git a/morechoice/morechoice.php b/morechoice/morechoice.php index fe726d27..fbb88ce1 100644 --- a/morechoice/morechoice.php +++ b/morechoice/morechoice.php @@ -8,7 +8,6 @@ * Status: Deprecated */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\DI; diff --git a/morepokes/morepokes.php b/morepokes/morepokes.php index abe59a6e..2ac09a73 100644 --- a/morepokes/morepokes.php +++ b/morepokes/morepokes.php @@ -7,7 +7,6 @@ * */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\DI; diff --git a/newmemberwidget/newmemberwidget.php b/newmemberwidget/newmemberwidget.php index 01977d0c..ba7dfb39 100644 --- a/newmemberwidget/newmemberwidget.php +++ b/newmemberwidget/newmemberwidget.php @@ -6,10 +6,8 @@ * Author: Tobias Diekershoff ***/ -use Friendica\App; use Friendica\Content\Text\BBCode; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\DI; use Friendica\Model\User; @@ -17,7 +15,7 @@ use Friendica\Model\User; function newmemberwidget_install() { Hook::register( 'network_mod_init', 'addon/newmemberwidget/newmemberwidget.php', 'newmemberwidget_network_mod_init'); - Logger::notice('newmemberwidget installed'); + DI::logger()->notice('newmemberwidget installed'); } function newmemberwidget_network_mod_init ($b) diff --git a/nitter/nitter.php b/nitter/nitter.php index 946b18c0..adbfd6b0 100644 --- a/nitter/nitter.php +++ b/nitter/nitter.php @@ -25,7 +25,6 @@ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\Core\Renderer; use Friendica\DI; diff --git a/nominatim/nominatim.php b/nominatim/nominatim.php index 6ad4a8a3..3a567b7b 100644 --- a/nominatim/nominatim.php +++ b/nominatim/nominatim.php @@ -6,9 +6,7 @@ * Author: Michael Vogel */ -use Friendica\App; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\DI; @@ -46,19 +44,19 @@ function nominatim_resolve_item(array &$item) $s = DI::httpClient()->fetch('https://nominatim.openstreetmap.org/reverse?lat=' . $coords[0] . '&lon=' . $coords[1] . '&format=json&addressdetails=0&accept-language=' . $language); if (empty($s)) { - Logger::info('API could not be queried'); + DI::logger()->info('API could not be queried'); return; } $data = json_decode($s, true); if (empty($data['display_name'])) { - Logger::info('No results found for coordinates', ['coordinates' => $item['coord'], 'data' => $data]); + DI::logger()->info('No results found for coordinates', ['coordinates' => $item['coord'], 'data' => $data]); return; } $item['location'] = $data['display_name']; - Logger::info('Got location', ['lat' => $coords[0], 'long' => $coords[1], 'location' => $item['location']]); + DI::logger()->info('Got location', ['lat' => $coords[0], 'long' => $coords[1], 'location' => $item['location']]); if (!empty($item['location'])) { DI::cache()->set('nominatim:' . $language . ':' . $coords[0] . '-' . $coords[1], $item['location']); diff --git a/notifyall/notifyall.php b/notifyall/notifyall.php index 966a9184..f814c4f5 100644 --- a/notifyall/notifyall.php +++ b/notifyall/notifyall.php @@ -9,9 +9,7 @@ */ use Friendica\Addon\notifyall\NotifyAllEmail; -use Friendica\App; use Friendica\Database\DBA; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\DI; @@ -59,7 +57,7 @@ function notifyall_post() $notifyEmail = new NotifyAllEmail(DI::l10n(), DI::config(), DI::baseUrl(), $text); - foreach ($recipients as $recipient) { + foreach (DBA::toArray($recipients) as $recipient) { DI::emailer()->send($notifyEmail->withRecipient($recipient['email'])); } diff --git a/nsfw/nsfw.php b/nsfw/nsfw.php index 674fc201..37d34d7d 100644 --- a/nsfw/nsfw.php +++ b/nsfw/nsfw.php @@ -104,12 +104,13 @@ function nsfw_addon_settings_post(array &$b) function nsfw_prepare_body_content_filter(&$hook_data) { $words = null; - if (DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'nsfw', 'disable')) { + $uid = $hook_data['uid'] ?? DI::userSession()->getLocalUserId(); + if (DI::pConfig()->get($uid, 'nsfw', 'disable')) { return; } - if (DI::userSession()->getLocalUserId()) { - $words = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'nsfw', 'words'); + if ($uid) { + $words = DI::pConfig()->get($uid, 'nsfw', 'words'); } if ($words) { @@ -136,10 +137,10 @@ function nsfw_prepare_body_content_filter(&$hook_data) break; case '#': // Hashtag-only search $tag_search = true; - $found = nsfw_find_word_in_item_tags($hook_data['item']['hashtags'], substr($word, 1)); + $found = nsfw_find_word_in_item_tags($hook_data['item']['hashtags'] ?? [], substr($word, 1)); break; default: - $found = strpos($body, $word) !== false || nsfw_find_word_in_item_tags($hook_data['item']['tags'], $word); + $found = strpos($body, $word) !== false || nsfw_find_word_in_item_tags($hook_data['item']['tags'] ?? [], $word); break; } diff --git a/numfriends/numfriends.php b/numfriends/numfriends.php index 538a4a3e..5652c8f0 100644 --- a/numfriends/numfriends.php +++ b/numfriends/numfriends.php @@ -6,9 +6,7 @@ * Author: Mike Macgirvin */ -use Friendica\App; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\DI; @@ -17,7 +15,7 @@ function numfriends_install() { Hook::register('addon_settings', 'addon/numfriends/numfriends.php', 'numfriends_settings'); Hook::register('addon_settings_post', 'addon/numfriends/numfriends.php', 'numfriends_settings_post'); - Logger::notice("installed numfriends"); + DI::logger()->notice("installed numfriends"); } /** @@ -39,7 +37,7 @@ function numfriends_settings_post($post) { /** * - * Called from the Addon Setting form. + * Called from the Addon Setting form. * Add our own settings info to the page. * */ @@ -50,7 +48,7 @@ function numfriends_settings(array &$data) } $numfriends = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'system', 'display_friend_count', 24); - + $t = Renderer::getMarkupTemplate('settings.tpl', 'addon/numfriends/'); $html = Renderer::replaceMacros($t, [ '$numfriends' => ['numfriends', DI::l10n()->t('How many contacts to display on profile sidebar'), $numfriends], diff --git a/openstreetmap/openstreetmap.php b/openstreetmap/openstreetmap.php index ae22aff0..bf0f54b6 100644 --- a/openstreetmap/openstreetmap.php +++ b/openstreetmap/openstreetmap.php @@ -9,10 +9,8 @@ * */ -use Friendica\App; use Friendica\Core\Cache\Enum\Duration; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\DI; use Friendica\Core\Config\Util\ConfigFileManager; @@ -32,12 +30,12 @@ function openstreetmap_install() Hook::register('Map::getCoordinates', 'addon/openstreetmap/openstreetmap.php', 'openstreetmap_get_coordinates'); Hook::register('page_header', 'addon/openstreetmap/openstreetmap.php', 'openstreetmap_alterheader'); - Logger::notice("installed openstreetmap"); + DI::logger()->notice("installed openstreetmap"); } function openstreetmap_load_config(ConfigFileManager $loader) { - DI::app()->getConfigCache()->load($loader->loadAddonConfig('openstreetmap'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); + DI::appHelper()->getConfigCache()->load($loader->loadAddonConfig('openstreetmap'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); } function openstreetmap_alterheader(&$navHtml) @@ -155,8 +153,8 @@ function openstreetmap_generate_map(array &$b) $lat = $b['lat']; // round($b['lat'], 5); $lon = $b['lon']; // round($b['lon'], 5); - Logger::debug('lat: ' . $lat); - Logger::debug('lon: ' . $lon); + DI::logger()->debug('lat: ' . $lat); + DI::logger()->debug('lon: ' . $lon); $cardlink = '=7.0" }, - "platform-dev": [], - "plugin-api-version": "1.1.0" + "platform-dev": {}, + "plugin-api-version": "2.6.0" } diff --git a/phpmailer/phpmailer.php b/phpmailer/phpmailer.php index 4c12709d..10287a04 100644 --- a/phpmailer/phpmailer.php +++ b/phpmailer/phpmailer.php @@ -7,7 +7,6 @@ * Maintainer: Hypolite Petovan */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\DI; use Friendica\Object\EMail\IEmail; @@ -25,14 +24,18 @@ function phpmailer_install() function phpmailer_load_config(ConfigFileManager $loader) { - DI::app()->getConfigCache()->load($loader->loadAddonConfig('phpmailer'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); + DI::appHelper()->getConfigCache()->load($loader->loadAddonConfig('phpmailer'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); } /** - * @param IEmail $email + * @param null|IEmail $email */ -function phpmailer_emailer_send_prepare(IEmail &$email) +function phpmailer_emailer_send_prepare(?IEmail &$email) { + if ($email === null) { + return; + } + // Passing `true` enables exceptions $mailer = new PHPMailer(true); try { diff --git a/phpmailer/vendor/autoload.php b/phpmailer/vendor/autoload.php index 60925835..1d45b283 100644 --- a/phpmailer/vendor/autoload.php +++ b/phpmailer/vendor/autoload.php @@ -2,6 +2,24 @@ // autoload.php @generated by Composer +if (PHP_VERSION_ID < 50600) { + if (!headers_sent()) { + header('HTTP/1.1 500 Internal Server Error'); + } + $err = 'Composer 2.3.0 dropped support for autoloading on PHP <5.6 and you are running '.PHP_VERSION.', please upgrade PHP or use Composer 2.2 LTS via "composer self-update --2.2". Aborting.'.PHP_EOL; + if (!ini_get('display_errors')) { + if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') { + fwrite(STDERR, $err); + } elseif (!headers_sent()) { + echo $err; + } + } + trigger_error( + $err, + E_USER_ERROR + ); +} + require_once __DIR__ . '/composer/autoload_real.php'; return ComposerAutoloaderInitPhpMailerAddon::getLoader(); diff --git a/phpmailer/vendor/composer/ClassLoader.php b/phpmailer/vendor/composer/ClassLoader.php index 03b9bb9c..7824d8f7 100644 --- a/phpmailer/vendor/composer/ClassLoader.php +++ b/phpmailer/vendor/composer/ClassLoader.php @@ -37,26 +37,81 @@ namespace Composer\Autoload; * * @author Fabien Potencier * @author Jordi Boggiano - * @see http://www.php-fig.org/psr/psr-0/ - * @see http://www.php-fig.org/psr/psr-4/ + * @see https://www.php-fig.org/psr/psr-0/ + * @see https://www.php-fig.org/psr/psr-4/ */ class ClassLoader { + /** @var \Closure(string):void */ + private static $includeFile; + + /** @var string|null */ + private $vendorDir; + // PSR-4 + /** + * @var array> + */ private $prefixLengthsPsr4 = array(); + /** + * @var array> + */ private $prefixDirsPsr4 = array(); + /** + * @var list + */ private $fallbackDirsPsr4 = array(); // PSR-0 + /** + * List of PSR-0 prefixes + * + * Structured as array('F (first letter)' => array('Foo\Bar (full prefix)' => array('path', 'path2'))) + * + * @var array>> + */ private $prefixesPsr0 = array(); + /** + * @var list + */ private $fallbackDirsPsr0 = array(); + /** @var bool */ private $useIncludePath = false; + + /** + * @var array + */ private $classMap = array(); + + /** @var bool */ private $classMapAuthoritative = false; + + /** + * @var array + */ private $missingClasses = array(); + + /** @var string|null */ private $apcuPrefix; + /** + * @var array + */ + private static $registeredLoaders = array(); + + /** + * @param string|null $vendorDir + */ + public function __construct($vendorDir = null) + { + $this->vendorDir = $vendorDir; + self::initializeIncludeClosure(); + } + + /** + * @return array> + */ public function getPrefixes() { if (!empty($this->prefixesPsr0)) { @@ -66,28 +121,42 @@ class ClassLoader return array(); } + /** + * @return array> + */ public function getPrefixesPsr4() { return $this->prefixDirsPsr4; } + /** + * @return list + */ public function getFallbackDirs() { return $this->fallbackDirsPsr0; } + /** + * @return list + */ public function getFallbackDirsPsr4() { return $this->fallbackDirsPsr4; } + /** + * @return array Array of classname => path + */ public function getClassMap() { return $this->classMap; } /** - * @param array $classMap Class to filename map + * @param array $classMap Class to filename map + * + * @return void */ public function addClassMap(array $classMap) { @@ -102,22 +171,25 @@ class ClassLoader * Registers a set of PSR-0 directories for a given prefix, either * appending or prepending to the ones previously set for this prefix. * - * @param string $prefix The prefix - * @param array|string $paths The PSR-0 root directories - * @param bool $prepend Whether to prepend the directories + * @param string $prefix The prefix + * @param list|string $paths The PSR-0 root directories + * @param bool $prepend Whether to prepend the directories + * + * @return void */ public function add($prefix, $paths, $prepend = false) { + $paths = (array) $paths; if (!$prefix) { if ($prepend) { $this->fallbackDirsPsr0 = array_merge( - (array) $paths, + $paths, $this->fallbackDirsPsr0 ); } else { $this->fallbackDirsPsr0 = array_merge( $this->fallbackDirsPsr0, - (array) $paths + $paths ); } @@ -126,19 +198,19 @@ class ClassLoader $first = $prefix[0]; if (!isset($this->prefixesPsr0[$first][$prefix])) { - $this->prefixesPsr0[$first][$prefix] = (array) $paths; + $this->prefixesPsr0[$first][$prefix] = $paths; return; } if ($prepend) { $this->prefixesPsr0[$first][$prefix] = array_merge( - (array) $paths, + $paths, $this->prefixesPsr0[$first][$prefix] ); } else { $this->prefixesPsr0[$first][$prefix] = array_merge( $this->prefixesPsr0[$first][$prefix], - (array) $paths + $paths ); } } @@ -147,25 +219,28 @@ class ClassLoader * Registers a set of PSR-4 directories for a given namespace, either * appending or prepending to the ones previously set for this namespace. * - * @param string $prefix The prefix/namespace, with trailing '\\' - * @param array|string $paths The PSR-4 base directories - * @param bool $prepend Whether to prepend the directories + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param list|string $paths The PSR-4 base directories + * @param bool $prepend Whether to prepend the directories * * @throws \InvalidArgumentException + * + * @return void */ public function addPsr4($prefix, $paths, $prepend = false) { + $paths = (array) $paths; if (!$prefix) { // Register directories for the root namespace. if ($prepend) { $this->fallbackDirsPsr4 = array_merge( - (array) $paths, + $paths, $this->fallbackDirsPsr4 ); } else { $this->fallbackDirsPsr4 = array_merge( $this->fallbackDirsPsr4, - (array) $paths + $paths ); } } elseif (!isset($this->prefixDirsPsr4[$prefix])) { @@ -175,18 +250,18 @@ class ClassLoader throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); } $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; - $this->prefixDirsPsr4[$prefix] = (array) $paths; + $this->prefixDirsPsr4[$prefix] = $paths; } elseif ($prepend) { // Prepend directories for an already registered namespace. $this->prefixDirsPsr4[$prefix] = array_merge( - (array) $paths, + $paths, $this->prefixDirsPsr4[$prefix] ); } else { // Append directories for an already registered namespace. $this->prefixDirsPsr4[$prefix] = array_merge( $this->prefixDirsPsr4[$prefix], - (array) $paths + $paths ); } } @@ -195,8 +270,10 @@ class ClassLoader * Registers a set of PSR-0 directories for a given prefix, * replacing any others previously set for this prefix. * - * @param string $prefix The prefix - * @param array|string $paths The PSR-0 base directories + * @param string $prefix The prefix + * @param list|string $paths The PSR-0 base directories + * + * @return void */ public function set($prefix, $paths) { @@ -211,10 +288,12 @@ class ClassLoader * Registers a set of PSR-4 directories for a given namespace, * replacing any others previously set for this namespace. * - * @param string $prefix The prefix/namespace, with trailing '\\' - * @param array|string $paths The PSR-4 base directories + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param list|string $paths The PSR-4 base directories * * @throws \InvalidArgumentException + * + * @return void */ public function setPsr4($prefix, $paths) { @@ -234,6 +313,8 @@ class ClassLoader * Turns on searching the include path for class files. * * @param bool $useIncludePath + * + * @return void */ public function setUseIncludePath($useIncludePath) { @@ -256,6 +337,8 @@ class ClassLoader * that have not been registered with the class map. * * @param bool $classMapAuthoritative + * + * @return void */ public function setClassMapAuthoritative($classMapAuthoritative) { @@ -276,6 +359,8 @@ class ClassLoader * APCu prefix to use to cache found/not-found classes, if the extension is enabled. * * @param string|null $apcuPrefix + * + * @return void */ public function setApcuPrefix($apcuPrefix) { @@ -296,33 +381,55 @@ class ClassLoader * Registers this instance as an autoloader. * * @param bool $prepend Whether to prepend the autoloader or not + * + * @return void */ public function register($prepend = false) { spl_autoload_register(array($this, 'loadClass'), true, $prepend); + + if (null === $this->vendorDir) { + return; + } + + if ($prepend) { + self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders; + } else { + unset(self::$registeredLoaders[$this->vendorDir]); + self::$registeredLoaders[$this->vendorDir] = $this; + } } /** * Unregisters this instance as an autoloader. + * + * @return void */ public function unregister() { spl_autoload_unregister(array($this, 'loadClass')); + + if (null !== $this->vendorDir) { + unset(self::$registeredLoaders[$this->vendorDir]); + } } /** * Loads the given class or interface. * * @param string $class The name of the class - * @return bool|null True if loaded, null otherwise + * @return true|null True if loaded, null otherwise */ public function loadClass($class) { if ($file = $this->findFile($class)) { - includeFile($file); + $includeFile = self::$includeFile; + $includeFile($file); return true; } + + return null; } /** @@ -367,6 +474,21 @@ class ClassLoader return $file; } + /** + * Returns the currently registered loaders keyed by their corresponding vendor directories. + * + * @return array + */ + public static function getRegisteredLoaders() + { + return self::$registeredLoaders; + } + + /** + * @param string $class + * @param string $ext + * @return string|false + */ private function findFileWithExtension($class, $ext) { // PSR-4 lookup @@ -432,14 +554,26 @@ class ClassLoader return false; } -} -/** - * Scope isolated include. - * - * Prevents access to $this/self from included files. - */ -function includeFile($file) -{ - include $file; + /** + * @return void + */ + private static function initializeIncludeClosure() + { + if (self::$includeFile !== null) { + return; + } + + /** + * Scope isolated include. + * + * Prevents access to $this/self from included files. + * + * @param string $file + * @return void + */ + self::$includeFile = \Closure::bind(static function($file) { + include $file; + }, null, null); + } } diff --git a/phpmailer/vendor/composer/InstalledVersions.php b/phpmailer/vendor/composer/InstalledVersions.php new file mode 100644 index 00000000..51e734a7 --- /dev/null +++ b/phpmailer/vendor/composer/InstalledVersions.php @@ -0,0 +1,359 @@ + + * Jordi Boggiano + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer; + +use Composer\Autoload\ClassLoader; +use Composer\Semver\VersionParser; + +/** + * This class is copied in every Composer installed project and available to all + * + * See also https://getcomposer.org/doc/07-runtime.md#installed-versions + * + * To require its presence, you can require `composer-runtime-api ^2.0` + * + * @final + */ +class InstalledVersions +{ + /** + * @var mixed[]|null + * @psalm-var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array}|array{}|null + */ + private static $installed; + + /** + * @var bool|null + */ + private static $canGetVendors; + + /** + * @var array[] + * @psalm-var array}> + */ + private static $installedByVendor = array(); + + /** + * Returns a list of all package names which are present, either by being installed, replaced or provided + * + * @return string[] + * @psalm-return list + */ + public static function getInstalledPackages() + { + $packages = array(); + foreach (self::getInstalled() as $installed) { + $packages[] = array_keys($installed['versions']); + } + + if (1 === \count($packages)) { + return $packages[0]; + } + + return array_keys(array_flip(\call_user_func_array('array_merge', $packages))); + } + + /** + * Returns a list of all package names with a specific type e.g. 'library' + * + * @param string $type + * @return string[] + * @psalm-return list + */ + public static function getInstalledPackagesByType($type) + { + $packagesByType = array(); + + foreach (self::getInstalled() as $installed) { + foreach ($installed['versions'] as $name => $package) { + if (isset($package['type']) && $package['type'] === $type) { + $packagesByType[] = $name; + } + } + } + + return $packagesByType; + } + + /** + * Checks whether the given package is installed + * + * This also returns true if the package name is provided or replaced by another package + * + * @param string $packageName + * @param bool $includeDevRequirements + * @return bool + */ + public static function isInstalled($packageName, $includeDevRequirements = true) + { + foreach (self::getInstalled() as $installed) { + if (isset($installed['versions'][$packageName])) { + return $includeDevRequirements || !isset($installed['versions'][$packageName]['dev_requirement']) || $installed['versions'][$packageName]['dev_requirement'] === false; + } + } + + return false; + } + + /** + * Checks whether the given package satisfies a version constraint + * + * e.g. If you want to know whether version 2.3+ of package foo/bar is installed, you would call: + * + * Composer\InstalledVersions::satisfies(new VersionParser, 'foo/bar', '^2.3') + * + * @param VersionParser $parser Install composer/semver to have access to this class and functionality + * @param string $packageName + * @param string|null $constraint A version constraint to check for, if you pass one you have to make sure composer/semver is required by your package + * @return bool + */ + public static function satisfies(VersionParser $parser, $packageName, $constraint) + { + $constraint = $parser->parseConstraints((string) $constraint); + $provided = $parser->parseConstraints(self::getVersionRanges($packageName)); + + return $provided->matches($constraint); + } + + /** + * Returns a version constraint representing all the range(s) which are installed for a given package + * + * It is easier to use this via isInstalled() with the $constraint argument if you need to check + * whether a given version of a package is installed, and not just whether it exists + * + * @param string $packageName + * @return string Version constraint usable with composer/semver + */ + public static function getVersionRanges($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + $ranges = array(); + if (isset($installed['versions'][$packageName]['pretty_version'])) { + $ranges[] = $installed['versions'][$packageName]['pretty_version']; + } + if (array_key_exists('aliases', $installed['versions'][$packageName])) { + $ranges = array_merge($ranges, $installed['versions'][$packageName]['aliases']); + } + if (array_key_exists('replaced', $installed['versions'][$packageName])) { + $ranges = array_merge($ranges, $installed['versions'][$packageName]['replaced']); + } + if (array_key_exists('provided', $installed['versions'][$packageName])) { + $ranges = array_merge($ranges, $installed['versions'][$packageName]['provided']); + } + + return implode(' || ', $ranges); + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @param string $packageName + * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present + */ + public static function getVersion($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + if (!isset($installed['versions'][$packageName]['version'])) { + return null; + } + + return $installed['versions'][$packageName]['version']; + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @param string $packageName + * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present + */ + public static function getPrettyVersion($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + if (!isset($installed['versions'][$packageName]['pretty_version'])) { + return null; + } + + return $installed['versions'][$packageName]['pretty_version']; + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @param string $packageName + * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as reference + */ + public static function getReference($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + if (!isset($installed['versions'][$packageName]['reference'])) { + return null; + } + + return $installed['versions'][$packageName]['reference']; + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @param string $packageName + * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as install path. Packages of type metapackages also have a null install path. + */ + public static function getInstallPath($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + return isset($installed['versions'][$packageName]['install_path']) ? $installed['versions'][$packageName]['install_path'] : null; + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @return array + * @psalm-return array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool} + */ + public static function getRootPackage() + { + $installed = self::getInstalled(); + + return $installed[0]['root']; + } + + /** + * Returns the raw installed.php data for custom implementations + * + * @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect. + * @return array[] + * @psalm-return array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} + */ + public static function getRawData() + { + @trigger_error('getRawData only returns the first dataset loaded, which may not be what you expect. Use getAllRawData() instead which returns all datasets for all autoloaders present in the process.', E_USER_DEPRECATED); + + if (null === self::$installed) { + // only require the installed.php file if this file is loaded from its dumped location, + // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937 + if (substr(__DIR__, -8, 1) !== 'C') { + self::$installed = include __DIR__ . '/installed.php'; + } else { + self::$installed = array(); + } + } + + return self::$installed; + } + + /** + * Returns the raw data of all installed.php which are currently loaded for custom implementations + * + * @return array[] + * @psalm-return list}> + */ + public static function getAllRawData() + { + return self::getInstalled(); + } + + /** + * Lets you reload the static array from another file + * + * This is only useful for complex integrations in which a project needs to use + * this class but then also needs to execute another project's autoloader in process, + * and wants to ensure both projects have access to their version of installed.php. + * + * A typical case would be PHPUnit, where it would need to make sure it reads all + * the data it needs from this class, then call reload() with + * `require $CWD/vendor/composer/installed.php` (or similar) as input to make sure + * the project in which it runs can then also use this class safely, without + * interference between PHPUnit's dependencies and the project's dependencies. + * + * @param array[] $data A vendor/composer/installed.php data set + * @return void + * + * @psalm-param array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} $data + */ + public static function reload($data) + { + self::$installed = $data; + self::$installedByVendor = array(); + } + + /** + * @return array[] + * @psalm-return list}> + */ + private static function getInstalled() + { + if (null === self::$canGetVendors) { + self::$canGetVendors = method_exists('Composer\Autoload\ClassLoader', 'getRegisteredLoaders'); + } + + $installed = array(); + + if (self::$canGetVendors) { + foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) { + if (isset(self::$installedByVendor[$vendorDir])) { + $installed[] = self::$installedByVendor[$vendorDir]; + } elseif (is_file($vendorDir.'/composer/installed.php')) { + /** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} $required */ + $required = require $vendorDir.'/composer/installed.php'; + $installed[] = self::$installedByVendor[$vendorDir] = $required; + if (null === self::$installed && strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) { + self::$installed = $installed[count($installed) - 1]; + } + } + } + } + + if (null === self::$installed) { + // only require the installed.php file if this file is loaded from its dumped location, + // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937 + if (substr(__DIR__, -8, 1) !== 'C') { + /** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} $required */ + $required = require __DIR__ . '/installed.php'; + self::$installed = $required; + } else { + self::$installed = array(); + } + } + + if (self::$installed !== array()) { + $installed[] = self::$installed; + } + + return $installed; + } +} diff --git a/phpmailer/vendor/composer/autoload_classmap.php b/phpmailer/vendor/composer/autoload_classmap.php index 31c59aff..c20440c1 100644 --- a/phpmailer/vendor/composer/autoload_classmap.php +++ b/phpmailer/vendor/composer/autoload_classmap.php @@ -2,10 +2,11 @@ // autoload_classmap.php @generated by Composer -$vendorDir = dirname(dirname(__FILE__)); +$vendorDir = dirname(__DIR__); $baseDir = dirname($vendorDir); return array( + 'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php', 'PHPMailer\\PHPMailer\\DSNConfigurator' => $vendorDir . '/phpmailer/phpmailer/src/DSNConfigurator.php', 'PHPMailer\\PHPMailer\\Exception' => $vendorDir . '/phpmailer/phpmailer/src/Exception.php', 'PHPMailer\\PHPMailer\\OAuth' => $vendorDir . '/phpmailer/phpmailer/src/OAuth.php', diff --git a/phpmailer/vendor/composer/autoload_namespaces.php b/phpmailer/vendor/composer/autoload_namespaces.php index b7fc0125..15a2ff3a 100644 --- a/phpmailer/vendor/composer/autoload_namespaces.php +++ b/phpmailer/vendor/composer/autoload_namespaces.php @@ -2,7 +2,7 @@ // autoload_namespaces.php @generated by Composer -$vendorDir = dirname(dirname(__FILE__)); +$vendorDir = dirname(__DIR__); $baseDir = dirname($vendorDir); return array( diff --git a/phpmailer/vendor/composer/autoload_psr4.php b/phpmailer/vendor/composer/autoload_psr4.php index 0706da6f..28567a00 100644 --- a/phpmailer/vendor/composer/autoload_psr4.php +++ b/phpmailer/vendor/composer/autoload_psr4.php @@ -2,7 +2,7 @@ // autoload_psr4.php @generated by Composer -$vendorDir = dirname(dirname(__FILE__)); +$vendorDir = dirname(__DIR__); $baseDir = dirname($vendorDir); return array( diff --git a/phpmailer/vendor/composer/autoload_real.php b/phpmailer/vendor/composer/autoload_real.php index e7e97ae8..65adf3da 100644 --- a/phpmailer/vendor/composer/autoload_real.php +++ b/phpmailer/vendor/composer/autoload_real.php @@ -22,31 +22,14 @@ class ComposerAutoloaderInitPhpMailerAddon return self::$loader; } + require __DIR__ . '/platform_check.php'; + spl_autoload_register(array('ComposerAutoloaderInitPhpMailerAddon', 'loadClassLoader'), true, true); - self::$loader = $loader = new \Composer\Autoload\ClassLoader(); + self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__)); spl_autoload_unregister(array('ComposerAutoloaderInitPhpMailerAddon', 'loadClassLoader')); - $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded()); - if ($useStaticLoader) { - require_once __DIR__ . '/autoload_static.php'; - - call_user_func(\Composer\Autoload\ComposerStaticInitPhpMailerAddon::getInitializer($loader)); - } else { - $map = require __DIR__ . '/autoload_namespaces.php'; - foreach ($map as $namespace => $path) { - $loader->set($namespace, $path); - } - - $map = require __DIR__ . '/autoload_psr4.php'; - foreach ($map as $namespace => $path) { - $loader->setPsr4($namespace, $path); - } - - $classMap = require __DIR__ . '/autoload_classmap.php'; - if ($classMap) { - $loader->addClassMap($classMap); - } - } + require __DIR__ . '/autoload_static.php'; + call_user_func(\Composer\Autoload\ComposerStaticInitPhpMailerAddon::getInitializer($loader)); $loader->register(true); diff --git a/phpmailer/vendor/composer/autoload_static.php b/phpmailer/vendor/composer/autoload_static.php index d07c239a..8fc70b40 100644 --- a/phpmailer/vendor/composer/autoload_static.php +++ b/phpmailer/vendor/composer/autoload_static.php @@ -21,6 +21,7 @@ class ComposerStaticInitPhpMailerAddon ); public static $classMap = array ( + 'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php', 'PHPMailer\\PHPMailer\\DSNConfigurator' => __DIR__ . '/..' . '/phpmailer/phpmailer/src/DSNConfigurator.php', 'PHPMailer\\PHPMailer\\Exception' => __DIR__ . '/..' . '/phpmailer/phpmailer/src/Exception.php', 'PHPMailer\\PHPMailer\\OAuth' => __DIR__ . '/..' . '/phpmailer/phpmailer/src/OAuth.php', diff --git a/phpmailer/vendor/composer/installed.json b/phpmailer/vendor/composer/installed.json index 99511ee9..142a295b 100644 --- a/phpmailer/vendor/composer/installed.json +++ b/phpmailer/vendor/composer/installed.json @@ -1,81 +1,90 @@ -[ - { - "name": "phpmailer/phpmailer", - "version": "v6.9.1", - "version_normalized": "6.9.1.0", - "source": { - "type": "git", - "url": "https://github.com/PHPMailer/PHPMailer.git", - "reference": "039de174cd9c17a8389754d3b877a2ed22743e18" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/039de174cd9c17a8389754d3b877a2ed22743e18", - "reference": "039de174cd9c17a8389754d3b877a2ed22743e18", - "shasum": "" - }, - "require": { - "ext-ctype": "*", - "ext-filter": "*", - "ext-hash": "*", - "php": ">=5.5.0" - }, - "require-dev": { - "dealerdirect/phpcodesniffer-composer-installer": "^1.0", - "doctrine/annotations": "^1.2.6 || ^1.13.3", - "php-parallel-lint/php-console-highlighter": "^1.0.0", - "php-parallel-lint/php-parallel-lint": "^1.3.2", - "phpcompatibility/php-compatibility": "^9.3.5", - "roave/security-advisories": "dev-latest", - "squizlabs/php_codesniffer": "^3.7.2", - "yoast/phpunit-polyfills": "^1.0.4" - }, - "suggest": { - "decomplexity/SendOauth2": "Adapter for using XOAUTH2 authentication", - "ext-mbstring": "Needed to send email in multibyte encoding charset or decode encoded addresses", - "ext-openssl": "Needed for secure SMTP sending and DKIM signing", - "greew/oauth2-azure-provider": "Needed for Microsoft Azure XOAUTH2 authentication", - "hayageek/oauth2-yahoo": "Needed for Yahoo XOAUTH2 authentication", - "league/oauth2-google": "Needed for Google XOAUTH2 authentication", - "psr/log": "For optional PSR-3 debug logging", - "symfony/polyfill-mbstring": "To support UTF-8 if the Mbstring PHP extension is not enabled (^1.2)", - "thenetworg/oauth2-azure": "Needed for Microsoft XOAUTH2 authentication" - }, - "time": "2023-11-25T22:23:28+00:00", - "type": "library", - "installation-source": "dist", - "autoload": { - "psr-4": { - "PHPMailer\\PHPMailer\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "LGPL-2.1-only" +{ + "packages": [ + { + "name": "phpmailer/phpmailer", + "version": "v6.10.0", + "version_normalized": "6.10.0.0", + "source": { + "type": "git", + "url": "https://github.com/PHPMailer/PHPMailer.git", + "reference": "bf74d75a1fde6beaa34a0ddae2ec5fce0f72a144" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/bf74d75a1fde6beaa34a0ddae2ec5fce0f72a144", + "reference": "bf74d75a1fde6beaa34a0ddae2ec5fce0f72a144", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "ext-filter": "*", + "ext-hash": "*", + "php": ">=5.5.0" + }, + "require-dev": { + "dealerdirect/phpcodesniffer-composer-installer": "^1.0", + "doctrine/annotations": "^1.2.6 || ^1.13.3", + "php-parallel-lint/php-console-highlighter": "^1.0.0", + "php-parallel-lint/php-parallel-lint": "^1.3.2", + "phpcompatibility/php-compatibility": "^9.3.5", + "roave/security-advisories": "dev-latest", + "squizlabs/php_codesniffer": "^3.7.2", + "yoast/phpunit-polyfills": "^1.0.4" + }, + "suggest": { + "decomplexity/SendOauth2": "Adapter for using XOAUTH2 authentication", + "ext-mbstring": "Needed to send email in multibyte encoding charset or decode encoded addresses", + "ext-openssl": "Needed for secure SMTP sending and DKIM signing", + "greew/oauth2-azure-provider": "Needed for Microsoft Azure XOAUTH2 authentication", + "hayageek/oauth2-yahoo": "Needed for Yahoo XOAUTH2 authentication", + "league/oauth2-google": "Needed for Google XOAUTH2 authentication", + "psr/log": "For optional PSR-3 debug logging", + "symfony/polyfill-mbstring": "To support UTF-8 if the Mbstring PHP extension is not enabled (^1.2)", + "thenetworg/oauth2-azure": "Needed for Microsoft XOAUTH2 authentication" + }, + "time": "2025-04-24T15:19:31+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "PHPMailer\\PHPMailer\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-2.1-only" + ], + "authors": [ + { + "name": "Marcus Bointon", + "email": "phpmailer@synchromedia.co.uk" + }, + { + "name": "Jim Jagielski", + "email": "jimjag@gmail.com" + }, + { + "name": "Andy Prevost", + "email": "codeworxtech@users.sourceforge.net" + }, + { + "name": "Brent R. Matzelle" + } + ], + "description": "PHPMailer is a full-featured email creation and transfer class for PHP", + "support": { + "issues": "https://github.com/PHPMailer/PHPMailer/issues", + "source": "https://github.com/PHPMailer/PHPMailer/tree/v6.10.0" + }, + "funding": [ + { + "url": "https://github.com/Synchro", + "type": "github" + } + ], + "install-path": "../phpmailer/phpmailer" + } ], - "authors": [ - { - "name": "Marcus Bointon", - "email": "phpmailer@synchromedia.co.uk" - }, - { - "name": "Jim Jagielski", - "email": "jimjag@gmail.com" - }, - { - "name": "Andy Prevost", - "email": "codeworxtech@users.sourceforge.net" - }, - { - "name": "Brent R. Matzelle" - } - ], - "description": "PHPMailer is a full-featured email creation and transfer class for PHP", - "funding": [ - { - "url": "https://github.com/Synchro", - "type": "github" - } - ] - } -] + "dev": true, + "dev-package-names": [] +} diff --git a/phpmailer/vendor/composer/installed.php b/phpmailer/vendor/composer/installed.php new file mode 100644 index 00000000..554d2c40 --- /dev/null +++ b/phpmailer/vendor/composer/installed.php @@ -0,0 +1,32 @@ + array( + 'name' => 'friendica-addons/phpmailer', + 'pretty_version' => 'dev-2025.07-rc', + 'version' => 'dev-2025.07-rc', + 'reference' => '715f70032330ad14f710284104c8593c7800e125', + 'type' => 'friendica-addon', + 'install_path' => __DIR__ . '/../../', + 'aliases' => array(), + 'dev' => true, + ), + 'versions' => array( + 'friendica-addons/phpmailer' => array( + 'pretty_version' => 'dev-2025.07-rc', + 'version' => 'dev-2025.07-rc', + 'reference' => '715f70032330ad14f710284104c8593c7800e125', + 'type' => 'friendica-addon', + 'install_path' => __DIR__ . '/../../', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'phpmailer/phpmailer' => array( + 'pretty_version' => 'v6.10.0', + 'version' => '6.10.0.0', + 'reference' => 'bf74d75a1fde6beaa34a0ddae2ec5fce0f72a144', + 'type' => 'library', + 'install_path' => __DIR__ . '/../phpmailer/phpmailer', + 'aliases' => array(), + 'dev_requirement' => false, + ), + ), +); diff --git a/phpmailer/vendor/composer/platform_check.php b/phpmailer/vendor/composer/platform_check.php new file mode 100644 index 00000000..f79e574b --- /dev/null +++ b/phpmailer/vendor/composer/platform_check.php @@ -0,0 +1,26 @@ += 70000)) { + $issues[] = 'Your Composer dependencies require a PHP version ">= 7.0.0". You are running ' . PHP_VERSION . '.'; +} + +if ($issues) { + if (!headers_sent()) { + header('HTTP/1.1 500 Internal Server Error'); + } + if (!ini_get('display_errors')) { + if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') { + fwrite(STDERR, 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . implode(PHP_EOL, $issues) . PHP_EOL.PHP_EOL); + } elseif (!headers_sent()) { + echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL; + } + } + trigger_error( + 'Composer detected issues in your platform: ' . implode(' ', $issues), + E_USER_ERROR + ); +} diff --git a/phpmailer/vendor/phpmailer/phpmailer/.editorconfig b/phpmailer/vendor/phpmailer/phpmailer/.editorconfig deleted file mode 100644 index a7c44ddb..00000000 --- a/phpmailer/vendor/phpmailer/phpmailer/.editorconfig +++ /dev/null @@ -1,15 +0,0 @@ -root = true - -[*] -charset = utf-8 -indent_size = 4 -indent_style = space -end_of_line = lf -insert_final_newline = true -trim_trailing_whitespace = true - -[*.md] -trim_trailing_whitespace = false - -[*.{yml,yaml}] -indent_size = 2 diff --git a/phpmailer/vendor/phpmailer/phpmailer/README.md b/phpmailer/vendor/phpmailer/phpmailer/README.md index e3e4ecff..862a4e1a 100644 --- a/phpmailer/vendor/phpmailer/phpmailer/README.md +++ b/phpmailer/vendor/phpmailer/phpmailer/README.md @@ -20,34 +20,35 @@ - Multipart/alternative emails for mail clients that do not read HTML email - Add attachments, including inline - Support for UTF-8 content and 8bit, base64, binary, and quoted-printable encodings -- SMTP authentication with LOGIN, PLAIN, CRAM-MD5, and XOAUTH2 mechanisms over SMTPS and SMTP+STARTTLS transports +- Full UTF-8 support when using servers that support `SMTPUTF8`. +- Support for iCal events in multiparts and attachments +- SMTP authentication with `LOGIN`, `PLAIN`, `CRAM-MD5`, and `XOAUTH2` mechanisms over SMTPS and SMTP+STARTTLS transports - Validates email addresses automatically - Protects against header injection attacks - Error messages in over 50 languages! - DKIM and S/MIME signing support -- Compatible with PHP 5.5 and later, including PHP 8.2 +- Compatible with PHP 5.5 and later, including PHP 8.4 - Namespaced to prevent name clashes - Much more! ## Why you might need it -Many PHP developers need to send email from their code. The only PHP function that supports this directly is [`mail()`](https://www.php.net/manual/en/function.mail.php). However, it does not provide any assistance for making use of popular features such as encryption, authentication, HTML messages, and attachments. +Many PHP developers need to send email from their code. The only PHP function that supports this directly is [`mail()`](https://www.php.net/manual/en/function.mail.php). However, it does not provide any assistance for making use of popular features such as authentication, HTML messages, and attachments. Formatting email correctly is surprisingly difficult. There are myriad overlapping (and conflicting) standards, requiring tight adherence to horribly complicated formatting and encoding rules – the vast majority of code that you'll find online that uses the `mail()` function directly is just plain wrong, if not unsafe! The PHP `mail()` function usually sends via a local mail server, typically fronted by a `sendmail` binary on Linux, BSD, and macOS platforms, however, Windows usually doesn't include a local mail server; PHPMailer's integrated SMTP client allows email sending on all platforms without needing a local mail server. Be aware though, that the `mail()` function should be avoided when possible; it's both faster and [safer](https://exploitbox.io/paper/Pwning-PHP-Mail-Function-For-Fun-And-RCE.html) to use SMTP to localhost. *Please* don't be tempted to do it yourself – if you don't use PHPMailer, there are many other excellent libraries that -you should look at before rolling your own. Try [SwiftMailer](https://swiftmailer.symfony.com/) -, [Laminas/Mail](https://docs.laminas.dev/laminas-mail/), [ZetaComponents](https://github.com/zetacomponents/Mail), etc. +you should look at before rolling your own. Try [Symfony Mailer](https://symfony.com/doc/current/mailer.html), [Laminas/Mail](https://docs.laminas.dev/laminas-mail/), [ZetaComponents](https://github.com/zetacomponents/Mail), etc. ## License -This software is distributed under the [LGPL 2.1](http://www.gnu.org/licenses/lgpl-2.1.html) license, along with the [GPL Cooperation Commitment](https://gplcc.github.io/gplcc/). Please read [LICENSE](https://github.com/PHPMailer/PHPMailer/blob/master/LICENSE) for information on the software availability and distribution. +This software is distributed under the [LGPL 2.1](https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html) license, along with the [GPL Cooperation Commitment](https://gplcc.github.io/gplcc/). Please read [LICENSE](https://github.com/PHPMailer/PHPMailer/blob/master/LICENSE) for information on the software availability and distribution. ## Installation & loading PHPMailer is available on [Packagist](https://packagist.org/packages/phpmailer/phpmailer) (using semantic versioning), and installation via [Composer](https://getcomposer.org) is the recommended way to install PHPMailer. Just add this line to your `composer.json` file: ```json -"phpmailer/phpmailer": "^6.9.1" +"phpmailer/phpmailer": "^6.10.0" ``` or run @@ -74,7 +75,7 @@ require 'path/to/PHPMailer/src/PHPMailer.php'; require 'path/to/PHPMailer/src/SMTP.php'; ``` -If you're not using the `SMTP` class explicitly (you're probably not), you don't need a `use` line for the SMTP class. Even if you're not using exceptions, you do still need to load the `Exception` class as it is used internally. +If you're not using the `SMTP` class explicitly (you're probably not), you don't need a `use` line for it. Even if you're not using exceptions, you do still need to load the `Exception` class as it is used internally. ## Legacy versions PHPMailer 5.2 (which is compatible with PHP 5.0 — 7.0) is no longer supported, even for security updates. You will find the latest version of 5.2 in the [5.2-stable branch](https://github.com/PHPMailer/PHPMailer/tree/5.2-stable). If you're using PHP 5.5 or later (which you should be), switch to the 6.x releases. @@ -95,7 +96,7 @@ use PHPMailer\PHPMailer\PHPMailer; use PHPMailer\PHPMailer\SMTP; use PHPMailer\PHPMailer\Exception; -//Load Composer's autoloader +//Load Composer's autoloader (created by composer, not included with PHPMailer) require 'vendor/autoload.php'; //Create an instance; passing `true` enables exceptions @@ -144,7 +145,7 @@ If you are re-using the instance (e.g. when sending to a mailing list), you may That's it. You should now be ready to use PHPMailer! ## Localization -PHPMailer defaults to English, but in the [language](https://github.com/PHPMailer/PHPMailer/tree/master/language/) folder, you'll find many translations for PHPMailer error messages that you may encounter. Their filenames contain [ISO 639-1](http://en.wikipedia.org/wiki/ISO_639-1) language code for the translations, for example `fr` for French. To specify a language, you need to tell PHPMailer which one to use, like this: +PHPMailer defaults to English, but in the [language](https://github.com/PHPMailer/PHPMailer/tree/master/language/) folder, you'll find many translations for PHPMailer error messages that you may encounter. Their filenames contain [ISO 639-1](https://en.wikipedia.org/wiki/ISO_639-1) language code for the translations, for example `fr` for French. To specify a language, you need to tell PHPMailer which one to use, like this: ```php //To load the French version @@ -162,9 +163,9 @@ To reduce PHPMailer's deployed code footprint, examples are not included if you Complete generated API documentation is [available online](https://phpmailer.github.io/PHPMailer/). -You can generate complete API-level documentation by running `phpdoc` in the top-level folder, and documentation will appear in the `docs` folder, though you'll need to have [PHPDocumentor](http://www.phpdoc.org) installed. You may find [the unit tests](https://github.com/PHPMailer/PHPMailer/blob/master/test/PHPMailerTest.php) a good reference for how to do various operations such as encryption. +You can generate complete API-level documentation by running `phpdoc` in the top-level folder, and documentation will appear in the `docs` folder, though you'll need to have [PHPDocumentor](https://www.phpdoc.org) installed. You may find [the unit tests](https://github.com/PHPMailer/PHPMailer/blob/master/test/PHPMailer/PHPMailerTest.php) a good reference for how to do various operations such as encryption. -If the documentation doesn't cover what you need, search the [many questions on Stack Overflow](http://stackoverflow.com/questions/tagged/phpmailer), and before you ask a question about "SMTP Error: Could not connect to SMTP host.", [read the troubleshooting guide](https://github.com/PHPMailer/PHPMailer/wiki/Troubleshooting). +If the documentation doesn't cover what you need, search the [many questions on Stack Overflow](https://stackoverflow.com/questions/tagged/phpmailer), and before you ask a question about "SMTP Error: Could not connect to SMTP host.", [read the troubleshooting guide](https://github.com/PHPMailer/PHPMailer/wiki/Troubleshooting). ## Tests [PHPMailer tests](https://github.com/PHPMailer/PHPMailer/tree/master/test/) use PHPUnit 9, with [a polyfill](https://github.com/Yoast/PHPUnit-Polyfills) to let 9-style tests run on older PHPUnit and PHP versions. @@ -213,7 +214,7 @@ use. [Learn more.](https://tidelift.com/subscription/pkg/packagist-phpmailer-php See [changelog](changelog.md). ## History -- PHPMailer was originally written in 2001 by Brent R. Matzelle as a [SourceForge project](http://sourceforge.net/projects/phpmailer/). +- PHPMailer was originally written in 2001 by Brent R. Matzelle as a [SourceForge project](https://sourceforge.net/projects/phpmailer/). - [Marcus Bointon](https://github.com/Synchro) (`coolbru` on SF) and Andy Prevost (`codeworxtech`) took over the project in 2004. - Became an Apache incubator project on Google Code in 2010, managed by Jim Jagielski. - Marcus created [his fork on GitHub](https://github.com/Synchro/PHPMailer) in 2008. diff --git a/phpmailer/vendor/phpmailer/phpmailer/SECURITY.md b/phpmailer/vendor/phpmailer/phpmailer/SECURITY.md index 035a87f7..4f34026d 100644 --- a/phpmailer/vendor/phpmailer/phpmailer/SECURITY.md +++ b/phpmailer/vendor/phpmailer/phpmailer/SECURITY.md @@ -13,13 +13,13 @@ PHPMailer versions 6.1.5 and earlier contain an output escaping bug that occurs PHPMailer versions prior to 6.0.6 and 5.2.27 are vulnerable to an object injection attack by passing `phar://` paths into `addAttachment()` and other functions that may receive unfiltered local paths, possibly leading to RCE. Recorded as [CVE-2018-19296](https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2018-19296). See [this article](https://knasmueller.net/5-answers-about-php-phar-exploitation) for more info on this type of vulnerability. Mitigated by blocking the use of paths containing URL-protocol style prefixes such as `phar://`. Reported by Sehun Oh of cyberone.kr. -PHPMailer versions prior to 5.2.24 (released July 26th 2017) have an XSS vulnerability in one of the code examples, [CVE-2017-11503](https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2017-11503). The `code_generator.phps` example did not filter user input prior to output. This file is distributed with a `.phps` extension, so it it not normally executable unless it is explicitly renamed, and the file is not included when PHPMailer is loaded through composer, so it is safe by default. There was also an undisclosed potential XSS vulnerability in the default exception handler (unused by default). Patches for both issues kindly provided by Patrick Monnerat of the Fedora Project. +PHPMailer versions prior to 5.2.24 (released July 26th 2017) have an XSS vulnerability in one of the code examples, [CVE-2017-11503](https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2017-11503). The `code_generator.phps` example did not filter user input prior to output. This file is distributed with a `.phps` extension, so it is not normally executable unless it is explicitly renamed, and the file is not included when PHPMailer is loaded through composer, so it is safe by default. There was also an undisclosed potential XSS vulnerability in the default exception handler (unused by default). Patches for both issues kindly provided by Patrick Monnerat of the Fedora Project. PHPMailer versions prior to 5.2.22 (released January 9th 2017) have a local file disclosure vulnerability, [CVE-2017-5223](https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2017-5223). If content passed into `msgHTML()` is sourced from unfiltered user input, relative paths can map to absolute local file paths and added as attachments. Also note that `addAttachment` (just like `file_get_contents`, `passthru`, `unlink`, etc) should not be passed user-sourced params either! Reported by Yongxiang Li of Asiasecurity. PHPMailer versions prior to 5.2.20 (released December 28th 2016) are vulnerable to [CVE-2016-10045](https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2016-10045) a remote code execution vulnerability, responsibly reported by [Dawid Golunski](https://legalhackers.com/advisories/PHPMailer-Exploit-Remote-Code-Exec-CVE-2016-10045-Vuln-Patch-Bypass.html), and patched by Paul Buonopane (@Zenexer). -PHPMailer versions prior to 5.2.18 (released December 2016) are vulnerable to [CVE-2016-10033](https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2016-10033) a remote code execution vulnerability, responsibly reported by [Dawid Golunski](http://legalhackers.com/advisories/PHPMailer-Exploit-Remote-Code-Exec-CVE-2016-10033-Vuln.html). +PHPMailer versions prior to 5.2.18 (released December 2016) are vulnerable to [CVE-2016-10033](https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2016-10033) a remote code execution vulnerability, responsibly reported by [Dawid Golunski](https://legalhackers.com/advisories/PHPMailer-Exploit-Remote-Code-Exec-CVE-2016-10033-Vuln.html). PHPMailer versions prior to 5.2.14 (released November 2015) are vulnerable to [CVE-2015-8476](https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2015-8476) an SMTP CRLF injection bug permitting arbitrary message sending. diff --git a/phpmailer/vendor/phpmailer/phpmailer/SMTPUTF8.md b/phpmailer/vendor/phpmailer/phpmailer/SMTPUTF8.md new file mode 100644 index 00000000..ca284ee2 --- /dev/null +++ b/phpmailer/vendor/phpmailer/phpmailer/SMTPUTF8.md @@ -0,0 +1,48 @@ +# A short history of UTF-8 in email + +## Background + +For most of its existence, SMTP has been a 7-bit channel, only supporting US-ASCII characters. This has been a problem for many languages, especially those that use non-Latin scripts, and has led to the development of various workarounds. + +The first major improvement, introduced in 1994 in [RFC 1652](https://www.rfc-editor.org/rfc/rfc1652) and extended in 2011 in [RFC 6152](https://www.rfc-editor.org/rfc/rfc6152), was the addition of the `8BITMIME` SMTP extension, which allowed raw 8-bit data to be included in message bodies sent over SMTP. +This allowed the message *contents* to contain 8-bit data, including things like UTF-8 text, even though the SMTP protocol itself was still firmly 7-bit. This worked by having the server switch to 8-bit after the headers, and then back to 7-bit after the completion of a `DATA` command. + +From 1996, messages could support [RFC 2047 encoding](https://www.rfc-editor.org/rfc/rfc2047), which permitted inserting characters from any character set into header *values* (but not names), but only by encoding them in somewhat unreadable ways to allow them to survive passage through a 7-bit channel. An example with a subject of "Schrödinger's cat" would be: + +``` +Subject: =?utf-8?Q=Schr=C3=B6dinger=92s_Cat?= +``` + +Here the accented `ö` is encoded as `=C3=B6`, which is the UTF-8 encoding of the 2-byte character, and the whole thing is wrapped in `=?utf-8?Q?` to indicate that it uses the UTF-8 charset and `quoted-printable` encoding. This is a bit of a hack, and not very human-friendly, but it works. + +Similarly, 8-bit message bodies could be encoded using the same `quoted-printable` and `base64` content transfer encoding (CTE) schemes, which preserved the 8-bit content while encoding it in a format that could survive transmission through a 7-bit channel. + +Domain names were originally also stuck in a 7-bit world, actually even more constrained to only a subset of the US-ASCII character set. But of course, many people want to have domains in their own language/script. Internationalized domain name (IDN) permitted this, using yet another complex encoding scheme called punycode, defined for domain names in 2003 in [RFC 3492](https://www.rfc-editor.org/rfc/rfc3492). This finally allowed the domain part (after the `@`) of email addresses to contain UTF-8, though it was actually an illusion preserved by email client applications. For example, an address of +`user@café.example.com` translates to +`user@xn--caf-dma.example.com` in punycode, rendering it mostly unreadable, but 7-bit friendly, and remaining compatible with email clients that don't know about IDN. + +The one remaining part of email that could not handle UTF-8 is the local part of email addresses (the part before the `@`). + +I've only mentioned UTF-8 here, but most of these approaches also allowed other character sets that were popular, such as [the ISO-8859 family](https://en.wikipedia.org/wiki/ISO/IEC_8859). However, UTF-8 solves so many problems that these other character sets are gradually falling out of favour, as UTF-8 can support all languages. + +This patchwork of overlapping approaches has served us well, but we have to admit that it's a mess. + +## SMTPUTF8 + +`SMTPUTF8` is another SMTP extension, defined in [RFC 6531](https://www.rfc-editor.org/rfc/rfc6531) in 2012. This essentially solves the whole problem, allowing the entire SMTP conversation — commands, headers, and message bodies — to be sent in raw, unencoded UTF-8. + +But there's a problem with this approach: adoption. If you send a UTF-8 message to a recipient whose mail server doesn't support this format, the sender has to somehow downgrade the message to make it survive a transition to 7-bit. This is a hard problem to solve, especially since there is no way to make a 7-bit system support UTF-8 in the local parts of addresses. This downgrade problem is what held up the adoption of `SMTPUTF8` in PHPMailer for many years, but in that time the *de facto* approach has become to simply fail in that situation, and tell the recipient it's time they upgraded their mail server 😅. + +The vast majority of large email providers (gmail, Yahoo, Microsoft, etc), mail servers (postfix, exim, IIS, etc), and mail clients (Apple Mail, Outlook, Thunderbird, etc) now all support SMTPUTF8, so the need for backward compatibility is no longer what it was. + +## SMTPUTF8 in PHPMailer + +Several other PHP email libraries have implemented a halfway solution to `SMTPUTF8`, adding only the ability to support UTF-8 in email addresses, not elsewhere in the protocol. I wanted PHPMailer to do it "the right way", and this has taken much longer. PHPMailer now supports UTF-8 everywhere, and does not need to use transfer or header encodings for UTF-8 text when connecting to an `SMTPUTF8`-capable mail server. + +This support is handled automatically: if you add an email address that requires UTF-8, PHPMailer will use UTF-8 for everything. If not, it will fall back to 7-bit and encode the message as necessary. + +The one place you will need to be careful is in the selection of the address validator. By default, PHPMailer uses PHP's built-in `filter_var` validator, which does not allow UTF-8 email addresses. When PHPMailer spots that you have submitted a UTF-8 address, but have not altered the default validator, it will automatically switch to using a UTF-8-compatible validator. As soon as you do this, any SMTP connection you make will *require* that the server you connect to supports `SMTPUTF8`. You can select this validator explicitly by setting `PHPMailer::$validator = 'eai'` (an acronym for Email Address Internationalization). + +### Postfix gotcha + +Postfix has supported `SMTPUTF8` for a long time, but it has a peculiarity that it does not always advertise that it does so. However, rather surprisingly, if you use UTF-8 in the conversation, it will work anyway. diff --git a/phpmailer/vendor/phpmailer/phpmailer/VERSION b/phpmailer/vendor/phpmailer/phpmailer/VERSION index dc3829f5..cf79bf90 100644 --- a/phpmailer/vendor/phpmailer/phpmailer/VERSION +++ b/phpmailer/vendor/phpmailer/phpmailer/VERSION @@ -1 +1 @@ -6.9.1 +6.10.0 diff --git a/phpmailer/vendor/phpmailer/phpmailer/composer.json b/phpmailer/vendor/phpmailer/phpmailer/composer.json index fa170a0b..7b008b7c 100644 --- a/phpmailer/vendor/phpmailer/phpmailer/composer.json +++ b/phpmailer/vendor/phpmailer/phpmailer/composer.json @@ -28,7 +28,8 @@ "config": { "allow-plugins": { "dealerdirect/phpcodesniffer-composer-installer": true - } + }, + "lock": false }, "require": { "php": ">=5.5.0", diff --git a/phpmailer/vendor/phpmailer/phpmailer/get_oauth_token.php b/phpmailer/vendor/phpmailer/phpmailer/get_oauth_token.php index cda0445c..0e54a00b 100644 --- a/phpmailer/vendor/phpmailer/phpmailer/get_oauth_token.php +++ b/phpmailer/vendor/phpmailer/phpmailer/get_oauth_token.php @@ -12,7 +12,7 @@ * @copyright 2012 - 2020 Marcus Bointon * @copyright 2010 - 2012 Jim Jagielski * @copyright 2004 - 2009 Andy Prevost - * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + * @license https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html GNU Lesser General Public License * @note This program is distributed in the hope that it will be useful - WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. @@ -36,7 +36,7 @@ namespace PHPMailer\PHPMailer; * Aliases for League Provider Classes * Make sure you have added these to your composer.json and run `composer install` * Plenty to choose from here: - * @see http://oauth2-client.thephpleague.com/providers/thirdparty/ + * @see https://oauth2-client.thephpleague.com/providers/thirdparty/ */ //@see https://github.com/thephpleague/oauth2-google use League\OAuth2\Client\Provider\Google; @@ -178,5 +178,5 @@ if (!isset($_GET['code'])) { ); //Use this to interact with an API on the users behalf //Use this to get a new access token if the old one expires - echo 'Refresh Token: ', $token->getRefreshToken(); + echo 'Refresh Token: ', htmlspecialchars($token->getRefreshToken()); } diff --git a/phpmailer/vendor/phpmailer/phpmailer/language/phpmailer.lang-es.php b/phpmailer/vendor/phpmailer/phpmailer/language/phpmailer.lang-es.php index 69920418..4e74bfb7 100644 --- a/phpmailer/vendor/phpmailer/phpmailer/language/phpmailer.lang-es.php +++ b/phpmailer/vendor/phpmailer/phpmailer/language/phpmailer.lang-es.php @@ -5,27 +5,32 @@ * @package PHPMailer * @author Matt Sturdy * @author Crystopher Glodzienski Cardoso + * @author Daniel Cruz */ $PHPMAILER_LANG['authenticate'] = 'Error SMTP: Imposible autentificar.'; +$PHPMAILER_LANG['buggy_php'] = 'Tu versión de PHP está afectada por un bug que puede resultar en mensajes corruptos. Para arreglarlo, cambia a enviar usando SMTP, deshabilita la opción mail.add_x_header en tu php.ini, cambia a MacOS o Linux, o actualiza tu PHP a la versión 7.0.17+ o 7.1.3+.'; $PHPMAILER_LANG['connect_host'] = 'Error SMTP: Imposible conectar al servidor SMTP.'; $PHPMAILER_LANG['data_not_accepted'] = 'Error SMTP: Datos no aceptados.'; $PHPMAILER_LANG['empty_message'] = 'El cuerpo del mensaje está vacío.'; $PHPMAILER_LANG['encoding'] = 'Codificación desconocida: '; $PHPMAILER_LANG['execute'] = 'Imposible ejecutar: '; +$PHPMAILER_LANG['extension_missing'] = 'Extensión faltante: '; $PHPMAILER_LANG['file_access'] = 'Imposible acceder al archivo: '; $PHPMAILER_LANG['file_open'] = 'Error de Archivo: Imposible abrir el archivo: '; $PHPMAILER_LANG['from_failed'] = 'La(s) siguiente(s) direcciones de remitente fallaron: '; $PHPMAILER_LANG['instantiate'] = 'Imposible crear una instancia de la función Mail.'; $PHPMAILER_LANG['invalid_address'] = 'Imposible enviar: dirección de email inválido: '; +$PHPMAILER_LANG['invalid_header'] = 'Nombre o valor de encabezado no válido'; +$PHPMAILER_LANG['invalid_hostentry'] = 'Hostentry inválido: '; +$PHPMAILER_LANG['invalid_host'] = 'Host inválido: '; $PHPMAILER_LANG['mailer_not_supported'] = ' mailer no está soportado.'; $PHPMAILER_LANG['provide_address'] = 'Debe proporcionar al menos una dirección de email de destino.'; $PHPMAILER_LANG['recipients_failed'] = 'Error SMTP: Los siguientes destinos fallaron: '; $PHPMAILER_LANG['signing'] = 'Error al firmar: '; -$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() falló.'; -$PHPMAILER_LANG['smtp_error'] = 'Error del servidor SMTP: '; -$PHPMAILER_LANG['variable_set'] = 'No se pudo configurar la variable: '; -$PHPMAILER_LANG['extension_missing'] = 'Extensión faltante: '; $PHPMAILER_LANG['smtp_code'] = 'Código del servidor SMTP: '; $PHPMAILER_LANG['smtp_code_ex'] = 'Información adicional del servidor SMTP: '; -$PHPMAILER_LANG['invalid_header'] = 'Nombre o valor de encabezado no válido'; +$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() falló.'; +$PHPMAILER_LANG['smtp_detail'] = 'Detalle: '; +$PHPMAILER_LANG['smtp_error'] = 'Error del servidor SMTP: '; +$PHPMAILER_LANG['variable_set'] = 'No se pudo configurar la variable: '; diff --git a/phpmailer/vendor/phpmailer/phpmailer/language/phpmailer.lang-fr.php b/phpmailer/vendor/phpmailer/phpmailer/language/phpmailer.lang-fr.php index 0d367fcf..a6d582d8 100644 --- a/phpmailer/vendor/phpmailer/phpmailer/language/phpmailer.lang-fr.php +++ b/phpmailer/vendor/phpmailer/phpmailer/language/phpmailer.lang-fr.php @@ -6,7 +6,6 @@ * Some French punctuation requires a thin non-breaking space (U+202F) character before it, * for example before a colon or exclamation mark. * There is one of these characters between these quotes: " " - * @see http://unicode.org/udhr/n/notes_fra.html */ $PHPMAILER_LANG['authenticate'] = 'Erreur SMTP : échec de l’authentification.'; @@ -31,7 +30,7 @@ $PHPMAILER_LANG['recipients_failed'] = 'Erreur SMTP : les destinataires s $PHPMAILER_LANG['signing'] = 'Erreur de signature : '; $PHPMAILER_LANG['smtp_code'] = 'Code SMTP : '; $PHPMAILER_LANG['smtp_code_ex'] = 'Informations supplémentaires SMTP : '; -$PHPMAILER_LANG['smtp_connect_failed'] = 'La fonction SMTP connect() a échouée.'; +$PHPMAILER_LANG['smtp_connect_failed'] = 'La fonction SMTP connect() a échoué.'; $PHPMAILER_LANG['smtp_detail'] = 'Détails : '; $PHPMAILER_LANG['smtp_error'] = 'Erreur du serveur SMTP : '; $PHPMAILER_LANG['variable_set'] = 'Impossible d’initialiser ou de réinitialiser une variable : '; diff --git a/phpmailer/vendor/phpmailer/phpmailer/language/phpmailer.lang-ja.php b/phpmailer/vendor/phpmailer/phpmailer/language/phpmailer.lang-ja.php index c76f5264..d01869ce 100644 --- a/phpmailer/vendor/phpmailer/phpmailer/language/phpmailer.lang-ja.php +++ b/phpmailer/vendor/phpmailer/phpmailer/language/phpmailer.lang-ja.php @@ -3,27 +3,35 @@ /** * Japanese PHPMailer language file: refer to English translation for definitive list * @package PHPMailer - * @author Mitsuhiro Yoshida + * @author Mitsuhiro Yoshida * @author Yoshi Sakai * @author Arisophy + * @author ARAKI Musashi */ $PHPMAILER_LANG['authenticate'] = 'SMTPエラー: 認証できませんでした。'; +$PHPMAILER_LANG['buggy_php'] = 'ご利用のバージョンのPHPには不具合があり、メッセージが破損するおそれがあります。問題の解決は以下のいずれかを行ってください。SMTPでの送信に切り替える。php.iniのmail.add_x_headerをoffにする。MacOSまたはLinuxに切り替える。PHPバージョン7.0.17以降または7.1.3以降にアップグレードする。'; $PHPMAILER_LANG['connect_host'] = 'SMTPエラー: SMTPホストに接続できませんでした。'; $PHPMAILER_LANG['data_not_accepted'] = 'SMTPエラー: データが受け付けられませんでした。'; $PHPMAILER_LANG['empty_message'] = 'メール本文が空です。'; $PHPMAILER_LANG['encoding'] = '不明なエンコーディング: '; $PHPMAILER_LANG['execute'] = '実行できませんでした: '; +$PHPMAILER_LANG['extension_missing'] = '拡張機能が見つかりません: '; $PHPMAILER_LANG['file_access'] = 'ファイルにアクセスできません: '; $PHPMAILER_LANG['file_open'] = 'ファイルエラー: ファイルを開けません: '; $PHPMAILER_LANG['from_failed'] = 'Fromアドレスを登録する際にエラーが発生しました: '; $PHPMAILER_LANG['instantiate'] = 'メール関数が正常に動作しませんでした。'; $PHPMAILER_LANG['invalid_address'] = '不正なメールアドレス: '; -$PHPMAILER_LANG['provide_address'] = '少なくとも1つメールアドレスを 指定する必要があります。'; +$PHPMAILER_LANG['invalid_header'] = '不正なヘッダー名またはその内容'; +$PHPMAILER_LANG['invalid_hostentry'] = '不正なホストエントリー: '; +$PHPMAILER_LANG['invalid_host'] = '不正なホスト: '; $PHPMAILER_LANG['mailer_not_supported'] = ' メーラーがサポートされていません。'; +$PHPMAILER_LANG['provide_address'] = '少なくとも1つメールアドレスを 指定する必要があります。'; $PHPMAILER_LANG['recipients_failed'] = 'SMTPエラー: 次の受信者アドレスに 間違いがあります: '; $PHPMAILER_LANG['signing'] = '署名エラー: '; +$PHPMAILER_LANG['smtp_code'] = 'SMTPコード: '; +$PHPMAILER_LANG['smtp_code_ex'] = 'SMTP追加情報: '; $PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP接続に失敗しました。'; +$PHPMAILER_LANG['smtp_detail'] = '詳細: '; $PHPMAILER_LANG['smtp_error'] = 'SMTPサーバーエラー: '; $PHPMAILER_LANG['variable_set'] = '変数が存在しません: '; -$PHPMAILER_LANG['extension_missing'] = '拡張機能が見つかりません: '; diff --git a/phpmailer/vendor/phpmailer/phpmailer/language/phpmailer.lang-ku.php b/phpmailer/vendor/phpmailer/phpmailer/language/phpmailer.lang-ku.php new file mode 100644 index 00000000..cf3bda69 --- /dev/null +++ b/phpmailer/vendor/phpmailer/phpmailer/language/phpmailer.lang-ku.php @@ -0,0 +1,27 @@ + + */ + +$PHPMAILER_LANG['authenticate'] = 'هەڵەی SMTP : نەتوانرا کۆدەکە پشتڕاست بکرێتەوە '; +$PHPMAILER_LANG['connect_host'] = 'هەڵەی SMTP: نەتوانرا پەیوەندی بە سێرڤەرەوە بکات SMTP.'; +$PHPMAILER_LANG['data_not_accepted'] = 'هەڵەی SMTP: ئەو زانیاریانە قبوڵ نەکرا.'; +$PHPMAILER_LANG['empty_message'] = 'پەیامەکە بەتاڵە'; +$PHPMAILER_LANG['encoding'] = 'کۆدکردنی نەزانراو : '; +$PHPMAILER_LANG['execute'] = 'ناتوانرێت جێبەجێ بکرێت: '; +$PHPMAILER_LANG['file_access'] = 'ناتوانرێت دەستت بگات بە فایلەکە: '; +$PHPMAILER_LANG['file_open'] = 'هەڵەی پەڕگە(فایل): ناتوانرێت بکرێتەوە: '; +$PHPMAILER_LANG['from_failed'] = 'هەڵە لە ئاستی ناونیشانی نێرەر: '; +$PHPMAILER_LANG['instantiate'] = 'ناتوانرێت خزمەتگوزاری پۆستە پێشکەش بکرێت.'; +$PHPMAILER_LANG['invalid_address'] = 'نەتوانرا بنێردرێت ، چونکە ناونیشانی ئیمەیڵەکە نادروستە: '; +$PHPMAILER_LANG['mailer_not_supported'] = ' مەیلەر پشتگیری ناکات'; +$PHPMAILER_LANG['provide_address'] = 'دەبێت ناونیشانی ئیمەیڵی لانیکەم یەک وەرگر دابین بکرێت.'; +$PHPMAILER_LANG['recipients_failed'] = ' هەڵەی SMTP: ئەم هەڵانەی خوارەوەشکستی هێنا لە ناردن بۆ هەردووکیان: '; +$PHPMAILER_LANG['signing'] = 'هەڵەی واژۆ: '; +$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect()پەیوەندی شکستی هێنا .'; +$PHPMAILER_LANG['smtp_error'] = 'هەڵەی ئاستی سێرڤەری SMTP: '; +$PHPMAILER_LANG['variable_set'] = 'ناتوانرێت بیگۆڕیت یان دوبارە بینێریتەوە: '; +$PHPMAILER_LANG['extension_missing'] = 'درێژکراوە نەماوە: '; diff --git a/phpmailer/vendor/phpmailer/phpmailer/language/phpmailer.lang-pt.php b/phpmailer/vendor/phpmailer/phpmailer/language/phpmailer.lang-pt.php index f1ce946e..79a68026 100644 --- a/phpmailer/vendor/phpmailer/phpmailer/language/phpmailer.lang-pt.php +++ b/phpmailer/vendor/phpmailer/phpmailer/language/phpmailer.lang-pt.php @@ -3,25 +3,32 @@ /** * Portuguese (European) PHPMailer language file: refer to English translation for definitive list * @package PHPMailer - * @author Jonadabe + * @author João Vieira */ -$PHPMAILER_LANG['authenticate'] = 'Erro do SMTP: Não foi possível realizar a autenticação.'; -$PHPMAILER_LANG['connect_host'] = 'Erro do SMTP: Não foi possível realizar ligação com o servidor SMTP.'; -$PHPMAILER_LANG['data_not_accepted'] = 'Erro do SMTP: Os dados foram rejeitados.'; -$PHPMAILER_LANG['empty_message'] = 'A mensagem no e-mail está vazia.'; +$PHPMAILER_LANG['authenticate'] = 'Erro SMTP: Falha na autenticação.'; +$PHPMAILER_LANG['buggy_php'] = 'A sua versão do PHP tem um bug que pode causar mensagens corrompidas. Para resolver, utilize o envio por SMTP, desative a opção mail.add_x_header no ficheiro php.ini, mude para MacOS ou Linux, ou atualize o PHP para a versão 7.0.17+ ou 7.1.3+.'; +$PHPMAILER_LANG['connect_host'] = 'Erro SMTP: Não foi possível ligar ao servidor SMTP.'; +$PHPMAILER_LANG['data_not_accepted'] = 'Erro SMTP: Dados não aceites.'; +$PHPMAILER_LANG['empty_message'] = 'A mensagem de e-mail está vazia.'; $PHPMAILER_LANG['encoding'] = 'Codificação desconhecida: '; $PHPMAILER_LANG['execute'] = 'Não foi possível executar: '; -$PHPMAILER_LANG['file_access'] = 'Não foi possível aceder o ficheiro: '; -$PHPMAILER_LANG['file_open'] = 'Abertura do ficheiro: Não foi possível abrir o ficheiro: '; -$PHPMAILER_LANG['from_failed'] = 'Ocorreram falhas nos endereços dos seguintes remententes: '; -$PHPMAILER_LANG['instantiate'] = 'Não foi possível iniciar uma instância da função mail.'; -$PHPMAILER_LANG['invalid_address'] = 'Não foi enviado nenhum e-mail para o endereço de e-mail inválido: '; -$PHPMAILER_LANG['mailer_not_supported'] = ' mailer não é suportado.'; -$PHPMAILER_LANG['provide_address'] = 'Tem de fornecer pelo menos um endereço como destinatário do e-mail.'; -$PHPMAILER_LANG['recipients_failed'] = 'Erro do SMTP: O endereço do seguinte destinatário falhou: '; -$PHPMAILER_LANG['signing'] = 'Erro ao assinar: '; -$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() falhou.'; -$PHPMAILER_LANG['smtp_error'] = 'Erro de servidor SMTP: '; -$PHPMAILER_LANG['variable_set'] = 'Não foi possível definir ou redefinir a variável: '; $PHPMAILER_LANG['extension_missing'] = 'Extensão em falta: '; +$PHPMAILER_LANG['file_access'] = 'Não foi possível aceder ao ficheiro: '; +$PHPMAILER_LANG['file_open'] = 'Erro ao abrir o ficheiro: '; +$PHPMAILER_LANG['from_failed'] = 'O envio falhou para o seguinte endereço do remetente: '; +$PHPMAILER_LANG['instantiate'] = 'Não foi possível instanciar a função mail.'; +$PHPMAILER_LANG['invalid_address'] = 'Endereço de e-mail inválido: '; +$PHPMAILER_LANG['invalid_header'] = 'Nome ou valor do cabeçalho inválido.'; +$PHPMAILER_LANG['invalid_hostentry'] = 'Entrada de host inválida: '; +$PHPMAILER_LANG['invalid_host'] = 'Host inválido: '; +$PHPMAILER_LANG['mailer_not_supported'] = 'O cliente de e-mail não é suportado.'; +$PHPMAILER_LANG['provide_address'] = 'Deve fornecer pelo menos um endereço de destinatário.'; +$PHPMAILER_LANG['recipients_failed'] = 'Erro SMTP: Falha no envio para os seguintes destinatários: '; +$PHPMAILER_LANG['signing'] = 'Erro ao assinar: '; +$PHPMAILER_LANG['smtp_code'] = 'Código SMTP: '; +$PHPMAILER_LANG['smtp_code_ex'] = 'Informações adicionais SMTP: '; +$PHPMAILER_LANG['smtp_connect_failed'] = 'Falha na função SMTP connect().'; +$PHPMAILER_LANG['smtp_detail'] = 'Detalhes: '; +$PHPMAILER_LANG['smtp_error'] = 'Erro do servidor SMTP: '; +$PHPMAILER_LANG['variable_set'] = 'Não foi possível definir ou redefinir a variável: '; diff --git a/phpmailer/vendor/phpmailer/phpmailer/language/phpmailer.lang-ru.php b/phpmailer/vendor/phpmailer/phpmailer/language/phpmailer.lang-ru.php index 8c8c5e81..8013f37c 100644 --- a/phpmailer/vendor/phpmailer/phpmailer/language/phpmailer.lang-ru.php +++ b/phpmailer/vendor/phpmailer/phpmailer/language/phpmailer.lang-ru.php @@ -5,24 +5,32 @@ * @package PHPMailer * @author Alexey Chumakov * @author Foster Snowhill + * @author ProjectSoft */ -$PHPMAILER_LANG['authenticate'] = 'Ошибка SMTP: ошибка авторизации.'; +$PHPMAILER_LANG['authenticate'] = 'Ошибка SMTP: не удалось пройти аутентификацию.'; +$PHPMAILER_LANG['buggy_php'] = 'В вашей версии PHP есть ошибка, которая может привести к повреждению сообщений. Чтобы исправить, переключитесь на отправку по SMTP, отключите опцию mail.add_x_header в ваш php.ini, переключитесь на MacOS или Linux или обновите PHP до версии 7.0.17+ или 7.1.3+.'; $PHPMAILER_LANG['connect_host'] = 'Ошибка SMTP: не удается подключиться к SMTP-серверу.'; $PHPMAILER_LANG['data_not_accepted'] = 'Ошибка SMTP: данные не приняты.'; +$PHPMAILER_LANG['empty_message'] = 'Пустое сообщение'; $PHPMAILER_LANG['encoding'] = 'Неизвестная кодировка: '; $PHPMAILER_LANG['execute'] = 'Невозможно выполнить команду: '; +$PHPMAILER_LANG['extension_missing'] = 'Расширение отсутствует: '; $PHPMAILER_LANG['file_access'] = 'Нет доступа к файлу: '; $PHPMAILER_LANG['file_open'] = 'Файловая ошибка: не удаётся открыть файл: '; $PHPMAILER_LANG['from_failed'] = 'Неверный адрес отправителя: '; $PHPMAILER_LANG['instantiate'] = 'Невозможно запустить функцию mail().'; -$PHPMAILER_LANG['provide_address'] = 'Пожалуйста, введите хотя бы один email-адрес получателя.'; -$PHPMAILER_LANG['mailer_not_supported'] = ' — почтовый сервер не поддерживается.'; -$PHPMAILER_LANG['recipients_failed'] = 'Ошибка SMTP: не удалась отправка таким адресатам: '; -$PHPMAILER_LANG['empty_message'] = 'Пустое сообщение'; $PHPMAILER_LANG['invalid_address'] = 'Не отправлено из-за неправильного формата email-адреса: '; +$PHPMAILER_LANG['invalid_header'] = 'Неверное имя или значение заголовка'; +$PHPMAILER_LANG['invalid_hostentry'] = 'Неверная запись хоста: '; +$PHPMAILER_LANG['invalid_host'] = 'Неверный хост: '; +$PHPMAILER_LANG['mailer_not_supported'] = ' — почтовый сервер не поддерживается.'; +$PHPMAILER_LANG['provide_address'] = 'Вы должны указать хотя бы один адрес электронной почты получателя.'; +$PHPMAILER_LANG['recipients_failed'] = 'Ошибка SMTP: Ошибка следующих получателей: '; $PHPMAILER_LANG['signing'] = 'Ошибка подписи: '; -$PHPMAILER_LANG['smtp_connect_failed'] = 'Ошибка соединения с SMTP-сервером'; +$PHPMAILER_LANG['smtp_code'] = 'Код SMTP: '; +$PHPMAILER_LANG['smtp_code_ex'] = 'Дополнительная информация SMTP: '; +$PHPMAILER_LANG['smtp_connect_failed'] = 'Ошибка соединения с SMTP-сервером.'; +$PHPMAILER_LANG['smtp_detail'] = 'Детали: '; $PHPMAILER_LANG['smtp_error'] = 'Ошибка SMTP-сервера: '; $PHPMAILER_LANG['variable_set'] = 'Невозможно установить или сбросить переменную: '; -$PHPMAILER_LANG['extension_missing'] = 'Расширение отсутствует: '; diff --git a/phpmailer/vendor/phpmailer/phpmailer/language/phpmailer.lang-tr.php b/phpmailer/vendor/phpmailer/phpmailer/language/phpmailer.lang-tr.php index f938f802..3c45bc1c 100644 --- a/phpmailer/vendor/phpmailer/phpmailer/language/phpmailer.lang-tr.php +++ b/phpmailer/vendor/phpmailer/phpmailer/language/phpmailer.lang-tr.php @@ -11,21 +11,28 @@ */ $PHPMAILER_LANG['authenticate'] = 'SMTP Hatası: Oturum açılamadı.'; +$PHPMAILER_LANG['buggy_php'] = 'PHP sürümünüz iletilerin bozulmasına neden olabilecek bir hatadan etkileniyor. Bunu düzeltmek için, SMTP kullanarak göndermeye geçin, mail.add_x_header seçeneğini devre dışı bırakın php.ini dosyanızdaki mail.add_x_header seçeneğini devre dışı bırakın, MacOS veya Linux geçin veya PHP sürümünü 7.0.17+ veya 7.1.3+ sürümüne yükseltin,'; $PHPMAILER_LANG['connect_host'] = 'SMTP Hatası: SMTP sunucusuna bağlanılamadı.'; $PHPMAILER_LANG['data_not_accepted'] = 'SMTP Hatası: Veri kabul edilmedi.'; $PHPMAILER_LANG['empty_message'] = 'Mesajın içeriği boş'; $PHPMAILER_LANG['encoding'] = 'Bilinmeyen karakter kodlama: '; $PHPMAILER_LANG['execute'] = 'Çalıştırılamadı: '; +$PHPMAILER_LANG['extension_missing'] = 'Eklenti bulunamadı: '; $PHPMAILER_LANG['file_access'] = 'Dosyaya erişilemedi: '; $PHPMAILER_LANG['file_open'] = 'Dosya Hatası: Dosya açılamadı: '; $PHPMAILER_LANG['from_failed'] = 'Belirtilen adreslere gönderme başarısız: '; $PHPMAILER_LANG['instantiate'] = 'Örnek e-posta fonksiyonu oluşturulamadı.'; $PHPMAILER_LANG['invalid_address'] = 'Geçersiz e-posta adresi: '; +$PHPMAILER_LANG['invalid_header'] = 'Geçersiz başlık adı veya değeri: '; +$PHPMAILER_LANG['invalid_hostentry'] = 'Geçersiz ana bilgisayar girişi: '; +$PHPMAILER_LANG['invalid_host'] = 'Geçersiz ana bilgisayar: '; $PHPMAILER_LANG['mailer_not_supported'] = ' e-posta kütüphanesi desteklenmiyor.'; $PHPMAILER_LANG['provide_address'] = 'En az bir alıcı e-posta adresi belirtmelisiniz.'; $PHPMAILER_LANG['recipients_failed'] = 'SMTP Hatası: Belirtilen alıcılara ulaşılamadı: '; $PHPMAILER_LANG['signing'] = 'İmzalama hatası: '; +$PHPMAILER_LANG['smtp_code'] = 'SMTP kodu: '; +$PHPMAILER_LANG['smtp_code_ex'] = 'ek SMTP bilgileri: '; $PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP connect() fonksiyonu başarısız.'; +$PHPMAILER_LANG['smtp_detail'] = 'SMTP SMTP Detayı: '; $PHPMAILER_LANG['smtp_error'] = 'SMTP sunucu hatası: '; $PHPMAILER_LANG['variable_set'] = 'Değişken ayarlanamadı ya da sıfırlanamadı: '; -$PHPMAILER_LANG['extension_missing'] = 'Eklenti bulunamadı: '; diff --git a/phpmailer/vendor/phpmailer/phpmailer/language/phpmailer.lang-ur.php b/phpmailer/vendor/phpmailer/phpmailer/language/phpmailer.lang-ur.php new file mode 100644 index 00000000..0b9de0f1 --- /dev/null +++ b/phpmailer/vendor/phpmailer/phpmailer/language/phpmailer.lang-ur.php @@ -0,0 +1,30 @@ + + */ + +$PHPMAILER_LANG['authenticate'] = 'SMTP خرابی: تصدیق کرنے سے قاصر۔'; +$PHPMAILER_LANG['connect_host'] = 'SMTP خرابی: سرور سے منسلک ہونے سے قاصر۔'; +$PHPMAILER_LANG['data_not_accepted'] = 'SMTP خرابی: ڈیٹا قبول نہیں کیا گیا۔'; +$PHPMAILER_LANG['empty_message'] = 'پیغام کی باڈی خالی ہے۔'; +$PHPMAILER_LANG['encoding'] = 'نامعلوم انکوڈنگ: '; +$PHPMAILER_LANG['execute'] = 'عمل کرنے کے قابل نہیں '; +$PHPMAILER_LANG['file_access'] = 'فائل تک رسائی سے قاصر:'; +$PHPMAILER_LANG['file_open'] = 'فائل کی خرابی: فائل کو کھولنے سے قاصر:'; +$PHPMAILER_LANG['from_failed'] = 'درج ذیل بھیجنے والے کا پتہ ناکام ہو گیا:'; +$PHPMAILER_LANG['instantiate'] = 'میل فنکشن کی مثال بنانے سے قاصر۔'; +$PHPMAILER_LANG['invalid_address'] = 'بھیجنے سے قاصر: غلط ای میل پتہ:'; +$PHPMAILER_LANG['mailer_not_supported'] = ' میلر تعاون یافتہ نہیں ہے۔'; +$PHPMAILER_LANG['provide_address'] = 'آپ کو کم از کم ایک منزل کا ای میل پتہ فراہم کرنا چاہیے۔'; +$PHPMAILER_LANG['recipients_failed'] = 'SMTP خرابی: درج ذیل پتہ پر نہیں بھیجا جاسکا: '; +$PHPMAILER_LANG['signing'] = 'دستخط کی خرابی: '; +$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP ملنا ناکام ہوا'; +$PHPMAILER_LANG['smtp_error'] = 'SMTP سرور کی خرابی: '; +$PHPMAILER_LANG['variable_set'] = 'متغیر سیٹ نہیں کیا جا سکا: '; +$PHPMAILER_LANG['extension_missing'] = 'ایکٹینشن موجود نہیں ہے۔ '; +$PHPMAILER_LANG['smtp_code'] = 'SMTP سرور کوڈ: '; +$PHPMAILER_LANG['smtp_code_ex'] = 'اضافی SMTP سرور کی معلومات:'; +$PHPMAILER_LANG['invalid_header'] = 'غلط ہیڈر کا نام یا قدر'; diff --git a/phpmailer/vendor/phpmailer/phpmailer/src/DSNConfigurator.php b/phpmailer/vendor/phpmailer/phpmailer/src/DSNConfigurator.php index 566c9618..7058c1f0 100644 --- a/phpmailer/vendor/phpmailer/phpmailer/src/DSNConfigurator.php +++ b/phpmailer/vendor/phpmailer/phpmailer/src/DSNConfigurator.php @@ -13,7 +13,7 @@ * @copyright 2012 - 2023 Marcus Bointon * @copyright 2010 - 2012 Jim Jagielski * @copyright 2004 - 2009 Andy Prevost - * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + * @license https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html GNU Lesser General Public License * @note This program is distributed in the hope that it will be useful - WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. diff --git a/phpmailer/vendor/phpmailer/phpmailer/src/Exception.php b/phpmailer/vendor/phpmailer/phpmailer/src/Exception.php index 52eaf951..09c1a2cf 100644 --- a/phpmailer/vendor/phpmailer/phpmailer/src/Exception.php +++ b/phpmailer/vendor/phpmailer/phpmailer/src/Exception.php @@ -13,7 +13,7 @@ * @copyright 2012 - 2020 Marcus Bointon * @copyright 2010 - 2012 Jim Jagielski * @copyright 2004 - 2009 Andy Prevost - * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + * @license https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html GNU Lesser General Public License * @note This program is distributed in the hope that it will be useful - WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. diff --git a/phpmailer/vendor/phpmailer/phpmailer/src/OAuth.php b/phpmailer/vendor/phpmailer/phpmailer/src/OAuth.php index c1d5b776..a7e95886 100644 --- a/phpmailer/vendor/phpmailer/phpmailer/src/OAuth.php +++ b/phpmailer/vendor/phpmailer/phpmailer/src/OAuth.php @@ -13,7 +13,7 @@ * @copyright 2012 - 2020 Marcus Bointon * @copyright 2010 - 2012 Jim Jagielski * @copyright 2004 - 2009 Andy Prevost - * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + * @license https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html GNU Lesser General Public License * @note This program is distributed in the hope that it will be useful - WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. @@ -29,7 +29,7 @@ use League\OAuth2\Client\Token\AccessToken; * OAuth - OAuth2 authentication wrapper class. * Uses the oauth2-client package from the League of Extraordinary Packages. * - * @see http://oauth2-client.thephpleague.com + * @see https://oauth2-client.thephpleague.com * * @author Marcus Bointon (Synchro/coolbru) */ diff --git a/phpmailer/vendor/phpmailer/phpmailer/src/OAuthTokenProvider.php b/phpmailer/vendor/phpmailer/phpmailer/src/OAuthTokenProvider.php index 11555074..cbda1a12 100644 --- a/phpmailer/vendor/phpmailer/phpmailer/src/OAuthTokenProvider.php +++ b/phpmailer/vendor/phpmailer/phpmailer/src/OAuthTokenProvider.php @@ -13,7 +13,7 @@ * @copyright 2012 - 2020 Marcus Bointon * @copyright 2010 - 2012 Jim Jagielski * @copyright 2004 - 2009 Andy Prevost - * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + * @license https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html GNU Lesser General Public License * @note This program is distributed in the hope that it will be useful - WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. diff --git a/phpmailer/vendor/phpmailer/phpmailer/src/PHPMailer.php b/phpmailer/vendor/phpmailer/phpmailer/src/PHPMailer.php index ba4bcd47..2444bcf3 100644 --- a/phpmailer/vendor/phpmailer/phpmailer/src/PHPMailer.php +++ b/phpmailer/vendor/phpmailer/phpmailer/src/PHPMailer.php @@ -13,7 +13,7 @@ * @copyright 2012 - 2020 Marcus Bointon * @copyright 2010 - 2012 Jim Jagielski * @copyright 2004 - 2009 Andy Prevost - * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + * @license https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html GNU Lesser General Public License * @note This program is distributed in the hope that it will be useful - WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. @@ -152,8 +152,7 @@ class PHPMailer * Only supported in simple alt or alt_inline message types * To generate iCal event structures, use classes like EasyPeasyICS or iCalcreator. * - * @see http://sprain.ch/blog/downloads/php-class-easypeasyics-create-ical-files-with-php/ - * @see http://kigkonsult.se/iCalcreator/ + * @see https://kigkonsult.se/iCalcreator/ * * @var string */ @@ -254,7 +253,7 @@ class PHPMailer * You can set your own, but it must be in the format "", * as defined in RFC5322 section 3.6.4 or it will be ignored. * - * @see https://tools.ietf.org/html/rfc5322#section-3.6.4 + * @see https://www.rfc-editor.org/rfc/rfc5322#section-3.6.4 * * @var string */ @@ -358,7 +357,7 @@ class PHPMailer public $AuthType = ''; /** - * SMTP SMTPXClient command attibutes + * SMTP SMTPXClient command attributes * * @var array */ @@ -388,7 +387,7 @@ class PHPMailer * 'DELAY' will notify you if there is an unusual delay in delivery, but the actual * delivery's outcome (success or failure) is not yet decided. * - * @see https://tools.ietf.org/html/rfc3461 See section 4.1 for more information about NOTIFY + * @see https://www.rfc-editor.org/rfc/rfc3461.html#section-4.1 for more information about NOTIFY */ public $dsn = ''; @@ -468,7 +467,7 @@ class PHPMailer * Only applicable when sending via SMTP. * * @see https://en.wikipedia.org/wiki/Variable_envelope_return_path - * @see http://www.postfix.org/VERP_README.html Postfix VERP info + * @see https://www.postfix.org/VERP_README.html Postfix VERP info * * @var bool */ @@ -551,10 +550,10 @@ class PHPMailer * The function that handles the result of the send email action. * It is called out by send() for each email sent. * - * Value can be any php callable: http://www.php.net/is_callable + * Value can be any php callable: https://www.php.net/is_callable * * Parameters: - * bool $result result of the send action + * bool $result result of the send action * array $to email addresses of the recipients * array $cc cc email addresses * array $bcc bcc email addresses @@ -581,6 +580,10 @@ class PHPMailer * May be a callable to inject your own validator, but there are several built-in validators. * The default validator uses PHP's FILTER_VALIDATE_EMAIL filter_var option. * + * If CharSet is UTF8, the validator is left at the default value, + * and you send to addresses that use non-ASCII local parts, then + * PHPMailer automatically changes to the 'eai' validator. + * * @see PHPMailer::validateAddress() * * @var string|callable @@ -660,6 +663,14 @@ class PHPMailer */ protected $ReplyToQueue = []; + /** + * Whether the need for SMTPUTF8 has been detected. Set by + * preSend() if necessary. + * + * @var bool + */ + public $UseSMTPUTF8 = false; + /** * The array of attachments. * @@ -757,7 +768,7 @@ class PHPMailer * * @var string */ - const VERSION = '6.9.1'; + const VERSION = '6.10.0'; /** * Error severity: message only, continue processing. @@ -903,7 +914,7 @@ class PHPMailer } //Is this a PSR-3 logger? if ($this->Debugoutput instanceof \Psr\Log\LoggerInterface) { - $this->Debugoutput->debug($str); + $this->Debugoutput->debug(rtrim($str, "\r\n")); return; } @@ -1072,7 +1083,7 @@ class PHPMailer * be modified after calling this function), addition of such addresses is delayed until send(). * Addresses that have been added already return false, but do not throw exceptions. * - * @param string $kind One of 'to', 'cc', 'bcc', or 'ReplyTo' + * @param string $kind One of 'to', 'cc', 'bcc', or 'Reply-To' * @param string $address The email address * @param string $name An optional username associated with the address * @@ -1111,19 +1122,22 @@ class PHPMailer $params = [$kind, $address, $name]; //Enqueue addresses with IDN until we know the PHPMailer::$CharSet. //Domain is assumed to be whatever is after the last @ symbol in the address - if (static::idnSupported() && $this->has8bitChars(substr($address, ++$pos))) { - if ('Reply-To' !== $kind) { - if (!array_key_exists($address, $this->RecipientsQueue)) { - $this->RecipientsQueue[$address] = $params; + if ($this->has8bitChars(substr($address, ++$pos))) { + if (static::idnSupported()) { + if ('Reply-To' !== $kind) { + if (!array_key_exists($address, $this->RecipientsQueue)) { + $this->RecipientsQueue[$address] = $params; + + return true; + } + } elseif (!array_key_exists($address, $this->ReplyToQueue)) { + $this->ReplyToQueue[$address] = $params; return true; } - } elseif (!array_key_exists($address, $this->ReplyToQueue)) { - $this->ReplyToQueue[$address] = $params; - - return true; } - + //We have an 8-bit domain, but we are missing the necessary extensions to support it + //Or we are already sending to this address return false; } @@ -1161,6 +1175,15 @@ class PHPMailer */ protected function addAnAddress($kind, $address, $name = '') { + if ( + self::$validator === 'php' && + ((bool) preg_match('/[\x80-\xFF]/', $address)) + ) { + //The caller has not altered the validator and is sending to an address + //with UTF-8, so assume that they want UTF-8 support instead of failing + $this->CharSet = self::CHARSET_UTF8; + self::$validator = 'eai'; + } if (!in_array($kind, ['to', 'cc', 'bcc', 'Reply-To'])) { $error_message = sprintf( '%s: %s', @@ -1212,7 +1235,7 @@ class PHPMailer * Uses the imap_rfc822_parse_adrlist function if the IMAP extension is available. * Note that quotes in the name part are removed. * - * @see http://www.andrew.cmu.edu/user/agreen1/testing/mrbs/web/Mail/RFC822.php A more careful implementation + * @see https://www.andrew.cmu.edu/user/agreen1/testing/mrbs/web/Mail/RFC822.php A more careful implementation * * @param string $addrstr The address list string * @param bool $useimap Whether to use the IMAP extension to parse the list @@ -1363,6 +1386,7 @@ class PHPMailer * * `pcre` Use old PCRE implementation; * * `php` Use PHP built-in FILTER_VALIDATE_EMAIL; * * `html5` Use the pattern given by the HTML5 spec for 'email' type form input elements. + * * `eai` Use a pattern similar to the HTML5 spec for 'email' and to firefox, extended to support EAI (RFC6530). * * `noregex` Don't use a regex: super fast, really dumb. * Alternatively you may pass in a callable to inject your own validator, for example: * @@ -1407,7 +1431,6 @@ class PHPMailer * * IPv6 literals: 'first.last@[IPv6:a1::]' * Not all of these will necessarily work for sending! * - * @see http://squiloople.com/2009/12/20/email-address-validation/ * @copyright 2009-2010 Michael Rushton * Feel free to use and redistribute this code. But please keep this copyright notice. */ @@ -1434,6 +1457,24 @@ class PHPMailer '[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/sD', $address ); + case 'eai': + /* + * This is the pattern used in the HTML5 spec for validation of 'email' type + * form input elements (as above), modified to accept Unicode email addresses. + * This is also more lenient than Firefox' html5 spec, in order to make the regex faster. + * 'eai' is an acronym for Email Address Internationalization. + * This validator is selected automatically if you attempt to use recipient addresses + * that contain Unicode characters in the local part. + * + * @see https://html.spec.whatwg.org/#e-mail-state-(type=email) + * @see https://en.wikipedia.org/wiki/International_email + */ + return (bool) preg_match( + '/^[-\p{L}\p{N}\p{M}.!#$%&\'*+\/=?^_`{|}~]+@[\p{L}\p{N}\p{M}](?:[\p{L}\p{N}\p{M}-]{0,61}' . + '[\p{L}\p{N}\p{M}])?(?:\.[\p{L}\p{N}\p{M}]' . + '(?:[-\p{L}\p{N}\p{M}]{0,61}[\p{L}\p{N}\p{M}])?)*$/usD', + $address + ); case 'php': default: return filter_var($address, FILTER_VALIDATE_EMAIL) !== false; @@ -1567,9 +1608,26 @@ class PHPMailer $this->error_count = 0; //Reset errors $this->mailHeader = ''; + //The code below tries to support full use of Unicode, + //while remaining compatible with legacy SMTP servers to + //the greatest degree possible: If the message uses + //Unicode in the local parts of any addresses, it is sent + //using SMTPUTF8. If not, it it sent using + //punycode-encoded domains and plain SMTP. + if ( + static::CHARSET_UTF8 === strtolower($this->CharSet) && + ($this->anyAddressHasUnicodeLocalPart($this->RecipientsQueue) || + $this->anyAddressHasUnicodeLocalPart(array_keys($this->all_recipients)) || + $this->anyAddressHasUnicodeLocalPart($this->ReplyToQueue) || + $this->addressHasUnicodeLocalPart($this->From)) + ) { + $this->UseSMTPUTF8 = true; + } //Dequeue recipient and Reply-To addresses with IDN foreach (array_merge($this->RecipientsQueue, $this->ReplyToQueue) as $params) { - $params[1] = $this->punyencodeAddress($params[1]); + if (!$this->UseSMTPUTF8) { + $params[1] = $this->punyencodeAddress($params[1]); + } call_user_func_array([$this, 'addAnAddress'], $params); } if (count($this->to) + count($this->cc) + count($this->bcc) < 1) { @@ -1734,9 +1792,8 @@ class PHPMailer //This sets the SMTP envelope sender which gets turned into a return-path header by the receiver //A space after `-f` is optional, but there is a long history of its presence //causing problems, so we don't use one - //Exim docs: http://www.exim.org/exim-html-current/doc/html/spec_html/ch-the_exim_command_line.html - //Sendmail docs: http://www.sendmail.org/~ca/email/man/sendmail.html - //Qmail docs: http://www.qmail.org/man/man8/qmail-inject.html + //Exim docs: https://www.exim.org/exim-html-current/doc/html/spec_html/ch-the_exim_command_line.html + //Sendmail docs: https://www.sendmail.org/~ca/email/man/sendmail.html //Example problem: https://www.drupal.org/node/1057954 //PHP 5.6 workaround @@ -1874,7 +1931,7 @@ class PHPMailer */ protected static function isPermittedPath($path) { - //Matches scheme definition from https://tools.ietf.org/html/rfc3986#section-3.1 + //Matches scheme definition from https://www.rfc-editor.org/rfc/rfc3986#section-3.1 return !preg_match('#^[a-z][a-z\d+.-]*://#i', $path); } @@ -1901,7 +1958,7 @@ class PHPMailer /** * Send mail using the PHP mail() function. * - * @see http://www.php.net/manual/en/book.mail.php + * @see https://www.php.net/manual/en/book.mail.php * * @param string $header The message headers * @param string $body The message body @@ -1931,9 +1988,8 @@ class PHPMailer //This sets the SMTP envelope sender which gets turned into a return-path header by the receiver //A space after `-f` is optional, but there is a long history of its presence //causing problems, so we don't use one - //Exim docs: http://www.exim.org/exim-html-current/doc/html/spec_html/ch-the_exim_command_line.html - //Sendmail docs: http://www.sendmail.org/~ca/email/man/sendmail.html - //Qmail docs: http://www.qmail.org/man/man8/qmail-inject.html + //Exim docs: https://www.exim.org/exim-html-current/doc/html/spec_html/ch-the_exim_command_line.html + //Sendmail docs: https://www.sendmail.org/~ca/email/man/sendmail.html //Example problem: https://www.drupal.org/node/1057954 //CVE-2016-10033, CVE-2016-10045: Don't pass -f if characters will be escaped. @@ -2062,6 +2118,11 @@ class PHPMailer if (!$this->smtpConnect($this->SMTPOptions)) { throw new Exception($this->lang('smtp_connect_failed'), self::STOP_CRITICAL); } + //If we have recipient addresses that need Unicode support, + //but the server doesn't support it, stop here + if ($this->UseSMTPUTF8 && !$this->smtp->getServerExt('SMTPUTF8')) { + throw new Exception($this->lang('no_smtputf8'), self::STOP_CRITICAL); + } //Sender already validated in preSend() if ('' === $this->Sender) { $smtp_from = $this->From; @@ -2163,6 +2224,7 @@ class PHPMailer $this->smtp->setDebugLevel($this->SMTPDebug); $this->smtp->setDebugOutput($this->Debugoutput); $this->smtp->setVerp($this->do_verp); + $this->smtp->setSMTPUTF8($this->UseSMTPUTF8); if ($this->Host === null) { $this->Host = 'localhost'; } @@ -2360,6 +2422,7 @@ class PHPMailer 'smtp_detail' => 'Detail: ', 'smtp_error' => 'SMTP server error: ', 'variable_set' => 'Cannot set or reset variable: ', + 'no_smtputf8' => 'Server does not support SMTPUTF8 needed to send to Unicode addresses', ]; if (empty($lang_path)) { //Calculate an absolute path so it can work if CWD is not here @@ -2709,7 +2772,7 @@ class PHPMailer } //Only allow a custom message ID if it conforms to RFC 5322 section 3.6.4 - //https://tools.ietf.org/html/rfc5322#section-3.6.4 + //https://www.rfc-editor.org/rfc/rfc5322#section-3.6.4 if ( '' !== $this->MessageID && preg_match( @@ -2874,7 +2937,9 @@ class PHPMailer $bodyEncoding = $this->Encoding; $bodyCharSet = $this->CharSet; //Can we do a 7-bit downgrade? - if (static::ENCODING_8BIT === $bodyEncoding && !$this->has8bitChars($this->Body)) { + if ($this->UseSMTPUTF8) { + $bodyEncoding = static::ENCODING_8BIT; + } elseif (static::ENCODING_8BIT === $bodyEncoding && !$this->has8bitChars($this->Body)) { $bodyEncoding = static::ENCODING_7BIT; //All ISO 8859, Windows codepage and UTF-8 charsets are ascii compatible up to 7-bit $bodyCharSet = static::CHARSET_ASCII; @@ -3511,7 +3576,8 @@ class PHPMailer /** * Encode a header value (not including its label) optimally. * Picks shortest of Q, B, or none. Result includes folding if needed. - * See RFC822 definitions for phrase, comment and text positions. + * See RFC822 definitions for phrase, comment and text positions, + * and RFC2047 for inline encodings. * * @param string $str The header value to encode * @param string $position What context the string will be used in @@ -3520,6 +3586,11 @@ class PHPMailer */ public function encodeHeader($str, $position = 'text') { + $position = strtolower($position); + if ($this->UseSMTPUTF8 && !("comment" === $position)) { + return trim(static::normalizeBreaks($str)); + } + $matchcount = 0; switch (strtolower($position)) { case 'phrase': @@ -3634,7 +3705,7 @@ class PHPMailer * without breaking lines within a character. * Adapted from a function by paravoid. * - * @see http://www.php.net/manual/en/function.mb-encode-mimeheader.php#60283 + * @see https://www.php.net/manual/en/function.mb-encode-mimeheader.php#60283 * * @param string $str multi-byte text to wrap encode * @param string $linebreak string to use as linefeed/end-of-line @@ -3690,7 +3761,7 @@ class PHPMailer /** * Encode a string using Q encoding. * - * @see http://tools.ietf.org/html/rfc2047#section-4.2 + * @see https://www.rfc-editor.org/rfc/rfc2047#section-4.2 * * @param string $str the text to encode * @param string $position Where the text is going to be used, see the RFC for what that means @@ -4184,7 +4255,7 @@ class PHPMailer if ('smtp' === $this->Mailer && null !== $this->smtp) { $lasterror = $this->smtp->getError(); if (!empty($lasterror['error'])) { - $msg .= $this->lang('smtp_error') . $lasterror['error']; + $msg .= ' ' . $this->lang('smtp_error') . $lasterror['error']; if (!empty($lasterror['detail'])) { $msg .= ' ' . $this->lang('smtp_detail') . $lasterror['detail']; } @@ -4228,7 +4299,7 @@ class PHPMailer $result = $_SERVER['SERVER_NAME']; } elseif (function_exists('gethostname') && gethostname() !== false) { $result = gethostname(); - } elseif (php_uname('n') !== false) { + } elseif (php_uname('n') !== '') { $result = php_uname('n'); } if (!static::isValidHost($result)) { @@ -4253,7 +4324,7 @@ class PHPMailer empty($host) || !is_string($host) || strlen($host) > 256 - || !preg_match('/^([a-zA-Z\d.-]*|\[[a-fA-F\d:]+\])$/', $host) + || !preg_match('/^([a-z\d.-]*|\[[a-f\d:]+\])$/i', $host) ) { return false; } @@ -4267,10 +4338,49 @@ class PHPMailer //Is it a valid IPv4 address? return filter_var($host, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) !== false; } - //Is it a syntactically valid hostname (when embeded in a URL)? - return filter_var('http://' . $host, FILTER_VALIDATE_URL) !== false; + //Is it a syntactically valid hostname (when embedded in a URL)? + return filter_var('https://' . $host, FILTER_VALIDATE_URL) !== false; } + /** + * Check whether the supplied address uses Unicode in the local part. + * + * @return bool + */ + protected function addressHasUnicodeLocalPart($address) + { + return (bool) preg_match('/[\x80-\xFF].*@/', $address); + } + + /** + * Check whether any of the supplied addresses use Unicode in the local part. + * + * @return bool + */ + protected function anyAddressHasUnicodeLocalPart($addresses) + { + foreach ($addresses as $address) { + if (is_array($address)) { + $address = $address[0]; + } + if ($this->addressHasUnicodeLocalPart($address)) { + return true; + } + } + return false; + } + + /** + * Check whether the message requires SMTPUTF8 based on what's known so far. + * + * @return bool + */ + public function needsSMTPUTF8() + { + return $this->UseSMTPUTF8; + } + + /** * Get an error message in the current language. * @@ -4679,7 +4789,7 @@ class PHPMailer * Multi-byte-safe pathinfo replacement. * Drop-in replacement for pathinfo(), but multibyte- and cross-platform-safe. * - * @see http://www.php.net/manual/en/function.pathinfo.php#107461 + * @see https://www.php.net/manual/en/function.pathinfo.php#107461 * * @param string $path A filename or path, does not need to exist as a file * @param int|string $options Either a PATHINFO_* constant, @@ -4914,7 +5024,7 @@ class PHPMailer * Uses the 'relaxed' algorithm from RFC6376 section 3.4.2. * Canonicalized headers should *always* use CRLF, regardless of mailer setting. * - * @see https://tools.ietf.org/html/rfc6376#section-3.4.2 + * @see https://www.rfc-editor.org/rfc/rfc6376#section-3.4.2 * * @param string $signHeader Header * @@ -4926,7 +5036,7 @@ class PHPMailer $signHeader = static::normalizeBreaks($signHeader, self::CRLF); //Unfold header lines //Note PCRE \s is too broad a definition of whitespace; RFC5322 defines it as `[ \t]` - //@see https://tools.ietf.org/html/rfc5322#section-2.2 + //@see https://www.rfc-editor.org/rfc/rfc5322#section-2.2 //That means this may break if you do something daft like put vertical tabs in your headers. $signHeader = preg_replace('/\r\n[ \t]+/', ' ', $signHeader); //Break headers out into an array @@ -4958,7 +5068,7 @@ class PHPMailer * Uses the 'simple' algorithm from RFC6376 section 3.4.3. * Canonicalized bodies should *always* use CRLF, regardless of mailer setting. * - * @see https://tools.ietf.org/html/rfc6376#section-3.4.3 + * @see https://www.rfc-editor.org/rfc/rfc6376#section-3.4.3 * * @param string $body Message Body * @@ -4994,7 +5104,7 @@ class PHPMailer $DKIMquery = 'dns/txt'; //Query method $DKIMtime = time(); //Always sign these headers without being asked - //Recommended list from https://tools.ietf.org/html/rfc6376#section-5.4.1 + //Recommended list from https://www.rfc-editor.org/rfc/rfc6376#section-5.4.1 $autoSignHeaders = [ 'from', 'to', @@ -5100,7 +5210,7 @@ class PHPMailer } //The DKIM-Signature header is included in the signature *except for* the value of the `b` tag //which is appended after calculating the signature - //https://tools.ietf.org/html/rfc6376#section-3.5 + //https://www.rfc-editor.org/rfc/rfc6376#section-3.5 $dkimSignatureHeader = 'DKIM-Signature: v=1;' . ' d=' . $this->DKIM_domain . ';' . ' s=' . $this->DKIM_selector . ';' . static::$LE . diff --git a/phpmailer/vendor/phpmailer/phpmailer/src/POP3.php b/phpmailer/vendor/phpmailer/phpmailer/src/POP3.php index 7b25fdd7..1190a1e2 100644 --- a/phpmailer/vendor/phpmailer/phpmailer/src/POP3.php +++ b/phpmailer/vendor/phpmailer/phpmailer/src/POP3.php @@ -13,7 +13,7 @@ * @copyright 2012 - 2020 Marcus Bointon * @copyright 2010 - 2012 Jim Jagielski * @copyright 2004 - 2009 Andy Prevost - * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + * @license https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html GNU Lesser General Public License * @note This program is distributed in the hope that it will be useful - WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. @@ -46,7 +46,7 @@ class POP3 * * @var string */ - const VERSION = '6.9.1'; + const VERSION = '6.10.0'; /** * Default POP3 port number. @@ -250,7 +250,9 @@ class POP3 //On Windows this will raise a PHP Warning error if the hostname doesn't exist. //Rather than suppress it with @fsockopen, capture it cleanly instead - set_error_handler([$this, 'catchWarning']); + set_error_handler(function () { + call_user_func_array([$this, 'catchWarning'], func_get_args()); + }); if (false === $port) { $port = static::DEFAULT_PORT; diff --git a/phpmailer/vendor/phpmailer/phpmailer/src/SMTP.php b/phpmailer/vendor/phpmailer/phpmailer/src/SMTP.php index 1b5b0077..7226ee93 100644 --- a/phpmailer/vendor/phpmailer/phpmailer/src/SMTP.php +++ b/phpmailer/vendor/phpmailer/phpmailer/src/SMTP.php @@ -13,7 +13,7 @@ * @copyright 2012 - 2020 Marcus Bointon * @copyright 2010 - 2012 Jim Jagielski * @copyright 2004 - 2009 Andy Prevost - * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + * @license https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html GNU Lesser General Public License * @note This program is distributed in the hope that it will be useful - WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. @@ -35,7 +35,7 @@ class SMTP * * @var string */ - const VERSION = '6.9.1'; + const VERSION = '6.10.0'; /** * SMTP line break constant. @@ -62,7 +62,7 @@ class SMTP * The maximum line length allowed by RFC 5321 section 4.5.3.1.6, * *excluding* a trailing CRLF break. * - * @see https://tools.ietf.org/html/rfc5321#section-4.5.3.1.6 + * @see https://www.rfc-editor.org/rfc/rfc5321#section-4.5.3.1.6 * * @var int */ @@ -72,7 +72,7 @@ class SMTP * The maximum line length allowed for replies in RFC 5321 section 4.5.3.1.5, * *including* a trailing CRLF line break. * - * @see https://tools.ietf.org/html/rfc5321#section-4.5.3.1.5 + * @see https://www.rfc-editor.org/rfc/rfc5321#section-4.5.3.1.5 * * @var int */ @@ -152,19 +152,28 @@ class SMTP /** * Whether to use VERP. * - * @see http://en.wikipedia.org/wiki/Variable_envelope_return_path - * @see http://www.postfix.org/VERP_README.html Info on VERP + * @see https://en.wikipedia.org/wiki/Variable_envelope_return_path + * @see https://www.postfix.org/VERP_README.html Info on VERP * * @var bool */ public $do_verp = false; + /** + * Whether to use SMTPUTF8. + * + * @see https://www.rfc-editor.org/rfc/rfc6531 + * + * @var bool + */ + public $do_smtputf8 = false; + /** * The timeout value for connection, in seconds. * Default of 5 minutes (300sec) is from RFC2821 section 4.5.3.2. * This needs to be quite high to function correctly with hosts using greetdelay as an anti-spam measure. * - * @see http://tools.ietf.org/html/rfc2821#section-4.5.3.2 + * @see https://www.rfc-editor.org/rfc/rfc2821#section-4.5.3.2 * * @var int */ @@ -187,12 +196,12 @@ class SMTP */ protected $smtp_transaction_id_patterns = [ 'exim' => '/[\d]{3} OK id=(.*)/', - 'sendmail' => '/[\d]{3} 2.0.0 (.*) Message/', - 'postfix' => '/[\d]{3} 2.0.0 Ok: queued as (.*)/', - 'Microsoft_ESMTP' => '/[0-9]{3} 2.[\d].0 (.*)@(?:.*) Queued mail for delivery/', + 'sendmail' => '/[\d]{3} 2\.0\.0 (.*) Message/', + 'postfix' => '/[\d]{3} 2\.0\.0 Ok: queued as (.*)/', + 'Microsoft_ESMTP' => '/[0-9]{3} 2\.[\d]\.0 (.*)@(?:.*) Queued mail for delivery/', 'Amazon_SES' => '/[\d]{3} Ok (.*)/', 'SendGrid' => '/[\d]{3} Ok: queued as (.*)/', - 'CampaignMonitor' => '/[\d]{3} 2.0.0 OK:([a-zA-Z\d]{48})/', + 'CampaignMonitor' => '/[\d]{3} 2\.0\.0 OK:([a-zA-Z\d]{48})/', 'Haraka' => '/[\d]{3} Message Queued \((.*)\)/', 'ZoneMTA' => '/[\d]{3} Message queued as (.*)/', 'Mailjet' => '/[\d]{3} OK queued as (.*)/', @@ -280,7 +289,8 @@ class SMTP } //Is this a PSR-3 logger? if ($this->Debugoutput instanceof \Psr\Log\LoggerInterface) { - $this->Debugoutput->debug($str); + //Remove trailing line breaks potentially added by calls to SMTP::client_send() + $this->Debugoutput->debug(rtrim($str, "\r\n")); return; } @@ -293,6 +303,7 @@ class SMTP switch ($this->Debugoutput) { case 'error_log': //Don't output, just log + /** @noinspection ForgottenDebugOutputInspection */ error_log($str); break; case 'html': @@ -371,7 +382,7 @@ class SMTP } //Anything other than a 220 response means something went wrong //RFC 5321 says the server will wait for us to send a QUIT in response to a 554 error - //https://tools.ietf.org/html/rfc5321#section-3.1 + //https://www.rfc-editor.org/rfc/rfc5321#section-3.1 if ($responseCode === 554) { $this->quit(); } @@ -404,7 +415,9 @@ class SMTP $errstr = ''; if ($streamok) { $socket_context = stream_context_create($options); - set_error_handler([$this, 'errorHandler']); + set_error_handler(function () { + call_user_func_array([$this, 'errorHandler'], func_get_args()); + }); $connection = stream_socket_client( $host . ':' . $port, $errno, @@ -419,7 +432,9 @@ class SMTP 'Connection: stream_socket_client not available, falling back to fsockopen', self::DEBUG_CONNECTION ); - set_error_handler([$this, 'errorHandler']); + set_error_handler(function () { + call_user_func_array([$this, 'errorHandler'], func_get_args()); + }); $connection = fsockopen( $host, $port, @@ -483,7 +498,9 @@ class SMTP } //Begin encrypted connection - set_error_handler([$this, 'errorHandler']); + set_error_handler(function () { + call_user_func_array([$this, 'errorHandler'], func_get_args()); + }); $crypto_ok = stream_socket_enable_crypto( $this->smtp_conn, true, @@ -574,7 +591,7 @@ class SMTP } //Send encoded username and password if ( - //Format from https://tools.ietf.org/html/rfc4616#section-2 + //Format from https://www.rfc-editor.org/rfc/rfc4616#section-2 //We skip the first field (it's forgery), so the string starts with a null byte !$this->sendCommand( 'User & Password', @@ -648,7 +665,7 @@ class SMTP } //The following borrowed from - //http://php.net/manual/en/function.mhash.php#27225 + //https://www.php.net/manual/en/function.mhash.php#27225 //RFC 2104 HMAC implementation for php. //Creates an md5 HMAC. @@ -787,7 +804,7 @@ class SMTP //Send the lines to the server foreach ($lines_out as $line_out) { //Dot-stuffing as per RFC5321 section 4.5.2 - //https://tools.ietf.org/html/rfc5321#section-4.5.2 + //https://www.rfc-editor.org/rfc/rfc5321#section-4.5.2 if (!empty($line_out) && $line_out[0] === '.') { $line_out = '.' . $line_out; } @@ -905,7 +922,15 @@ class SMTP * $from. Returns true if successful or false otherwise. If True * the mail transaction is started and then one or more recipient * commands may be called followed by a data command. - * Implements RFC 821: MAIL FROM: . + * Implements RFC 821: MAIL FROM: and + * two extensions, namely XVERP and SMTPUTF8. + * + * The server's EHLO response is not checked. If use of either + * extensions is enabled even though the server does not support + * that, mail submission will fail. + * + * XVERP is documented at https://www.postfix.org/VERP_README.html + * and SMTPUTF8 is specified in RFC 6531. * * @param string $from Source address of this message * @@ -914,10 +939,11 @@ class SMTP public function mail($from) { $useVerp = ($this->do_verp ? ' XVERP' : ''); + $useSmtputf8 = ($this->do_smtputf8 ? ' SMTPUTF8' : ''); return $this->sendCommand( 'MAIL FROM', - 'MAIL FROM:<' . $from . '>' . $useVerp, + 'MAIL FROM:<' . $from . '>' . $useSmtputf8 . $useVerp, 250 ); } @@ -1162,7 +1188,9 @@ class SMTP } else { $this->edebug('CLIENT -> SERVER: ' . $data, self::DEBUG_CLIENT); } - set_error_handler([$this, 'errorHandler']); + set_error_handler(function () { + call_user_func_array([$this, 'errorHandler'], func_get_args()); + }); $result = fwrite($this->smtp_conn, $data); restore_error_handler(); @@ -1265,7 +1293,9 @@ class SMTP while (is_resource($this->smtp_conn) && !feof($this->smtp_conn)) { //Must pass vars in here as params are by reference //solution for signals inspired by https://github.com/symfony/symfony/pull/6540 - set_error_handler([$this, 'errorHandler']); + set_error_handler(function () { + call_user_func_array([$this, 'errorHandler'], func_get_args()); + }); $n = stream_select($selR, $selW, $selW, $this->Timelimit); restore_error_handler(); @@ -1352,6 +1382,26 @@ class SMTP return $this->do_verp; } + /** + * Enable or disable use of SMTPUTF8. + * + * @param bool $enabled + */ + public function setSMTPUTF8($enabled = false) + { + $this->do_smtputf8 = $enabled; + } + + /** + * Get SMTPUTF8 use. + * + * @return bool + */ + public function getSMTPUTF8() + { + return $this->do_smtputf8; + } + /** * Set error messages and codes. * diff --git a/piwik/piwik.php b/piwik/piwik.php index fd6d5fc9..b7e9e71c 100644 --- a/piwik/piwik.php +++ b/piwik/piwik.php @@ -35,9 +35,7 @@ * setting. */ -use Friendica\App; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\DI; use Friendica\Core\Config\Util\ConfigFileManager; @@ -46,12 +44,12 @@ function piwik_install() { Hook::register('load_config', 'addon/piwik/piwik.php', 'piwik_load_config'); Hook::register('page_end', 'addon/piwik/piwik.php', 'piwik_analytics'); - Logger::notice("installed piwik addon"); + DI::logger()->notice("installed piwik addon"); } function piwik_load_config(ConfigFileManager $loader) { - DI::app()->getConfigCache()->load($loader->loadAddonConfig('piwik'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); + DI::appHelper()->getConfigCache()->load($loader->loadAddonConfig('piwik'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); } function piwik_analytics(string &$b) @@ -76,7 +74,7 @@ function piwik_analytics(string &$b) * Add the Piwik tracking code for the site. * If async is set to true use asynchronous tracking */ - + $scriptAsyncValue = $async ? 'true' : 'false'; $scriptPhpEndpoint = $shortendpoint ? 'js/' : 'piwik.php'; $scriptJsEndpoint = $shortendpoint ? 'js/' : 'piwik.js'; diff --git a/planets/planets.php b/planets/planets.php index 8a206fb5..8849010a 100644 --- a/planets/planets.php +++ b/planets/planets.php @@ -7,9 +7,7 @@ * Author: Tony Baldwin */ -use Friendica\App; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\DI; @@ -29,7 +27,7 @@ function planets_install() Hook::register('addon_settings', 'addon/planets/planets.php', 'planets_settings'); Hook::register('addon_settings_post', 'addon/planets/planets.php', 'planets_settings_post'); - Logger::notice("installed planets"); + DI::logger()->notice("installed planets"); } /** @@ -40,7 +38,7 @@ function planets_install() */ function planets_post_hook(&$item) { - Logger::notice('planets invoked'); + DI::logger()->notice('planets invoked'); if (!DI::userSession()->getLocalUserId()) { /* non-zero if this is a logged in user of this system */ diff --git a/pnut/lib/phpnut.php b/pnut/lib/phpnut.php index ff765243..716945ed 100644 --- a/pnut/lib/phpnut.php +++ b/pnut/lib/phpnut.php @@ -1025,7 +1025,7 @@ class phpnut * see: https://docs.pnut.io/resources/posts/search * @param string $query The search query. Supports * normal search terms. Searches post text. - * @return array An array of associative arrays, each representing one post. + * @return string|array|false An array of associative arrays, each representing one post. * or false on error */ public function searchPosts(array $params=[], string $query='', string $order='default') @@ -1769,7 +1769,7 @@ class phpnut * see: https://docs.pnut.io/resources/messages/search * @param string $query The search query. Supports * normal search terms. Searches common channel raw. - * @return array An array of associative arrays, each representing one channel. + * @return string|array|false An array of associative arrays, each representing one channel. * or false on error */ public function searchMessages(array $params=[], string $query='', string $order='default') diff --git a/pnut/pnut.php b/pnut/pnut.php index 32f60f6d..5460b991 100644 --- a/pnut/pnut.php +++ b/pnut/pnut.php @@ -14,7 +14,6 @@ use Friendica\Content\Text\BBCode; use Friendica\Content\Text\Plaintext; use Friendica\Core\Config\Util\ConfigFileManager; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\Core\System; use Friendica\DI; @@ -76,7 +75,7 @@ function pnut_connect() try { $token = $nut->getAccessToken($callback_url); - Logger::debug('Got Token', [$token]); + DI::logger()->debug('Got Token', [$token]); $o = DI::l10n()->t('You are now authenticated with pnut.io.'); DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'pnut', 'access_token', $token); } catch (phpnutException $e) { @@ -90,7 +89,7 @@ function pnut_connect() function pnut_load_config(ConfigFileManager $loader) { - DI::app()->getConfigCache()->load($loader->loadAddonConfig('pnut'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); + DI::appHelper()->getConfigCache()->load($loader->loadAddonConfig('pnut'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); } function pnut_addon_admin(string &$o) @@ -266,8 +265,8 @@ function pnut_post_hook(array &$b) return; } - Logger::notice('PNUT post invoked', ['id' => $b['id'], 'guid' => $b['guid'], 'plink' => $b['plink']]); - Logger::debug('PNUT array', $b); + DI::logger()->notice('PNUT post invoked', ['id' => $b['id'], 'guid' => $b['guid'], 'plink' => $b['plink']]); + DI::logger()->debug('PNUT array', $b); $token = DI::pConfig()->get($b['uid'], 'pnut', 'access_token'); $nut = new phpnut\phpnut($token); @@ -276,7 +275,7 @@ function pnut_post_hook(array &$b) $text = $msgarr['text']; $raw = []; - Logger::debug('PNUT msgarr', $msgarr); + DI::logger()->debug('PNUT msgarr', $msgarr); if (count($msgarr['parts']) > 1) { $tstamp = time(); @@ -292,23 +291,23 @@ function pnut_post_hook(array &$b) if ($msgarr['type'] == 'photo') { $fileraw = ['type' => 'dev.mcmillian.friendica.image', 'kind' => 'image', 'is_public' => true]; foreach ($msgarr['images'] as $image) { - Logger::debug('PNUT image', $image); + DI::logger()->debug('PNUT image', $image); if (!empty($image['id'])) { $photo = Photo::selectFirst([], ['id' => $image['id']]); - Logger::debug('PNUT selectFirst'); + DI::logger()->debug('PNUT selectFirst'); } else { $photo = Photo::createPhotoForExternalResource($image['url']); - Logger::debug('PNUT createPhotoForExternalResource'); + DI::logger()->debug('PNUT createPhotoForExternalResource'); } $picturedata = Photo::getImageForPhoto($photo); - Logger::debug('PNUT photo', $photo); + DI::logger()->debug('PNUT photo', $photo); $picurefile = tempnam(System::getTempPath(), 'pnut'); file_put_contents($picurefile, $picturedata); - Logger::debug('PNUT got file?', ['filename' => $picurefile]); + DI::logger()->debug('PNUT got file?', ['filename' => $picurefile]); $imagefile = $nut->createFile($picurefile, $fileraw); - Logger::debug('PNUT file', ['pnutimagefile' => $imagefile]); + DI::logger()->debug('PNUT file', ['pnutimagefile' => $imagefile]); unlink($picurefile); $raw['io.pnut.core.oembed'][] = ['+io.pnut.core.file' => ['file_id' => $imagefile['id'], 'file_token' => $imagefile['file_token'], 'format' => 'oembed']]; @@ -318,5 +317,5 @@ function pnut_post_hook(array &$b) $raw['io.pnut.core.crosspost'][] = ['canonical_url' => $b['plink']]; $nut->createPost($text, ['raw' => $raw]); - Logger::debug('PNUT post complete', ['id' => $b['id'], 'text' => $text, 'raw' => $raw]); + DI::logger()->debug('PNUT post complete', ['id' => $b['id'], 'text' => $text, 'raw' => $raw]); } diff --git a/public_server/public_server.php b/public_server/public_server.php index 7591c7d0..9cd0f667 100644 --- a/public_server/public_server.php +++ b/public_server/public_server.php @@ -6,10 +6,8 @@ * Author: Keith Fernie */ -use Friendica\App; use Friendica\BaseModule; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\Database\DBA; use Friendica\DI; @@ -29,7 +27,7 @@ function public_server_install() function public_server_load_config(ConfigFileManager $loader) { - DI::app()->getConfigCache()->load($loader->loadAddonConfig('public_server'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); + DI::appHelper()->getConfigCache()->load($loader->loadAddonConfig('public_server'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); } function public_server_register_account($b) @@ -48,7 +46,7 @@ function public_server_register_account($b) function public_server_cron($b) { - Logger::notice("public_server: cron start"); + DI::logger()->notice("public_server: cron start"); $users = DBA::selectToArray('user', [], ["`account_expires_on` > ? AND `account_expires_on` < ? AND `expire_notification_sent` <= ?", DBA::NULL_DATETIME, DateTimeFormat::utc('now + 5 days'), DBA::NULL_DATETIME]); @@ -97,7 +95,7 @@ function public_server_cron($b) } } - Logger::notice("public_server: cron end"); + DI::logger()->notice("public_server: cron end"); } function public_server_enotify(array &$b) diff --git a/pumpio/pumpio.php b/pumpio/pumpio.php index d7c2ac32..2d6937e8 100644 --- a/pumpio/pumpio.php +++ b/pumpio/pumpio.php @@ -8,9 +8,7 @@ use Friendica\Content\Text\BBCode; use Friendica\Content\Text\HTML; -use Friendica\Core\Addon; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Protocol; use Friendica\Core\Renderer; use Friendica\Core\Worker; @@ -107,7 +105,7 @@ function pumpio_registerclient($host) $params['logo_url'] = DI::baseUrl() . '/images/friendica-256.png'; $params['redirect_uris'] = DI::baseUrl() . '/pumpio/connect'; - Logger::info('pumpio_registerclient: ' . $url . ' parameters', $params); + DI::logger()->info('pumpio_registerclient: ' . $url . ' parameters', $params); // @TODO Rewrite this to our own HTTP client $ch = curl_init($url); @@ -122,10 +120,10 @@ function pumpio_registerclient($host) if ($curl_info['http_code'] == '200') { $values = json_decode($s); - Logger::info('pumpio_registerclient: success ', (array)$values); + DI::logger()->info('pumpio_registerclient: success ', (array)$values); return $values; } - Logger::info('pumpio_registerclient: failed: ', $curl_info); + DI::logger()->info('pumpio_registerclient: failed: ', $curl_info); return false; } @@ -138,7 +136,7 @@ function pumpio_connect() $hostname = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'pumpio', 'host'); if ((($consumer_key == '') || ($consumer_secret == '')) && ($hostname != '')) { - Logger::notice('pumpio_connect: register client'); + DI::logger()->notice('pumpio_connect: register client'); $clientdata = pumpio_registerclient($hostname); DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'pumpio', 'consumer_key', $clientdata->client_id); DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'pumpio', 'consumer_secret', $clientdata->client_secret); @@ -146,11 +144,11 @@ function pumpio_connect() $consumer_key = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'pumpio', 'consumer_key'); $consumer_secret = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'pumpio', 'consumer_secret'); - Logger::info('pumpio_connect: ckey: ' . $consumer_key . ' csecrect: ' . $consumer_secret); + DI::logger()->info('pumpio_connect: ckey: ' . $consumer_key . ' csecrect: ' . $consumer_secret); } if (($consumer_key == '') || ($consumer_secret == '')) { - Logger::notice('pumpio_connect: '.sprintf('Unable to register the client at the pump.io server "%s".', $hostname)); + DI::logger()->notice('pumpio_connect: '.sprintf('Unable to register the client at the pump.io server "%s".', $hostname)); return DI::l10n()->t("Unable to register the client at the pump.io server '%s'.", $hostname); } @@ -179,7 +177,7 @@ function pumpio_connect() if (($success = $client->Initialize())) { if (($success = $client->Process())) { if (strlen($client->access_token)) { - Logger::info('pumpio_connect: otoken: ' . $client->access_token . ', osecrect: ' . $client->access_token_secret); + DI::logger()->info('pumpio_connect: otoken: ' . $client->access_token . ', osecrect: ' . $client->access_token_secret); DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'pumpio', 'oauth_token', $client->access_token); DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'pumpio', 'oauth_token_secret', $client->access_token_secret); } @@ -191,11 +189,11 @@ function pumpio_connect() } if ($success) { - Logger::notice('pumpio_connect: authenticated'); + DI::logger()->notice('pumpio_connect: authenticated'); $o = DI::l10n()->t('You are now authenticated to pumpio.'); $o .= '
' . DI::l10n()->t('return to the connector page') . ''; } else { - Logger::notice('pumpio_connect: could not connect'); + DI::logger()->notice('pumpio_connect: could not connect'); $o = 'Could not connect to pumpio. Refresh the page or try again later.'; } @@ -319,7 +317,7 @@ function pumpio_settings_post(array &$b) function pumpio_load_config(ConfigFileManager $loader) { - DI::app()->getConfigCache()->load($loader->loadAddonConfig('pumpio'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); + DI::appHelper()->getConfigCache()->load($loader->loadAddonConfig('pumpio'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); } function pumpio_hook_fork(array &$b) @@ -345,7 +343,7 @@ function pumpio_hook_fork(array &$b) if (DI::pConfig()->get($post['uid'], 'pumpio', 'import')) { // Don't fork if it isn't a reply to a pump.io post if (($post['gravity'] != Item::GRAVITY_PARENT) && !Post::exists(['id' => $post['parent'], 'network' => Protocol::PUMPIO])) { - Logger::notice('No pump.io parent found for item ' . $post['id']); + DI::logger()->notice('No pump.io parent found for item ' . $post['id']); $b['execute'] = false; return; } @@ -389,7 +387,7 @@ function pumpio_send(array &$b) return; } - Logger::debug('pumpio_send: parameter ', $b); + DI::logger()->debug('pumpio_send: parameter ', $b); $b['body'] = Post\Media::addAttachmentsToBody($b['uri-id'], DI::contentItem()->addSharedPost($b)); @@ -399,7 +397,7 @@ function pumpio_send(array &$b) $orig_post = Post::selectFirst([], $condition); if (!DBA::isResult($orig_post)) { - Logger::notice('pumpio_send: no pumpio post ' . $b['parent']); + DI::logger()->notice('pumpio_send: no pumpio post ' . $b['parent']); return; } else { $iscomment = true; @@ -409,7 +407,7 @@ function pumpio_send(array &$b) $receiver = pumpio_getreceiver($b); - Logger::notice('pumpio_send: receiver ', $receiver); + DI::logger()->notice('pumpio_send: receiver ', $receiver); if (!count($receiver) && ($b['private'] == Item::PRIVATE) || !strstr($b['postopts'], 'pumpio')) { return; @@ -543,13 +541,13 @@ function pumpio_send(array &$b) } $post_id = $user->object->id; - Logger::notice('pumpio_send ' . $username . ': success ' . $post_id); + DI::logger()->notice('pumpio_send ' . $username . ': success ' . $post_id); if ($post_id && $iscomment) { - Logger::notice('pumpio_send ' . $username . ': Update extid ' . $post_id . ' for post id ' . $b['id']); + DI::logger()->notice('pumpio_send ' . $username . ': Update extid ' . $post_id . ' for post id ' . $b['id']); Item::update(['extid' => $post_id], ['id' => $b['id']]); } } else { - Logger::notice('pumpio_send '.$username.': '.$url.' general error: ' . print_r($user, true)); + DI::logger()->notice('pumpio_send '.$username.': '.$url.' general error: ' . print_r($user, true)); Worker::defer(); } } @@ -619,16 +617,18 @@ function pumpio_action(int $uid, string $uri, string $action, string $content = } if ($success) { - Logger::notice('pumpio_action '.$username.' '.$action.': success '.$uri); + DI::logger()->notice('pumpio_action '.$username.' '.$action.': success '.$uri); } else { - Logger::notice('pumpio_action '.$username.' '.$action.': general error: '.$uri); + DI::logger()->notice('pumpio_action '.$username.' '.$action.': general error: '.$uri); Worker::defer(); } } function pumpio_sync() { - if (!Addon::isEnabled('pumpio')) { + $addonHelper = DI::addonHelper(); + + if (!$addonHelper->isAddonEnabled('pumpio')) { return; } @@ -639,15 +639,15 @@ function pumpio_sync() if ($last) { $next = $last + ($poll_interval * 60); if ($next > time()) { - Logger::notice('pumpio: poll intervall not reached'); + DI::logger()->notice('pumpio: poll intervall not reached'); return; } } - Logger::notice('pumpio: cron_start'); + DI::logger()->notice('pumpio: cron_start'); $pconfigs = DBA::selectToArray('pconfig', ['uid'], ['cat' => 'pumpio', 'k' => 'mirror', 'v' => '1']); foreach ($pconfigs as $rr) { - Logger::notice('pumpio: mirroring user '.$rr['uid']); + DI::logger()->notice('pumpio: mirroring user '.$rr['uid']); pumpio_fetchtimeline($rr['uid']); } @@ -662,12 +662,12 @@ function pumpio_sync() foreach ($pconfigs as $rr) { if ($abandon_days != 0) { if (DBA::exists('user', ["uid = ? AND `login_date` >= ?", $rr['uid'], $abandon_limit])) { - Logger::notice('abandoned account: timeline from user '.$rr['uid'].' will not be imported'); + DI::logger()->notice('abandoned account: timeline from user '.$rr['uid'].' will not be imported'); continue; } } - Logger::notice('pumpio: importing timeline from user '.$rr['uid']); + DI::logger()->notice('pumpio: importing timeline from user '.$rr['uid']); pumpio_fetchinbox($rr['uid']); // check for new contacts once a day @@ -684,7 +684,7 @@ function pumpio_sync() } } - Logger::notice('pumpio: cron_end'); + DI::logger()->notice('pumpio: cron_end'); DI::keyValue()->set('pumpio_last_poll', time()); } @@ -729,7 +729,7 @@ function pumpio_fetchtimeline(int $uid) $url = 'https://'.$hostname.'/api/user/'.$username.'/feed/major'; - Logger::notice('pumpio: fetching for user ' . $uid . ' ' . $url . ' C:' . $client->client_id . ' CS:' . $client->client_secret . ' T:' . $client->access_token . ' TS:' . $client->access_token_secret); + DI::logger()->notice('pumpio: fetching for user ' . $uid . ' ' . $url . ' C:' . $client->client_id . ' CS:' . $client->client_secret . ' T:' . $client->access_token . ' TS:' . $client->access_token_secret); $useraddr = $username.'@'.$hostname; @@ -741,7 +741,7 @@ function pumpio_fetchtimeline(int $uid) } if (!$success) { - Logger::notice('pumpio: error fetching posts for user ' . $uid . ' ' . $useraddr . ' ', $user); + DI::logger()->notice('pumpio: error fetching posts for user ' . $uid . ' ' . $useraddr . ' ', $user); return; } @@ -801,11 +801,11 @@ function pumpio_fetchtimeline(int $uid) } } - Logger::notice('pumpio: posting for user ' . $uid); + DI::logger()->notice('pumpio: posting for user ' . $uid); Item::insert($postarray, true); - Logger::notice('pumpio: posting done - user ' . $uid); + DI::logger()->notice('pumpio: posting done - user ' . $uid); } } } @@ -846,16 +846,16 @@ function pumpio_dounlike(int $uid, array $self, $post, string $own_id) Item::markForDeletion(['verb' => Activity::LIKE, 'uid' => $uid, 'contact-id' => $contactid, 'thr-parent' => $orig_post['uri']]); if (DBA::isResult($contact)) { - Logger::notice('pumpio_dounlike: unliked existing like. User ' . $own_id . ' ' . $uid . ' Contact: ' . $contactid . ' URI ' . $orig_post['uri']); + DI::logger()->notice('pumpio_dounlike: unliked existing like. User ' . $own_id . ' ' . $uid . ' Contact: ' . $contactid . ' URI ' . $orig_post['uri']); } else { - Logger::notice('pumpio_dounlike: not found. User ' . $own_id . ' ' . $uid . ' Contact: ' . $contactid . ' Url ' . $orig_post['uri']); + DI::logger()->notice('pumpio_dounlike: not found. User ' . $own_id . ' ' . $uid . ' Contact: ' . $contactid . ' Url ' . $orig_post['uri']); } } function pumpio_dolike(int $uid, array $self, $post, string $own_id, $threadcompletion = true) { if (empty($post->object->id)) { - Logger::info('Got empty like: '.print_r($post, true)); + DI::logger()->info('Got empty like: '.print_r($post, true)); return; } @@ -900,7 +900,7 @@ function pumpio_dolike(int $uid, array $self, $post, string $own_id, $threadcomp ]; if (Post::exists($condition)) { - Logger::notice('pumpio_dolike: found existing like. User ' . $own_id . ' ' . $uid . ' Contact: ' . $contactid . ' URI ' . $orig_post['uri']); + DI::logger()->notice('pumpio_dolike: found existing like. User ' . $own_id . ' ' . $uid . ' Contact: ' . $contactid . ' URI ' . $orig_post['uri']); return; } @@ -934,7 +934,7 @@ function pumpio_dolike(int $uid, array $self, $post, string $own_id, $threadcomp $ret = Item::insert($likedata); - Logger::notice('pumpio_dolike: ' . $ret . ' User ' . $own_id . ' ' . $uid . ' Contact: ' . $contactid . ' URI ' . $orig_post['uri']); + DI::logger()->notice('pumpio_dolike: ' . $ret . ' User ' . $own_id . ' ' . $uid . ' Contact: ' . $contactid . ' URI ' . $orig_post['uri']); } function pumpio_get_contact($uid, $contact, $no_insert = false) @@ -1405,7 +1405,7 @@ function pumpio_fetchallcomments($uid, $id) $hostname = DI::pConfig()->get($uid, 'pumpio', 'host'); $username = DI::pConfig()->get($uid, 'pumpio', 'user'); - Logger::notice('pumpio_fetchallcomments: completing comment for user ' . $uid . ' post id ' . $id); + DI::logger()->notice('pumpio_fetchallcomments: completing comment for user ' . $uid . ' post id ' . $id); $own_id = 'https://' . $hostname . '/' . $username; @@ -1430,7 +1430,7 @@ function pumpio_fetchallcomments($uid, $id) $client->access_token = $otoken; $client->access_token_secret = $osecret; - Logger::notice('pumpio_fetchallcomments: fetching comment for user ' . $uid . ', URL ' . $url); + DI::logger()->notice('pumpio_fetchallcomments: fetching comment for user ' . $uid . ', URL ' . $url); $item = new \stdClass(); @@ -1495,7 +1495,7 @@ function pumpio_fetchallcomments($uid, $id) $post->object = $item; - Logger::notice('pumpio_fetchallcomments: posting comment ' . $post->object->id . ' ', json_decode(json_encode($post), true)); + DI::logger()->notice('pumpio_fetchallcomments: posting comment ' . $post->object->id . ' ', json_decode(json_encode($post), true)); pumpio_dopost($client, $uid, $self, $post, $own_id, false); } } diff --git a/pumpio/pumpio_sync.php b/pumpio/pumpio_sync.php index beaf6e81..09548c6d 100644 --- a/pumpio/pumpio_sync.php +++ b/pumpio/pumpio_sync.php @@ -1,5 +1,5 @@ DI::config()->get('system', 'maxloadavg', 50)) { - Logger::notice('system: load ' . $load[0] . ' too high. Pumpio sync deferred to next scheduled run.'); + DI::logger()->notice('system: load ' . $load[0] . ' too high. Pumpio sync deferred to next scheduled run.'); return; } } diff --git a/qcomment/qcomment.php b/qcomment/qcomment.php index 1b8bfcbf..f7126531 100644 --- a/qcomment/qcomment.php +++ b/qcomment/qcomment.php @@ -18,7 +18,6 @@ * */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\Core\Renderer; use Friendica\DI; diff --git a/randplace/randplace.php b/randplace/randplace.php index 34f48c6c..89a75f98 100644 --- a/randplace/randplace.php +++ b/randplace/randplace.php @@ -19,9 +19,7 @@ * */ -use Friendica\App; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\DI; @@ -41,7 +39,7 @@ function randplace_install() Hook::register('addon_settings', 'addon/randplace/randplace.php', 'randplace_settings'); Hook::register('addon_settings_post', 'addon/randplace/randplace.php', 'randplace_settings_post'); - Logger::notice("installed randplace"); + DI::logger()->notice("installed randplace"); } function randplace_uninstall() @@ -51,7 +49,7 @@ function randplace_uninstall() * * Except hooks, they are all unregistered automatically and don't need to be unregistered manually. */ - Logger::notice("removed randplace"); + DI::logger()->notice("removed randplace"); } function randplace_post_hook(&$item) @@ -62,7 +60,7 @@ function randplace_post_hook(&$item) * - A status post by a profile owner * - The profile owner must have allowed our addon */ - Logger::notice('randplace invoked'); + DI::logger()->notice('randplace invoked'); if (!DI::userSession()->getLocalUserId()) { /* non-zero if this is a logged in user of this system */ diff --git a/ratioed/RatioedPanel.php b/ratioed/RatioedPanel.php index bd9b44dc..4cf5d7ff 100644 --- a/ratioed/RatioedPanel.php +++ b/ratioed/RatioedPanel.php @@ -3,12 +3,13 @@ namespace Friendica\Addon\ratioed; use Friendica\Content\Pager; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\Database\DBA; use Friendica\DI; use Friendica\Model\User; +use Friendica\Model\Verb; use Friendica\Module\Moderation\Users\Active; +use Friendica\Protocol\Activity; /** * This class implements the "Behaviour" panel in Moderation/Users @@ -24,7 +25,6 @@ class RatioedPanel extends Active return Renderer::replaceMacros($template, array('$config' => DI::baseUrl() . '/settings/addon')); } - $action = $this->parameters['action'] ?? ''; $uid = $this->parameters['uid'] ?? 0; $user = []; @@ -32,31 +32,10 @@ class RatioedPanel extends Active $user = User::getById($uid, ['username', 'blocked']); if (!$user) { $this->systemMessages->addNotice($this->t('User not found')); - $this->baseUrl->redirect('moderation/users'); + $this->baseUrl->redirect('ratioed'); } } - switch ($action) { - case 'delete': - if ($this->session->getLocalUserId() != $uid) { - self::checkFormSecurityTokenRedirectOnError('moderation/users/active', 'moderation_users_active', 't'); - // delete user - User::remove($uid); - - $this->systemMessages->addNotice($this->t('User "%s" deleted', $user['username'])); - } else { - $this->systemMessages->addNotice($this->t('You can\'t remove yourself')); - } - - $this->baseUrl->redirect('moderation/users/active'); - break; - case 'block': - self::checkFormSecurityTokenRedirectOnError('moderation/users/active', 'moderation_users_active', 't'); - User::block($uid); - $this->systemMessages->addNotice($this->t('User "%s" blocked', $user['username'])); - $this->baseUrl->redirect('moderation/users/active'); - break; - } $pager = new Pager($this->l10n, $this->args->getQueryString(), 100); $valid_orders = [ @@ -69,9 +48,9 @@ class RatioedPanel extends Active ]; $order = 'last-item'; - $order_direction = '-'; - if (!empty($request['o'])) { - $new_order = $request['o']; + $order_direction = '+'; + if (!empty($_REQUEST['o'])) { + $new_order = $_REQUEST['o']; if ($new_order[0] === '-') { $order_direction = '-'; $new_order = substr($new_order, 1); @@ -97,6 +76,11 @@ class RatioedPanel extends Active $this->t('Comments last 24h'), $this->t('Reactions last 24h'), $this->t('Ratio last 24h'), + $this->t('Replies last month'), + $this->t('Reply likes'), + $this->t('Respondee likes'), + $this->t('OP likes'), + $this->t('Reply guy score'), ]; $field_names = [ 'name', @@ -109,6 +93,11 @@ class RatioedPanel extends Active 'comments', 'reactions', 'ratio', + 'reply_count', + 'reply_likes', + 'reply_respondee_likes', + 'reply_op_likes', + 'reply_guy_score', ]; $th_users = array_map(null, $header_titles, $valid_orders, $field_names); @@ -147,9 +136,130 @@ class RatioedPanel extends Active ]); } + protected function getReplyGuyRow($contact_uid) + { + $like_vid = Verb::getID(Activity::LIKE); + $post_vid = Verb::getID(Activity::POST); + + /* + * This is a complicated query. + * + * The innermost select retrieves a chain of four posts: an + * original post, a target comment (possibly deep down in the + * thread), a reply from our user, and a like for that reply. + * If there's no like, we still want to count the reply, so we + * use an outer join. + * + * The second select adds "points" for different kinds of + * likes. The outermost select then counts up these points, + * and the number of distinct replies. + */ + $reply_guy_result = DBA::p(' +SELECT + COUNT(distinct reply_id) AS replies_total, + SUM(like_point) AS like_total, + SUM(target_like_point) AS target_like_total, + SUM(original_like_point) AS original_like_total +FROM ( + SELECT + reply_id, + like_date, + like_date IS NOT NULL AS like_point, + like_author = target_author AS target_like_point, + like_author = original_author AS original_like_point + FROM ( + SELECT + original_post.`uri-id` AS original_id, + original_post.`author-id` AS original_author, + original_post.created AS original_date, + target_post.`uri-id` AS target_id, + target_post.`author-id` AS target_author, + target_post.created AS target_date, + reply_post.`uri-id` AS reply_id, + reply_post.`author-id` AS reply_author, + reply_post.created AS reply_date, + like_post.`uri-id` AS like_id, + like_post.`author-id` AS like_author, + like_post.created AS like_date + FROM + post AS original_post + JOIN + post AS target_post + ON + original_post.`uri-id` = target_post.`parent-uri-id` + JOIN + post AS reply_post + ON + target_post.`uri-id` = reply_post.`thr-parent-id` AND + reply_post.`author-id` = ? AND + reply_post.`author-id` != target_post.`author-id` AND + reply_post.`author-id` != original_post.`author-id` AND + reply_post.`uri-id` != reply_post.`thr-parent-id` AND + reply_post.vid = ? AND + reply_post.created > CURDATE() - INTERVAL 1 MONTH + LEFT OUTER JOIN + post AS like_post + ON + reply_post.`uri-id` = like_post.`thr-parent-id` AND + like_post.vid = ? AND + like_post.`author-id` != reply_post.`author-id` + ) AS post_meta +) AS reply_counts +', $contact_uid, $post_vid, $like_vid); + return $reply_guy_result; + } + + // https://stackoverflow.com/a/48283297/235936 + protected function sigFig($value, $digits) + { + if ($value == 0) { + $decimalPlaces = $digits - 1; + } elseif ($value < 0) { + $decimalPlaces = $digits - floor(log10($value * -1)) - 1; + } else { + $decimalPlaces = $digits - floor(log10($value)) - 1; + } + + $answer = ($decimalPlaces > 0) ? + number_format($value, $decimalPlaces) : round($value, $decimalPlaces); + return $answer; + } + + protected function fillReplyGuyData(&$user) + { + $reply_guy_result = $this->getReplyGuyRow($user['user_contact_uid']); + if (DBA::isResult($reply_guy_result)) { + $reply_guy_result_row = DBA::fetch($reply_guy_result); + $user['reply_count'] = (int) $reply_guy_result_row['replies_total'] ?? 0; + $user['reply_likes'] = (int) $reply_guy_result_row['like_total'] ?? 0; + $user['reply_respondee_likes'] = (int) $reply_guy_result_row['target_like_total'] ?? 0; + $user['reply_op_likes'] = (int) $reply_guy_result_row['original_like_total'] ?? 0; + + $denominator = $user['reply_likes'] + $user['reply_respondee_likes'] + $user['reply_op_likes']; + if ($user['reply_count'] === 0) { + $user['reply_guy'] = false; + $user['reply_guy_score'] = 0; + } elseif ($denominator == 0) { + $user['reply_guy'] = true; + $user['reply_guy_score'] = '∞'; + } else { + $reply_guy_score = $user['reply_count'] / $denominator; + $user['reply_guy'] = $reply_guy_score >= 1.0; + $user['reply_guy_score'] = $this->sigFig($reply_guy_score, 2); + } + } else { + $user['reply_count'] = "error"; + $user['reply_likes'] = "error"; + $user['reply_respondee_likes'] = "error"; + $user['reply_op_likes'] = "error"; + $user['reply_guy'] = false; + $user['reply_guy_score'] = 0; + } + } + protected function setupUserCallback(): \Closure { - Logger::debug("ratioed: setupUserCallback"); + DI::logger()->debug("ratioed: setupUserCallback"); $parentCallback = parent::setupUserCallback(); return function ($user) use ($parentCallback) { $blocked_count = DBA::count('user-contact', ['uid' => $user['uid'], 'is-blocked' => 1]); @@ -159,9 +269,8 @@ class RatioedPanel extends Active if (DBA::isResult($self_contact_result)) { $self_contact_result_row = DBA::fetch($self_contact_result); $user['user_contact_uid'] = $self_contact_result_row['user_contact_uid']; - } - else { - $user['user_contact_uid'] = NULL; + } else { + $user['user_contact_uid'] = null; } if ($user['user_contact_uid']) { @@ -173,34 +282,34 @@ class RatioedPanel extends Active if ($user['reactions'] > 0) { $user['ratio'] = number_format($user['comments'] / $user['reactions'], 1, '.', ''); $user['ratioed'] = (float)($user['ratio']) >= 2.0; - } - else { + } else { + $user['reactions'] = 0; if ($user['comments'] == 0) { - $user['ratio'] = '0'; + $user['comments'] = 0; + $user['ratio'] = 0; $user['ratioed'] = false; - } - else { + } else { $user['ratio'] = '∞'; $user['ratioed'] = false; } } - } - else { + } else { $user['comments'] = 'error'; $user['reactions'] = 'error'; $user['ratio'] = 'error'; $user['ratioed'] = false; } - } - else { + } else { $user['comments'] = 'error'; $user['reactions'] = 'error'; $user['ratio'] = 'error'; $user['ratioed'] = false; } + $this->fillReplyGuyData($user); + $user = $parentCallback($user); - Logger::debug("ratioed: setupUserCallback", [ + DI::logger()->debug("ratioed: setupUserCallback", [ 'uid' => $user['uid'], 'blocked_by' => $user['blocked_by'], 'comments' => $user['comments'], diff --git a/ratioed/ratioed.php b/ratioed/ratioed.php index 8ae0d48c..5cc6d539 100644 --- a/ratioed/ratioed.php +++ b/ratioed/ratioed.php @@ -2,13 +2,12 @@ /** * Name: Ratioed * Description: Additional moderation user table with statistics about user behaviour - * Version: 0.1 + * Version: 0.3 * Author: Matthew Exon */ use Friendica\Addon\ratioed\RatioedPanel; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\DI; /** @@ -18,7 +17,7 @@ function ratioed_install() { Hook::register('moderation_users_tabs', 'addon/ratioed/ratioed.php', 'ratioed_users_tabs'); - Logger::info("ratioed: installed"); + DI::logger()->info("ratioed: installed"); } /** @@ -34,7 +33,7 @@ function ratioed_module() {} * @param array $arr Parameters, including "tabs" which is the list to modify, and "selectedTab", which is the currently selected tab ID */ function ratioed_users_tabs(array &$arr) { - Logger::debug("ratioed: users tabs"); + DI::logger()->debug("ratioed: users tabs"); array_push($arr['tabs'], [ 'label' => DI::l10n()->t('Behaviour'), @@ -50,7 +49,7 @@ function ratioed_users_tabs(array &$arr) { * @brief Displays the ratioed tab in the moderation panel */ function ratioed_content() { - Logger::debug("ratioed: content"); + DI::logger()->debug("ratioed: content"); $ratioed = DI::getDice()->create(RatioedPanel::class, [$_SERVER]); $httpException = DI::getDice()->create(Friendica\Module\Special\HTTPException::class); diff --git a/ratioed/templates/help.tpl b/ratioed/templates/help.tpl index fee47e34..0d012ca7 100644 --- a/ratioed/templates/help.tpl +++ b/ratioed/templates/help.tpl @@ -2,7 +2,7 @@

Ratioed Plugin Help

- This plugin provides administrators with additional statistics about + This plugin provides moderators with additional statistics about the behaviour of users. These may be useful as early warning signs that warrant more carefully watching the behaviour of a user. They are not suitable as a trigger for instantly blocking, @@ -28,7 +28,7 @@

This plugin allows viewing of an actual ratio, calculated over the last 24 hours. This is a useful timeframe for sudden dogpiling - events that administrators might not otherwise notice. The plugin + events that moderators might not otherwise notice. The plugin also calculates other statistics.

Explanation of Statistics

@@ -68,10 +68,63 @@ 24h". It is intended to approximate the traditional ratio as understood on Twitter.

+

Replies last month

+

+ This is the number of times the user posted a reply to someone + else, on a thread the user did not start, any time in the last + month. +

+

Reply likes

+

+ This is the number of likes received by the user on their + replies to other people's posts in the last month. Replies that + receive likes can be assumed to be more of a valuable + contribution than replies that do not. +

+

Respondee likes

+

+ The number of times in the last month the user replied to + someone else's comment and that person then liked the reply. + Likes to replies are not necessarily a positive thing, but if + the person you're replying to approves the reply, that's a very + good sign. Of course it's also common in a debate for neither + side to like the other side's comments without that indicating + an unhealthy interaction, so interpret this statistic cautiously. +

+

OP likes

+

+ The number of times in the last month the user replied on a + thread and the original poster that started the thread liked the + reply. While there is no formal concept of "ownership" of a + thread, conventionally the original poster is assumed to have + started the thread for a reason, and making replies that do not + fulfil that purpose are bad etiquette. Getting approval from + the original poster therefore is a good sign that the user is + posting replies that are wanted. +

+

Reply guy score

+

+ A "reply + guy" is a common Internet phenomenon of people + (disproportionately male) posting unwanted comments on other + (disproportionately female) people's threads, derailing the + conversation. This score loosely quantifies this phenomenon, + as the ratio betwen the number of replies and the sum of likes, + respondee likes, and OP likes. This formula gives extra weight + to particularly relevant likes: a reply to a top-level post that + is liked by the original poster scores the maximum of 3 + "points". A score above 1.0 might indicate cause for concern + for moderators. +

+

+ Since this is indicative of long-term behaviour, the score is + calculated over a month instead of 24 hours. +

+

Performance

The statistics are computed from scratch each time the page loads. - It's possible that this might put a heavy load on the database. and + It's possible that this might put a heavy load on the database, and the page may take a long time to load.

Extending

diff --git a/ratioed/templates/ratioed.tpl b/ratioed/templates/ratioed.tpl index 0d81b0d7..2413ed9d 100644 --- a/ratioed/templates/ratioed.tpl +++ b/ratioed/templates/ratioed.tpl @@ -2,26 +2,21 @@
-

{{$title}} - {{$page}} ({{$count}})

-

- {{$h_newuser}} -

+

+ {{$title}} - {{$page}} ({{$count}}) + +

- + {{foreach $th_users as $k=>$th}} - {{if $k < 2 || $order_users == $th.1 || ($k==5 && !in_array($order_users,[$th_users.2.1, $th_users.3.1, $th_users.4.1])) }} + {{if $k < 2 || $order_users == $th.1 || ($k==4 && !in_array($order_users,[$th_users.2.1, $th_users.3.1, $th_users.5.1])) }} {{foreach $users as $u}} - - + + @@ -63,11 +49,7 @@ {{/if}} - {{if $order_users == $th_users.4.1}} - - {{/if}} - - {{if !in_array($order_users,[$th_users.2.1, $th_users.3.1, $th_users.4.1]) }} + {{if $order_users == $th_users.5.1}} @@ -135,30 +121,11 @@ {{/foreach}} - + {{/foreach}}
-
- - -
-
- + {{if $order_users == $th.1}} {{if $order_direction_users == "+"}} ↓ @@ -41,17 +36,8 @@
- {{if $u.is_deletable}} -
- - -
- {{else}} -   - {{/if}} -
{{$u.name}} {{$u.email}}{{$u.login_date}}{{$u.lastitem_date}} - {{if $u.is_deletable}} - - - - - - - {{else}} -   - {{/if}} -
- {{$pager nofilter}}
diff --git a/rendertime/rendertime.php b/rendertime/rendertime.php index 731cf003..4523d911 100644 --- a/rendertime/rendertime.php +++ b/rendertime/rendertime.php @@ -7,7 +7,6 @@ * */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\Core\Renderer; use Friendica\DI; @@ -60,7 +59,7 @@ function rendertime_page_end(string &$o) if (DI::userSession()->isSiteAdmin() && (($_GET['mode'] ?? '') != 'minimal') && !DI::mode()->isMobile() && !DI::mode()->isMobile() && !$ignored) { - $o = $o . '
' . DI::l10n()->t("Database: %s/%s, Network: %s, Rendering: %s, Session: %s, I/O: %s, Other: %s, Total: %s", + $o = $o . '
'; //Add css to header - $css_file = __DIR__ . '/view/' . DI::app()->getCurrentTheme() . '.css'; + $css_file = __DIR__ . '/view/' . DI::appHelper()->getCurrentTheme() . '.css'; if (!file_exists($css_file)) { $css_file = __DIR__ . '/view/default.css'; } @@ -105,7 +104,7 @@ function smileybutton_jot_tool(string &$body) DI::page()->registerStylesheet($css_file); //Get the correct image for the theme - $image = 'addon/smileybutton/view/' . DI::app()->getCurrentTheme() . '.png'; + $image = 'addon/smileybutton/view/' . DI::appHelper()->getCurrentTheme() . '.png'; if (!file_exists($image)) { $image = 'addon/smileybutton/view/default.png'; } diff --git a/smilies_adult/smilies_adult.php b/smilies_adult/smilies_adult.php index e8af21e1..4a80168d 100644 --- a/smilies_adult/smilies_adult.php +++ b/smilies_adult/smilies_adult.php @@ -4,12 +4,11 @@ * Description: Smily icons that could or should not be included in core * Version: 1.0 * Author: Mike Macgirvin - * + * * This is a template for how to extend the "smily" code. - * + * */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\DI; diff --git a/startpage/startpage.php b/startpage/startpage.php index e4d80c0c..558af473 100644 --- a/startpage/startpage.php +++ b/startpage/startpage.php @@ -7,7 +7,6 @@ * */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\Core\Renderer; use Friendica\DI; diff --git a/statusnet/library/codebirdsn.php b/statusnet/library/codebirdsn.php index 9807d97f..bffca163 100644 --- a/statusnet/library/codebirdsn.php +++ b/statusnet/library/codebirdsn.php @@ -976,7 +976,7 @@ class CodebirdSN * @param string $method The method that has been called * @param string $reply The actual reply, JSON-encoded or URL-encoded * - * @return array|object The parsed reply + * @return string|array|object The parsed reply */ protected function _parseApiReply($method, $reply) { diff --git a/statusnet/library/statusnetoauth.php b/statusnet/library/statusnetoauth.php index c32b2b4f..da21be58 100644 --- a/statusnet/library/statusnetoauth.php +++ b/statusnet/library/statusnetoauth.php @@ -12,7 +12,7 @@ require_once __DIR__ . DIRECTORY_SEPARATOR . 'twitteroauth.php'; */ class StatusNetOAuth extends TwitterOAuth { - function get_maxlength() + public function get_maxlength() { $config = $this->get($this->host . 'statusnet/config.json'); if (empty($config)) { @@ -21,27 +21,27 @@ class StatusNetOAuth extends TwitterOAuth return $config->site->textlimit; } - function accessTokenURL() + public function accessTokenURL() { return $this->host . 'oauth/access_token'; } - function authenticateURL() + public function authenticateURL() { return $this->host . 'oauth/authenticate'; } - function authorizeURL() + public function authorizeURL() { return $this->host . 'oauth/authorize'; } - function requestTokenURL() + public function requestTokenURL() { return $this->host . 'oauth/request_token'; } - function __construct($apipath, $consumer_key, $consumer_secret, $oauth_token = NULL, $oauth_token_secret = NULL) + public function __construct($apipath, $consumer_key, $consumer_secret, $oauth_token = NULL, $oauth_token_secret = NULL) { parent::__construct($consumer_key, $consumer_secret, $oauth_token, $oauth_token_secret); $this->host = $apipath; @@ -52,9 +52,9 @@ class StatusNetOAuth extends TwitterOAuth * * Copied here from the TwitterOAuth library and complemented by applying the proxy settings of Friendica * - * @return array|object API results + * @return array|object|mixed API results */ - function http($url, $method, $postfields = NULL) + public function http($url, $method, $postfields = NULL) { $this->http_info = []; $ci = curl_init(); diff --git a/statusnet/library/twitteroauth.php b/statusnet/library/twitteroauth.php index bf413d23..bab66195 100644 --- a/statusnet/library/twitteroauth.php +++ b/statusnet/library/twitteroauth.php @@ -45,11 +45,11 @@ class TwitterOAuth public $http_header; /** * Contains the last HTTP request info - * @var string + * @var array */ public $http_info; - /** @var OAuthToken */ + /** @var OAuthToken|null */ private $token; /** @var OAuthConsumer */ private $consumer; @@ -59,27 +59,27 @@ class TwitterOAuth /** * Set API URLS */ - function accessTokenURL() + public function accessTokenURL() { return 'https://api.twitter.com/oauth/access_token'; } - function authenticateURL() + public function authenticateURL() { return 'https://twitter.com/oauth/authenticate'; } - function authorizeURL() + public function authorizeURL() { return 'https://twitter.com/oauth/authorize'; } - function requestTokenURL() + public function requestTokenURL() { return 'https://api.twitter.com/oauth/request_token'; } - function __construct($consumer_key, $consumer_secret, $oauth_token = null, $oauth_token_secret = null) + public function __construct($consumer_key, $consumer_secret, $oauth_token = null, $oauth_token_secret = null) { $this->sha1_method = new OAuthSignatureMethod_HMAC_SHA1(); $this->consumer = new OAuthConsumer($consumer_key, $consumer_secret); @@ -96,7 +96,7 @@ class TwitterOAuth * @param callable $oauth_callback * @return array */ - function getRequestToken($oauth_callback = null) + public function getRequestToken($oauth_callback = null) { $parameters = []; if (!empty($oauth_callback)) { @@ -114,7 +114,7 @@ class TwitterOAuth * * @return string */ - function getAuthorizeURL($token, $sign_in_with_twitter = TRUE) + public function getAuthorizeURL($token, $sign_in_with_twitter = TRUE) { if (is_array($token)) { $token = $token['oauth_token']; @@ -137,7 +137,7 @@ class TwitterOAuth * "user_id" => "9436992", * "screen_name" => "abraham") */ - function getAccessToken($oauth_verifier = FALSE) + public function getAccessToken($oauth_verifier = FALSE) { $parameters = []; if (!empty($oauth_verifier)) { @@ -162,7 +162,7 @@ class TwitterOAuth * "screen_name" => "abraham", * "x_auth_expires" => "0") */ - function getXAuthToken($username, $password) + public function getXAuthToken($username, $password) { $parameters = []; $parameters['x_auth_username'] = $username; @@ -182,7 +182,7 @@ class TwitterOAuth * @param array $parameters * @return mixed|string */ - function get($url, $parameters = []) + public function get($url, $parameters = []) { $response = $this->oAuthRequest($url, 'GET', $parameters); if ($this->format === 'json' && $this->decode_json) { @@ -199,7 +199,7 @@ class TwitterOAuth * @param array $parameters * @return mixed|string */ - function post($url, $parameters = []) + public function post($url, $parameters = []) { $response = $this->oAuthRequest($url, 'POST', $parameters); if ($this->format === 'json' && $this->decode_json) { @@ -216,7 +216,7 @@ class TwitterOAuth * @param array $parameters * @return mixed|string */ - function delete($url, $parameters = []) + public function delete($url, $parameters = []) { $response = $this->oAuthRequest($url, 'DELETE', $parameters); if ($this->format === 'json' && $this->decode_json) { @@ -234,7 +234,7 @@ class TwitterOAuth * @param array $parameters * @return mixed|string */ - function oAuthRequest($url, $method, $parameters) + public function oAuthRequest($url, $method, $parameters) { if (strrpos($url, 'https://') !== 0 && strrpos($url, 'http://') !== 0) { $url = "{$this->host}{$url}.{$this->format}"; @@ -258,9 +258,9 @@ class TwitterOAuth * @param string $url * @param string $method * @param mixed $postfields - * @return string API results + * @return string|bool|mixed API results */ - function http($url, $method, $postfields = null) + public function http($url, $method, $postfields = null) { $this->http_info = []; $ci = curl_init(); @@ -305,7 +305,7 @@ class TwitterOAuth * @param string $header * @return int */ - function getHeader($ch, $header) + public function getHeader($ch, $header) { $i = strpos($header, ':'); if (!empty($i)) { diff --git a/statusnet/statusnet.php b/statusnet/statusnet.php index 48f9c254..8663aaea 100644 --- a/statusnet/statusnet.php +++ b/statusnet/statusnet.php @@ -38,10 +38,8 @@ define('STATUSNET_DEFAULT_POLL_INTERVAL', 5); // given in minutes require_once __DIR__ . DIRECTORY_SEPARATOR . 'library' . DIRECTORY_SEPARATOR . 'statusnetoauth.php'; use CodebirdSN\CodebirdSN; -use Friendica\App; use Friendica\Content\Text\Plaintext; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\Core\System; use Friendica\Database\DBA; @@ -59,7 +57,7 @@ function statusnet_install() Hook::register('hook_fork', 'addon/statusnet/statusnet.php', 'statusnet_hook_fork'); Hook::register('post_local', 'addon/statusnet/statusnet.php', 'statusnet_post_local'); Hook::register('jot_networks', 'addon/statusnet/statusnet.php', 'statusnet_jot_nets'); - Logger::notice('installed GNU Social'); + DI::logger()->notice('installed GNU Social'); } function statusnet_jot_nets(array &$jotnets_fields) @@ -356,7 +354,7 @@ function statusnet_post_hook(array &$b) return; } - Logger::notice('GNU Socialpost invoked'); + DI::logger()->notice('GNU Socialpost invoked'); DI::pConfig()->load($b['uid'], 'statusnet'); @@ -408,7 +406,7 @@ function statusnet_post_hook(array &$b) $cb->setToken($otoken, $osecret); $result = $cb->statuses_update($postdata); //$result = $dent->post('statuses/update', $postdata); - Logger::info('statusnet_post send, result: ' . print_r($result, true) . + DI::logger()->info('statusnet_post send, result: ' . print_r($result, true) . "\nmessage: " . $msg . "\nOriginal post: " . print_r($b, true) . "\nPost Data: " . print_r($postdata, true)); if (!empty($result->source)) { @@ -416,9 +414,9 @@ function statusnet_post_hook(array &$b) } if (!empty($result->error)) { - Logger::notice('Send to GNU Social failed: "' . $result->error . '"'); + DI::logger()->notice('Send to GNU Social failed: "' . $result->error . '"'); } elseif ($iscomment) { - Logger::notice('statusnet_post: Update extid ' . $result->id . ' for post id ' . $b['id']); + DI::logger()->notice('statusnet_post: Update extid ' . $result->id . ' for post id ' . $b['id']); Item::update(['extid' => $hostname . '::' . $result->id, 'body' => $result->text], ['id' => $b['id']]); } } diff --git a/tesseract/tesseract.php b/tesseract/tesseract.php index 4c630dbb..a07c690c 100644 --- a/tesseract/tesseract.php +++ b/tesseract/tesseract.php @@ -7,8 +7,8 @@ */ use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\System; +use Friendica\DI; use thiagoalessio\TesseractOCR\TesseractOCR; require_once __DIR__ . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'autoload.php'; @@ -17,7 +17,7 @@ function tesseract_install() { Hook::register('ocr-detection', __FILE__, 'tesseract_ocr_detection'); - Logger::notice('installed tesseract'); + DI::logger()->notice('installed tesseract'); } function tesseract_ocr_detection(&$media) @@ -33,6 +33,6 @@ function tesseract_ocr_detection(&$media) $ocr->imageData($media['img_str'], strlen($media['img_str'])); $media['description'] = $ocr->run(); } catch (\Throwable $th) { - Logger::info('Error calling TesseractOCR', ['message' => $th->getMessage()]); + DI::logger()->info('Error calling TesseractOCR', ['message' => $th->getMessage()]); } } diff --git a/testdrive/testdrive.php b/testdrive/testdrive.php index 55645284..90fb5918 100644 --- a/testdrive/testdrive.php +++ b/testdrive/testdrive.php @@ -6,7 +6,6 @@ * Author: Mike Macgirvin */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\Core\Search; use Friendica\Database\DBA; @@ -27,7 +26,7 @@ function testdrive_install() function testdrive_load_config(ConfigFileManager $loader) { - DI::app()->getConfigCache()->load($loader->loadAddonConfig('testdrive'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); + DI::appHelper()->getConfigCache()->load($loader->loadAddonConfig('testdrive'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); } function testdrive_globaldir_update(array &$b) diff --git a/tumblr/tumblr.php b/tumblr/tumblr.php index 1e9f5c7f..9e691bf2 100644 --- a/tumblr/tumblr.php +++ b/tumblr/tumblr.php @@ -14,7 +14,6 @@ use Friendica\Content\Text\NPF; use Friendica\Core\Cache\Enum\Duration; use Friendica\Core\Config\Util\ConfigFileManager; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Protocol; use Friendica\Core\Renderer; use Friendica\Core\System; @@ -60,12 +59,12 @@ function tumblr_install() Hook::register('check_item_notification', __FILE__, 'tumblr_check_item_notification'); Hook::register('probe_detect', __FILE__, 'tumblr_probe_detect'); Hook::register('item_by_link', __FILE__, 'tumblr_item_by_link'); - Logger::info('installed tumblr'); + DI::logger()->info('installed tumblr'); } function tumblr_load_config(ConfigFileManager $loader) { - DI::app()->getConfigCache()->load($loader->loadAddonConfig('tumblr'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); + DI::appHelper()->getConfigCache()->load($loader->loadAddonConfig('tumblr'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); } function tumblr_check_item_notification(array &$notification_data) @@ -121,16 +120,16 @@ function tumblr_item_by_link(array &$hookData) return; } - Logger::debug('Found tumblr post', ['url' => $hookData['uri'], 'blog' => $matches[1], 'id' => $matches[2]]); + DI::logger()->debug('Found tumblr post', ['url' => $hookData['uri'], 'blog' => $matches[1], 'id' => $matches[2]]); $parameters = ['id' => $matches[2], 'reblog_info' => false, 'notes_info' => false, 'npf' => false]; $result = tumblr_get($hookData['uid'], 'blog/' . $matches[1] . '/posts', $parameters); if ($result->meta->status > 399) { - Logger::notice('Error fetching status', ['meta' => $result->meta, 'response' => $result->response, 'errors' => $result->errors, 'blog' => $matches[1], 'id' => $matches[2]]); + DI::logger()->notice('Error fetching status', ['meta' => $result->meta, 'response' => $result->response, 'errors' => $result->errors, 'blog' => $matches[1], 'id' => $matches[2]]); return []; } - Logger::debug('Got post', ['blog' => $matches[1], 'id' => $matches[2], 'result' => $result->response->posts]); + DI::logger()->debug('Got post', ['blog' => $matches[1], 'id' => $matches[2], 'result' => $result->response->posts]); if (!empty($result->response->posts)) { $hookData['item_id'] = tumblr_process_post($result->response->posts[0], $hookData['uid'], Item::PR_FETCHED); Item::incrementInbound(Protocol::TUMBLR); @@ -159,20 +158,20 @@ function tumblr_follow(array &$hook_data) return; } - Logger::debug('Check if contact is Tumblr', ['url' => $hook_data['url']]); + DI::logger()->debug('Check if contact is Tumblr', ['url' => $hook_data['url']]); $fields = tumblr_get_contact_by_url($hook_data['url'], $uid); if (empty($fields)) { - Logger::debug('Contact is not a Tumblr contact', ['url' => $hook_data['url']]); + DI::logger()->debug('Contact is not a Tumblr contact', ['url' => $hook_data['url']]); return; } $result = tumblr_post($uid, 'user/follow', ['url' => $fields['url']]); if ($result->meta->status <= 399) { $hook_data['contact'] = $fields; - Logger::debug('Successfully start following', ['url' => $fields['url']]); + DI::logger()->debug('Successfully start following', ['url' => $fields['url']]); } else { - Logger::notice('Following failed', ['meta' => $result->meta, 'response' => $result->response, 'errors' => $result->errors, 'url' => $fields['url']]); + DI::logger()->notice('Following failed', ['meta' => $result->meta, 'response' => $result->response, 'errors' => $result->errors, 'url' => $fields['url']]); } } @@ -392,12 +391,17 @@ function tumblr_settings_post(array &$b) DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'tumblr', 'import', intval($_POST['tumblr_import'])); $max_tags = DI::config()->get('tumblr', 'max_tags') ?? TUMBLR_DEFAULT_MAXIMUM_TAGS; - $tags = []; - foreach (explode(',', $_POST['tags']) as $tag) { - if (count($tags) < $max_tags) { - $tags[] = trim($tag, ' #'); - } - } + + $tags = array_slice( + array_filter( + array_map( + function($tag) { return trim($tag, ' #');}, + explode(',', $_POST['tags']) ?: [] + ) + ), + 0, + $max_tags, + ); DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'tumblr', 'tags', $tags); } @@ -415,11 +419,11 @@ function tumblr_cron() if ($last) { $next = $last + ($poll_interval * 60); if ($next > time()) { - Logger::notice('poll interval not reached'); + DI::logger()->notice('poll interval not reached'); return; } } - Logger::notice('cron_start'); + DI::logger()->notice('cron_start'); $abandon_days = intval(DI::config()->get('system', 'account_abandon_days')); if ($abandon_days < 1) { @@ -432,30 +436,30 @@ function tumblr_cron() foreach ($pconfigs as $pconfig) { if ($abandon_days != 0) { if (!DBA::exists('user', ["`uid` = ? AND `login_date` >= ?", $pconfig['uid'], $abandon_limit])) { - Logger::notice('abandoned account: timeline from user will not be imported', ['user' => $pconfig['uid']]); + DI::logger()->notice('abandoned account: timeline from user will not be imported', ['user' => $pconfig['uid']]); continue; } } - Logger::notice('importing timeline - start', ['user' => $pconfig['uid']]); + DI::logger()->notice('importing timeline - start', ['user' => $pconfig['uid']]); tumblr_fetch_dashboard($pconfig['uid'], $last); tumblr_fetch_tags($pconfig['uid'], $last); - Logger::notice('importing timeline - done', ['user' => $pconfig['uid']]); + DI::logger()->notice('importing timeline - done', ['user' => $pconfig['uid']]); } $last_clean = DI::keyValue()->get('tumblr_last_clean'); if (empty($last_clean) || ($last_clean + 86400 < time())) { - Logger::notice('Start contact cleanup'); + DI::logger()->notice('Start contact cleanup'); $contacts = DBA::select('account-user-view', ['id', 'pid'], ["`network` = ? AND `uid` != ? AND `rel` = ?", Protocol::TUMBLR, 0, Contact::NOTHING]); while ($contact = DBA::fetch($contacts)) { Worker::add(Worker::PRIORITY_LOW, 'MergeContact', $contact['pid'], $contact['id'], 0); } DBA::close($contacts); DI::keyValue()->set('tumblr_last_clean', time()); - Logger::notice('Contact cleanup done'); + DI::logger()->notice('Contact cleanup done'); } - Logger::notice('cron_end'); + DI::logger()->notice('cron_end'); DI::keyValue()->set('tumblr_last_poll', time()); } @@ -478,7 +482,7 @@ function tumblr_hook_fork(array &$b) if (DI::pConfig()->get($post['uid'], 'tumblr', 'import')) { // Don't post if it isn't a reply to a tumblr post if (($post['gravity'] != Item::GRAVITY_PARENT) && !Post::exists(['id' => $post['parent'], 'network' => Protocol::TUMBLR])) { - Logger::notice('No tumblr parent found', ['item' => $post['id']]); + DI::logger()->notice('No tumblr parent found', ['item' => $post['id']]); $b['execute'] = false; return; } @@ -525,20 +529,20 @@ function tumblr_send(array &$b) } if ($b['gravity'] != Item::GRAVITY_PARENT) { - Logger::debug('Got comment', ['item' => $b]); + DI::logger()->debug('Got comment', ['item' => $b]); $parent = tumblr_get_post_from_uri($b['thr-parent']); if (empty($parent)) { - Logger::notice('No tumblr post', ['thr-parent' => $b['thr-parent']]); + DI::logger()->notice('No tumblr post', ['thr-parent' => $b['thr-parent']]); return; } - Logger::debug('Parent found', ['parent' => $parent]); + DI::logger()->debug('Parent found', ['parent' => $parent]); $page = tumblr_get_page($b['uid']); if ($b['gravity'] == Item::GRAVITY_COMMENT) { - Logger::notice('Commenting is not supported (yet)'); + DI::logger()->notice('Commenting is not supported (yet)'); } else { if (($b['verb'] == Activity::LIKE) && !$b['deleted']) { $params = ['id' => $parent['id'], 'reblog_key' => $parent['reblog_key']]; @@ -562,12 +566,12 @@ function tumblr_send(array &$b) } if ($result->meta->status < 400) { - Logger::info('Successfully performed activity', ['verb' => $b['verb'], 'deleted' => $b['deleted'], 'meta' => $result->meta, 'response' => $result->response]); + DI::logger()->info('Successfully performed activity', ['verb' => $b['verb'], 'deleted' => $b['deleted'], 'meta' => $result->meta, 'response' => $result->response]); if (!$b['deleted'] && !empty($result->response->id_string)) { - Item::update(['extid' => 'tumblr::' . $result->response->id_string], ['id' => $b['id']]); + Item::update(['extid' => 'tumblr::' . $result->response->id_string], ['guid' => $b['guid']]); } } else { - Logger::notice('Error while performing activity', ['verb' => $b['verb'], 'deleted' => $b['deleted'], 'meta' => $result->meta, 'response' => $result->response, 'errors' => $result->errors, 'params' => $params]); + DI::logger()->notice('Error while performing activity', ['verb' => $b['verb'], 'deleted' => $b['deleted'], 'meta' => $result->meta, 'response' => $result->response, 'errors' => $result->errors, 'params' => $params]); } } return; @@ -665,9 +669,9 @@ function tumblr_send_legacy(array $b) $result = tumblr_post($b['uid'], 'blog/' . $page . '/post', $params); if ($result->meta->status < 400) { - Logger::info('Success (legacy)', ['blog' => $page, 'meta' => $result->meta, 'response' => $result->response]); + DI::logger()->info('Success (legacy)', ['blog' => $page, 'meta' => $result->meta, 'response' => $result->response]); } else { - Logger::notice('Error posting blog (legacy)', ['blog' => $page, 'meta' => $result->meta, 'response' => $result->response, 'errors' => $result->errors, 'params' => $params]); + DI::logger()->notice('Error posting blog (legacy)', ['blog' => $page, 'meta' => $result->meta, 'response' => $result->response, 'errors' => $result->errors, 'params' => $params]); } } @@ -676,7 +680,7 @@ function tumblr_send_npf(array $post): bool $page = tumblr_get_page($post['uid']); if (empty($page)) { - Logger::notice('Missing page, post will not be send to Tumblr.', ['uid' => $post['uid'], 'page' => $page, 'id' => $post['id']]); + DI::logger()->notice('Missing page, post will not be send to Tumblr.', ['uid' => $post['uid'], 'page' => $page, 'id' => $post['id']]); // "true" is returned, since the legacy function will fail as well. return true; } @@ -707,10 +711,10 @@ function tumblr_send_npf(array $post): bool $result = tumblr_post($post['uid'], 'blog/' . $page . '/posts', $params); if ($result->meta->status < 400) { - Logger::info('Success (NPF)', ['blog' => $page, 'meta' => $result->meta, 'response' => $result->response]); + DI::logger()->info('Success (NPF)', ['blog' => $page, 'meta' => $result->meta, 'response' => $result->response]); return true; } else { - Logger::notice('Error posting blog (NPF)', ['blog' => $page, 'meta' => $result->meta, 'response' => $result->response, 'errors' => $result->errors, 'params' => $params]); + DI::logger()->notice('Error posting blog (NPF)', ['blog' => $page, 'meta' => $result->meta, 'response' => $result->response, 'errors' => $result->errors, 'params' => $params]); return false; } } @@ -743,14 +747,25 @@ function tumblr_fetch_tags(int $uid, int $last_poll) } foreach (DI::pConfig()->get($uid, 'tumblr', 'tags') ?? [] as $tag) { + // Tumblr will return an error for queries on empty tag + if (!$tag) { + continue; + } + $data = tumblr_get($uid, 'tagged', ['tag' => $tag]); + + if (!is_array($data->response)) { + DI::logger()->warning('Unexpected Tumblr response format', ['uid' => $uid, 'url' => 'tagged', 'parameters' => ['tag' => $tag], 'data' => $data]); + continue; + } + foreach (array_reverse($data->response) as $post) { $id = tumblr_process_post($post, $uid, Item::PR_TAG, $last_poll); if (!empty($id)) { - Logger::debug('Tag post imported', ['tag' => $tag, 'id' => $id]); + DI::logger()->debug('Tag post imported', ['tag' => $tag, 'id' => $id]); $post = Post::selectFirst(['uri-id'], ['id' => $id]); $stored = Post\Category::storeFileByURIId($post['uri-id'], $uid, Post\Category::SUBCRIPTION, $tag); - Logger::debug('Stored tag subscription for user', ['uri-id' => $post['uri-id'], 'uid' => $uid, 'tag' => $tag, 'stored' => $stored]); + DI::logger()->debug('Stored tag subscription for user', ['uri-id' => $post['uri-id'], 'uid' => $uid, 'tag' => $tag, 'stored' => $stored]); Item::incrementInbound(Protocol::TUMBLR); } } @@ -775,8 +790,8 @@ function tumblr_fetch_dashboard(int $uid, int $last_poll) $dashboard = tumblr_get($uid, 'user/dashboard', $parameters); if ($dashboard->meta->status > 399) { - Logger::notice('Error fetching dashboard', ['meta' => $dashboard->meta, 'response' => $dashboard->response, 'errors' => $dashboard->errors]); - return []; + DI::logger()->notice('Error fetching dashboard', ['meta' => $dashboard->meta, 'response' => $dashboard->response, 'errors' => $dashboard->errors]); + return; } if (empty($dashboard->response->posts)) { @@ -788,7 +803,7 @@ function tumblr_fetch_dashboard(int $uid, int $last_poll) $last = $post->id; } - Logger::debug('Importing post', ['uid' => $uid, 'created' => date(DateTimeFormat::MYSQL, $post->timestamp), 'id' => $post->id_string]); + DI::logger()->debug('Importing post', ['uid' => $uid, 'created' => date(DateTimeFormat::MYSQL, $post->timestamp), 'id' => $post->id_string]); tumblr_process_post($post, $uid, Item::PR_NONE, $last_poll); Item::incrementInbound(Protocol::TUMBLR); @@ -1063,7 +1078,7 @@ function tumblr_get_type_replacement(array $data, string $plink): string } default: - Logger::notice('Unknown type', ['type' => $data['type'], 'data' => $data, 'plink' => $plink]); + DI::logger()->notice('Unknown type', ['type' => $data['type'], 'data' => $data, 'plink' => $plink]); $body = ''; } @@ -1118,9 +1133,9 @@ function tumblr_get_contact(stdClass $blog, int $uid): array $cid = $contact['id']; Contact::update($fields, ['id' => $cid], true); } - Logger::debug('Get user contact', ['id' => $cid, 'uid' => $uid, 'update' => $update]); + DI::logger()->debug('Get user contact', ['id' => $cid, 'uid' => $uid, 'update' => $update]); } else { - Logger::debug('Get public contact', ['id' => $cid, 'uid' => $uid, 'update' => $update]); + DI::logger()->debug('Get public contact', ['id' => $cid, 'uid' => $uid, 'update' => $update]); } if (!empty($avatar)) { @@ -1156,13 +1171,13 @@ function tumblr_get_contact_fields(stdClass $blog, int $uid, bool $update): arra ]; if (!$update) { - Logger::debug('Got contact fields', ['uid' => $uid, 'url' => $fields['url']]); + DI::logger()->debug('Got contact fields', ['uid' => $uid, 'url' => $fields['url']]); return $fields; } $info = tumblr_get($uid, 'blog/' . $blog->uuid . '/info'); if ($info->meta->status > 399) { - Logger::notice('Error fetching blog info', ['meta' => $info->meta, 'response' => $info->response, 'errors' => $info->errors]); + DI::logger()->notice('Error fetching blog info', ['meta' => $info->meta, 'response' => $info->response, 'errors' => $info->errors]); return $fields; } Item::incrementInbound(Protocol::TUMBLR); @@ -1184,7 +1199,7 @@ function tumblr_get_contact_fields(stdClass $blog, int $uid, bool $update): arra $fields['header'] = $info->response->blog->theme->header_image_focused; - Logger::debug('Got updated contact fields', ['uid' => $uid, 'url' => $fields['url']]); + DI::logger()->debug('Got updated contact fields', ['uid' => $uid, 'url' => $fields['url']]); return $fields; } @@ -1226,7 +1241,7 @@ function tumblr_get_blogs(int $uid): array { $userinfo = tumblr_get($uid, 'user/info'); if ($userinfo->meta->status > 399) { - Logger::notice('Error fetching blogs', ['meta' => $userinfo->meta, 'response' => $userinfo->response, 'errors' => $userinfo->errors]); + DI::logger()->notice('Error fetching blogs', ['meta' => $userinfo->meta, 'response' => $userinfo->response, 'errors' => $userinfo->errors]); return []; } @@ -1282,15 +1297,15 @@ function tumblr_get_contact_by_url(string $url, int $uid): ?array return null; } - Logger::debug('Update Tumblr blog data', ['url' => $url, 'blog' => $blog, 'uid' => $uid]); + DI::logger()->debug('Update Tumblr blog data', ['url' => $url, 'blog' => $blog, 'uid' => $uid]); $info = tumblr_get($uid, 'blog/' . $blog . '/info'); if ($info->meta->status > 399) { - Logger::notice('Error fetching blog info', ['meta' => $info->meta, 'response' => $info->response, 'errors' => $info->errors, 'blog' => $blog, 'uid' => $uid]); + DI::logger()->notice('Error fetching blog info', ['meta' => $info->meta, 'response' => $info->response, 'errors' => $info->errors, 'blog' => $blog, 'uid' => $uid]); return null; } - Logger::debug('Got data', ['blog' => $blog, 'meta' => $info->meta]); + DI::logger()->debug('Got data', ['blog' => $blog, 'meta' => $info->meta]); Item::incrementInbound(Protocol::TUMBLR); $baseurl = 'https://tumblr.com'; @@ -1419,7 +1434,7 @@ function tumblr_get_token(int $uid, string $code = ''): string $refresh_token = DI::pConfig()->get($uid, 'tumblr', 'refresh_token'); if (empty($code) && !empty($access_token) && ($expires_at > (time()))) { - Logger::debug('Got token', ['uid' => $uid, 'expires_at' => date('c', $expires_at)]); + DI::logger()->debug('Got token', ['uid' => $uid, 'expires_at' => date('c', $expires_at)]); return $access_token; } @@ -1431,11 +1446,11 @@ function tumblr_get_token(int $uid, string $code = ''): string if (empty($refresh_token) && empty($code)) { $result = tumblr_exchange_token($uid); if (empty($result->refresh_token)) { - Logger::info('Invalid result while exchanging token', ['uid' => $uid]); + DI::logger()->info('Invalid result while exchanging token', ['uid' => $uid]); return ''; } $expires_at = time() + $result->expires_in; - Logger::debug('Updated token from OAuth1 to OAuth2', ['uid' => $uid, 'expires_at' => date('c', $expires_at)]); + DI::logger()->debug('Updated token from OAuth1 to OAuth2', ['uid' => $uid, 'expires_at' => date('c', $expires_at)]); } else { if (!empty($code)) { $parameters['code'] = $code; @@ -1447,18 +1462,18 @@ function tumblr_get_token(int $uid, string $code = ''): string $curlResult = DI::httpClient()->post('https://api.tumblr.com/v2/oauth2/token', $parameters); if (!$curlResult->isSuccess()) { - Logger::info('Error fetching token', ['uid' => $uid, 'code' => $code, 'result' => $curlResult->getBodyString(), 'parameters' => $parameters]); + DI::logger()->info('Error fetching token', ['uid' => $uid, 'code' => $code, 'result' => $curlResult->getBodyString(), 'parameters' => $parameters]); return ''; } $result = json_decode($curlResult->getBodyString()); if (empty($result)) { - Logger::info('Invalid result when updating token', ['uid' => $uid]); + DI::logger()->info('Invalid result when updating token', ['uid' => $uid]); return ''; } $expires_at = time() + $result->expires_in; - Logger::debug('Renewed token', ['uid' => $uid, 'expires_at' => date('c', $expires_at)]); + DI::logger()->debug('Renewed token', ['uid' => $uid, 'expires_at' => date('c', $expires_at)]); } DI::pConfig()->set($uid, 'tumblr', 'access_token', $result->access_token); @@ -1502,7 +1517,7 @@ function tumblr_exchange_token(int $uid): stdClass $response = $client->post('oauth2/exchange', ['auth' => 'oauth']); return json_decode($response->getBody()->getContents()); } catch (RequestException $exception) { - Logger::notice('Exchange failed', ['code' => $exception->getCode(), 'message' => $exception->getMessage()]); + DI::logger()->notice('Exchange failed', ['code' => $exception->getCode(), 'message' => $exception->getMessage()]); return new stdClass; } } diff --git a/twitter/twitter.php b/twitter/twitter.php index 10f8a2fb..a9654405 100644 --- a/twitter/twitter.php +++ b/twitter/twitter.php @@ -38,7 +38,6 @@ use Friendica\Content\Text\BBCode; use Friendica\Content\Text\Plaintext; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\Core\Worker; use Friendica\DI; @@ -67,7 +66,7 @@ function twitter_install() function twitter_load_config(ConfigFileManager $loader) { - DI::app()->getConfigCache()->load($loader->loadAddonConfig('twitter'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); + DI::appHelper()->getConfigCache()->load($loader->loadAddonConfig('twitter'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); } function twitter_jot_nets(array &$jotnets_fields) @@ -217,7 +216,7 @@ function twitter_post_hook(array &$b) $b['body'] = Post\Media::addAttachmentsToBody($b['uri-id'], DI::contentItem()->addSharedPost($b)); - Logger::notice('twitter post invoked', ['id' => $b['id'], 'guid' => $b['guid']]); + DI::logger()->notice('twitter post invoked', ['id' => $b['id'], 'guid' => $b['guid']]); DI::pConfig()->load($b['uid'], 'twitter'); @@ -227,17 +226,17 @@ function twitter_post_hook(array &$b) $access_secret = DI::pConfig()->get($b['uid'], 'twitter', 'access_secret'); if (empty($api_key) || empty($api_secret) || empty($access_token) || empty($access_secret)) { - Logger::info('Missing keys, secrets or tokens.'); + DI::logger()->info('Missing keys, secrets or tokens.'); return; } $msgarr = Plaintext::getPost($b, 280, true, BBCode::TWITTER); - Logger::debug('Got plaintext', ['id' => $b['id'], 'message' => $msgarr]); + DI::logger()->debug('Got plaintext', ['id' => $b['id'], 'message' => $msgarr]); $media_ids = []; if (!empty($msgarr['images']) || !empty($msgarr['remote_images'])) { - Logger::info('Got images', ['id' => $b['id'], 'images' => $msgarr['images'] ?? []]); + DI::logger()->info('Got images', ['id' => $b['id'], 'images' => $msgarr['images'] ?? []]); $retrial = Worker::getRetrial(); if ($retrial > 4) { @@ -250,7 +249,7 @@ function twitter_post_hook(array &$b) try { $media_ids[] = twitter_upload_image($b['uid'], $image, $retrial); } catch (RequestException $exception) { - Logger::warning('Error while uploading image', ['image' => $image, 'code' => $exception->getCode(), 'message' => $exception->getMessage()]); + DI::logger()->warning('Error while uploading image', ['image' => $image, 'code' => $exception->getCode(), 'message' => $exception->getMessage()]); Worker::defer(); return; } @@ -259,13 +258,13 @@ function twitter_post_hook(array &$b) $in_reply_to_tweet_id = 0; - Logger::debug('Post message', ['id' => $b['id'], 'parts' => count($msgarr['parts'])]); + DI::logger()->debug('Post message', ['id' => $b['id'], 'parts' => count($msgarr['parts'])]); foreach ($msgarr['parts'] as $key => $part) { try { $id = twitter_post_status($b['uid'], $part, $media_ids, $in_reply_to_tweet_id); - Logger::info('twitter_post send', ['part' => $key, 'id' => $b['id'], 'result' => $id]); + DI::logger()->info('twitter_post send', ['part' => $key, 'id' => $b['id'], 'result' => $id]); } catch (RequestException $exception) { - Logger::warning('Error while posting message', ['part' => $key, 'id' => $b['id'], 'code' => $exception->getCode(), 'message' => $exception->getMessage()]); + DI::logger()->warning('Error while posting message', ['part' => $key, 'id' => $b['id'], 'code' => $exception->getCode(), 'message' => $exception->getMessage()]); $status = [ 'code' => $exception->getCode(), 'reason' => $exception->getResponse()->getReasonPhrase(), @@ -319,9 +318,9 @@ function twitter_upload_image(int $uid, array $image, int $retrial) $picturedata = $picture->asString(); $new_size = strlen($picturedata); - Logger::info('Uploading', ['uid' => $uid, 'retrial' => $retrial, 'height' => $new_height, 'width' => $new_width, 'size' => $new_size, 'orig-height' => $height, 'orig-width' => $width, 'orig-size' => $size, 'image' => $image]); + DI::logger()->info('Uploading', ['uid' => $uid, 'retrial' => $retrial, 'height' => $new_height, 'width' => $new_width, 'size' => $new_size, 'orig-height' => $height, 'orig-width' => $width, 'orig-size' => $size, 'image' => $image]); $media = twitter_post($uid, 'https://upload.twitter.com/1.1/media/upload.json', 'form_params', ['media' => base64_encode($picturedata)]); - Logger::info('Uploading done', ['uid' => $uid, 'retrial' => $retrial, 'height' => $new_height, 'width' => $new_width, 'size' => $new_size, 'orig-height' => $height, 'orig-width' => $width, 'orig-size' => $size, 'image' => $image]); + DI::logger()->info('Uploading done', ['uid' => $uid, 'retrial' => $retrial, 'height' => $new_height, 'width' => $new_width, 'size' => $new_size, 'orig-height' => $height, 'orig-width' => $width, 'orig-size' => $size, 'image' => $image]); if (isset($media->media_id_string)) { $media_id = $media->media_id_string; @@ -334,10 +333,10 @@ function twitter_upload_image(int $uid, array $image, int $retrial) ] ]; $ret = twitter_post($uid, 'https://upload.twitter.com/1.1/media/metadata/create.json', 'json', $data); - Logger::info('Metadata create', ['uid' => $uid, 'data' => $data, 'return' => $ret]); + DI::logger()->info('Metadata create', ['uid' => $uid, 'data' => $data, 'return' => $ret]); } } else { - Logger::error('Failed upload', ['uid' => $uid, 'size' => strlen($picturedata), 'image' => $image['url'], 'return' => $media]); + DI::logger()->error('Failed upload', ['uid' => $uid, 'size' => strlen($picturedata), 'image' => $image['url'], 'return' => $media]); throw new Exception('Failed upload of ' . $image['url']); } @@ -373,7 +372,7 @@ function twitter_post(int $uid, string $url, string $type, array $data): stdClas DI::pConfig()->set($uid, 'twitter', 'last_status', $status); $content = json_decode($body) ?? new stdClass; - Logger::debug('Success', ['content' => $content]); + DI::logger()->debug('Success', ['content' => $content]); return $content; } @@ -402,7 +401,7 @@ function twitter_test_connection(int $uid) 'content' => $response->getBody()->getContents() ]; DI::pConfig()->set(1, 'twitter', 'last_status', $status); - Logger::info('Test successful', ['uid' => $uid]); + DI::logger()->info('Test successful', ['uid' => $uid]); } catch (RequestException $exception) { $status = [ 'code' => $exception->getCode(), @@ -410,6 +409,6 @@ function twitter_test_connection(int $uid) 'content' => $exception->getMessage() ]; DI::pConfig()->set(1, 'twitter', 'last_status', $status); - Logger::info('Test failed', ['uid' => $uid]); + DI::logger()->info('Test failed', ['uid' => $uid]); } } diff --git a/unicode_smilies/unicode_smilies.php b/unicode_smilies/unicode_smilies.php index 22ee3439..8ec47175 100644 --- a/unicode_smilies/unicode_smilies.php +++ b/unicode_smilies/unicode_smilies.php @@ -2,12 +2,11 @@ /* * Name: Unicode Smilies * Description: Smilies based on the unicode emojis - On Linux use https://github.com/eosrei/emojione-color-font to see them in color and http://www.unicode.org/emoji/charts/full-emoji-list.html - * Version: 1.1.2 + * Version: 1.1.3 * Author: Michael Vogel * Author: Matthias Ebers */ -use Friendica\App; use Friendica\Content\Smilies; use Friendica\Core\Hook; @@ -25,7 +24,7 @@ function unicode_smilies_smilies(array &$b) Smilies::add($b, ':-D', '😁'); Smilies::add($b, ':D', '😁'); Smilies::add($b, ';-)', '😉'); - // Smilies::add($b, ';)', '😉'); // Deactivated since this leads to disturbed html entities +// Smilies::add($b, ';)', '😉'); // Deactivated since this leads to disturbed html entities Smilies::add($b, ':-P', '😛'); Smilies::add($b, ':-p', '😛'); Smilies::add($b, ':P', '😛'); @@ -54,353 +53,350 @@ function unicode_smilies_smilies(array &$b) // Smilies::add($b, 'O_o', '&#x;'); // face-smiling - Smilies::add($b, ':grinning face:', '😀'); - Smilies::add($b, ':grinning face with big eyes:', '😃'); - Smilies::add($b, ':grinning face with smiling eyes:', '😄'); - Smilies::add($b, ':beaming face with smiling eyes:', '😁'); - Smilies::add($b, ':grinning squinting face:', '😆'); - Smilies::add($b, ':laughing:', '😆'); - Smilies::add($b, ':grinning face with sweat:', '😅'); - Smilies::add($b, ':rolling on the floor laughing:', '🤣'); + Smilies::add($b, ':grinning face:', '😀'); + Smilies::add($b, ':grinning face with big eyes:', '😃'); + Smilies::add($b, ':grinning face with smiling eyes:', '😄'); + Smilies::add($b, ':beaming face with smiling eyes:', '😁'); + Smilies::add($b, ':grinning squinting face:', '😆'); + Smilies::add($b, ':laughing:', '😆'); + Smilies::add($b, ':grinning face with sweat:', '😅'); + Smilies::add($b, ':rolling on the floor laughing:', '🤣'); Smilies::add($b, ':rofl:', '🤣'); - Smilies::add($b, ':face with tears of joy:', '😂'); + Smilies::add($b, ':face with tears of joy:', '😂'); Smilies::add($b, ':tearsofjoy:', '😂'); - Smilies::add($b, ':slightly smiling face:', '🙂'); - Smilies::add($b, ':upside-down face:', '🙃'); - Smilies::add($b, ':winking face:', '😉'); - Smilies::add($b, ':smiling face with smiling eyes:', '😊'); - Smilies::add($b, ':smiling face with halo:', '😇'); + Smilies::add($b, ':slightly smiling face:', '🙂'); + Smilies::add($b, ':upside-down face:', '🙃'); + Smilies::add($b, ':winking face:', '😉'); + Smilies::add($b, ':smiling face with smiling eyes:', '😊'); + Smilies::add($b, ':smiling face with halo:', '😇'); // face-affection - Smilies::add($b, ':smiling face with hearts:', '🥰'); - Smilies::add($b, ':smiling face with heart-eyes:', '😍'); - Smilies::add($b, ':star-struck:', '🤩'); - Smilies::add($b, ':face blowing a kiss:', '😘'); - Smilies::add($b, ':kissing face:', '😗'); - Smilies::add($b, ':smiling face:', '☺'); - Smilies::add($b, ':kissing face with closed eyes:', '😚'); - Smilies::add($b, ':kissing face with smiling eyes:', '😙'); + Smilies::add($b, ':smiling face with hearts:', '🥰'); + Smilies::add($b, ':smiling face with heart-eyes:', '😍'); + Smilies::add($b, ':star-struck:', '🤩'); + Smilies::add($b, ':face blowing a kiss:', '😘'); + Smilies::add($b, ':kissing face:', '😗'); + Smilies::add($b, ':smiling face:', '☺'); + Smilies::add($b, ':kissing face with closed eyes:', '😚'); + Smilies::add($b, ':kissing face with smiling eyes:', '😙'); // face-tongue - Smilies::add($b, ':face savoring food:', '😋'); - Smilies::add($b, ':face with tongue:', '😛'); - Smilies::add($b, ':winking face with tongue:', '😜'); - Smilies::add($b, ':zany face:', '🤪'); - Smilies::add($b, ':squinting face with tongue:', '😝'); - Smilies::add($b, ':money-mouth face:', '🤑'); + Smilies::add($b, ':face savoring food:', '😋'); + Smilies::add($b, ':face with tongue:', '😛'); + Smilies::add($b, ':winking face with tongue:', '😜'); + Smilies::add($b, ':zany face:', '🤪'); + Smilies::add($b, ':squinting face with tongue:', '😝'); + Smilies::add($b, ':money-mouth face:', '🤑'); // face-hand - Smilies::add($b, ':hugging face:', '🤗'); - Smilies::add($b, ':face with hand over mouth:', '🤭'); - Smilies::add($b, ':shushing face:', '🤫'); - Smilies::add($b, ':thinking face:', '🤔'); + Smilies::add($b, ':hugging face:', '🤗'); + Smilies::add($b, ':face with hand over mouth:', '🤭'); + Smilies::add($b, ':shushing face:', '🤫'); + Smilies::add($b, ':thinking face:', '🤔'); // face-neutral-skeptical - Smilies::add($b, ':zipper-mouth face:', '🤐'); - Smilies::add($b, ':face with raised eyebrow:', '🤨'); - Smilies::add($b, ':neutral face:', '😐'); - Smilies::add($b, ':expressionless face:', '😑'); - Smilies::add($b, ':face without mouth:', '😶'); - Smilies::add($b, ':smirking face:', '😏'); - Smilies::add($b, ':unamused face:', '😒'); - Smilies::add($b, ':face with rolling eyes:', '🙄'); - Smilies::add($b, ':grimacing face:', '😬'); - Smilies::add($b, ':lying face:', '🤥'); + Smilies::add($b, ':zipper-mouth face:', '🤐'); + Smilies::add($b, ':face with raised eyebrow:', '🤨'); + Smilies::add($b, ':neutral face:', '😐'); + Smilies::add($b, ':expressionless face:', '😑'); + Smilies::add($b, ':face without mouth:', '😶'); + Smilies::add($b, ':smirking face:', '😏'); + Smilies::add($b, ':unamused face:', '😒'); + Smilies::add($b, ':face with rolling eyes:', '🙄'); + Smilies::add($b, ':grimacing face:', '😬'); + Smilies::add($b, ':lying face:', '🤥'); // face-sleepy - Smilies::add($b, ':relieved face:', '😌'); - Smilies::add($b, ':pensive face:', '😔'); - Smilies::add($b, ':sleepy face:', '😪'); - Smilies::add($b, ':drooling face:', '🤤'); + Smilies::add($b, ':relieved face:', '😌'); + Smilies::add($b, ':pensive face:', '😔'); + Smilies::add($b, ':sleepy face:', '😪'); + Smilies::add($b, ':drooling face:', '🤤'); Smilies::add($b, ':drool:', '🤤'); - Smilies::add($b, ':sleeping face:', '😴'); + Smilies::add($b, ':sleeping face:', '😴'); // face-unwell - Smilies::add($b, ':face with medical mask:', '😷'); - Smilies::add($b, ':face with thermometer:', '🤒'); - Smilies::add($b, ':face with head-bandage:', '🤕'); - Smilies::add($b, ':nauseated face:', '🤢'); - Smilies::add($b, ':face vomiting:', '🤮'); + Smilies::add($b, ':face with medical mask:', '😷'); + Smilies::add($b, ':face with thermometer:', '🤒'); + Smilies::add($b, ':face with head-bandage:', '🤕'); + Smilies::add($b, ':nauseated face:', '🤢'); + Smilies::add($b, ':face vomiting:', '🤮'); Smilies::add($b, ':vomit:', '🤮'); - Smilies::add($b, ':sneezing face:', '🤧'); - Smilies::add($b, ':hot face:', '🥵'); - Smilies::add($b, ':cold face:', '🥶'); - Smilies::add($b, ':woozy face:', '🥴'); - Smilies::add($b, ':dizzy face:', '😵'); + Smilies::add($b, ':sneezing face:', '🤧'); + Smilies::add($b, ':hot face:', '🥵'); + Smilies::add($b, ':cold face:', '🥶'); + Smilies::add($b, ':woozy face:', '🥴'); + Smilies::add($b, ':dizzy face:', '😵'); Smilies::add($b, ':dead:', '😵'); - Smilies::add($b, ':exploding head:', '🤯'); + Smilies::add($b, ':exploding head:', '🤯'); // face-hat - Smilies::add($b, ':cowboy hat face:', '🤠'); - Smilies::add($b, ':partying face:', '🥳'); + Smilies::add($b, ':cowboy hat face:', '🤠'); + Smilies::add($b, ':partying face:', '🥳'); // face-glasses - Smilies::add($b, ':smiling face with sunglasses:', '😎'); - Smilies::add($b, ':nerd face:', '🤓'); - Smilies::add($b, ':face with monocle:', '🧐'); + Smilies::add($b, ':smiling face with sunglasses:', '😎'); + Smilies::add($b, ':nerd face:', '🤓'); + Smilies::add($b, ':face with monocle:', '🧐'); // face-concerned - Smilies::add($b, ':confused face:', '😕'); - Smilies::add($b, ':worried face:', '😟'); - Smilies::add($b, ':slightly frowning face:', '🙁'); - Smilies::add($b, ':frowning face:', '☹'); - Smilies::add($b, ':face with open mouth:', '😮'); - Smilies::add($b, ':hushed face:', '😯'); - Smilies::add($b, ':astonished face:', '😲'); - Smilies::add($b, ':flushed face:', '😳'); + Smilies::add($b, ':confused face:', '😕'); + Smilies::add($b, ':worried face:', '😟'); + Smilies::add($b, ':slightly frowning face:', '🙁'); + Smilies::add($b, ':frowning face:', '☹'); + Smilies::add($b, ':face with open mouth:', '😮'); + Smilies::add($b, ':hushed face:', '😯'); + Smilies::add($b, ':astonished face:', '😲'); + Smilies::add($b, ':flushed face:', '😳'); Smilies::add($b, ':dazed:', '😳'); - Smilies::add($b, ':pleading face:', '🥺'); - Smilies::add($b, ':frowning face with open mouth:', '😦'); - Smilies::add($b, ':anguished face:', '😧'); - Smilies::add($b, ':fearful face:', '😨'); - Smilies::add($b, ':anxious face with sweat:', '😰'); - Smilies::add($b, ':sad but relieved face:', '😥'); - Smilies::add($b, ':crying face:', '😢'); - Smilies::add($b, ':loudly crying face:', '😭'); - Smilies::add($b, ':face screaming in fear:', '😱'); - Smilies::add($b, ':confounded face:', '😖'); - Smilies::add($b, ':persevering face:', '😣'); - Smilies::add($b, ':disappointed face:', '😞'); + Smilies::add($b, ':pleading face:', '🥺'); + Smilies::add($b, ':frowning face with open mouth:', '😦'); + Smilies::add($b, ':anguished face:', '😧'); + Smilies::add($b, ':fearful face:', '😨'); + Smilies::add($b, ':anxious face with sweat:', '😰'); + Smilies::add($b, ':sad but relieved face:', '😥'); + Smilies::add($b, ':crying face:', '😢'); + Smilies::add($b, ':loudly crying face:', '😭'); + Smilies::add($b, ':face screaming in fear:', '😱'); + Smilies::add($b, ':confounded face:', '😖'); + Smilies::add($b, ':persevering face:', '😣'); + Smilies::add($b, ':disappointed face:', '😞'); // face-negative - Smilies::add($b, ':face with steam from nose:', '😤'); - Smilies::add($b, ':pouting face:', '😡'); - Smilies::add($b, ':angry face:', '😠'); - Smilies::add($b, ':face with symbols on mouth:', '🤬'); - Smilies::add($b, ':smiling face with horns:', '😈'); - Smilies::add($b, ':angry face with horns:', '👿'); - Smilies::add($b, ':skull:', '💀'); - Smilies::add($b, ':skull and crossbones:', '☠'); + Smilies::add($b, ':face with steam from nose:', '😤'); + Smilies::add($b, ':pouting face:', '😡'); + Smilies::add($b, ':angry face:', '😠'); + Smilies::add($b, ':face with symbols on mouth:', '🤬'); + Smilies::add($b, ':smiling face with horns:', '😈'); + Smilies::add($b, ':angry face with horns:', '👿'); + Smilies::add($b, ':skull:', '💀'); + Smilies::add($b, ':skull and crossbones:', '☠'); // face-costume - Smilies::add($b, ':pile of poo:', '💩'); - Smilies::add($b, ':clown face:', '🤡'); - Smilies::add($b, ':ogre:', '👹'); - Smilies::add($b, ':goblin:', '👺'); - Smilies::add($b, ':ghost:', '👻'); - Smilies::add($b, ':alien:', '👽'); - Smilies::add($b, ':alien monster:', '👾'); - Smilies::add($b, ':robot:', '🤖'); + Smilies::add($b, ':pile of poo:', '💩'); + Smilies::add($b, ':clown face:', '🤡'); + Smilies::add($b, ':ogre:', '👹'); + Smilies::add($b, ':goblin:', '👺'); + Smilies::add($b, ':ghost:', '👻'); + Smilies::add($b, ':alien:', '👽'); + Smilies::add($b, ':alien monster:', '👾'); + Smilies::add($b, ':robot:', '🤖'); // cat-face - Smilies::add($b, ':grinning cat:', '😺'); - Smilies::add($b, ':grinning cat with smiling eyes:', '😸'); - Smilies::add($b, ':cat with tears of joy:', '😹'); - Smilies::add($b, ':smiling cat with heart-eyes:', '😻'); - Smilies::add($b, ':cat with wry smile:', '😼'); - Smilies::add($b, ':kissing cat:', '😽'); - Smilies::add($b, ':weary cat:', '🙀'); - Smilies::add($b, ':crying cat:', '😿'); - Smilies::add($b, ':pouting cat:', '😾'); + Smilies::add($b, ':grinning cat:', '😺'); + Smilies::add($b, ':grinning cat with smiling eyes:', '😸'); + Smilies::add($b, ':cat with tears of joy:', '😹'); + Smilies::add($b, ':smiling cat with heart-eyes:', '😻'); + Smilies::add($b, ':cat with wry smile:', '😼'); + Smilies::add($b, ':kissing cat:', '😽'); + Smilies::add($b, ':weary cat:', '🙀'); + Smilies::add($b, ':crying cat:', '😿'); + Smilies::add($b, ':pouting cat:', '😾'); // monkey-face - Smilies::add($b, ':see-no-evil monkey:', '🙈'); - Smilies::add($b, ':hear-no-evil monkey:', '🙉'); - Smilies::add($b, ':speak-no-evil monkey:', '🙊'); + Smilies::add($b, ':see-no-evil monkey:', '🙈'); + Smilies::add($b, ':hear-no-evil monkey:', '🙉'); + Smilies::add($b, ':speak-no-evil monkey:', '🙊'); //emotion - Smilies::add($b, ':kiss mark:', '💋'); - Smilies::add($b, ':love letter:', '💌'); - Smilies::add($b, ':heart with arrow:', '💘'); - Smilies::add($b, ':heart with ribbon:', '💝'); - Smilies::add($b, ':sparkling heart:', '💖'); - Smilies::add($b, ':loveheart:', '💖'); - Smilies::add($b, ':growing heart:', '💗'); - Smilies::add($b, ':beating heart:', '💓'); - Smilies::add($b, ':revolving hearts:', '💞'); - Smilies::add($b, ':two hearts:', '💕'); - Smilies::add($b, ':heart decoration:', '💟'); - Smilies::add($b, ':heart exclamation:', '❣'); - Smilies::add($b, ':broken heart:', '💔'); - Smilies::add($b, ':red heart:', '❤'); - Smilies::add($b, ':orange heart:', '🧡'); - Smilies::add($b, ':yellow heart:', '💛'); - Smilies::add($b, ':green heart:', '💚'); - Smilies::add($b, ':blue heart:', '💙'); - Smilies::add($b, ':purple heart:', '💜'); - Smilies::add($b, ':brown heart:', '🤎'); - Smilies::add($b, ':black heart:', '🖤'); - Smilies::add($b, ':white heart:', '🤍'); - Smilies::add($b, ':hundred points:', '💯'); - Smilies::add($b, ':anger symbol:', '💢'); - Smilies::add($b, ':collision:', '💥'); - Smilies::add($b, ':dizzy:', '💫'); - Smilies::add($b, ':sweat droplets:', '💦'); - Smilies::add($b, ':dashing away:', '💨'); - Smilies::add($b, ':hole:', '🕳'); - Smilies::add($b, ':bomb:', '💣'); - Smilies::add($b, ':speech balloon:', '💬'); - Smilies::add($b, ':left speech bubble:', '🗨'); - Smilies::add($b, ':right anger bubble:', '🗯'); - Smilies::add($b, ':thought balloon:', '💭'); - Smilies::add($b, ':zzz:', '💤'); + Smilies::add($b, ':kiss mark:', '💋'); + Smilies::add($b, ':love letter:', '💌'); + Smilies::add($b, ':heart with arrow:', '💘'); + Smilies::add($b, ':heart with ribbon:', '💝'); + Smilies::add($b, ':sparkling heart:', '💖'); + Smilies::add($b, ':loveheart:', '💖'); + Smilies::add($b, ':growing heart:', '💗'); + Smilies::add($b, ':beating heart:', '💓'); + Smilies::add($b, ':revolving hearts:', '💞'); + Smilies::add($b, ':two hearts:', '💕'); + Smilies::add($b, ':heart decoration:', '💟'); + Smilies::add($b, ':heart exclamation:', '❣'); + Smilies::add($b, ':broken heart:', '💔'); + Smilies::add($b, ':red heart:', '❤'); + Smilies::add($b, ':orange heart:', '🧡'); + Smilies::add($b, ':yellow heart:', '💛'); + Smilies::add($b, ':green heart:', '💚'); + Smilies::add($b, ':blue heart:', '💙'); + Smilies::add($b, ':purple heart:', '💜'); + Smilies::add($b, ':brown heart:', '🤎'); + Smilies::add($b, ':black heart:', '🖤'); + Smilies::add($b, ':white heart:', '🤍'); + Smilies::add($b, ':hundred points:', '💯'); + Smilies::add($b, ':anger symbol:', '💢'); + Smilies::add($b, ':collision:', '💥'); + Smilies::add($b, ':dizzy:', '💫'); + Smilies::add($b, ':sweat droplets:', '💦'); + Smilies::add($b, ':dashing away:', '💨'); + Smilies::add($b, ':hole:', '🕳'); + Smilies::add($b, ':bomb:', '💣'); + Smilies::add($b, ':speech balloon:', '💬'); + Smilies::add($b, ':left speech bubble:', '🗨'); + Smilies::add($b, ':right anger bubble:', '🗯'); + Smilies::add($b, ':thought balloon:', '💭'); + Smilies::add($b, ':zzz:', '💤'); // People & Body // hand-fingers-open - Smilies::add($b, ':waving hand:', '👋'); - Smilies::add($b, ':raised back of hand:', '🤚'); - Smilies::add($b, ':hand with fingers splayed:', '🖐'); - Smilies::add($b, ':raised hand:', '✋'); - Smilies::add($b, ':vulcan salute:', '🖖'); + Smilies::add($b, ':waving hand:', '👋'); + Smilies::add($b, ':raised back of hand:', '🤚'); + Smilies::add($b, ':hand with fingers splayed:', '🖐'); + Smilies::add($b, ':raised hand:', '✋'); + Smilies::add($b, ':vulcan salute:', '🖖'); // hand-fingers-partial - Smilies::add($b, ':OK hand:', '👌'); -// Smilies::add($b, ':pinching hand:', '🤏'); - Smilies::add($b, ':victory hand:', '✌'); - Smilies::add($b, ':crossed fingers:', '🤞'); - Smilies::add($b, ':love-you gesture:', '🤟'); - Smilies::add($b, ':sign of the horns:', '🤘'); - Smilies::add($b, ':call me hand:', '🤙'); + Smilies::add($b, ':OK hand:', '👌'); + Smilies::add($b, ':victory hand:', '✌'); + Smilies::add($b, ':crossed fingers:', '🤞'); + Smilies::add($b, ':love-you gesture:', '🤟'); + Smilies::add($b, ':sign of the horns:', '🤘'); + Smilies::add($b, ':call me hand:', '🤙'); // hand-single-finger - Smilies::add($b, ':backhand index pointing left:', '👈'); - Smilies::add($b, ':backhand index pointing right:', '👉'); - Smilies::add($b, ':backhand index pointing up:', '👆'); - Smilies::add($b, ':middle finger:', '🖕'); - Smilies::add($b, ':backhand index pointing down:', '👇'); - Smilies::add($b, ':index pointing up:', '☝'); + Smilies::add($b, ':backhand index pointing left:', '👈'); + Smilies::add($b, ':backhand index pointing right:', '👉'); + Smilies::add($b, ':backhand index pointing up:', '👆'); + Smilies::add($b, ':middle finger:', '🖕'); + Smilies::add($b, ':backhand index pointing down:', '👇'); + Smilies::add($b, ':index pointing up:', '☝'); // hand-fingers-closed - Smilies::add($b, ':thumbs up:', '👍'); + Smilies::add($b, ':thumbs up:', '👍'); Smilies::add($b, ':like:', '👍'); Smilies::add($b, '\\o/', '👍'); - Smilies::add($b, ':thumbs down:', '👎'); + Smilies::add($b, ':thumbs down:', '👎'); Smilies::add($b, ':dislike:', '👎'); - Smilies::add($b, ':raised fist:', '✊'); - Smilies::add($b, ':oncoming fist:', '👊'); - Smilies::add($b, ':left-facing fist:', '🤛'); - Smilies::add($b, ':right-facing fist:', '🤜'); + Smilies::add($b, ':raised fist:', '✊'); + Smilies::add($b, ':oncoming fist:', '👊'); + Smilies::add($b, ':left-facing fist:', '🤛'); + Smilies::add($b, ':right-facing fist:', '🤜'); // hands - Smilies::add($b, ':clapping hands:', '👏'); - Smilies::add($b, ':raising hands:', '🙌'); - Smilies::add($b, ':open hands:', '👐'); - Smilies::add($b, ':palms up together:', '🤲'); - Smilies::add($b, ':handshake:', '🤝'); - Smilies::add($b, ':folded hands:', '🙏'); + Smilies::add($b, ':clapping hands:', '👏'); + Smilies::add($b, ':raising hands:', '🙌'); + Smilies::add($b, ':open hands:', '👐'); + Smilies::add($b, ':palms up together:', '🤲'); + Smilies::add($b, ':handshake:', '🤝'); + Smilies::add($b, ':folded hands:', '🙏'); // hand-prop - Smilies::add($b, ':writing hand:', '✍'); - Smilies::add($b, ':nail polish:', '💅'); - Smilies::add($b, ':selfie:', '🤳'); + Smilies::add($b, ':writing hand:', '✍'); + Smilies::add($b, ':nail polish:', '💅'); + Smilies::add($b, ':selfie:', '🤳'); // body-parts - Smilies::add($b, ':flexed biceps:', '💪'); - Smilies::add($b, ':mechanical arm:', '🦾'); - Smilies::add($b, ':mechanical leg:', '🦿'); - Smilies::add($b, ':leg:', '🦵'); - Smilies::add($b, ':foot:', '🦶'); - Smilies::add($b, ':ear:', '👂'); -// Smilies::add($b, ':ear with hearing aid:', '🦻'); - Smilies::add($b, ':nose:', '👃'); - Smilies::add($b, ':brain:', '🧠'); - Smilies::add($b, ':tooth:', '🦷'); - Smilies::add($b, ':bone:', '🦴'); - Smilies::add($b, ':eyes:', '👀'); - Smilies::add($b, ':eye:', '👁'); - Smilies::add($b, ':tongue:', '👅'); - Smilies::add($b, ':mouth:', '👄'); + Smilies::add($b, ':flexed biceps:', '💪'); + Smilies::add($b, ':mechanical arm:', '🦾'); + Smilies::add($b, ':mechanical leg:', '🦿'); + Smilies::add($b, ':leg:', '🦵'); + Smilies::add($b, ':foot:', '🦶'); + Smilies::add($b, ':ear:', '👂'); + Smilies::add($b, ':brain:', '🧠'); + Smilies::add($b, ':tooth:', '🦷'); + Smilies::add($b, ':bone:', '🦴'); + Smilies::add($b, ':eyes:', '👀'); + Smilies::add($b, ':eye:', '👁'); + Smilies::add($b, ':tongue:', '👅'); + Smilies::add($b, ':mouth:', '👄'); // person - Smilies::add($b, ':baby:', '👶'); - Smilies::add($b, ':child:', '🧒'); - Smilies::add($b, ':boy:', '👦'); - Smilies::add($b, ':girl:', '👧'); - Smilies::add($b, ':person:', '🧑'); - Smilies::add($b, ':person: blond hair:', '👱'); - Smilies::add($b, ':man:', '👨'); - Smilies::add($b, ':man: beard:', '🧔'); + Smilies::add($b, ':baby:', '👶'); + Smilies::add($b, ':child:', '🧒'); + Smilies::add($b, ':boy:', '👦'); + Smilies::add($b, ':girl:', '👧'); + Smilies::add($b, ':person:', '🧑'); + Smilies::add($b, ':person: blond hair:', '👱'); + Smilies::add($b, ':man:', '👨'); + Smilies::add($b, ':man: beard:', '🧔'); Smilies::add($b, ':beard:', '🧔'); - Smilies::add($b, ':man: red hair:', '👨‍🦰'); - Smilies::add($b, ':man: curly hair:', '👨‍🦱'); - Smilies::add($b, ':man: white hair:', '👨‍🦳'); - Smilies::add($b, ':man: bald:', '👨‍🦲'); - Smilies::add($b, ':woman:', '👩'); - Smilies::add($b, ':woman: red hair:', '👩‍🦰'); - Smilies::add($b, ':person: red hair:', '🧑‍🦰'); - Smilies::add($b, ':woman: curly hair:', '👩‍🦱'); - Smilies::add($b, ':person: curly hair:', '🧑‍🦱'); - Smilies::add($b, ':woman: white hair:', '👩‍🦳'); - Smilies::add($b, ':person: white hair:', '🧑‍🦳'); - Smilies::add($b, ':woman: bald:', '👩‍🦲'); - Smilies::add($b, ':bald::', '🧑‍🦲'); - Smilies::add($b, ':woman: blond hair:', '👱‍♀️'); - Smilies::add($b, ':man: blond hair:', '👱‍♂️'); - Smilies::add($b, ':older person:', '🧓'); - Smilies::add($b, ':old man:', '👴'); - Smilies::add($b, ':old woman:', '👵'); + Smilies::add($b, ':man: red hair:', '👨‍🦰'); + Smilies::add($b, ':man: curly hair:', '👨‍🦱'); + Smilies::add($b, ':man: white hair:', '👨‍🦳'); + Smilies::add($b, ':man: bald:', '👨‍🦲'); + Smilies::add($b, ':woman:', '👩'); + Smilies::add($b, ':woman: red hair:', '👩‍🦰'); + Smilies::add($b, ':person: red hair:', '🧑‍🦰'); + Smilies::add($b, ':woman: curly hair:', '👩‍🦱'); + Smilies::add($b, ':person: curly hair:', '🧑‍🦱'); + Smilies::add($b, ':woman: white hair:', '👩‍🦳'); + Smilies::add($b, ':person: white hair:', '🧑‍🦳'); + Smilies::add($b, ':woman: bald:', '👩‍🦲'); + Smilies::add($b, ':bald::', '🧑‍🦲'); + Smilies::add($b, ':woman: blond hair:', '👱‍♀️'); + Smilies::add($b, ':man: blond hair:', '👱‍♂️'); + Smilies::add($b, ':older person:', '🧓'); + Smilies::add($b, ':old man:', '👴'); + Smilies::add($b, ':old woman:', '👵'); Smilies::add($b, ':pregnant:', '🤰'); // person-gesture - Smilies::add($b, ':person frowning:', '🙍'); - Smilies::add($b, ':man frowning:', '🙍‍♂️'); - Smilies::add($b, ':woman frowning:', '🙍‍♀️'); - Smilies::add($b, ':person pouting:', '🙎'); - Smilies::add($b, ':man pouting:', '🙎‍♂️'); - Smilies::add($b, ':woman pouting:', '🙎‍♀️'); - Smilies::add($b, ':person gesturing NO:', '🙅'); - Smilies::add($b, ':man gesturing NO:', '🙅‍♂️'); - Smilies::add($b, ':woman gesturing NO:', '🙅‍♀️'); - Smilies::add($b, ':person gesturing OK:', '🙆'); - Smilies::add($b, ':man gesturing OK:', '🙆‍♂️'); - Smilies::add($b, ':woman gesturing OK:', '🙆‍♀️'); - Smilies::add($b, ':person tipping hand:', '💁'); - Smilies::add($b, ':man tipping hand:', '💁‍♂️'); - Smilies::add($b, ':woman tipping hand:', '💁‍♀️'); - Smilies::add($b, ':person raising hand:', '🙋'); - Smilies::add($b, ':man raising hand:', '🙋‍♂️'); - Smilies::add($b, ':woman raising hand', '🙋‍♀️'); -// Smilies::add($b, ':deaf person:', '🧏'); -// Smilies::add($b, ':deaf man:', '🧏‍♂️'); -// Smilies::add($b, ':deaf woman:', '🧏‍♀️'); - Smilies::add($b, ':person bowing:', '🙇'); + Smilies::add($b, ':person frowning:', '🙍'); + Smilies::add($b, ':man frowning:', '🙍‍♂️'); + Smilies::add($b, ':woman frowning:', '🙍‍♀️'); + Smilies::add($b, ':person pouting:', '🙎'); + Smilies::add($b, ':man pouting:', '🙎‍♂️'); + Smilies::add($b, ':woman pouting:', '🙎‍♀️'); + Smilies::add($b, ':person gesturing NO:', '🙅'); + Smilies::add($b, ':man gesturing NO:', '🙅‍♂️'); + Smilies::add($b, ':woman gesturing NO:', '🙅‍♀️'); + Smilies::add($b, ':person gesturing OK:', '🙆'); + Smilies::add($b, ':man gesturing OK:', '🙆‍♂️'); + Smilies::add($b, ':woman gesturing OK:', '🙆‍♀️'); + Smilies::add($b, ':person tipping hand:', '💁'); + Smilies::add($b, ':man tipping hand:', '💁‍♂️'); + Smilies::add($b, ':woman tipping hand:', '💁‍♀️'); + Smilies::add($b, ':person raising hand:', '🙋'); + Smilies::add($b, ':man raising hand:', '🙋‍♂️'); + Smilies::add($b, ':woman raising hand', '🙋‍♀️'); +// Smilies::add($b, ':deaf person:', '🧏'); +// Smilies::add($b, ':deaf man:', '🧏‍♂️'); +// Smilies::add($b, ':deaf woman:', '🧏‍♀️'); + Smilies::add($b, ':person bowing:', '🙇'); Smilies::add($b, ':bow:', '🙇'); - Smilies::add($b, ':man bowing:', '🙇‍♂️'); - Smilies::add($b, ':woman bowing:', '🙇‍♀️'); - Smilies::add($b, ':person facepalming:', '🤦'); + Smilies::add($b, ':man bowing:', '🙇‍♂️'); + Smilies::add($b, ':woman bowing:', '🙇‍♀️'); + Smilies::add($b, ':person facepalming:', '🤦'); Smilies::add($b, ':facepalm:', '🤦'); - Smilies::add($b, ':man facepalming:', '🤦‍♂️'); - Smilies::add($b, ':woman facepalming:', '🤦‍♀️'); - Smilies::add($b, ':person shrugging:', '🤷'); + Smilies::add($b, ':man facepalming:', '🤦‍♂️'); + Smilies::add($b, ':woman facepalming:', '🤦‍♀️'); + Smilies::add($b, ':person shrugging:', '🤷'); Smilies::add($b, ':shrug:', '🤷'); - Smilies::add($b, ':man shrugging:', '🤷‍♂️'); - Smilies::add($b, ':woman shrugging:', '🤷‍♀️'); + Smilies::add($b, ':man shrugging:', '🤷‍♂️'); + Smilies::add($b, ':woman shrugging:', '🤷‍♀️'); // person-role // person-fantasy - Smilies::add($b, ':baby angel:', '👼'); + Smilies::add($b, ':baby angel:', '👼'); Smilies::add($b, ':angel:', '👼'); Smilies::add($b, ':cherub:', '👼'); - Smilies::add($b, ':Santa Claus:', '🎅'); - Smilies::add($b, ':Mrs. Claus:', '🤶'); - Smilies::add($b, ':superhero:', '🦸'); - Smilies::add($b, ':man superhero:', '🦸‍♂️'); - Smilies::add($b, ':woman superhero:', '🦸‍♀️'); - Smilies::add($b, ':supervillain:', '🦹'); - Smilies::add($b, ':man supervillain:', '🦹‍♂️'); - Smilies::add($b, ':woman supervillain:', '🦹‍♀️'); - Smilies::add($b, ':mage:', '🧙'); - Smilies::add($b, ':man mage:', '🧙‍♂️'); - Smilies::add($b, ':woman mage:', '🧙‍♀️'); - Smilies::add($b, ':fairy:', '🧚'); - Smilies::add($b, ':man fairy:', '🧚‍♂️'); - Smilies::add($b, ':woman fairy:', '🧚‍♀️'); - Smilies::add($b, ':vampire:', '🧛'); - Smilies::add($b, ':man vampire:', '🧛‍♂️'); - Smilies::add($b, ':woman vampire:', '🧛‍♀️'); - Smilies::add($b, ':merperson:', '🧜'); - Smilies::add($b, ':merman:', '🧜‍♂️'); - Smilies::add($b, ':mermaid:', '🧜‍♀️'); - Smilies::add($b, ':elf:', '🧝'); - Smilies::add($b, ':man elf:', '🧝‍♂️'); - Smilies::add($b, ':woman elf:', '🧝‍♀️'); - Smilies::add($b, ':genie:', '🧞'); - Smilies::add($b, ':man genie:', '🧞‍♂️'); - Smilies::add($b, ':woman genie:', '🧞‍♀️'); - Smilies::add($b, ':zombie:', '🧟'); - Smilies::add($b, ':man zombie:', '🧟‍♂️'); - Smilies::add($b, ':woman zombie:', '🧟‍♀️'); + Smilies::add($b, ':Santa Claus:', '🎅'); + Smilies::add($b, ':Mrs. Claus:', '🤶'); + Smilies::add($b, ':superhero:', '🦸'); + Smilies::add($b, ':man superhero:', '🦸‍♂️'); + Smilies::add($b, ':woman superhero:', '🦸‍♀️'); + Smilies::add($b, ':supervillain:', '🦹'); + Smilies::add($b, ':man supervillain:', '🦹‍♂️'); + Smilies::add($b, ':woman supervillain:', '🦹‍♀️'); + Smilies::add($b, ':mage:', '🧙'); + Smilies::add($b, ':man mage:', '🧙‍♂️'); + Smilies::add($b, ':woman mage:', '🧙‍♀️'); + Smilies::add($b, ':fairy:', '🧚'); + Smilies::add($b, ':man fairy:', '🧚‍♂️'); + Smilies::add($b, ':woman fairy:', '🧚‍♀️'); + Smilies::add($b, ':vampire:', '🧛'); + Smilies::add($b, ':man vampire:', '🧛‍♂️'); + Smilies::add($b, ':woman vampire:', '🧛‍♀️'); + Smilies::add($b, ':merperson:', '🧜'); + Smilies::add($b, ':merman:', '🧜‍♂️'); + Smilies::add($b, ':mermaid:', '🧜‍♀️'); + Smilies::add($b, ':elf:', '🧝'); + Smilies::add($b, ':man elf:', '🧝‍♂️'); + Smilies::add($b, ':woman elf:', '🧝‍♀️'); + Smilies::add($b, ':genie:', '🧞'); + Smilies::add($b, ':man genie:', '🧞‍♂️'); + Smilies::add($b, ':woman genie:', '🧞‍♀️'); + Smilies::add($b, ':zombie:', '🧟'); + Smilies::add($b, ':man zombie:', '🧟‍♂️'); + Smilies::add($b, ':woman zombie:', '🧟‍♀️'); // person-activity @@ -411,83 +407,83 @@ function unicode_smilies_smilies(array &$b) // person-resting // family - Smilies::add($b, ':people holding hands:', '🧑‍🤝‍🧑'); - Smilies::add($b, ':women holding hands:', '👭'); - Smilies::add($b, ':woman and man holding hands:', '👫'); - Smilies::add($b, ':men holding hands:', '👬'); - Smilies::add($b, ':kiss:', '💏'); - Smilies::add($b, ':couple with heart:', '💑'); - Smilies::add($b, ':family:', '👪'); + Smilies::add($b, ':people holding hands:', '🧑‍🤝‍🧑'); + Smilies::add($b, ':women holding hands:', '👭'); + Smilies::add($b, ':woman and man holding hands:', '👫'); + Smilies::add($b, ':men holding hands:', '👬'); + Smilies::add($b, ':kiss:', '💏'); + Smilies::add($b, ':couple with heart:', '💑'); + Smilies::add($b, ':family:', '👪'); // person-symbol - Smilies::add($b, ':speaking head:', '🗣'); - Smilies::add($b, ':bust in silhouette:', '👤'); - Smilies::add($b, ':busts in silhouette:', '👥'); - Smilies::add($b, ':footprints:', '👣'); + Smilies::add($b, ':speaking head:', '🗣'); + Smilies::add($b, ':bust in silhouette:', '👤'); + Smilies::add($b, ':busts in silhouette:', '👥'); + Smilies::add($b, ':footprints:', '👣'); // Component // hair-style // Animals & Nature // animal-mammal - Smilies::add($b, ':monkey face:', '🐵'); - Smilies::add($b, ':monkey:', '🐒'); - Smilies::add($b, ':gorilla:', '🦍'); - Smilies::add($b, ':orangutan:', '🦧'); - Smilies::add($b, ':dog face:', '🐶'); - Smilies::add($b, ':dog:', '🐕'); - Smilies::add($b, ':guide dog:', '🦮'); - Smilies::add($b, ':poodle:', '🐩'); - Smilies::add($b, ':wolf:', '🐺'); - Smilies::add($b, ':fox:', '🦊'); - Smilies::add($b, ':raccoon:', '🦝'); - Smilies::add($b, ':cat face:', '🐱'); - Smilies::add($b, ':cat:', '🐈'); - Smilies::add($b, ':lion:', '🦁'); - Smilies::add($b, ':tiger face:', '🐯'); - Smilies::add($b, ':tiger:', '🐅'); - Smilies::add($b, ':leopard:', '🐆'); - Smilies::add($b, ':horse face:', '🐴'); - Smilies::add($b, ':horse:', '🐎'); - Smilies::add($b, ':unicorn:', '🦄'); - Smilies::add($b, ':zebra:', '🦓'); - Smilies::add($b, ':deer:', '🦌'); - Smilies::add($b, ':cow face:', '🐮'); - Smilies::add($b, ':ox:', '🐂'); - Smilies::add($b, ':water buffalo:', '🐃'); - Smilies::add($b, ':cow:', '🐄'); - Smilies::add($b, ':pig face:', '🐷'); - Smilies::add($b, ':pig:', '🐖'); + Smilies::add($b, ':monkey face:', '🐵'); + Smilies::add($b, ':monkey:', '🐒'); + Smilies::add($b, ':gorilla:', '🦍'); + Smilies::add($b, ':orangutan:', '🦧'); + Smilies::add($b, ':dog face:', '🐶'); + Smilies::add($b, ':dog:', '🐕'); + Smilies::add($b, ':guide dog:', '🦮'); + Smilies::add($b, ':poodle:', '🐩'); + Smilies::add($b, ':wolf:', '🐺'); + Smilies::add($b, ':fox:', '🦊'); + Smilies::add($b, ':raccoon:', '🦝'); + Smilies::add($b, ':cat face:', '🐱'); + Smilies::add($b, ':cat:', '🐈'); + Smilies::add($b, ':lion:', '🦁'); + Smilies::add($b, ':tiger face:', '🐯'); + Smilies::add($b, ':tiger:', '🐅'); + Smilies::add($b, ':leopard:', '🐆'); + Smilies::add($b, ':horse face:', '🐴'); + Smilies::add($b, ':horse:', '🐎'); + Smilies::add($b, ':unicorn:', '🦄'); + Smilies::add($b, ':zebra:', '🦓'); + Smilies::add($b, ':deer:', '🦌'); + Smilies::add($b, ':cow face:', '🐮'); + Smilies::add($b, ':ox:', '🐂'); + Smilies::add($b, ':water buffalo:', '🐃'); + Smilies::add($b, ':cow:', '🐄'); + Smilies::add($b, ':pig face:', '🐷'); + Smilies::add($b, ':pig:', '🐖'); Smilies::add($b, ':boar:', '🐗'); - Smilies::add($b, ':pig nose:', '🐽'); - Smilies::add($b, ':ram:', '🐏'); - Smilies::add($b, ':sheep:', '🐑'); - Smilies::add($b, ':goat:', '🐐'); + Smilies::add($b, ':pig nose:', '🐽'); + Smilies::add($b, ':ram:', '🐏'); + Smilies::add($b, ':sheep:', '🐑'); + Smilies::add($b, ':goat:', '🐐'); Smilies::add($b, ':camel:', '🐪'); - Smilies::add($b, ':two-hump camel:', '🐫'); - Smilies::add($b, ':llama:', '🦙'); - Smilies::add($b, ':giraffe:', '🦒'); - Smilies::add($b, ':elephant:', '🐘'); - Smilies::add($b, ':rhinoceros:', '🦏'); - Smilies::add($b, ':hippopotamus:', '🦛'); - Smilies::add($b, ':mouse face:', '🐭'); - Smilies::add($b, ':mouse:', '🐁'); - Smilies::add($b, ':rat:', '🐀'); - Smilies::add($b, ':hamster:', '🐹'); - Smilies::add($b, ':rabbit face:', '🐰'); - Smilies::add($b, ':rabbit:', '🐇'); - Smilies::add($b, ':chipmunk:', '🐿'); - Smilies::add($b, ':hedgehog:', '🦔'); - Smilies::add($b, ':bat:', '🦇'); - Smilies::add($b, ':bear:', '🐻'); - Smilies::add($b, ':koala:', '🐨'); - Smilies::add($b, ':panda:', '🐼'); - Smilies::add($b, ':sloth:', '🦥'); - Smilies::add($b, ':otter:', '🦦'); - Smilies::add($b, ':skunk:', '🦨'); - Smilies::add($b, ':kangaroo:', '🦘'); - Smilies::add($b, ':badger:', '🦡'); - Smilies::add($b, ':paw prints:', '🐾'); + Smilies::add($b, ':two-hump camel:', '🐫'); + Smilies::add($b, ':llama:', '🦙'); + Smilies::add($b, ':giraffe:', '🦒'); + Smilies::add($b, ':elephant:', '🐘'); + Smilies::add($b, ':rhinoceros:', '🦏'); + Smilies::add($b, ':hippopotamus:', '🦛'); + Smilies::add($b, ':mouse face:', '🐭'); + Smilies::add($b, ':mouse:', '🐁'); + Smilies::add($b, ':rat:', '🐀'); + Smilies::add($b, ':hamster:', '🐹'); + Smilies::add($b, ':rabbit face:', '🐰'); + Smilies::add($b, ':rabbit:', '🐇'); + Smilies::add($b, ':chipmunk:', '🐿'); + Smilies::add($b, ':hedgehog:', '🦔'); + Smilies::add($b, ':bat:', '🦇'); + Smilies::add($b, ':bear:', '🐻'); + Smilies::add($b, ':koala:', '🐨'); + Smilies::add($b, ':panda:', '🐼'); + Smilies::add($b, ':sloth:', '🦥'); + Smilies::add($b, ':otter:', '🦦'); + Smilies::add($b, ':skunk:', '🦨'); + Smilies::add($b, ':kangaroo:', '🦘'); + Smilies::add($b, ':badger:', '🦡'); + Smilies::add($b, ':paw prints:', '🐾'); // Smilies::add($b, ':bunnyflowers:', '&#x;'); Smilies::add($b, ':chick:', '🐤'); Smilies::add($b, ':ladybird:', '🐞'); @@ -495,959 +491,958 @@ function unicode_smilies_smilies(array &$b) // Smilies::add($b, ':dragonfly:', '&#x;'); // animal-bird - Smilies::add($b, ':turkey:', '🦃'); - Smilies::add($b, ':chicken:', '🐔'); - Smilies::add($b, ':rooster:', '🐓'); - Smilies::add($b, ':hatching chick:', '🐣'); - Smilies::add($b, ':baby chick:', '🐤'); - Smilies::add($b, ':front-facing baby chick:', '🐥'); - Smilies::add($b, ':bird:', '🐦'); - Smilies::add($b, ':tux:', '🐧'); - Smilies::add($b, ':dove:', '🕊'); - Smilies::add($b, ':eagle:', '🦅'); - Smilies::add($b, ':duck:', '🦆'); - Smilies::add($b, ':swan:', '🦢'); - Smilies::add($b, ':owl:', '🦉'); - Smilies::add($b, ':flamingo:', '🦩'); - Smilies::add($b, ':peacock:', '🦚'); - Smilies::add($b, ':parrot:', '🦜'); + Smilies::add($b, ':turkey:', '🦃'); + Smilies::add($b, ':chicken:', '🐔'); + Smilies::add($b, ':rooster:', '🐓'); + Smilies::add($b, ':hatching chick:', '🐣'); + Smilies::add($b, ':baby chick:', '🐤'); + Smilies::add($b, ':front-facing baby chick:', '🐥'); + Smilies::add($b, ':bird:', '🐦'); + Smilies::add($b, ':tux:', '🐧'); + Smilies::add($b, ':dove:', '🕊'); + Smilies::add($b, ':eagle:', '🦅'); + Smilies::add($b, ':duck:', '🦆'); + Smilies::add($b, ':swan:', '🦢'); + Smilies::add($b, ':owl:', '🦉'); + Smilies::add($b, ':flamingo:', '🦩'); + Smilies::add($b, ':peacock:', '🦚'); + Smilies::add($b, ':parrot:', '🦜'); // animal-amphibian - Smilies::add($b, ':frog:', '🐸'); + Smilies::add($b, ':frog:', '🐸'); // animal-reptile - Smilies::add($b, ':crocodile:', '🐊'); - Smilies::add($b, ':turtle:', '🐢'); - Smilies::add($b, ':lizard:', '🦎'); - Smilies::add($b, ':snake:', '🐍'); - Smilies::add($b, ':dragon face:', '🐲'); - Smilies::add($b, ':dragon:', '🐉'); + Smilies::add($b, ':crocodile:', '🐊'); + Smilies::add($b, ':turtle:', '🐢'); + Smilies::add($b, ':lizard:', '🦎'); + Smilies::add($b, ':snake:', '🐍'); + Smilies::add($b, ':dragon face:', '🐲'); + Smilies::add($b, ':dragon:', '🐉'); Smilies::add($b, ':draco:', '🐉'); - Smilies::add($b, ':sauropod:', '🦕'); - Smilies::add($b, ':T-Rex:', '🦖'); + Smilies::add($b, ':sauropod:', '🦕'); + Smilies::add($b, ':T-Rex:', '🦖'); // animal-marine - Smilies::add($b, ':spouting whale:', '🐳'); - Smilies::add($b, ':whale:', '🐋'); - Smilies::add($b, ':dolphin:', '🐬'); - Smilies::add($b, ':fish:', '🐟'); - Smilies::add($b, ':tropical fish:', '🐠'); - Smilies::add($b, ':blowfish:', '🐡'); - Smilies::add($b, ':shark:', '🦈'); - Smilies::add($b, ':octopus:', '🐙'); - Smilies::add($b, ':spiral shell:', '🐚'); + Smilies::add($b, ':spouting whale:', '🐳'); + Smilies::add($b, ':whale:', '🐋'); + Smilies::add($b, ':dolphin:', '🐬'); + Smilies::add($b, ':fish:', '🐟'); + Smilies::add($b, ':tropical fish:', '🐠'); + Smilies::add($b, ':blowfish:', '🐡'); + Smilies::add($b, ':shark:', '🦈'); + Smilies::add($b, ':octopus:', '🐙'); + Smilies::add($b, ':spiral shell:', '🐚'); // animal-bug - Smilies::add($b, ':snail:', '🐌'); - Smilies::add($b, ':butterfly:', '🦋'); - Smilies::add($b, ':bug:', '🐛'); - Smilies::add($b, ':ant:', '🐜'); - Smilies::add($b, ':honeybee:', '🐝'); - Smilies::add($b, ':lady beetle:', '🐞'); - Smilies::add($b, ':cricket:', '🦗'); - Smilies::add($b, ':spider:', '🕷'); - Smilies::add($b, ':spider web:', '🕸'); - Smilies::add($b, ':scorpion:', '🦂'); - Smilies::add($b, ':mosquito:', '🦟'); - Smilies::add($b, ':microbe:', '🦠'); + Smilies::add($b, ':snail:', '🐌'); + Smilies::add($b, ':butterfly:', '🦋'); + Smilies::add($b, ':bug:', '🐛'); + Smilies::add($b, ':ant:', '🐜'); + Smilies::add($b, ':honeybee:', '🐝'); + Smilies::add($b, ':lady beetle:', '🐞'); + Smilies::add($b, ':cricket:', '🦗'); + Smilies::add($b, ':spider:', '🕷'); + Smilies::add($b, ':spider web:', '🕸'); + Smilies::add($b, ':scorpion:', '🦂'); + Smilies::add($b, ':mosquito:', '🦟'); + Smilies::add($b, ':microbe:', '🦠'); // plant-flower - Smilies::add($b, ':bouquet:', '💐'); - Smilies::add($b, ':cherry blossom:', '🌸'); - Smilies::add($b, ':white flower:', '💮'); - Smilies::add($b, ':rosette:', '🏵'); - Smilies::add($b, ':rose:', '🌹'); - Smilies::add($b, ':wilted flower:', '🥀'); - Smilies::add($b, ':hibiscus:', '🌺'); - Smilies::add($b, ':sunflower:', '🌻'); - Smilies::add($b, ':blossom:', '🌼'); - Smilies::add($b, ':tulip:', '🌷'); + Smilies::add($b, ':bouquet:', '💐'); + Smilies::add($b, ':cherry blossom:', '🌸'); + Smilies::add($b, ':white flower:', '💮'); + Smilies::add($b, ':rosette:', '🏵'); + Smilies::add($b, ':rose:', '🌹'); + Smilies::add($b, ':wilted flower:', '🥀'); + Smilies::add($b, ':hibiscus:', '🌺'); + Smilies::add($b, ':sunflower:', '🌻'); + Smilies::add($b, ':blossom:', '🌼'); + Smilies::add($b, ':tulip:', '🌷'); // plant-other - Smilies::add($b, ':seedling:', '🌱'); - Smilies::add($b, ':evergreen tree:', '🌲'); - Smilies::add($b, ':deciduous tree:', '🌳'); - Smilies::add($b, ':palm tree:', '🌴'); - Smilies::add($b, ':cactus:', '🌵'); - Smilies::add($b, ':sheaf of rice:', '🌾'); - Smilies::add($b, ':herb:', '🌿'); - Smilies::add($b, ':shamrock:', '☘'); - Smilies::add($b, ':four leaf clover:', '🍀'); - Smilies::add($b, ':maple leaf:', '🍁'); - Smilies::add($b, ':fallen leaf:', '🍂'); - Smilies::add($b, ':leaf fluttering in wind:', '🍃'); + Smilies::add($b, ':seedling:', '🌱'); + Smilies::add($b, ':evergreen tree:', '🌲'); + Smilies::add($b, ':deciduous tree:', '🌳'); + Smilies::add($b, ':palm tree:', '🌴'); + Smilies::add($b, ':cactus:', '🌵'); + Smilies::add($b, ':sheaf of rice:', '🌾'); + Smilies::add($b, ':herb:', '🌿'); + Smilies::add($b, ':shamrock:', '☘'); + Smilies::add($b, ':four leaf clover:', '🍀'); + Smilies::add($b, ':maple leaf:', '🍁'); + Smilies::add($b, ':fallen leaf:', '🍂'); + Smilies::add($b, ':leaf fluttering in wind:', '🍃'); // Food & Drink // food-fruit - Smilies::add($b, ':grapes:', '🍇'); - Smilies::add($b, ':melon:', '🍈'); - Smilies::add($b, ':watermelon:', '🍉'); - Smilies::add($b, ':tangerine:', '🍊'); - Smilies::add($b, ':lemon:', '🍋'); - Smilies::add($b, ':banana:', '🍌'); - Smilies::add($b, ':pineapple:', '🍍'); - Smilies::add($b, ':mango:', '🥭'); - Smilies::add($b, ':red apple:', '🍎'); + Smilies::add($b, ':grapes:', '🍇'); + Smilies::add($b, ':melon:', '🍈'); + Smilies::add($b, ':watermelon:', '🍉'); + Smilies::add($b, ':tangerine:', '🍊'); + Smilies::add($b, ':lemon:', '🍋'); + Smilies::add($b, ':banana:', '🍌'); + Smilies::add($b, ':pineapple:', '🍍'); + Smilies::add($b, ':mango:', '🥭'); + Smilies::add($b, ':red apple:', '🍎'); Smilies::add($b, ':apple:', '🍎'); - Smilies::add($b, ':green apple:', '🍏'); - Smilies::add($b, ':pear:', '🍐'); - Smilies::add($b, ':peach:', '🍑'); - Smilies::add($b, ':cherries:', '🍒'); - Smilies::add($b, ':strawberry:', '🍓'); - Smilies::add($b, ':kiwi fruit:', '🥝'); - Smilies::add($b, ':tomato:', '🍅'); - Smilies::add($b, ':coconut:', '🥥'); + Smilies::add($b, ':green apple:', '🍏'); + Smilies::add($b, ':pear:', '🍐'); + Smilies::add($b, ':peach:', '🍑'); + Smilies::add($b, ':cherries:', '🍒'); + Smilies::add($b, ':strawberry:', '🍓'); + Smilies::add($b, ':kiwi fruit:', '🥝'); + Smilies::add($b, ':tomato:', '🍅'); + Smilies::add($b, ':coconut:', '🥥'); // food-vegetable - Smilies::add($b, ':avocado:', '🥑'); - Smilies::add($b, ':eggplant:', '🍆'); - Smilies::add($b, ':potato:', '🥔'); - Smilies::add($b, ':carrot:', '🥕'); - Smilies::add($b, ':ear of corn:', '🌽'); - Smilies::add($b, ':hot pepper:', '🌶'); - Smilies::add($b, ':cucumber:', '🥒'); - Smilies::add($b, ':leafy green:', '🥬'); - Smilies::add($b, ':broccoli:', '🥦'); - Smilies::add($b, ':garlic:', '🧄'); - Smilies::add($b, ':onion:', '🧅'); - Smilies::add($b, ':mushroom:', '🍄'); - Smilies::add($b, ':peanuts:', '🥜'); - Smilies::add($b, ':chestnut:', '🌰'); + Smilies::add($b, ':avocado:', '🥑'); + Smilies::add($b, ':eggplant:', '🍆'); + Smilies::add($b, ':potato:', '🥔'); + Smilies::add($b, ':carrot:', '🥕'); + Smilies::add($b, ':ear of corn:', '🌽'); + Smilies::add($b, ':hot pepper:', '🌶'); + Smilies::add($b, ':cucumber:', '🥒'); + Smilies::add($b, ':leafy green:', '🥬'); + Smilies::add($b, ':broccoli:', '🥦'); + Smilies::add($b, ':garlic:', '🧄'); + Smilies::add($b, ':onion:', '🧅'); + Smilies::add($b, ':mushroom:', '🍄'); + Smilies::add($b, ':peanuts:', '🥜'); + Smilies::add($b, ':chestnut:', '🌰'); // food-prepared - Smilies::add($b, ':bread:', '🍞'); - Smilies::add($b, ':croissant:', '🥐'); - Smilies::add($b, ':baguette bread:', '🥖'); - Smilies::add($b, ':pretzel:', '🥨'); - Smilies::add($b, ':bagel:', '🥯'); - Smilies::add($b, ':pancakes:', '🥞'); - Smilies::add($b, ':waffle:', '🧇'); - Smilies::add($b, ':cheese wedge:', '🧀'); - Smilies::add($b, ':meat on bone:', '🍖'); - Smilies::add($b, ':poultry leg:', '🍗'); - Smilies::add($b, ':cut of meat:', '🥩'); - Smilies::add($b, ':bacon:', '🥓'); - Smilies::add($b, ':hamburger:', '🍔'); - Smilies::add($b, ':french fries:', '🍟'); - Smilies::add($b, ':pizza:', '🍕'); - Smilies::add($b, ':hot dog:', '🌭'); - Smilies::add($b, ':sandwich:', '🥪'); - Smilies::add($b, ':taco:', '🌮'); - Smilies::add($b, ':burrito:', '🌯'); - Smilies::add($b, ':stuffed flatbread:', '🥙'); - Smilies::add($b, ':falafel:', '🧆'); - Smilies::add($b, ':egg:', '🥚'); - Smilies::add($b, ':cooking:', '🍳'); + Smilies::add($b, ':bread:', '🍞'); + Smilies::add($b, ':croissant:', '🥐'); + Smilies::add($b, ':baguette bread:', '🥖'); + Smilies::add($b, ':pretzel:', '🥨'); + Smilies::add($b, ':bagel:', '🥯'); + Smilies::add($b, ':pancakes:', '🥞'); + Smilies::add($b, ':waffle:', '🧇'); + Smilies::add($b, ':cheese wedge:', '🧀'); + Smilies::add($b, ':meat on bone:', '🍖'); + Smilies::add($b, ':poultry leg:', '🍗'); + Smilies::add($b, ':cut of meat:', '🥩'); + Smilies::add($b, ':bacon:', '🥓'); + Smilies::add($b, ':hamburger:', '🍔'); + Smilies::add($b, ':french fries:', '🍟'); + Smilies::add($b, ':pizza:', '🍕'); + Smilies::add($b, ':hot dog:', '🌭'); + Smilies::add($b, ':sandwich:', '🥪'); + Smilies::add($b, ':taco:', '🌮'); + Smilies::add($b, ':burrito:', '🌯'); + Smilies::add($b, ':stuffed flatbread:', '🥙'); + Smilies::add($b, ':falafel:', '🧆'); + Smilies::add($b, ':egg:', '🥚'); + Smilies::add($b, ':cooking:', '🍳'); Smilies::add($b, ':fryegg:', '🍳'); - Smilies::add($b, ':shallow pan of food:', '🥘'); - Smilies::add($b, ':pot of food:', '🍲'); - Smilies::add($b, ':bowl with spoon:', '🥣'); - Smilies::add($b, ':green salad:', '🥗'); - Smilies::add($b, ':popcorn:', '🍿'); - Smilies::add($b, ':butter:', '🧈'); - Smilies::add($b, ':salt:', '🧂'); - Smilies::add($b, ':canned food:', '🥫'); + Smilies::add($b, ':shallow pan of food:', '🥘'); + Smilies::add($b, ':pot of food:', '🍲'); + Smilies::add($b, ':bowl with spoon:', '🥣'); + Smilies::add($b, ':green salad:', '🥗'); + Smilies::add($b, ':popcorn:', '🍿'); + Smilies::add($b, ':butter:', '🧈'); + Smilies::add($b, ':salt:', '🧂'); + Smilies::add($b, ':canned food:', '🥫'); // food-asian - Smilies::add($b, ':bento box:', '🍱'); - Smilies::add($b, ':rice cracker:', '🍘'); - Smilies::add($b, ':rice ball:', '🍙'); - Smilies::add($b, ':cooked rice:', '🍚'); - Smilies::add($b, ':curry rice:', '🍛'); - Smilies::add($b, ':steaming bowl:', '🍜'); - Smilies::add($b, ':spaghetti:', '🍝'); - Smilies::add($b, ':roasted sweet potato:', '🍠'); - Smilies::add($b, ':oden:', '🍢'); - Smilies::add($b, ':sushi:', '🍣'); - Smilies::add($b, ':fried shrimp:', '🍤'); - Smilies::add($b, ':fish cake with swirl:', '🍥'); - Smilies::add($b, ':moon cake:', '🥮'); - Smilies::add($b, ':dango:', '🍡'); - Smilies::add($b, ':dumpling:', '🥟'); - Smilies::add($b, ':fortune cookie:', '🥠'); - Smilies::add($b, ':takeout box:', '🥡'); + Smilies::add($b, ':bento box:', '🍱'); + Smilies::add($b, ':rice cracker:', '🍘'); + Smilies::add($b, ':rice ball:', '🍙'); + Smilies::add($b, ':cooked rice:', '🍚'); + Smilies::add($b, ':curry rice:', '🍛'); + Smilies::add($b, ':steaming bowl:', '🍜'); + Smilies::add($b, ':spaghetti:', '🍝'); + Smilies::add($b, ':roasted sweet potato:', '🍠'); + Smilies::add($b, ':oden:', '🍢'); + Smilies::add($b, ':sushi:', '🍣'); + Smilies::add($b, ':fried shrimp:', '🍤'); + Smilies::add($b, ':fish cake with swirl:', '🍥'); + Smilies::add($b, ':moon cake:', '🥮'); + Smilies::add($b, ':dango:', '🍡'); + Smilies::add($b, ':dumpling:', '🥟'); + Smilies::add($b, ':fortune cookie:', '🥠'); + Smilies::add($b, ':takeout box:', '🥡'); // food-marine - Smilies::add($b, ':crab:', '🦀'); - Smilies::add($b, ':lobster:', '🦞'); - Smilies::add($b, ':shrimp:', '🦐'); - Smilies::add($b, ':squid:', '🦑'); -// Smilies::add($b, ':oyster:', '🦪'); + Smilies::add($b, ':crab:', '🦀'); + Smilies::add($b, ':lobster:', '🦞'); + Smilies::add($b, ':shrimp:', '🦐'); + Smilies::add($b, ':squid:', '🦑'); +// Smilies::add($b, ':oyster:', '🦪'); // food-sweet - Smilies::add($b, ':soft ice cream:', '🍦'); - Smilies::add($b, ':shaved ice:', '🍧'); - Smilies::add($b, ':ice cream:', '🍨'); - Smilies::add($b, ':doughnut:', '🍩'); - Smilies::add($b, ':cookie:', '🍪'); - Smilies::add($b, ':birthday cake:', '🎂'); - Smilies::add($b, ':shortcake:', '🍰'); + Smilies::add($b, ':soft ice cream:', '🍦'); + Smilies::add($b, ':shaved ice:', '🍧'); + Smilies::add($b, ':ice cream:', '🍨'); + Smilies::add($b, ':doughnut:', '🍩'); + Smilies::add($b, ':cookie:', '🍪'); + Smilies::add($b, ':birthday cake:', '🎂'); + Smilies::add($b, ':shortcake:', '🍰'); Smilies::add($b, ':cake:', '🍰'); - Smilies::add($b, ':cupcake:', '🧁'); - Smilies::add($b, ':pie:', '🥧'); - Smilies::add($b, ':chocolate bar:', '🍫'); - Smilies::add($b, ':candy:', '🍬'); - Smilies::add($b, ':lollipop:', '🍭'); - Smilies::add($b, ':custard:', '🍮'); - Smilies::add($b, ':honey pot:', '🍯'); + Smilies::add($b, ':cupcake:', '🧁'); + Smilies::add($b, ':pie:', '🥧'); + Smilies::add($b, ':chocolate bar:', '🍫'); + Smilies::add($b, ':candy:', '🍬'); + Smilies::add($b, ':lollipop:', '🍭'); + Smilies::add($b, ':custard:', '🍮'); + Smilies::add($b, ':honey pot:', '🍯'); -// drink - Smilies::add($b, ':baby bottle:', '🍼'); - Smilies::add($b, ':glass of milk:', '🥛'); - Smilies::add($b, ':hot beverage:', '☕'); +// drink + Smilies::add($b, ':baby bottle:', '🍼'); + Smilies::add($b, ':glass of milk:', '🥛'); + Smilies::add($b, ':hot beverage:', '☕'); Smilies::add($b, ':coffee:', '☕'); Smilies::add($b, ':tea:', '☕'); Smilies::add($b, ':tee:', '☕'); - Smilies::add($b, ':teacup without handle:', '🍵'); - Smilies::add($b, ':sake:', '🍶'); - Smilies::add($b, ':bottle with popping cork:', '🍾'); - Smilies::add($b, ':wine glass:', '🍷'); - Smilies::add($b, ':cocktail glass:', '🍸'); - Smilies::add($b, ':tropical drink:', '🍹'); - Smilies::add($b, ':beer mug:', '🍺'); + Smilies::add($b, ':teacup without handle:', '🍵'); + Smilies::add($b, ':sake:', '🍶'); + Smilies::add($b, ':bottle with popping cork:', '🍾'); + Smilies::add($b, ':wine glass:', '🍷'); + Smilies::add($b, ':cocktail glass:', '🍸'); + Smilies::add($b, ':tropical drink:', '🍹'); + Smilies::add($b, ':beer mug:', '🍺'); Smilies::add($b, ':beer:', '🍺'); Smilies::add($b, ':homebrew:', '🍺'); - Smilies::add($b, ':clinking beer mugs:', '🍻'); - Smilies::add($b, ':clinking glasses:', '🥂'); - Smilies::add($b, ':tumbler glass:', '🥃'); - Smilies::add($b, ':cup with straw:', '🥤'); -// Smilies::add($b, ':beverage box:', '🧃'); - Smilies::add($b, ':mate:', '🧉'); - Smilies::add($b, ':ice:', '🧊'); + Smilies::add($b, ':clinking beer mugs:', '🍻'); + Smilies::add($b, ':clinking glasses:', '🥂'); + Smilies::add($b, ':tumbler glass:', '🥃'); + Smilies::add($b, ':cup with straw:', '🥤'); +// Smilies::add($b, ':beverage box:', '🧃'); + Smilies::add($b, ':mate:', '🧉'); + Smilies::add($b, ':ice:', '🧊'); // dishware - Smilies::add($b, ':chopsticks:', '🥢'); - Smilies::add($b, ':fork and knife with plate:', '🍽'); - Smilies::add($b, ':fork and knife:', '🍴'); - Smilies::add($b, ':spoon:', '🥄'); - Smilies::add($b, ':kitchen knife:', '🔪'); - Smilies::add($b, ':amphora:', '🏺'); + Smilies::add($b, ':chopsticks:', '🥢'); + Smilies::add($b, ':fork and knife with plate:', '🍽'); + Smilies::add($b, ':fork and knife:', '🍴'); + Smilies::add($b, ':spoon:', '🥄'); + Smilies::add($b, ':kitchen knife:', '🔪'); + Smilies::add($b, ':amphora:', '🏺'); // Travel & Places // place-map - Smilies::add($b, ':globe showing Europe-Africa:', '🌍'); - Smilies::add($b, ':globe showing Americas:', '🌎'); - Smilies::add($b, ':globe showing Asia-Australia:', '🌏'); - Smilies::add($b, ':globe with meridians:', '🌐'); - Smilies::add($b, ':world map:', '🗺'); - Smilies::add($b, ':map of Japan:', '🗾'); - Smilies::add($b, ':compass:', '🧭'); + Smilies::add($b, ':globe showing Europe-Africa:', '🌍'); + Smilies::add($b, ':globe showing Americas:', '🌎'); + Smilies::add($b, ':globe showing Asia-Australia:', '🌏'); + Smilies::add($b, ':globe with meridians:', '🌐'); + Smilies::add($b, ':world map:', '🗺'); + Smilies::add($b, ':map of Japan:', '🗾'); + Smilies::add($b, ':compass:', '🧭'); // place-geographic - Smilies::add($b, ':snow-capped mountain:', '🏔'); - Smilies::add($b, ':mountain:', '⛰'); - Smilies::add($b, ':volcano:', '🌋'); - Smilies::add($b, ':mount fuji:', '🗻'); - Smilies::add($b, ':camping:', '🏕'); - Smilies::add($b, ':beach with umbrella:', '🏖'); - Smilies::add($b, ':desert:', '🏜'); - Smilies::add($b, ':desert island:', '🏝'); - Smilies::add($b, ':national park:', '🏞'); + Smilies::add($b, ':snow-capped mountain:', '🏔'); + Smilies::add($b, ':mountain:', '⛰'); + Smilies::add($b, ':volcano:', '🌋'); + Smilies::add($b, ':mount fuji:', '🗻'); + Smilies::add($b, ':camping:', '🏕'); + Smilies::add($b, ':beach with umbrella:', '🏖'); + Smilies::add($b, ':desert:', '🏜'); + Smilies::add($b, ':desert island:', '🏝'); + Smilies::add($b, ':national park:', '🏞'); // place-building - Smilies::add($b, ':stadium:', '🏟'); - Smilies::add($b, ':classical building:', '🏛'); - Smilies::add($b, ':building construction:', '🏗'); - Smilies::add($b, ':brick:', '🧱'); - Smilies::add($b, ':houses:', '🏘'); - Smilies::add($b, ':derelict house:', '🏚'); - Smilies::add($b, ':house:', '🏠'); - Smilies::add($b, ':house with garden:', '🏡'); - Smilies::add($b, ':office building:', '🏢'); - Smilies::add($b, ':Japanese post office:', '🏣'); - Smilies::add($b, ':post office:', '🏤'); - Smilies::add($b, ':hospital:', '🏥'); - Smilies::add($b, ':bank:', '🏦'); - Smilies::add($b, ':hotel:', '🏨'); - Smilies::add($b, ':love hotel:', '🏩'); - Smilies::add($b, ':convenience store:', '🏪'); - Smilies::add($b, ':school:', '🏫'); - Smilies::add($b, ':department store:', '🏬'); - Smilies::add($b, ':factory:', '🏭'); - Smilies::add($b, ':Japanese castle:', '🏯'); - Smilies::add($b, ':castle:', '🏰'); - Smilies::add($b, ':wedding:', '💒'); - Smilies::add($b, ':Tokyo tower:', '🗼'); - Smilies::add($b, ':Statue of Liberty:', '🗽'); - + Smilies::add($b, ':stadium:', '🏟'); + Smilies::add($b, ':classical building:', '🏛'); + Smilies::add($b, ':building construction:', '🏗'); + Smilies::add($b, ':brick:', '🧱'); + Smilies::add($b, ':houses:', '🏘'); + Smilies::add($b, ':derelict house:', '🏚'); + Smilies::add($b, ':house:', '🏠'); + Smilies::add($b, ':house with garden:', '🏡'); + Smilies::add($b, ':office building:', '🏢'); + Smilies::add($b, ':Japanese post office:', '🏣'); + Smilies::add($b, ':post office:', '🏤'); + Smilies::add($b, ':hospital:', '🏥'); + Smilies::add($b, ':bank:', '🏦'); + Smilies::add($b, ':hotel:', '🏨'); + Smilies::add($b, ':love hotel:', '🏩'); + Smilies::add($b, ':convenience store:', '🏪'); + Smilies::add($b, ':school:', '🏫'); + Smilies::add($b, ':department store:', '🏬'); + Smilies::add($b, ':factory:', '🏭'); + Smilies::add($b, ':Japanese castle:', '🏯'); + Smilies::add($b, ':castle:', '🏰'); + Smilies::add($b, ':wedding:', '💒'); + Smilies::add($b, ':Tokyo tower:', '🗼'); + Smilies::add($b, ':Statue of Liberty:', '🗽'); // place-religious - Smilies::add($b, ':church:', '⛪'); - Smilies::add($b, ':mosque:', '🕌'); -// Smilies::add($b, ':hindu temple:', '🛕'); - Smilies::add($b, ':synagogue:', '🕍'); - Smilies::add($b, ':shinto shrine:', '⛩'); - Smilies::add($b, ':kaaba:', '🕋'); + Smilies::add($b, ':church:', '⛪'); + Smilies::add($b, ':mosque:', '🕌'); +// Smilies::add($b, ':hindu temple:', '🛕'); + Smilies::add($b, ':synagogue:', '🕍'); + Smilies::add($b, ':shinto shrine:', '⛩'); + Smilies::add($b, ':kaaba:', '🕋'); // place-other - Smilies::add($b, ':fountain:', '⛲'); - Smilies::add($b, ':tent:', '⛺'); - Smilies::add($b, ':foggy:', '🌁'); - Smilies::add($b, ':night with stars:', '🌃'); - Smilies::add($b, ':cityscape:', '🏙'); - Smilies::add($b, ':sunrise over mountains:', '🌄'); - Smilies::add($b, ':sunrise:', '🌅'); - Smilies::add($b, ':cityscape at dusk:', '🌆'); - Smilies::add($b, ':sunset:', '🌇'); - Smilies::add($b, ':bridge at night:', '🌉'); - Smilies::add($b, ':hot springs:', '♨'); - Smilies::add($b, ':carousel horse:', '🎠'); - Smilies::add($b, ':ferris wheel:', '🎡'); - Smilies::add($b, ':roller coaster:', '🎢'); - Smilies::add($b, ':barber pole:', '💈'); - Smilies::add($b, ':circus tent:', '🎪'); + Smilies::add($b, ':fountain:', '⛲'); + Smilies::add($b, ':tent:', '⛺'); + Smilies::add($b, ':foggy:', '🌁'); + Smilies::add($b, ':night with stars:', '🌃'); + Smilies::add($b, ':cityscape:', '🏙'); + Smilies::add($b, ':sunrise over mountains:', '🌄'); + Smilies::add($b, ':sunrise:', '🌅'); + Smilies::add($b, ':cityscape at dusk:', '🌆'); + Smilies::add($b, ':sunset:', '🌇'); + Smilies::add($b, ':bridge at night:', '🌉'); + Smilies::add($b, ':hot springs:', '♨'); + Smilies::add($b, ':carousel horse:', '🎠'); + Smilies::add($b, ':ferris wheel:', '🎡'); + Smilies::add($b, ':roller coaster:', '🎢'); + Smilies::add($b, ':barber pole:', '💈'); + Smilies::add($b, ':circus tent:', '🎪'); // transport-ground - Smilies::add($b, ':locomotive:', '🚂'); - Smilies::add($b, ':railway car:', '🚃'); - Smilies::add($b, ':high-speed train:', '🚄'); - Smilies::add($b, ':bullet train:', '🚅'); - Smilies::add($b, ':train:', '🚆'); - Smilies::add($b, ':metro:', '🚇'); - Smilies::add($b, ':light rail:', '🚈'); - Smilies::add($b, ':station:', '🚉'); - Smilies::add($b, ':tram:', '🚊'); - Smilies::add($b, ':monorail:', '🚝'); - Smilies::add($b, ':mountain railway:', '🚞'); - Smilies::add($b, ':tram car:', '🚋'); - Smilies::add($b, ':bus:', '🚌'); - Smilies::add($b, ':oncoming bus:', '🚍'); - Smilies::add($b, ':trolleybus:', '🚎'); - Smilies::add($b, ':minibus:', '🚐'); - Smilies::add($b, ':ambulance:', '🚑'); - Smilies::add($b, ':fire engine:', '🚒'); - Smilies::add($b, ':police car:', '🚓'); - Smilies::add($b, ':oncoming police car:', '🚔'); - Smilies::add($b, ':taxi:', '🚕'); - Smilies::add($b, ':oncoming taxi:', '🚖'); - Smilies::add($b, ':automobile:', '🚗'); - Smilies::add($b, ':oncoming automobile:', '🚘'); - Smilies::add($b, ':sport utility vehicle:', '🚙'); - Smilies::add($b, ':delivery truck:', '🚚'); - Smilies::add($b, ':articulated lorry:', '🚛'); - Smilies::add($b, ':tractor:', '🚜'); - Smilies::add($b, ':racing car:', '🏎'); - Smilies::add($b, ':motorcycle:', '🏍'); - Smilies::add($b, ':motor scooter:', '🛵'); -// Smilies::add($b, ':manual wheelchair:', '🦽'); -// Smilies::add($b, ':motorized wheelchair:', '🦼'); -// Smilies::add($b, ':auto rickshaw:', '🛺'); - Smilies::add($b, ':bicycle:', '🚲'); - Smilies::add($b, ':kick scooter:', '🛴'); - Smilies::add($b, ':skateboard:', '🛹'); - Smilies::add($b, ':bus stop:', '🚏'); - Smilies::add($b, ':motorway:', '🛣'); - Smilies::add($b, ':railway track:', '🛤'); - Smilies::add($b, ':oil drum:', '🛢'); - Smilies::add($b, ':fuel pump:', '⛽'); - Smilies::add($b, ':police car light:', '🚨'); - Smilies::add($b, ':horizontal traffic light:', '🚥'); - Smilies::add($b, ':vertical traffic light:', '🚦'); - Smilies::add($b, ':stop sign:', '🛑'); - Smilies::add($b, ':construction:', '🚧'); + Smilies::add($b, ':locomotive:', '🚂'); + Smilies::add($b, ':railway car:', '🚃'); + Smilies::add($b, ':high-speed train:', '🚄'); + Smilies::add($b, ':bullet train:', '🚅'); + Smilies::add($b, ':train:', '🚆'); + Smilies::add($b, ':metro:', '🚇'); + Smilies::add($b, ':light rail:', '🚈'); + Smilies::add($b, ':station:', '🚉'); + Smilies::add($b, ':tram:', '🚊'); + Smilies::add($b, ':monorail:', '🚝'); + Smilies::add($b, ':mountain railway:', '🚞'); + Smilies::add($b, ':tram car:', '🚋'); + Smilies::add($b, ':bus:', '🚌'); + Smilies::add($b, ':oncoming bus:', '🚍'); + Smilies::add($b, ':trolleybus:', '🚎'); + Smilies::add($b, ':minibus:', '🚐'); + Smilies::add($b, ':ambulance:', '🚑'); + Smilies::add($b, ':fire engine:', '🚒'); + Smilies::add($b, ':police car:', '🚓'); + Smilies::add($b, ':oncoming police car:', '🚔'); + Smilies::add($b, ':taxi:', '🚕'); + Smilies::add($b, ':oncoming taxi:', '🚖'); + Smilies::add($b, ':automobile:', '🚗'); + Smilies::add($b, ':oncoming automobile:', '🚘'); + Smilies::add($b, ':sport utility vehicle:', '🚙'); + Smilies::add($b, ':delivery truck:', '🚚'); + Smilies::add($b, ':articulated lorry:', '🚛'); + Smilies::add($b, ':tractor:', '🚜'); + Smilies::add($b, ':racing car:', '🏎'); + Smilies::add($b, ':motorcycle:', '🏍'); + Smilies::add($b, ':motor scooter:', '🛵'); +// Smilies::add($b, ':manual wheelchair:', '🦽'); +// Smilies::add($b, ':motorized wheelchair:', '🦼'); +// Smilies::add($b, ':auto rickshaw:', '🛺'); + Smilies::add($b, ':bicycle:', '🚲'); + Smilies::add($b, ':kick scooter:', '🛴'); + Smilies::add($b, ':skateboard:', '🛹'); + Smilies::add($b, ':bus stop:', '🚏'); + Smilies::add($b, ':motorway:', '🛣'); + Smilies::add($b, ':railway track:', '🛤'); + Smilies::add($b, ':oil drum:', '🛢'); + Smilies::add($b, ':fuel pump:', '⛽'); + Smilies::add($b, ':police car light:', '🚨'); + Smilies::add($b, ':horizontal traffic light:', '🚥'); + Smilies::add($b, ':vertical traffic light:', '🚦'); + Smilies::add($b, ':stop sign:', '🛑'); + Smilies::add($b, ':construction:', '🚧'); // transport-water - Smilies::add($b, ':anchor:', '⚓'); - Smilies::add($b, ':sailboat:', '⛵'); - Smilies::add($b, ':canoe:', '🛶'); - Smilies::add($b, ':speedboat:', '🚤'); - Smilies::add($b, ':passenger ship:', '🛳'); - Smilies::add($b, ':ferry:', '⛴'); - Smilies::add($b, ':motor boat:', '🛥'); - Smilies::add($b, ':ship:', '🚢'); + Smilies::add($b, ':anchor:', '⚓'); + Smilies::add($b, ':sailboat:', '⛵'); + Smilies::add($b, ':canoe:', '🛶'); + Smilies::add($b, ':speedboat:', '🚤'); + Smilies::add($b, ':passenger ship:', '🛳'); + Smilies::add($b, ':ferry:', '⛴'); + Smilies::add($b, ':motor boat:', '🛥'); + Smilies::add($b, ':ship:', '🚢'); // transport-air - Smilies::add($b, ':airplane:', '✈'); - Smilies::add($b, ':small airplane:', '🛩'); - Smilies::add($b, ':airplane departure:', '🛫'); - Smilies::add($b, ':airplane arrival:', '🛬'); - Smilies::add($b, ':parachute:', '🪂'); - Smilies::add($b, ':seat:', '💺'); - Smilies::add($b, ':helicopter:', '🚁'); - Smilies::add($b, ':suspension railway:', '🚟'); - Smilies::add($b, ':mountain cableway:', '🚠'); - Smilies::add($b, ':aerial tramway:', '🚡'); - Smilies::add($b, ':satellite:', '🛰'); - Smilies::add($b, ':rocket:', '🚀'); - Smilies::add($b, ':flying saucer:', '🛸'); + Smilies::add($b, ':airplane:', '✈'); + Smilies::add($b, ':small airplane:', '🛩'); + Smilies::add($b, ':airplane departure:', '🛫'); + Smilies::add($b, ':airplane arrival:', '🛬'); + Smilies::add($b, ':parachute:', '🪂'); + Smilies::add($b, ':seat:', '💺'); + Smilies::add($b, ':helicopter:', '🚁'); + Smilies::add($b, ':suspension railway:', '🚟'); + Smilies::add($b, ':mountain cableway:', '🚠'); + Smilies::add($b, ':aerial tramway:', '🚡'); + Smilies::add($b, ':satellite:', '🛰'); + Smilies::add($b, ':rocket:', '🚀'); + Smilies::add($b, ':flying saucer:', '🛸'); // hotel - Smilies::add($b, ':bellhop bell:', '🛎'); - Smilies::add($b, ':luggage:', '🧳'); + Smilies::add($b, ':bellhop bell:', '🛎'); + Smilies::add($b, ':luggage:', '🧳'); // time - Smilies::add($b, ':hourglass done:', '⌛'); - Smilies::add($b, ':hourglass not done:', '⏳'); - Smilies::add($b, ':watch:', '⌚'); - Smilies::add($b, ':alarm clock:', '⏰'); - Smilies::add($b, ':stopwatch:', '⏱'); - Smilies::add($b, ':timer clock:', '⏲'); - Smilies::add($b, ':mantelpiece clock:', '🕰'); - Smilies::add($b, ':twelve o’clock:', '🕛'); - Smilies::add($b, ':twelve-thirty:', '🕧'); - Smilies::add($b, ':one o’clock:', '🕐'); - Smilies::add($b, ':one-thirty:', '🕜'); - Smilies::add($b, ':two o’clock:', '🕑'); - Smilies::add($b, ':two-thirty:', '🕝'); - Smilies::add($b, ':three o’clock:', '🕒'); - Smilies::add($b, ':three-thirty:', '🕞'); - Smilies::add($b, ':four o’clock:', '🕓'); - Smilies::add($b, ':four-thirty:', '🕟'); - Smilies::add($b, ':five o’clock:', '🕔'); - Smilies::add($b, ':five-thirty:', '🕠'); - Smilies::add($b, ':six o’clock:', '🕕'); - Smilies::add($b, ':six-thirty:', '🕡'); - Smilies::add($b, ':seven o’clock:', '🕖'); - Smilies::add($b, ':seven-thirty:', '🕢'); - Smilies::add($b, ':eight o’clock:', '🕗'); - Smilies::add($b, ':eight-thirty:', '🕣'); - Smilies::add($b, ':nine o’clock:', '🕘'); - Smilies::add($b, ':nine-thirty:', '🕤'); - Smilies::add($b, ':ten o’clock:', '🕙'); - Smilies::add($b, ':ten-thirty:', '🕥'); - Smilies::add($b, ':eleven o’clock:', '🕚'); - Smilies::add($b, ':eleven-thirty:', '🕦'); + Smilies::add($b, ':hourglass done:', '⌛'); + Smilies::add($b, ':hourglass not done:', '⏳'); + Smilies::add($b, ':watch:', '⌚'); + Smilies::add($b, ':alarm clock:', '⏰'); + Smilies::add($b, ':stopwatch:', '⏱'); + Smilies::add($b, ':timer clock:', '⏲'); + Smilies::add($b, ':mantelpiece clock:', '🕰'); + Smilies::add($b, ':twelve o’clock:', '🕛'); + Smilies::add($b, ':twelve-thirty:', '🕧'); + Smilies::add($b, ':one o’clock:', '🕐'); + Smilies::add($b, ':one-thirty:', '🕜'); + Smilies::add($b, ':two o’clock:', '🕑'); + Smilies::add($b, ':two-thirty:', '🕝'); + Smilies::add($b, ':three o’clock:', '🕒'); + Smilies::add($b, ':three-thirty:', '🕞'); + Smilies::add($b, ':four o’clock:', '🕓'); + Smilies::add($b, ':four-thirty:', '🕟'); + Smilies::add($b, ':five o’clock:', '🕔'); + Smilies::add($b, ':five-thirty:', '🕠'); + Smilies::add($b, ':six o’clock:', '🕕'); + Smilies::add($b, ':six-thirty:', '🕡'); + Smilies::add($b, ':seven o’clock:', '🕖'); + Smilies::add($b, ':seven-thirty:', '🕢'); + Smilies::add($b, ':eight o’clock:', '🕗'); + Smilies::add($b, ':eight-thirty:', '🕣'); + Smilies::add($b, ':nine o’clock:', '🕘'); + Smilies::add($b, ':nine-thirty:', '🕤'); + Smilies::add($b, ':ten o’clock:', '🕙'); + Smilies::add($b, ':ten-thirty:', '🕥'); + Smilies::add($b, ':eleven o’clock:', '🕚'); + Smilies::add($b, ':eleven-thirty:', '🕦'); // sky & weather - Smilies::add($b, ':new moon:', '🌑'); - Smilies::add($b, ':waxing crescent moon:', '🌒'); - Smilies::add($b, ':first quarter moon:', '🌓'); - Smilies::add($b, ':waxing gibbous moon:', '🌔'); - Smilies::add($b, ':full moon:', '🌕'); - Smilies::add($b, ':waning gibbous moon:', '🌖'); - Smilies::add($b, ':last quarter moon:', '🌗'); - Smilies::add($b, ':waning crescent moon:', '🌘'); - Smilies::add($b, ':crescent moon:', '🌙'); - Smilies::add($b, ':new moon face:', '🌚'); - Smilies::add($b, ':first quarter moon face:', '🌛'); - Smilies::add($b, ':last quarter moon face:', '🌜'); - Smilies::add($b, ':thermometer:', '🌡'); - Smilies::add($b, ':sun:', '☀'); - Smilies::add($b, ':full moon face:', '🌝'); - Smilies::add($b, ':sun with face:', '🌞'); - Smilies::add($b, ':ringed planet:', '🪐'); - Smilies::add($b, ':star:', '⭐'); - Smilies::add($b, ':glowing star:', '🌟'); - Smilies::add($b, ':shooting star:', '🌠'); - Smilies::add($b, ':milky way:', '🌌'); - Smilies::add($b, ':cloud:', '☁'); - Smilies::add($b, ':sun behind cloud:', '⛅'); - Smilies::add($b, ':cloud with lightning and rain:', '⛈'); - Smilies::add($b, ':sun behind small cloud:', '🌤'); - Smilies::add($b, ':sun behind large cloud:', '🌥'); - Smilies::add($b, ':sun behind rain cloud:', '🌦'); - Smilies::add($b, ':cloud with rain:', '🌧'); - Smilies::add($b, ':cloud with snow:', '🌨'); - Smilies::add($b, ':cloud with lightning:', '🌩'); - Smilies::add($b, ':tornado:', '🌪'); - Smilies::add($b, ':fog:', '🌫'); - Smilies::add($b, ':wind face:', '🌬'); - Smilies::add($b, ':cyclone:', '🌀'); - Smilies::add($b, ':rainbow:', '🌈'); - Smilies::add($b, ':closed umbrella:', '🌂'); - Smilies::add($b, ':umbrella:', '☂'); - Smilies::add($b, ':umbrella with rain drops:', '☔'); - Smilies::add($b, ':umbrella on ground:', '⛱'); - Smilies::add($b, ':high voltage:', '⚡'); - Smilies::add($b, ':snowflake:', '❄'); - Smilies::add($b, ':snowman:', '☃'); - Smilies::add($b, ':snowman without snow:', '⛄'); - Smilies::add($b, ':comet:', '☄'); - Smilies::add($b, ':fire:', '🔥'); - Smilies::add($b, ':droplet:', '💧'); - Smilies::add($b, ':water wave:', '🌊'); + Smilies::add($b, ':new moon:', '🌑'); + Smilies::add($b, ':waxing crescent moon:', '🌒'); + Smilies::add($b, ':first quarter moon:', '🌓'); + Smilies::add($b, ':waxing gibbous moon:', '🌔'); + Smilies::add($b, ':full moon:', '🌕'); + Smilies::add($b, ':waning gibbous moon:', '🌖'); + Smilies::add($b, ':last quarter moon:', '🌗'); + Smilies::add($b, ':waning crescent moon:', '🌘'); + Smilies::add($b, ':crescent moon:', '🌙'); + Smilies::add($b, ':new moon face:', '🌚'); + Smilies::add($b, ':first quarter moon face:', '🌛'); + Smilies::add($b, ':last quarter moon face:', '🌜'); + Smilies::add($b, ':thermometer:', '🌡'); + Smilies::add($b, ':sun:', '☀'); + Smilies::add($b, ':full moon face:', '🌝'); + Smilies::add($b, ':sun with face:', '🌞'); + Smilies::add($b, ':ringed planet:', '🪐'); + Smilies::add($b, ':star:', '⭐'); + Smilies::add($b, ':glowing star:', '🌟'); + Smilies::add($b, ':shooting star:', '🌠'); + Smilies::add($b, ':milky way:', '🌌'); + Smilies::add($b, ':cloud:', '☁'); + Smilies::add($b, ':sun behind cloud:', '⛅'); + Smilies::add($b, ':cloud with lightning and rain:', '⛈'); + Smilies::add($b, ':sun behind small cloud:', '🌤'); + Smilies::add($b, ':sun behind large cloud:', '🌥'); + Smilies::add($b, ':sun behind rain cloud:', '🌦'); + Smilies::add($b, ':cloud with rain:', '🌧'); + Smilies::add($b, ':cloud with snow:', '🌨'); + Smilies::add($b, ':cloud with lightning:', '🌩'); + Smilies::add($b, ':tornado:', '🌪'); + Smilies::add($b, ':fog:', '🌫'); + Smilies::add($b, ':wind face:', '🌬'); + Smilies::add($b, ':cyclone:', '🌀'); + Smilies::add($b, ':rainbow:', '🌈'); + Smilies::add($b, ':closed umbrella:', '🌂'); + Smilies::add($b, ':umbrella:', '☂'); + Smilies::add($b, ':umbrella with rain drops:', '☔'); + Smilies::add($b, ':umbrella on ground:', '⛱'); + Smilies::add($b, ':high voltage:', '⚡'); + Smilies::add($b, ':snowflake:', '❄'); + Smilies::add($b, ':snowman:', '☃'); + Smilies::add($b, ':snowman without snow:', '⛄'); + Smilies::add($b, ':comet:', '☄'); + Smilies::add($b, ':fire:', '🔥'); + Smilies::add($b, ':droplet:', '💧'); + Smilies::add($b, ':water wave:', '🌊'); // Activities // event - Smilies::add($b, ':jack-o-lantern:', '🎃'); - Smilies::add($b, ':Christmas tree:', '🎄'); - Smilies::add($b, ':fireworks:', '🎆'); - Smilies::add($b, ':sparkler:', '🎇'); - Smilies::add($b, ':firecracker:', '🧨'); - Smilies::add($b, ':sparkles:', '✨'); - Smilies::add($b, ':balloon:', '🎈'); - Smilies::add($b, ':party popper:', '🎉'); - Smilies::add($b, ':confetti ball:', '🎊'); - Smilies::add($b, ':tanabata tree:', '🎋'); - Smilies::add($b, ':pine decoration:', '🎍'); - Smilies::add($b, ':Japanese dolls:', '🎎'); - Smilies::add($b, ':carp streamer:', '🎏'); - Smilies::add($b, ':wind chime:', '🎐'); - Smilies::add($b, ':moon viewing ceremony:', '🎑'); - Smilies::add($b, ':red envelope:', '🧧'); - Smilies::add($b, ':ribbon:', '🎀'); - Smilies::add($b, ':wrapped gift:', '🎁'); - Smilies::add($b, ':reminder ribbon:', '🎗'); - Smilies::add($b, ':admission tickets:', '🎟'); - Smilies::add($b, ':ticket:', '🎫'); + Smilies::add($b, ':jack-o-lantern:', '🎃'); + Smilies::add($b, ':Christmas tree:', '🎄'); + Smilies::add($b, ':fireworks:', '🎆'); + Smilies::add($b, ':sparkler:', '🎇'); + Smilies::add($b, ':firecracker:', '🧨'); + Smilies::add($b, ':sparkles:', '✨'); + Smilies::add($b, ':balloon:', '🎈'); + Smilies::add($b, ':party popper:', '🎉'); + Smilies::add($b, ':confetti ball:', '🎊'); + Smilies::add($b, ':tanabata tree:', '🎋'); + Smilies::add($b, ':pine decoration:', '🎍'); + Smilies::add($b, ':Japanese dolls:', '🎎'); + Smilies::add($b, ':carp streamer:', '🎏'); + Smilies::add($b, ':wind chime:', '🎐'); + Smilies::add($b, ':moon viewing ceremony:', '🎑'); + Smilies::add($b, ':red envelope:', '🧧'); + Smilies::add($b, ':ribbon:', '🎀'); + Smilies::add($b, ':wrapped gift:', '🎁'); + Smilies::add($b, ':reminder ribbon:', '🎗'); + Smilies::add($b, ':admission tickets:', '🎟'); + Smilies::add($b, ':ticket:', '🎫'); // award-medal - Smilies::add($b, ':military medal:', '🎖'); - Smilies::add($b, ':trophy:', '🏆'); - Smilies::add($b, ':sports medal:', '🏅'); - Smilies::add($b, ':1st place medal:', '🥇'); - Smilies::add($b, ':2nd place medal:', '🥈'); - Smilies::add($b, ':3rd place medal:', '🥉'); + Smilies::add($b, ':military medal:', '🎖'); + Smilies::add($b, ':trophy:', '🏆'); + Smilies::add($b, ':sports medal:', '🏅'); + Smilies::add($b, ':1st place medal:', '🥇'); + Smilies::add($b, ':2nd place medal:', '🥈'); + Smilies::add($b, ':3rd place medal:', '🥉'); // sport - Smilies::add($b, ':soccer ball:', '⚽'); - Smilies::add($b, ':baseball:', '⚾'); - Smilies::add($b, ':softball:', '🥎'); - Smilies::add($b, ':basketball:', '🏀'); - Smilies::add($b, ':volleyball:', '🏐'); - Smilies::add($b, ':american football:', '🏈'); + Smilies::add($b, ':soccer ball:', '⚽'); + Smilies::add($b, ':baseball:', '⚾'); + Smilies::add($b, ':softball:', '🥎'); + Smilies::add($b, ':basketball:', '🏀'); + Smilies::add($b, ':volleyball:', '🏐'); + Smilies::add($b, ':american football:', '🏈'); Smilies::add($b, ':football:', '🏈'); - Smilies::add($b, ':rugby football:', '🏉'); - Smilies::add($b, ':tennis:', '🎾'); - Smilies::add($b, ':flying disc:', '🥏'); - Smilies::add($b, ':bowling:', '🎳'); - Smilies::add($b, ':cricket game:', '🏏'); - Smilies::add($b, ':field hockey:', '🏑'); - Smilies::add($b, ':ice hockey:', '🏒'); - Smilies::add($b, ':lacrosse:', '🥍'); - Smilies::add($b, ':ping pong:', '🏓'); - Smilies::add($b, ':badminton:', '🏸'); - Smilies::add($b, ':boxing glove:', '🥊'); - Smilies::add($b, ':martial arts uniform:', '🥋'); - Smilies::add($b, ':goal net:', '🥅'); - Smilies::add($b, ':flag in hole:', '⛳'); - Smilies::add($b, ':ice skate:', '⛸'); - Smilies::add($b, ':fishing pole:', '🎣'); -// Smilies::add($b, ':diving mask:', '🤿'); - Smilies::add($b, ':running shirt:', '🎽'); - Smilies::add($b, ':skis:', '🎿'); - Smilies::add($b, ':sled:', '🛷'); - Smilies::add($b, ':curling stone:', '🥌'); + Smilies::add($b, ':rugby football:', '🏉'); + Smilies::add($b, ':tennis:', '🎾'); + Smilies::add($b, ':flying disc:', '🥏'); + Smilies::add($b, ':bowling:', '🎳'); + Smilies::add($b, ':cricket game:', '🏏'); + Smilies::add($b, ':field hockey:', '🏑'); + Smilies::add($b, ':ice hockey:', '🏒'); + Smilies::add($b, ':lacrosse:', '🥍'); + Smilies::add($b, ':ping pong:', '🏓'); + Smilies::add($b, ':badminton:', '🏸'); + Smilies::add($b, ':boxing glove:', '🥊'); + Smilies::add($b, ':martial arts uniform:', '🥋'); + Smilies::add($b, ':goal net:', '🥅'); + Smilies::add($b, ':flag in hole:', '⛳'); + Smilies::add($b, ':ice skate:', '⛸'); + Smilies::add($b, ':fishing pole:', '🎣'); +// Smilies::add($b, ':diving mask:', '🤿'); + Smilies::add($b, ':running shirt:', '🎽'); + Smilies::add($b, ':skis:', '🎿'); + Smilies::add($b, ':sled:', '🛷'); + Smilies::add($b, ':curling stone:', '🥌'); Smilies::add($b, ':cycling:', '🚴'); Smilies::add($b, ':darts:', '🎯'); Smilies::add($b, ':fencing:', '🤺'); Smilies::add($b, ':juggling:', '🤹'); -// Smilies::add($b, ':skipping:', '&#x;'); -// Smilies::add($b, ':archery:', '&#x;'); +// Smilies::add($b, ':skipping:', '&#x;'); +// Smilies::add($b, ':archery:', '&#x;'); Smilies::add($b, ':surfing:', '🏄'); Smilies::add($b, ':snooker:', '🎱'); Smilies::add($b, ':horseriding:', '🏇'); // game - Smilies::add($b, ':direct hit:', '🎯'); - Smilies::add($b, ':yo-yo:', '🪀'); - Smilies::add($b, ':kite:', '🪁'); - Smilies::add($b, ':pool 8 ball:', '🎱'); - Smilies::add($b, ':crystal ball:', '🔮'); - Smilies::add($b, ':nazar amulet:', '🧿'); - Smilies::add($b, ':video game:', '🎮'); - Smilies::add($b, ':joystick:', '🕹'); - Smilies::add($b, ':slot machine:', '🎰'); - Smilies::add($b, ':game die:', '🎲'); - Smilies::add($b, ':puzzle piece:', '🧩'); - Smilies::add($b, ':teddy bear:', '🧸'); - Smilies::add($b, ':spade suit:', '♠'); - Smilies::add($b, ':heart suit:', '♥'); - Smilies::add($b, ':diamond suit:', '♦'); - Smilies::add($b, ':club suit:', '♣'); - Smilies::add($b, ':chess pawn:', '♟'); - Smilies::add($b, ':joker:', '🃏'); - Smilies::add($b, ':mahjong red dragon:', '🀄'); - Smilies::add($b, ':flower playing cards:', '🎴'); + Smilies::add($b, ':direct hit:', '🎯'); + Smilies::add($b, ':yo-yo:', '🪀'); + Smilies::add($b, ':kite:', '🪁'); + Smilies::add($b, ':pool 8 ball:', '🎱'); + Smilies::add($b, ':crystal ball:', '🔮'); + Smilies::add($b, ':nazar amulet:', '🧿'); + Smilies::add($b, ':video game:', '🎮'); + Smilies::add($b, ':joystick:', '🕹'); + Smilies::add($b, ':slot machine:', '🎰'); + Smilies::add($b, ':game die:', '🎲'); + Smilies::add($b, ':puzzle piece:', '🧩'); + Smilies::add($b, ':teddy bear:', '🧸'); + Smilies::add($b, ':spade suit:', '♠'); + Smilies::add($b, ':heart suit:', '♥'); + Smilies::add($b, ':diamond suit:', '♦'); + Smilies::add($b, ':club suit:', '♣'); + Smilies::add($b, ':chess pawn:', '♟'); + Smilies::add($b, ':joker:', '🃏'); + Smilies::add($b, ':mahjong red dragon:', '🀄'); + Smilies::add($b, ':flower playing cards:', '🎴'); // arts & crafts - Smilies::add($b, ':performing arts:', '🎭'); - Smilies::add($b, ':framed picture:', '🖼'); - Smilies::add($b, ':artist palette:', '🎨'); - Smilies::add($b, ':thread:', '🧵'); - Smilies::add($b, ':yarn:', '🧶'); + Smilies::add($b, ':performing arts:', '🎭'); + Smilies::add($b, ':framed picture:', '🖼'); + Smilies::add($b, ':artist palette:', '🎨'); + Smilies::add($b, ':thread:', '🧵'); + Smilies::add($b, ':yarn:', '🧶'); // Objects // clothing - Smilies::add($b, ':glasses:', '👓'); - Smilies::add($b, ':sunglasses:', '🕶'); - Smilies::add($b, ':goggles:', '🥽'); - Smilies::add($b, ':lab coat:', '🥼'); - Smilies::add($b, ':safety vest:', '🦺'); - Smilies::add($b, ':necktie:', '👔'); - Smilies::add($b, ':t-shirt:', '👕'); - Smilies::add($b, ':jeans:', '👖'); - Smilies::add($b, ':scarf:', '🧣'); - Smilies::add($b, ':gloves:', '🧤'); - Smilies::add($b, ':coat:', '🧥'); - Smilies::add($b, ':socks:', '🧦'); - Smilies::add($b, ':dress:', '👗'); - Smilies::add($b, ':kimono:', '👘'); - Smilies::add($b, ':sari:', '🥻'); - Smilies::add($b, ':one-piece swimsuit:', '🩱'); - Smilies::add($b, ':briefs:', '🩲'); - Smilies::add($b, ':shorts:', '🩳'); - Smilies::add($b, ':bikini:', '👙'); - Smilies::add($b, ':woman’s clothes:', '👚'); - Smilies::add($b, ':purse:', '👛'); - Smilies::add($b, ':handbag:', '👜'); - Smilies::add($b, ':clutch bag:', '👝'); - Smilies::add($b, ':shopping bags:', '🛍'); - Smilies::add($b, ':backpack:', '🎒'); - Smilies::add($b, ':man’s shoe:', '👞'); - Smilies::add($b, ':running shoe:', '👟'); - Smilies::add($b, ':hiking boot:', '🥾'); - Smilies::add($b, ':flat shoe:', '🥿'); - Smilies::add($b, ':high-heeled shoe:', '👠'); - Smilies::add($b, ':woman’s sandal:', '👡'); -// Smilies::add($b, ':ballet shoes:', '🩰'); - Smilies::add($b, ':woman’s boot:', '👢'); - Smilies::add($b, ':crown:', '👑'); - Smilies::add($b, ':woman’s hat:', '👒'); - Smilies::add($b, ':top hat:', '🎩'); - Smilies::add($b, ':graduation cap:', '🎓'); - Smilies::add($b, ':billed cap:', '🧢'); - Smilies::add($b, ':rescue worker’s helmet:', '⛑'); - Smilies::add($b, ':prayer beads:', '📿'); - Smilies::add($b, ':lipstick:', '💄'); - Smilies::add($b, ':ring:', '💍'); - Smilies::add($b, ':gem stone:', '💎'); + Smilies::add($b, ':glasses:', '👓'); + Smilies::add($b, ':sunglasses:', '🕶'); + Smilies::add($b, ':goggles:', '🥽'); + Smilies::add($b, ':lab coat:', '🥼'); + Smilies::add($b, ':safety vest:', '🦺'); + Smilies::add($b, ':necktie:', '👔'); + Smilies::add($b, ':t-shirt:', '👕'); + Smilies::add($b, ':jeans:', '👖'); + Smilies::add($b, ':scarf:', '🧣'); + Smilies::add($b, ':gloves:', '🧤'); + Smilies::add($b, ':coat:', '🧥'); + Smilies::add($b, ':socks:', '🧦'); + Smilies::add($b, ':dress:', '👗'); + Smilies::add($b, ':kimono:', '👘'); + Smilies::add($b, ':sari:', '🥻'); + Smilies::add($b, ':one-piece swimsuit:', '🩱'); + Smilies::add($b, ':briefs:', '🩲'); + Smilies::add($b, ':shorts:', '🩳'); + Smilies::add($b, ':bikini:', '👙'); + Smilies::add($b, ':woman’s clothes:', '👚'); + Smilies::add($b, ':purse:', '👛'); + Smilies::add($b, ':handbag:', '👜'); + Smilies::add($b, ':clutch bag:', '👝'); + Smilies::add($b, ':shopping bags:', '🛍'); + Smilies::add($b, ':backpack:', '🎒'); + Smilies::add($b, ':man’s shoe:', '👞'); + Smilies::add($b, ':running shoe:', '👟'); + Smilies::add($b, ':hiking boot:', '🥾'); + Smilies::add($b, ':flat shoe:', '🥿'); + Smilies::add($b, ':high-heeled shoe:', '👠'); + Smilies::add($b, ':woman’s sandal:', '👡'); +// Smilies::add($b, ':ballet shoes:', '🩰'); + Smilies::add($b, ':woman’s boot:', '👢'); + Smilies::add($b, ':crown:', '👑'); + Smilies::add($b, ':woman’s hat:', '👒'); + Smilies::add($b, ':top hat:', '🎩'); + Smilies::add($b, ':graduation cap:', '🎓'); + Smilies::add($b, ':billed cap:', '🧢'); + Smilies::add($b, ':rescue worker’s helmet:', '⛑'); + Smilies::add($b, ':prayer beads:', '📿'); + Smilies::add($b, ':lipstick:', '💄'); + Smilies::add($b, ':ring:', '💍'); + Smilies::add($b, ':gem stone:', '💎'); // sound - Smilies::add($b, ':muted speaker:', '🔇'); - Smilies::add($b, ':speaker low volume:', '🔈'); - Smilies::add($b, ':speaker medium volume:', '🔉'); - Smilies::add($b, ':speaker high volume:', '🔊'); - Smilies::add($b, ':loudspeaker:', '📢'); - Smilies::add($b, ':megaphone:', '📣'); - Smilies::add($b, ':postal horn:', '📯'); - Smilies::add($b, ':bell:', '🔔'); - Smilies::add($b, ':bell with slash:', '🔕'); + Smilies::add($b, ':muted speaker:', '🔇'); + Smilies::add($b, ':speaker low volume:', '🔈'); + Smilies::add($b, ':speaker medium volume:', '🔉'); + Smilies::add($b, ':speaker high volume:', '🔊'); + Smilies::add($b, ':loudspeaker:', '📢'); + Smilies::add($b, ':megaphone:', '📣'); + Smilies::add($b, ':postal horn:', '📯'); + Smilies::add($b, ':bell:', '🔔'); + Smilies::add($b, ':bell with slash:', '🔕'); // musik - Smilies::add($b, ':musical score:', '🎼'); - Smilies::add($b, ':musical note:', '🎵'); - Smilies::add($b, ':musical notes:', '🎶'); - Smilies::add($b, ':studio microphone:', '🎙'); - Smilies::add($b, ':level slider:', '🎚'); - Smilies::add($b, ':control knobs:', '🎛'); - Smilies::add($b, ':microphone:', '🎤'); - Smilies::add($b, ':headphone:', '🎧'); - Smilies::add($b, ':radio:', '📻'); + Smilies::add($b, ':musical score:', '🎼'); + Smilies::add($b, ':musical note:', '🎵'); + Smilies::add($b, ':musical notes:', '🎶'); + Smilies::add($b, ':studio microphone:', '🎙'); + Smilies::add($b, ':level slider:', '🎚'); + Smilies::add($b, ':control knobs:', '🎛'); + Smilies::add($b, ':microphone:', '🎤'); + Smilies::add($b, ':headphone:', '🎧'); + Smilies::add($b, ':radio:', '📻'); // musical-instrument - Smilies::add($b, ':saxophone:', '🎷'); - Smilies::add($b, ':guitar:', '🎸'); - Smilies::add($b, ':musical keyboard:', '🎹'); - Smilies::add($b, ':trumpet:', '🎺'); - Smilies::add($b, ':violin:', '🎻'); -// Smilies::add($b, ':banjo:', '🪕'); - Smilies::add($b, ':drum:', '🥁'); + Smilies::add($b, ':saxophone:', '🎷'); + Smilies::add($b, ':guitar:', '🎸'); + Smilies::add($b, ':musical keyboard:', '🎹'); + Smilies::add($b, ':trumpet:', '🎺'); + Smilies::add($b, ':violin:', '🎻'); +// Smilies::add($b, ':banjo:', '🪕'); + Smilies::add($b, ':drum:', '🥁'); // phone - Smilies::add($b, ':mobile phone:', '📱'); - Smilies::add($b, ':mobile phone with arrow:', '📲'); - Smilies::add($b, ':telephone:', '☎'); - Smilies::add($b, ':telephone receiver:', '📞'); - Smilies::add($b, ':pager:', '📟'); - Smilies::add($b, ':fax machine:', '📠'); + Smilies::add($b, ':mobile phone:', '📱'); + Smilies::add($b, ':mobile phone with arrow:', '📲'); + Smilies::add($b, ':telephone:', '☎'); + Smilies::add($b, ':telephone receiver:', '📞'); + Smilies::add($b, ':pager:', '📟'); + Smilies::add($b, ':fax machine:', '📠'); // computer - Smilies::add($b, ':battery:', '🔋'); - Smilies::add($b, ':electric plug:', '🔌'); - Smilies::add($b, ':laptop:', '💻'); - Smilies::add($b, ':desktop computer:', '🖥'); - Smilies::add($b, ':printer:', '🖨'); - Smilies::add($b, ':keyboard:', '⌨'); - Smilies::add($b, ':computer mouse:', '🖱'); - Smilies::add($b, ':trackball:', '🖲'); - Smilies::add($b, ':computer disk:', '💽'); - Smilies::add($b, ':floppy disk:', '💾'); - Smilies::add($b, ':optical disk:', '💿'); - Smilies::add($b, ':dvd:', '📀'); - Smilies::add($b, ':abacus:', '🧮'); + Smilies::add($b, ':battery:', '🔋'); + Smilies::add($b, ':electric plug:', '🔌'); + Smilies::add($b, ':laptop:', '💻'); + Smilies::add($b, ':desktop computer:', '🖥'); + Smilies::add($b, ':printer:', '🖨'); + Smilies::add($b, ':keyboard:', '⌨'); + Smilies::add($b, ':computer mouse:', '🖱'); + Smilies::add($b, ':trackball:', '🖲'); + Smilies::add($b, ':computer disk:', '💽'); + Smilies::add($b, ':floppy disk:', '💾'); + Smilies::add($b, ':optical disk:', '💿'); + Smilies::add($b, ':dvd:', '📀'); + Smilies::add($b, ':abacus:', '🧮'); // light & video - Smilies::add($b, ':movie camera:', '🎥'); - Smilies::add($b, ':film frames:', '🎞'); - Smilies::add($b, ':film projector:', '📽'); - Smilies::add($b, ':clapper board:', '🎬'); - Smilies::add($b, ':television:', '📺'); - Smilies::add($b, ':camera:', '📷'); - Smilies::add($b, ':camera with flash:', '📸'); - Smilies::add($b, ':video camera:', '📹'); - Smilies::add($b, ':videocassette:', '📼'); - Smilies::add($b, ':magnifying glass tilted left:', '🔍'); - Smilies::add($b, ':magnifying glass tilted right:', '🔎'); - Smilies::add($b, ':candle:', '🕯'); - Smilies::add($b, ':light bulb:', '💡'); - Smilies::add($b, ':flashlight:', '🔦'); - Smilies::add($b, ':red paper lantern:', '🏮'); -// Smilies::add($b, ':diya lamp:', '🪔'); + Smilies::add($b, ':movie camera:', '🎥'); + Smilies::add($b, ':film frames:', '🎞'); + Smilies::add($b, ':film projector:', '📽'); + Smilies::add($b, ':clapper board:', '🎬'); + Smilies::add($b, ':television:', '📺'); + Smilies::add($b, ':camera:', '📷'); + Smilies::add($b, ':camera with flash:', '📸'); + Smilies::add($b, ':video camera:', '📹'); + Smilies::add($b, ':videocassette:', '📼'); + Smilies::add($b, ':magnifying glass tilted left:', '🔍'); + Smilies::add($b, ':magnifying glass tilted right:', '🔎'); + Smilies::add($b, ':candle:', '🕯'); + Smilies::add($b, ':light bulb:', '💡'); + Smilies::add($b, ':flashlight:', '🔦'); + Smilies::add($b, ':red paper lantern:', '🏮'); +// Smilies::add($b, ':diya lamp:', '🪔'); // book-paper - Smilies::add($b, ':notebook with decorative cover:', '📔'); - Smilies::add($b, ':closed book:', '📕'); - Smilies::add($b, ':open book:', '📖'); - Smilies::add($b, ':green book:', '📗'); - Smilies::add($b, ':blue book:', '📘'); - Smilies::add($b, ':orange book:', '📙'); - Smilies::add($b, ':books:', '📚'); - Smilies::add($b, ':notebook:', '📓'); - Smilies::add($b, ':ledger:', '📒'); - Smilies::add($b, ':page with curl:', '📃'); - Smilies::add($b, ':scroll:', '📜'); - Smilies::add($b, ':page facing up:', '📄'); - Smilies::add($b, ':newspaper:', '📰'); - Smilies::add($b, ':rolled-up newspaper:', '🗞'); - Smilies::add($b, ':bookmark tabs:', '📑'); - Smilies::add($b, ':bookmark:', '🔖'); - Smilies::add($b, ':label:', '🏷'); + Smilies::add($b, ':notebook with decorative cover:', '📔'); + Smilies::add($b, ':closed book:', '📕'); + Smilies::add($b, ':open book:', '📖'); + Smilies::add($b, ':green book:', '📗'); + Smilies::add($b, ':blue book:', '📘'); + Smilies::add($b, ':orange book:', '📙'); + Smilies::add($b, ':books:', '📚'); + Smilies::add($b, ':notebook:', '📓'); + Smilies::add($b, ':ledger:', '📒'); + Smilies::add($b, ':page with curl:', '📃'); + Smilies::add($b, ':scroll:', '📜'); + Smilies::add($b, ':page facing up:', '📄'); + Smilies::add($b, ':newspaper:', '📰'); + Smilies::add($b, ':rolled-up newspaper:', '🗞'); + Smilies::add($b, ':bookmark tabs:', '📑'); + Smilies::add($b, ':bookmark:', '🔖'); + Smilies::add($b, ':label:', '🏷'); // money - Smilies::add($b, ':money bag:', '💰'); - Smilies::add($b, ':yen banknote:', '💴'); - Smilies::add($b, ':dollar banknote:', '💵'); - Smilies::add($b, ':euro banknote:', '💶'); - Smilies::add($b, ':pound banknote:', '💷'); - Smilies::add($b, ':money with wings:', '💸'); - Smilies::add($b, ':credit card:', '💳'); - Smilies::add($b, ':receipt:', '🧾'); - Smilies::add($b, ':chart increasing with yen:', '💹'); + Smilies::add($b, ':money bag:', '💰'); + Smilies::add($b, ':yen banknote:', '💴'); + Smilies::add($b, ':dollar banknote:', '💵'); + Smilies::add($b, ':euro banknote:', '💶'); + Smilies::add($b, ':pound banknote:', '💷'); + Smilies::add($b, ':money with wings:', '💸'); + Smilies::add($b, ':credit card:', '💳'); + Smilies::add($b, ':receipt:', '🧾'); + Smilies::add($b, ':chart increasing with yen:', '💹'); // mail - Smilies::add($b, ':envelope:', '✉'); - Smilies::add($b, ':e-mail:', '📧'); - Smilies::add($b, ':incoming envelope:', '📨'); - Smilies::add($b, ':envelope with arrow:', '📩'); - Smilies::add($b, ':outbox tray:', '📤'); - Smilies::add($b, ':inbox tray:', '📥'); - Smilies::add($b, ':package:', '📦'); - Smilies::add($b, ':closed mailbox with raised flag:', '📫'); - Smilies::add($b, ':closed mailbox with lowered flag:', '📪'); - Smilies::add($b, ':open mailbox with raised flag:', '📬'); - Smilies::add($b, ':open mailbox with lowered flag:', '📭'); - Smilies::add($b, ':postbox:', '📮'); - Smilies::add($b, ':ballot box with ballot:', '🗳'); + Smilies::add($b, ':envelope:', '✉'); + Smilies::add($b, ':e-mail:', '📧'); + Smilies::add($b, ':incoming envelope:', '📨'); + Smilies::add($b, ':envelope with arrow:', '📩'); + Smilies::add($b, ':outbox tray:', '📤'); + Smilies::add($b, ':inbox tray:', '📥'); + Smilies::add($b, ':package:', '📦'); + Smilies::add($b, ':closed mailbox with raised flag:', '📫'); + Smilies::add($b, ':closed mailbox with lowered flag:', '📪'); + Smilies::add($b, ':open mailbox with raised flag:', '📬'); + Smilies::add($b, ':open mailbox with lowered flag:', '📭'); + Smilies::add($b, ':postbox:', '📮'); + Smilies::add($b, ':ballot box with ballot:', '🗳'); // writing - Smilies::add($b, ':pencil:', '✏'); - Smilies::add($b, ':black nib:', '✒'); - Smilies::add($b, ':fountain pen:', '🖋'); - Smilies::add($b, ':pen:', '🖊'); - Smilies::add($b, ':paintbrush:', '🖌'); - Smilies::add($b, ':crayon:', '🖍'); - Smilies::add($b, ':memo:', '📝'); + Smilies::add($b, ':pencil:', '✏'); + Smilies::add($b, ':black nib:', '✒'); + Smilies::add($b, ':fountain pen:', '🖋'); + Smilies::add($b, ':pen:', '🖊'); + Smilies::add($b, ':paintbrush:', '🖌'); + Smilies::add($b, ':crayon:', '🖍'); + Smilies::add($b, ':memo:', '📝'); // office - Smilies::add($b, ':briefcase:', '💼'); - Smilies::add($b, ':file folder:', '📁'); - Smilies::add($b, ':open file folder:', '📂'); - Smilies::add($b, ':card index dividers:', '🗂'); - Smilies::add($b, ':calendar:', '📅'); - Smilies::add($b, ':tear-off calendar:', '📆'); - Smilies::add($b, ':spiral notepad:', '🗒'); - Smilies::add($b, ':spiral calendar:', '🗓'); - Smilies::add($b, ':card index:', '📇'); - Smilies::add($b, ':chart increasing:', '📈'); - Smilies::add($b, ':chart decreasing:', '📉'); - Smilies::add($b, ':bar chart:', '📊'); - Smilies::add($b, ':clipboard:', '📋'); - Smilies::add($b, ':pushpin:', '📌'); - Smilies::add($b, ':round pushpin:', '📍'); - Smilies::add($b, ':paperclip:', '📎'); - Smilies::add($b, ':linked paperclips:', '🖇'); - Smilies::add($b, ':straight ruler:', '📏'); - Smilies::add($b, ':triangular ruler:', '📐'); - Smilies::add($b, ':scissors:', '✂'); - Smilies::add($b, ':card file box:', '🗃'); - Smilies::add($b, ':file cabinet:', '🗄'); - Smilies::add($b, ':wastebasket:', '🗑'); + Smilies::add($b, ':briefcase:', '💼'); + Smilies::add($b, ':file folder:', '📁'); + Smilies::add($b, ':open file folder:', '📂'); + Smilies::add($b, ':card index dividers:', '🗂'); + Smilies::add($b, ':calendar:', '📅'); + Smilies::add($b, ':tear-off calendar:', '📆'); + Smilies::add($b, ':spiral notepad:', '🗒'); + Smilies::add($b, ':spiral calendar:', '🗓'); + Smilies::add($b, ':card index:', '📇'); + Smilies::add($b, ':chart increasing:', '📈'); + Smilies::add($b, ':chart decreasing:', '📉'); + Smilies::add($b, ':bar chart:', '📊'); + Smilies::add($b, ':clipboard:', '📋'); + Smilies::add($b, ':pushpin:', '📌'); + Smilies::add($b, ':round pushpin:', '📍'); + Smilies::add($b, ':paperclip:', '📎'); + Smilies::add($b, ':linked paperclips:', '🖇'); + Smilies::add($b, ':straight ruler:', '📏'); + Smilies::add($b, ':triangular ruler:', '📐'); + Smilies::add($b, ':scissors:', '✂'); + Smilies::add($b, ':card file box:', '🗃'); + Smilies::add($b, ':file cabinet:', '🗄'); + Smilies::add($b, ':wastebasket:', '🗑'); // lock - Smilies::add($b, ':locked:', '🔒'); - Smilies::add($b, ':unlocked:', '🔓'); - Smilies::add($b, ':locked with pen:', '🔏'); - Smilies::add($b, ':locked with key:', '🔐'); - Smilies::add($b, ':key:', '🔑'); - Smilies::add($b, ':old key:', '🗝'); + Smilies::add($b, ':locked:', '🔒'); + Smilies::add($b, ':unlocked:', '🔓'); + Smilies::add($b, ':locked with pen:', '🔏'); + Smilies::add($b, ':locked with key:', '🔐'); + Smilies::add($b, ':key:', '🔑'); + Smilies::add($b, ':old key:', '🗝'); // tool - Smilies::add($b, ':hammer:', '🔨'); -// Smilies::add($b, ':axe:', '🪓'); - Smilies::add($b, ':pick:', '⛏'); - Smilies::add($b, ':hammer and pick:', '⚒'); - Smilies::add($b, ':hammer and wrench:', '🛠'); - Smilies::add($b, ':dagger:', '🗡'); + Smilies::add($b, ':hammer:', '🔨'); +// Smilies::add($b, ':axe:', '🪓'); + Smilies::add($b, ':pick:', '⛏'); + Smilies::add($b, ':hammer and pick:', '⚒'); + Smilies::add($b, ':hammer and wrench:', '🛠'); + Smilies::add($b, ':dagger:', '🗡'); Smilies::add($b, ':sabre:', '🗡'); - Smilies::add($b, ':crossed swords:', '⚔'); - Smilies::add($b, ':pistol:', '🔫'); - Smilies::add($b, ':bow and arrow:', '🏹'); - Smilies::add($b, ':shield:', '🛡'); - Smilies::add($b, ':wrench:', '🔧'); - Smilies::add($b, ':nut and bolt:', '🔩'); - Smilies::add($b, ':gear:', '⚙'); - Smilies::add($b, ':clamp:', '🗜'); - Smilies::add($b, ':balance scale:', '⚖'); - Smilies::add($b, ':white cane:', '🦯'); - Smilies::add($b, ':link:', '🔗'); - Smilies::add($b, ':chains:', '⛓'); - Smilies::add($b, ':toolbox:', '🧰'); - Smilies::add($b, ':magnet:', '🧲'); + Smilies::add($b, ':crossed swords:', '⚔'); + Smilies::add($b, ':pistol:', '🔫'); + Smilies::add($b, ':bow and arrow:', '🏹'); + Smilies::add($b, ':shield:', '🛡'); + Smilies::add($b, ':wrench:', '🔧'); + Smilies::add($b, ':nut and bolt:', '🔩'); + Smilies::add($b, ':gear:', '⚙'); + Smilies::add($b, ':clamp:', '🗜'); + Smilies::add($b, ':balance scale:', '⚖'); + Smilies::add($b, ':white cane:', '🦯'); + Smilies::add($b, ':link:', '🔗'); + Smilies::add($b, ':chains:', '⛓'); + Smilies::add($b, ':toolbox:', '🧰'); + Smilies::add($b, ':magnet:', '🧲'); // science - Smilies::add($b, ':alembic:', '⚗'); - Smilies::add($b, ':test tube:', '🧪'); - Smilies::add($b, ':petri dish:', '🧫'); - Smilies::add($b, ':dna:', '🧬'); - Smilies::add($b, ':microscope:', '🔬'); - Smilies::add($b, ':telescope:', '🔭'); - Smilies::add($b, ':satellite antenna:', '📡'); - Smilies::add($b, ':asterism:', '⁂'); - Smilies::add($b, ':outlines white star:', '⚝'); + Smilies::add($b, ':alembic:', '⚗'); + Smilies::add($b, ':test tube:', '🧪'); + Smilies::add($b, ':petri dish:', '🧫'); + Smilies::add($b, ':dna:', '🧬'); + Smilies::add($b, ':microscope:', '🔬'); + Smilies::add($b, ':telescope:', '🔭'); + Smilies::add($b, ':satellite antenna:', '📡'); + Smilies::add($b, ':asterism:', '⁂'); + Smilies::add($b, ':outlines white star:', '颅'); // medical - Smilies::add($b, ':syringe:', '💉'); - Smilies::add($b, ':drop of blood:', '🩸'); - Smilies::add($b, ':pill:', '💊'); - Smilies::add($b, ':adhesive bandage:', '🩹'); - Smilies::add($b, ':stethoscope:', '🩺'); + Smilies::add($b, ':syringe:', '💉'); + Smilies::add($b, ':drop of blood:', '🩸'); + Smilies::add($b, ':pill:', '💊'); + Smilies::add($b, ':adhesive bandage:', '🩹'); + Smilies::add($b, ':stethoscope:', '🩺'); // household - Smilies::add($b, ':door:', '🚪'); - Smilies::add($b, ':bed:', '🛏'); - Smilies::add($b, ':couch and lamp:', '🛋'); -// Smilies::add($b, ':chair:', '🪑'); - Smilies::add($b, ':toilet:', '🚽'); - Smilies::add($b, ':shower:', '🚿'); - Smilies::add($b, ':bathtub:', '🛁'); - Smilies::add($b, ':razor:', '🪒'); - Smilies::add($b, ':lotion bottle:', '🧴'); - Smilies::add($b, ':safety pin:', '🧷'); - Smilies::add($b, ':broom:', '🧹'); - Smilies::add($b, ':basket:', '🧺'); - Smilies::add($b, ':roll of paper:', '🧻'); - Smilies::add($b, ':soap:', '🧼'); - Smilies::add($b, ':sponge:', '🧽'); - Smilies::add($b, ':fire extinguisher:', '🧯'); - Smilies::add($b, ':shopping cart:', '🛒'); + Smilies::add($b, ':door:', '🚪'); + Smilies::add($b, ':bed:', '🛏'); + Smilies::add($b, ':couch and lamp:', '🛋'); +// Smilies::add($b, ':chair:', '🪑'); + Smilies::add($b, ':toilet:', '🚽'); + Smilies::add($b, ':shower:', '🚿'); + Smilies::add($b, ':bathtub:', '🛁'); + Smilies::add($b, ':razor:', '🪒'); + Smilies::add($b, ':lotion bottle:', '🧴'); + Smilies::add($b, ':safety pin:', '🧷'); + Smilies::add($b, ':broom:', '🧹'); + Smilies::add($b, ':basket:', '🧺'); + Smilies::add($b, ':roll of paper:', '🧻'); + Smilies::add($b, ':soap:', '🧼'); + Smilies::add($b, ':sponge:', '🧽'); + Smilies::add($b, ':fire extinguisher:', '🧯'); + Smilies::add($b, ':shopping cart:', '🛒'); // other-object - Smilies::add($b, ':cigarette:', '🚬'); - Smilies::add($b, ':coffin:', '⚰'); - Smilies::add($b, ':funeral urn:', '⚱'); - Smilies::add($b, ':moai:', '🗿'); + Smilies::add($b, ':cigarette:', '🚬'); + Smilies::add($b, ':coffin:', '⚰'); + Smilies::add($b, ':funeral urn:', '⚱'); + Smilies::add($b, ':moai:', '🗿'); // Symbols // transport-sign - Smilies::add($b, ':atm sign:', '🏧'); - Smilies::add($b, ':litter in bin sign:', '🚮'); - Smilies::add($b, ':potable water:', '🚰'); - Smilies::add($b, ':wheelchair symbol:', '♿'); - Smilies::add($b, ':men’s room:', '🚹'); - Smilies::add($b, ':women’s room:', '🚺'); - Smilies::add($b, ':restroom:', '🚻'); - Smilies::add($b, ':baby symbol:', '🚼'); - Smilies::add($b, ':water closet:', '🚾'); - Smilies::add($b, ':passport control:', '🛂'); - Smilies::add($b, ':customs:', '🛃'); - Smilies::add($b, ':baggage claim:', '🛄'); - Smilies::add($b, ':left luggage:', '🛅'); + Smilies::add($b, ':atm sign:', '🏧'); + Smilies::add($b, ':litter in bin sign:', '🚮'); + Smilies::add($b, ':potable water:', '🚰'); + Smilies::add($b, ':wheelchair symbol:', '♿'); + Smilies::add($b, ':men’s room:', '🚹'); + Smilies::add($b, ':women’s room:', '🚺'); + Smilies::add($b, ':restroom:', '🚻'); + Smilies::add($b, ':baby symbol:', '🚼'); + Smilies::add($b, ':water closet:', '🚾'); + Smilies::add($b, ':passport control:', '🛂'); + Smilies::add($b, ':customs:', '🛃'); + Smilies::add($b, ':baggage claim:', '🛄'); + Smilies::add($b, ':left luggage:', '🛅'); // warning - Smilies::add($b, ':warning:', '⚠'); - Smilies::add($b, ':children crossing:', '🚸'); - Smilies::add($b, ':no entry:', '⛔'); - Smilies::add($b, ':prohibited:', '🚫'); - Smilies::add($b, ':no bicycles:', '🚳'); - Smilies::add($b, ':no smoking:', '🚭'); - Smilies::add($b, ':no littering:', '🚯'); - Smilies::add($b, ':non-potable water:', '🚱'); - Smilies::add($b, ':no pedestrians:', '🚷'); - Smilies::add($b, ':no mobile phones:', '📵'); - Smilies::add($b, ':no one under eighteen:', '🔞'); - Smilies::add($b, ':radioactive:', '☢'); - Smilies::add($b, ':biohazard:', '☣'); + Smilies::add($b, ':warning:', '⚠'); + Smilies::add($b, ':children crossing:', '🚸'); + Smilies::add($b, ':no entry:', '⛔'); + Smilies::add($b, ':prohibited:', '🚫'); + Smilies::add($b, ':no bicycles:', '🚳'); + Smilies::add($b, ':no smoking:', '🚭'); + Smilies::add($b, ':no littering:', '🚯'); + Smilies::add($b, ':non-potable water:', '🚱'); + Smilies::add($b, ':no pedestrians:', '🚷'); + Smilies::add($b, ':no mobile phones:', '📵'); + Smilies::add($b, ':no one under eighteen:', '🔞'); + Smilies::add($b, ':radioactive:', '☢'); + Smilies::add($b, ':biohazard:', '☣'); Smilies::add($b, ':army:', '🪖'); // arrow - Smilies::add($b, ':up arrow:', '⬆'); - Smilies::add($b, ':up-right arrow:', '↗'); - Smilies::add($b, ':right arrow:', '➡'); - Smilies::add($b, ':down-right arrow:', '↘'); - Smilies::add($b, ':down arrow:', '⬇'); - Smilies::add($b, ':down-left arrow:', '↙'); - Smilies::add($b, ':left arrow:', '⬅'); - Smilies::add($b, ':up-left arrow:', '↖'); - Smilies::add($b, ':up-down arrow:', '↕'); - Smilies::add($b, ':left-right arrow:', '↔'); - Smilies::add($b, ':right arrow curving left:', '↩'); - Smilies::add($b, ':left arrow curving right:', '↪'); - Smilies::add($b, ':right arrow curving up:', '⤴'); - Smilies::add($b, ':right arrow curving down:', '⤵'); - Smilies::add($b, ':clockwise vertical arrows:', '🔃'); - Smilies::add($b, ':counterclockwise arrows button:', '🔄'); - Smilies::add($b, ':BACK arrow:', '🔙'); - Smilies::add($b, ':END arrow:', '🔚'); - Smilies::add($b, ':ON! arrow:', '🔛'); - Smilies::add($b, ':SOON arrow:', '🔜'); - Smilies::add($b, ':TOP arrow:', '🔝'); + Smilies::add($b, ':up arrow:', '⬆'); + Smilies::add($b, ':up-right arrow:', '↗'); + Smilies::add($b, ':right arrow:', '➡'); + Smilies::add($b, ':down-right arrow:', '↘'); + Smilies::add($b, ':down arrow:', '⬇'); + Smilies::add($b, ':down-left arrow:', '↙'); + Smilies::add($b, ':left arrow:', '⬅'); + Smilies::add($b, ':up-left arrow:', '↖'); + Smilies::add($b, ':up-down arrow:', '↕'); + Smilies::add($b, ':left-right arrow:', '↔'); + Smilies::add($b, ':right arrow curving left:', '↩'); + Smilies::add($b, ':left arrow curving right:', '↪'); + Smilies::add($b, ':right arrow curving up:', '⤴'); + Smilies::add($b, ':right arrow curving down:', '⤵'); + Smilies::add($b, ':clockwise vertical arrows:', '🔃'); + Smilies::add($b, ':counterclockwise arrows button:', '🔄'); + Smilies::add($b, ':BACK arrow:', '🔙'); + Smilies::add($b, ':END arrow:', '🔚'); + Smilies::add($b, ':ON! arrow:', '🔛'); + Smilies::add($b, ':SOON arrow:', '🔜'); + Smilies::add($b, ':TOP arrow:', '🔝'); // religion - Smilies::add($b, ':place of worship:', '🛐'); - Smilies::add($b, ':atom symbol:', '⚛'); - Smilies::add($b, ':om:', '🕉'); - Smilies::add($b, ':star of David:', '✡'); - Smilies::add($b, ':wheel of dharma:', '☸'); - Smilies::add($b, ':yin yang:', '☯'); - Smilies::add($b, ':latin cross:', '✝'); - Smilies::add($b, ':orthodox cross:', '☦'); - Smilies::add($b, ':star and crescent:', '☪'); - Smilies::add($b, ':peace symbol:', '☮'); - Smilies::add($b, ':menorah:', '🕎'); - Smilies::add($b, ':dotted six-pointed star:', '🔯'); + Smilies::add($b, ':place of worship:', '🛐'); + Smilies::add($b, ':atom symbol:', '⚛'); + Smilies::add($b, ':om:', '🕉'); + Smilies::add($b, ':star of David:', '✡'); + Smilies::add($b, ':wheel of dharma:', '☸'); + Smilies::add($b, ':yin yang:', '☯'); + Smilies::add($b, ':latin cross:', '✝'); + Smilies::add($b, ':orthodox cross:', '☦'); + Smilies::add($b, ':star and crescent:', '☪'); + Smilies::add($b, ':peace symbol:', '☮'); + Smilies::add($b, ':menorah:', '🕎'); + Smilies::add($b, ':dotted six-pointed star:', '🔯'); // zodiac - Smilies::add($b, ':Aries:', '♈'); - Smilies::add($b, ':Taurus:', '♉'); - Smilies::add($b, ':Gemini:', '♊'); - Smilies::add($b, ':Cancer:', '♋'); - Smilies::add($b, ':Leo:', '♌'); - Smilies::add($b, ':Virgo:', '♍'); - Smilies::add($b, ':Libra:', '♎'); - Smilies::add($b, ':Scorpio:', '♏'); - Smilies::add($b, ':Sagittarius:', '♐'); - Smilies::add($b, ':Capricorn:', '♑'); - Smilies::add($b, ':Aquarius:', '♒'); - Smilies::add($b, ':Pisces:', '♓'); - Smilies::add($b, ':Ophiuchus:', '⛎'); + Smilies::add($b, ':Aries:', '♈'); + Smilies::add($b, ':Taurus:', '♉'); + Smilies::add($b, ':Gemini:', '♊'); + Smilies::add($b, ':Cancer:', '♋'); + Smilies::add($b, ':Leo:', '♌'); + Smilies::add($b, ':Virgo:', '♍'); + Smilies::add($b, ':Libra:', '♎'); + Smilies::add($b, ':Scorpio:', '♏'); + Smilies::add($b, ':Sagittarius:', '♐'); + Smilies::add($b, ':Capricorn:', '♑'); + Smilies::add($b, ':Aquarius:', '♒'); + Smilies::add($b, ':Pisces:', '♓'); + Smilies::add($b, ':Ophiuchus:', '⛎'); // av-symbol - Smilies::add($b, ':shuffle tracks button:', '🔀'); - Smilies::add($b, ':repeat button:', '🔁'); - Smilies::add($b, ':repeat single button:', '🔂'); - Smilies::add($b, ':play button:', '▶'); - Smilies::add($b, ':fast-forward button:', '⏩'); - Smilies::add($b, ':next track button:', '⏭'); - Smilies::add($b, ':play or pause button:', '⏯'); - Smilies::add($b, ':reverse button:', '◀'); - Smilies::add($b, ':fast reverse button:', '⏪'); - Smilies::add($b, ':last track button:', '⏮'); - Smilies::add($b, ':upwards button:', '🔼'); - Smilies::add($b, ':fast up button:', '⏫'); - Smilies::add($b, ':downwards button:', '🔽'); - Smilies::add($b, ':fast down button:', '⏬'); - Smilies::add($b, ':pause button:', '⏸'); - Smilies::add($b, ':stop button:', '⏹'); - Smilies::add($b, ':record button:', '⏺'); - Smilies::add($b, ':eject button:', '⏏'); - Smilies::add($b, ':cinema:', '🎦'); - Smilies::add($b, ':dim button:', '🔅'); - Smilies::add($b, ':bright button:', '🔆'); - Smilies::add($b, ':antenna bars:', '📶'); - Smilies::add($b, ':vibration mode:', '📳'); - Smilies::add($b, ':mobile phone off:', '📴'); + Smilies::add($b, ':shuffle tracks button:', '🔀'); + Smilies::add($b, ':repeat button:', '🔁'); + Smilies::add($b, ':repeat single button:', '🔂'); + Smilies::add($b, ':play button:', '▶'); + Smilies::add($b, ':fast-forward button:', '⏩'); + Smilies::add($b, ':next track button:', '⏭'); + Smilies::add($b, ':play or pause button:', '⏯'); + Smilies::add($b, ':reverse button:', '◀'); + Smilies::add($b, ':fast reverse button:', '⏪'); + Smilies::add($b, ':last track button:', '⏮'); + Smilies::add($b, ':upwards button:', '🔼'); + Smilies::add($b, ':fast up button:', '⏫'); + Smilies::add($b, ':downwards button:', '🔽'); + Smilies::add($b, ':fast down button:', '⏬'); + Smilies::add($b, ':pause button:', '⏸'); + Smilies::add($b, ':stop button:', '⏹'); + Smilies::add($b, ':record button:', '⏺'); + Smilies::add($b, ':eject button:', '⏏'); + Smilies::add($b, ':cinema:', '🎦'); + Smilies::add($b, ':dim button:', '🔅'); + Smilies::add($b, ':bright button:', '🔆'); + Smilies::add($b, ':antenna bars:', '📶'); + Smilies::add($b, ':vibration mode:', '📳'); + Smilies::add($b, ':mobile phone off:', '📴'); // gender - Smilies::add($b, ':female sign:', '♀'); - Smilies::add($b, ':male sign:', '♂'); + Smilies::add($b, ':female sign:', '♀'); + Smilies::add($b, ':male sign:', '♂'); // math - Smilies::add($b, ':multiply:', '✖'); - Smilies::add($b, ':plus:', '➕'); - Smilies::add($b, ':minus:', '➖'); - Smilies::add($b, ':divide:', '➗'); - Smilies::add($b, ':infinity:', '♾'); + Smilies::add($b, ':multiply:', '✖'); + Smilies::add($b, ':plus:', '➕'); + Smilies::add($b, ':minus:', '➖'); + Smilies::add($b, ':divide:', '➗'); + Smilies::add($b, ':infinity:', '♾'); Smilies::add($b, ':kreisoperator:', '∘'); Smilies::add($b, ':leere menge:', '∅'); Smilies::add($b, ':rundung:', '≈'); @@ -1458,407 +1453,408 @@ function unicode_smilies_smilies(array &$b) Smilies::add($b, ':prozent:', '%'); // punctuation - Smilies::add($b, ':double exclamation mark:', '‼'); - Smilies::add($b, ':exclamation question mark:', '⁉'); - Smilies::add($b, ':question mark:', '❓'); - Smilies::add($b, ':white question mark:', '❔'); - Smilies::add($b, ':white exclamation mark:', '❕'); - Smilies::add($b, ':exclamation mark:', '❗'); - Smilies::add($b, ':wavy dash:', '〰'); + Smilies::add($b, ':double exclamation mark:', '‼'); + Smilies::add($b, ':exclamation question mark:', '⁉'); + Smilies::add($b, ':question mark:', '❓'); + Smilies::add($b, ':white question mark:', '❔'); + Smilies::add($b, ':white exclamation mark:', '❕'); + Smilies::add($b, ':exclamation mark:', '❗'); + Smilies::add($b, ':wavy dash:', '〰'); // currency - Smilies::add($b, ':currency exchange:', '💱'); - Smilies::add($b, ':heavy dollar sign:', '💲'); + Smilies::add($b, ':currency exchange:', '💱'); + Smilies::add($b, ':heavy dollar sign:', '💲'); // other-symbol - Smilies::add($b, ':medical symbol:', '⚕'); - Smilies::add($b, ':recycling symbol:', '♻'); - Smilies::add($b, ':fleur-de-lis:', '⚜'); - Smilies::add($b, ':trident emblem:', '🔱'); - Smilies::add($b, ':name badge:', '📛'); - Smilies::add($b, ':Japanese symbol for beginner:', '🔰'); - Smilies::add($b, ':hollow red circle:', '⭕'); - Smilies::add($b, ':check mark button:', '✅'); - Smilies::add($b, ':check box with check:', '☑'); - Smilies::add($b, ':check mark:', '✔'); - Smilies::add($b, ':cross mark:', '❌'); - Smilies::add($b, ':cross mark button:', '❎'); - Smilies::add($b, ':curly loop:', '➰'); - Smilies::add($b, ':double curly loop:', '➿'); - Smilies::add($b, ':part alternation mark:', '〽'); - Smilies::add($b, ':eight-spoked asterisk:', '✳'); - Smilies::add($b, ':eight-pointed star:', '✴'); - Smilies::add($b, ':sparkle:', '❇'); - Smilies::add($b, ':copyright:', '©'); - Smilies::add($b, ':registered:', '®'); - Smilies::add($b, ':trade mark:', '™'); + Smilies::add($b, ':medical symbol:', '⚕'); + Smilies::add($b, ':recycling symbol:', '♻'); + Smilies::add($b, ':fleur-de-lis:', '⚜'); + Smilies::add($b, ':trident emblem:', '🔱'); + Smilies::add($b, ':name badge:', '📛'); + Smilies::add($b, ':Japanese symbol for beginner:', '🔰'); + Smilies::add($b, ':hollow red circle:', '⭕'); + Smilies::add($b, ':check mark button:', '✅'); + Smilies::add($b, ':check box with check:', '☑'); + Smilies::add($b, ':check mark:', '✔'); + Smilies::add($b, ':cross mark:', '❌'); + Smilies::add($b, ':cross mark button:', '❎'); + Smilies::add($b, ':curly loop:', '➰'); + Smilies::add($b, ':double curly loop:', '➿'); + Smilies::add($b, ':part alternation mark:', '〽'); + Smilies::add($b, ':eight-spoked asterisk:', '✳'); + Smilies::add($b, ':eight-pointed star:', '✴'); + Smilies::add($b, ':sparkle:', '❇'); + Smilies::add($b, ':copyright:', '©'); + Smilies::add($b, ':registered:', '®'); + Smilies::add($b, ':trade mark:', '™'); // keycap - Smilies::add($b, ':keycap: #:', '#️⃣'); - Smilies::add($b, ':keycap: *:', '*️⃣'); - Smilies::add($b, ':keycap: 0:', '0️⃣'); - Smilies::add($b, ':keycap: 1:', '1️⃣'); - Smilies::add($b, ':keycap: 2:', '2️⃣'); - Smilies::add($b, ':keycap: 3:', '3️⃣'); - Smilies::add($b, ':keycap: 4:', '4️⃣'); - Smilies::add($b, ':keycap: 5:', '5️⃣'); - Smilies::add($b, ':keycap: 6:', '6️⃣'); - Smilies::add($b, ':keycap: 7:', '7️⃣'); - Smilies::add($b, ':keycap: 8:', '8️⃣'); - Smilies::add($b, ':keycap: 9:', '9️⃣'); - Smilies::add($b, ':keycap: 10:', '🔟'); + Smilies::add($b, ':keycap: #:', '#️⃣'); + Smilies::add($b, ':keycap: *:', '*️⃣'); + Smilies::add($b, ':keycap: 0:', '0️⃣'); + Smilies::add($b, ':keycap: 1:', '1️⃣'); + Smilies::add($b, ':keycap: 2:', '2️⃣'); + Smilies::add($b, ':keycap: 3:', '3️⃣'); + Smilies::add($b, ':keycap: 4:', '4️⃣'); + Smilies::add($b, ':keycap: 5:', '5️⃣'); + Smilies::add($b, ':keycap: 6:', '6️⃣'); + Smilies::add($b, ':keycap: 7:', '7️⃣'); + Smilies::add($b, ':keycap: 8:', '8️⃣'); + Smilies::add($b, ':keycap: 9:', '9️⃣'); + Smilies::add($b, ':keycap: 10:', '🔟'); // alphanum - Smilies::add($b, ':input latin uppercase:', '🔠'); - Smilies::add($b, ':input latin lowercase:', '🔡'); - Smilies::add($b, ':input numbers:', '🔢'); - Smilies::add($b, ':input symbols:', '🔣'); - Smilies::add($b, ':input latin letters:', '🔤'); - Smilies::add($b, ':A button (blood type):', '🅰'); - Smilies::add($b, ':AB button (blood type):', '🆎'); - Smilies::add($b, ':B button (blood type):', '🅱'); - Smilies::add($b, ':CL button:', '🆑'); - Smilies::add($b, ':COOL button:', '🆒'); + Smilies::add($b, ':input latin uppercase:', '🔠'); + Smilies::add($b, ':input latin lowercase:', '🔡'); + Smilies::add($b, ':input numbers:', '🔢'); + Smilies::add($b, ':input symbols:', '🔣'); + Smilies::add($b, ':input latin letters:', '🔤'); + Smilies::add($b, ':A button (blood type):', '🅰'); + Smilies::add($b, ':AB button (blood type):', '🆎'); + Smilies::add($b, ':B button (blood type):', '🅱'); + Smilies::add($b, ':CL button:', '🆑'); + Smilies::add($b, ':COOL button:', '🆒'); Smilies::add($b, ':cool:', '🆒'); - Smilies::add($b, ':FREE button:', '🆓'); - Smilies::add($b, ':information:', 'ℹ'); - Smilies::add($b, ':ID button:', '🆔'); - Smilies::add($b, ':circled M:', 'Ⓜ'); - Smilies::add($b, ':NEW button:', '🆕'); - Smilies::add($b, ':NG button:', '🆖'); - Smilies::add($b, ':O button (blood type):', '🅾'); - Smilies::add($b, ':OK button:', '🆗'); - Smilies::add($b, ':P button:', '🅿'); - Smilies::add($b, ':SOS button:', '🆘'); - Smilies::add($b, ':UP! button:', '🆙'); - Smilies::add($b, ':VS button:', '🆚'); - Smilies::add($b, ':Japanese “here” button:', '🈁'); - Smilies::add($b, ':Japanese “service charge” button:', '🈂'); - Smilies::add($b, ':Japanese “monthly amount” button:', '🈷'); - Smilies::add($b, ':Japanese “not free of charge” button:', '🈶'); - Smilies::add($b, ':Japanese “reserved” button:', '🈯'); - Smilies::add($b, ':Japanese “bargain” button:', '🉐'); - Smilies::add($b, ':Japanese “discount” button:', '🈹'); - Smilies::add($b, ':Japanese “free of charge” button:', '🈚'); - Smilies::add($b, ':Japanese “prohibited” button:', '🈲'); - Smilies::add($b, ':Japanese “acceptable” button:', '🉑'); - Smilies::add($b, ':Japanese “application” button:', '🈸'); - Smilies::add($b, ':Japanese “passing grade” button:', '🈴'); - Smilies::add($b, ':Japanese “vacancy” button:', '🈳'); - Smilies::add($b, ':Japanese “congratulations” button:', '㊗'); - Smilies::add($b, ':Japanese “secret” button:', '㊙'); - Smilies::add($b, ':Japanese “open for business” button:', '🈺'); - Smilies::add($b, ':Japanese “no vacancy” button:', '🈵'); + Smilies::add($b, ':FREE button:', '🆓'); + Smilies::add($b, ':information:', 'ℹ'); + Smilies::add($b, ':ID button:', '🆔'); + Smilies::add($b, ':circled M:', 'Ⓜ'); + Smilies::add($b, ':NEW button:', '🆕'); + Smilies::add($b, ':NG button:', '🆖'); + Smilies::add($b, ':O button (blood type):', '🅾'); + Smilies::add($b, ':OK button:', '🆗'); + Smilies::add($b, ':P button:', '🅿'); + Smilies::add($b, ':SOS button:', '🆘'); + Smilies::add($b, ':UP! button:', '🆙'); + Smilies::add($b, ':VS button:', '🆚'); + Smilies::add($b, ':Japanese “here” button:', '🈁'); + Smilies::add($b, ':Japanese “service charge” button:', '🈂'); + Smilies::add($b, ':Japanese “monthly amount” button:', '🈷'); + Smilies::add($b, ':Japanese “not free of charge” button:', '🈶'); + Smilies::add($b, ':Japanese “reserved” button:', '🈯'); + Smilies::add($b, ':Japanese “bargain” button:', '🉐'); + Smilies::add($b, ':Japanese “discount” button:', '🈹'); + Smilies::add($b, ':Japanese “free of charge” button:', '🈚'); + Smilies::add($b, ':Japanese “prohibited” button:', '🈲'); + Smilies::add($b, ':Japanese “acceptable” button:', '🉑'); + Smilies::add($b, ':Japanese “application” button:', '🈸'); + Smilies::add($b, ':Japanese “passing grade” button:', '🈴'); + Smilies::add($b, ':Japanese “vacancy” button:', '🈳'); + Smilies::add($b, ':Japanese “congratulations” button:', '㊗'); + Smilies::add($b, ':Japanese “secret” button:', '㊙'); + Smilies::add($b, ':Japanese “open for business” button:', '🈺'); + Smilies::add($b, ':Japanese “no vacancy” button:', '🈵'); // geometric - Smilies::add($b, ':red circle:', '🔴'); -// Smilies::add($b, ':orange circle:', '🟠'); -// Smilies::add($b, ':yellow circle:', '🟡'); -// Smilies::add($b, ':green circle:', '🟢'); - Smilies::add($b, ':blue circle:', '🔵'); -// Smilies::add($b, ':purple circle:', '🟣'); -// Smilies::add($b, ':brown circle:', '🟤'); - Smilies::add($b, ':black circle:', '⚫'); - Smilies::add($b, ':white circle:', '⚪'); -// Smilies::add($b, ':red square:', '🟥'); -// Smilies::add($b, ':orange square:', '🟧'); -// Smilies::add($b, ':yellow square:', '🟨'); -// Smilies::add($b, ':green square:', '🟩'); -// Smilies::add($b, ':blue square:', '🟦'); -// Smilies::add($b, ':purple square:', '🟪'); -// Smilies::add($b, ':brown square:', '🟫'); - Smilies::add($b, ':black large square:', '⬛'); - Smilies::add($b, ':white large square:', '⬜'); - Smilies::add($b, ':black medium square:', '◼'); - Smilies::add($b, ':white medium square:', '◻'); - Smilies::add($b, ':black medium-small square:', '◾'); - Smilies::add($b, ':white medium-small square:', '◽'); - Smilies::add($b, ':black small square:', '▪'); - Smilies::add($b, ':white small square:', '▫'); - Smilies::add($b, ':large orange diamond:', '🔶'); - Smilies::add($b, ':large blue diamond:', '🔷'); - Smilies::add($b, ':small orange diamond:', '🔸'); - Smilies::add($b, ':small blue diamond:', '🔹'); - Smilies::add($b, ':red triangle pointed up:', '🔺'); - Smilies::add($b, ':red triangle pointed down:', '🔻'); - Smilies::add($b, ':diamond with a dot:', '💠'); - Smilies::add($b, ':radio button:', '🔘'); - Smilies::add($b, ':white square button:', '🔳'); - Smilies::add($b, ':black square button:', '🔲'); + Smilies::add($b, ':red circle:', '🔴'); +// Smilies::add($b, ':orange circle:', '🟠'); +// Smilies::add($b, ':yellow circle:', '🟡'); +// Smilies::add($b, ':green circle:', '🟢'); + Smilies::add($b, ':blue circle:', '🔵'); +// Smilies::add($b, ':purple circle:', '🟣'); +// Smilies::add($b, ':brown circle:', '🟤'); + Smilies::add($b, ':black circle:', '⚫'); + Smilies::add($b, ':white circle:', '⚪'); +// Smilies::add($b, ':red square:', '🟥'); +// Smilies::add($b, ':orange square:', '🟧'); +// Smilies::add($b, ':yellow square:', '🟨'); +// Smilies::add($b, ':green square:', '🟩'); +// Smilies::add($b, ':blue square:', '🟦'); +// Smilies::add($b, ':purple square:', '🟪'); +// Smilies::add($b, ':brown square:', '🟫'); + Smilies::add($b, ':black large square:', '⬛'); + Smilies::add($b, ':white large square:', '⬜'); + Smilies::add($b, ':black medium square:', '◼'); + Smilies::add($b, ':white medium square:', '◻'); + Smilies::add($b, ':black medium-small square:', '◾'); + Smilies::add($b, ':white medium-small square:', '◽'); + Smilies::add($b, ':black small square:', '▪'); + Smilies::add($b, ':white small square:', '▫'); + Smilies::add($b, ':large orange diamond:', '🔶'); + Smilies::add($b, ':large blue diamond:', '🔷'); + Smilies::add($b, ':small orange diamond:', '🔸'); + Smilies::add($b, ':small blue diamond:', '🔹'); + Smilies::add($b, ':red triangle pointed up:', '🔺'); + Smilies::add($b, ':red triangle pointed down:', '🔻'); + Smilies::add($b, ':diamond with a dot:', '💠'); + Smilies::add($b, ':radio button:', '🔘'); + Smilies::add($b, ':white square button:', '🔳'); + Smilies::add($b, ':black square button:', '🔲'); // Flags // flag - Smilies::add($b, ':chequered flag:', '🏁'); - Smilies::add($b, ':triangular flag:', '🚩'); - Smilies::add($b, ':crossed flags:', '🎌'); - Smilies::add($b, ':black flag:', '🏴'); - Smilies::add($b, ':white flag:', '🏳'); - Smilies::add($b, ':rainbow flag:', '🏳️‍🌈'); - Smilies::add($b, ':pirate flag:', '🏴‍☠️'); + Smilies::add($b, ':chequered flag:', '🏁'); + Smilies::add($b, ':triangular flag:', '🚩'); + Smilies::add($b, ':crossed flags:', '🎌'); + Smilies::add($b, ':black flag:', '🏴'); + Smilies::add($b, ':white flag:', '🏳'); + Smilies::add($b, ':rainbow flag:', '🏳️‍🌈'); + Smilies::add($b, ':pirate flag:', '🏴‍☠️'); // country-flag - Smilies::add($b, ':ascension island:', '🇦🇨'); - Smilies::add($b, ':andorra:', '🇦🇩'); - Smilies::add($b, ':united arab emirates:', '🇦🇪'); - Smilies::add($b, ':afghanistan:', '🇦🇫'); - Smilies::add($b, ':antigua & barbuda:', '🇦🇬'); - Smilies::add($b, ':anguilla:', '🇦🇮'); - Smilies::add($b, ':albania:', '🇦🇱'); - Smilies::add($b, ':armenia:', '🇦🇲'); - Smilies::add($b, ':angola:', '🇦🇴'); - Smilies::add($b, ':antarctica:', '🇦🇶'); - Smilies::add($b, ':argentina:', '🇦🇷'); - Smilies::add($b, ':americansamoa:', '🇦🇸'); - Smilies::add($b, ':austria:', '🇦🇹'); - Smilies::add($b, ':australia:', '🇦🇺'); - Smilies::add($b, ':aruba:', '🇦🇼'); - Smilies::add($b, ':ålandislands:', '🇦🇽'); - Smilies::add($b, ':azerbaijan:', '🇦🇿'); - Smilies::add($b, ':bosnia&herzegovina:', '🇧🇦'); - Smilies::add($b, ':barbados:', '🇧🇧'); - Smilies::add($b, ':bangladesh:', '🇧🇩'); - Smilies::add($b, ':belgium:', '🇧🇪'); - Smilies::add($b, ':burkinafaso:', '🇧🇫'); - Smilies::add($b, ':bulgaria:', '🇧🇬'); - Smilies::add($b, ':bahrain:', '🇧🇭'); - Smilies::add($b, ':burundi:', '🇧🇮'); - Smilies::add($b, ':benin:', '🇧🇯'); - Smilies::add($b, ':st.barthélemy:', '🇧🇱'); - Smilies::add($b, ':bermuda:', '🇧🇲'); - Smilies::add($b, ':brunei:', '🇧🇳'); - Smilies::add($b, ':bolivia:', '🇧🇴'); - Smilies::add($b, ':caribbeannetherlands:', '🇧🇶'); - Smilies::add($b, ':brazil:', '🇧🇷'); - Smilies::add($b, ':bahamas:', '🇧🇸'); - Smilies::add($b, ':bhutan:', '🇧🇹'); - Smilies::add($b, ':bouvetisland:', '🇧🇻'); - Smilies::add($b, ':botswana:', '🇧🇼'); - Smilies::add($b, ':belarus:', '🇧🇾'); - Smilies::add($b, ':belize:', '🇧🇿'); - Smilies::add($b, ':canada:', '🇨🇦'); - Smilies::add($b, ':cocos(keeling)islands:', '🇨🇨'); - Smilies::add($b, ':congo-kinshasa:', '🇨🇩'); - Smilies::add($b, ':centralafricanrepublic:', '🇨🇫'); - Smilies::add($b, ':congo-brazzaville:', '🇨🇬'); - Smilies::add($b, ':switzerland:', '🇨🇭'); - Smilies::add($b, ':côted’ivoire:', '🇨🇮'); - Smilies::add($b, ':cookislands:', '🇨🇰'); - Smilies::add($b, ':chile:', '🇨🇱'); - Smilies::add($b, ':cameroon:', '🇨🇲'); - Smilies::add($b, ':china:', '🇨🇳'); - Smilies::add($b, ':colombia:', '🇨🇴'); - Smilies::add($b, ':clippertonisland:', '🇨🇵'); - Smilies::add($b, ':costarica:', '🇨🇷'); - Smilies::add($b, ':cuba:', '🇨🇺'); - Smilies::add($b, ':capeverde:', '🇨🇻'); - Smilies::add($b, ':curaçao:', '🇨🇼'); - Smilies::add($b, ':christmasisland:', '🇨🇽'); - Smilies::add($b, ':cyprus:', '🇨🇾'); - Smilies::add($b, ':czechia:', '🇨🇿'); - Smilies::add($b, ':germany:', '🇩🇪'); - Smilies::add($b, ':diegogarcia:', '🇩🇬'); - Smilies::add($b, ':djibouti:', '🇩🇯'); - Smilies::add($b, ':denmark:', '🇩🇰'); - Smilies::add($b, ':dominica:', '🇩🇲'); - Smilies::add($b, ':dominicanrepublic:', '🇩🇴'); - Smilies::add($b, ':algeria:', '🇩🇿'); - Smilies::add($b, ':ceuta&melilla:', '🇪🇦'); - Smilies::add($b, ':ecuador:', '🇪🇨'); - Smilies::add($b, ':estonia:', '🇪🇪'); - Smilies::add($b, ':egypt:', '🇪🇬'); - Smilies::add($b, ':westernsahara:', '🇪🇭'); - Smilies::add($b, ':eritrea:', '🇪🇷'); - Smilies::add($b, ':spain:', '🇪🇸'); - Smilies::add($b, ':ethiopia:', '🇪🇹'); - Smilies::add($b, ':europeanunion:', '🇪🇺'); - Smilies::add($b, ':finland:', '🇫🇮'); - Smilies::add($b, ':fiji:', '🇫🇯'); - Smilies::add($b, ':falklandislands:', '🇫🇰'); - Smilies::add($b, ':micronesia:', '🇫🇲'); - Smilies::add($b, ':faroeislands:', '🇫🇴'); - Smilies::add($b, ':france:', '🇫🇷'); - Smilies::add($b, ':gabon:', '🇬🇦'); - Smilies::add($b, ':unitedkingdom:', '🇬🇧'); - Smilies::add($b, ':grenada:', '🇬🇩'); - Smilies::add($b, ':georgia:', '🇬🇪'); - Smilies::add($b, ':frenchguiana:', '🇬🇫'); - Smilies::add($b, ':guernsey:', '🇬🇬'); - Smilies::add($b, ':ghana:', '🇬🇭'); - Smilies::add($b, ':gibraltar:', '🇬🇮'); - Smilies::add($b, ':greenland:', '🇬🇱'); - Smilies::add($b, ':gambia:', '🇬🇲'); - Smilies::add($b, ':guinea:', '🇬🇳'); - Smilies::add($b, ':guadeloupe:', '🇬🇵'); - Smilies::add($b, ':equatorialguinea:', '🇬🇶'); - Smilies::add($b, ':greece:', '🇬🇷'); - Smilies::add($b, ':southgeorgia&southsandwichislands:', '🇬🇸'); - Smilies::add($b, ':guatemala:', '🇬🇹'); - Smilies::add($b, ':guam:', '🇬🇺'); - Smilies::add($b, ':guinea-bissau:', '🇬🇼'); - Smilies::add($b, ':guyana:', '🇬🇾'); - Smilies::add($b, ':hongkongsarchina:', '🇭🇰'); - Smilies::add($b, ':heard&mcdonaldislands:', '🇭🇲'); - Smilies::add($b, ':honduras:', '🇭🇳'); - Smilies::add($b, ':croatia:', '🇭🇷'); - Smilies::add($b, ':haiti:', '🇭🇹'); - Smilies::add($b, ':hungary:', '🇭🇺'); - Smilies::add($b, ':canaryislands:', '🇮🇨'); - Smilies::add($b, ':indonesia:', '🇮🇩'); - Smilies::add($b, ':ireland:', '🇮🇪'); - Smilies::add($b, ':israel:', '🇮🇱'); - Smilies::add($b, ':isleofman:', '🇮🇲'); - Smilies::add($b, ':india:', '🇮🇳'); - Smilies::add($b, ':britishindianoceanterritory:', '🇮🇴'); - Smilies::add($b, ':iraq:', '🇮🇶'); - Smilies::add($b, ':iran:', '🇮🇷'); - Smilies::add($b, ':iceland:', '🇮🇸'); - Smilies::add($b, ':italy:', '🇮🇹'); - Smilies::add($b, ':jersey:', '🇯🇪'); - Smilies::add($b, ':jamaica:', '🇯🇲'); - Smilies::add($b, ':jordan:', '🇯🇴'); - Smilies::add($b, ':japan:', '🇯🇵'); - Smilies::add($b, ':kenya:', '🇰🇪'); - Smilies::add($b, ':kyrgyzstan:', '🇰🇬'); - Smilies::add($b, ':cambodia:', '🇰🇭'); - Smilies::add($b, ':kiribati:', '🇰🇮'); - Smilies::add($b, ':comoros:', '🇰🇲'); - Smilies::add($b, ':st.kitts&nevis:', '🇰🇳'); - Smilies::add($b, ':northkorea:', '🇰🇵'); - Smilies::add($b, ':southkorea:', '🇰🇷'); - Smilies::add($b, ':kuwait:', '🇰🇼'); - Smilies::add($b, ':caymanislands:', '🇰🇾'); - Smilies::add($b, ':kazakhstan:', '🇰🇿'); - Smilies::add($b, ':laos:', '🇱🇦'); - Smilies::add($b, ':lebanon:', '🇱🇧'); - Smilies::add($b, ':st.lucia:', '🇱🇨'); - Smilies::add($b, ':liechtenstein:', '🇱🇮'); - Smilies::add($b, ':srilanka:', '🇱🇰'); - Smilies::add($b, ':liberia:', '🇱🇷'); - Smilies::add($b, ':lesotho:', '🇱🇸'); - Smilies::add($b, ':lithuania:', '🇱🇹'); - Smilies::add($b, ':luxembourg:', '🇱🇺'); - Smilies::add($b, ':latvia:', '🇱🇻'); - Smilies::add($b, ':libya:', '🇱🇾'); - Smilies::add($b, ':morocco:', '🇲🇦'); - Smilies::add($b, ':monaco:', '🇲🇨'); - Smilies::add($b, ':moldova:', '🇲🇩'); - Smilies::add($b, ':montenegro:', '🇲🇪'); - Smilies::add($b, ':st.martin:', '🇲🇫'); - Smilies::add($b, ':madagascar:', '🇲🇬'); - Smilies::add($b, ':marshallislands:', '🇲🇭'); - Smilies::add($b, ':northmacedonia:', '🇲🇰'); - Smilies::add($b, ':mali:', '🇲🇱'); - Smilies::add($b, ':myanmar(burma):', '🇲🇲'); - Smilies::add($b, ':mongolia:', '🇲🇳'); - Smilies::add($b, ':macaosarchina:', '🇲🇴'); - Smilies::add($b, ':northernmarianaislands:', '🇲🇵'); - Smilies::add($b, ':martinique:', '🇲🇶'); - Smilies::add($b, ':mauritania:', '🇲🇷'); - Smilies::add($b, ':montserrat:', '🇲🇸'); - Smilies::add($b, ':malta:', '🇲🇹'); - Smilies::add($b, ':mauritius:', '🇲🇺'); - Smilies::add($b, ':maldives:', '🇲🇻'); - Smilies::add($b, ':malawi:', '🇲🇼'); - Smilies::add($b, ':mexico:', '🇲🇽'); - Smilies::add($b, ':malaysia:', '🇲🇾'); - Smilies::add($b, ':mozambique:', '🇲🇿'); - Smilies::add($b, ':namibia:', '🇳🇦'); - Smilies::add($b, ':newcaledonia:', '🇳🇨'); - Smilies::add($b, ':niger:', '🇳🇪'); - Smilies::add($b, ':norfolkisland:', '🇳🇫'); - Smilies::add($b, ':nigeria:', '🇳🇬'); - Smilies::add($b, ':nicaragua:', '🇳🇮'); - Smilies::add($b, ':netherlands:', '🇳🇱'); - Smilies::add($b, ':norway:', '🇳🇴'); - Smilies::add($b, ':nepal:', '🇳🇵'); - Smilies::add($b, ':nauru:', '🇳🇷'); - Smilies::add($b, ':niue:', '🇳🇺'); - Smilies::add($b, ':newzealand:', '🇳🇿'); - Smilies::add($b, ':oman:', '🇴🇲'); - Smilies::add($b, ':panama:', '🇵🇦'); - Smilies::add($b, ':peru:', '🇵🇪'); - Smilies::add($b, ':frenchpolynesia:', '🇵🇫'); - Smilies::add($b, ':papuanewguinea:', '🇵🇬'); - Smilies::add($b, ':philippines:', '🇵🇭'); - Smilies::add($b, ':pakistan:', '🇵🇰'); - Smilies::add($b, ':poland:', '🇵🇱'); - Smilies::add($b, ':st.pierre&miquelon:', '🇵🇲'); - Smilies::add($b, ':pitcairnislands:', '🇵🇳'); - Smilies::add($b, ':puertorico:', '🇵🇷'); - Smilies::add($b, ':palestinianterritories:', '🇵🇸'); - Smilies::add($b, ':portugal:', '🇵🇹'); - Smilies::add($b, ':palau:', '🇵🇼'); - Smilies::add($b, ':paraguay:', '🇵🇾'); - Smilies::add($b, ':qatar:', '🇶🇦'); - Smilies::add($b, ':réunion:', '🇷🇪'); - Smilies::add($b, ':romania:', '🇷🇴'); - Smilies::add($b, ':serbia:', '🇷🇸'); - Smilies::add($b, ':russia:', '🇷🇺'); - Smilies::add($b, ':rwanda:', '🇷🇼'); - Smilies::add($b, ':saudiarabia:', '🇸🇦'); - Smilies::add($b, ':solomonislands:', '🇸🇧'); - Smilies::add($b, ':seychelles:', '🇸🇨'); - Smilies::add($b, ':sudan:', '🇸🇩'); - Smilies::add($b, ':sweden:', '🇸🇪'); - Smilies::add($b, ':singapore:', '🇸🇬'); - Smilies::add($b, ':st.helena:', '🇸🇭'); - Smilies::add($b, ':slovenia:', '🇸🇮'); - Smilies::add($b, ':svalbard&janmayen:', '🇸🇯'); - Smilies::add($b, ':slovakia:', '🇸🇰'); - Smilies::add($b, ':sierraleone:', '🇸🇱'); - Smilies::add($b, ':sanmarino:', '🇸🇲'); - Smilies::add($b, ':senegal:', '🇸🇳'); - Smilies::add($b, ':somalia:', '🇸🇴'); - Smilies::add($b, ':suriname:', '🇸🇷'); - Smilies::add($b, ':southsudan:', '🇸🇸'); - Smilies::add($b, ':sãotomé&príncipe:', '🇸🇹'); - Smilies::add($b, ':elsalvador:', '🇸🇻'); - Smilies::add($b, ':sintmaarten:', '🇸🇽'); - Smilies::add($b, ':syria:', '🇸🇾'); - Smilies::add($b, ':eswatini:', '🇸🇿'); - Smilies::add($b, ':tristandacunha:', '🇹🇦'); - Smilies::add($b, ':turks&caicosislands:', '🇹🇨'); - Smilies::add($b, ':chad:', '🇹🇩'); - Smilies::add($b, ':frenchsouthernterritories:', '🇹🇫'); - Smilies::add($b, ':togo:', '🇹🇬'); - Smilies::add($b, ':thailand:', '🇹🇭'); - Smilies::add($b, ':tajikistan:', '🇹🇯'); - Smilies::add($b, ':tokelau:', '🇹🇰'); - Smilies::add($b, ':timor-leste:', '🇹🇱'); - Smilies::add($b, ':turkmenistan:', '🇹🇲'); - Smilies::add($b, ':tunisia:', '🇹🇳'); - Smilies::add($b, ':tonga:', '🇹🇴'); - Smilies::add($b, ':turkey:', '🇹🇷'); - Smilies::add($b, ':trinidad&tobago:', '🇹🇹'); - Smilies::add($b, ':tuvalu:', '🇹🇻'); - Smilies::add($b, ':taiwan:', '🇹🇼'); - Smilies::add($b, ':tanzania:', '🇹🇿'); - Smilies::add($b, ':ukraine:', '🇺🇦'); - Smilies::add($b, ':uganda:', '🇺🇬'); - Smilies::add($b, ':u.s.outlyingislands:', '🇺🇲'); - Smilies::add($b, ':unitednations:', '🇺🇳'); - Smilies::add($b, ':unitedstates:', '🇺🇸'); - Smilies::add($b, ':uruguay:', '🇺🇾'); - Smilies::add($b, ':uzbekistan:', '🇺🇿'); - Smilies::add($b, ':vaticancity:', '🇻🇦'); - Smilies::add($b, ':st.vincent&grenadines:', '🇻🇨'); - Smilies::add($b, ':venezuela:', '🇻🇪'); - Smilies::add($b, ':britishvirginislands:', '🇻🇬'); - Smilies::add($b, ':u.s.virginislands:', '🇻🇮'); - Smilies::add($b, ':vietnam:', '🇻🇳'); - Smilies::add($b, ':vanuatu:', '🇻🇺'); - Smilies::add($b, ':wallis&futuna:', '🇼🇫'); - Smilies::add($b, ':samoa:', '🇼🇸'); - Smilies::add($b, ':kosovo:', '🇽🇰'); - Smilies::add($b, ':yemen:', '🇾🇪'); - Smilies::add($b, ':mayotte:', '🇾🇹'); - Smilies::add($b, ':southafrica:', '🇿🇦'); - Smilies::add($b, ':zambia:', '🇿🇲'); - Smilies::add($b, ':zimbabwe:', '🇿🇼'); + Smilies::add($b, ':ascension island:', '🇦🇨'); + Smilies::add($b, ':andorra:', '🇦🇩'); + Smilies::add($b, ':united arab emirates:', '🇦🇪'); + Smilies::add($b, ':afghanistan:', '🇦🇫'); + Smilies::add($b, ':antigua & barbuda:', '🇦🇬'); + Smilies::add($b, ':anguilla:', '🇦🇮'); + Smilies::add($b, ':albania:', '🇦🇱'); + Smilies::add($b, ':armenia:', '🇦🇲'); + Smilies::add($b, ':angola:', '🇦🇴'); + Smilies::add($b, ':antarctica:', '🇦🇶'); + Smilies::add($b, ':argentina:', '🇦🇷'); + Smilies::add($b, ':americansamoa:', '🇦🇸'); + Smilies::add($b, ':austria:', '🇦🇹'); + Smilies::add($b, ':australia:', '🇦🇺'); + Smilies::add($b, ':aruba:', '🇦🇼'); + Smilies::add($b, ':ålandislands:', '🇦🇽'); + Smilies::add($b, ':azerbaijan:', '🇦🇿'); + Smilies::add($b, ':bosnia&herzegovina:', '🇧🇦'); + Smilies::add($b, ':barbados:', '🇧🇧'); + Smilies::add($b, ':bangladesh:', '🇧🇩'); + Smilies::add($b, ':belgium:', '🇧🇪'); + Smilies::add($b, ':burkinafaso:', '🇧🇫'); + Smilies::add($b, ':bulgaria:', '🇧🇬'); + Smilies::add($b, ':bahrain:', '🇧🇭'); + Smilies::add($b, ':burundi:', '🇧🇮'); + Smilies::add($b, ':benin:', '🇧🇯'); + Smilies::add($b, ':st.barthélemy:', '🇧🇱'); + Smilies::add($b, ':bermuda:', '🇧🇲'); + Smilies::add($b, ':brunei:', '🇧🇳'); + Smilies::add($b, ':bolivia:', '🇧🇴'); + Smilies::add($b, ':caribbeannetherlands:', '🇧🇶'); + Smilies::add($b, ':brazil:', '🇧🇷'); + Smilies::add($b, ':bahamas:', '🇧🇸'); + Smilies::add($b, ':bhutan:', '🇧🇹'); + Smilies::add($b, ':bouvetisland:', '🇧🇻'); + Smilies::add($b, ':botswana:', '🇧🇼'); + Smilies::add($b, ':belarus:', '🇧🇾'); + Smilies::add($b, ':belize:', '🇧🇿'); + Smilies::add($b, ':canada:', '🇨🇦'); + Smilies::add($b, ':cocos(keeling)islands:', '🇨🇨'); + Smilies::add($b, ':congo-kinshasa:', '🇨🇩'); + Smilies::add($b, ':centralafricanrepublic:', '🇨🇫'); + Smilies::add($b, ':congo-brazzaville:', '🇨🇬'); + Smilies::add($b, ':switzerland:', '🇨🇭'); + Smilies::add($b, ':côted’ivoire:', '🇨🇮'); + Smilies::add($b, ':cookislands:', '🇨🇰'); + Smilies::add($b, ':chile:', '🇨🇱'); + Smilies::add($b, ':cameroon:', '🇨🇲'); + Smilies::add($b, ':china:', '🇨🇳'); + Smilies::add($b, ':colombia:', '🇨🇴'); + Smilies::add($b, ':clippertonisland:', '🇨🇵'); + Smilies::add($b, ':costarica:', '🇨🇷'); + Smilies::add($b, ':cuba:', '🇨🇺'); + Smilies::add($b, ':capeverde:', '🇨🇻'); + Smilies::add($b, ':curaçao:', '🇨🇼'); + Smilies::add($b, ':christmasisland:', '🇨🇽'); + Smilies::add($b, ':cyprus:', '🇨🇾'); + Smilies::add($b, ':czechia:', '🇨🇿'); + Smilies::add($b, ':germany:', '🇩🇪'); + Smilies::add($b, ':diegogarcia:', '🇩🇬'); + Smilies::add($b, ':djibouti:', '🇩🇯'); + Smilies::add($b, ':denmark:', '🇩🇰'); + Smilies::add($b, ':dominica:', '🇩🇲'); + Smilies::add($b, ':dominicanrepublic:', '🇩🇴'); + Smilies::add($b, ':algeria:', '🇩🇿'); + Smilies::add($b, ':ceuta&melilla:', '🇪🇦'); + Smilies::add($b, ':ecuador:', '🇪🇨'); + Smilies::add($b, ':estonia:', '🇪🇪'); + Smilies::add($b, ':egypt:', '🇪🇬'); + Smilies::add($b, ':westernsahara:', '🇪🇭'); + Smilies::add($b, ':eritrea:', '🇪🇷'); + Smilies::add($b, ':spain:', '🇪🇸'); + Smilies::add($b, ':ethiopia:', '🇪🇹'); + Smilies::add($b, ':europeanunion:', '🇪🇺'); + Smilies::add($b, ':finland:', '🇫🇮'); + Smilies::add($b, ':fiji:', '🇫🇯'); + Smilies::add($b, ':falklandislands:', '🇫🇰'); + Smilies::add($b, ':micronesia:', '🇫🇲'); + Smilies::add($b, ':faroeislands:', '🇫🇴'); + Smilies::add($b, ':france:', '🇫🇷'); + Smilies::add($b, ':gabon:', '🇬🇦'); + Smilies::add($b, ':unitedkingdom:', '🇬🇧'); + Smilies::add($b, ':grenada:', '🇬🇩'); + Smilies::add($b, ':georgia:', '🇬🇪'); + Smilies::add($b, ':frenchguiana:', '🇬🇫'); + Smilies::add($b, ':guernsey:', '🇬🇬'); + Smilies::add($b, ':ghana:', '🇬🇭'); + Smilies::add($b, ':gibraltar:', '🇬🇮'); + Smilies::add($b, ':greenland:', '🇬🇱'); + Smilies::add($b, ':gambia:', '🇬🇲'); + Smilies::add($b, ':guinea:', '🇬🇳'); + Smilies::add($b, ':guadeloupe:', '🇬🇵'); + Smilies::add($b, ':equatorialguinea:', '🇬🇶'); + Smilies::add($b, ':greece:', '🇬,;🇷'); + Smilies::add($b, ':southgeorgia&southsandwichislands:', '🇬🇸'); + Smilies::add($b, ':guatemala:', '🇬🇹'); + Smilies::add($b, ':guam:', '🇬🇺'); + Smilies::add($b, ':guinea-bissau:', '🇬🇼'); + Smilies::add($b, ':guyana:', '🇬🇾'); + Smilies::add($b, ':hongkongsarchina:', '🇭🇰'); + Smilies::add($b, ':heard&mcdonaldislands:', '🇭🇲'); + Smilies::add($b, ':honduras:', '🇭🇳'); + Smilies::add($b, ':croatia:', '🇭🇷'); + Smilies::add($b, ':haiti:', '🇭🇹'); + Smilies::add($b, ':hungary:', '🇭🇺'); + Smilies::add($b, ':canaryislands:', '🇮🇨'); + Smilies::add($b, ':indonesia:', '🇮🇩'); + Smilies::add($b, ':ireland:', '🇮🇪'); + Smilies::add($b, ':israel:', '🇮🇱'); + Smilies::add($b, ':isleofman:', '🇮🇲'); + Smilies::add($b, ':india:', '🇮🇳'); + Smilies::add($b, ':britishindianoceanterritory:', '🇮🇴'); + Smilies::add($b, ':iraq:', '🇮🇶'); + Smilies::add($b, ':iran:', '🇮🇷'); + Smilies::add($b, ':iceland:', '🇮🇸'); + Smilies::add($b, ':italy:', '🇮🇹'); + Smilies::add($b, ':jersey:', '🇯🇪'); + Smilies::add($b, ':jamaica:', '🇯🇲'); + Smilies::add($b, ':jordan:', '🇯🇴'); + Smilies::add($b, ':japan:', '🇯🇵'); + Smilies::add($b, ':kenya:', '🇰🇪'); + Smilies::add($b, ':kyrgyzstan:', '🇰🇬'); + Smilies::add($b, ':cambodia:', '🇰🇭'); + Smilies::add($b, ':kiribati:', '🇰🇮'); + Smilies::add($b, ':comoros:', '🇰🇲'); + Smilies::add($b, ':st.kitts&nevis:', '🇰🇳'); + Smilies::add($b, ':northkorea:', '🇰🇵'); + Smilies::add($b, ':southkorea:', '🇰🇷'); + Smilies::add($b, ':kuwait:', '🇰🇼'); + Smilies::add($b, ':caymanislands:', '🇰🇾'); + Smilies::add($b, ':kazakhstan:', '🇰🇿'); + Smilies::add($b, ':laos:', '🇱🇦'); + Smilies::add($b, ':lebanon:', '🇱🇧'); + Smilies::add($b, ':st.lucia:', '🇱🇨'); + Smilies::add($b, ':liechtenstein:', '🇱🇮'); + Smilies::add($b, ':srilanka:', '🇱🇰'); + Smilies::add($b, ':liberia:', '🇱🇷'); + Smilies::add($b, ':lesotho:', '🇱🇸'); + Smilies::add($b, ':lithuania:', '🇱🇹'); + Smilies::add($b, ':luxembourg:', '🇱🇺'); + Smilies::add($b, ':latvia:', '🇱🇻'); + Smilies::add($b, ':libya:', '🇱🇾'); + Smilies::add($b, ':morocco:', '🇲🇦'); + Smilies::add($b, ':monaco:', '🇲🇨'); + Smilies::add($b, ':moldova:', '🇲🇩'); + Smilies::add($b, ':montenegro:', '🇲🇪'); + Smilies::add($b, ':st.martin:', '🇲🇫'); + Smilies::add($b, ':madagascar:', '🇲🇬'); + Smilies::add($b, ':marshallislands:', '🇲🇭'); + Smilies::add($b, ':northmacedonia:', '🇲🇰'); + Smilies::add($b, ':mali:', '🇲🇱'); + Smilies::add($b, ':myanmar(burma):', '🇲🇲'); + Smilies::add($b, ':mongolia:', '🇲🇳'); + Smilies::add($b, ':macaosarchina:', '🇲🇴'); + Smilies::add($b, ':northernmarianaislands:', '🇲🇵'); + Smilies::add($b, ':martinique:', '🇲🇶'); + Smilies::add($b, ':mauritania:', '🇲🇷'); + Smilies::add($b, ':montserrat:', '🇲🇸'); + Smilies::add($b, ':malta:', '🇲🇹'); + Smilies::add($b, ':mauritius:', '🇲🇺'); + Smilies::add($b, ':maldives:', '🇲🇻'); + Smilies::add($b, ':malawi:', '🇲🇼'); + Smilies::add($b, ':mexico:', '🇲🇽'); + Smilies::add($b, ':malaysia:', '🇲🇾'); + Smilies::add($b, ':mozambique:', '🇲🇿'); + Smilies::add($b, ':namibia:', '🇳🇦'); + Smilies::add($b, ':newcaledonia:', '🇳🇨'); + Smilies::add($b, ':niger:', '🇳🇪'); + Smilies::add($b, ':norfolkisland:', '🇳🇫'); + Smilies::add($b, ':nigeria:', '🇳🇬'); + Smilies::add($b, ':nicaragua:', '🇳🇮'); + Smilies::add($b, ':netherlands:', '🇳🇱'); + Smilies::add($b, ':norway:', '🇳🇴'); + Smilies::add($b, ':nepal:', '🇳🇵'); + Smilies::add($b, ':nauru:', '🇳🇷'); + Smilies::add($b, ':niue:', '🇳🇺'); + Smilies::add($b, ':newzealand:', '🇳🇿'); + Smilies::add($b, ':oman:', '🇴🇲'); + Smilies::add($b, ':panama:', '🇵🇦'); + Smilies::add($b, ':peru:', '🇵🇪'); + Smilies::add($b, ':frenchpolynesia:', '🇵🇫'); + Smilies::add($b, ':papuanewguinea:', '🇵🇬'); + Smilies::add($b, ':philippines:', '🇵🇭'); + Smilies::add($b, ':pakistan:', '🇵🇰'); + Smilies::add($b, ':poland:', '🇵🇱'); + Smilies::add($b, ':st.pierre&miquelon:', '🇵🇲'); + Smilies::add($b, ':pitcairnislands:', '🇵🇳'); + Smilies::add($b, ':puertorico:', '🇵🇷'); + Smilies::add($b, ':palestinianterritories:', '🇵🇸'); + Smilies::add($b, ':portugal:', '🇵🇹'); + Smilies::add($b, ':palau:', '🇵🇼'); + Smilies::add($b, ':paraguay:', '🇵🇾'); + Smilies::add($b, ':qatar:', '🇶🇦'); + Smilies::add($b, ':réunion:', '🇷🇪'); + Smilies::add($b, ':romania:', '🇷🇴'); + Smilies::add($b, ':serbia:', '🇷🇸'); + Smilies::add($b, ':russia:', '🇷🇺'); + Smilies::add($b, ':rwanda:', '🇷🇼'); + Smilies::add($b, ':saudiarabia:', '🇸🇦'); + Smilies::add($b, ':solomonislands:', '🇸🇧'); + Smilies::add($b, ':seychelles:', '🇸🇨'); + Smilies::add($b, ':sudan:', '🇸🇩'); + Smilies::add($b, ':sweden:', '🇸🇪'); + Smilies::add($b, ':singapore:', '🇸🇬'); + Smilies::add($b, ':st.helena:', '🇸🇭'); + Smilies::add($b, ':slovenia:', '🇸🇮'); + Smilies::add($b, ':svalbard&janmayen:', '🇸🇯'); + Smilies::add($b, ':slovakia:', '🇸🇰'); + Smilies::add($b, ':sierraleone:', '🇸🇱'); + Smilies::add($b, ':sanmarino:', '🇸🇲'); + Smilies::add($b, ':senegal:', '🇸🇳'); + Smilies::add($b, ':somalia:', '🇸🇴'); + Smilies::add($b, ':suriname:', '🇸🇷'); + Smilies::add($b, ':southsudan:', '🇸🇸'); + Smilies::add($b, ':sãotomé&príncipe:', '🇸🇹'); + Smilies::add($b, ':elsalvador:', '🇸🇻'); + Smilies::add($b, ':sintmaarten:', '🇸🇽'); + Smilies::add($b, ':syria:', '🇸🇾'); + Smilies::add($b, ':eswatini:', '🇸🇿'); + Smilies::add($b, ':tristandacunha:', '🇹🇦'); + Smilies::add($b, ':turks&caicosislands:', '🇹🇨'); + Smilies::add($b, ':chad:', '🇹🇩'); + Smilies::add($b, ':frenchsouthernterritories:', '🇹🇫'); + Smilies::add($b, ':togo:', '🇹🇬'); + Smilies::add($b, ':thailand:', '🇹🇭'); + Smilies::add($b, ':tajikistan:', '🇹🇯'); + Smilies::add($b, ':tokelau:', '🇹🇰'); + Smilies::add($b, ':timor-leste:', '🇹🇱'); + Smilies::add($b, ':turkmenistan:', '🇹🇲'); + Smilies::add($b, ':tunisia:', '🇹🇳'); + Smilies::add($b, ':tonga:', '🇹🇴'); + Smilies::add($b, ':turkey:', '🇹🇷'); + Smilies::add($b, ':trinidad&tobago:', '🇹🇹'); + Smilies::add($b, ':tuvalu:', '🇹🇻'); + Smilies::add($b, ':taiwan:', '🇹🇼'); + Smilies::add($b, ':tanzania:', '🇹🇿'); + Smilies::add($b, ':ukraine:', '🇺🇦'); + Smilies::add($b, ':uganda:', '🇺🇬'); + Smilies::add($b, ':u.s.outlyingislands:', '🇺🇲'); + Smilies::add($b, ':unitednations:', '🇺🇳'); + Smilies::add($b, ':unitedstates:', '🇺🇸'); + Smilies::add($b, ':uruguay:', '🇺🇾'); + Smilies::add($b, ':uzbekistan:', '🇺🇿'); + Smilies::add($b, ':vaticancity:', '🇻🇦'); + Smilies::add($b, ':st.vincent&grenadines:', '🇻🇨'); + Smilies::add($b, ':venezuela:', '🇻🇪'); + Smilies::add($b, ':britishvirginislands:', '🇻🇬'); + Smilies::add($b, ':u.s.virginislands:', '🇻🇮'); + Smilies::add($b, ':vietnam:', '🇻🇳'); + Smilies::add($b, ':vanuatu:', '🇻🇺'); + Smilies::add($b, ':wallis&futuna:', '🇼🇫'); + Smilies::add($b, ':samoa:', '🇼🇸'); + Smilies::add($b, ':kosovo:', '🇽🇰'); + Smilies::add($b, ':yemen:', '🇾🇪'); + Smilies::add($b, ':mayotte:', '🇾🇹'); + Smilies::add($b, ':southafrica:', '🇿🇦'); + Smilies::add($b, ':zambia:', '🇿🇲'); + Smilies::add($b, ':zimbabwe:', '🇿🇼'); // subdivision-flag - Smilies::add($b, ':england:', '🏴󠁧󠁢󠁥󠁮󠁧󠁿'); - Smilies::add($b, ':scotland:', '🏴󠁧󠁢󠁳󠁴󠁿'); - Smilies::add($b, ':wales:', '🏴󠁧󠁢󠁷󠁬󠁳󠁿'); + Smilies::add($b, ':england:', '🏴󠁧󠁢󠁥󠁮󠁧󠁿'); + Smilies::add($b, ':scotland:', '🏴󠁧󠁢󠁳󠁴󠁿'); + Smilies::add($b, ':wales:', '🏴󠁧󠁢󠁷󠁬󠁳󠁿'); } + diff --git a/viewsrc/viewsrc.php b/viewsrc/viewsrc.php index c4d21ccb..bd07b541 100644 --- a/viewsrc/viewsrc.php +++ b/viewsrc/viewsrc.php @@ -7,7 +7,6 @@ * */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\DI; diff --git a/webdav_storage/src/WebDavConfig.php b/webdav_storage/src/WebDavConfig.php index 2236e97a..320b06a2 100644 --- a/webdav_storage/src/WebDavConfig.php +++ b/webdav_storage/src/WebDavConfig.php @@ -52,7 +52,7 @@ class WebDavConfig implements ICanConfigureStorage $this->config = $config; $this->client = $client; - $this->authOptions = null; + $this->authOptions = []; if (!empty($this->config->get('webdav', 'username'))) { $this->authOptions = [ diff --git a/webrtc/webrtc.php b/webrtc/webrtc.php index e142b374..e5d4ce6e 100644 --- a/webrtc/webrtc.php +++ b/webrtc/webrtc.php @@ -7,7 +7,6 @@ * Author: Tobias Diekershoff */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\Core\Renderer; use Friendica\DI; diff --git a/wppost/wppost.php b/wppost/wppost.php index f2ee5d21..de216806 100644 --- a/wppost/wppost.php +++ b/wppost/wppost.php @@ -9,7 +9,6 @@ use Friendica\Content\Text\BBCode; use Friendica\Content\Text\HTML; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\Database\DBA; use Friendica\DI; @@ -257,13 +256,13 @@ function wppost_send(array &$b) EOT; - Logger::debug('wppost: data: ' . $xml); + DI::logger()->debug('wppost: data: ' . $xml); $x = ''; if ($wp_blog !== 'test') { $x = DI::httpClient()->post($wp_blog, $xml)->getBodyString(); } - Logger::info('posted to wordpress: ' . $x); + DI::logger()->info('posted to wordpress: ' . $x); } }