]> git.mxchange.org Git - friendica.git/commitdiff
Merge pull request #7071 from nupplaphil/task/mod_bookmarklet
authorHypolite Petovan <hypolite@mrpetovan.com>
Fri, 3 May 2019 00:03:26 +0000 (20:03 -0400)
committerGitHub <noreply@github.com>
Fri, 3 May 2019 00:03:26 +0000 (20:03 -0400)
Move mod/bookmarklet to src/Module/BookMarklet

60 files changed:
mod/allfriends.php [deleted file]
mod/directory.php [deleted file]
mod/notify.php
mod/ping.php
mod/subthread.php
mod/tagger.php
src/App.php
src/App/Router.php
src/Console/ArchiveContact.php [new file with mode: 0644]
src/Console/AutomaticInstallation.php [new file with mode: 0644]
src/Console/Cache.php [new file with mode: 0644]
src/Console/Config.php [new file with mode: 0644]
src/Console/CreateDoxygen.php [new file with mode: 0644]
src/Console/DatabaseStructure.php [new file with mode: 0644]
src/Console/DocBloxErrorChecker.php [new file with mode: 0644]
src/Console/Extract.php [new file with mode: 0644]
src/Console/GlobalCommunityBlock.php [new file with mode: 0644]
src/Console/GlobalCommunitySilence.php [new file with mode: 0644]
src/Console/Maintenance.php [new file with mode: 0644]
src/Console/NewPassword.php [new file with mode: 0644]
src/Console/PhpToPo.php [new file with mode: 0644]
src/Console/PoToPhp.php [new file with mode: 0644]
src/Console/PostUpdate.php [new file with mode: 0644]
src/Console/ServerBlock.php [new file with mode: 0644]
src/Console/Storage.php [new file with mode: 0644]
src/Console/Typo.php [new file with mode: 0644]
src/Core/Console.php
src/Core/Console/ArchiveContact.php [deleted file]
src/Core/Console/AutomaticInstallation.php [deleted file]
src/Core/Console/Cache.php [deleted file]
src/Core/Console/Config.php [deleted file]
src/Core/Console/CreateDoxygen.php [deleted file]
src/Core/Console/DatabaseStructure.php [deleted file]
src/Core/Console/DocBloxErrorChecker.php [deleted file]
src/Core/Console/Extract.php [deleted file]
src/Core/Console/GlobalCommunityBlock.php [deleted file]
src/Core/Console/GlobalCommunitySilence.php [deleted file]
src/Core/Console/Maintenance.php [deleted file]
src/Core/Console/NewPassword.php [deleted file]
src/Core/Console/PhpToPo.php [deleted file]
src/Core/Console/PoToPhp.php [deleted file]
src/Core/Console/PostUpdate.php [deleted file]
src/Core/Console/ServerBlock.php [deleted file]
src/Core/Console/Storage.php [deleted file]
src/Core/Console/Typo.php [deleted file]
src/Model/Contact.php
src/Model/Item.php
src/Model/Profile.php
src/Module/AllFriends.php [new file with mode: 0644]
src/Module/Directory.php [new file with mode: 0644]
src/Module/Feed.php
src/Protocol/DFRN.php
tests/src/Console/AutomaticInstallationConsoleTest.php [new file with mode: 0644]
tests/src/Console/ConfigConsoleTest.php [new file with mode: 0644]
tests/src/Console/ConsoleTest.php [new file with mode: 0644]
tests/src/Console/ServerBlockConsoleTest.php [new file with mode: 0644]
tests/src/Core/Console/AutomaticInstallationConsoleTest.php [deleted file]
tests/src/Core/Console/ConfigConsoleTest.php [deleted file]
tests/src/Core/Console/ConsoleTest.php [deleted file]
tests/src/Core/Console/ServerBlockConsoleTest.php [deleted file]

diff --git a/mod/allfriends.php b/mod/allfriends.php
deleted file mode 100644 (file)
index ce648cc..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-<?php
-/**
- * @file mod/allfriends.php
- */
-
-use Friendica\App;
-use Friendica\Content\ContactSelector;
-use Friendica\Content\Pager;
-use Friendica\Core\L10n;
-use Friendica\Core\Renderer;
-use Friendica\Core\System;
-use Friendica\Database\DBA;
-use Friendica\Model;
-use Friendica\Module;
-use Friendica\Util\Proxy as ProxyUtils;
-
-
-function allfriends_content(App $a)
-{
-       $o = '';
-       if (!local_user()) {
-               notice(L10n::t('Permission denied.') . EOL);
-               return;
-       }
-
-       $cid = 0;
-       if ($a->argc > 1) {
-               $cid = intval($a->argv[1]);
-       }
-
-       if (!$cid) {
-               return;
-       }
-
-       $uid = $a->user['uid'];
-
-       $contact = DBA::selectFirst('contact', ['name', 'url', 'photo', 'uid', 'id'], ['id' => $cid, 'uid' => local_user()]);
-
-       if (!DBA::isResult($contact)) {
-               return;
-       }
-
-       $a->page['aside'] = "";
-       Model\Profile::load($a, "", 0, Model\Contact::getDetailsByURL($contact["url"]));
-
-       $total = Model\GContact::countAllFriends(local_user(), $cid);
-
-       $pager = new Pager($a->query_string);
-
-       $r = Model\GContact::allFriends(local_user(), $cid, $pager->getStart(), $pager->getItemsPerPage());
-       if (!DBA::isResult($r)) {
-               $o .= L10n::t('No friends to display.');
-               return $o;
-       }
-
-       $id = 0;
-
-       $entries = [];
-       foreach ($r as $rr) {
-               //get further details of the contact
-               $contact_details = Model\Contact::getDetailsByURL($rr['url'], $uid, $rr);
-
-               $connlnk = '';
-               // $rr[cid] is only available for common contacts. So if the contact is a common one, use contact_photo_menu to generate the photo_menu
-               // If the contact is not common to the user, Connect/Follow' will be added to the photo menu
-               if ($rr['cid']) {
-                       $rr['id'] = $rr['cid'];
-                       $photo_menu = Model\Contact::photoMenu($rr);
-               } else {
-                       $connlnk = System::baseUrl() . '/follow/?url=' . $rr['url'];
-                       $photo_menu = [
-                               'profile' => [L10n::t("View Profile"), Model\Contact::magicLink($rr['url'])],
-                               'follow' => [L10n::t("Connect/Follow"), $connlnk]
-                       ];
-               }
-
-               $entry = [
-                       'url'          => Model\Contact::magicLink($rr['url']),
-                       'itemurl'      => defaults($contact_details, 'addr', $rr['url']),
-                       'name'         => $contact_details['name'],
-                       'thumb'        => ProxyUtils::proxifyUrl($contact_details['thumb'], false, ProxyUtils::SIZE_THUMB),
-                       'img_hover'    => $contact_details['name'],
-                       'details'      => $contact_details['location'],
-                       'tags'         => $contact_details['keywords'],
-                       'about'        => $contact_details['about'],
-                       'account_type' => Model\Contact::getAccountType($contact_details),
-                       'network'      => ContactSelector::networkToName($contact_details['network'], $contact_details['url']),
-                       'photo_menu'   => $photo_menu,
-                       'conntxt'      => L10n::t('Connect'),
-                       'connlnk'      => $connlnk,
-                       'id'           => ++$id,
-               ];
-               $entries[] = $entry;
-       }
-
-       $tab_str = Module\Contact::getTabsHTML($a, $contact, 4);
-
-       $tpl = Renderer::getMarkupTemplate('viewcontact_template.tpl');
-       $o .= Renderer::replaceMacros($tpl, [
-               '$tab_str' => $tab_str,
-               '$contacts' => $entries,
-               '$paginate' => $pager->renderFull($total),
-       ]);
-
-       return $o;
-}
diff --git a/mod/directory.php b/mod/directory.php
deleted file mode 100644 (file)
index 256c9bb..0000000
+++ /dev/null
@@ -1,230 +0,0 @@
-<?php
-/**
- * @file mod/directory.php
- */
-
-use Friendica\App;
-use Friendica\Content\Nav;
-use Friendica\Content\Pager;
-use Friendica\Content\Widget;
-use Friendica\Core\Config;
-use Friendica\Core\Hook;
-use Friendica\Core\L10n;
-use Friendica\Core\Renderer;
-use Friendica\Database\DBA;
-use Friendica\Model\Contact;
-use Friendica\Model\Profile;
-use Friendica\Util\Proxy as ProxyUtils;
-use Friendica\Util\Strings;
-
-function directory_init(App $a)
-{
-       if (local_user()) {
-               $a->page['aside'] .= Widget::findPeople();
-               $a->page['aside'] .= Widget::follow();
-       } else {
-               unset($_SESSION['theme']);
-               unset($_SESSION['mobile-theme']);
-       }
-}
-
-function directory_post(App $a)
-{
-       if (!empty($_POST['search'])) {
-               $a->data['search'] = $_POST['search'];
-       }
-}
-
-function directory_content(App $a)
-{
-       if ((Config::get('system', 'block_public') && !local_user() && !remote_user())
-               || (Config::get('system', 'block_local_dir') && !local_user() && !remote_user())
-       ) {
-               notice(L10n::t('Public access denied.') . EOL);
-               return;
-       }
-
-       $o = '';
-       $entries = [];
-
-       Nav::setSelected('directory');
-
-       if (!empty($a->data['search'])) {
-               $search = Strings::escapeTags(trim($a->data['search']));
-       } else {
-               $search = (!empty($_GET['search']) ? Strings::escapeTags(trim(rawurldecode($_GET['search']))) : '');
-       }
-
-       $gdirpath = '';
-       $dirurl = Config::get('system', 'directory');
-       if (strlen($dirurl)) {
-               $gdirpath = Profile::zrl($dirurl, true);
-       }
-
-       if ($search) {
-               $search = DBA::escape($search);
-
-               $sql_extra = " AND ((`profile`.`name` LIKE '%$search%') OR
-                               (`user`.`nickname` LIKE '%$search%') OR
-                               (`profile`.`pdesc` LIKE '%$search%') OR
-                               (`profile`.`locality` LIKE '%$search%') OR
-                               (`profile`.`region` LIKE '%$search%') OR
-                               (`profile`.`country-name` LIKE '%$search%') OR
-                               (`profile`.`gender` LIKE '%$search%') OR
-                               (`profile`.`marital` LIKE '%$search%') OR
-                               (`profile`.`sexual` LIKE '%$search%') OR
-                               (`profile`.`about` LIKE '%$search%') OR
-                               (`profile`.`romance` LIKE '%$search%') OR
-                               (`profile`.`work` LIKE '%$search%') OR
-                               (`profile`.`education` LIKE '%$search%') OR
-                               (`profile`.`pub_keywords` LIKE '%$search%') OR
-                               (`profile`.`prv_keywords` LIKE '%$search%'))";
-       } else {
-               $sql_extra = '';
-       }
-
-       $publish = (Config::get('system', 'publish_all') ? '' : " AND `publish` = 1 " );
-
-
-       $total = 0;
-       $cnt = DBA::fetchFirst("SELECT COUNT(*) AS `total` FROM `profile`
-                               LEFT JOIN `user` ON `user`.`uid` = `profile`.`uid`
-                               WHERE `is-default` $publish AND NOT `user`.`blocked` AND NOT `user`.`account_removed` $sql_extra");
-       if (DBA::isResult($cnt)) {
-               $total = $cnt['total'];
-       }
-       $pager = new Pager($a->query_string, 60);
-
-       $order = " ORDER BY `name` ASC ";
-
-       $limit = $pager->getStart()."," . $pager->getItemsPerPage();
-
-       $r = DBA::p("SELECT `profile`.*, `profile`.`uid` AS `profile_uid`, `user`.`nickname`, `user`.`timezone` , `user`.`page-flags`,
-                       `contact`.`addr`, `contact`.`url` AS `profile_url` FROM `profile`
-                       LEFT JOIN `user` ON `user`.`uid` = `profile`.`uid`
-                       LEFT JOIN `contact` ON `contact`.`uid` = `user`.`uid`
-                       WHERE `is-default` $publish AND NOT `user`.`blocked` AND NOT `user`.`account_removed` AND `contact`.`self`
-                       $sql_extra $order LIMIT $limit"
-       );
-       if (DBA::isResult($r)) {
-               if (in_array('small', $a->argv)) {
-                       $photo = 'thumb';
-               } else {
-                       $photo = 'photo';
-               }
-
-               while ($rr = DBA::fetch($r)) {
-                       $entries[] = format_directory_entry($rr, $photo);
-               }
-               DBA::close($r);
-       } else {
-               info(L10n::t("No entries \x28some entries may be hidden\x29.") . EOL);
-       }
-
-       $tpl = Renderer::getMarkupTemplate('directory_header.tpl');
-
-       $o .= Renderer::replaceMacros($tpl, [
-               '$search'    => $search,
-               '$globaldir' => L10n::t('Global Directory'),
-               '$gdirpath'  => $gdirpath,
-               '$desc'      => L10n::t('Find on this site'),
-               '$contacts'  => $entries,
-               '$finding'   => L10n::t('Results for:'),
-               '$findterm'  => (strlen($search) ? $search : ""),
-               '$title'     => L10n::t('Site Directory'),
-               '$search_mod' => 'directory',
-               '$submit'    => L10n::t('Find'),
-               '$paginate'  => $pager->renderFull($total),
-       ]);
-
-       return $o;
-}
-
-/**
- * Format contact/profile/user data from the database into an usable
- * array for displaying directory entries.
- * 
- * @param array $arr The directory entry from the database.
- * @param string $photo_size Avatar size (thumb, photo or micro).
- * 
- * @return array
- */
-function format_directory_entry(array $arr, $photo_size = 'photo')
-{
-       $itemurl = (($arr['addr'] != "") ? $arr['addr'] : $arr['profile_url']);
-
-       $profile_link = $arr['profile_url'];
-
-       $pdesc = (($arr['pdesc']) ? $arr['pdesc'] . '<br />' : '');
-
-       $details = '';
-       if (strlen($arr['locality'])) {
-               $details .= $arr['locality'];
-       }
-       if (strlen($arr['region'])) {
-               if (strlen($arr['locality'])) {
-                       $details .= ', ';
-               }
-               $details .= $arr['region'];
-       }
-       if (strlen($arr['country-name'])) {
-               if (strlen($details)) {
-                       $details .= ', ';
-               }
-               $details .= $arr['country-name'];
-       }
-
-       $profile = $arr;
-
-       if (!empty($profile['address'])
-               || !empty($profile['locality'])
-               || !empty($profile['region'])
-               || !empty($profile['postal-code'])
-               || !empty($profile['country-name'])
-       ) {
-               $location = L10n::t('Location:');
-       } else {
-               $location = '';
-       }
-
-       $gender   = (!empty($profile['gender'])   ? L10n::t('Gender:')   : false);
-       $marital  = (!empty($profile['marital'])  ? L10n::t('Status:')   : false);
-       $homepage = (!empty($profile['homepage']) ? L10n::t('Homepage:') : false);
-       $about    = (!empty($profile['about'])    ? L10n::t('About:')    : false);
-
-       $location_e = $location;
-
-       $photo_menu = [
-               'profile' => [L10n::t("View Profile"), Contact::magicLink($profile_link)]
-       ];
-
-       $entry = [
-               'id'           => $arr['id'],
-               'url'          => Contact::magicLInk($profile_link),
-               'itemurl'      => $itemurl,
-               'thumb'        => ProxyUtils::proxifyUrl($arr[$photo_size], false, ProxyUtils::SIZE_THUMB),
-               'img_hover'    => $arr['name'],
-               'name'         => $arr['name'],
-               'details'      => $details,
-               'account_type' => Contact::getAccountType($arr),
-               'profile'      => $profile,
-               'location'     => $location_e,
-               'tags'         => $arr['pub_keywords'],
-               'gender'       => $gender,
-               'pdesc'        => $pdesc,
-               'marital'      => $marital,
-               'homepage'     => $homepage,
-               'about'        => $about,
-               'photo_menu'   => $photo_menu,
-
-       ];
-
-       $hook = ['contact' => $arr, 'entry' => $entry];
-
-       Hook::callAll('directory_item', $hook);
-
-       unset($profile);
-       unset($location);
-
-       return $hook['entry'];
-}
index 87035817841d637b957037051ca087b34a9551ba..7f9974d30a1e5737b1d61ddc4dd089a29641c70e 100644 (file)
@@ -26,18 +26,6 @@ function notify_init(App $a)
                $note = $nm->getByID($a->argv[2]);
                if ($note) {
                        $nm->setSeen($note);
-
-                       // The friendica client has problems with the GUID. this is some workaround
-                       if ($a->isFriendicaApp()) {
-                               require_once("include/items.php");
-                               $urldata = parse_url($note['link']);
-                               $guid = basename($urldata["path"]);
-                               $itemdata = Item::getIdAndNickByGuid($guid, local_user());
-                               if ($itemdata["id"] != 0) {
-                                       $note['link'] = System::baseUrl().'/display/'.$itemdata["nick"].'/'.$itemdata["id"];
-                               }
-                       }
-
                        System::externalRedirect($note['link']);
                }
 
index b89cb9246c29b45c5fe9656c0c569ee4b140d924..9b844cc48ddc02ad7ce52f3753e20f3d74cd08ce 100644 (file)
@@ -313,14 +313,7 @@ function ping_init(App $a)
                usort($notifs, $sort_function);
 
                if (DBA::isResult($notifs)) {
-                       // Are the nofications called from the regular process or via the friendica app?
-                       $regularnotifications = (!empty($_GET['uid']) && !empty($_GET['_']));
-
                        foreach ($notifs as $notif) {
-                               if ($a->isFriendicaApp() || !$regularnotifications) {
-                                       $notif['message'] = str_replace("{0}", $notif['name'], $notif['message']);
-                               }
-
                                $contact = Contact::getDetailsByURL($notif['url']);
                                if (isset($contact['micro'])) {
                                        $notif['photo'] = ProxyUtils::proxifyUrl($contact['micro'], false, ProxyUtils::SIZE_MICRO);
index 23ebf4fe4858f40a7f46f2bde0a6251852edb09d..9fa1a410d37130eff5ad646e84f840c0c1011ba5 100644 (file)
@@ -87,7 +87,7 @@ function subthread_content(App $a) {
 
        $post_type = (($item['resource-id']) ? L10n::t('photo') : L10n::t('status'));
        $objtype = (($item['resource-id']) ? ACTIVITY_OBJ_IMAGE : ACTIVITY_OBJ_NOTE );
-       $link = XML::escape('<link rel="alternate" type="text/html" href="' . System::baseUrl() . '/display/' . $owner['nickname'] . '/' . $item['id'] . '" />' . "\n");
+       $link = XML::escape('<link rel="alternate" type="text/html" href="' . System::baseUrl() . '/display/' . $item['guid'] . '" />' . "\n");
        $body = $item['body'];
 
        $obj = <<< EOT
@@ -128,7 +128,7 @@ EOT;
 
        $ulink = '[url=' . $contact['url'] . ']' . $contact['name'] . '[/url]';
        $alink = '[url=' . $item['author-link'] . ']' . $item['author-name'] . '[/url]';
-       $plink = '[url=' . System::baseUrl() . '/display/' . $owner['nickname'] . '/' . $item['id'] . ']' . $post_type . '[/url]';
+       $plink = '[url=' . System::baseUrl() . '/display/' . $item['guid'] . ']' . $post_type . '[/url]';
        $arr['body'] =  sprintf( $bodyverb, $ulink, $alink, $plink );
 
        $arr['verb'] = $activity;
index 7cb43e330c951989b94e61cb7375dfe9836e20f0..5d3d1923e4425958b4d53a00e3ea436cd8553c76 100644 (file)
@@ -40,14 +40,12 @@ function tagger_content(App $a) {
        }
 
        $owner_uid = $item['uid'];
-       $owner_nick = '';
        $blocktags = 0;
 
-       $r = q("select `nickname`,`blocktags` from user where uid = %d limit 1",
+       $r = q("select `blocktags` from user where uid = %d limit 1",
                intval($owner_uid)
        );
        if (DBA::isResult($r)) {
-               $owner_nick = $r[0]['nickname'];
                $blocktags = $r[0]['blocktags'];
        }
 
@@ -69,12 +67,7 @@ function tagger_content(App $a) {
        $xterm = XML::escape($term);
        $post_type = (($item['resource-id']) ? L10n::t('photo') : L10n::t('status'));
        $targettype = (($item['resource-id']) ? ACTIVITY_OBJ_IMAGE : ACTIVITY_OBJ_NOTE );
-
-       if ($owner_nick) {
-               $href = System::baseUrl() . '/display/' . $owner_nick . '/' . $item['id'];
-       } else {
-               $href = System::baseUrl() . '/display/' . $item['guid'];
-       }
+       $href = System::baseUrl() . '/display/' . $item['guid'];
 
        $link = XML::escape('<link rel="alternate" type="text/html" href="'. $href . '" />' . "\n");
 
index f3b0ab64156c7be4dd6ba8e055e51c838fb87060..017661c4ca666081ad997b5e5d97ad7ce3ed4d08 100644 (file)
@@ -87,11 +87,6 @@ class App
         */
        private $baseURL;
 
-       /**
-        * @var bool true, if the call is from the Friendica APP, otherwise false
-        */
-       private $isFriendicaApp;
-
        /**
         * @var bool true, if the call is from an backend node (f.e. worker)
         */
@@ -257,8 +252,6 @@ class App
                $this->profiler = $profiler;
                $this->logger   = $logger;
 
-               $this->checkFriendicaApp();
-
                $this->profiler->reset();
 
                $this->reload();
@@ -601,28 +594,6 @@ class App
                        $this->getBaseURL();
        }
 
-       /**
-        * Checks, if the call is from the Friendica App
-        *
-        * Reason:
-        * The friendica client has problems with the GUID in the notify. this is some workaround
-        */
-       private function checkFriendicaApp()
-       {
-               // Friendica-Client
-               $this->isFriendicaApp = isset($_SERVER['HTTP_USER_AGENT']) && $_SERVER['HTTP_USER_AGENT'] == 'Apache-HttpClient/UNAVAILABLE (java 1.4)';
-       }
-
-       /**
-        *      Is the call via the Friendica app? (not a "normale" call)
-        *
-        * @return bool true if it's from the Friendica app
-        */
-       public function isFriendicaApp()
-       {
-               return $this->isFriendicaApp;
-       }
-
        /**
         * @brief Checks if the site is called via a backend process
         *
@@ -1006,10 +977,9 @@ class App
        {
                // Missing DB connection: ERROR
                if ($this->getMode()->has(App\Mode::LOCALCONFIGPRESENT) && !$this->getMode()->has(App\Mode::DBAVAILABLE)) {
-                       echo Module\Special\HTTPException::rawContent(
+                       Module\Special\HTTPException::rawContent(
                                new HTTPException\InternalServerErrorException('Apologies but the website is unavailable at the moment.')
                        );
-                       exit;
                }
 
                // Max Load Average reached: ERROR
@@ -1017,17 +987,15 @@ class App
                        header('Retry-After: 120');
                        header('Refresh: 120; url=' . $this->getBaseURL() . "/" . $this->query_string);
 
-                       echo Module\Special\HTTPException::rawContent(
+                       Module\Special\HTTPException::rawContent(
                                new HTTPException\ServiceUnavaiableException('The node is currently overloaded. Please try again later.')
                        );
-                       exit;
                }
 
                if (strstr($this->query_string, '.well-known/host-meta') && ($this->query_string != '.well-known/host-meta')) {
-                       echo Module\Special\HTTPException::rawContent(
+                       Module\Special\HTTPException::rawContent(
                                new HTTPException\NotFoundException()
                        );
-                       exit;
                }
 
                if (!$this->getMode()->isInstall()) {
@@ -1078,10 +1046,9 @@ class App
                                        // Someone came with an invalid parameter, maybe as a DDoS attempt
                                        // We simply stop processing here
                                        Core\Logger::log("Invalid ZRL parameter " . $_GET['zrl'], Core\Logger::DEBUG);
-                                       echo Module\Special\HTTPException::rawContent(
+                                       Module\Special\HTTPException::rawContent(
                                                new HTTPException\ForbiddenException()
                                        );
-                                       exit;
                                }
                        }
                }
@@ -1202,11 +1169,6 @@ class App
                        }
                }
 
-               // Then we try name-matching a Friendica\Module class
-               if (!$this->module_class && class_exists('Friendica\\Module\\' . ucfirst($this->module))) {
-                       $this->module_class = 'Friendica\\Module\\' . ucfirst($this->module);
-               }
-
                /* Finally, we look for a 'standard' program module in the 'mod' directory
                 * We emulate a Module class through the LegacyModule class
                 */
@@ -1272,8 +1234,7 @@ class App
                        Core\Hook::callAll($this->module . '_mod_afterpost', $placeholder);
                        call_user_func([$this->module_class, 'afterpost']);
                } catch(HTTPException $e) {
-                       echo Module\Special\HTTPException::rawContent($e);
-                       exit;
+                       Module\Special\HTTPException::rawContent($e);
                }
 
                $content = '';
index db40599dd295278930e71009a502ff511e823d10..83cdf425542c5c3a2df8fa59f46498879eef5f31 100644 (file)
@@ -40,15 +40,51 @@ class Router
         */
        public function collectRoutes()
        {
-               $this->routeCollector->addRoute(['GET', 'POST'], '/itemsource[/{guid}]', Module\Itemsource::class);
-               $this->routeCollector->addRoute(['GET'],         '/amcd',                Module\AccountManagementControlDocument::class);
                $this->routeCollector->addGroup('/.well-known', function (RouteCollector $collector) {
                        $collector->addRoute(['GET'], '/host-meta'       , Module\WellKnown\HostMeta::class);
                        $collector->addRoute(['GET'], '/nodeinfo[/1.0]'  , Module\NodeInfo::class);
                        $collector->addRoute(['GET'], '/webfinger'       , Module\Xrd::class);
                        $collector->addRoute(['GET'], '/x-social-relay'  , Module\WellKnown\XSocialRelay::class);
                });
+               $this->routeCollector->addGroup('/admin', function (RouteCollector $collector) {
+                       $collector->addRoute(['GET']        , '[/]'                     , Module\Admin\Summary::class);
+
+                       $collector->addRoute(['GET', 'POST'], '/addons'                 , Module\Admin\Addons\Index::class);
+                       $collector->addRoute(['GET', 'POST'], '/addons/{addon}'         , Module\Admin\Addons\Details::class);
+
+                       $collector->addRoute(['GET', 'POST'], '/blocklist/contact'      , Module\Admin\Blocklist\Contact::class);
+                       $collector->addRoute(['GET', 'POST'], '/blocklist/server'       , Module\Admin\Blocklist\Server::class);
+
+                       $collector->addRoute(['GET']        , '/dbsync[/check]'         , Module\Admin\DBSync::class);
+                       $collector->addRoute(['GET']        , '/dbsync/{update:\d+}'    , Module\Admin\DBSync::class);
+                       $collector->addRoute(['GET']        , '/dbsync/mark/{update:\d+}', Module\Admin\DBSync::class);
+
+                       $collector->addRoute(['GET', 'POST'], '/features'               , Module\Admin\Features::class);
+                       $collector->addRoute(['GET']        , '/federation'             , Module\Admin\Federation::class);
+
+                       $collector->addRoute(['GET', 'POST'], '/item/delete'            , Module\Admin\Item\Delete::class);
+                       $collector->addRoute(['GET', 'POST'], '/item/source[/{guid}]'   , Module\Admin\Item\Source::class);
+
+                       $collector->addRoute(['GET']        , '/logs/view'              , Module\Admin\Logs\View::class);
+                       $collector->addRoute(['GET', 'POST'], '/logs'                   , Module\Admin\Logs\Settings::class);
+
+                       $collector->addRoute(['GET']        , '/phpinfo'                , Module\Admin\PhpInfo::class);
+
+                       $collector->addRoute(['GET']        , '/queue[/deferred]'       , Module\Admin\Queue::class);
+
+                       $collector->addRoute(['GET', 'POST'], '/site'                   , Module\Admin\Site::class);
+
+                       $collector->addRoute(['GET', 'POST'], '/themes'                 , Module\Admin\Themes\Index::class);
+                       $collector->addRoute(['GET', 'POST'], '/themes/{theme}'         , Module\Admin\Themes\Details::class);
+                       $collector->addRoute(['GET', 'POST'], '/themes/{theme}/embed'   , Module\Admin\Themes\Embed::class);
+
+                       $collector->addRoute(['GET', 'POST'], '/tos'                    , Module\Admin\Tos::class);
+
+                       $collector->addRoute(['GET', 'POST'], '/users[/{action}/{uid}]' , Module\Admin\Users::class);
+               });
+               $this->routeCollector->addRoute(['GET'],         '/amcd',                Module\AccountManagementControlDocument::class);
                $this->routeCollector->addRoute(['GET'],         '/acctlink',            Module\Acctlink::class);
+               $this->routeCollector->addRoute(['GET'],         '/allfriends/{id:\d+}', Module\AllFriends::class);
                $this->routeCollector->addRoute(['GET'],         '/apps',                Module\Apps::class);
                $this->routeCollector->addRoute(['GET'],         '/attach/{item:\d+}',   Module\Attach::class);
                $this->routeCollector->addRoute(['GET'],         '/babel',               Module\Babel::class);
@@ -65,6 +101,7 @@ class Router
                        $collector->addRoute(['GET'], '/{nickname}/replies',                 Module\Feed::class);
                        $collector->addRoute(['GET'], '/{nickname}/activity',                Module\Feed::class);
                });
+               $this->routeCollector->addRoute(['GET'],         '/directory',           Module\Directory::class);
                $this->routeCollector->addRoute(['GET'],         '/feedtest',            Module\Feedtest::class);
                $this->routeCollector->addRoute(['GET'],         '/filer[/{id:\d+}]',    Module\Filer::class);
                $this->routeCollector->addRoute(['GET'],         '/followers/{owner}',   Module\Followers::class);
@@ -86,6 +123,7 @@ class Router
                        $collector->addRoute(['GET', 'POST'], '[/]',                         Module\Install::class);
                        $collector->addRoute(['GET'],         '/testrewrite',                Module\Install::class);
                });
+               $this->routeCollector->addRoute(['GET', 'POST'], '/itemsource[/{guid}]', Module\Itemsource::class);
                $this->routeCollector->addRoute(['GET', 'POST'], '/localtime',           Module\Localtime::class);
                $this->routeCollector->addRoute(['GET', 'POST'], '/login',               Module\Login::class);
                $this->routeCollector->addRoute(['GET'],         '/magic',               Module\Magic::class);
@@ -118,43 +156,6 @@ class Router
                $this->routeCollector->addRoute(['GET'],         '/tos',                 Module\Tos::class);
                $this->routeCollector->addRoute(['GET'],         '/webfinger',           Module\WebFinger::class);
                $this->routeCollector->addRoute(['GET'],         '/xrd',                 Module\Xrd::class);
-
-               $this->routeCollector->addGroup('/admin', function (RouteCollector $collector) {
-                       $collector->addRoute(['GET']        , '[/]'                     , Module\Admin\Summary::class);
-
-                       $collector->addRoute(['GET', 'POST'], '/addons'                 , Module\Admin\Addons\Index::class);
-                       $collector->addRoute(['GET', 'POST'], '/addons/{addon}'         , Module\Admin\Addons\Details::class);
-
-                       $collector->addRoute(['GET', 'POST'], '/blocklist/contact'      , Module\Admin\Blocklist\Contact::class);
-                       $collector->addRoute(['GET', 'POST'], '/blocklist/server'       , Module\Admin\Blocklist\Server::class);
-
-                       $collector->addRoute(['GET']        , '/dbsync[/check]'         , Module\Admin\DBSync::class);
-                       $collector->addRoute(['GET']        , '/dbsync/{update:\d+}'    , Module\Admin\DBSync::class);
-                       $collector->addRoute(['GET']        , '/dbsync/mark/{update:\d+}', Module\Admin\DBSync::class);
-
-                       $collector->addRoute(['GET', 'POST'], '/features'               , Module\Admin\Features::class);
-                       $collector->addRoute(['GET']        , '/federation'             , Module\Admin\Federation::class);
-
-                       $collector->addRoute(['GET', 'POST'], '/item/delete'            , Module\Admin\Item\Delete::class);
-                       $collector->addRoute(['GET', 'POST'], '/item/source[/{guid}]'   , Module\Admin\Item\Source::class);
-
-                       $collector->addRoute(['GET']        , '/logs/view'              , Module\Admin\Logs\View::class);
-                       $collector->addRoute(['GET', 'POST'], '/logs'                   , Module\Admin\Logs\Settings::class);
-
-                       $collector->addRoute(['GET']        , '/phpinfo'                , Module\Admin\PhpInfo::class);
-
-                       $collector->addRoute(['GET']        , '/queue[/deferred]'       , Module\Admin\Queue::class);
-
-                       $collector->addRoute(['GET', 'POST'], '/site'                   , Module\Admin\Site::class);
-
-                       $collector->addRoute(['GET', 'POST'], '/themes'                 , Module\Admin\Themes\Index::class);
-                       $collector->addRoute(['GET', 'POST'], '/themes/{theme}'         , Module\Admin\Themes\Details::class);
-                       $collector->addRoute(['GET', 'POST'], '/themes/{theme}/embed'   , Module\Admin\Themes\Embed::class);
-
-                       $collector->addRoute(['GET', 'POST'], '/tos'                    , Module\Admin\Tos::class);
-
-                       $collector->addRoute(['GET', 'POST'], '/users[/{action}/{uid}]' , Module\Admin\Users::class);
-               });
        }
 
        public function __construct(RouteCollector $routeCollector = null)
diff --git a/src/Console/ArchiveContact.php b/src/Console/ArchiveContact.php
new file mode 100644 (file)
index 0000000..cf177cf
--- /dev/null
@@ -0,0 +1,75 @@
+<?php
+
+namespace Friendica\Console;
+
+use Friendica\Core\L10n;
+use Friendica\Database\DBA;
+use Friendica\Util\Strings;
+use RuntimeException;
+
+/**
+ * @brief tool to archive a contact on the server
+ *
+ * With this tool you can archive a contact when you know that it isn't existing anymore.
+ * Normally this does happen automatically after a few days.
+ *
+ * License: AGPLv3 or later, same as Friendica
+ *
+ */
+class ArchiveContact extends \Asika\SimpleConsole\Console
+{
+       protected $helpOptions = ['h', 'help', '?'];
+
+       protected function getHelp()
+       {
+               $help = <<<HELP
+console archivecontact - archive a contact
+Usage
+       bin/console archivecontact <profile_url> [-h|--help|-?] [-v]
+
+Description
+       Archive a contact when you know that it isn't existing anymore. Normally this does happen automatically after a few days.
+
+Options
+    -h|--help|-? Show help information
+    -v           Show more debug information.
+HELP;
+               return $help;
+       }
+
+       protected function doExecute()
+       {
+               $a = \Friendica\BaseObject::getApp();
+
+               if ($this->getOption('v')) {
+                       $this->out('Class: ' . __CLASS__);
+                       $this->out('Arguments: ' . var_export($this->args, true));
+                       $this->out('Options: ' . var_export($this->options, true));
+               }
+
+               if (count($this->args) == 0) {
+                       $this->out($this->getHelp());
+                       return 0;
+               }
+
+               if (count($this->args) > 1) {
+                       throw new \Asika\SimpleConsole\CommandArgsException('Too many arguments');
+               }
+
+               if ($a->getMode()->isInstall()) {
+                       throw new RuntimeException('Friendica isn\'t properly installed yet.');
+               }
+
+               $nurl = Strings::normaliseLink($this->getArgument(0));
+               if (!DBA::exists('contact', ['nurl' => $nurl, 'archive' => false])) {
+                       throw new RuntimeException(L10n::t('Could not find any unarchived contact entry for this URL (%s)', $nurl));
+               }
+               if (DBA::update('contact', ['archive' => true], ['nurl' => $nurl])) {
+                       $this->out(L10n::t('The contact entries have been archived'));
+               } else {
+                       throw new RuntimeException('The contact archival failed.');
+               }
+
+               return 0;
+       }
+}
diff --git a/src/Console/AutomaticInstallation.php b/src/Console/AutomaticInstallation.php
new file mode 100644 (file)
index 0000000..718573d
--- /dev/null
@@ -0,0 +1,265 @@
+<?php
+
+namespace Friendica\Console;
+
+use Asika\SimpleConsole\Console;
+use Friendica\BaseObject;
+use Friendica\Core\Config;
+use Friendica\Core\Installer;
+use Friendica\Core\Theme;
+use Friendica\Util\BasePath;
+use Friendica\Util\BaseURL;
+use Friendica\Util\Config\ConfigFileLoader;
+use RuntimeException;
+
+class AutomaticInstallation extends Console
+{
+       protected function getHelp()
+       {
+               return <<<HELP
+Installation - Install Friendica automatically
+Synopsis
+       bin/console autoinstall [-h|--help|-?] [-v] [-a] [-f]
+
+Description
+    Installs Friendica with data based on the local.config.php file or environment variables
+
+Notes
+    Not checking .htaccess/URL-Rewrite during CLI installation.
+
+Options
+    -h|--help|-?            Show help information
+    -v                      Show more debug information.
+    -a                      All setup checks are required (except .htaccess)
+    -f|--file <config>      prepared config file (e.g. "config/local.config.php" itself) which will override every other config option - except the environment variables)
+    -s|--savedb               Save the DB credentials to the file (if environment variables is used)
+    -H|--dbhost <host>        The host of the mysql/mariadb database (env MYSQL_HOST)
+    -p|--dbport <port>        The port of the mysql/mariadb database (env MYSQL_PORT)
+    -d|--dbdata <database>    The name of the mysql/mariadb database (env MYSQL_DATABASE)
+    -U|--dbuser <username>    The username of the mysql/mariadb database login (env MYSQL_USER or MYSQL_USERNAME)
+    -P|--dbpass <password>    The password of the mysql/mariadb database login (env MYSQL_PASSWORD)
+    -U|--url <url>            The full base URL of Friendica - f.e. 'https://friendica.local/sub' (env FRIENDICA_URL) 
+    -B|--phppath <php_path>   The path of the PHP binary (env FRIENDICA_PHP_PATH)
+    -b|--basepath <base_path> The basepath of Friendica (env FRIENDICA_BASE_PATH)
+    -t|--tz <timezone>        The timezone of Friendica (env FRIENDICA_TZ)
+    -L|--lang <language>      The language of Friendica (env FRIENDICA_LANG)
+Environment variables
+   MYSQL_HOST                  The host of the mysql/mariadb database (mandatory if mysql and environment is used)
+   MYSQL_PORT                  The port of the mysql/mariadb database
+   MYSQL_USERNAME|MYSQL_USER   The username of the mysql/mariadb database login (MYSQL_USERNAME is for mysql, MYSQL_USER for mariadb)
+   MYSQL_PASSWORD              The password of the mysql/mariadb database login
+   MYSQL_DATABASE              The name of the mysql/mariadb database
+   FRIENDICA_URL               The full base URL of Friendica - f.e. 'https://friendica.local/sub'
+   FRIENDICA_PHP_PATH          The path of the PHP binary - leave empty for auto detection
+   FRIENDICA_BASE_PATH         The basepath of Friendica - leave empty for auto detection
+   FRIENDICA_ADMIN_MAIL        The admin email address of Friendica (this email will be used for admin access)
+   FRIENDICA_TZ                The timezone of Friendica
+   FRIENDICA_LANG              The langauge of Friendica
+   
+Examples
+       bin/console autoinstall -f 'input.config.php
+               Installs Friendica with the prepared 'input.config.php' file
+
+       bin/console autoinstall --savedb
+               Installs Friendica with environment variables and saves them to the 'config/local.config.php' file
+
+       bin/console autoinstall -h localhost -p 3365 -U user -P passwort1234 -d friendica
+               Installs Friendica with a local mysql database with credentials
+HELP;
+       }
+
+       protected function doExecute()
+       {
+               // Initialise the app
+               $this->out("Initializing setup...\n");
+
+               $a = BaseObject::getApp();
+
+               $installer = new Installer();
+
+               $configCache = $a->getConfigCache();
+               $installer->setUpCache($configCache, BasePath::create($a->getBasePath(), $_SERVER));
+
+               $this->out(" Complete!\n\n");
+
+               // Check Environment
+               $this->out("Checking environment...\n");
+
+               $installer->resetChecks();
+
+               if (!$this->runBasicChecks($installer, $configCache)) {
+                       $errorMessage = $this->extractErrors($installer->getChecks());
+                       throw new RuntimeException($errorMessage);
+               }
+
+               $this->out(" Complete!\n\n");
+
+               // if a config file is set,
+               $config_file = $this->getOption(['f', 'file']);
+
+               if (!empty($config_file)) {
+                       if ($config_file != 'config' . DIRECTORY_SEPARATOR . 'local.config.php') {
+                               // Copy config file
+                               $this->out("Copying config file...\n");
+                               if (!copy($a->getBasePath() . DIRECTORY_SEPARATOR . $config_file, $a->getBasePath() . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'local.config.php')) {
+                                       throw new RuntimeException("ERROR: Saving config file failed. Please copy '$config_file' to '" . $a->getBasePath() . "'" . DIRECTORY_SEPARATOR . "config" . DIRECTORY_SEPARATOR . "local.config.php' manually.\n");
+                               }
+                       }
+
+                       //reload the config cache
+                       $loader = new ConfigFileLoader($a->getBasePath(), $a->getMode());
+                       $loader->setupCache($configCache);
+
+               } else {
+                       // Creating config file
+                       $this->out("Creating config file...\n");
+
+                       $save_db = $this->getOption(['s', 'savedb'], false);
+
+                       $db_host = $this->getOption(['H', 'dbhost'], ($save_db) ? (getenv('MYSQL_HOST')) : Installer::DEFAULT_HOST);
+                       $db_port = $this->getOption(['p', 'dbport'], ($save_db) ? getenv('MYSQL_PORT') : null);
+                       $configCache->set('database', 'hostname', $db_host . (!empty($db_port) ? ':' . $db_port : ''));
+                       $configCache->set('database', 'database',
+                               $this->getOption(['d', 'dbdata'],
+                                       ($save_db) ? getenv('MYSQL_DATABASE') : ''));
+                       $configCache->set('database', 'username',
+                               $this->getOption(['U', 'dbuser'],
+                                       ($save_db) ? getenv('MYSQL_USER') . getenv('MYSQL_USERNAME') : ''));
+                       $configCache->set('database', 'password',
+                               $this->getOption(['P', 'dbpass'],
+                                       ($save_db) ? getenv('MYSQL_PASSWORD') : ''));
+
+                       $php_path = $this->getOption(['b', 'phppath'], !empty('FRIENDICA_PHP_PATH') ? getenv('FRIENDICA_PHP_PATH') : null);
+                       if (!empty($php_path)) {
+                               $configCache->set('config', 'php_path', $php_path);
+                       } else {
+                               $configCache->set('config', 'php_path', $installer->getPHPPath());
+                       }
+
+                       $configCache->set('config', 'admin_email',
+                               $this->getOption(['A', 'admin'],
+                                       !empty(getenv('FRIENDICA_ADMIN_MAIL')) ? getenv('FRIENDICA_ADMIN_MAIL') : ''));
+                       $configCache->set('system', 'default_timezone',
+                               $this->getOption(['T', 'tz'],
+                                       !empty(getenv('FRIENDICA_TZ')) ? getenv('FRIENDICA_TZ') : Installer::DEFAULT_TZ));
+                       $configCache->set('system', 'language',
+                               $this->getOption(['L', 'lang'],
+                                       !empty(getenv('FRIENDICA_LANG')) ? getenv('FRIENDICA_LANG') : Installer::DEFAULT_LANG));
+
+                       $basepath = $this->getOption(['b', 'basepath'], !empty(getenv('FRIENDICA_BASE_PATH')) ? getenv('FRIENDICA_BASE_PATH') : null);
+                       if (!empty($basepath)) {
+                               $configCache->set('system', 'basepath', $basepath);
+                       }
+
+                       $url = $this->getOption(['U', 'url'], !empty(getenv('FRIENDICA_URL')) ? getenv('FRIENDICA_URL') : null);
+
+                       if (empty($url)) {
+                               $this->out('The Friendica URL has to be set during CLI installation.');
+                               return 1;
+                       } else {
+                               $baseUrl = new BaseURL($a->getConfig(), []);
+                               $baseUrl->saveByURL($url);
+                       }
+
+                       $installer->createConfig($configCache);
+               }
+
+               $this->out(" Complete!\n\n");
+
+               // Check database connection
+               $this->out("Checking database...\n");
+
+               $installer->resetChecks();
+
+               if (!$installer->checkDB($configCache, $a->getProfiler())) {
+                       $errorMessage = $this->extractErrors($installer->getChecks());
+                       throw new RuntimeException($errorMessage);
+               }
+
+               $this->out(" Complete!\n\n");
+
+               // Install database
+               $this->out("Inserting data into database...\n");
+
+               $installer->resetChecks();
+
+               if (!$installer->installDatabase($a->getBasePath())) {
+                       $errorMessage = $this->extractErrors($installer->getChecks());
+                       throw new RuntimeException($errorMessage);
+               }
+
+               $this->out(" Complete!\n\n");
+
+               // Install theme
+               $this->out("Installing theme\n");
+               if (!empty(Config::get('system', 'theme'))) {
+                       Theme::install(Config::get('system', 'theme'));
+                       $this->out(" Complete\n\n");
+               } else {
+                       $this->out(" Theme setting is empty. Please check the file 'config/local.config.php'\n\n");
+               }
+
+               $this->out("\nInstallation is finished\n");
+
+               return 0;
+       }
+
+       /**
+        * @param Installer                 $installer   The Installer instance
+        * @param Config\Cache\IConfigCache $configCache The config cache
+        *
+        * @return bool true if checks were successfully, otherwise false
+        * @throws \Friendica\Network\HTTPException\InternalServerErrorException
+        */
+       private function runBasicChecks(Installer $installer, Config\Cache\IConfigCache $configCache)
+       {
+               $checked = true;
+
+               $installer->resetChecks();
+               if (!$installer->checkFunctions())              {
+                       $checked = false;
+               }
+               if (!$installer->checkImagick()) {
+                       $checked = false;
+               }
+               if (!$installer->checkLocalIni()) {
+                       $checked = false;
+               }
+               if (!$installer->checkSmarty3()) {
+                       $checked = false;
+               }
+               if (!$installer->checkKeys()) {
+                       $checked = false;
+               }
+
+               $php_path = $configCache->get('config', 'php_path');
+
+               if (!$installer->checkPHP($php_path, true)) {
+                       $checked = false;
+               }
+
+               $this->out(" NOTICE: Not checking .htaccess/URL-Rewrite during CLI installation.\n");
+
+               return $checked;
+       }
+
+       /**
+        * @param array $results
+        * @return string
+        */
+       private function extractErrors($results)
+       {
+               $errorMessage = '';
+               $allChecksRequired = $this->getOption('a') !== null;
+
+               foreach ($results as $result) {
+                       if (($allChecksRequired || $result['required'] === true) && $result['status'] === false) {
+                               $errorMessage .= "--------\n";
+                               $errorMessage .= $result['title'] . ': ' . $result['help'] . "\n";
+                       }
+               }
+
+               return $errorMessage;
+       }
+}
diff --git a/src/Console/Cache.php b/src/Console/Cache.php
new file mode 100644 (file)
index 0000000..eefb6cc
--- /dev/null
@@ -0,0 +1,178 @@
+<?php
+
+namespace Friendica\Console;
+
+use Asika\SimpleConsole\CommandArgsException;
+use Friendica\App;
+use Friendica\Core;
+use RuntimeException;
+
+/**
+ * @brief tool to access the cache from the CLI
+ *
+ * With this script you can access the cache of your node from the CLI.
+ * You can read current values stored in the cache and set new values
+ * in cache keys.
+ *
+ * @author Hypolite Petovan <hypolite@mrpetovan.com>
+ */
+class Cache extends \Asika\SimpleConsole\Console
+{
+       protected $helpOptions = ['h', 'help', '?'];
+
+       protected function getHelp()
+       {
+               $help = <<<HELP
+console cache - Manage node cache
+Synopsis
+       bin/console cache list [-h|--help|-?] [-v]
+       bin/console cache get <key> [-h|--help|-?] [-v]
+       bin/console cache set <key> <value> [-h|--help|-?] [-v]
+       bin/console cache flush [-h|--help|-?] [-v]
+       bin/console cache clear [-h|--help|-?] [-v]
+
+Description
+       bin/console cache list [<prefix>]
+               List all cache keys, optionally filtered by a prefix
+
+       bin/console cache get <key>
+               Shows the value of the provided cache key
+
+       bin/console cache set <key> <value> [<ttl>]
+               Sets the value of the provided cache key, optionally with the provided TTL (time to live) with a default of five minutes.
+
+       bin/console cache flush
+               Clears expired cache keys
+
+       bin/console cache clear
+               Clears all cache keys
+
+Options
+    -h|--help|-? Show help information
+    -v           Show more debug information.
+HELP;
+               return $help;
+       }
+
+       protected function doExecute()
+       {
+               $a = \Friendica\BaseObject::getApp();
+
+               if ($this->getOption('v')) {
+                       $this->out('Executable: ' . $this->executable);
+                       $this->out('Class: ' . __CLASS__);
+                       $this->out('Arguments: ' . var_export($this->args, true));
+                       $this->out('Options: ' . var_export($this->options, true));
+               }
+
+               if ($a->getMode()->has(App\Mode::DBCONFIGAVAILABLE)) {
+                       $this->out('Database isn\'t ready or populated yet, database cache won\'t be available');
+               }
+
+               Core\Cache::init();
+
+               if ($this->getOption('v')) {
+                       $this->out('Cache Driver Name: ' . Core\Cache::$driver_name);
+                       $this->out('Cache Driver Class: ' . Core\Cache::$driver_class);
+               }
+
+               switch ($this->getArgument(0)) {
+                       case 'list':
+                               $this->executeList();
+                               break;
+                       case 'get':
+                               $this->executeGet();
+                               break;
+                       case 'set':
+                               $this->executeSet();
+                               break;
+                       case 'flush':
+                               $this->executeFlush();
+                               break;
+                       case 'clear':
+                               $this->executeClear();
+                               break;
+               }
+
+               if (count($this->args) == 0) {
+                       $this->out($this->getHelp());
+                       return 0;
+               }
+
+               return 0;
+       }
+
+       private function executeList()
+       {
+               $prefix = $this->getArgument(1);
+               $keys = Core\Cache::getAllKeys($prefix);
+
+               if (empty($prefix)) {
+                       $this->out('Listing all cache keys:');
+               } else {
+                       $this->out('Listing all cache keys starting with "' . $prefix . '":');
+               }
+
+               $count = 0;
+               foreach ($keys as $key) {
+                       $this->out($key);
+                       $count++;
+               }
+
+               $this->out($count . ' keys found');
+       }
+
+       private function executeGet()
+       {
+               if (count($this->args) >= 2) {
+                       $key = $this->getArgument(1);
+                       $value = Core\Cache::get($key);
+
+                       $this->out("{$key} => " . var_export($value, true));
+               } else {
+                       throw new CommandArgsException('Too few arguments for get');
+               }
+       }
+
+       private function executeSet()
+       {
+               if (count($this->args) >= 3) {
+                       $key = $this->getArgument(1);
+                       $value = $this->getArgument(2);
+                       $duration = intval($this->getArgument(3, Core\Cache::FIVE_MINUTES));
+
+                       if (is_array(Core\Cache::get($key))) {
+                               throw new RuntimeException("$key is an array and can't be set using this command.");
+                       }
+
+                       $result = Core\Cache::set($key, $value, $duration);
+                       if ($result) {
+                               $this->out("{$key} <= " . Core\Cache::get($key));
+                       } else {
+                               $this->out("Unable to set {$key}");
+                       }
+               } else {
+                       throw new CommandArgsException('Too few arguments for set');
+               }
+       }
+
+       private function executeFlush()
+       {
+               $result = Core\Cache::clear();
+               if ($result) {
+                       $this->out('Cache successfully flushed');
+               } else {
+                       $this->out('Unable to flush the cache');
+               }
+       }
+
+       private function executeClear()
+       {
+               $result = Core\Cache::clear(false);
+               if ($result) {
+                       $this->out('Cache successfully cleared');
+               } else {
+                       $this->out('Unable to flush the cache');
+               }
+       }
+}
diff --git a/src/Console/Config.php b/src/Console/Config.php
new file mode 100644 (file)
index 0000000..a27ca13
--- /dev/null
@@ -0,0 +1,171 @@
+<?php
+
+namespace Friendica\Console;
+
+use Asika\SimpleConsole\CommandArgsException;
+use Friendica\App;
+use Friendica\Core;
+use RuntimeException;
+
+/**
+ * @brief tool to access the system config from the CLI
+ *
+ * With this script you can access the system configuration of your node from
+ * the CLI. You can do both, reading current values stored in the database and
+ * set new values to config variables.
+ *
+ * Usage:
+ *   If you specify no parameters at the CLI, the script will list all config
+ *   variables defined.
+ *
+ *   If you specify one parameter, the script will list all config variables
+ *   defined in this section of the configuration (e.g. "system").
+ *
+ *   If you specify two parameters, the script will show you the current value
+ *   of the named configuration setting. (e.g. "system loglevel")
+ *
+ *   If you specify three parameters, the named configuration setting will be
+ *   set to the value of the last parameter. (e.g. "system loglevel 0" will
+ *   disable logging)
+ *
+ * @author Tobias Diekershoff <tobias.diekershoff@gmx.net>
+ * @author Hypolite Petovan <hypolite@mrpetovan.com>
+ */
+class Config extends \Asika\SimpleConsole\Console
+{
+       protected $helpOptions = ['h', 'help', '?'];
+
+       protected function getHelp()
+       {
+               $help = <<<HELP
+console config - Manage site configuration
+Synopsis
+       bin/console config [-h|--help|-?] [-v]
+       bin/console config <category> [-h|--help|-?] [-v]
+       bin/console config <category> <key> [-h|--help|-?] [-v]
+       bin/console config <category> <key> <value> [-h|--help|-?] [-v]
+
+Description
+       bin/console config
+               Lists all config values
+
+       bin/console config <category>
+               Lists all config values in the provided category
+
+       bin/console config <category> <key>
+               Shows the value of the provided key in the category
+
+       bin/console config <category> <key> <value>
+               Sets the value of the provided key in the category
+
+Notes:
+       Setting config entries which are manually set in config/local.config.php may result in
+       conflict between database settings and the manual startup settings.
+
+Options
+    -h|--help|-? Show help information
+    -v           Show more debug information.
+HELP;
+               return $help;
+       }
+
+       protected function doExecute()
+       {
+               $a = \Friendica\BaseObject::getApp();
+
+               if ($this->getOption('v')) {
+                       $this->out('Executable: ' . $this->executable);
+                       $this->out('Class: ' . __CLASS__);
+                       $this->out('Arguments: ' . var_export($this->args, true));
+                       $this->out('Options: ' . var_export($this->options, true));
+               }
+
+               if (count($this->args) > 3) {
+                       throw new CommandArgsException('Too many arguments');
+               }
+
+               if (!$a->getMode()->has(App\Mode::DBCONFIGAVAILABLE)) {
+                       $this->out('Database isn\'t ready or populated yet, showing file config only');
+               }
+
+               if (count($this->args) == 3) {
+                       $cat = $this->getArgument(0);
+                       $key = $this->getArgument(1);
+                       $value = $this->getArgument(2);
+
+                       if (is_array(Core\Config::get($cat, $key))) {
+                               throw new RuntimeException("$cat.$key is an array and can't be set using this command.");
+                       }
+
+                       $result = Core\Config::set($cat, $key, $value);
+                       if ($result) {
+                               $this->out("{$cat}.{$key} <= " .
+                                       Core\Config::get($cat, $key));
+                       } else {
+                               $this->out("Unable to set {$cat}.{$key}");
+                       }
+               }
+
+               if (count($this->args) == 2) {
+                       $cat = $this->getArgument(0);
+                       $key = $this->getArgument(1);
+                       $value = Core\Config::get($this->getArgument(0), $this->getArgument(1));
+
+                       if (is_array($value)) {
+                               foreach ($value as $k => $v) {
+                                       $this->out("{$cat}.{$key}[{$k}] => " . (is_array($v) ? implode(', ', $v) : $v));
+                               }
+                       } else {
+                               $this->out("{$cat}.{$key} => " . $value);
+                       }
+               }
+
+               if (count($this->args) == 1) {
+                       $cat = $this->getArgument(0);
+                       Core\Config::load($cat);
+
+                       if ($a->getConfigCache()->get($cat) !== null) {
+                               $this->out("[{$cat}]");
+                               $catVal = $a->getConfigCache()->get($cat);
+                               foreach ($catVal as $key => $value) {
+                                       if (is_array($value)) {
+                                               foreach ($value as $k => $v) {
+                                                       $this->out("{$key}[{$k}] => " . (is_array($v) ? implode(', ', $v) : $v));
+                                               }
+                                       } else {
+                                               $this->out("{$key} => " . $value);
+                                       }
+                               }
+                       } else {
+                               $this->out('Config section ' . $this->getArgument(0) . ' returned nothing');
+                       }
+               }
+
+               if (count($this->args) == 0) {
+                       Core\Config::load();
+
+                       if (Core\Config::get('system', 'config_adapter') == 'jit' && $a->getMode()->has(App\Mode::DBCONFIGAVAILABLE)) {
+                               $this->out('Warning: The JIT (Just In Time) Config adapter doesn\'t support loading the entire configuration, showing file config only');
+                       }
+
+                       $config = $a->getConfigCache()->getAll();
+                       foreach ($config as $cat => $section) {
+                               if (is_array($section)) {
+                                       foreach ($section as $key => $value) {
+                                               if (is_array($value)) {
+                                                       foreach ($value as $k => $v) {
+                                                               $this->out("{$cat}.{$key}[{$k}] => " . (is_array($v) ? implode(', ', $v) : $v));
+                                                       }
+                                               } else {
+                                                       $this->out("{$cat}.{$key} => " . $value);
+                                               }
+                                       }
+                               } else {
+                                       $this->out("config.{$cat} => " . $section);
+                               }
+                       }
+               }
+
+               return 0;
+       }
+}
diff --git a/src/Console/CreateDoxygen.php b/src/Console/CreateDoxygen.php
new file mode 100644 (file)
index 0000000..0196839
--- /dev/null
@@ -0,0 +1,148 @@
+<?php
+
+namespace Friendica\Console;
+
+/**
+ * Description of CreateDoxygen
+ *
+ * @author Hypolite Petovan <hypolite@mrpetovan.com>
+ */
+class CreateDoxygen extends \Asika\SimpleConsole\Console
+{
+       protected $helpOptions = ['h', 'help', '?'];
+
+       protected function getHelp()
+       {
+               $help = <<<HELP
+console createdoxygen - Generate Doxygen headers
+Usage
+       bin/console createdoxygen <file> [-h|--help|-?] [-v]
+
+Description
+       Outputs the provided file with added Doxygen headers to functions
+
+Options
+    -h|--help|-? Show help information
+    -v           Show more debug information.
+HELP;
+               return $help;
+       }
+
+       protected function doExecute()
+       {
+               if ($this->getOption('v')) {
+                       $this->out('Class: ' . __CLASS__);
+                       $this->out('Arguments: ' . var_export($this->args, true));
+                       $this->out('Options: ' . var_export($this->options, true));
+               }
+
+               if (count($this->args) == 0) {
+                       $this->out($this->getHelp());
+                       return 0;
+               }
+
+               if (count($this->args) > 1) {
+                       throw new \Asika\SimpleConsole\CommandArgsException('Too many arguments');
+               }
+
+               $file = $this->getArgument(0);
+               if (!file_exists($file)) {
+                       throw new \RuntimeException('Unable to find specified file.');
+               }
+
+               $data = file_get_contents($file);
+
+               $lines = explode("\n", $data);
+
+               $previous = "";
+
+               foreach ($lines AS $line) {
+                       $line = rtrim(trim($line, "\r"));
+
+                       if (strstr(strtolower($line), "function")) {
+                               $detect = strtolower(trim($line));
+                               $detect = implode(" ", explode(" ", $detect));
+
+                               $found = false;
+
+                               if (substr($detect, 0, 9) == "function ") {
+                                       $found = true;
+                               }
+
+                               if (substr($detect, 0, 19) == "protected function ") {
+                                       $found = true;
+                               }
+
+                               if (substr($detect, 0, 17) == "private function ") {
+                                       $found = true;
+                               }
+
+                               if (substr($detect, 0, 23) == "public static function ") {
+                                       $found = true;
+                               }
+
+                               if (substr($detect, 0, 24) == "private static function ") {
+                                       $found = true;
+                               }
+
+                               if (substr($detect, 0, 10) == "function (") {
+                                       $found = false;
+                               }
+
+                               if ($found && ( trim($previous) == "*/")) {
+                                       $found = false;
+                               }
+
+                               if ($found) {
+                                       $this->out($this->addDocumentation($line));
+                               }
+                       }
+                       $this->out($line);
+                       $previous = $line;
+               }
+
+               return 0;
+       }
+
+       /**
+        * @brief Adds a doxygen header
+        *
+        * @param string $line The current line of the document
+        *
+        * @return string added doxygen header
+        */
+       private function addDocumentation($line)
+       {
+               $trimmed = ltrim($line);
+               $length = strlen($line) - strlen($trimmed);
+               $space = substr($line, 0, $length);
+
+               $block = $space . "/**\n" .
+                       $space . " * @brief \n" .
+                       $space . " *\n"; /**/
+
+
+               $left = strpos($line, "(");
+               $line = substr($line, $left + 1);
+
+               $right = strpos($line, ")");
+               $line = trim(substr($line, 0, $right));
+
+               if ($line != "") {
+                       $parameters = explode(",", $line);
+                       foreach ($parameters AS $parameter) {
+                               $parameter = trim($parameter);
+                               $splitted = explode("=", $parameter);
+
+                               $block .= $space . " * @param " . trim($splitted[0], "& ") . "\n";
+                       }
+                       if (count($parameters) > 0) $block .= $space . " *\n";
+               }
+
+               $block .= $space . " * @return \n" .
+                       $space . " */\n";
+
+               return $block;
+       }
+
+}
diff --git a/src/Console/DatabaseStructure.php b/src/Console/DatabaseStructure.php
new file mode 100644 (file)
index 0000000..3feaa64
--- /dev/null
@@ -0,0 +1,94 @@
+<?php
+
+namespace Friendica\Console;
+
+use Friendica\Core;
+use Friendica\Core\Update;
+use Friendica\Database\DBA;
+use Friendica\Database\DBStructure;
+use RuntimeException;
+
+/**
+ * @brief Performs database updates from the command line
+ *
+ * @author Hypolite Petovan <hypolite@mrpetovan.com>
+ */
+class DatabaseStructure extends \Asika\SimpleConsole\Console
+{
+       protected $helpOptions = ['h', 'help', '?'];
+
+       protected function getHelp()
+       {
+               $help = <<<HELP
+console dbstructure - Performs database updates
+Usage
+       bin/console dbstructure <command> [-h|--help|-?] |-f|--force] [-v]
+
+Commands
+       dryrun   Show database update schema queries without running them
+       update   Update database schema
+       dumpsql  Dump database schema
+       toinnodb Convert all tables from MyISAM to InnoDB
+
+Options
+    -h|--help|-?       Show help information
+    -v                 Show more debug information.
+    -f|--force         Force the update command (Even if the database structure matches)
+    -o|--override      Override running or stalling updates
+HELP;
+               return $help;
+       }
+
+       protected function doExecute()
+       {
+               if ($this->getOption('v')) {
+                       $this->out('Class: ' . __CLASS__);
+                       $this->out('Arguments: ' . var_export($this->args, true));
+                       $this->out('Options: ' . var_export($this->options, true));
+               }
+
+               if (count($this->args) == 0) {
+                       $this->out($this->getHelp());
+                       return 0;
+               }
+
+               if (count($this->args) > 1) {
+                       throw new \Asika\SimpleConsole\CommandArgsException('Too many arguments');
+               }
+
+               if (!DBA::connected()) {
+                       throw new RuntimeException('Unable to connect to database');
+               }
+
+               Core\Config::load();
+
+               $a = get_app();
+
+               switch ($this->getArgument(0)) {
+                       case "dryrun":
+                               $output = DBStructure::update($a->getBasePath(), true, false);
+                               break;
+                       case "update":
+                               $force    = $this->getOption(['f', 'force'], false);
+                               $override = $this->getOption(['o', 'override'], false);
+                               $output = Update::run($a->getBasePath(), $force, $override,true, false);
+                               break;
+                       case "dumpsql":
+                               ob_start();
+                               DBStructure::printStructure($a->getBasePath());
+                               $output = ob_get_clean();
+                               break;
+                       case "toinnodb":
+                               ob_start();
+                               DBStructure::convertToInnoDB();
+                               $output = ob_get_clean();
+                               break;
+                       default:
+                               $output = 'Unknown command: ' . $this->getArgument(0);
+               }
+
+               $this->out($output);
+
+               return 0;
+       }
+}
diff --git a/src/Console/DocBloxErrorChecker.php b/src/Console/DocBloxErrorChecker.php
new file mode 100644 (file)
index 0000000..4393e99
--- /dev/null
@@ -0,0 +1,186 @@
+<?php
+
+namespace Friendica\Console;
+
+/**
+ * When I installed docblox, I had the experience that it does not generate any output at all.
+ * This script may be used to find that kind of problems with the documentation build process.
+ * If docblox generates output, use another approach for debugging.
+ *
+ * Basically, docblox takes a list of files to build documentation from. This script assumes there is a file or set of files
+ * breaking the build when it is included in that list. It tries to calculate the smallest list containing these files.
+ * Unfortunatly, the original problem is NP-complete, so what the script does is a best guess only.
+ *
+ * So it starts with a list of all files in the project.
+ * If that list can't be build, it cuts it in two parts and tries both parts independently. If only one of them breaks,
+ * it takes that one and tries the same independently. If both break, it assumes this is the smallest set. This assumption
+ * is not necessarily true. Maybe the smallest set consists of two files and both of them were in different parts when
+ * the list was divided, but by now it is my best guess. To make this assumption better, the list is shuffled after every step.
+ *
+ * After that, the script tries to remove a file from the list. It tests if the list breaks and if so, it
+ * assumes that the file it removed belongs to the set of erroneous files.
+ * This is done for all files, so, in the end removing one file leads to a working doc build.
+ *
+ * @author Alexander Kampmann
+ * @author Hypolite Petovan <hypolite@mrpetovan.com>
+ */
+class DocBloxErrorChecker extends \Asika\SimpleConsole\Console
+{
+
+       protected $helpOptions = ['h', 'help', '?'];
+
+       protected function getHelp()
+       {
+               $help = <<<HELP
+console docbloxerrorchecker - Checks the file tree for docblox errors
+Usage
+       bin/console docbloxerrorchecker [-h|--help|-?] [-v]
+
+Options
+    -h|--help|-? Show help information
+    -v           Show more debug information.
+HELP;
+               return $help;
+       }
+
+       protected function doExecute()
+       {
+               if ($this->getOption('v')) {
+                       $this->out('Class: ' . __CLASS__);
+                       $this->out('Arguments: ' . var_export($this->args, true));
+                       $this->out('Options: ' . var_export($this->options, true));
+               }
+
+               if (count($this->args) > 0) {
+                       throw new \Asika\SimpleConsole\CommandArgsException('Too many arguments');
+               }
+
+               if (!$this->commandExists('docblox')) {
+                       throw new \RuntimeException('DocBlox isn\'t available.');
+               }
+
+               $dir = \get_app()->getBasePath();
+
+               //stack for dirs to search
+               $dirstack = [];
+               //list of source files
+               $filelist = [];
+
+               //loop over all files in $dir
+               while ($dh = opendir($dir)) {
+                       while ($file = readdir($dh)) {
+                               if (is_dir($dir . "/" . $file)) {
+                                       //add to directory stack
+                                       if (strpos($file, '.') !== 0) {
+                                               array_push($dirstack, $dir . "/" . $file);
+                                               $this->out('dir ' . $dir . '/' . $file);
+                                       }
+                               } else {
+                                       //test if it is a source file and add to filelist
+                                       if (substr($file, strlen($file) - 4) == ".php") {
+                                               array_push($filelist, $dir . "/" . $file);
+                                               $this->out($dir . '/' . $file);
+                                       }
+                               }
+                       }
+                       //look at the next dir
+                       $dir = array_pop($dirstack);
+               }
+
+               //check the entire set
+               if ($this->runs($filelist)) {
+                       throw new \RuntimeException("I can not detect a problem.");
+               }
+
+               //check half of the set and discard if that half is okay
+               $res = $filelist;
+               $i = count($res);
+               do {
+                       $this->out($i . '/' . count($filelist) . ' elements remaining.');
+                       $res = $this->reduce($res, count($res) / 2);
+                       shuffle($res);
+                       $i = count($res);
+               } while (count($res) < $i);
+
+               //check one file after another
+               $needed = [];
+
+               while (count($res) != 0) {
+                       $file = array_pop($res);
+
+                       if ($this->runs(array_merge($res, $needed))) {
+                               $this->out('needs: ' . $file . ' and file count ' . count($needed));
+                               array_push($needed, $file);
+                       }
+               }
+
+               $this->out('Smallest Set is: ' . $this->namesList($needed) . ' with ' . count($needed) . ' files. ');
+
+               return 0;
+       }
+
+       private function commandExists($command)
+       {
+               $prefix = strpos(strtolower(PHP_OS),'win') > -1 ? 'where' : 'which';
+               exec("{$prefix} {$command}", $output, $returnVal);
+               return $returnVal === 0;
+       }
+
+       /**
+        * This function generates a comma separated list of file names.
+        *
+        * @param array $fileset Set of file names
+        *
+        * @return string comma-separated list of the file names
+        */
+       private function namesList($fileset)
+       {
+               return implode(',', $fileset);
+       }
+
+       /**
+        * This functions runs phpdoc on the provided list of files
+        *
+        * @param array $fileset Set of filenames
+        *
+        * @return bool true, if that set can be built
+        */
+       private function runs($fileset)
+       {
+               $fsParam = $this->namesList($fileset);
+               $this->exec('docblox -t phpdoc_out -f ' . $fsParam);
+               if (file_exists("phpdoc_out/index.html")) {
+                       $this->out('Subset ' . $fsParam . ' is okay.');
+                       $this->exec('rm -r phpdoc_out');
+                       return true;
+               } else {
+                       $this->out('Subset ' . $fsParam . ' failed.');
+                       return false;
+               }
+       }
+
+       /**
+        * This functions cuts down a fileset by removing files until it finally works.
+        * it was meant to be recursive, but php's maximum stack size is to small. So it just simulates recursion.
+        *
+        * In that version, it does not necessarily generate the smallest set, because it may not alter the elements order enough.
+        *
+        * @param array $fileset set of filenames
+        * @param int $ps number of files in subsets
+        *
+        * @return array a part of $fileset, that crashes
+        */
+       private function reduce($fileset, $ps)
+       {
+               //split array...
+               $parts = array_chunk($fileset, $ps);
+               //filter working subsets...
+               $parts = array_filter($parts, [$this, 'runs']);
+               //melt remaining parts together
+               if (is_array($parts)) {
+                       return array_reduce($parts, "array_merge", []);
+               }
+               return [];
+       }
+
+}
diff --git a/src/Console/Extract.php b/src/Console/Extract.php
new file mode 100644 (file)
index 0000000..7fac598
--- /dev/null
@@ -0,0 +1,140 @@
+<?php
+
+namespace Friendica\Console;
+
+/**
+ * Extracts translation strings from the Friendica project's files to be exported
+ * to Transifex for translation.
+ *
+ * Outputs a PHP file with language strings used by Friendica
+ *
+ * @author Hypolite Petovan <hypolite@mrpetovan.com>
+ */
+class Extract extends \Asika\SimpleConsole\Console
+{
+       protected $helpOptions = ['h', 'help', '?'];
+
+       protected function getHelp()
+       {
+               $help = <<<HELP
+console extract - Generate translation string file for the Friendica project (deprecated)
+Usage
+       bin/console extract [-h|--help|-?] [-v]
+
+Description
+       This script was used to generate the translation string file to be exported to Transifex,
+       please use bin/run_xgettext.sh instead
+
+Options
+    -h|--help|-? Show help information
+    -v           Show more debug information.
+HELP;
+               return $help;
+       }
+
+       protected function doExecute()
+       {
+               if ($this->getOption('v')) {
+                       $this->out('Class: ' . __CLASS__);
+                       $this->out('Arguments: ' . var_export($this->args, true));
+                       $this->out('Options: ' . var_export($this->options, true));
+               }
+
+               if (count($this->args) > 0) {
+                       throw new \Asika\SimpleConsole\CommandArgsException('Too many arguments');
+               }
+
+               $s = '<?php' . PHP_EOL;
+               $s .= '
+               function string_plural_select($n){
+                       return ($n != 1);
+               }
+
+               ';
+
+               $arr = [];
+
+               $files = array_merge(
+                       ['index.php', 'boot.php'],
+                       glob('mod/*'),
+                       glob('include/*'),
+                       glob('addon/*/*'),
+                       $this->globRecursive('src')
+               );
+
+               foreach ($files as $file) {
+                       $str = file_get_contents($file);
+
+                       $pat = '|L10n::t\(([^\)]*+)[\)]|';
+                       $patt = '|L10n::tt\(([^\)]*+)[\)]|';
+
+                       $matches = [];
+                       $matchestt = [];
+
+                       preg_match_all($pat, $str, $matches);
+                       preg_match_all($patt, $str, $matchestt);
+
+                       if (count($matches) || count($matchestt)) {
+                               $s .= '// ' . $file . PHP_EOL;
+                       }
+
+                       if (!empty($matches[1])) {
+                               foreach ($matches[1] as $long_match) {
+                                       $match_arr = preg_split('/(?<=[\'"])\s*,/', $long_match);
+                                       $match = $match_arr[0];
+                                       if (!in_array($match, $arr)) {
+                                               if (substr($match, 0, 1) == '$') {
+                                                       continue;
+                                               }
+
+                                               $arr[] = $match;
+
+                                               $s .= '$a->strings[' . $match . '] = ' . $match . ';' . "\n";
+                                       }
+                               }
+                       }
+                       if (!empty($matchestt[1])) {
+                               foreach ($matchestt[1] as $match) {
+                                       $matchtkns = preg_split("|[ \t\r\n]*,[ \t\r\n]*|", $match);
+                                       if (count($matchtkns) == 3 && !in_array($matchtkns[0], $arr)) {
+                                               if (substr($matchtkns[1], 0, 1) == '$') {
+                                                       continue;
+                                               }
+
+                                               $arr[] = $matchtkns[0];
+
+                                               $s .= '$a->strings[' . $matchtkns[0] . "] = array(\n";
+                                               $s .= "\t0 => " . $matchtkns[0] . ",\n";
+                                               $s .= "\t1 => " . $matchtkns[1] . ",\n";
+                                               $s .= ");\n";
+                                       }
+                               }
+                       }
+               }
+
+               $s .= '// Timezones' . PHP_EOL;
+
+               $zones = timezone_identifiers_list();
+               foreach ($zones as $zone) {
+                       $s .= '$a->strings[\'' . $zone . '\'] = \'' . $zone . '\';' . "\n";
+               }
+
+               $this->out($s);
+
+               return 0;
+       }
+
+       private function globRecursive($path) {
+               $dir_iterator = new \RecursiveDirectoryIterator($path);
+               $iterator = new \RecursiveIteratorIterator($dir_iterator, \RecursiveIteratorIterator::SELF_FIRST);
+
+               $return = [];
+               foreach ($iterator as $file) {
+                       if ($file->getBasename() != '.' && $file->getBasename() != '..') {
+                               $return[] = $file->getPathname();
+                       }
+               }
+
+               return $return;
+       }
+}
diff --git a/src/Console/GlobalCommunityBlock.php b/src/Console/GlobalCommunityBlock.php
new file mode 100644 (file)
index 0000000..bc067da
--- /dev/null
@@ -0,0 +1,75 @@
+<?php
+
+namespace Friendica\Console;
+
+use Friendica\Core\L10n;
+use Friendica\Model\Contact;
+
+/**
+ * @brief tool to block an account from the node
+ *
+ * With this tool, you can block an account in such a way, that no postings
+ * or comments this account writes are accepted to the node.
+ *
+ * License: AGPLv3 or later, same as Friendica
+ *
+ * @author Tobias Diekershoff <tobias.diekershoff@gmx.net>
+ * @author Hypolite Petovan <hypolite@mrpetovan.com>
+ */
+class GlobalCommunityBlock extends \Asika\SimpleConsole\Console
+{
+       protected $helpOptions = ['h', 'help', '?'];
+
+       protected function getHelp()
+       {
+               $help = <<<HELP
+console globalcommunityblock - Block remote profile from interacting with this node
+Usage
+       bin/console globalcommunityblock <profile_url> [-h|--help|-?] [-v]
+
+Description
+       Blocks an account in such a way that no postings or comments this account writes are accepted to this node.
+
+Options
+    -h|--help|-? Show help information
+    -v           Show more debug information.
+HELP;
+               return $help;
+       }
+
+       protected function doExecute()
+       {
+               $a = \get_app();
+
+               if ($this->getOption('v')) {
+                       $this->out('Class: ' . __CLASS__);
+                       $this->out('Arguments: ' . var_export($this->args, true));
+                       $this->out('Options: ' . var_export($this->options, true));
+               }
+
+               if (count($this->args) == 0) {
+                       $this->out($this->getHelp());
+                       return 0;
+               }
+
+               if (count($this->args) > 1) {
+                       throw new \Asika\SimpleConsole\CommandArgsException('Too many arguments');
+               }
+
+               if ($a->getMode()->isInstall()) {
+                       throw new \RuntimeException('Database isn\'t ready or populated yet');
+               }
+
+               $contact_id = Contact::getIdForURL($this->getArgument(0));
+               if (!$contact_id) {
+                       throw new \RuntimeException(L10n::t('Could not find any contact entry for this URL (%s)', $this->getArgument(0)));
+               }
+               if(Contact::block($contact_id)) {
+                       $this->out(L10n::t('The contact has been blocked from the node'));
+               } else {
+                       throw new \RuntimeException('The contact block failed.');
+               }
+
+               return 0;
+       }
+}
diff --git a/src/Console/GlobalCommunitySilence.php b/src/Console/GlobalCommunitySilence.php
new file mode 100644 (file)
index 0000000..daaf551
--- /dev/null
@@ -0,0 +1,92 @@
+<?php
+
+namespace Friendica\Console;
+
+use Friendica\Core\Protocol;
+use Friendica\Database\DBA;
+use Friendica\Network\Probe;
+use Friendica\Util\Strings;
+use RuntimeException;
+
+/**
+ * @brief tool to silence accounts on the global community page
+ *
+ * With this tool, you can silence an account on the global community page.
+ * Postings from silenced accounts will not be displayed on the community
+ * page. This silencing does only affect the display on the community page,
+ * accounts following the silenced accounts will still get their postings.
+ *
+ * License: AGPLv3 or later, same as Friendica
+ *
+ * @author Tobias Diekershoff <tobias.diekershoff@gmx.net>
+ * @author Hypolite Petovan <hypolite@mrpetovan.com>
+ */
+class GlobalCommunitySilence extends \Asika\SimpleConsole\Console
+{
+       protected $helpOptions = ['h', 'help', '?'];
+
+       protected function getHelp()
+       {
+               $help = <<<HELP
+console globalcommunitysilence - Silence remote profile from global community page
+Usage
+       bin/console globalcommunitysilence <profile_url> [-h|--help|-?] [-v]
+
+Description
+       With this tool, you can silence an account on the global community page.
+       Postings from silenced accounts will not be displayed on the community page.
+       This silencing does only affect the display on the community page, accounts
+       following the silenced accounts will still get their postings.
+
+Options
+    -h|--help|-? Show help information
+    -v           Show more debug information.
+HELP;
+               return $help;
+       }
+
+       protected function doExecute()
+       {
+               $a = \get_app();
+
+               if ($this->getOption('v')) {
+                       $this->out('Class: ' . __CLASS__);
+                       $this->out('Arguments: ' . var_export($this->args, true));
+                       $this->out('Options: ' . var_export($this->options, true));
+               }
+
+               if (count($this->args) == 0) {
+                       $this->out($this->getHelp());
+                       return 0;
+               }
+
+               if (count($this->args) > 1) {
+                       throw new \Asika\SimpleConsole\CommandArgsException('Too many arguments');
+               }
+
+               if ($a->getMode()->isInstall()) {
+                       throw new RuntimeException('Database isn\'t ready or populated yet');
+               }
+
+               /**
+                * 1. make nurl from last parameter
+                * 2. check DB (contact) if there is a contact with uid=0 and that nurl, get the ID
+                * 3. set the flag hidden=1 for the contact entry with the found ID
+                * */
+               $net = Probe::uri($this->getArgument(0));
+               if (in_array($net['network'], [Protocol::PHANTOM, Protocol::MAIL])) {
+                       throw new RuntimeException('This account seems not to exist.');
+               }
+
+               $nurl = Strings::normaliseLink($net['url']);
+               $contact = DBA::selectFirst("contact", ["id"], ["nurl" => $nurl, "uid" => 0]);
+               if (DBA::isResult($contact)) {
+                       DBA::update("contact", ["hidden" => true], ["id" => $contact["id"]]);
+                       $this->out('NOTICE: The account should be silenced from the global community page');
+               } else {
+                       throw new RuntimeException('NOTICE: Could not find any entry for this URL (' . $nurl . ')');
+               }
+
+               return 0;
+       }
+}
diff --git a/src/Console/Maintenance.php b/src/Console/Maintenance.php
new file mode 100644 (file)
index 0000000..080eb09
--- /dev/null
@@ -0,0 +1,95 @@
+<?php
+
+namespace Friendica\Console;
+
+use Friendica\Core;
+
+/**
+ * @brief Sets maintenance mode for this node
+ *
+ * @author Hypolite Petovan <hypolite@mrpetovan.com>
+ */
+class Maintenance extends \Asika\SimpleConsole\Console
+{
+       protected $helpOptions = ['h', 'help', '?'];
+
+       protected function getHelp()
+       {
+               $help = <<<HELP
+console maintenance - Sets maintenance mode for this node
+Usage
+       bin/console maintenance <enable> [<reason>] [-h|--help|-?] [-v]
+
+Description
+       <enable> cen be either 0 or 1 to disabled or enable the maintenance mode on this node.
+
+       <reason> is a quote-enclosed string with the optional reason for the maintenance mode.
+
+Examples
+       bin/console maintenance 1
+               Enables the maintenance mode without setting a reason message
+
+       bin/console maintenance 1 "SSL certification update"
+               Enables the maintenance mode with setting a reason message
+
+       bin/console maintenance 0
+               Disables the maintenance mode
+
+Options
+    -h|--help|-? Show help information
+    -v           Show more debug information.
+HELP;
+               return $help;
+       }
+
+       protected function doExecute()
+       {
+               $a = \Friendica\BaseObject::getApp();
+
+               if ($this->getOption('v')) {
+                       $this->out('Class: ' . __CLASS__);
+                       $this->out('Arguments: ' . var_export($this->args, true));
+                       $this->out('Options: ' . var_export($this->options, true));
+               }
+
+               if (count($this->args) == 0) {
+                       $this->out($this->getHelp());
+                       return 0;
+               }
+
+               if (count($this->args) > 2) {
+                       throw new \Asika\SimpleConsole\CommandArgsException('Too many arguments');
+               }
+
+               if ($a->getMode()->isInstall()) {
+                       throw new \RuntimeException('Database isn\'t ready or populated yet');
+               }
+
+               $enabled = intval($this->getArgument(0));
+
+               Core\Config::set('system', 'maintenance', $enabled);
+
+               $reason = $this->getArgument(1);
+
+               if ($enabled && $this->getArgument(1)) {
+                       Core\Config::set('system', 'maintenance_reason', $this->getArgument(1));
+               } else {
+                       Core\Config::set('system', 'maintenance_reason', '');
+               }
+
+               if ($enabled) {
+                       $mode_str = "maintenance mode";
+               } else {
+                       $mode_str = "normal mode";
+               }
+
+               $this->out('System set in ' . $mode_str);
+
+               if ($enabled && $reason != '') {
+                       $this->out('Maintenance reason: ' . $reason);
+               }
+
+               return 0;
+       }
+
+}
diff --git a/src/Console/NewPassword.php b/src/Console/NewPassword.php
new file mode 100644 (file)
index 0000000..dc69438
--- /dev/null
@@ -0,0 +1,90 @@
+<?php
+
+namespace Friendica\Console;
+
+use Friendica\Core\L10n;
+use Friendica\Database\DBA;
+use Friendica\Model\User;
+use RuntimeException;
+
+/**
+ * @brief tool to set a new password for a user
+ *
+ * With this tool, you can set a new password for a user
+ *
+ * License: AGPLv3 or later, same as Friendica
+ *
+ * @author Michael Vogel <heluecht@pirati.ca>
+ */
+class NewPassword extends \Asika\SimpleConsole\Console
+{
+       protected $helpOptions = ['h', 'help', '?'];
+
+       protected function getHelp()
+       {
+               $help = <<<HELP
+console newpassword - Creates a new password for a given user
+Usage
+       bin/console newpassword <nickname> [<password>] [-h|--help|-?] [-v]
+
+Description
+       Creates a new password for a user without using the "forgot password" functionality.
+
+Options
+    -h|--help|-? Show help information
+    -v           Show more debug information.
+HELP;
+               return $help;
+       }
+
+       protected function doExecute()
+       {
+               $a = \get_app();
+
+               if ($this->getOption('v')) {
+                       $this->out('Class: ' . __CLASS__);
+                       $this->out('Arguments: ' . var_export($this->args, true));
+                       $this->out('Options: ' . var_export($this->options, true));
+               }
+
+               if (count($this->args) == 0) {
+                       $this->out($this->getHelp());
+                       return 0;
+               }
+
+               if (count($this->args) > 2) {
+                       throw new \Asika\SimpleConsole\CommandArgsException('Too many arguments');
+               }
+
+               if ($a->getMode()->isInstall()) {
+                       throw new RuntimeException('Database isn\'t ready or populated yet');
+               }
+
+               $nick = $this->getArgument(0);
+
+               $user = DBA::selectFirst('user', ['uid'], ['nickname' => $nick]);
+               if (!DBA::isResult($user)) {
+                       throw new RuntimeException(L10n::t('User not found'));
+               }
+
+               $password = $this->getArgument(1);
+               if (is_null($password)) {
+                       $this->out(L10n::t('Enter new password: '), false);
+                       $password = \Seld\CliPrompt\CliPrompt::hiddenPrompt(true);
+               }
+
+               try {
+                       $result = User::updatePassword($user['uid'], $password);
+
+                       if (!DBA::isResult($result)) {
+                               throw new \Exception(L10n::t('Password update failed. Please try again.'));
+                       }
+
+                       $this->out(L10n::t('Password changed.'));
+               } catch (\Exception $e) {
+                       throw new RuntimeException($e->getMessage(), $e->getCode(), $e);
+               }
+
+               return 0;
+       }
+}
diff --git a/src/Console/PhpToPo.php b/src/Console/PhpToPo.php
new file mode 100644 (file)
index 0000000..d73c7f4
--- /dev/null
@@ -0,0 +1,237 @@
+<?php
+
+namespace Friendica\Console;
+
+/**
+ * Read a strings.php file and create messages.po in the same directory
+ *
+ * @author Hypolite Petovan <hypolite@mrpetovan.com>
+ */
+class PhpToPo extends \Asika\SimpleConsole\Console
+{
+
+       protected $helpOptions = ['h', 'help', '?'];
+
+       private $normBaseMsgIds = [];
+       const NORM_REGEXP = "|[\\\]|";
+
+       protected function getHelp()
+       {
+               $help = <<<HELP
+console php2po - Generate a messages.po file from a strings.php file
+Usage
+       bin/console php2po [-p <n>] [--base <file>] <path/to/strings.php> [-h|--help|-?] [-v]
+
+Description
+       Read a strings.php file and create the according messages.po in the same directory
+
+Options
+       -p <n>        Number of plural forms. Default: 2
+       --base <file> Path to base messages.po file. Default: view/lang/C/messages.po
+       -h|--help|-?  Show help information
+       -v            Show more debug information.
+HELP;
+               return $help;
+       }
+
+       protected function doExecute()
+       {
+               if ($this->getOption('v')) {
+                       $this->out('Class: ' . __CLASS__);
+                       $this->out('Arguments: ' . var_export($this->args, true));
+                       $this->out('Options: ' . var_export($this->options, true));
+               }
+
+               if (count($this->args) == 0) {
+                       $this->out($this->getHelp());
+                       return 0;
+               }
+
+               if (count($this->args) > 1) {
+                       throw new \Asika\SimpleConsole\CommandArgsException('Too many arguments');
+               }
+
+               $a = \get_app();
+
+               $phpfile = realpath($this->getArgument(0));
+
+               if (!file_exists($phpfile)) {
+                       throw new \RuntimeException('Supplied file path doesn\'t exist.');
+               }
+
+               if (!is_writable(dirname($phpfile))) {
+                       throw new \RuntimeException('Supplied directory isn\'t writable.');
+               }
+
+               $pofile = dirname($phpfile) . DIRECTORY_SEPARATOR . 'messages.po';
+
+               // start !
+               include_once($phpfile);
+
+               $out = '';
+               $out .= "# FRIENDICA Distributed Social Network\n";
+               $out .= "# Copyright (C) 2010, 2011, 2012, 2013 the Friendica Project\n";
+               $out .= "# This file is distributed under the same license as the Friendica package.\n";
+               $out .= "# \n";
+               $out .= 'msgid ""' . "\n";
+               $out .= 'msgstr ""' . "\n";
+               $out .= '"Project-Id-Version: friendica\n"' . "\n";
+               $out .= '"Report-Msgid-Bugs-To: \n"' . "\n";
+               $out .= '"POT-Creation-Date: ' . date("Y-m-d H:i:sO") . '\n"' . "\n";
+               $out .= '"MIME-Version: 1.0\n"' . "\n";
+               $out .= '"Content-Type: text/plain; charset=UTF-8\n"' . "\n";
+               $out .= '"Content-Transfer-Encoding: 8bit\n"' . "\n";
+
+               // search for plural info
+               $lang = "";
+               $lang_logic = "";
+               $lang_pnum = $this->getOption('p', 2);
+
+               $infile = file($phpfile);
+               foreach ($infile as $l) {
+                       $l = trim($l);
+                       if ($this->startsWith($l, 'function string_plural_select_')) {
+                               $lang = str_replace('function string_plural_select_', '', str_replace('($n){', '', $l));
+                       }
+                       if ($this->startsWith($l, 'return')) {
+                               $lang_logic = str_replace('$', '', trim(str_replace('return ', '', $l), ';'));
+                               break;
+                       }
+               }
+
+               $this->out('Language: ' . $lang);
+               $this->out('Plural forms: ' . $lang_pnum);
+               $this->out('Plural forms: ' . $lang_logic);
+
+               $out .= sprintf('"Language: %s\n"', $lang) . "\n";
+               $out .= sprintf('"Plural-Forms: nplurals=%s; plural=%s;\n"', $lang_pnum, $lang_logic) . "\n";
+               $out .= "\n";
+
+               $base_path = $this->getOption('base', 'view/lang/C/messages.po');
+
+               // load base messages.po and extract msgids
+               $base_msgids = [];
+               $base_f = file($base_path);
+               if (!$base_f) {
+                       throw new \RuntimeException('The base ' . $base_path . ' file is missing or unavailable to read.');
+               }
+
+               $this->out('Loading base file ' . $base_path . '...');
+
+               $_f = 0;
+               $_mid = "";
+               $_mids = [];
+               foreach ($base_f as $l) {
+                       $l = trim($l);
+
+                       if ($this->startsWith($l, 'msgstr')) {
+                               if ($_mid != '""') {
+                                       $base_msgids[$_mid] = $_mids;
+                                       $this->normBaseMsgIds[preg_replace(self::NORM_REGEXP, "", $_mid)] = $_mid;
+                               }
+
+                               $_f = 0;
+                               $_mid = "";
+                               $_mids = [];
+                       }
+
+                       if ($this->startsWith($l, '"') && $_f == 2) {
+                               $_mids[count($_mids) - 1] .= "\n" . $l;
+                       }
+                       if ($this->startsWith($l, 'msgid_plural ')) {
+                               $_f = 2;
+                               $_mids[] = str_replace('msgid_plural ', '', $l);
+                       }
+
+                       if ($this->startsWith($l, '"') && $_f == 1) {
+                               $_mid .= "\n" . $l;
+                               $_mids[count($_mids) - 1] .= "\n" . $l;
+                       }
+                       if ($this->startsWith($l, 'msgid ')) {
+                               $_f = 1;
+                               $_mid = str_replace('msgid ', '', $l);
+                               $_mids = [$_mid];
+                       }
+               }
+
+               $this->out('Creating ' . $pofile . '...');
+
+               // create msgid and msgstr
+               $warnings = "";
+               foreach ($a->strings as $key => $str) {
+                       $msgid = $this->massageString($key);
+
+                       if (preg_match("|%[sd0-9](\$[sn])*|", $msgid)) {
+                               $out .= "#, php-format\n";
+                       }
+                       $msgid = $this->findOriginalMsgId($msgid);
+                       $out .= 'msgid ' . $msgid . "\n";
+
+                       if (is_array($str)) {
+                               if (array_key_exists($msgid, $base_msgids) && isset($base_msgids[$msgid][1])) {
+                                       $out .= 'msgid_plural ' . $base_msgids[$msgid][1] . "\n";
+                               } else {
+                                       $out .= 'msgid_plural ' . $msgid . "\n";
+                                       $warnings .= "[W] No source plural form for msgid:\n" . str_replace("\n", "\n\t", $msgid) . "\n\n";
+                               }
+                               foreach ($str as $n => $msgstr) {
+                                       $out .= 'msgstr[' . $n . '] ' . $this->massageString($msgstr) . "\n";
+                               }
+                       } else {
+                               $out .= 'msgstr ' . $this->massageString($str) . "\n";
+                       }
+
+                       $out .= "\n";
+               }
+
+               if (!file_put_contents($pofile, $out)) {
+                       throw new \RuntimeException('Unable to write to ' . $pofile);
+               }
+
+               if ($warnings != '') {
+                       $this->out($warnings);
+               }
+
+               return 0;
+       }
+
+       private function startsWith($haystack, $needle)
+       {
+               // search backwards starting from haystack length characters from the end
+               return $needle === "" || strrpos($haystack, $needle, -strlen($haystack)) !== FALSE;
+       }
+
+       /**
+        * Get a string and retun a message.po ready text
+        * - replace " with \"
+        * - replace tab char with \t
+        * - manage multiline strings
+        *
+        * @param string $str
+        * @return string
+        */
+       private function massageString($str)
+       {
+               $str = str_replace('\\', '\\\\', $str);
+               $str = str_replace('"', '\"', $str);
+               $str = str_replace("\t", '\t', $str);
+               $str = str_replace("\n", '\n"' . "\n" . '"', $str);
+               if (strpos($str, "\n") !== false && $str[0] !== '"') {
+                       $str = '"' . "\n" . $str;
+               }
+
+               $str = preg_replace("|\n([^\"])|", "\n\"$1", $str);
+               return sprintf('"%s"', $str);
+       }
+
+       private function findOriginalMsgId($str)
+       {
+               $norm_str = preg_replace(self::NORM_REGEXP, "", $str);
+               if (array_key_exists($norm_str, $this->normBaseMsgIds)) {
+                       return $this->normBaseMsgIds[$norm_str];
+               }
+
+               return $str;
+       }
+
+}
diff --git a/src/Console/PoToPhp.php b/src/Console/PoToPhp.php
new file mode 100644 (file)
index 0000000..c4ba42c
--- /dev/null
@@ -0,0 +1,198 @@
+<?php
+
+namespace Friendica\Console;
+
+/**
+ * Read a messages.po file and create strings.php in the same directory
+ *
+ * @author Hypolite Petovan <hypolite@mrpetovan.com>
+ */
+class PoToPhp extends \Asika\SimpleConsole\Console
+{
+       protected $helpOptions = ['h', 'help', '?'];
+
+       const DQ_ESCAPE = "__DQ__";
+
+       protected function getHelp()
+       {
+               $help = <<<HELP
+console php2po - Generate a strings.php file from a messages.po file
+Usage
+       bin/console php2po <path/to/messages.po> [-h|--help|-?] [-v]
+
+Description
+       Read a messages.po file and create the according strings.php in the same directory
+
+Options
+       -h|--help|-?  Show help information
+       -v            Show more debug information.
+HELP;
+               return $help;
+       }
+
+       protected function doExecute()
+       {
+               if ($this->getOption('v')) {
+                       $this->out('Class: ' . __CLASS__);
+                       $this->out('Arguments: ' . var_export($this->args, true));
+                       $this->out('Options: ' . var_export($this->options, true));
+               }
+
+               if (count($this->args) == 0) {
+                       $this->out($this->getHelp());
+                       return 0;
+               }
+
+               if (count($this->args) > 1) {
+                       throw new \Asika\SimpleConsole\CommandArgsException('Too many arguments');
+               }
+
+               $pofile = realpath($this->getArgument(0));
+
+               if (!file_exists($pofile)) {
+                       throw new \RuntimeException('Supplied file path doesn\'t exist.');
+               }
+
+               if (!is_writable(dirname($pofile))) {
+                       throw new \RuntimeException('Supplied directory isn\'t writable.');
+               }
+
+               $outfile = dirname($pofile) . DIRECTORY_SEPARATOR . 'strings.php';
+
+               if (basename(dirname($pofile)) == 'C') {
+                       $lang = 'en';
+               } else {
+                       $lang = str_replace('-', '_', basename(dirname($pofile)));
+               }
+
+               $this->out('Out to ' . $outfile);
+
+               $out = "<?php\n\n";
+
+               $infile = file($pofile);
+               $k = '';
+               $v = '';
+               $arr = false;
+               $ink = false;
+               $inv = false;
+               $escape_s_exp = '|[^\\\\]\$[a-z]|';
+
+               foreach ($infile as $l) {
+                       $l = str_replace('\"', self::DQ_ESCAPE, $l);
+                       $len = strlen($l);
+                       if ($l[0] == "#") {
+                               $l = "";
+                       }
+
+                       if (substr($l, 0, 15) == '"Plural-Forms: ') {
+                               $match = [];
+                               preg_match("|nplurals=([0-9]*); *plural=(.*)[;\\\\]|", $l, $match);
+                               $cond = str_replace('n', '$n', $match[2]);
+                               // define plural select function if not already defined
+                               $fnname = 'string_plural_select_' . $lang;
+                               $out .= 'if(! function_exists("' . $fnname . '")) {' . "\n";
+                               $out .= 'function ' . $fnname . '($n){' . "\n";
+                               $out .= '       $n = intval($n);' . "\n";
+                               $out .= '       return ' . $cond . ';' . "\n";
+                               $out .= '}}' . "\n";
+                       }
+
+                       if ($k != '' && substr($l, 0, 7) == 'msgstr ') {
+                               if ($ink) {
+                                       $ink = false;
+                                       $out .= '$a->strings["' . $k . '"] = ';
+                               }
+
+                               if ($inv) {
+                                       $out .= '"' . $v . '"';
+                               }
+
+                               $v = substr($l, 8, $len - 10);
+                               $v = preg_replace_callback($escape_s_exp, [$this, 'escapeDollar'], $v);
+
+                               $inv = true;
+                       }
+
+                       if ($k != "" && substr($l, 0, 7) == 'msgstr[') {
+                               if ($ink) {
+                                       $ink = false;
+                                       $out .= '$a->strings["' . $k . '"] = ';
+                               }
+                               if ($inv) {
+                                       $inv = false;
+                                       $out .= '"' . $v . '"';
+                               }
+
+                               if (!$arr) {
+                                       $arr = true;
+                                       $out .= "[\n";
+                               }
+
+                               $match = [];
+                               preg_match("|\[([0-9]*)\] (.*)|", $l, $match);
+                               $out .= "\t"
+                                       . preg_replace_callback($escape_s_exp, [$this, 'escapeDollar'], $match[1])
+                                       . ' => '
+                                       . preg_replace_callback($escape_s_exp, [$this, 'escapeDollar'], $match[2])
+                                       . ",\n";
+                       }
+
+                       if (substr($l, 0, 6) == 'msgid_') {
+                               $ink = false;
+                               $out .= '$a->strings["' . $k . '"] = ';
+                       }
+
+                       if ($ink) {
+                               $k .= trim($l, "\"\r\n");
+                               $k = preg_replace_callback($escape_s_exp, [$this, 'escapeDollar'], $k);
+                       }
+
+                       if (substr($l, 0, 6) == 'msgid ') {
+                               if ($inv) {
+                                       $inv = false;
+                                       $out .= '"' . $v . '"';
+                               }
+
+                               if ($k != "") {
+                                       $out .= ($arr) ? "];\n" : ";\n";
+                               }
+
+                               $arr = false;
+                               $k = str_replace("msgid ", "", $l);
+                               if ($k != '""') {
+                                       $k = trim($k, "\"\r\n");
+                               } else {
+                                       $k = '';
+                               }
+
+                               $k = preg_replace_callback($escape_s_exp, [$this, 'escapeDollar'], $k);
+                               $ink = true;
+                       }
+
+                       if ($inv && substr($l, 0, 6) != "msgstr") {
+                               $v .= trim($l, "\"\r\n");
+                               $v = preg_replace_callback($escape_s_exp, [$this, 'escapeDollar'], $v);
+                       }
+               }
+
+               if ($inv) {
+                       $out .= '"' . $v . '"';
+               }
+
+               if ($k != '') {
+                       $out .= ($arr ? "];\n" : ";\n");
+               }
+
+               $out = str_replace(self::DQ_ESCAPE, '\"', $out);
+               if (!file_put_contents($outfile, $out)) {
+                       throw new \RuntimeException('Unable to write to ' . $outfile);
+               }
+
+               return 0;
+       }
+
+       private function escapeDollar($match)
+       {
+               return str_replace('$', '\$', $match[0]);
+       }
+}
diff --git a/src/Console/PostUpdate.php b/src/Console/PostUpdate.php
new file mode 100644 (file)
index 0000000..4d7246d
--- /dev/null
@@ -0,0 +1,72 @@
+<?php
+
+namespace Friendica\Console;
+
+use Friendica\Core\Config;
+use Friendica\Core\L10n;
+use Friendica\Core\Update;
+
+/**
+ * Performs database post updates
+ *
+ * License: AGPLv3 or later, same as Friendica
+ *
+ * @author Tobias Diekershoff <tobias.diekershoff@gmx.net>
+ * @author Hypolite Petovan <hypolite@mrpetovan.com>
+ */
+class PostUpdate extends \Asika\SimpleConsole\Console
+{
+        protected $helpOptions = ['h', 'help', '?'];
+
+        protected function getHelp()
+        {
+                $help = <<<HELP
+console postupdate - Performs database post updates
+Usage
+        bin/console postupdate [-h|--help|-?] [--reset <version>]
+
+Options
+    -h|--help|-?      Show help information
+    --reset <version> Reset the post update version
+HELP;
+                return $help;
+        }
+
+       protected function doExecute()
+       {
+               $a = \Friendica\BaseObject::getApp();
+
+               if ($this->getOption($this->helpOptions)) {
+                       $this->out($this->getHelp());
+                       return 0;
+               }
+
+               $reset_version = $this->getOption('reset');
+               if (is_bool($reset_version)) {
+                       $this->out($this->getHelp());
+                       return 0;
+               } elseif ($reset_version) {
+                       Config::set('system', 'post_update_version', $reset_version);
+                       echo L10n::t('Post update version number has been set to %s.', $reset_version) . "\n";
+                       return 0;
+               }
+
+               if ($a->getMode()->isInstall()) {
+                       throw new \RuntimeException('Database isn\'t ready or populated yet');
+               }
+
+               echo L10n::t('Check for pending update actions.') . "\n";
+               Update::run($a->getBasePath(), true, false, true, false);
+               echo L10n::t('Done.') . "\n";
+
+               echo L10n::t('Execute pending post updates.') . "\n";
+
+               while (!\Friendica\Database\PostUpdate::update()) {
+                       echo '.';
+               }
+
+               echo "\n" . L10n::t('All pending post updates are done.') . "\n";
+
+               return 0;
+       }
+}
diff --git a/src/Console/ServerBlock.php b/src/Console/ServerBlock.php
new file mode 100644 (file)
index 0000000..7e45f10
--- /dev/null
@@ -0,0 +1,171 @@
+<?php
+
+namespace Friendica\Console;
+
+use Asika\SimpleConsole\CommandArgsException;
+use Asika\SimpleConsole\Console;
+use Console_Table;
+use Friendica\BaseObject;
+use Friendica\Core\Config\Configuration;
+
+/**
+ * @brief Manage blocked servers
+ *
+ * With this tool, you can list the current blocked servers
+ * or you can add / remove a blocked server from the list
+ */
+class ServerBlock extends Console
+{
+       const DEFAULT_REASON = 'blocked';
+
+       protected $helpOptions = ['h', 'help', '?'];
+
+       protected function getHelp()
+       {
+               $help = <<<HELP
+console serverblock - Manage blocked servers
+Usage
+       bin/console serverblock [-h|--help|-?] [-v]
+       bin/console serverblock add <server> <reason> [-h|--help|-?] [-v]
+       bin/console serverblock remove <server> [-h|--help|-?] [-v]
+
+Description
+       With this tool, you can list the current blocked servers
+    or you can add / remove a blocked server from the list
+
+Options
+    -h|--help|-? Show help information
+    -v           Show more debug information.
+HELP;
+               return $help;
+       }
+
+       protected function doExecute()
+       {
+               $a = BaseObject::getApp();
+
+               if (count($this->args) == 0) {
+                       $this->printBlockedServers($a->getConfig());
+                       return 0;
+               }
+
+               switch ($this->getArgument(0)) {
+                       case 'add':
+                               return $this->addBlockedServer($a->getConfig());
+                       case 'remove':
+                               return $this->removeBlockedServer($a->getConfig());
+                       default:
+                               throw new CommandArgsException('Unknown command.');
+                               break;
+               }
+       }
+
+       /**
+        * Prints the whole list of blocked domains including the reason
+        *
+        * @param Configuration $config
+        */
+       private function printBlockedServers(Configuration $config)
+       {
+               $table = new Console_Table();
+               $table->setHeaders(['Domain', 'Reason']);
+               $blocklist = $config->get('system', 'blocklist');
+               foreach ($blocklist as $domain) {
+                       $table->addRow($domain);
+               }
+               $this->out($table->getTable());
+       }
+
+       /**
+        * Adds a server to the blocked list
+        *
+        * @param Configuration $config
+        *
+        * @return int The return code (0 = success, 1 = failed)
+        */
+       private function addBlockedServer(Configuration $config)
+       {
+               if (count($this->args) < 2 || count($this->args) > 3) {
+                       throw new CommandArgsException('Add needs a domain and optional a reason.');
+               }
+
+               $domain = $this->getArgument(1);
+               $reason = (count($this->args) === 3) ? $this->getArgument(2) : self::DEFAULT_REASON;
+
+               $update = false;
+
+               $currBlocklist = $config->get('system', 'blocklist');
+               $newBlockList = [];
+               foreach ($currBlocklist  as $blocked) {
+                       if ($blocked['domain'] === $domain) {
+                               $update = true;
+                               $newBlockList[] = [
+                                       'domain' => $domain,
+                                       'reason' => $reason,
+                               ];
+                       } else {
+                               $newBlockList[] = $blocked;
+                       }
+               }
+
+               if (!$update) {
+                       $newBlockList[] = [
+                               'domain' => $domain,
+                               'reason' => $reason,
+                       ];
+               }
+
+               if ($config->set('system', 'blocklist', $newBlockList)) {
+                       if ($update) {
+                               $this->out(sprintf("The domain '%s' is now updated. (Reason: '%s')", $domain, $reason));
+                       } else {
+                               $this->out(sprintf("The domain '%s' is now blocked. (Reason: '%s')", $domain, $reason));
+                       }
+                       return 0;
+               } else {
+                       $this->out(sprintf("Couldn't save '%s' as blocked server", $domain));
+                       return 1;
+               }
+       }
+
+       /**
+        * Removes a server from the blocked list
+        *
+        * @param Configuration $config
+        *
+        * @return int The return code (0 = success, 1 = failed)
+        */
+       private function removeBlockedServer(Configuration $config)
+       {
+               if (count($this->args) !== 2) {
+                       throw new CommandArgsException('Remove needs a second parameter.');
+               }
+
+               $domain = $this->getArgument(1);
+
+               $found = false;
+
+               $currBlocklist = $config->get('system', 'blocklist');
+               $newBlockList = [];
+               foreach ($currBlocklist as $blocked) {
+                       if ($blocked['domain'] === $domain) {
+                               $found = true;
+                       } else {
+                               $newBlockList[] = $blocked;
+                       }
+               }
+
+               if (!$found) {
+                       $this->out(sprintf("The domain '%s' is not blocked.", $domain));
+                       return 1;
+               }
+
+               if ($config->set('system', 'blocklist', $newBlockList)) {
+                       $this->out(sprintf("The domain '%s' is not more blocked", $domain));
+                       return 0;
+               } else {
+                       $this->out(sprintf("Couldn't remove '%s' from blocked servers", $domain));
+                       return 1;
+               }
+       }
+}
diff --git a/src/Console/Storage.php b/src/Console/Storage.php
new file mode 100644 (file)
index 0000000..30b5567
--- /dev/null
@@ -0,0 +1,147 @@
+<?php
+
+namespace Friendica\Console;
+
+use Asika\SimpleConsole\CommandArgsException;
+use Friendica\Core\StorageManager;
+
+/**
+ * @brief tool to manage storage backend and stored data from CLI
+ *
+ */
+class Storage extends \Asika\SimpleConsole\Console
+{
+       protected $helpOptions = ['h', 'help', '?'];
+
+       protected function getHelp()
+       {
+               $help = <<<HELP
+console storage - manage storage backend and stored data
+Synopsis
+    bin/console storage [-h|--help|-?] [-v]
+        Show this help
+    
+    bin/console storage list
+        List available storage backends
+    
+    bin/console storage set <name>
+        Set current storage backend
+            name        storage backend to use. see "list".
+    
+    bin/console storage move [table] [-n 5000]
+        Move stored data to current storage backend.
+            table       one of "photo" or "attach". default to both
+            -n          limit of processed entry batch size
+HELP;
+               return $help;
+       }
+
+       protected function doExecute()
+       {
+               if ($this->getOption('v')) {
+                       $this->out('Executable: ' . $this->executable);
+                       $this->out('Class: ' . __CLASS__);
+                       $this->out('Arguments: ' . var_export($this->args, true));
+                       $this->out('Options: ' . var_export($this->options, true));
+               }
+
+               if (count($this->args) == 0) {
+                       $this->out($this->getHelp());
+                       return -1;
+               }
+
+               switch ($this->args[0]) {
+                       case 'list':
+                               return $this->doList();
+                               break;
+                       case 'set':
+                               return $this->doSet();
+                               break;
+                       case 'move':
+                               return $this->doMove();
+                               break;
+               }
+
+               $this->out(sprintf('Invalid action "%s"', $this->args[0]));
+               return -1;
+       }
+
+       protected function doList()
+       {
+               $rowfmt = ' %-3s | %-20s';
+               $current = StorageManager::getBackend();
+               $this->out(sprintf($rowfmt, 'Sel', 'Name'));
+               $this->out('-----------------------');
+               $isregisterd = false;
+               foreach (StorageManager::listBackends() as $name => $class) {
+                       $issel = ' ';
+                       if ($current === $class) {
+                               $issel = '*';
+                               $isregisterd = true;
+                       };
+                       $this->out(sprintf($rowfmt, $issel, $name));
+               }
+
+               if ($current === '') {
+                       $this->out();
+                       $this->out('This system is using legacy storage system');
+               }
+               if ($current !== '' && !$isregisterd) {
+                       $this->out();
+                       $this->out('The current storage class (' . $current . ') is not registered!');
+               }
+               return 0;
+       }
+
+       protected function doSet()
+       {
+               if (count($this->args) !== 2) {
+                       throw new CommandArgsException('Invalid arguments');
+               }
+
+               $name = $this->args[1];
+               $class = StorageManager::getByName($name);
+
+               if ($class === '') {
+                       $this->out($name . ' is not a registered backend.');
+                       return -1;
+               }
+
+               if (!StorageManager::setBackend($class)) {
+                       $this->out($class . ' is not a valid backend storage class.');
+                       return -1;
+               }
+
+               return 0;
+       }
+
+       protected function doMove()
+       {
+               $tables = null;
+               if (count($this->args) < 1 || count($this->args) > 2) {
+                       throw new CommandArgsException('Invalid arguments');
+               }
+
+               if (count($this->args) == 2) {
+                       $table = strtolower($this->args[1]);
+                       if (!in_array($table, ['photo', 'attach'])) {
+                               throw new CommandArgsException('Invalid table');
+                       }
+                       $tables = [$table];
+               }
+
+               $current = StorageManager::getBackend();
+               $total = 0;
+
+               do {
+                       $moved = StorageManager::move($current, $tables, $this->getOption('n', 5000));
+                       if ($moved) {
+                               $this->out(date('[Y-m-d H:i:s] ') . sprintf('Moved %d files', $moved));
+                       }
+
+                       $total += $moved;
+               } while ($moved);
+
+               $this->out(sprintf(date('[Y-m-d H:i:s] ') . 'Moved %d files total', $total));
+       }
+}
diff --git a/src/Console/Typo.php b/src/Console/Typo.php
new file mode 100644 (file)
index 0000000..5f5fa0b
--- /dev/null
@@ -0,0 +1,117 @@
+<?php
+
+namespace Friendica\Console;
+
+use Friendica\BaseObject;
+
+/**
+ * Tired of chasing typos and finding them after a commit.
+ * Run this and quickly see if we've got any parse errors in our application files.
+ *
+ * @author Hypolite Petovan <hypolite@mrpetovan.com>
+ */
+class Typo extends \Asika\SimpleConsole\Console
+{
+       protected $helpOptions = ['h', 'help', '?'];
+
+       protected function getHelp()
+       {
+               $help = <<<HELP
+console typo - Checks for parse errors in Friendica files
+Usage
+       bin/console typo [-h|--help|-?] [-v]
+
+Description
+       Checks all PHP files in the Friendica file tree for parse errors
+
+Options
+       -h|--help|-?  Show help information
+       -v            Show more debug information.
+HELP;
+               return $help;
+       }
+
+       protected function doExecute()
+       {
+               if ($this->getOption('v')) {
+                       $this->out('Class: ' . __CLASS__);
+                       $this->out('Arguments: ' . var_export($this->args, true));
+                       $this->out('Options: ' . var_export($this->options, true));
+               }
+
+               if (count($this->args) > 0) {
+                       throw new \Asika\SimpleConsole\CommandArgsException('Too many arguments');
+               }
+
+               $php_path = BaseObject::getApp()->getConfigCache()->get('config', 'php_path', 'php');
+
+               if ($this->getOption('v')) {
+                       $this->out('Directory: src');
+               }
+
+               $Iterator = new \RecursiveDirectoryIterator('src');
+
+               foreach (new \RecursiveIteratorIterator($Iterator) as $file) {
+                       if (substr($file, -4) === '.php') {
+                               $this->checkFile($php_path, $file);
+                       }
+               }
+
+               if ($this->getOption('v')) {
+                       $this->out('Directory: mod');
+               }
+
+               $files = glob('mod/*.php');
+               $this->checkFiles($php_path, $files);
+
+               if ($this->getOption('v')) {
+                       $this->out('Directory: include');
+               }
+
+               $files = glob('include/*.php');
+               $this->checkFiles($php_path, $files);
+
+               if ($this->getOption('v')) {
+                       $this->out('Directory: addon');
+               }
+
+               $dirs = glob('addon/*');
+               foreach ($dirs as $dir) {
+                       $addon = basename($dir);
+                       $files = glob($dir . '/' . $addon . '.php');
+                       $this->checkFiles($php_path, $files);
+               }
+
+               if ($this->getOption('v')) {
+                       $this->out('String files');
+               }
+
+               $files = glob('view/lang/*/strings.php');
+               $this->checkFiles($php_path, $files);
+
+               $this->out('No errors.');
+
+               return 0;
+       }
+
+       private function checkFiles($php_path, array $files)
+       {
+               foreach ($files as $file) {
+                       $this->checkFile($php_path, $file);
+               }
+       }
+
+       private function checkFile($php_path, $file)
+       {
+               if ($this->getOption('v')) {
+                       $this->out('Checking ' . $file);
+               }
+
+               $output = [];
+               $ret = 0;
+               exec("$php_path -l $file", $output, $ret);
+               if ($ret !== 0) {
+                       throw new \RuntimeException('Parse error found in ' . $file . ', scan stopped.');
+               }
+       }
+}
index 0cc63a5913fcef016e217a9d44e927c0b27953c4..2893c27b2341e2275b3f2055d84b7e3e4a8b9052 100644 (file)
@@ -2,6 +2,8 @@
 
 namespace Friendica\Core;
 
+use Friendica;
+
 /**
  * Description of Console
  *
@@ -47,24 +49,24 @@ HELP;
        }
 
        protected $subConsoles = [
-               'cache'                  => __NAMESPACE__ . '\Console\Cache',
-               'config'                 => __NAMESPACE__ . '\Console\Config',
-               'createdoxygen'          => __NAMESPACE__ . '\Console\CreateDoxygen',
-               'docbloxerrorchecker'    => __NAMESPACE__ . '\Console\DocBloxErrorChecker',
-               'dbstructure'            => __NAMESPACE__ . '\Console\DatabaseStructure',
-               'extract'                => __NAMESPACE__ . '\Console\Extract',
-               'globalcommunityblock'   => __NAMESPACE__ . '\Console\GlobalCommunityBlock',
-               'globalcommunitysilence' => __NAMESPACE__ . '\Console\GlobalCommunitySilence',
-               'archivecontact'         => __NAMESPACE__ . '\Console\ArchiveContact',
-               'autoinstall'            => __NAMESPACE__ . '\Console\AutomaticInstallation',
-               'maintenance'            => __NAMESPACE__ . '\Console\Maintenance',
-               'newpassword'            => __NAMESPACE__ . '\Console\NewPassword',
-               'php2po'                 => __NAMESPACE__ . '\Console\PhpToPo',
-               'po2php'                 => __NAMESPACE__ . '\Console\PoToPhp',
-               'typo'                   => __NAMESPACE__ . '\Console\Typo',
-               'postupdate'             => __NAMESPACE__ . '\Console\PostUpdate',
-               'serverblock'            => __NAMESPACE__ . '\Console\ServerBlock',
-               'storage'                => __NAMESPACE__ . '\Console\Storage',
+               'cache'                  => Friendica\Console\Cache::class,
+               'config'                 => Friendica\Console\Config::class,
+               'createdoxygen'          => Friendica\Console\CreateDoxygen::class,
+               'docbloxerrorchecker'    => Friendica\Console\DocBloxErrorChecker::class,
+               'dbstructure'            => Friendica\Console\DatabaseStructure::class,
+               'extract'                => Friendica\Console\Extract::class,
+               'globalcommunityblock'   => Friendica\Console\GlobalCommunityBlock::class,
+               'globalcommunitysilence' => Friendica\Console\GlobalCommunitySilence::class,
+               'archivecontact'         => Friendica\Console\ArchiveContact::class,
+               'autoinstall'            => Friendica\Console\AutomaticInstallation::class,
+               'maintenance'            => Friendica\Console\Maintenance::class,
+               'newpassword'            => Friendica\Console\NewPassword::class,
+               'php2po'                 => Friendica\Console\PhpToPo::class,
+               'po2php'                 => Friendica\Console\PoToPhp::class,
+               'typo'                   => Friendica\Console\Typo::class,
+               'postupdate'             => Friendica\Console\PostUpdate::class,
+               'serverblock'            => Friendica\Console\ServerBlock::class,
+               'storage'                => Friendica\Console\Storage::class,
        ];
 
        protected function doExecute()
diff --git a/src/Core/Console/ArchiveContact.php b/src/Core/Console/ArchiveContact.php
deleted file mode 100644 (file)
index b93c079..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-<?php
-
-namespace Friendica\Core\Console;
-
-use Friendica\Core\L10n;
-use Friendica\Database\DBA;
-use Friendica\Util\Strings;
-use RuntimeException;
-
-/**
- * @brief tool to archive a contact on the server
- *
- * With this tool you can archive a contact when you know that it isn't existing anymore.
- * Normally this does happen automatically after a few days.
- *
- * License: AGPLv3 or later, same as Friendica
- *
- */
-class ArchiveContact extends \Asika\SimpleConsole\Console
-{
-       protected $helpOptions = ['h', 'help', '?'];
-
-       protected function getHelp()
-       {
-               $help = <<<HELP
-console archivecontact - archive a contact
-Usage
-       bin/console archivecontact <profile_url> [-h|--help|-?] [-v]
-
-Description
-       Archive a contact when you know that it isn't existing anymore. Normally this does happen automatically after a few days.
-
-Options
-    -h|--help|-? Show help information
-    -v           Show more debug information.
-HELP;
-               return $help;
-       }
-
-       protected function doExecute()
-       {
-               $a = \Friendica\BaseObject::getApp();
-
-               if ($this->getOption('v')) {
-                       $this->out('Class: ' . __CLASS__);
-                       $this->out('Arguments: ' . var_export($this->args, true));
-                       $this->out('Options: ' . var_export($this->options, true));
-               }
-
-               if (count($this->args) == 0) {
-                       $this->out($this->getHelp());
-                       return 0;
-               }
-
-               if (count($this->args) > 1) {
-                       throw new \Asika\SimpleConsole\CommandArgsException('Too many arguments');
-               }
-
-               if ($a->getMode()->isInstall()) {
-                       throw new RuntimeException('Friendica isn\'t properly installed yet.');
-               }
-
-               $nurl = Strings::normaliseLink($this->getArgument(0));
-               if (!DBA::exists('contact', ['nurl' => $nurl, 'archive' => false])) {
-                       throw new RuntimeException(L10n::t('Could not find any unarchived contact entry for this URL (%s)', $nurl));
-               }
-               if (DBA::update('contact', ['archive' => true], ['nurl' => $nurl])) {
-                       $this->out(L10n::t('The contact entries have been archived'));
-               } else {
-                       throw new RuntimeException('The contact archival failed.');
-               }
-
-               return 0;
-       }
-}
diff --git a/src/Core/Console/AutomaticInstallation.php b/src/Core/Console/AutomaticInstallation.php
deleted file mode 100644 (file)
index e2857d6..0000000
+++ /dev/null
@@ -1,265 +0,0 @@
-<?php
-
-namespace Friendica\Core\Console;
-
-use Asika\SimpleConsole\Console;
-use Friendica\BaseObject;
-use Friendica\Core\Config;
-use Friendica\Core\Installer;
-use Friendica\Core\Theme;
-use Friendica\Util\BasePath;
-use Friendica\Util\BaseURL;
-use Friendica\Util\Config\ConfigFileLoader;
-use RuntimeException;
-
-class AutomaticInstallation extends Console
-{
-       protected function getHelp()
-       {
-               return <<<HELP
-Installation - Install Friendica automatically
-Synopsis
-       bin/console autoinstall [-h|--help|-?] [-v] [-a] [-f]
-
-Description
-    Installs Friendica with data based on the local.config.php file or environment variables
-
-Notes
-    Not checking .htaccess/URL-Rewrite during CLI installation.
-
-Options
-    -h|--help|-?            Show help information
-    -v                      Show more debug information.
-    -a                      All setup checks are required (except .htaccess)
-    -f|--file <config>      prepared config file (e.g. "config/local.config.php" itself) which will override every other config option - except the environment variables)
-    -s|--savedb               Save the DB credentials to the file (if environment variables is used)
-    -H|--dbhost <host>        The host of the mysql/mariadb database (env MYSQL_HOST)
-    -p|--dbport <port>        The port of the mysql/mariadb database (env MYSQL_PORT)
-    -d|--dbdata <database>    The name of the mysql/mariadb database (env MYSQL_DATABASE)
-    -U|--dbuser <username>    The username of the mysql/mariadb database login (env MYSQL_USER or MYSQL_USERNAME)
-    -P|--dbpass <password>    The password of the mysql/mariadb database login (env MYSQL_PASSWORD)
-    -U|--url <url>            The full base URL of Friendica - f.e. 'https://friendica.local/sub' (env FRIENDICA_URL) 
-    -B|--phppath <php_path>   The path of the PHP binary (env FRIENDICA_PHP_PATH)
-    -b|--basepath <base_path> The basepath of Friendica (env FRIENDICA_BASE_PATH)
-    -t|--tz <timezone>        The timezone of Friendica (env FRIENDICA_TZ)
-    -L|--lang <language>      The language of Friendica (env FRIENDICA_LANG)
-Environment variables
-   MYSQL_HOST                  The host of the mysql/mariadb database (mandatory if mysql and environment is used)
-   MYSQL_PORT                  The port of the mysql/mariadb database
-   MYSQL_USERNAME|MYSQL_USER   The username of the mysql/mariadb database login (MYSQL_USERNAME is for mysql, MYSQL_USER for mariadb)
-   MYSQL_PASSWORD              The password of the mysql/mariadb database login
-   MYSQL_DATABASE              The name of the mysql/mariadb database
-   FRIENDICA_URL               The full base URL of Friendica - f.e. 'https://friendica.local/sub'
-   FRIENDICA_PHP_PATH          The path of the PHP binary - leave empty for auto detection
-   FRIENDICA_BASE_PATH         The basepath of Friendica - leave empty for auto detection
-   FRIENDICA_ADMIN_MAIL        The admin email address of Friendica (this email will be used for admin access)
-   FRIENDICA_TZ                The timezone of Friendica
-   FRIENDICA_LANG              The langauge of Friendica
-   
-Examples
-       bin/console autoinstall -f 'input.config.php
-               Installs Friendica with the prepared 'input.config.php' file
-
-       bin/console autoinstall --savedb
-               Installs Friendica with environment variables and saves them to the 'config/local.config.php' file
-
-       bin/console autoinstall -h localhost -p 3365 -U user -P passwort1234 -d friendica
-               Installs Friendica with a local mysql database with credentials
-HELP;
-       }
-
-       protected function doExecute()
-       {
-               // Initialise the app
-               $this->out("Initializing setup...\n");
-
-               $a = BaseObject::getApp();
-
-               $installer = new Installer();
-
-               $configCache = $a->getConfigCache();
-               $installer->setUpCache($configCache, BasePath::create($a->getBasePath(), $_SERVER));
-
-               $this->out(" Complete!\n\n");
-
-               // Check Environment
-               $this->out("Checking environment...\n");
-
-               $installer->resetChecks();
-
-               if (!$this->runBasicChecks($installer, $configCache)) {
-                       $errorMessage = $this->extractErrors($installer->getChecks());
-                       throw new RuntimeException($errorMessage);
-               }
-
-               $this->out(" Complete!\n\n");
-
-               // if a config file is set,
-               $config_file = $this->getOption(['f', 'file']);
-
-               if (!empty($config_file)) {
-                       if ($config_file != 'config' . DIRECTORY_SEPARATOR . 'local.config.php') {
-                               // Copy config file
-                               $this->out("Copying config file...\n");
-                               if (!copy($a->getBasePath() . DIRECTORY_SEPARATOR . $config_file, $a->getBasePath() . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'local.config.php')) {
-                                       throw new RuntimeException("ERROR: Saving config file failed. Please copy '$config_file' to '" . $a->getBasePath() . "'" . DIRECTORY_SEPARATOR . "config" . DIRECTORY_SEPARATOR . "local.config.php' manually.\n");
-                               }
-                       }
-
-                       //reload the config cache
-                       $loader = new ConfigFileLoader($a->getBasePath(), $a->getMode());
-                       $loader->setupCache($configCache);
-
-               } else {
-                       // Creating config file
-                       $this->out("Creating config file...\n");
-
-                       $save_db = $this->getOption(['s', 'savedb'], false);
-
-                       $db_host = $this->getOption(['H', 'dbhost'], ($save_db) ? (getenv('MYSQL_HOST')) : Installer::DEFAULT_HOST);
-                       $db_port = $this->getOption(['p', 'dbport'], ($save_db) ? getenv('MYSQL_PORT') : null);
-                       $configCache->set('database', 'hostname', $db_host . (!empty($db_port) ? ':' . $db_port : ''));
-                       $configCache->set('database', 'database',
-                               $this->getOption(['d', 'dbdata'],
-                                       ($save_db) ? getenv('MYSQL_DATABASE') : ''));
-                       $configCache->set('database', 'username',
-                               $this->getOption(['U', 'dbuser'],
-                                       ($save_db) ? getenv('MYSQL_USER') . getenv('MYSQL_USERNAME') : ''));
-                       $configCache->set('database', 'password',
-                               $this->getOption(['P', 'dbpass'],
-                                       ($save_db) ? getenv('MYSQL_PASSWORD') : ''));
-
-                       $php_path = $this->getOption(['b', 'phppath'], !empty('FRIENDICA_PHP_PATH') ? getenv('FRIENDICA_PHP_PATH') : null);
-                       if (!empty($php_path)) {
-                               $configCache->set('config', 'php_path', $php_path);
-                       } else {
-                               $configCache->set('config', 'php_path', $installer->getPHPPath());
-                       }
-
-                       $configCache->set('config', 'admin_email',
-                               $this->getOption(['A', 'admin'],
-                                       !empty(getenv('FRIENDICA_ADMIN_MAIL')) ? getenv('FRIENDICA_ADMIN_MAIL') : ''));
-                       $configCache->set('system', 'default_timezone',
-                               $this->getOption(['T', 'tz'],
-                                       !empty(getenv('FRIENDICA_TZ')) ? getenv('FRIENDICA_TZ') : Installer::DEFAULT_TZ));
-                       $configCache->set('system', 'language',
-                               $this->getOption(['L', 'lang'],
-                                       !empty(getenv('FRIENDICA_LANG')) ? getenv('FRIENDICA_LANG') : Installer::DEFAULT_LANG));
-
-                       $basepath = $this->getOption(['b', 'basepath'], !empty(getenv('FRIENDICA_BASE_PATH')) ? getenv('FRIENDICA_BASE_PATH') : null);
-                       if (!empty($basepath)) {
-                               $configCache->set('system', 'basepath', $basepath);
-                       }
-
-                       $url = $this->getOption(['U', 'url'], !empty(getenv('FRIENDICA_URL')) ? getenv('FRIENDICA_URL') : null);
-
-                       if (empty($url)) {
-                               $this->out('The Friendica URL has to be set during CLI installation.');
-                               return 1;
-                       } else {
-                               $baseUrl = new BaseURL($a->getConfig(), []);
-                               $baseUrl->saveByURL($url);
-                       }
-
-                       $installer->createConfig($configCache);
-               }
-
-               $this->out(" Complete!\n\n");
-
-               // Check database connection
-               $this->out("Checking database...\n");
-
-               $installer->resetChecks();
-
-               if (!$installer->checkDB($configCache, $a->getProfiler())) {
-                       $errorMessage = $this->extractErrors($installer->getChecks());
-                       throw new RuntimeException($errorMessage);
-               }
-
-               $this->out(" Complete!\n\n");
-
-               // Install database
-               $this->out("Inserting data into database...\n");
-
-               $installer->resetChecks();
-
-               if (!$installer->installDatabase($a->getBasePath())) {
-                       $errorMessage = $this->extractErrors($installer->getChecks());
-                       throw new RuntimeException($errorMessage);
-               }
-
-               $this->out(" Complete!\n\n");
-
-               // Install theme
-               $this->out("Installing theme\n");
-               if (!empty(Config::get('system', 'theme'))) {
-                       Theme::install(Config::get('system', 'theme'));
-                       $this->out(" Complete\n\n");
-               } else {
-                       $this->out(" Theme setting is empty. Please check the file 'config/local.config.php'\n\n");
-               }
-
-               $this->out("\nInstallation is finished\n");
-
-               return 0;
-       }
-
-       /**
-        * @param Installer                 $installer   The Installer instance
-        * @param Config\Cache\IConfigCache $configCache The config cache
-        *
-        * @return bool true if checks were successfully, otherwise false
-        * @throws \Friendica\Network\HTTPException\InternalServerErrorException
-        */
-       private function runBasicChecks(Installer $installer, Config\Cache\IConfigCache $configCache)
-       {
-               $checked = true;
-
-               $installer->resetChecks();
-               if (!$installer->checkFunctions())              {
-                       $checked = false;
-               }
-               if (!$installer->checkImagick()) {
-                       $checked = false;
-               }
-               if (!$installer->checkLocalIni()) {
-                       $checked = false;
-               }
-               if (!$installer->checkSmarty3()) {
-                       $checked = false;
-               }
-               if (!$installer->checkKeys()) {
-                       $checked = false;
-               }
-
-               $php_path = $configCache->get('config', 'php_path');
-
-               if (!$installer->checkPHP($php_path, true)) {
-                       $checked = false;
-               }
-
-               $this->out(" NOTICE: Not checking .htaccess/URL-Rewrite during CLI installation.\n");
-
-               return $checked;
-       }
-
-       /**
-        * @param array $results
-        * @return string
-        */
-       private function extractErrors($results)
-       {
-               $errorMessage = '';
-               $allChecksRequired = $this->getOption('a') !== null;
-
-               foreach ($results as $result) {
-                       if (($allChecksRequired || $result['required'] === true) && $result['status'] === false) {
-                               $errorMessage .= "--------\n";
-                               $errorMessage .= $result['title'] . ': ' . $result['help'] . "\n";
-                       }
-               }
-
-               return $errorMessage;
-       }
-}
diff --git a/src/Core/Console/Cache.php b/src/Core/Console/Cache.php
deleted file mode 100644 (file)
index 510c05b..0000000
+++ /dev/null
@@ -1,178 +0,0 @@
-<?php
-
-namespace Friendica\Core\Console;
-
-use Asika\SimpleConsole\CommandArgsException;
-use Friendica\App;
-use Friendica\Core;
-use RuntimeException;
-
-/**
- * @brief tool to access the cache from the CLI
- *
- * With this script you can access the cache of your node from the CLI.
- * You can read current values stored in the cache and set new values
- * in cache keys.
- *
- * @author Hypolite Petovan <hypolite@mrpetovan.com>
- */
-class Cache extends \Asika\SimpleConsole\Console
-{
-       protected $helpOptions = ['h', 'help', '?'];
-
-       protected function getHelp()
-       {
-               $help = <<<HELP
-console cache - Manage node cache
-Synopsis
-       bin/console cache list [-h|--help|-?] [-v]
-       bin/console cache get <key> [-h|--help|-?] [-v]
-       bin/console cache set <key> <value> [-h|--help|-?] [-v]
-       bin/console cache flush [-h|--help|-?] [-v]
-       bin/console cache clear [-h|--help|-?] [-v]
-
-Description
-       bin/console cache list [<prefix>]
-               List all cache keys, optionally filtered by a prefix
-
-       bin/console cache get <key>
-               Shows the value of the provided cache key
-
-       bin/console cache set <key> <value> [<ttl>]
-               Sets the value of the provided cache key, optionally with the provided TTL (time to live) with a default of five minutes.
-
-       bin/console cache flush
-               Clears expired cache keys
-
-       bin/console cache clear
-               Clears all cache keys
-
-Options
-    -h|--help|-? Show help information
-    -v           Show more debug information.
-HELP;
-               return $help;
-       }
-
-       protected function doExecute()
-       {
-               $a = \Friendica\BaseObject::getApp();
-
-               if ($this->getOption('v')) {
-                       $this->out('Executable: ' . $this->executable);
-                       $this->out('Class: ' . __CLASS__);
-                       $this->out('Arguments: ' . var_export($this->args, true));
-                       $this->out('Options: ' . var_export($this->options, true));
-               }
-
-               if ($a->getMode()->has(App\Mode::DBCONFIGAVAILABLE)) {
-                       $this->out('Database isn\'t ready or populated yet, database cache won\'t be available');
-               }
-
-               Core\Cache::init();
-
-               if ($this->getOption('v')) {
-                       $this->out('Cache Driver Name: ' . Core\Cache::$driver_name);
-                       $this->out('Cache Driver Class: ' . Core\Cache::$driver_class);
-               }
-
-               switch ($this->getArgument(0)) {
-                       case 'list':
-                               $this->executeList();
-                               break;
-                       case 'get':
-                               $this->executeGet();
-                               break;
-                       case 'set':
-                               $this->executeSet();
-                               break;
-                       case 'flush':
-                               $this->executeFlush();
-                               break;
-                       case 'clear':
-                               $this->executeClear();
-                               break;
-               }
-
-               if (count($this->args) == 0) {
-                       $this->out($this->getHelp());
-                       return 0;
-               }
-
-               return 0;
-       }
-
-       private function executeList()
-       {
-               $prefix = $this->getArgument(1);
-               $keys = Core\Cache::getAllKeys($prefix);
-
-               if (empty($prefix)) {
-                       $this->out('Listing all cache keys:');
-               } else {
-                       $this->out('Listing all cache keys starting with "' . $prefix . '":');
-               }
-
-               $count = 0;
-               foreach ($keys as $key) {
-                       $this->out($key);
-                       $count++;
-               }
-
-               $this->out($count . ' keys found');
-       }
-
-       private function executeGet()
-       {
-               if (count($this->args) >= 2) {
-                       $key = $this->getArgument(1);
-                       $value = Core\Cache::get($key);
-
-                       $this->out("{$key} => " . var_export($value, true));
-               } else {
-                       throw new CommandArgsException('Too few arguments for get');
-               }
-       }
-
-       private function executeSet()
-       {
-               if (count($this->args) >= 3) {
-                       $key = $this->getArgument(1);
-                       $value = $this->getArgument(2);
-                       $duration = intval($this->getArgument(3, Core\Cache::FIVE_MINUTES));
-
-                       if (is_array(Core\Cache::get($key))) {
-                               throw new RuntimeException("$key is an array and can't be set using this command.");
-                       }
-
-                       $result = Core\Cache::set($key, $value, $duration);
-                       if ($result) {
-                               $this->out("{$key} <= " . Core\Cache::get($key));
-                       } else {
-                               $this->out("Unable to set {$key}");
-                       }
-               } else {
-                       throw new CommandArgsException('Too few arguments for set');
-               }
-       }
-
-       private function executeFlush()
-       {
-               $result = Core\Cache::clear();
-               if ($result) {
-                       $this->out('Cache successfully flushed');
-               } else {
-                       $this->out('Unable to flush the cache');
-               }
-       }
-
-       private function executeClear()
-       {
-               $result = Core\Cache::clear(false);
-               if ($result) {
-                       $this->out('Cache successfully cleared');
-               } else {
-                       $this->out('Unable to flush the cache');
-               }
-       }
-}
diff --git a/src/Core/Console/Config.php b/src/Core/Console/Config.php
deleted file mode 100644 (file)
index cf5c09f..0000000
+++ /dev/null
@@ -1,171 +0,0 @@
-<?php
-
-namespace Friendica\Core\Console;
-
-use Asika\SimpleConsole\CommandArgsException;
-use Friendica\App;
-use Friendica\Core;
-use RuntimeException;
-
-/**
- * @brief tool to access the system config from the CLI
- *
- * With this script you can access the system configuration of your node from
- * the CLI. You can do both, reading current values stored in the database and
- * set new values to config variables.
- *
- * Usage:
- *   If you specify no parameters at the CLI, the script will list all config
- *   variables defined.
- *
- *   If you specify one parameter, the script will list all config variables
- *   defined in this section of the configuration (e.g. "system").
- *
- *   If you specify two parameters, the script will show you the current value
- *   of the named configuration setting. (e.g. "system loglevel")
- *
- *   If you specify three parameters, the named configuration setting will be
- *   set to the value of the last parameter. (e.g. "system loglevel 0" will
- *   disable logging)
- *
- * @author Tobias Diekershoff <tobias.diekershoff@gmx.net>
- * @author Hypolite Petovan <hypolite@mrpetovan.com>
- */
-class Config extends \Asika\SimpleConsole\Console
-{
-       protected $helpOptions = ['h', 'help', '?'];
-
-       protected function getHelp()
-       {
-               $help = <<<HELP
-console config - Manage site configuration
-Synopsis
-       bin/console config [-h|--help|-?] [-v]
-       bin/console config <category> [-h|--help|-?] [-v]
-       bin/console config <category> <key> [-h|--help|-?] [-v]
-       bin/console config <category> <key> <value> [-h|--help|-?] [-v]
-
-Description
-       bin/console config
-               Lists all config values
-
-       bin/console config <category>
-               Lists all config values in the provided category
-
-       bin/console config <category> <key>
-               Shows the value of the provided key in the category
-
-       bin/console config <category> <key> <value>
-               Sets the value of the provided key in the category
-
-Notes:
-       Setting config entries which are manually set in config/local.config.php may result in
-       conflict between database settings and the manual startup settings.
-
-Options
-    -h|--help|-? Show help information
-    -v           Show more debug information.
-HELP;
-               return $help;
-       }
-
-       protected function doExecute()
-       {
-               $a = \Friendica\BaseObject::getApp();
-
-               if ($this->getOption('v')) {
-                       $this->out('Executable: ' . $this->executable);
-                       $this->out('Class: ' . __CLASS__);
-                       $this->out('Arguments: ' . var_export($this->args, true));
-                       $this->out('Options: ' . var_export($this->options, true));
-               }
-
-               if (count($this->args) > 3) {
-                       throw new CommandArgsException('Too many arguments');
-               }
-
-               if (!$a->getMode()->has(App\Mode::DBCONFIGAVAILABLE)) {
-                       $this->out('Database isn\'t ready or populated yet, showing file config only');
-               }
-
-               if (count($this->args) == 3) {
-                       $cat = $this->getArgument(0);
-                       $key = $this->getArgument(1);
-                       $value = $this->getArgument(2);
-
-                       if (is_array(Core\Config::get($cat, $key))) {
-                               throw new RuntimeException("$cat.$key is an array and can't be set using this command.");
-                       }
-
-                       $result = Core\Config::set($cat, $key, $value);
-                       if ($result) {
-                               $this->out("{$cat}.{$key} <= " .
-                                       Core\Config::get($cat, $key));
-                       } else {
-                               $this->out("Unable to set {$cat}.{$key}");
-                       }
-               }
-
-               if (count($this->args) == 2) {
-                       $cat = $this->getArgument(0);
-                       $key = $this->getArgument(1);
-                       $value = Core\Config::get($this->getArgument(0), $this->getArgument(1));
-
-                       if (is_array($value)) {
-                               foreach ($value as $k => $v) {
-                                       $this->out("{$cat}.{$key}[{$k}] => " . (is_array($v) ? implode(', ', $v) : $v));
-                               }
-                       } else {
-                               $this->out("{$cat}.{$key} => " . $value);
-                       }
-               }
-
-               if (count($this->args) == 1) {
-                       $cat = $this->getArgument(0);
-                       Core\Config::load($cat);
-
-                       if ($a->getConfigCache()->get($cat) !== null) {
-                               $this->out("[{$cat}]");
-                               $catVal = $a->getConfigCache()->get($cat);
-                               foreach ($catVal as $key => $value) {
-                                       if (is_array($value)) {
-                                               foreach ($value as $k => $v) {
-                                                       $this->out("{$key}[{$k}] => " . (is_array($v) ? implode(', ', $v) : $v));
-                                               }
-                                       } else {
-                                               $this->out("{$key} => " . $value);
-                                       }
-                               }
-                       } else {
-                               $this->out('Config section ' . $this->getArgument(0) . ' returned nothing');
-                       }
-               }
-
-               if (count($this->args) == 0) {
-                       Core\Config::load();
-
-                       if (Core\Config::get('system', 'config_adapter') == 'jit' && $a->getMode()->has(App\Mode::DBCONFIGAVAILABLE)) {
-                               $this->out('Warning: The JIT (Just In Time) Config adapter doesn\'t support loading the entire configuration, showing file config only');
-                       }
-
-                       $config = $a->getConfigCache()->getAll();
-                       foreach ($config as $cat => $section) {
-                               if (is_array($section)) {
-                                       foreach ($section as $key => $value) {
-                                               if (is_array($value)) {
-                                                       foreach ($value as $k => $v) {
-                                                               $this->out("{$cat}.{$key}[{$k}] => " . (is_array($v) ? implode(', ', $v) : $v));
-                                                       }
-                                               } else {
-                                                       $this->out("{$cat}.{$key} => " . $value);
-                                               }
-                                       }
-                               } else {
-                                       $this->out("config.{$cat} => " . $section);
-                               }
-                       }
-               }
-
-               return 0;
-       }
-}
diff --git a/src/Core/Console/CreateDoxygen.php b/src/Core/Console/CreateDoxygen.php
deleted file mode 100644 (file)
index 1de2cee..0000000
+++ /dev/null
@@ -1,148 +0,0 @@
-<?php
-
-namespace Friendica\Core\Console;
-
-/**
- * Description of CreateDoxygen
- *
- * @author Hypolite Petovan <hypolite@mrpetovan.com>
- */
-class CreateDoxygen extends \Asika\SimpleConsole\Console
-{
-       protected $helpOptions = ['h', 'help', '?'];
-
-       protected function getHelp()
-       {
-               $help = <<<HELP
-console createdoxygen - Generate Doxygen headers
-Usage
-       bin/console createdoxygen <file> [-h|--help|-?] [-v]
-
-Description
-       Outputs the provided file with added Doxygen headers to functions
-
-Options
-    -h|--help|-? Show help information
-    -v           Show more debug information.
-HELP;
-               return $help;
-       }
-
-       protected function doExecute()
-       {
-               if ($this->getOption('v')) {
-                       $this->out('Class: ' . __CLASS__);
-                       $this->out('Arguments: ' . var_export($this->args, true));
-                       $this->out('Options: ' . var_export($this->options, true));
-               }
-
-               if (count($this->args) == 0) {
-                       $this->out($this->getHelp());
-                       return 0;
-               }
-
-               if (count($this->args) > 1) {
-                       throw new \Asika\SimpleConsole\CommandArgsException('Too many arguments');
-               }
-
-               $file = $this->getArgument(0);
-               if (!file_exists($file)) {
-                       throw new \RuntimeException('Unable to find specified file.');
-               }
-
-               $data = file_get_contents($file);
-
-               $lines = explode("\n", $data);
-
-               $previous = "";
-
-               foreach ($lines AS $line) {
-                       $line = rtrim(trim($line, "\r"));
-
-                       if (strstr(strtolower($line), "function")) {
-                               $detect = strtolower(trim($line));
-                               $detect = implode(" ", explode(" ", $detect));
-
-                               $found = false;
-
-                               if (substr($detect, 0, 9) == "function ") {
-                                       $found = true;
-                               }
-
-                               if (substr($detect, 0, 19) == "protected function ") {
-                                       $found = true;
-                               }
-
-                               if (substr($detect, 0, 17) == "private function ") {
-                                       $found = true;
-                               }
-
-                               if (substr($detect, 0, 23) == "public static function ") {
-                                       $found = true;
-                               }
-
-                               if (substr($detect, 0, 24) == "private static function ") {
-                                       $found = true;
-                               }
-
-                               if (substr($detect, 0, 10) == "function (") {
-                                       $found = false;
-                               }
-
-                               if ($found && ( trim($previous) == "*/")) {
-                                       $found = false;
-                               }
-
-                               if ($found) {
-                                       $this->out($this->addDocumentation($line));
-                               }
-                       }
-                       $this->out($line);
-                       $previous = $line;
-               }
-
-               return 0;
-       }
-
-       /**
-        * @brief Adds a doxygen header
-        *
-        * @param string $line The current line of the document
-        *
-        * @return string added doxygen header
-        */
-       private function addDocumentation($line)
-       {
-               $trimmed = ltrim($line);
-               $length = strlen($line) - strlen($trimmed);
-               $space = substr($line, 0, $length);
-
-               $block = $space . "/**\n" .
-                       $space . " * @brief \n" .
-                       $space . " *\n"; /**/
-
-
-               $left = strpos($line, "(");
-               $line = substr($line, $left + 1);
-
-               $right = strpos($line, ")");
-               $line = trim(substr($line, 0, $right));
-
-               if ($line != "") {
-                       $parameters = explode(",", $line);
-                       foreach ($parameters AS $parameter) {
-                               $parameter = trim($parameter);
-                               $splitted = explode("=", $parameter);
-
-                               $block .= $space . " * @param " . trim($splitted[0], "& ") . "\n";
-                       }
-                       if (count($parameters) > 0) $block .= $space . " *\n";
-               }
-
-               $block .= $space . " * @return \n" .
-                       $space . " */\n";
-
-               return $block;
-       }
-
-}
diff --git a/src/Core/Console/DatabaseStructure.php b/src/Core/Console/DatabaseStructure.php
deleted file mode 100644 (file)
index dededa9..0000000
+++ /dev/null
@@ -1,94 +0,0 @@
-<?php
-
-namespace Friendica\Core\Console;
-
-use Friendica\Core;
-use Friendica\Core\Update;
-use Friendica\Database\DBA;
-use Friendica\Database\DBStructure;
-use RuntimeException;
-
-/**
- * @brief Performs database updates from the command line
- *
- * @author Hypolite Petovan <hypolite@mrpetovan.com>
- */
-class DatabaseStructure extends \Asika\SimpleConsole\Console
-{
-       protected $helpOptions = ['h', 'help', '?'];
-
-       protected function getHelp()
-       {
-               $help = <<<HELP
-console dbstructure - Performs database updates
-Usage
-       bin/console dbstructure <command> [-h|--help|-?] |-f|--force] [-v]
-
-Commands
-       dryrun   Show database update schema queries without running them
-       update   Update database schema
-       dumpsql  Dump database schema
-       toinnodb Convert all tables from MyISAM to InnoDB
-
-Options
-    -h|--help|-?       Show help information
-    -v                 Show more debug information.
-    -f|--force         Force the update command (Even if the database structure matches)
-    -o|--override      Override running or stalling updates
-HELP;
-               return $help;
-       }
-
-       protected function doExecute()
-       {
-               if ($this->getOption('v')) {
-                       $this->out('Class: ' . __CLASS__);
-                       $this->out('Arguments: ' . var_export($this->args, true));
-                       $this->out('Options: ' . var_export($this->options, true));
-               }
-
-               if (count($this->args) == 0) {
-                       $this->out($this->getHelp());
-                       return 0;
-               }
-
-               if (count($this->args) > 1) {
-                       throw new \Asika\SimpleConsole\CommandArgsException('Too many arguments');
-               }
-
-               if (!DBA::connected()) {
-                       throw new RuntimeException('Unable to connect to database');
-               }
-
-               Core\Config::load();
-
-               $a = get_app();
-
-               switch ($this->getArgument(0)) {
-                       case "dryrun":
-                               $output = DBStructure::update($a->getBasePath(), true, false);
-                               break;
-                       case "update":
-                               $force    = $this->getOption(['f', 'force'], false);
-                               $override = $this->getOption(['o', 'override'], false);
-                               $output = Update::run($a->getBasePath(), $force, $override,true, false);
-                               break;
-                       case "dumpsql":
-                               ob_start();
-                               DBStructure::printStructure($a->getBasePath());
-                               $output = ob_get_clean();
-                               break;
-                       case "toinnodb":
-                               ob_start();
-                               DBStructure::convertToInnoDB();
-                               $output = ob_get_clean();
-                               break;
-                       default:
-                               $output = 'Unknown command: ' . $this->getArgument(0);
-               }
-
-               $this->out($output);
-
-               return 0;
-       }
-}
diff --git a/src/Core/Console/DocBloxErrorChecker.php b/src/Core/Console/DocBloxErrorChecker.php
deleted file mode 100644 (file)
index 506e48f..0000000
+++ /dev/null
@@ -1,186 +0,0 @@
-<?php
-
-namespace Friendica\Core\Console;
-
-/**
- * When I installed docblox, I had the experience that it does not generate any output at all.
- * This script may be used to find that kind of problems with the documentation build process.
- * If docblox generates output, use another approach for debugging.
- *
- * Basically, docblox takes a list of files to build documentation from. This script assumes there is a file or set of files
- * breaking the build when it is included in that list. It tries to calculate the smallest list containing these files.
- * Unfortunatly, the original problem is NP-complete, so what the script does is a best guess only.
- *
- * So it starts with a list of all files in the project.
- * If that list can't be build, it cuts it in two parts and tries both parts independently. If only one of them breaks,
- * it takes that one and tries the same independently. If both break, it assumes this is the smallest set. This assumption
- * is not necessarily true. Maybe the smallest set consists of two files and both of them were in different parts when
- * the list was divided, but by now it is my best guess. To make this assumption better, the list is shuffled after every step.
- *
- * After that, the script tries to remove a file from the list. It tests if the list breaks and if so, it
- * assumes that the file it removed belongs to the set of erroneous files.
- * This is done for all files, so, in the end removing one file leads to a working doc build.
- *
- * @author Alexander Kampmann
- * @author Hypolite Petovan <hypolite@mrpetovan.com>
- */
-class DocBloxErrorChecker extends \Asika\SimpleConsole\Console
-{
-
-       protected $helpOptions = ['h', 'help', '?'];
-
-       protected function getHelp()
-       {
-               $help = <<<HELP
-console docbloxerrorchecker - Checks the file tree for docblox errors
-Usage
-       bin/console docbloxerrorchecker [-h|--help|-?] [-v]
-
-Options
-    -h|--help|-? Show help information
-    -v           Show more debug information.
-HELP;
-               return $help;
-       }
-
-       protected function doExecute()
-       {
-               if ($this->getOption('v')) {
-                       $this->out('Class: ' . __CLASS__);
-                       $this->out('Arguments: ' . var_export($this->args, true));
-                       $this->out('Options: ' . var_export($this->options, true));
-               }
-
-               if (count($this->args) > 0) {
-                       throw new \Asika\SimpleConsole\CommandArgsException('Too many arguments');
-               }
-
-               if (!$this->commandExists('docblox')) {
-                       throw new \RuntimeException('DocBlox isn\'t available.');
-               }
-
-               $dir = \get_app()->getBasePath();
-
-               //stack for dirs to search
-               $dirstack = [];
-               //list of source files
-               $filelist = [];
-
-               //loop over all files in $dir
-               while ($dh = opendir($dir)) {
-                       while ($file = readdir($dh)) {
-                               if (is_dir($dir . "/" . $file)) {
-                                       //add to directory stack
-                                       if (strpos($file, '.') !== 0) {
-                                               array_push($dirstack, $dir . "/" . $file);
-                                               $this->out('dir ' . $dir . '/' . $file);
-                                       }
-                               } else {
-                                       //test if it is a source file and add to filelist
-                                       if (substr($file, strlen($file) - 4) == ".php") {
-                                               array_push($filelist, $dir . "/" . $file);
-                                               $this->out($dir . '/' . $file);
-                                       }
-                               }
-                       }
-                       //look at the next dir
-                       $dir = array_pop($dirstack);
-               }
-
-               //check the entire set
-               if ($this->runs($filelist)) {
-                       throw new \RuntimeException("I can not detect a problem.");
-               }
-
-               //check half of the set and discard if that half is okay
-               $res = $filelist;
-               $i = count($res);
-               do {
-                       $this->out($i . '/' . count($filelist) . ' elements remaining.');
-                       $res = $this->reduce($res, count($res) / 2);
-                       shuffle($res);
-                       $i = count($res);
-               } while (count($res) < $i);
-
-               //check one file after another
-               $needed = [];
-
-               while (count($res) != 0) {
-                       $file = array_pop($res);
-
-                       if ($this->runs(array_merge($res, $needed))) {
-                               $this->out('needs: ' . $file . ' and file count ' . count($needed));
-                               array_push($needed, $file);
-                       }
-               }
-
-               $this->out('Smallest Set is: ' . $this->namesList($needed) . ' with ' . count($needed) . ' files. ');
-
-               return 0;
-       }
-
-       private function commandExists($command)
-       {
-               $prefix = strpos(strtolower(PHP_OS),'win') > -1 ? 'where' : 'which';
-               exec("{$prefix} {$command}", $output, $returnVal);
-               return $returnVal === 0;
-       }
-
-       /**
-        * This function generates a comma separated list of file names.
-        *
-        * @param array $fileset Set of file names
-        *
-        * @return string comma-separated list of the file names
-        */
-       private function namesList($fileset)
-       {
-               return implode(',', $fileset);
-       }
-
-       /**
-        * This functions runs phpdoc on the provided list of files
-        *
-        * @param array $fileset Set of filenames
-        *
-        * @return bool true, if that set can be built
-        */
-       private function runs($fileset)
-       {
-               $fsParam = $this->namesList($fileset);
-               $this->exec('docblox -t phpdoc_out -f ' . $fsParam);
-               if (file_exists("phpdoc_out/index.html")) {
-                       $this->out('Subset ' . $fsParam . ' is okay.');
-                       $this->exec('rm -r phpdoc_out');
-                       return true;
-               } else {
-                       $this->out('Subset ' . $fsParam . ' failed.');
-                       return false;
-               }
-       }
-
-       /**
-        * This functions cuts down a fileset by removing files until it finally works.
-        * it was meant to be recursive, but php's maximum stack size is to small. So it just simulates recursion.
-        *
-        * In that version, it does not necessarily generate the smallest set, because it may not alter the elements order enough.
-        *
-        * @param array $fileset set of filenames
-        * @param int $ps number of files in subsets
-        *
-        * @return array a part of $fileset, that crashes
-        */
-       private function reduce($fileset, $ps)
-       {
-               //split array...
-               $parts = array_chunk($fileset, $ps);
-               //filter working subsets...
-               $parts = array_filter($parts, [$this, 'runs']);
-               //melt remaining parts together
-               if (is_array($parts)) {
-                       return array_reduce($parts, "array_merge", []);
-               }
-               return [];
-       }
-
-}
diff --git a/src/Core/Console/Extract.php b/src/Core/Console/Extract.php
deleted file mode 100644 (file)
index e7c751f..0000000
+++ /dev/null
@@ -1,140 +0,0 @@
-<?php
-
-namespace Friendica\Core\Console;
-
-/**
- * Extracts translation strings from the Friendica project's files to be exported
- * to Transifex for translation.
- *
- * Outputs a PHP file with language strings used by Friendica
- *
- * @author Hypolite Petovan <hypolite@mrpetovan.com>
- */
-class Extract extends \Asika\SimpleConsole\Console
-{
-       protected $helpOptions = ['h', 'help', '?'];
-
-       protected function getHelp()
-       {
-               $help = <<<HELP
-console extract - Generate translation string file for the Friendica project (deprecated)
-Usage
-       bin/console extract [-h|--help|-?] [-v]
-
-Description
-       This script was used to generate the translation string file to be exported to Transifex,
-       please use bin/run_xgettext.sh instead
-
-Options
-    -h|--help|-? Show help information
-    -v           Show more debug information.
-HELP;
-               return $help;
-       }
-
-       protected function doExecute()
-       {
-               if ($this->getOption('v')) {
-                       $this->out('Class: ' . __CLASS__);
-                       $this->out('Arguments: ' . var_export($this->args, true));
-                       $this->out('Options: ' . var_export($this->options, true));
-               }
-
-               if (count($this->args) > 0) {
-                       throw new \Asika\SimpleConsole\CommandArgsException('Too many arguments');
-               }
-
-               $s = '<?php' . PHP_EOL;
-               $s .= '
-               function string_plural_select($n){
-                       return ($n != 1);
-               }
-
-               ';
-
-               $arr = [];
-
-               $files = array_merge(
-                       ['index.php', 'boot.php'],
-                       glob('mod/*'),
-                       glob('include/*'),
-                       glob('addon/*/*'),
-                       $this->globRecursive('src')
-               );
-
-               foreach ($files as $file) {
-                       $str = file_get_contents($file);
-
-                       $pat = '|L10n::t\(([^\)]*+)[\)]|';
-                       $patt = '|L10n::tt\(([^\)]*+)[\)]|';
-
-                       $matches = [];
-                       $matchestt = [];
-
-                       preg_match_all($pat, $str, $matches);
-                       preg_match_all($patt, $str, $matchestt);
-
-                       if (count($matches) || count($matchestt)) {
-                               $s .= '// ' . $file . PHP_EOL;
-                       }
-
-                       if (!empty($matches[1])) {
-                               foreach ($matches[1] as $long_match) {
-                                       $match_arr = preg_split('/(?<=[\'"])\s*,/', $long_match);
-                                       $match = $match_arr[0];
-                                       if (!in_array($match, $arr)) {
-                                               if (substr($match, 0, 1) == '$') {
-                                                       continue;
-                                               }
-
-                                               $arr[] = $match;
-
-                                               $s .= '$a->strings[' . $match . '] = ' . $match . ';' . "\n";
-                                       }
-                               }
-                       }
-                       if (!empty($matchestt[1])) {
-                               foreach ($matchestt[1] as $match) {
-                                       $matchtkns = preg_split("|[ \t\r\n]*,[ \t\r\n]*|", $match);
-                                       if (count($matchtkns) == 3 && !in_array($matchtkns[0], $arr)) {
-                                               if (substr($matchtkns[1], 0, 1) == '$') {
-                                                       continue;
-                                               }
-
-                                               $arr[] = $matchtkns[0];
-
-                                               $s .= '$a->strings[' . $matchtkns[0] . "] = array(\n";
-                                               $s .= "\t0 => " . $matchtkns[0] . ",\n";
-                                               $s .= "\t1 => " . $matchtkns[1] . ",\n";
-                                               $s .= ");\n";
-                                       }
-                               }
-                       }
-               }
-
-               $s .= '// Timezones' . PHP_EOL;
-
-               $zones = timezone_identifiers_list();
-               foreach ($zones as $zone) {
-                       $s .= '$a->strings[\'' . $zone . '\'] = \'' . $zone . '\';' . "\n";
-               }
-
-               $this->out($s);
-
-               return 0;
-       }
-
-       private function globRecursive($path) {
-               $dir_iterator = new \RecursiveDirectoryIterator($path);
-               $iterator = new \RecursiveIteratorIterator($dir_iterator, \RecursiveIteratorIterator::SELF_FIRST);
-
-               $return = [];
-               foreach ($iterator as $file) {
-                       if ($file->getBasename() != '.' && $file->getBasename() != '..') {
-                               $return[] = $file->getPathname();
-                       }
-               }
-
-               return $return;
-       }
-}
diff --git a/src/Core/Console/GlobalCommunityBlock.php b/src/Core/Console/GlobalCommunityBlock.php
deleted file mode 100644 (file)
index d99d99c..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-<?php
-
-namespace Friendica\Core\Console;
-
-use Friendica\Core\L10n;
-use Friendica\Model\Contact;
-
-/**
- * @brief tool to block an account from the node
- *
- * With this tool, you can block an account in such a way, that no postings
- * or comments this account writes are accepted to the node.
- *
- * License: AGPLv3 or later, same as Friendica
- *
- * @author Tobias Diekershoff <tobias.diekershoff@gmx.net>
- * @author Hypolite Petovan <hypolite@mrpetovan.com>
- */
-class GlobalCommunityBlock extends \Asika\SimpleConsole\Console
-{
-       protected $helpOptions = ['h', 'help', '?'];
-
-       protected function getHelp()
-       {
-               $help = <<<HELP
-console globalcommunityblock - Block remote profile from interacting with this node
-Usage
-       bin/console globalcommunityblock <profile_url> [-h|--help|-?] [-v]
-
-Description
-       Blocks an account in such a way that no postings or comments this account writes are accepted to this node.
-
-Options
-    -h|--help|-? Show help information
-    -v           Show more debug information.
-HELP;
-               return $help;
-       }
-
-       protected function doExecute()
-       {
-               $a = \get_app();
-
-               if ($this->getOption('v')) {
-                       $this->out('Class: ' . __CLASS__);
-                       $this->out('Arguments: ' . var_export($this->args, true));
-                       $this->out('Options: ' . var_export($this->options, true));
-               }
-
-               if (count($this->args) == 0) {
-                       $this->out($this->getHelp());
-                       return 0;
-               }
-
-               if (count($this->args) > 1) {
-                       throw new \Asika\SimpleConsole\CommandArgsException('Too many arguments');
-               }
-
-               if ($a->getMode()->isInstall()) {
-                       throw new \RuntimeException('Database isn\'t ready or populated yet');
-               }
-
-               $contact_id = Contact::getIdForURL($this->getArgument(0));
-               if (!$contact_id) {
-                       throw new \RuntimeException(L10n::t('Could not find any contact entry for this URL (%s)', $this->getArgument(0)));
-               }
-               if(Contact::block($contact_id)) {
-                       $this->out(L10n::t('The contact has been blocked from the node'));
-               } else {
-                       throw new \RuntimeException('The contact block failed.');
-               }
-
-               return 0;
-       }
-}
diff --git a/src/Core/Console/GlobalCommunitySilence.php b/src/Core/Console/GlobalCommunitySilence.php
deleted file mode 100644 (file)
index b028124..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-<?php
-
-namespace Friendica\Core\Console;
-
-use Friendica\Core\Protocol;
-use Friendica\Database\DBA;
-use Friendica\Network\Probe;
-use Friendica\Util\Strings;
-use RuntimeException;
-
-/**
- * @brief tool to silence accounts on the global community page
- *
- * With this tool, you can silence an account on the global community page.
- * Postings from silenced accounts will not be displayed on the community
- * page. This silencing does only affect the display on the community page,
- * accounts following the silenced accounts will still get their postings.
- *
- * License: AGPLv3 or later, same as Friendica
- *
- * @author Tobias Diekershoff <tobias.diekershoff@gmx.net>
- * @author Hypolite Petovan <hypolite@mrpetovan.com>
- */
-class GlobalCommunitySilence extends \Asika\SimpleConsole\Console
-{
-       protected $helpOptions = ['h', 'help', '?'];
-
-       protected function getHelp()
-       {
-               $help = <<<HELP
-console globalcommunitysilence - Silence remote profile from global community page
-Usage
-       bin/console globalcommunitysilence <profile_url> [-h|--help|-?] [-v]
-
-Description
-       With this tool, you can silence an account on the global community page.
-       Postings from silenced accounts will not be displayed on the community page.
-       This silencing does only affect the display on the community page, accounts
-       following the silenced accounts will still get their postings.
-
-Options
-    -h|--help|-? Show help information
-    -v           Show more debug information.
-HELP;
-               return $help;
-       }
-
-       protected function doExecute()
-       {
-               $a = \get_app();
-
-               if ($this->getOption('v')) {
-                       $this->out('Class: ' . __CLASS__);
-                       $this->out('Arguments: ' . var_export($this->args, true));
-                       $this->out('Options: ' . var_export($this->options, true));
-               }
-
-               if (count($this->args) == 0) {
-                       $this->out($this->getHelp());
-                       return 0;
-               }
-
-               if (count($this->args) > 1) {
-                       throw new \Asika\SimpleConsole\CommandArgsException('Too many arguments');
-               }
-
-               if ($a->getMode()->isInstall()) {
-                       throw new RuntimeException('Database isn\'t ready or populated yet');
-               }
-
-               /**
-                * 1. make nurl from last parameter
-                * 2. check DB (contact) if there is a contact with uid=0 and that nurl, get the ID
-                * 3. set the flag hidden=1 for the contact entry with the found ID
-                * */
-               $net = Probe::uri($this->getArgument(0));
-               if (in_array($net['network'], [Protocol::PHANTOM, Protocol::MAIL])) {
-                       throw new RuntimeException('This account seems not to exist.');
-               }
-
-               $nurl = Strings::normaliseLink($net['url']);
-               $contact = DBA::selectFirst("contact", ["id"], ["nurl" => $nurl, "uid" => 0]);
-               if (DBA::isResult($contact)) {
-                       DBA::update("contact", ["hidden" => true], ["id" => $contact["id"]]);
-                       $this->out('NOTICE: The account should be silenced from the global community page');
-               } else {
-                       throw new RuntimeException('NOTICE: Could not find any entry for this URL (' . $nurl . ')');
-               }
-
-               return 0;
-       }
-}
diff --git a/src/Core/Console/Maintenance.php b/src/Core/Console/Maintenance.php
deleted file mode 100644 (file)
index 0cb0da9..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-<?php
-
-namespace Friendica\Core\Console;
-
-use Friendica\Core;
-
-/**
- * @brief Sets maintenance mode for this node
- *
- * @author Hypolite Petovan <hypolite@mrpetovan.com>
- */
-class Maintenance extends \Asika\SimpleConsole\Console
-{
-       protected $helpOptions = ['h', 'help', '?'];
-
-       protected function getHelp()
-       {
-               $help = <<<HELP
-console maintenance - Sets maintenance mode for this node
-Usage
-       bin/console maintenance <enable> [<reason>] [-h|--help|-?] [-v]
-
-Description
-       <enable> cen be either 0 or 1 to disabled or enable the maintenance mode on this node.
-
-       <reason> is a quote-enclosed string with the optional reason for the maintenance mode.
-
-Examples
-       bin/console maintenance 1
-               Enables the maintenance mode without setting a reason message
-
-       bin/console maintenance 1 "SSL certification update"
-               Enables the maintenance mode with setting a reason message
-
-       bin/console maintenance 0
-               Disables the maintenance mode
-
-Options
-    -h|--help|-? Show help information
-    -v           Show more debug information.
-HELP;
-               return $help;
-       }
-
-       protected function doExecute()
-       {
-               $a = \Friendica\BaseObject::getApp();
-
-               if ($this->getOption('v')) {
-                       $this->out('Class: ' . __CLASS__);
-                       $this->out('Arguments: ' . var_export($this->args, true));
-                       $this->out('Options: ' . var_export($this->options, true));
-               }
-
-               if (count($this->args) == 0) {
-                       $this->out($this->getHelp());
-                       return 0;
-               }
-
-               if (count($this->args) > 2) {
-                       throw new \Asika\SimpleConsole\CommandArgsException('Too many arguments');
-               }
-
-               if ($a->getMode()->isInstall()) {
-                       throw new \RuntimeException('Database isn\'t ready or populated yet');
-               }
-
-               $enabled = intval($this->getArgument(0));
-
-               Core\Config::set('system', 'maintenance', $enabled);
-
-               $reason = $this->getArgument(1);
-
-               if ($enabled && $this->getArgument(1)) {
-                       Core\Config::set('system', 'maintenance_reason', $this->getArgument(1));
-               } else {
-                       Core\Config::set('system', 'maintenance_reason', '');
-               }
-
-               if ($enabled) {
-                       $mode_str = "maintenance mode";
-               } else {
-                       $mode_str = "normal mode";
-               }
-
-               $this->out('System set in ' . $mode_str);
-
-               if ($enabled && $reason != '') {
-                       $this->out('Maintenance reason: ' . $reason);
-               }
-
-               return 0;
-       }
-
-}
diff --git a/src/Core/Console/NewPassword.php b/src/Core/Console/NewPassword.php
deleted file mode 100644 (file)
index 3cd96ad..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-<?php
-
-namespace Friendica\Core\Console;
-
-use Friendica\Core\L10n;
-use Friendica\Database\DBA;
-use Friendica\Model\User;
-use RuntimeException;
-
-/**
- * @brief tool to set a new password for a user
- *
- * With this tool, you can set a new password for a user
- *
- * License: AGPLv3 or later, same as Friendica
- *
- * @author Michael Vogel <heluecht@pirati.ca>
- */
-class NewPassword extends \Asika\SimpleConsole\Console
-{
-       protected $helpOptions = ['h', 'help', '?'];
-
-       protected function getHelp()
-       {
-               $help = <<<HELP
-console newpassword - Creates a new password for a given user
-Usage
-       bin/console newpassword <nickname> [<password>] [-h|--help|-?] [-v]
-
-Description
-       Creates a new password for a user without using the "forgot password" functionality.
-
-Options
-    -h|--help|-? Show help information
-    -v           Show more debug information.
-HELP;
-               return $help;
-       }
-
-       protected function doExecute()
-       {
-               $a = \get_app();
-
-               if ($this->getOption('v')) {
-                       $this->out('Class: ' . __CLASS__);
-                       $this->out('Arguments: ' . var_export($this->args, true));
-                       $this->out('Options: ' . var_export($this->options, true));
-               }
-
-               if (count($this->args) == 0) {
-                       $this->out($this->getHelp());
-                       return 0;
-               }
-
-               if (count($this->args) > 2) {
-                       throw new \Asika\SimpleConsole\CommandArgsException('Too many arguments');
-               }
-
-               if ($a->getMode()->isInstall()) {
-                       throw new RuntimeException('Database isn\'t ready or populated yet');
-               }
-
-               $nick = $this->getArgument(0);
-
-               $user = DBA::selectFirst('user', ['uid'], ['nickname' => $nick]);
-               if (!DBA::isResult($user)) {
-                       throw new RuntimeException(L10n::t('User not found'));
-               }
-
-               $password = $this->getArgument(1);
-               if (is_null($password)) {
-                       $this->out(L10n::t('Enter new password: '), false);
-                       $password = \Seld\CliPrompt\CliPrompt::hiddenPrompt(true);
-               }
-
-               try {
-                       $result = User::updatePassword($user['uid'], $password);
-
-                       if (!DBA::isResult($result)) {
-                               throw new \Exception(L10n::t('Password update failed. Please try again.'));
-                       }
-
-                       $this->out(L10n::t('Password changed.'));
-               } catch (\Exception $e) {
-                       throw new RuntimeException($e->getMessage(), $e->getCode(), $e);
-               }
-
-               return 0;
-       }
-}
diff --git a/src/Core/Console/PhpToPo.php b/src/Core/Console/PhpToPo.php
deleted file mode 100644 (file)
index 93d8274..0000000
+++ /dev/null
@@ -1,237 +0,0 @@
-<?php
-
-namespace Friendica\Core\Console;
-
-/**
- * Read a strings.php file and create messages.po in the same directory
- *
- * @author Hypolite Petovan <hypolite@mrpetovan.com>
- */
-class PhpToPo extends \Asika\SimpleConsole\Console
-{
-
-       protected $helpOptions = ['h', 'help', '?'];
-
-       private $normBaseMsgIds = [];
-       const NORM_REGEXP = "|[\\\]|";
-
-       protected function getHelp()
-       {
-               $help = <<<HELP
-console php2po - Generate a messages.po file from a strings.php file
-Usage
-       bin/console php2po [-p <n>] [--base <file>] <path/to/strings.php> [-h|--help|-?] [-v]
-
-Description
-       Read a strings.php file and create the according messages.po in the same directory
-
-Options
-       -p <n>        Number of plural forms. Default: 2
-       --base <file> Path to base messages.po file. Default: view/lang/C/messages.po
-       -h|--help|-?  Show help information
-       -v            Show more debug information.
-HELP;
-               return $help;
-       }
-
-       protected function doExecute()
-       {
-               if ($this->getOption('v')) {
-                       $this->out('Class: ' . __CLASS__);
-                       $this->out('Arguments: ' . var_export($this->args, true));
-                       $this->out('Options: ' . var_export($this->options, true));
-               }
-
-               if (count($this->args) == 0) {
-                       $this->out($this->getHelp());
-                       return 0;
-               }
-
-               if (count($this->args) > 1) {
-                       throw new \Asika\SimpleConsole\CommandArgsException('Too many arguments');
-               }
-
-               $a = \get_app();
-
-               $phpfile = realpath($this->getArgument(0));
-
-               if (!file_exists($phpfile)) {
-                       throw new \RuntimeException('Supplied file path doesn\'t exist.');
-               }
-
-               if (!is_writable(dirname($phpfile))) {
-                       throw new \RuntimeException('Supplied directory isn\'t writable.');
-               }
-
-               $pofile = dirname($phpfile) . DIRECTORY_SEPARATOR . 'messages.po';
-
-               // start !
-               include_once($phpfile);
-
-               $out = '';
-               $out .= "# FRIENDICA Distributed Social Network\n";
-               $out .= "# Copyright (C) 2010, 2011, 2012, 2013 the Friendica Project\n";
-               $out .= "# This file is distributed under the same license as the Friendica package.\n";
-               $out .= "# \n";
-               $out .= 'msgid ""' . "\n";
-               $out .= 'msgstr ""' . "\n";
-               $out .= '"Project-Id-Version: friendica\n"' . "\n";
-               $out .= '"Report-Msgid-Bugs-To: \n"' . "\n";
-               $out .= '"POT-Creation-Date: ' . date("Y-m-d H:i:sO") . '\n"' . "\n";
-               $out .= '"MIME-Version: 1.0\n"' . "\n";
-               $out .= '"Content-Type: text/plain; charset=UTF-8\n"' . "\n";
-               $out .= '"Content-Transfer-Encoding: 8bit\n"' . "\n";
-
-               // search for plural info
-               $lang = "";
-               $lang_logic = "";
-               $lang_pnum = $this->getOption('p', 2);
-
-               $infile = file($phpfile);
-               foreach ($infile as $l) {
-                       $l = trim($l);
-                       if ($this->startsWith($l, 'function string_plural_select_')) {
-                               $lang = str_replace('function string_plural_select_', '', str_replace('($n){', '', $l));
-                       }
-                       if ($this->startsWith($l, 'return')) {
-                               $lang_logic = str_replace('$', '', trim(str_replace('return ', '', $l), ';'));
-                               break;
-                       }
-               }
-
-               $this->out('Language: ' . $lang);
-               $this->out('Plural forms: ' . $lang_pnum);
-               $this->out('Plural forms: ' . $lang_logic);
-
-               $out .= sprintf('"Language: %s\n"', $lang) . "\n";
-               $out .= sprintf('"Plural-Forms: nplurals=%s; plural=%s;\n"', $lang_pnum, $lang_logic) . "\n";
-               $out .= "\n";
-
-               $base_path = $this->getOption('base', 'view/lang/C/messages.po');
-
-               // load base messages.po and extract msgids
-               $base_msgids = [];
-               $base_f = file($base_path);
-               if (!$base_f) {
-                       throw new \RuntimeException('The base ' . $base_path . ' file is missing or unavailable to read.');
-               }
-
-               $this->out('Loading base file ' . $base_path . '...');
-
-               $_f = 0;
-               $_mid = "";
-               $_mids = [];
-               foreach ($base_f as $l) {
-                       $l = trim($l);
-
-                       if ($this->startsWith($l, 'msgstr')) {
-                               if ($_mid != '""') {
-                                       $base_msgids[$_mid] = $_mids;
-                                       $this->normBaseMsgIds[preg_replace(self::NORM_REGEXP, "", $_mid)] = $_mid;
-                               }
-
-                               $_f = 0;
-                               $_mid = "";
-                               $_mids = [];
-                       }
-
-                       if ($this->startsWith($l, '"') && $_f == 2) {
-                               $_mids[count($_mids) - 1] .= "\n" . $l;
-                       }
-                       if ($this->startsWith($l, 'msgid_plural ')) {
-                               $_f = 2;
-                               $_mids[] = str_replace('msgid_plural ', '', $l);
-                       }
-
-                       if ($this->startsWith($l, '"') && $_f == 1) {
-                               $_mid .= "\n" . $l;
-                               $_mids[count($_mids) - 1] .= "\n" . $l;
-                       }
-                       if ($this->startsWith($l, 'msgid ')) {
-                               $_f = 1;
-                               $_mid = str_replace('msgid ', '', $l);
-                               $_mids = [$_mid];
-                       }
-               }
-
-               $this->out('Creating ' . $pofile . '...');
-
-               // create msgid and msgstr
-               $warnings = "";
-               foreach ($a->strings as $key => $str) {
-                       $msgid = $this->massageString($key);
-
-                       if (preg_match("|%[sd0-9](\$[sn])*|", $msgid)) {
-                               $out .= "#, php-format\n";
-                       }
-                       $msgid = $this->findOriginalMsgId($msgid);
-                       $out .= 'msgid ' . $msgid . "\n";
-
-                       if (is_array($str)) {
-                               if (array_key_exists($msgid, $base_msgids) && isset($base_msgids[$msgid][1])) {
-                                       $out .= 'msgid_plural ' . $base_msgids[$msgid][1] . "\n";
-                               } else {
-                                       $out .= 'msgid_plural ' . $msgid . "\n";
-                                       $warnings .= "[W] No source plural form for msgid:\n" . str_replace("\n", "\n\t", $msgid) . "\n\n";
-                               }
-                               foreach ($str as $n => $msgstr) {
-                                       $out .= 'msgstr[' . $n . '] ' . $this->massageString($msgstr) . "\n";
-                               }
-                       } else {
-                               $out .= 'msgstr ' . $this->massageString($str) . "\n";
-                       }
-
-                       $out .= "\n";
-               }
-
-               if (!file_put_contents($pofile, $out)) {
-                       throw new \RuntimeException('Unable to write to ' . $pofile);
-               }
-
-               if ($warnings != '') {
-                       $this->out($warnings);
-               }
-
-               return 0;
-       }
-
-       private function startsWith($haystack, $needle)
-       {
-               // search backwards starting from haystack length characters from the end
-               return $needle === "" || strrpos($haystack, $needle, -strlen($haystack)) !== FALSE;
-       }
-
-       /**
-        * Get a string and retun a message.po ready text
-        * - replace " with \"
-        * - replace tab char with \t
-        * - manage multiline strings
-        *
-        * @param string $str
-        * @return string
-        */
-       private function massageString($str)
-       {
-               $str = str_replace('\\', '\\\\', $str);
-               $str = str_replace('"', '\"', $str);
-               $str = str_replace("\t", '\t', $str);
-               $str = str_replace("\n", '\n"' . "\n" . '"', $str);
-               if (strpos($str, "\n") !== false && $str[0] !== '"') {
-                       $str = '"' . "\n" . $str;
-               }
-
-               $str = preg_replace("|\n([^\"])|", "\n\"$1", $str);
-               return sprintf('"%s"', $str);
-       }
-
-       private function findOriginalMsgId($str)
-       {
-               $norm_str = preg_replace(self::NORM_REGEXP, "", $str);
-               if (array_key_exists($norm_str, $this->normBaseMsgIds)) {
-                       return $this->normBaseMsgIds[$norm_str];
-               }
-
-               return $str;
-       }
-
-}
diff --git a/src/Core/Console/PoToPhp.php b/src/Core/Console/PoToPhp.php
deleted file mode 100644 (file)
index d539eae..0000000
+++ /dev/null
@@ -1,198 +0,0 @@
-<?php
-
-namespace Friendica\Core\Console;
-
-/**
- * Read a messages.po file and create strings.php in the same directory
- *
- * @author Hypolite Petovan <hypolite@mrpetovan.com>
- */
-class PoToPhp extends \Asika\SimpleConsole\Console
-{
-       protected $helpOptions = ['h', 'help', '?'];
-
-       const DQ_ESCAPE = "__DQ__";
-
-       protected function getHelp()
-       {
-               $help = <<<HELP
-console php2po - Generate a strings.php file from a messages.po file
-Usage
-       bin/console php2po <path/to/messages.po> [-h|--help|-?] [-v]
-
-Description
-       Read a messages.po file and create the according strings.php in the same directory
-
-Options
-       -h|--help|-?  Show help information
-       -v            Show more debug information.
-HELP;
-               return $help;
-       }
-
-       protected function doExecute()
-       {
-               if ($this->getOption('v')) {
-                       $this->out('Class: ' . __CLASS__);
-                       $this->out('Arguments: ' . var_export($this->args, true));
-                       $this->out('Options: ' . var_export($this->options, true));
-               }
-
-               if (count($this->args) == 0) {
-                       $this->out($this->getHelp());
-                       return 0;
-               }
-
-               if (count($this->args) > 1) {
-                       throw new \Asika\SimpleConsole\CommandArgsException('Too many arguments');
-               }
-
-               $pofile = realpath($this->getArgument(0));
-
-               if (!file_exists($pofile)) {
-                       throw new \RuntimeException('Supplied file path doesn\'t exist.');
-               }
-
-               if (!is_writable(dirname($pofile))) {
-                       throw new \RuntimeException('Supplied directory isn\'t writable.');
-               }
-
-               $outfile = dirname($pofile) . DIRECTORY_SEPARATOR . 'strings.php';
-
-               if (basename(dirname($pofile)) == 'C') {
-                       $lang = 'en';
-               } else {
-                       $lang = str_replace('-', '_', basename(dirname($pofile)));
-               }
-
-               $this->out('Out to ' . $outfile);
-
-               $out = "<?php\n\n";
-
-               $infile = file($pofile);
-               $k = '';
-               $v = '';
-               $arr = false;
-               $ink = false;
-               $inv = false;
-               $escape_s_exp = '|[^\\\\]\$[a-z]|';
-
-               foreach ($infile as $l) {
-                       $l = str_replace('\"', self::DQ_ESCAPE, $l);
-                       $len = strlen($l);
-                       if ($l[0] == "#") {
-                               $l = "";
-                       }
-
-                       if (substr($l, 0, 15) == '"Plural-Forms: ') {
-                               $match = [];
-                               preg_match("|nplurals=([0-9]*); *plural=(.*)[;\\\\]|", $l, $match);
-                               $cond = str_replace('n', '$n', $match[2]);
-                               // define plural select function if not already defined
-                               $fnname = 'string_plural_select_' . $lang;
-                               $out .= 'if(! function_exists("' . $fnname . '")) {' . "\n";
-                               $out .= 'function ' . $fnname . '($n){' . "\n";
-                               $out .= '       $n = intval($n);' . "\n";
-                               $out .= '       return ' . $cond . ';' . "\n";
-                               $out .= '}}' . "\n";
-                       }
-
-                       if ($k != '' && substr($l, 0, 7) == 'msgstr ') {
-                               if ($ink) {
-                                       $ink = false;
-                                       $out .= '$a->strings["' . $k . '"] = ';
-                               }
-
-                               if ($inv) {
-                                       $out .= '"' . $v . '"';
-                               }
-
-                               $v = substr($l, 8, $len - 10);
-                               $v = preg_replace_callback($escape_s_exp, [$this, 'escapeDollar'], $v);
-
-                               $inv = true;
-                       }
-
-                       if ($k != "" && substr($l, 0, 7) == 'msgstr[') {
-                               if ($ink) {
-                                       $ink = false;
-                                       $out .= '$a->strings["' . $k . '"] = ';
-                               }
-                               if ($inv) {
-                                       $inv = false;
-                                       $out .= '"' . $v . '"';
-                               }
-
-                               if (!$arr) {
-                                       $arr = true;
-                                       $out .= "[\n";
-                               }
-
-                               $match = [];
-                               preg_match("|\[([0-9]*)\] (.*)|", $l, $match);
-                               $out .= "\t"
-                                       . preg_replace_callback($escape_s_exp, [$this, 'escapeDollar'], $match[1])
-                                       . ' => '
-                                       . preg_replace_callback($escape_s_exp, [$this, 'escapeDollar'], $match[2])
-                                       . ",\n";
-                       }
-
-                       if (substr($l, 0, 6) == 'msgid_') {
-                               $ink = false;
-                               $out .= '$a->strings["' . $k . '"] = ';
-                       }
-
-                       if ($ink) {
-                               $k .= trim($l, "\"\r\n");
-                               $k = preg_replace_callback($escape_s_exp, [$this, 'escapeDollar'], $k);
-                       }
-
-                       if (substr($l, 0, 6) == 'msgid ') {
-                               if ($inv) {
-                                       $inv = false;
-                                       $out .= '"' . $v . '"';
-                               }
-
-                               if ($k != "") {
-                                       $out .= ($arr) ? "];\n" : ";\n";
-                               }
-
-                               $arr = false;
-                               $k = str_replace("msgid ", "", $l);
-                               if ($k != '""') {
-                                       $k = trim($k, "\"\r\n");
-                               } else {
-                                       $k = '';
-                               }
-
-                               $k = preg_replace_callback($escape_s_exp, [$this, 'escapeDollar'], $k);
-                               $ink = true;
-                       }
-
-                       if ($inv && substr($l, 0, 6) != "msgstr") {
-                               $v .= trim($l, "\"\r\n");
-                               $v = preg_replace_callback($escape_s_exp, [$this, 'escapeDollar'], $v);
-                       }
-               }
-
-               if ($inv) {
-                       $out .= '"' . $v . '"';
-               }
-
-               if ($k != '') {
-                       $out .= ($arr ? "];\n" : ";\n");
-               }
-
-               $out = str_replace(self::DQ_ESCAPE, '\"', $out);
-               if (!file_put_contents($outfile, $out)) {
-                       throw new \RuntimeException('Unable to write to ' . $outfile);
-               }
-
-               return 0;
-       }
-
-       private function escapeDollar($match)
-       {
-               return str_replace('$', '\$', $match[0]);
-       }
-}
diff --git a/src/Core/Console/PostUpdate.php b/src/Core/Console/PostUpdate.php
deleted file mode 100644 (file)
index a903cd7..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-<?php
-
-namespace Friendica\Core\Console;
-
-use Friendica\Core\Config;
-use Friendica\Core\L10n;
-use Friendica\Core\Update;
-
-/**
- * Performs database post updates
- *
- * License: AGPLv3 or later, same as Friendica
- *
- * @author Tobias Diekershoff <tobias.diekershoff@gmx.net>
- * @author Hypolite Petovan <hypolite@mrpetovan.com>
- */
-class PostUpdate extends \Asika\SimpleConsole\Console
-{
-        protected $helpOptions = ['h', 'help', '?'];
-
-        protected function getHelp()
-        {
-                $help = <<<HELP
-console postupdate - Performs database post updates
-Usage
-        bin/console postupdate [-h|--help|-?] [--reset <version>]
-
-Options
-    -h|--help|-?      Show help information
-    --reset <version> Reset the post update version
-HELP;
-                return $help;
-        }
-
-       protected function doExecute()
-       {
-               $a = \Friendica\BaseObject::getApp();
-
-               if ($this->getOption($this->helpOptions)) {
-                       $this->out($this->getHelp());
-                       return 0;
-               }
-
-               $reset_version = $this->getOption('reset');
-               if (is_bool($reset_version)) {
-                       $this->out($this->getHelp());
-                       return 0;
-               } elseif ($reset_version) {
-                       Config::set('system', 'post_update_version', $reset_version);
-                       echo L10n::t('Post update version number has been set to %s.', $reset_version) . "\n";
-                       return 0;
-               }
-
-               if ($a->getMode()->isInstall()) {
-                       throw new \RuntimeException('Database isn\'t ready or populated yet');
-               }
-
-               echo L10n::t('Check for pending update actions.') . "\n";
-               Update::run($a->getBasePath(), true, false, true, false);
-               echo L10n::t('Done.') . "\n";
-
-               echo L10n::t('Execute pending post updates.') . "\n";
-
-               while (!\Friendica\Database\PostUpdate::update()) {
-                       echo '.';
-               }
-
-               echo "\n" . L10n::t('All pending post updates are done.') . "\n";
-
-               return 0;
-       }
-}
diff --git a/src/Core/Console/ServerBlock.php b/src/Core/Console/ServerBlock.php
deleted file mode 100644 (file)
index 94c97e1..0000000
+++ /dev/null
@@ -1,171 +0,0 @@
-<?php
-
-namespace Friendica\Core\Console;
-
-use Asika\SimpleConsole\CommandArgsException;
-use Asika\SimpleConsole\Console;
-use Console_Table;
-use Friendica\BaseObject;
-use Friendica\Core\Config\Configuration;
-
-/**
- * @brief Manage blocked servers
- *
- * With this tool, you can list the current blocked servers
- * or you can add / remove a blocked server from the list
- */
-class ServerBlock extends Console
-{
-       const DEFAULT_REASON = 'blocked';
-
-       protected $helpOptions = ['h', 'help', '?'];
-
-       protected function getHelp()
-       {
-               $help = <<<HELP
-console serverblock - Manage blocked servers
-Usage
-       bin/console serverblock [-h|--help|-?] [-v]
-       bin/console serverblock add <server> <reason> [-h|--help|-?] [-v]
-       bin/console serverblock remove <server> [-h|--help|-?] [-v]
-
-Description
-       With this tool, you can list the current blocked servers
-    or you can add / remove a blocked server from the list
-
-Options
-    -h|--help|-? Show help information
-    -v           Show more debug information.
-HELP;
-               return $help;
-       }
-
-       protected function doExecute()
-       {
-               $a = BaseObject::getApp();
-
-               if (count($this->args) == 0) {
-                       $this->printBlockedServers($a->getConfig());
-                       return 0;
-               }
-
-               switch ($this->getArgument(0)) {
-                       case 'add':
-                               return $this->addBlockedServer($a->getConfig());
-                       case 'remove':
-                               return $this->removeBlockedServer($a->getConfig());
-                       default:
-                               throw new CommandArgsException('Unknown command.');
-                               break;
-               }
-       }
-
-       /**
-        * Prints the whole list of blocked domains including the reason
-        *
-        * @param Configuration $config
-        */
-       private function printBlockedServers(Configuration $config)
-       {
-               $table = new Console_Table();
-               $table->setHeaders(['Domain', 'Reason']);
-               $blocklist = $config->get('system', 'blocklist');
-               foreach ($blocklist as $domain) {
-                       $table->addRow($domain);
-               }
-               $this->out($table->getTable());
-       }
-
-       /**
-        * Adds a server to the blocked list
-        *
-        * @param Configuration $config
-        *
-        * @return int The return code (0 = success, 1 = failed)
-        */
-       private function addBlockedServer(Configuration $config)
-       {
-               if (count($this->args) < 2 || count($this->args) > 3) {
-                       throw new CommandArgsException('Add needs a domain and optional a reason.');
-               }
-
-               $domain = $this->getArgument(1);
-               $reason = (count($this->args) === 3) ? $this->getArgument(2) : self::DEFAULT_REASON;
-
-               $update = false;
-
-               $currBlocklist = $config->get('system', 'blocklist');
-               $newBlockList = [];
-               foreach ($currBlocklist  as $blocked) {
-                       if ($blocked['domain'] === $domain) {
-                               $update = true;
-                               $newBlockList[] = [
-                                       'domain' => $domain,
-                                       'reason' => $reason,
-                               ];
-                       } else {
-                               $newBlockList[] = $blocked;
-                       }
-               }
-
-               if (!$update) {
-                       $newBlockList[] = [
-                               'domain' => $domain,
-                               'reason' => $reason,
-                       ];
-               }
-
-               if ($config->set('system', 'blocklist', $newBlockList)) {
-                       if ($update) {
-                               $this->out(sprintf("The domain '%s' is now updated. (Reason: '%s')", $domain, $reason));
-                       } else {
-                               $this->out(sprintf("The domain '%s' is now blocked. (Reason: '%s')", $domain, $reason));
-                       }
-                       return 0;
-               } else {
-                       $this->out(sprintf("Couldn't save '%s' as blocked server", $domain));
-                       return 1;
-               }
-       }
-
-       /**
-        * Removes a server from the blocked list
-        *
-        * @param Configuration $config
-        *
-        * @return int The return code (0 = success, 1 = failed)
-        */
-       private function removeBlockedServer(Configuration $config)
-       {
-               if (count($this->args) !== 2) {
-                       throw new CommandArgsException('Remove needs a second parameter.');
-               }
-
-               $domain = $this->getArgument(1);
-
-               $found = false;
-
-               $currBlocklist = $config->get('system', 'blocklist');
-               $newBlockList = [];
-               foreach ($currBlocklist as $blocked) {
-                       if ($blocked['domain'] === $domain) {
-                               $found = true;
-                       } else {
-                               $newBlockList[] = $blocked;
-                       }
-               }
-
-               if (!$found) {
-                       $this->out(sprintf("The domain '%s' is not blocked.", $domain));
-                       return 1;
-               }
-
-               if ($config->set('system', 'blocklist', $newBlockList)) {
-                       $this->out(sprintf("The domain '%s' is not more blocked", $domain));
-                       return 0;
-               } else {
-                       $this->out(sprintf("Couldn't remove '%s' from blocked servers", $domain));
-                       return 1;
-               }
-       }
-}
diff --git a/src/Core/Console/Storage.php b/src/Core/Console/Storage.php
deleted file mode 100644 (file)
index 805ef0a..0000000
+++ /dev/null
@@ -1,147 +0,0 @@
-<?php
-
-namespace Friendica\Core\Console;
-
-use Asika\SimpleConsole\CommandArgsException;
-use Friendica\Core\StorageManager;
-
-/**
- * @brief tool to manage storage backend and stored data from CLI
- *
- */
-class Storage extends \Asika\SimpleConsole\Console
-{
-       protected $helpOptions = ['h', 'help', '?'];
-
-       protected function getHelp()
-       {
-               $help = <<<HELP
-console storage - manage storage backend and stored data
-Synopsis
-    bin/console storage [-h|--help|-?] [-v]
-        Show this help
-    
-    bin/console storage list
-        List available storage backends
-    
-    bin/console storage set <name>
-        Set current storage backend
-            name        storage backend to use. see "list".
-    
-    bin/console storage move [table] [-n 5000]
-        Move stored data to current storage backend.
-            table       one of "photo" or "attach". default to both
-            -n          limit of processed entry batch size
-HELP;
-               return $help;
-       }
-
-       protected function doExecute()
-       {
-               if ($this->getOption('v')) {
-                       $this->out('Executable: ' . $this->executable);
-                       $this->out('Class: ' . __CLASS__);
-                       $this->out('Arguments: ' . var_export($this->args, true));
-                       $this->out('Options: ' . var_export($this->options, true));
-               }
-
-               if (count($this->args) == 0) {
-                       $this->out($this->getHelp());
-                       return -1;
-               }
-
-               switch ($this->args[0]) {
-                       case 'list':
-                               return $this->doList();
-                               break;
-                       case 'set':
-                               return $this->doSet();
-                               break;
-                       case 'move':
-                               return $this->doMove();
-                               break;
-               }
-
-               $this->out(sprintf('Invalid action "%s"', $this->args[0]));
-               return -1;
-       }
-
-       protected function doList()
-       {
-               $rowfmt = ' %-3s | %-20s';
-               $current = StorageManager::getBackend();
-               $this->out(sprintf($rowfmt, 'Sel', 'Name'));
-               $this->out('-----------------------');
-               $isregisterd = false;
-               foreach (StorageManager::listBackends() as $name => $class) {
-                       $issel = ' ';
-                       if ($current === $class) {
-                               $issel = '*';
-                               $isregisterd = true;
-                       };
-                       $this->out(sprintf($rowfmt, $issel, $name));
-               }
-
-               if ($current === '') {
-                       $this->out();
-                       $this->out('This system is using legacy storage system');
-               }
-               if ($current !== '' && !$isregisterd) {
-                       $this->out();
-                       $this->out('The current storage class (' . $current . ') is not registered!');
-               }
-               return 0;
-       }
-
-       protected function doSet()
-       {
-               if (count($this->args) !== 2) {
-                       throw new CommandArgsException('Invalid arguments');
-               }
-
-               $name = $this->args[1];
-               $class = StorageManager::getByName($name);
-
-               if ($class === '') {
-                       $this->out($name . ' is not a registered backend.');
-                       return -1;
-               }
-
-               if (!StorageManager::setBackend($class)) {
-                       $this->out($class . ' is not a valid backend storage class.');
-                       return -1;
-               }
-
-               return 0;
-       }
-
-       protected function doMove()
-       {
-               $tables = null;
-               if (count($this->args) < 1 || count($this->args) > 2) {
-                       throw new CommandArgsException('Invalid arguments');
-               }
-
-               if (count($this->args) == 2) {
-                       $table = strtolower($this->args[1]);
-                       if (!in_array($table, ['photo', 'attach'])) {
-                               throw new CommandArgsException('Invalid table');
-                       }
-                       $tables = [$table];
-               }
-
-               $current = StorageManager::getBackend();
-               $total = 0;
-
-               do {
-                       $moved = StorageManager::move($current, $tables, $this->getOption('n', 5000));
-                       if ($moved) {
-                               $this->out(date('[Y-m-d H:i:s] ') . sprintf('Moved %d files', $moved));
-                       }
-
-                       $total += $moved;
-               } while ($moved);
-
-               $this->out(sprintf(date('[Y-m-d H:i:s] ') . 'Moved %d files total', $total));
-       }
-}
diff --git a/src/Core/Console/Typo.php b/src/Core/Console/Typo.php
deleted file mode 100644 (file)
index 8d07051..0000000
+++ /dev/null
@@ -1,117 +0,0 @@
-<?php
-
-namespace Friendica\Core\Console;
-
-use Friendica\BaseObject;
-
-/**
- * Tired of chasing typos and finding them after a commit.
- * Run this and quickly see if we've got any parse errors in our application files.
- *
- * @author Hypolite Petovan <hypolite@mrpetovan.com>
- */
-class Typo extends \Asika\SimpleConsole\Console
-{
-       protected $helpOptions = ['h', 'help', '?'];
-
-       protected function getHelp()
-       {
-               $help = <<<HELP
-console typo - Checks for parse errors in Friendica files
-Usage
-       bin/console typo [-h|--help|-?] [-v]
-
-Description
-       Checks all PHP files in the Friendica file tree for parse errors
-
-Options
-       -h|--help|-?  Show help information
-       -v            Show more debug information.
-HELP;
-               return $help;
-       }
-
-       protected function doExecute()
-       {
-               if ($this->getOption('v')) {
-                       $this->out('Class: ' . __CLASS__);
-                       $this->out('Arguments: ' . var_export($this->args, true));
-                       $this->out('Options: ' . var_export($this->options, true));
-               }
-
-               if (count($this->args) > 0) {
-                       throw new \Asika\SimpleConsole\CommandArgsException('Too many arguments');
-               }
-
-               $php_path = BaseObject::getApp()->getConfigCache()->get('config', 'php_path', 'php');
-
-               if ($this->getOption('v')) {
-                       $this->out('Directory: src');
-               }
-
-               $Iterator = new \RecursiveDirectoryIterator('src');
-
-               foreach (new \RecursiveIteratorIterator($Iterator) as $file) {
-                       if (substr($file, -4) === '.php') {
-                               $this->checkFile($php_path, $file);
-                       }
-               }
-
-               if ($this->getOption('v')) {
-                       $this->out('Directory: mod');
-               }
-
-               $files = glob('mod/*.php');
-               $this->checkFiles($php_path, $files);
-
-               if ($this->getOption('v')) {
-                       $this->out('Directory: include');
-               }
-
-               $files = glob('include/*.php');
-               $this->checkFiles($php_path, $files);
-
-               if ($this->getOption('v')) {
-                       $this->out('Directory: addon');
-               }
-
-               $dirs = glob('addon/*');
-               foreach ($dirs as $dir) {
-                       $addon = basename($dir);
-                       $files = glob($dir . '/' . $addon . '.php');
-                       $this->checkFiles($php_path, $files);
-               }
-
-               if ($this->getOption('v')) {
-                       $this->out('String files');
-               }
-
-               $files = glob('view/lang/*/strings.php');
-               $this->checkFiles($php_path, $files);
-
-               $this->out('No errors.');
-
-               return 0;
-       }
-
-       private function checkFiles($php_path, array $files)
-       {
-               foreach ($files as $file) {
-                       $this->checkFile($php_path, $file);
-               }
-       }
-
-       private function checkFile($php_path, $file)
-       {
-               if ($this->getOption('v')) {
-                       $this->out('Checking ' . $file);
-               }
-
-               $output = [];
-               $ret = 0;
-               exec("$php_path -l $file", $output, $ret);
-               if ($ret !== 0) {
-                       throw new \RuntimeException('Parse error found in ' . $file . ', scan stopped.');
-               }
-       }
-}
index beb91d11a0b1f3a74e21383c97a2413eaaa4d435..6e7860c8aae96d58541d59cbfc40e763cb9866cb 100644 (file)
@@ -237,6 +237,28 @@ class Contact extends BaseObject
                return ['public' => $pcid, 'user' => $ucid];
        }
 
+       /**
+        * Returns contact details for a given contact id in combination with a user id
+        *
+        * @param int $cid A contact ID
+        * @param int $uid The User ID
+        * @param array $fields The selected fields for the contact
+        *
+        * @return array The contact details
+        *
+        * @throws \Exception
+        */
+       public static function getContactForUser($cid, $uid, array $fields = [])
+       {
+               $contact = DBA::selectFirst('contact', $fields, ['id' => $cid, 'uid' => $uid]);
+
+               if (!DBA::isResult($contact)) {
+                       return [];
+               } else {
+                       return $contact;
+               }
+       }
+
        /**
         * @brief Block contact id for user id
         *
index d85ed414fbe6ccad83a3386de2081c0870dcb998..387014d4b93e55883b1c90e0a081d4bc961be060 100644 (file)
@@ -2508,62 +2508,6 @@ class Item extends BaseObject
                        }, $item["body"]);
        }
 
-       public static function getGuidById($id)
-       {
-               $item = self::selectFirst(['guid'], ['id' => $id]);
-               if (DBA::isResult($item)) {
-                       return $item['guid'];
-               } else {
-                       return '';
-               }
-       }
-
-       /**
-        * This function is only used for the old Friendica app on Android that doesn't like paths with guid
-        *
-        * @param string $guid item guid
-        * @param int    $uid  user id
-        * @return array with id and nick of the item with the given guid
-        * @throws \Exception
-        */
-       public static function getIdAndNickByGuid($guid, $uid = 0)
-       {
-               $nick = "";
-               $id = 0;
-
-               if ($uid == 0) {
-                       $uid = local_user();
-               }
-
-               // Does the given user have this item?
-               if ($uid) {
-                       $item = self::selectFirst(['id'], ['guid' => $guid, 'uid' => $uid]);
-                       if (DBA::isResult($item)) {
-                               $user = DBA::selectFirst('user', ['nickname'], ['uid' => $uid]);
-                               if (!DBA::isResult($user)) {
-                                       return;
-                               }
-                               $id = $item['id'];
-                               $nick = $user['nickname'];
-                       }
-               }
-
-               // Or is it anywhere on the server?
-               if ($nick == "") {
-                       $condition = ["`guid` = ? AND `uid` != 0", $guid];
-                       $item = self::selectFirst(['id', 'uid'], $condition);
-                       if (DBA::isResult($item)) {
-                               $user = DBA::selectFirst('user', ['nickname'], ['uid' => $item['uid']]);
-                               if (!DBA::isResult($user)) {
-                                       return;
-                               }
-                               $id = $item['id'];
-                               $nick = $user['nickname'];
-                       }
-               }
-               return ["nick" => $nick, "id" => $id];
-       }
-
        /**
         * look for mention tags and setup a second delivery chain for forum/community posts if appropriate
         *
index 7028934d193b484df3a0dd0302bd9d63c8afc58f..9d2600b3daab16156c825ff4f458cd352ad1bf6a 100644 (file)
@@ -1235,4 +1235,75 @@ class Profile
        {
                return preg_replace('/[\?&]' . $param . '=(.*?)(&|$)/ism', '$2', $s);
        }
+
+       /**
+        * search for Profiles
+        *
+        * @param int  $start
+        * @param int  $count
+        * @param null $search
+        *
+        * @return array [ 'total' => 123, 'entries' => [...] ];
+        *
+        * @throws \Exception
+        */
+       public static function searchProfiles($start = 0, $count = 100, $search = null)
+       {
+               if ($search) {
+                       $search = DBA::escape($search);
+
+                       $sql_extra = " AND ((`profile`.`name` LIKE '%$search%') OR
+                               (`user`.`nickname` LIKE '%$search%') OR
+                               (`profile`.`pdesc` LIKE '%$search%') OR
+                               (`profile`.`locality` LIKE '%$search%') OR
+                               (`profile`.`region` LIKE '%$search%') OR
+                               (`profile`.`country-name` LIKE '%$search%') OR
+                               (`profile`.`gender` LIKE '%$search%') OR
+                               (`profile`.`marital` LIKE '%$search%') OR
+                               (`profile`.`sexual` LIKE '%$search%') OR
+                               (`profile`.`about` LIKE '%$search%') OR
+                               (`profile`.`romance` LIKE '%$search%') OR
+                               (`profile`.`work` LIKE '%$search%') OR
+                               (`profile`.`education` LIKE '%$search%') OR
+                               (`profile`.`pub_keywords` LIKE '%$search%') OR
+                               (`profile`.`prv_keywords` LIKE '%$search%'))";
+               } else {
+                       $sql_extra = '';
+               }
+
+               $publish = (Config::get('system', 'publish_all') ? '' : " AND `publish` = 1 ");
+
+               $total = 0;
+               $cnt = DBA::fetchFirst("SELECT COUNT(*) AS `total` 
+                               FROM `profile`
+                               LEFT JOIN `user` ON `user`.`uid` = `profile`.`uid`
+                               WHERE `is-default` $publish AND NOT `user`.`blocked` AND NOT `user`.`account_removed` $sql_extra");
+               if (DBA::isResult($cnt)) {
+                       $total = $cnt['total'];
+               }
+
+               $order = " ORDER BY `name` ASC ";
+               $limit = $start . ',' . $count;
+
+               $profiles = DBA::p("SELECT `profile`.*, `profile`.`uid` AS `profile_uid`, `user`.`nickname`, `user`.`timezone` , `user`.`page-flags`,
+                       `contact`.`addr`, `contact`.`url` AS `profile_url`
+                       FROM `profile`
+                       LEFT JOIN `user` ON `user`.`uid` = `profile`.`uid`
+                       LEFT JOIN `contact` ON `contact`.`uid` = `user`.`uid`
+                       WHERE `is-default` $publish AND NOT `user`.`blocked` AND NOT `user`.`account_removed` AND `contact`.`self`
+                       $sql_extra $order LIMIT $limit"
+               );
+
+               if (DBA::isResult($profiles)) {
+                       return [
+                               'total'   => $total,
+                               'entries' => DBA::toArray($profiles),
+                       ];
+               } else {
+                       return [
+                               'total'   => $total,
+                               'entries' => [],
+                       ];
+               }
+       }
 }
diff --git a/src/Module/AllFriends.php b/src/Module/AllFriends.php
new file mode 100644 (file)
index 0000000..b0e6ea1
--- /dev/null
@@ -0,0 +1,107 @@
+<?php
+
+namespace Friendica\Module;
+
+use Friendica\BaseModule;
+use Friendica\Content\ContactSelector;
+use Friendica\Content\Pager;
+use Friendica\Core\L10n;
+use Friendica\Core\Renderer;
+use Friendica\Model;
+use Friendica\Network\HTTPException;
+use Friendica\Util\Proxy as ProxyUtils;
+
+/**
+ * This module shows all public friends of the selected contact
+ */
+class AllFriends extends BaseModule
+{
+       public static function content()
+       {
+               $app = self::getApp();
+
+               if (!local_user()) {
+                       throw new HTTPException\ForbiddenException();
+               }
+
+               $cid = 0;
+
+               // @TODO: Replace with parameter from router
+               if ($app->argc > 1) {
+                       $cid = intval($app->argv[1]);
+               }
+
+               if (!$cid) {
+                       throw new HTTPException\BadRequestException(L10n::t('Invalid contact.'));
+               }
+
+               $uid = $app->user['uid'];
+
+               $contact = Model\Contact::getContactForUser($cid, local_user(), ['name', 'url', 'photo', 'uid', 'id']);
+
+               if (empty($contact)) {
+                       throw new HTTPException\BadRequestException(L10n::t('Invalid contact.'));
+               }
+
+               $app->page['aside'] = "";
+               Model\Profile::load($app, "", 0, Model\Contact::getDetailsByURL($contact["url"]));
+
+               $total = Model\GContact::countAllFriends(local_user(), $cid);
+
+               $pager = new Pager($app->query_string);
+
+               $friends = Model\GContact::allFriends(local_user(), $cid, $pager->getStart(), $pager->getItemsPerPage());
+               if (empty($friends)) {
+                       return L10n::t('No friends to display.');
+               }
+
+               $id = 0;
+
+               $entries = [];
+               foreach ($friends as $friend) {
+                       //get further details of the contact
+                       $contactDetails = Model\Contact::getDetailsByURL($friend['url'], $uid, $friend);
+
+                       $connlnk = '';
+                       // $friend[cid] is only available for common contacts. So if the contact is a common one, use contact_photo_menu to generate the photoMenu
+                       // If the contact is not common to the user, Connect/Follow' will be added to the photo menu
+                       if ($friend['cid']) {
+                               $friend['id'] = $friend['cid'];
+                               $photoMenu = Model\Contact::photoMenu($friend);
+                       } else {
+                               $connlnk = $app->getBaseURL() . '/follow/?url=' . $friend['url'];
+                               $photoMenu = [
+                                       'profile' => [L10n::t('View Profile'), Model\Contact::magicLinkbyId($friend['id'], $friend['url'])],
+                                       'follow'  => [L10n::t('Connect/Follow'), $connlnk]
+                               ];
+                       }
+
+                       $entry = [
+                               'url'          => Model\Contact::magicLinkbyId($friend['id'], $friend['url']),
+                               'itemurl'      => defaults($contactDetails, 'addr', $friend['url']),
+                               'name'         => $contactDetails['name'],
+                               'thumb'        => ProxyUtils::proxifyUrl($contactDetails['thumb'], false, ProxyUtils::SIZE_THUMB),
+                               'img_hover'    => $contactDetails['name'],
+                               'details'      => $contactDetails['location'],
+                               'tags'         => $contactDetails['keywords'],
+                               'about'        => $contactDetails['about'],
+                               'account_type' => Model\Contact::getAccountType($contactDetails),
+                               'network'      => ContactSelector::networkToName($contactDetails['network'], $contactDetails['url']),
+                               'photoMenu'    => $photoMenu,
+                               'conntxt'      => L10n::t('Connect'),
+                               'connlnk'      => $connlnk,
+                               'id'           => ++$id,
+                       ];
+                       $entries[] = $entry;
+               }
+
+               $tab_str = Contact::getTabsHTML($app, $contact, 4);
+
+               $tpl = Renderer::getMarkupTemplate('viewcontact_template.tpl');
+               return Renderer::replaceMacros($tpl, [
+                       '$tab_str'  => $tab_str,
+                       '$contacts' => $entries,
+                       '$paginate' => $pager->renderFull($total),
+               ]);
+       }
+}
diff --git a/src/Module/Directory.php b/src/Module/Directory.php
new file mode 100644 (file)
index 0000000..cdf43b8
--- /dev/null
@@ -0,0 +1,188 @@
+<?php
+
+namespace Friendica\Module;
+
+use Friendica\BaseModule;
+use Friendica\Content\Nav;
+use Friendica\Content\Pager;
+use Friendica\Content\Widget;
+use Friendica\Core\Hook;
+use Friendica\Core\L10n;
+use Friendica\Core\Renderer;
+use Friendica\Model\Contact;
+use Friendica\Model\Profile;
+use Friendica\Network\HTTPException;
+use Friendica\Util\Proxy as ProxyUtils;
+use Friendica\Util\Strings;
+
+/**
+ * Shows the local directory of this node
+ */
+class Directory extends BaseModule
+{
+       public static function init()
+       {
+               $app = self::getApp();
+
+               if (local_user()) {
+                       $app->page['aside'] .= Widget::findPeople();
+                       $app->page['aside'] .= Widget::follow();
+               } else {
+                       unset($_SESSION['theme']);
+                       unset($_SESSION['mobile-theme']);
+               }
+       }
+
+       public static function content()
+       {
+               $app = self::getApp();
+               $config = $app->getConfig();
+
+               if (($config->get('system', 'block_public') && !local_user() && !remote_user()) ||
+                       ($config->get('system', 'block_local_dir') && !local_user() && !remote_user())) {
+                       throw new HTTPException\ForbiddenException(L10n::t('Public access denied.'));
+               }
+
+               $output = '';
+               $entries = [];
+
+               Nav::setSelected('directory');
+
+               $search = (!empty($_REQUEST['search']) ?
+                       Strings::escapeTags(trim(rawurldecode($_REQUEST['search']))) :
+                       '');
+
+               $gDirPath = '';
+               $dirURL = $config->get('system', 'directory');
+               if (strlen($dirURL)) {
+                       $gDirPath = Profile::zrl($dirURL, true);
+               }
+
+               $pager = new Pager($app->query_string, 60);
+
+               $profiles = Profile::searchProfiles($pager->getStart(), $pager->getItemsPerPage(), $search);
+
+               if ($profiles['total'] === 0) {
+                       info(L10n::t('No entries (some entries may be hidden).') . EOL);
+               } else {
+                       if (in_array('small', $app->argv)) {
+                               $photo = 'thumb';
+                       } else {
+                               $photo = 'photo';
+                       }
+
+                       foreach ($profiles['entries'] as $entry) {
+                               $entries[] = self::formatEntry($entry, $photo);
+                       }
+               }
+
+               $tpl = Renderer::getMarkupTemplate('directory_header.tpl');
+
+               $output .= Renderer::replaceMacros($tpl, [
+                       '$search'     => $search,
+                       '$globaldir'  => L10n::t('Global Directory'),
+                       '$gDirPath'   => $gDirPath,
+                       '$desc'       => L10n::t('Find on this site'),
+                       '$contacts'   => $profiles['entries'],
+                       '$finding'    => L10n::t('Results for:'),
+                       '$findterm'   => (strlen($search) ? $search : ""),
+                       '$title'      => L10n::t('Site Directory'),
+                       '$search_mod' => 'directory',
+                       '$submit'     => L10n::t('Find'),
+                       '$paginate'   => $pager->renderFull($profiles['total']),
+               ]);
+
+               return $output;
+       }
+
+       /**
+        * Format contact/profile/user data from the database into an usable
+        * array for displaying directory entries.
+        *
+        * @param array  $contact    The directory entry from the database.
+        * @param string $photo_size Avatar size (thumb, photo or micro).
+        *
+        * @return array
+        *
+        * @throws \Exception
+        */
+       public static function formatEntry(array $contact, $photo_size = 'photo')
+       {
+               $itemurl = (($contact['addr'] != "") ? $contact['addr'] : $contact['profile_url']);
+
+               $profile_link = $contact['profile_url'];
+
+               $pdesc = (($contact['pdesc']) ? $contact['pdesc'] . '<br />' : '');
+
+               $details = '';
+               if (strlen($contact['locality'])) {
+                       $details .= $contact['locality'];
+               }
+               if (strlen($contact['region'])) {
+                       if (strlen($contact['locality'])) {
+                               $details .= ', ';
+                       }
+                       $details .= $contact['region'];
+               }
+               if (strlen($contact['country-name'])) {
+                       if (strlen($details)) {
+                               $details .= ', ';
+                       }
+                       $details .= $contact['country-name'];
+               }
+
+               $profile = $contact;
+
+               if (!empty($profile['address'])
+                       || !empty($profile['locality'])
+                       || !empty($profile['region'])
+                       || !empty($profile['postal-code'])
+                       || !empty($profile['country-name'])
+               ) {
+                       $location = L10n::t('Location:');
+               } else {
+                       $location = '';
+               }
+
+               $gender =   (!empty($profile['gender'])   ? L10n::t('Gender:')   : false);
+               $marital =  (!empty($profile['marital'])  ? L10n::t('Status:')   : false);
+               $homepage = (!empty($profile['homepage']) ? L10n::t('Homepage:') : false);
+               $about =    (!empty($profile['about'])    ? L10n::t('About:')    : false);
+
+               $location_e = $location;
+
+               $photo_menu = [
+                       'profile' => [L10n::t("View Profile"), Contact::magicLink($profile_link)]
+               ];
+
+               $entry = [
+                       'id'           => $contact['id'],
+                       'url'          => Contact::magicLInk($profile_link),
+                       'itemurl'      => $itemurl,
+                       'thumb'        => ProxyUtils::proxifyUrl($contact[$photo_size], false, ProxyUtils::SIZE_THUMB),
+                       'img_hover'    => $contact['name'],
+                       'name'         => $contact['name'],
+                       'details'      => $details,
+                       'account_type' => Contact::getAccountType($contact),
+                       'profile'      => $profile,
+                       'location'     => $location_e,
+                       'tags'         => $contact['pub_keywords'],
+                       'gender'       => $gender,
+                       'pdesc'        => $pdesc,
+                       'marital'      => $marital,
+                       'homepage'     => $homepage,
+                       'about'        => $about,
+                       'photo_menu'   => $photo_menu,
+
+               ];
+
+               $hook = ['contact' => $contact, 'entry' => $entry];
+
+               Hook::callAll('directory_item', $hook);
+
+               unset($profile);
+               unset($location);
+
+               return $hook['entry'];
+       }
+}
index ba1b085963d9d2afb99d37506d5e7aca39530ea8..15b2026e2c246559668a4e30df495e8a811280d0 100644 (file)
@@ -3,7 +3,6 @@
 namespace Friendica\Module;
 
 use Friendica\BaseModule;
-use Friendica\Core\System;
 use Friendica\Protocol\OStatus;
 
 /**
index b6252655acf651560314ae32dbbe0b57bc3aff07..1ceab79f65c37aa5074b03987c81982a35bb08c9 100644 (file)
@@ -359,7 +359,7 @@ class DFRN
                $ret = Item::select(Item::DELIVER_FIELDLIST, $condition);
                $items = Item::inArray($ret);
                if (!DBA::isResult($items)) {
-                       exit();
+                       return '';
                }
 
                $item = $items[0];
@@ -367,7 +367,7 @@ class DFRN
                if ($item['uid'] != 0) {
                        $owner = User::getOwnerDataById($item['uid']);
                        if (!$owner) {
-                               exit();
+                               return '';
                        }
                } else {
                        $owner = ['uid' => 0, 'nick' => 'feed-item'];
@@ -400,7 +400,7 @@ class DFRN
                                }
                        }
                } else {
-                       $root = self::entry($doc, $type, $item, $owner, true, 0, true);
+                       self::entry($doc, $type, $item, $owner, true, 0, true);
                }
 
                $atom = trim($doc->saveXML());
@@ -987,7 +987,7 @@ class DFRN
                }
 
                // Add conversation data. This is used for OStatus
-               $conversation_href = System::baseUrl()."/display/".$owner["nick"]."/".$item["parent"];
+               $conversation_href = System::baseUrl()."/display/".$item["parent-guid"];
                $conversation_uri = $conversation_href;
 
                if (isset($parent_item)) {
@@ -2212,14 +2212,13 @@ class DFRN
        /**
         * @brief Send a "poke"
         *
-        * @param array $item      the new item record
+        * @param array $item      The new item record
         * @param array $importer  Record of the importer user mixed with contact of the content
-        * @param int   $posted_id The record number of item record that was just posted
         * @return void
         * @throws \Friendica\Network\HTTPException\InternalServerErrorException
         * @todo  set proper type-hints (array?)
         */
-       private static function doPoke($item, $importer, $posted_id)
+       private static function doPoke(array $item, array $importer)
        {
                $verb = urldecode(substr($item["verb"], strpos($item["verb"], "#")+1));
                if (!$verb) {
@@ -2244,8 +2243,6 @@ class DFRN
                        if ($Blink && Strings::compareLink($Blink, System::baseUrl() . "/profile/" . $importer["nickname"])) {
                                $author = DBA::selectFirst('contact', ['name', 'thumb', 'url'], ['id' => $item['author-id']]);
 
-                               $item['id'] = $posted_id;
-
                                $parent = Item::selectFirst(['id'], ['uri' => $item['parent-uri'], 'uid' => $importer["importer_uid"]]);
                                $item["parent"] = $parent['id'];
 
@@ -2259,7 +2256,7 @@ class DFRN
                                        "to_email"     => $importer["email"],
                                        "uid"          => $importer["importer_uid"],
                                        "item"         => $item,
-                                       "link"         => System::baseUrl()."/display/".urlencode(Item::getGuidById($posted_id)),
+                                       "link"         => System::baseUrl()."/display/".urlencode($item['guid']),
                                        "source_name"  => $author["name"],
                                        "source_link"  => $author["url"],
                                        "source_photo" => $author["thumb"],
@@ -2754,7 +2751,8 @@ class DFRN
                        }
 
                        if (stristr($item["verb"], ACTIVITY_POKE)) {
-                               self::doPoke($item, $importer, $posted_id);
+                               $item['id'] = $posted_id;
+                               self::doPoke($item, $importer);
                        }
                }
        }
diff --git a/tests/src/Console/AutomaticInstallationConsoleTest.php b/tests/src/Console/AutomaticInstallationConsoleTest.php
new file mode 100644 (file)
index 0000000..5ea349f
--- /dev/null
@@ -0,0 +1,646 @@
+<?php
+
+namespace Friendica\Test\src\Console;
+
+use Friendica\Console\AutomaticInstallation;
+use Friendica\Core\Config\Cache\ConfigCache;
+use Friendica\Core\Installer;
+use Friendica\Core\Logger;
+use Friendica\Test\Util\DBAMockTrait;
+use Friendica\Test\Util\DBStructureMockTrait;
+use Friendica\Test\Util\L10nMockTrait;
+use Friendica\Test\Util\RendererMockTrait;
+use Friendica\Util\BaseURL;
+use Friendica\Util\Logger\VoidLogger;
+use org\bovigo\vfs\vfsStream;
+use org\bovigo\vfs\vfsStreamFile;
+
+/**
+ * @runTestsInSeparateProcesses
+ * @preserveGlobalState disabled
+ * @requires PHP 7.0
+ */
+class AutomaticInstallationConsoleTest extends ConsoleTest
+{
+       use L10nMockTrait;
+       use DBAMockTrait;
+       use DBStructureMockTrait;
+       use RendererMockTrait;
+
+       /**
+        * @var vfsStreamFile Assert file without DB credentials
+        */
+       private $assertFile;
+       /**
+        * @var vfsStreamFile Assert file with DB credentials
+        */
+       private $assertFileDb;
+
+       /**
+        * @var ConfigCache The configuration cache to check after each test
+        */
+       private $configCache;
+
+       public function setUp()
+       {
+               parent::setUp();
+
+               if ($this->root->hasChild('config' . DIRECTORY_SEPARATOR . 'local.config.php')) {
+                       $this->root->getChild('config')
+                               ->removeChild('local.config.php');
+               }
+
+               $this->mockL10nT();
+
+               $this->configCache = new ConfigCache();
+               $this->configCache->set('system', 'basepath', $this->root->url());
+               $this->configCache->set('config', 'php_path', trim(shell_exec('which php')));
+               $this->configCache->set('system', 'theme', 'smarty3');
+
+               $this->mockApp($this->root, true);
+
+               $this->configMock->shouldReceive('set')->andReturnUsing(function ($cat, $key, $value) {
+                       if ($key !== 'basepath') {
+                               return $this->configCache->set($cat, $key, $value);
+                       } else {
+                               return true;
+                       }
+               });
+
+               $this->configMock->shouldReceive('has')->andReturn(true);
+               $this->configMock->shouldReceive('get')->andReturnUsing(function ($cat, $key) {
+                       return $this->configCache->get($cat, $key);
+               });
+               $this->configMock->shouldReceive('load')->andReturnUsing(function ($config, $overwrite = false) {
+                       return $this->configCache->load($config, $overwrite);
+               });
+
+               $this->mode->shouldReceive('isInstall')->andReturn(true);
+               Logger::init(new VoidLogger());
+       }
+
+       /**
+        * Returns the dataset for each automatic installation test
+        *
+        * @return array the dataset
+        */
+       public function dataInstaller()
+       {
+               return [
+                       'empty' => [
+                               'data' => [
+                                       'database' => [
+                                               'hostname'    => '',
+                                               'username'    => '',
+                                               'password'    => '',
+                                               'database'    => '',
+                                               'port'        => '',
+                                       ],
+                                       'config' => [
+                                               'php_path'    => '',
+                                               'hostname'    => 'friendica.local',
+                                               'admin_email' => '',
+                                       ],
+                                       'system' => [
+                                               'basepath'    => '',
+                                               'urlpath'     => '',
+                                               'url'         => 'http://friendica.local',
+                                               'ssl_policy'  => 0,
+                                               'default_timezone' => '',
+                                               'language'    => '',
+                                       ],
+                               ],
+                       ],
+                       'normal' => [
+                               'data' => [
+                                       'database' => [
+                                               'hostname'    => 'testhost',
+                                               'port'        => 3306,
+                                               'username'    => 'friendica',
+                                               'password'    => 'a password',
+                                               'database'    => 'database',
+                                       ],
+                                       'config' => [
+                                               'php_path'    => '',
+                                               'hostname'    => 'friendica.local',
+                                               'admin_email' => 'admin@philipp.info',
+                                       ],
+                                       'system' => [
+                                               'urlpath'     => 'test/it',
+                                               'url'         => 'http://friendica.local/test/it',
+                                               'basepath'    => '',
+                                               'ssl_policy'  => '2',
+                                               'default_timezone' => 'en',
+                                               'language'    => 'Europe/Berlin',
+                                       ],
+                               ],
+                       ],
+                       'special' => [
+                               'data' => [
+                                       'database' => [
+                                               'hostname'    => 'testhost.new.domain',
+                                               'port'        => 3341,
+                                               'username'    => 'fr"§%ica',
+                                               'password'    => '$%\"gse',
+                                               'database'    => 'db',
+                                       ],
+                                       'config' => [
+                                               'php_path'    => '',
+                                               'hostname'    => 'friendica.local',
+                                               'admin_email' => 'admin@philipp.info',
+                                       ],
+                                       'system' => [
+                                               'urlpath'     => 'test/it',
+                                               'url'         => 'https://friendica.local/test/it',
+                                               'basepath'    => '',
+                                               'ssl_policy'  => '1',
+                                               'default_timezone' => 'en',
+                                               'language'    => 'Europe/Berlin',
+                                       ],
+                               ],
+                       ],
+               ];
+       }
+
+       private function assertFinished($txt, $withconfig = false, $copyfile = false)
+       {
+               $cfg = '';
+
+               if ($withconfig) {
+                       $cfg = <<<CFG
+
+
+Creating config file...
+
+ Complete!
+CFG;
+               }
+
+               if ($copyfile) {
+                       $cfg = <<<CFG
+
+
+Copying config file...
+
+ Complete!
+CFG;
+               }
+
+               $finished = <<<FIN
+Initializing setup...
+
+ Complete!
+
+
+Checking environment...
+
+ NOTICE: Not checking .htaccess/URL-Rewrite during CLI installation.
+
+ Complete!
+{$cfg}
+
+
+Checking database...
+
+ Complete!
+
+
+Inserting data into database...
+
+ Complete!
+
+
+Installing theme
+
+ Complete
+
+
+
+Installation is finished
+
+
+FIN;
+               $this->assertEquals($finished, $txt);
+       }
+
+       private function assertStuckDB($txt)
+       {
+               $finished = <<<FIN
+Initializing setup...
+
+ Complete!
+
+
+Checking environment...
+
+ NOTICE: Not checking .htaccess/URL-Rewrite during CLI installation.
+
+ Complete!
+
+
+Creating config file...
+
+ Complete!
+
+
+Checking database...
+
+[Error] --------
+Could not connect to database.: 
+
+
+FIN;
+
+               $this->assertEquals($finished, $txt);
+       }
+
+       private function assertStuckURL($txt)
+       {
+               $finished = <<<FIN
+Initializing setup...
+
+ Complete!
+
+
+Checking environment...
+
+ NOTICE: Not checking .htaccess/URL-Rewrite during CLI installation.
+
+ Complete!
+
+
+Creating config file...
+
+The Friendica URL has to be set during CLI installation.
+
+FIN;
+
+               $this->assertEquals($finished, $txt);
+       }
+
+       /**
+        * Asserts one config entry
+        *
+        * @param string     $cat           The category to test
+        * @param string     $key           The key to test
+        * @param null|array $assertion     The asserted value (null = empty, or array/string)
+        * @param string     $default_value The default value
+        */
+       public function assertConfigEntry($cat, $key, $assertion = null, $default_value = null)
+       {
+               if (!empty($assertion[$cat][$key])) {
+                       $this->assertEquals($assertion[$cat][$key], $this->configCache->get($cat, $key));
+               } elseif (!empty($assertion) && !is_array($assertion)) {
+                       $this->assertEquals($assertion, $this->configCache->get($cat, $key));
+               } elseif (!empty($default_value)) {
+                       $this->assertEquals($default_value, $this->configCache->get($cat, $key));
+               } else {
+                       $this->assertEmpty($this->configCache->get($cat, $key), $this->configCache->get($cat, $key));
+               }
+       }
+
+       /**
+        * Asserts all config entries
+        *
+        * @param null|array $assertion    The optional assertion array
+        * @param boolean    $saveDb       True, if the db credentials should get saved to the file
+        * @param boolean    $default      True, if we use the default values
+        * @param boolean    $defaultDb    True, if we use the default value for the DB
+        * @param boolean    $realBasepath True, if we use the real basepath of the installation, not the mocked one
+        */
+       public function assertConfig($assertion = null, $saveDb = false, $default = true, $defaultDb = true, $realBasepath = false)
+       {
+               if (!empty($assertion['database']['hostname'])) {
+                       $assertion['database']['hostname'] .= (!empty($assertion['database']['port']) ? ':' . $assertion['database']['port'] : '');
+               }
+
+               $this->assertConfigEntry('database', 'hostname', ($saveDb) ? $assertion : null, (!$saveDb || $defaultDb) ? Installer::DEFAULT_HOST : null);
+               $this->assertConfigEntry('database', 'username', ($saveDb) ? $assertion : null);
+               $this->assertConfigEntry('database', 'password', ($saveDb) ? $assertion : null);
+               $this->assertConfigEntry('database', 'database', ($saveDb) ? $assertion : null);
+
+               $this->assertConfigEntry('config', 'admin_email', $assertion);
+               $this->assertConfigEntry('config', 'php_path', trim(shell_exec('which php')));
+               $this->assertConfigEntry('config', 'hostname', $assertion);
+
+               $this->assertConfigEntry('system', 'default_timezone', $assertion, ($default) ? Installer::DEFAULT_TZ : null);
+               $this->assertConfigEntry('system', 'language', $assertion, ($default) ? Installer::DEFAULT_LANG : null);
+               $this->assertConfigEntry('system', 'url', $assertion);
+               $this->assertConfigEntry('system', 'urlpath', $assertion);
+               $this->assertConfigEntry('system', 'ssl_policy', $assertion, ($default) ? BaseURL::DEFAULT_SSL_SCHEME : null);
+               $this->assertConfigEntry('system', 'basepath', ($realBasepath) ? $this->root->url() : $assertion);
+       }
+
+       /**
+        * Test the automatic installation without any parameter/setting
+        * Should stuck because of missing hostname
+        */
+       public function testEmpty()
+       {
+               $console = new AutomaticInstallation($this->consoleArgv);
+
+               $txt = $this->dumpExecute($console);
+
+               $this->assertStuckURL($txt);
+       }
+
+       /**
+        * Test the automatic installation without any parameter/setting
+        * except URL
+        */
+       public function testEmptyWithURL()
+       {
+               $this->mockConnect(true, 1);
+               $this->mockConnected(true, 1);
+               $this->mockExistsTable('user', false, 1);
+               $this->mockUpdate([$this->root->url(), false, true, true], null, 1);
+
+               $this->mockGetMarkupTemplate('local.config.tpl', 'testTemplate', 1);
+               $this->mockReplaceMacros('testTemplate', \Mockery::any(), false, '', 1);
+
+               $console = new AutomaticInstallation($this->consoleArgv);
+               $console->setOption('url', 'http://friendica.local');
+
+               $txt = $this->dumpExecute($console);
+
+               $this->assertFinished($txt, true, false);
+               $this->assertTrue($this->root->hasChild('config' . DIRECTORY_SEPARATOR . 'local.config.php'));
+
+               $this->assertConfig(['config' => ['hostname' => 'friendica.local'], 'system' => ['url' => 'http://friendica.local', 'ssl_policy' => 0, 'urlPath' => '']], false, true, true, true);
+       }
+
+       /**
+        * Test the automatic installation with a prepared config file
+        * @dataProvider dataInstaller
+        */
+       public function testWithConfig(array $data)
+       {
+               $this->mockConnect(true, 1);
+               $this->mockConnected(true, 1);
+               $this->mockExistsTable('user', false, 1);
+               $this->mockUpdate([$this->root->url(), false, true, true], null, 1);
+
+               $conf = function ($cat, $key) use ($data) {
+                       if ($cat == 'database' && $key == 'hostname' && !empty($data['database']['port'])) {
+                               return $data[$cat][$key] . ':' . $data['database']['port'];
+                       }
+                       return $data[$cat][$key];
+               };
+
+               $config = <<<CONF
+<?php
+
+// Local configuration
+
+// If you're unsure about what any of the config keys below do, please check the config/defaults.config.php for detailed
+// documentation of their data type and behavior.
+
+return [
+       'database' => [
+               'hostname' => '{$conf('database', 'hostname')}',
+               'username' => '{$conf('database', 'username')}',
+               'password' => '{$conf('database', 'password')}',
+               'database' => '{$conf('database', 'database')}',
+               'charset' => 'utf8mb4',
+       ],
+
+       // ****************************************************************
+       // The configuration below will be overruled by the admin panel.
+       // Changes made below will only have an effect if the database does
+       // not contain any configuration for the friendica system.
+       // ****************************************************************
+
+       'config' => [
+               'admin_email' => '{$conf('config', 'admin_email')}',
+               'hostname' => '{$conf('config', 'hostname')}',
+               'sitename' => 'Friendica Social Network',
+               'register_policy' => \Friendica\Module\Register::OPEN,
+               'register_text' => '',
+       ],
+       'system' => [
+               'basepath' => '{$conf('system', 'basepath')}',
+               'urlpath' => '{$conf('system', 'urlpath')}',
+               'url' => '{$conf('system', 'url')}',
+               'ssl_policy' => '{$conf('system', 'ssl_policy')}',
+               'default_timezone' => '{$conf('system', 'default_timezone')}',
+               'language' => '{$conf('system', 'language')}',
+       ],
+];
+CONF;
+
+               vfsStream::newFile('prepared.config.php')
+                       ->at($this->root)
+                       ->setContent($config);
+
+               $console = new AutomaticInstallation($this->consoleArgv);
+               $console->setOption('f', 'prepared.config.php');
+
+               $txt = $this->dumpExecute($console);
+
+               $this->assertFinished($txt, false, true);
+
+               $this->assertTrue($this->root->hasChild('config' . DIRECTORY_SEPARATOR . 'local.config.php'));
+               $this->assertEquals($config, file_get_contents($this->root->getChild('config' . DIRECTORY_SEPARATOR . 'local.config.php')->url()));
+
+               $this->assertConfig($data, true, false, false);
+       }
+
+       /**
+        * Test the automatic installation with environment variables
+        * Includes saving the DB credentials to the file
+        * @dataProvider dataInstaller
+        */
+       public function testWithEnvironmentAndSave(array $data)
+       {
+               $this->mockConnect(true, 1);
+               $this->mockConnected(true, 1);
+               $this->mockExistsTable('user', false, 1);
+               $this->mockUpdate([$this->root->url(), false, true, true], null, 1);
+
+               $this->mockGetMarkupTemplate('local.config.tpl', 'testTemplate', 1);
+               $this->mockReplaceMacros('testTemplate', \Mockery::any(), false, '', 1);
+
+               $this->assertTrue(putenv('MYSQL_HOST='     . $data['database']['hostname']));
+               $this->assertTrue(putenv('MYSQL_PORT='     . $data['database']['port']));
+               $this->assertTrue(putenv('MYSQL_DATABASE=' . $data['database']['database']));
+               $this->assertTrue(putenv('MYSQL_USERNAME=' . $data['database']['username']));
+               $this->assertTrue(putenv('MYSQL_PASSWORD=' . $data['database']['password']));
+
+               $this->assertTrue(putenv('FRIENDICA_HOSTNAME='   . $data['config']['hostname']));
+               $this->assertTrue(putenv('FRIENDICA_BASE_PATH='  . $data['system']['basepath']));
+               $this->assertTrue(putenv('FRIENDICA_URL='        . $data['system']['url']));
+               $this->assertTrue(putenv('FRIENDICA_PHP_PATH='   . $data['config']['php_path']));
+               $this->assertTrue(putenv('FRIENDICA_ADMIN_MAIL=' . $data['config']['admin_email']));
+               $this->assertTrue(putenv('FRIENDICA_TZ='         . $data['system']['default_timezone']));
+               $this->assertTrue(putenv('FRIENDICA_LANG='       . $data['system']['language']));
+
+               $console = new AutomaticInstallation($this->consoleArgv);
+               $console->setOption('savedb', true);
+
+               $txt = $this->dumpExecute($console);
+
+               $this->assertFinished($txt, true);
+               $this->assertConfig($data, true, true, false, true);
+       }
+
+       /**
+        * Test the automatic installation with environment variables
+        * Don't save the db credentials to the file
+        * @dataProvider dataInstaller
+        */
+       public function testWithEnvironmentWithoutSave(array $data)
+       {
+               $this->mockConnect(true, 1);
+               $this->mockConnected(true, 1);
+               $this->mockExistsTable('user', false, 1);
+               $this->mockUpdate([$this->root->url(), false, true, true], null, 1);
+
+               $this->mockGetMarkupTemplate('local.config.tpl', 'testTemplate', 1);
+               $this->mockReplaceMacros('testTemplate', \Mockery::any(), false, '', 1);
+
+               $this->assertTrue(putenv('MYSQL_HOST=' . $data['database']['hostname']));
+               $this->assertTrue(putenv('MYSQL_PORT=' . $data['database']['port']));
+               $this->assertTrue(putenv('MYSQL_DATABASE=' . $data['database']['database']));
+               $this->assertTrue(putenv('MYSQL_USERNAME=' . $data['database']['username']));
+               $this->assertTrue(putenv('MYSQL_PASSWORD=' . $data['database']['password']));
+
+               $this->assertTrue(putenv('FRIENDICA_HOSTNAME='   . $data['config']['hostname']));
+               $this->assertTrue(putenv('FRIENDICA_BASE_PATH='  . $data['system']['basepath']));
+               $this->assertTrue(putenv('FRIENDICA_URL='        . $data['system']['url']));
+               $this->assertTrue(putenv('FRIENDICA_PHP_PATH='   . $data['config']['php_path']));
+               $this->assertTrue(putenv('FRIENDICA_ADMIN_MAIL=' . $data['config']['admin_email']));
+               $this->assertTrue(putenv('FRIENDICA_TZ='         . $data['system']['default_timezone']));
+               $this->assertTrue(putenv('FRIENDICA_LANG='       . $data['system']['language']));
+
+               $console = new AutomaticInstallation($this->consoleArgv);
+
+               $txt = $this->dumpExecute($console);
+
+               $this->assertFinished($txt, true);
+               $this->assertConfig($data, false, true, false, true);
+       }
+
+       /**
+        * Test the automatic installation with arguments
+        * @dataProvider dataInstaller
+        */
+       public function testWithArguments(array $data)
+       {
+               $this->mockConnect(true, 1);
+               $this->mockConnected(true, 1);
+               $this->mockExistsTable('user', false, 1);
+               $this->mockUpdate([$this->root->url(), false, true, true], null, 1);
+
+               $this->mockGetMarkupTemplate('local.config.tpl', 'testTemplate', 1);
+               $this->mockReplaceMacros('testTemplate', \Mockery::any(), false, '', 1);
+
+               $console = new AutomaticInstallation($this->consoleArgv);
+
+               $option = function($var, $cat, $key) use ($data, $console) {
+                       if (!empty($data[$cat][$key])) {
+                               $console->setOption($var, $data[$cat][$key]);
+                       }
+               };
+               $option('dbhost'    , 'database', 'hostname');
+               $option('dbport'    , 'database', 'port');
+               $option('dbuser'    , 'database', 'username');
+               $option('dbpass'    , 'database', 'password');
+               $option('dbdata'    , 'database', 'database');
+               $option('url'       , 'system'  , 'url');
+               $option('phppath'   , 'config'  , 'php_path');
+               $option('admin'     , 'config'  , 'admin_email');
+               $option('tz'        , 'system'  , 'default_timezone');
+               $option('lang'      , 'system'  , 'language');
+               $option('basepath'  , 'system'  , 'basepath');
+
+               $txt = $this->dumpExecute($console);
+
+               $this->assertFinished($txt, true);
+               $this->assertConfig($data, true, true, true, true);
+       }
+
+       /**
+        * Test the automatic installation with a wrong database connection
+        */
+       public function testNoDatabaseConnection()
+       {
+               $this->mockConnect(false, 1);
+
+               $this->mockGetMarkupTemplate('local.config.tpl', 'testTemplate', 1);
+               $this->mockReplaceMacros('testTemplate', \Mockery::any(), false, '', 1);
+
+               $console = new AutomaticInstallation($this->consoleArgv);
+               $console->setOption('url', 'http://friendica.local');
+
+               $txt = $this->dumpExecute($console);
+
+               $this->assertStuckDB($txt);
+               $this->assertTrue($this->root->hasChild('config' . DIRECTORY_SEPARATOR . 'local.config.php'));
+
+               $this->assertConfig(['config' => ['hostname' => 'friendica.local'], 'system' => ['url' => 'http://friendica.local', 'ssl_policy' => 0, 'urlpath' => '']], false, true, false, true);
+       }
+
+       public function testGetHelp()
+       {
+               // Usable to purposely fail if new commands are added without taking tests into account
+               $theHelp = <<<HELP
+Installation - Install Friendica automatically
+Synopsis
+       bin/console autoinstall [-h|--help|-?] [-v] [-a] [-f]
+
+Description
+    Installs Friendica with data based on the local.config.php file or environment variables
+
+Notes
+    Not checking .htaccess/URL-Rewrite during CLI installation.
+
+Options
+    -h|--help|-?            Show help information
+    -v                      Show more debug information.
+    -a                      All setup checks are required (except .htaccess)
+    -f|--file <config>      prepared config file (e.g. "config/local.config.php" itself) which will override every other config option - except the environment variables)
+    -s|--savedb               Save the DB credentials to the file (if environment variables is used)
+    -H|--dbhost <host>        The host of the mysql/mariadb database (env MYSQL_HOST)
+    -p|--dbport <port>        The port of the mysql/mariadb database (env MYSQL_PORT)
+    -d|--dbdata <database>    The name of the mysql/mariadb database (env MYSQL_DATABASE)
+    -U|--dbuser <username>    The username of the mysql/mariadb database login (env MYSQL_USER or MYSQL_USERNAME)
+    -P|--dbpass <password>    The password of the mysql/mariadb database login (env MYSQL_PASSWORD)
+    -U|--url <url>            The full base URL of Friendica - f.e. 'https://friendica.local/sub' (env FRIENDICA_URL) 
+    -B|--phppath <php_path>   The path of the PHP binary (env FRIENDICA_PHP_PATH)
+    -b|--basepath <base_path> The basepath of Friendica (env FRIENDICA_BASE_PATH)
+    -t|--tz <timezone>        The timezone of Friendica (env FRIENDICA_TZ)
+    -L|--lang <language>      The language of Friendica (env FRIENDICA_LANG)
+Environment variables
+   MYSQL_HOST                  The host of the mysql/mariadb database (mandatory if mysql and environment is used)
+   MYSQL_PORT                  The port of the mysql/mariadb database
+   MYSQL_USERNAME|MYSQL_USER   The username of the mysql/mariadb database login (MYSQL_USERNAME is for mysql, MYSQL_USER for mariadb)
+   MYSQL_PASSWORD              The password of the mysql/mariadb database login
+   MYSQL_DATABASE              The name of the mysql/mariadb database
+   FRIENDICA_URL               The full base URL of Friendica - f.e. 'https://friendica.local/sub'
+   FRIENDICA_PHP_PATH          The path of the PHP binary - leave empty for auto detection
+   FRIENDICA_BASE_PATH         The basepath of Friendica - leave empty for auto detection
+   FRIENDICA_ADMIN_MAIL        The admin email address of Friendica (this email will be used for admin access)
+   FRIENDICA_TZ                The timezone of Friendica
+   FRIENDICA_LANG              The langauge of Friendica
+   
+Examples
+       bin/console autoinstall -f 'input.config.php
+               Installs Friendica with the prepared 'input.config.php' file
+
+       bin/console autoinstall --savedb
+               Installs Friendica with environment variables and saves them to the 'config/local.config.php' file
+
+       bin/console autoinstall -h localhost -p 3365 -U user -P passwort1234 -d friendica
+               Installs Friendica with a local mysql database with credentials
+
+HELP;
+
+               $console = new AutomaticInstallation($this->consoleArgv);
+               $console->setOption('help', true);
+
+               $txt = $this->dumpExecute($console);
+
+               $this->assertEquals($theHelp, $txt);
+       }
+}
diff --git a/tests/src/Console/ConfigConsoleTest.php b/tests/src/Console/ConfigConsoleTest.php
new file mode 100644 (file)
index 0000000..8658097
--- /dev/null
@@ -0,0 +1,193 @@
+<?php
+
+namespace Friendica\Test\src\Console;
+
+use Friendica\App\Mode;
+use Friendica\Console\Config;
+
+/**
+ * @runTestsInSeparateProcesses
+ * @preserveGlobalState disabled
+ * @requires PHP 7.0
+ */
+class ConfigConsoleTest extends ConsoleTest
+{
+       protected function setUp()
+       {
+               parent::setUp();
+
+               $this->mockApp($this->root);
+
+               \Mockery::getConfiguration()->setConstantsMap([
+                       Mode::class => [
+                               'DBCONFIGAVAILABLE' => 0
+                       ]
+               ]);
+
+               $this->mode
+                       ->shouldReceive('has')
+                       ->andReturn(true);
+
+       }
+
+       function testSetGetKeyValue() {
+               $this->configMock
+                       ->shouldReceive('set')
+                       ->with('config', 'test', 'now')
+                       ->andReturn(true)
+                       ->once();
+               $this->configMock
+                       ->shouldReceive('get')
+                       ->with('config', 'test')
+                       ->andReturn('now')
+                       ->twice();
+
+               $console = new Config($this->consoleArgv);
+               $console->setArgument(0, 'config');
+               $console->setArgument(1, 'test');
+               $console->setArgument(2, 'now');
+               $txt = $this->dumpExecute($console);
+               $this->assertEquals("config.test <= now\n", $txt);
+
+               $this->configMock
+                       ->shouldReceive('get')
+                       ->with('config', 'test')
+                       ->andReturn('now')
+                       ->once();
+
+               $console = new Config($this->consoleArgv);
+               $console->setArgument(0, 'config');
+               $console->setArgument(1, 'test');
+               $txt = $this->dumpExecute($console);
+               $this->assertEquals("config.test => now\n", $txt);
+
+               $this->configMock
+                       ->shouldReceive('get')
+                       ->with('config', 'test')
+                       ->andReturn(null)
+                       ->once();
+
+               $console = new Config($this->consoleArgv);
+               $console->setArgument(0, 'config');
+               $console->setArgument(1, 'test');
+               $txt = $this->dumpExecute($console);
+               $this->assertEquals("config.test => \n", $txt);
+       }
+
+       function testSetArrayValue() {
+               $testArray = [1, 2, 3];
+               $this->configMock
+                       ->shouldReceive('get')
+                       ->with('config', 'test')
+                       ->andReturn($testArray)
+                       ->once();
+
+               $console = new Config($this->consoleArgv);
+               $console->setArgument(0, 'config');
+               $console->setArgument(1, 'test');
+               $console->setArgument(2, 'now');
+               $txt = $this->dumpExecute($console);
+
+               $this->assertEquals("[Error] config.test is an array and can't be set using this command.\n", $txt);
+       }
+
+       function testTooManyArguments() {
+               $console = new Config($this->consoleArgv);
+               $console->setArgument(0, 'config');
+               $console->setArgument(1, 'test');
+               $console->setArgument(2, 'it');
+               $console->setArgument(3, 'now');
+               $txt = $this->dumpExecute($console);
+               $assertion = '[Warning] Too many arguments';
+               $firstline = substr($txt, 0, strlen($assertion));
+               $this->assertEquals($assertion, $firstline);
+       }
+
+       function testVerbose() {
+               $this->configMock
+                       ->shouldReceive('get')
+                       ->with('test', 'it')
+                       ->andReturn('now')
+                       ->once();
+               $console = new Config($this->consoleArgv);
+               $console->setArgument(0, 'test');
+               $console->setArgument(1, 'it');
+               $console->setOption('v', 1);
+               $executable = $this->consoleArgv[0];
+               $assertion = <<<CONF
+Executable: {$executable}
+Class: Friendica\Console\Config
+Arguments: array (
+  0 => 'test',
+  1 => 'it',
+)
+Options: array (
+  'v' => 1,
+)
+test.it => now
+
+CONF;
+               $txt = $this->dumpExecute($console);
+               $this->assertEquals($assertion, $txt);
+       }
+
+       function testUnableToSet() {
+               $this->configMock
+                       ->shouldReceive('set')
+                       ->with('test', 'it', 'now')
+                       ->andReturn(false)
+                       ->once();
+               $this->configMock
+                       ->shouldReceive('get')
+                       ->with('test', 'it')
+                       ->andReturn(NULL)
+                       ->once();
+               $console = new Config();
+               $console->setArgument(0, 'test');
+               $console->setArgument(1, 'it');
+               $console->setArgument(2, 'now');
+               $txt = $this->dumpExecute($console);
+               $this->assertSame("Unable to set test.it\n", $txt);
+       }
+
+       public function testGetHelp()
+       {
+               // Usable to purposely fail if new commands are added without taking tests into account
+               $theHelp = <<<HELP
+console config - Manage site configuration
+Synopsis
+       bin/console config [-h|--help|-?] [-v]
+       bin/console config <category> [-h|--help|-?] [-v]
+       bin/console config <category> <key> [-h|--help|-?] [-v]
+       bin/console config <category> <key> <value> [-h|--help|-?] [-v]
+
+Description
+       bin/console config
+               Lists all config values
+
+       bin/console config <category>
+               Lists all config values in the provided category
+
+       bin/console config <category> <key>
+               Shows the value of the provided key in the category
+
+       bin/console config <category> <key> <value>
+               Sets the value of the provided key in the category
+
+Notes:
+       Setting config entries which are manually set in config/local.config.php may result in
+       conflict between database settings and the manual startup settings.
+
+Options
+    -h|--help|-? Show help information
+    -v           Show more debug information.
+
+HELP;
+               $console = new Config($this->consoleArgv);
+               $console->setOption('help', true);
+
+               $txt = $this->dumpExecute($console);
+
+               $this->assertEquals($txt, $theHelp);
+       }
+}
diff --git a/tests/src/Console/ConsoleTest.php b/tests/src/Console/ConsoleTest.php
new file mode 100644 (file)
index 0000000..21979e7
--- /dev/null
@@ -0,0 +1,46 @@
+<?php
+
+namespace Friendica\Test\src\Console;
+
+use Asika\SimpleConsole\Console;
+use Friendica\Test\MockedTest;
+use Friendica\Test\Util\AppMockTrait;
+use Friendica\Test\Util\Intercept;
+use Friendica\Test\Util\VFSTrait;
+
+abstract class ConsoleTest extends MockedTest
+{
+       use VFSTrait;
+       use AppMockTrait;
+
+       /**
+        * @var array The default argv for a Console Instance
+        */
+       protected $consoleArgv = [ 'consoleTest.php' ];
+
+       protected function setUp()
+       {
+               parent::setUp();
+
+               Intercept::setUp();
+
+               $this->setUpVfsDir();
+       }
+
+       /**
+        * Dumps the execution of an console output to a string and returns it
+        *
+        * @param Console $console The current console instance
+        *
+        * @return string the output of the execution
+        */
+       protected function dumpExecute($console)
+       {
+               Intercept::reset();
+               $console->execute();
+               $returnStr = Intercept::$cache;
+               Intercept::reset();
+
+               return $returnStr;
+       }
+}
diff --git a/tests/src/Console/ServerBlockConsoleTest.php b/tests/src/Console/ServerBlockConsoleTest.php
new file mode 100644 (file)
index 0000000..11856ea
--- /dev/null
@@ -0,0 +1,337 @@
+<?php
+
+namespace Friendica\Test\src\Console;
+
+use Friendica\Console\ServerBlock;
+
+/**
+ * @runTestsInSeparateProcesses
+ * @preserveGlobalState disabled
+ */
+class ServerBlockConsoleTest extends ConsoleTest
+{
+       protected $defaultBlockList = [
+               [
+                       'domain' => 'social.nobodyhasthe.biz',
+                       'reason' => 'Illegal content',
+               ],
+               [
+                       'domain' => 'pod.ordoevangelistarum.com',
+                       'reason' => 'Illegal content',
+               ]
+       ];
+
+       protected function setUp()
+       {
+               parent::setUp();
+
+               $this->mockApp($this->root);
+       }
+
+       /**
+        * Test to list the default blocked servers
+        */
+       public function testBlockedServersList()
+       {
+               $this->configMock
+                       ->shouldReceive('get')
+                       ->with('system', 'blocklist')
+                       ->andReturn($this->defaultBlockList)
+                       ->once();
+
+               $console = new ServerBlock($this->consoleArgv);
+               $txt = $this->dumpExecute($console);
+
+               $output = <<<CONS
++----------------------------+-----------------+
+| Domain                     | Reason          |
++----------------------------+-----------------+
+| social.nobodyhasthe.biz    | Illegal content |
+| pod.ordoevangelistarum.com | Illegal content |
++----------------------------+-----------------+
+
+
+CONS;
+
+               $this->assertEquals($output, $txt);
+       }
+
+       /**
+        * Test blockedservers add command
+        */
+       public function testAddBlockedServer()
+       {
+               $this->configMock
+                       ->shouldReceive('get')
+                       ->with('system', 'blocklist')
+                       ->andReturn($this->defaultBlockList)
+                       ->once();
+
+               $newBlockList = $this->defaultBlockList;
+               $newBlockList[] = [
+                       'domain' => 'testme.now',
+                       'reason' => 'I like it!',
+               ];
+
+               $this->configMock
+                       ->shouldReceive('set')
+                       ->with('system', 'blocklist', $newBlockList)
+                       ->andReturn(true)
+                       ->once();
+
+               $console = new ServerBlock($this->consoleArgv);
+               $console->setArgument(0, 'add');
+               $console->setArgument(1, 'testme.now');
+               $console->setArgument(2, 'I like it!');
+               $txt = $this->dumpExecute($console);
+
+               $this->assertEquals('The domain \'testme.now\' is now blocked. (Reason: \'I like it!\')' . PHP_EOL, $txt);
+       }
+
+       /**
+        * Test blockedservers add command with the default reason
+        */
+       public function testAddBlockedServerWithDefaultReason()
+       {
+               $this->configMock
+                       ->shouldReceive('get')
+                       ->with('system', 'blocklist')
+                       ->andReturn($this->defaultBlockList)
+                       ->once();
+
+               $newBlockList = $this->defaultBlockList;
+               $newBlockList[] = [
+                       'domain' => 'testme.now',
+                       'reason' => ServerBlock::DEFAULT_REASON,
+               ];
+
+               $this->configMock
+                       ->shouldReceive('set')
+                       ->with('system', 'blocklist', $newBlockList)
+                       ->andReturn(true)
+                       ->once();
+
+               $console = new ServerBlock($this->consoleArgv);
+               $console->setArgument(0, 'add');
+               $console->setArgument(1, 'testme.now');
+               $txt = $this->dumpExecute($console);
+
+               $this->assertEquals('The domain \'testme.now\' is now blocked. (Reason: \'' . ServerBlock::DEFAULT_REASON . '\')' . PHP_EOL, $txt);
+       }
+
+       /**
+        * Test blockedservers add command on existed domain
+        */
+       public function testUpdateBlockedServer()
+       {
+               $this->configMock
+                       ->shouldReceive('get')
+                       ->with('system', 'blocklist')
+                       ->andReturn($this->defaultBlockList)
+                       ->once();
+
+               $newBlockList = [
+                       [
+                               'domain' => 'social.nobodyhasthe.biz',
+                               'reason' => 'Illegal content',
+                       ],
+                       [
+                               'domain' => 'pod.ordoevangelistarum.com',
+                               'reason' => 'Other reason',
+                       ]
+               ];
+
+               $this->configMock
+                       ->shouldReceive('set')
+                       ->with('system', 'blocklist', $newBlockList)
+                       ->andReturn(true)
+                       ->once();
+
+               $console = new ServerBlock($this->consoleArgv);
+               $console->setArgument(0, 'add');
+               $console->setArgument(1, 'pod.ordoevangelistarum.com');
+               $console->setArgument(2, 'Other reason');
+               $txt = $this->dumpExecute($console);
+
+               $this->assertEquals('The domain \'pod.ordoevangelistarum.com\' is now updated. (Reason: \'Other reason\')' . PHP_EOL, $txt);
+       }
+
+       /**
+        * Test blockedservers remove command
+        */
+       public function testRemoveBlockedServer()
+       {
+               $this->configMock
+                       ->shouldReceive('get')
+                       ->with('system', 'blocklist')
+                       ->andReturn($this->defaultBlockList)
+                       ->once();
+
+               $newBlockList = [
+                       [
+                               'domain' => 'social.nobodyhasthe.biz',
+                               'reason' => 'Illegal content',
+                       ],
+               ];
+
+               $this->configMock
+                       ->shouldReceive('set')
+                       ->with('system', 'blocklist', $newBlockList)
+                       ->andReturn(true)
+                       ->once();
+
+               $console = new ServerBlock($this->consoleArgv);
+               $console->setArgument(0, 'remove');
+               $console->setArgument(1, 'pod.ordoevangelistarum.com');
+               $txt = $this->dumpExecute($console);
+
+               $this->assertEquals('The domain \'pod.ordoevangelistarum.com\' is not more blocked' . PHP_EOL, $txt);
+       }
+
+       /**
+        * Test blockedservers with a wrong command
+        */
+       public function testBlockedServersWrongCommand()
+       {
+               $console = new ServerBlock($this->consoleArgv);
+               $console->setArgument(0, 'wrongcommand');
+               $txt = $this->dumpExecute($console);
+
+               $this->assertStringStartsWith('[Warning] Unknown command', $txt);
+       }
+
+       /**
+        * Test blockedservers remove with not existing domain
+        */
+       public function testRemoveBlockedServerNotExist()
+       {
+               $this->configMock
+                       ->shouldReceive('get')
+                       ->with('system', 'blocklist')
+                       ->andReturn($this->defaultBlockList)
+                       ->once();
+
+               $console = new ServerBlock($this->consoleArgv);
+               $console->setArgument(0, 'remove');
+               $console->setArgument(1, 'not.exiting');
+               $txt = $this->dumpExecute($console);
+
+               $this->assertEquals('The domain \'not.exiting\' is not blocked.' . PHP_EOL, $txt);
+       }
+
+       /**
+        * Test blockedservers add command without argument
+        */
+       public function testAddBlockedServerMissingArgument()
+       {
+               $console = new ServerBlock($this->consoleArgv);
+               $console->setArgument(0, 'add');
+               $txt = $this->dumpExecute($console);
+
+               $this->assertStringStartsWith('[Warning] Add needs a domain and optional a reason.', $txt);
+       }
+
+       /**
+        * Test blockedservers add command without save
+        */
+       public function testAddBlockedServerNoSave()
+       {
+               $this->configMock
+                       ->shouldReceive('get')
+                       ->with('system', 'blocklist')
+                       ->andReturn($this->defaultBlockList)
+                       ->once();
+
+               $newBlockList = $this->defaultBlockList;
+               $newBlockList[] = [
+                       'domain' => 'testme.now',
+                       'reason' => ServerBlock::DEFAULT_REASON,
+               ];
+
+               $this->configMock
+                       ->shouldReceive('set')
+                       ->with('system', 'blocklist', $newBlockList)
+                       ->andReturn(false)
+                       ->once();
+
+               $console = new ServerBlock($this->consoleArgv);
+               $console->setArgument(0, 'add');
+               $console->setArgument(1, 'testme.now');
+               $txt = $this->dumpExecute($console);
+
+               $this->assertEquals('Couldn\'t save \'testme.now\' as blocked server' . PHP_EOL, $txt);
+       }
+
+       /**
+        * Test blockedservers remove command without save
+        */
+       public function testRemoveBlockedServerNoSave()
+       {
+               $this->configMock
+                       ->shouldReceive('get')
+                       ->with('system', 'blocklist')
+                       ->andReturn($this->defaultBlockList)
+                       ->once();
+
+               $newBlockList = [
+                       [
+                               'domain' => 'social.nobodyhasthe.biz',
+                               'reason' => 'Illegal content',
+                       ],
+               ];
+
+               $this->configMock
+                       ->shouldReceive('set')
+                       ->with('system', 'blocklist', $newBlockList)
+                       ->andReturn(false)
+                       ->once();
+
+               $console = new ServerBlock($this->consoleArgv);
+               $console->setArgument(0, 'remove');
+               $console->setArgument(1, 'pod.ordoevangelistarum.com');
+               $txt = $this->dumpExecute($console);
+
+               $this->assertEquals('Couldn\'t remove \'pod.ordoevangelistarum.com\' from blocked servers' . PHP_EOL, $txt);
+       }
+
+       /**
+        * Test blockedservers remove command without argument
+        */
+       public function testRemoveBlockedServerMissingArgument()
+       {
+               $console = new ServerBlock($this->consoleArgv);
+               $console->setArgument(0, 'remove');
+               $txt = $this->dumpExecute($console);
+
+               $this->assertStringStartsWith('[Warning] Remove needs a second parameter.', $txt);
+       }
+
+       /**
+        * Test the blockedservers help
+        */
+       public function testBlockedServersHelp()
+       {
+               $console = new ServerBlock($this->consoleArgv);
+               $console->setOption('help', true);
+               $txt = $this->dumpExecute($console);
+
+               $help = <<<HELP
+console serverblock - Manage blocked servers
+Usage
+       bin/console serverblock [-h|--help|-?] [-v]
+       bin/console serverblock add <server> <reason> [-h|--help|-?] [-v]
+       bin/console serverblock remove <server> [-h|--help|-?] [-v]
+
+Description
+       With this tool, you can list the current blocked servers
+    or you can add / remove a blocked server from the list
+
+Options
+    -h|--help|-? Show help information
+    -v           Show more debug information.
+
+HELP;
+
+               $this->assertEquals($help, $txt);
+       }
+}
diff --git a/tests/src/Core/Console/AutomaticInstallationConsoleTest.php b/tests/src/Core/Console/AutomaticInstallationConsoleTest.php
deleted file mode 100644 (file)
index 9ed3d40..0000000
+++ /dev/null
@@ -1,646 +0,0 @@
-<?php
-
-namespace Friendica\Test\src\Core\Console;
-
-use Friendica\Core\Config\Cache\ConfigCache;
-use Friendica\Core\Console\AutomaticInstallation;
-use Friendica\Core\Installer;
-use Friendica\Core\Logger;
-use Friendica\Test\Util\DBAMockTrait;
-use Friendica\Test\Util\DBStructureMockTrait;
-use Friendica\Test\Util\L10nMockTrait;
-use Friendica\Test\Util\RendererMockTrait;
-use Friendica\Util\BaseURL;
-use Friendica\Util\Logger\VoidLogger;
-use org\bovigo\vfs\vfsStream;
-use org\bovigo\vfs\vfsStreamFile;
-
-/**
- * @runTestsInSeparateProcesses
- * @preserveGlobalState disabled
- * @requires PHP 7.0
- */
-class AutomaticInstallationConsoleTest extends ConsoleTest
-{
-       use L10nMockTrait;
-       use DBAMockTrait;
-       use DBStructureMockTrait;
-       use RendererMockTrait;
-
-       /**
-        * @var vfsStreamFile Assert file without DB credentials
-        */
-       private $assertFile;
-       /**
-        * @var vfsStreamFile Assert file with DB credentials
-        */
-       private $assertFileDb;
-
-       /**
-        * @var ConfigCache The configuration cache to check after each test
-        */
-       private $configCache;
-
-       public function setUp()
-       {
-               parent::setUp();
-
-               if ($this->root->hasChild('config' . DIRECTORY_SEPARATOR . 'local.config.php')) {
-                       $this->root->getChild('config')
-                               ->removeChild('local.config.php');
-               }
-
-               $this->mockL10nT();
-
-               $this->configCache = new ConfigCache();
-               $this->configCache->set('system', 'basepath', $this->root->url());
-               $this->configCache->set('config', 'php_path', trim(shell_exec('which php')));
-               $this->configCache->set('system', 'theme', 'smarty3');
-
-               $this->mockApp($this->root, true);
-
-               $this->configMock->shouldReceive('set')->andReturnUsing(function ($cat, $key, $value) {
-                       if ($key !== 'basepath') {
-                               return $this->configCache->set($cat, $key, $value);
-                       } else {
-                               return true;
-                       }
-               });
-
-               $this->configMock->shouldReceive('has')->andReturn(true);
-               $this->configMock->shouldReceive('get')->andReturnUsing(function ($cat, $key) {
-                       return $this->configCache->get($cat, $key);
-               });
-               $this->configMock->shouldReceive('load')->andReturnUsing(function ($config, $overwrite = false) {
-                       return $this->configCache->load($config, $overwrite);
-               });
-
-               $this->mode->shouldReceive('isInstall')->andReturn(true);
-               Logger::init(new VoidLogger());
-       }
-
-       /**
-        * Returns the dataset for each automatic installation test
-        *
-        * @return array the dataset
-        */
-       public function dataInstaller()
-       {
-               return [
-                       'empty' => [
-                               'data' => [
-                                       'database' => [
-                                               'hostname'    => '',
-                                               'username'    => '',
-                                               'password'    => '',
-                                               'database'    => '',
-                                               'port'        => '',
-                                       ],
-                                       'config' => [
-                                               'php_path'    => '',
-                                               'hostname'    => 'friendica.local',
-                                               'admin_email' => '',
-                                       ],
-                                       'system' => [
-                                               'basepath'    => '',
-                                               'urlpath'     => '',
-                                               'url'         => 'http://friendica.local',
-                                               'ssl_policy'  => 0,
-                                               'default_timezone' => '',
-                                               'language'    => '',
-                                       ],
-                               ],
-                       ],
-                       'normal' => [
-                               'data' => [
-                                       'database' => [
-                                               'hostname'    => 'testhost',
-                                               'port'        => 3306,
-                                               'username'    => 'friendica',
-                                               'password'    => 'a password',
-                                               'database'    => 'database',
-                                       ],
-                                       'config' => [
-                                               'php_path'    => '',
-                                               'hostname'    => 'friendica.local',
-                                               'admin_email' => 'admin@philipp.info',
-                                       ],
-                                       'system' => [
-                                               'urlpath'     => 'test/it',
-                                               'url'         => 'http://friendica.local/test/it',
-                                               'basepath'    => '',
-                                               'ssl_policy'  => '2',
-                                               'default_timezone' => 'en',
-                                               'language'    => 'Europe/Berlin',
-                                       ],
-                               ],
-                       ],
-                       'special' => [
-                               'data' => [
-                                       'database' => [
-                                               'hostname'    => 'testhost.new.domain',
-                                               'port'        => 3341,
-                                               'username'    => 'fr"§%ica',
-                                               'password'    => '$%\"gse',
-                                               'database'    => 'db',
-                                       ],
-                                       'config' => [
-                                               'php_path'    => '',
-                                               'hostname'    => 'friendica.local',
-                                               'admin_email' => 'admin@philipp.info',
-                                       ],
-                                       'system' => [
-                                               'urlpath'     => 'test/it',
-                                               'url'         => 'https://friendica.local/test/it',
-                                               'basepath'    => '',
-                                               'ssl_policy'  => '1',
-                                               'default_timezone' => 'en',
-                                               'language'    => 'Europe/Berlin',
-                                       ],
-                               ],
-                       ],
-               ];
-       }
-
-       private function assertFinished($txt, $withconfig = false, $copyfile = false)
-       {
-               $cfg = '';
-
-               if ($withconfig) {
-                       $cfg = <<<CFG
-
-
-Creating config file...
-
- Complete!
-CFG;
-               }
-
-               if ($copyfile) {
-                       $cfg = <<<CFG
-
-
-Copying config file...
-
- Complete!
-CFG;
-               }
-
-               $finished = <<<FIN
-Initializing setup...
-
- Complete!
-
-
-Checking environment...
-
- NOTICE: Not checking .htaccess/URL-Rewrite during CLI installation.
-
- Complete!
-{$cfg}
-
-
-Checking database...
-
- Complete!
-
-
-Inserting data into database...
-
- Complete!
-
-
-Installing theme
-
- Complete
-
-
-
-Installation is finished
-
-
-FIN;
-               $this->assertEquals($finished, $txt);
-       }
-
-       private function assertStuckDB($txt)
-       {
-               $finished = <<<FIN
-Initializing setup...
-
- Complete!
-
-
-Checking environment...
-
- NOTICE: Not checking .htaccess/URL-Rewrite during CLI installation.
-
- Complete!
-
-
-Creating config file...
-
- Complete!
-
-
-Checking database...
-
-[Error] --------
-Could not connect to database.: 
-
-
-FIN;
-
-               $this->assertEquals($finished, $txt);
-       }
-
-       private function assertStuckURL($txt)
-       {
-               $finished = <<<FIN
-Initializing setup...
-
- Complete!
-
-
-Checking environment...
-
- NOTICE: Not checking .htaccess/URL-Rewrite during CLI installation.
-
- Complete!
-
-
-Creating config file...
-
-The Friendica URL has to be set during CLI installation.
-
-FIN;
-
-               $this->assertEquals($finished, $txt);
-       }
-
-       /**
-        * Asserts one config entry
-        *
-        * @param string     $cat           The category to test
-        * @param string     $key           The key to test
-        * @param null|array $assertion     The asserted value (null = empty, or array/string)
-        * @param string     $default_value The default value
-        */
-       public function assertConfigEntry($cat, $key, $assertion = null, $default_value = null)
-       {
-               if (!empty($assertion[$cat][$key])) {
-                       $this->assertEquals($assertion[$cat][$key], $this->configCache->get($cat, $key));
-               } elseif (!empty($assertion) && !is_array($assertion)) {
-                       $this->assertEquals($assertion, $this->configCache->get($cat, $key));
-               } elseif (!empty($default_value)) {
-                       $this->assertEquals($default_value, $this->configCache->get($cat, $key));
-               } else {
-                       $this->assertEmpty($this->configCache->get($cat, $key), $this->configCache->get($cat, $key));
-               }
-       }
-
-       /**
-        * Asserts all config entries
-        *
-        * @param null|array $assertion    The optional assertion array
-        * @param boolean    $saveDb       True, if the db credentials should get saved to the file
-        * @param boolean    $default      True, if we use the default values
-        * @param boolean    $defaultDb    True, if we use the default value for the DB
-        * @param boolean    $realBasepath True, if we use the real basepath of the installation, not the mocked one
-        */
-       public function assertConfig($assertion = null, $saveDb = false, $default = true, $defaultDb = true, $realBasepath = false)
-       {
-               if (!empty($assertion['database']['hostname'])) {
-                       $assertion['database']['hostname'] .= (!empty($assertion['database']['port']) ? ':' . $assertion['database']['port'] : '');
-               }
-
-               $this->assertConfigEntry('database', 'hostname', ($saveDb) ? $assertion : null, (!$saveDb || $defaultDb) ? Installer::DEFAULT_HOST : null);
-               $this->assertConfigEntry('database', 'username', ($saveDb) ? $assertion : null);
-               $this->assertConfigEntry('database', 'password', ($saveDb) ? $assertion : null);
-               $this->assertConfigEntry('database', 'database', ($saveDb) ? $assertion : null);
-
-               $this->assertConfigEntry('config', 'admin_email', $assertion);
-               $this->assertConfigEntry('config', 'php_path', trim(shell_exec('which php')));
-               $this->assertConfigEntry('config', 'hostname', $assertion);
-
-               $this->assertConfigEntry('system', 'default_timezone', $assertion, ($default) ? Installer::DEFAULT_TZ : null);
-               $this->assertConfigEntry('system', 'language', $assertion, ($default) ? Installer::DEFAULT_LANG : null);
-               $this->assertConfigEntry('system', 'url', $assertion);
-               $this->assertConfigEntry('system', 'urlpath', $assertion);
-               $this->assertConfigEntry('system', 'ssl_policy', $assertion, ($default) ? BaseURL::DEFAULT_SSL_SCHEME : null);
-               $this->assertConfigEntry('system', 'basepath', ($realBasepath) ? $this->root->url() : $assertion);
-       }
-
-       /**
-        * Test the automatic installation without any parameter/setting
-        * Should stuck because of missing hostname
-        */
-       public function testEmpty()
-       {
-               $console = new AutomaticInstallation($this->consoleArgv);
-
-               $txt = $this->dumpExecute($console);
-
-               $this->assertStuckURL($txt);
-       }
-
-       /**
-        * Test the automatic installation without any parameter/setting
-        * except URL
-        */
-       public function testEmptyWithURL()
-       {
-               $this->mockConnect(true, 1);
-               $this->mockConnected(true, 1);
-               $this->mockExistsTable('user', false, 1);
-               $this->mockUpdate([$this->root->url(), false, true, true], null, 1);
-
-               $this->mockGetMarkupTemplate('local.config.tpl', 'testTemplate', 1);
-               $this->mockReplaceMacros('testTemplate', \Mockery::any(), false, '', 1);
-
-               $console = new AutomaticInstallation($this->consoleArgv);
-               $console->setOption('url', 'http://friendica.local');
-
-               $txt = $this->dumpExecute($console);
-
-               $this->assertFinished($txt, true, false);
-               $this->assertTrue($this->root->hasChild('config' . DIRECTORY_SEPARATOR . 'local.config.php'));
-
-               $this->assertConfig(['config' => ['hostname' => 'friendica.local'], 'system' => ['url' => 'http://friendica.local', 'ssl_policy' => 0, 'urlPath' => '']], false, true, true, true);
-       }
-
-       /**
-        * Test the automatic installation with a prepared config file
-        * @dataProvider dataInstaller
-        */
-       public function testWithConfig(array $data)
-       {
-               $this->mockConnect(true, 1);
-               $this->mockConnected(true, 1);
-               $this->mockExistsTable('user', false, 1);
-               $this->mockUpdate([$this->root->url(), false, true, true], null, 1);
-
-               $conf = function ($cat, $key) use ($data) {
-                       if ($cat == 'database' && $key == 'hostname' && !empty($data['database']['port'])) {
-                               return $data[$cat][$key] . ':' . $data['database']['port'];
-                       }
-                       return $data[$cat][$key];
-               };
-
-               $config = <<<CONF
-<?php
-
-// Local configuration
-
-// If you're unsure about what any of the config keys below do, please check the config/defaults.config.php for detailed
-// documentation of their data type and behavior.
-
-return [
-       'database' => [
-               'hostname' => '{$conf('database', 'hostname')}',
-               'username' => '{$conf('database', 'username')}',
-               'password' => '{$conf('database', 'password')}',
-               'database' => '{$conf('database', 'database')}',
-               'charset' => 'utf8mb4',
-       ],
-
-       // ****************************************************************
-       // The configuration below will be overruled by the admin panel.
-       // Changes made below will only have an effect if the database does
-       // not contain any configuration for the friendica system.
-       // ****************************************************************
-
-       'config' => [
-               'admin_email' => '{$conf('config', 'admin_email')}',
-               'hostname' => '{$conf('config', 'hostname')}',
-               'sitename' => 'Friendica Social Network',
-               'register_policy' => \Friendica\Module\Register::OPEN,
-               'register_text' => '',
-       ],
-       'system' => [
-               'basepath' => '{$conf('system', 'basepath')}',
-               'urlpath' => '{$conf('system', 'urlpath')}',
-               'url' => '{$conf('system', 'url')}',
-               'ssl_policy' => '{$conf('system', 'ssl_policy')}',
-               'default_timezone' => '{$conf('system', 'default_timezone')}',
-               'language' => '{$conf('system', 'language')}',
-       ],
-];
-CONF;
-
-               vfsStream::newFile('prepared.config.php')
-                       ->at($this->root)
-                       ->setContent($config);
-
-               $console = new AutomaticInstallation($this->consoleArgv);
-               $console->setOption('f', 'prepared.config.php');
-
-               $txt = $this->dumpExecute($console);
-
-               $this->assertFinished($txt, false, true);
-
-               $this->assertTrue($this->root->hasChild('config' . DIRECTORY_SEPARATOR . 'local.config.php'));
-               $this->assertEquals($config, file_get_contents($this->root->getChild('config' . DIRECTORY_SEPARATOR . 'local.config.php')->url()));
-
-               $this->assertConfig($data, true, false, false);
-       }
-
-       /**
-        * Test the automatic installation with environment variables
-        * Includes saving the DB credentials to the file
-        * @dataProvider dataInstaller
-        */
-       public function testWithEnvironmentAndSave(array $data)
-       {
-               $this->mockConnect(true, 1);
-               $this->mockConnected(true, 1);
-               $this->mockExistsTable('user', false, 1);
-               $this->mockUpdate([$this->root->url(), false, true, true], null, 1);
-
-               $this->mockGetMarkupTemplate('local.config.tpl', 'testTemplate', 1);
-               $this->mockReplaceMacros('testTemplate', \Mockery::any(), false, '', 1);
-
-               $this->assertTrue(putenv('MYSQL_HOST='     . $data['database']['hostname']));
-               $this->assertTrue(putenv('MYSQL_PORT='     . $data['database']['port']));
-               $this->assertTrue(putenv('MYSQL_DATABASE=' . $data['database']['database']));
-               $this->assertTrue(putenv('MYSQL_USERNAME=' . $data['database']['username']));
-               $this->assertTrue(putenv('MYSQL_PASSWORD=' . $data['database']['password']));
-
-               $this->assertTrue(putenv('FRIENDICA_HOSTNAME='   . $data['config']['hostname']));
-               $this->assertTrue(putenv('FRIENDICA_BASE_PATH='  . $data['system']['basepath']));
-               $this->assertTrue(putenv('FRIENDICA_URL='        . $data['system']['url']));
-               $this->assertTrue(putenv('FRIENDICA_PHP_PATH='   . $data['config']['php_path']));
-               $this->assertTrue(putenv('FRIENDICA_ADMIN_MAIL=' . $data['config']['admin_email']));
-               $this->assertTrue(putenv('FRIENDICA_TZ='         . $data['system']['default_timezone']));
-               $this->assertTrue(putenv('FRIENDICA_LANG='       . $data['system']['language']));
-
-               $console = new AutomaticInstallation($this->consoleArgv);
-               $console->setOption('savedb', true);
-
-               $txt = $this->dumpExecute($console);
-
-               $this->assertFinished($txt, true);
-               $this->assertConfig($data, true, true, false, true);
-       }
-
-       /**
-        * Test the automatic installation with environment variables
-        * Don't save the db credentials to the file
-        * @dataProvider dataInstaller
-        */
-       public function testWithEnvironmentWithoutSave(array $data)
-       {
-               $this->mockConnect(true, 1);
-               $this->mockConnected(true, 1);
-               $this->mockExistsTable('user', false, 1);
-               $this->mockUpdate([$this->root->url(), false, true, true], null, 1);
-
-               $this->mockGetMarkupTemplate('local.config.tpl', 'testTemplate', 1);
-               $this->mockReplaceMacros('testTemplate', \Mockery::any(), false, '', 1);
-
-               $this->assertTrue(putenv('MYSQL_HOST=' . $data['database']['hostname']));
-               $this->assertTrue(putenv('MYSQL_PORT=' . $data['database']['port']));
-               $this->assertTrue(putenv('MYSQL_DATABASE=' . $data['database']['database']));
-               $this->assertTrue(putenv('MYSQL_USERNAME=' . $data['database']['username']));
-               $this->assertTrue(putenv('MYSQL_PASSWORD=' . $data['database']['password']));
-
-               $this->assertTrue(putenv('FRIENDICA_HOSTNAME='   . $data['config']['hostname']));
-               $this->assertTrue(putenv('FRIENDICA_BASE_PATH='  . $data['system']['basepath']));
-               $this->assertTrue(putenv('FRIENDICA_URL='        . $data['system']['url']));
-               $this->assertTrue(putenv('FRIENDICA_PHP_PATH='   . $data['config']['php_path']));
-               $this->assertTrue(putenv('FRIENDICA_ADMIN_MAIL=' . $data['config']['admin_email']));
-               $this->assertTrue(putenv('FRIENDICA_TZ='         . $data['system']['default_timezone']));
-               $this->assertTrue(putenv('FRIENDICA_LANG='       . $data['system']['language']));
-
-               $console = new AutomaticInstallation($this->consoleArgv);
-
-               $txt = $this->dumpExecute($console);
-
-               $this->assertFinished($txt, true);
-               $this->assertConfig($data, false, true, false, true);
-       }
-
-       /**
-        * Test the automatic installation with arguments
-        * @dataProvider dataInstaller
-        */
-       public function testWithArguments(array $data)
-       {
-               $this->mockConnect(true, 1);
-               $this->mockConnected(true, 1);
-               $this->mockExistsTable('user', false, 1);
-               $this->mockUpdate([$this->root->url(), false, true, true], null, 1);
-
-               $this->mockGetMarkupTemplate('local.config.tpl', 'testTemplate', 1);
-               $this->mockReplaceMacros('testTemplate', \Mockery::any(), false, '', 1);
-
-               $console = new AutomaticInstallation($this->consoleArgv);
-
-               $option = function($var, $cat, $key) use ($data, $console) {
-                       if (!empty($data[$cat][$key])) {
-                               $console->setOption($var, $data[$cat][$key]);
-                       }
-               };
-               $option('dbhost'    , 'database', 'hostname');
-               $option('dbport'    , 'database', 'port');
-               $option('dbuser'    , 'database', 'username');
-               $option('dbpass'    , 'database', 'password');
-               $option('dbdata'    , 'database', 'database');
-               $option('url'       , 'system'  , 'url');
-               $option('phppath'   , 'config'  , 'php_path');
-               $option('admin'     , 'config'  , 'admin_email');
-               $option('tz'        , 'system'  , 'default_timezone');
-               $option('lang'      , 'system'  , 'language');
-               $option('basepath'  , 'system'  , 'basepath');
-
-               $txt = $this->dumpExecute($console);
-
-               $this->assertFinished($txt, true);
-               $this->assertConfig($data, true, true, true, true);
-       }
-
-       /**
-        * Test the automatic installation with a wrong database connection
-        */
-       public function testNoDatabaseConnection()
-       {
-               $this->mockConnect(false, 1);
-
-               $this->mockGetMarkupTemplate('local.config.tpl', 'testTemplate', 1);
-               $this->mockReplaceMacros('testTemplate', \Mockery::any(), false, '', 1);
-
-               $console = new AutomaticInstallation($this->consoleArgv);
-               $console->setOption('url', 'http://friendica.local');
-
-               $txt = $this->dumpExecute($console);
-
-               $this->assertStuckDB($txt);
-               $this->assertTrue($this->root->hasChild('config' . DIRECTORY_SEPARATOR . 'local.config.php'));
-
-               $this->assertConfig(['config' => ['hostname' => 'friendica.local'], 'system' => ['url' => 'http://friendica.local', 'ssl_policy' => 0, 'urlpath' => '']], false, true, false, true);
-       }
-
-       public function testGetHelp()
-       {
-               // Usable to purposely fail if new commands are added without taking tests into account
-               $theHelp = <<<HELP
-Installation - Install Friendica automatically
-Synopsis
-       bin/console autoinstall [-h|--help|-?] [-v] [-a] [-f]
-
-Description
-    Installs Friendica with data based on the local.config.php file or environment variables
-
-Notes
-    Not checking .htaccess/URL-Rewrite during CLI installation.
-
-Options
-    -h|--help|-?            Show help information
-    -v                      Show more debug information.
-    -a                      All setup checks are required (except .htaccess)
-    -f|--file <config>      prepared config file (e.g. "config/local.config.php" itself) which will override every other config option - except the environment variables)
-    -s|--savedb               Save the DB credentials to the file (if environment variables is used)
-    -H|--dbhost <host>        The host of the mysql/mariadb database (env MYSQL_HOST)
-    -p|--dbport <port>        The port of the mysql/mariadb database (env MYSQL_PORT)
-    -d|--dbdata <database>    The name of the mysql/mariadb database (env MYSQL_DATABASE)
-    -U|--dbuser <username>    The username of the mysql/mariadb database login (env MYSQL_USER or MYSQL_USERNAME)
-    -P|--dbpass <password>    The password of the mysql/mariadb database login (env MYSQL_PASSWORD)
-    -U|--url <url>            The full base URL of Friendica - f.e. 'https://friendica.local/sub' (env FRIENDICA_URL) 
-    -B|--phppath <php_path>   The path of the PHP binary (env FRIENDICA_PHP_PATH)
-    -b|--basepath <base_path> The basepath of Friendica (env FRIENDICA_BASE_PATH)
-    -t|--tz <timezone>        The timezone of Friendica (env FRIENDICA_TZ)
-    -L|--lang <language>      The language of Friendica (env FRIENDICA_LANG)
-Environment variables
-   MYSQL_HOST                  The host of the mysql/mariadb database (mandatory if mysql and environment is used)
-   MYSQL_PORT                  The port of the mysql/mariadb database
-   MYSQL_USERNAME|MYSQL_USER   The username of the mysql/mariadb database login (MYSQL_USERNAME is for mysql, MYSQL_USER for mariadb)
-   MYSQL_PASSWORD              The password of the mysql/mariadb database login
-   MYSQL_DATABASE              The name of the mysql/mariadb database
-   FRIENDICA_URL               The full base URL of Friendica - f.e. 'https://friendica.local/sub'
-   FRIENDICA_PHP_PATH          The path of the PHP binary - leave empty for auto detection
-   FRIENDICA_BASE_PATH         The basepath of Friendica - leave empty for auto detection
-   FRIENDICA_ADMIN_MAIL        The admin email address of Friendica (this email will be used for admin access)
-   FRIENDICA_TZ                The timezone of Friendica
-   FRIENDICA_LANG              The langauge of Friendica
-   
-Examples
-       bin/console autoinstall -f 'input.config.php
-               Installs Friendica with the prepared 'input.config.php' file
-
-       bin/console autoinstall --savedb
-               Installs Friendica with environment variables and saves them to the 'config/local.config.php' file
-
-       bin/console autoinstall -h localhost -p 3365 -U user -P passwort1234 -d friendica
-               Installs Friendica with a local mysql database with credentials
-
-HELP;
-
-               $console = new AutomaticInstallation($this->consoleArgv);
-               $console->setOption('help', true);
-
-               $txt = $this->dumpExecute($console);
-
-               $this->assertEquals($theHelp, $txt);
-       }
-}
diff --git a/tests/src/Core/Console/ConfigConsoleTest.php b/tests/src/Core/Console/ConfigConsoleTest.php
deleted file mode 100644 (file)
index c58b05e..0000000
+++ /dev/null
@@ -1,193 +0,0 @@
-<?php
-
-namespace Friendica\Test\src\Core\Console;
-
-use Friendica\App\Mode;
-use Friendica\Core\Console\Config;
-
-/**
- * @runTestsInSeparateProcesses
- * @preserveGlobalState disabled
- * @requires PHP 7.0
- */
-class ConfigConsoleTest extends ConsoleTest
-{
-       protected function setUp()
-       {
-               parent::setUp();
-
-               $this->mockApp($this->root);
-
-               \Mockery::getConfiguration()->setConstantsMap([
-                       Mode::class => [
-                               'DBCONFIGAVAILABLE' => 0
-                       ]
-               ]);
-
-               $this->mode
-                       ->shouldReceive('has')
-                       ->andReturn(true);
-
-       }
-
-       function testSetGetKeyValue() {
-               $this->configMock
-                       ->shouldReceive('set')
-                       ->with('config', 'test', 'now')
-                       ->andReturn(true)
-                       ->once();
-               $this->configMock
-                       ->shouldReceive('get')
-                       ->with('config', 'test')
-                       ->andReturn('now')
-                       ->twice();
-
-               $console = new Config($this->consoleArgv);
-               $console->setArgument(0, 'config');
-               $console->setArgument(1, 'test');
-               $console->setArgument(2, 'now');
-               $txt = $this->dumpExecute($console);
-               $this->assertEquals("config.test <= now\n", $txt);
-
-               $this->configMock
-                       ->shouldReceive('get')
-                       ->with('config', 'test')
-                       ->andReturn('now')
-                       ->once();
-
-               $console = new Config($this->consoleArgv);
-               $console->setArgument(0, 'config');
-               $console->setArgument(1, 'test');
-               $txt = $this->dumpExecute($console);
-               $this->assertEquals("config.test => now\n", $txt);
-
-               $this->configMock
-                       ->shouldReceive('get')
-                       ->with('config', 'test')
-                       ->andReturn(null)
-                       ->once();
-
-               $console = new Config($this->consoleArgv);
-               $console->setArgument(0, 'config');
-               $console->setArgument(1, 'test');
-               $txt = $this->dumpExecute($console);
-               $this->assertEquals("config.test => \n", $txt);
-       }
-
-       function testSetArrayValue() {
-               $testArray = [1, 2, 3];
-               $this->configMock
-                       ->shouldReceive('get')
-                       ->with('config', 'test')
-                       ->andReturn($testArray)
-                       ->once();
-
-               $console = new Config($this->consoleArgv);
-               $console->setArgument(0, 'config');
-               $console->setArgument(1, 'test');
-               $console->setArgument(2, 'now');
-               $txt = $this->dumpExecute($console);
-
-               $this->assertEquals("[Error] config.test is an array and can't be set using this command.\n", $txt);
-       }
-
-       function testTooManyArguments() {
-               $console = new Config($this->consoleArgv);
-               $console->setArgument(0, 'config');
-               $console->setArgument(1, 'test');
-               $console->setArgument(2, 'it');
-               $console->setArgument(3, 'now');
-               $txt = $this->dumpExecute($console);
-               $assertion = '[Warning] Too many arguments';
-               $firstline = substr($txt, 0, strlen($assertion));
-               $this->assertEquals($assertion, $firstline);
-       }
-
-       function testVerbose() {
-               $this->configMock
-                       ->shouldReceive('get')
-                       ->with('test', 'it')
-                       ->andReturn('now')
-                       ->once();
-               $console = new Config($this->consoleArgv);
-               $console->setArgument(0, 'test');
-               $console->setArgument(1, 'it');
-               $console->setOption('v', 1);
-               $executable = $this->consoleArgv[0];
-               $assertion = <<<CONF
-Executable: {$executable}
-Class: Friendica\Core\Console\Config
-Arguments: array (
-  0 => 'test',
-  1 => 'it',
-)
-Options: array (
-  'v' => 1,
-)
-test.it => now
-
-CONF;
-               $txt = $this->dumpExecute($console);
-               $this->assertEquals($assertion, $txt);
-       }
-
-       function testUnableToSet() {
-               $this->configMock
-                       ->shouldReceive('set')
-                       ->with('test', 'it', 'now')
-                       ->andReturn(false)
-                       ->once();
-               $this->configMock
-                       ->shouldReceive('get')
-                       ->with('test', 'it')
-                       ->andReturn(NULL)
-                       ->once();
-               $console = new Config();
-               $console->setArgument(0, 'test');
-               $console->setArgument(1, 'it');
-               $console->setArgument(2, 'now');
-               $txt = $this->dumpExecute($console);
-               $this->assertSame("Unable to set test.it\n", $txt);
-       }
-
-       public function testGetHelp()
-       {
-               // Usable to purposely fail if new commands are added without taking tests into account
-               $theHelp = <<<HELP
-console config - Manage site configuration
-Synopsis
-       bin/console config [-h|--help|-?] [-v]
-       bin/console config <category> [-h|--help|-?] [-v]
-       bin/console config <category> <key> [-h|--help|-?] [-v]
-       bin/console config <category> <key> <value> [-h|--help|-?] [-v]
-
-Description
-       bin/console config
-               Lists all config values
-
-       bin/console config <category>
-               Lists all config values in the provided category
-
-       bin/console config <category> <key>
-               Shows the value of the provided key in the category
-
-       bin/console config <category> <key> <value>
-               Sets the value of the provided key in the category
-
-Notes:
-       Setting config entries which are manually set in config/local.config.php may result in
-       conflict between database settings and the manual startup settings.
-
-Options
-    -h|--help|-? Show help information
-    -v           Show more debug information.
-
-HELP;
-               $console = new Config($this->consoleArgv);
-               $console->setOption('help', true);
-
-               $txt = $this->dumpExecute($console);
-
-               $this->assertEquals($txt, $theHelp);
-       }
-}
diff --git a/tests/src/Core/Console/ConsoleTest.php b/tests/src/Core/Console/ConsoleTest.php
deleted file mode 100644 (file)
index e142e60..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-<?php
-
-namespace Friendica\Test\src\Core\Console;
-
-use Asika\SimpleConsole\Console;
-use Friendica\Test\MockedTest;
-use Friendica\Test\Util\AppMockTrait;
-use Friendica\Test\Util\Intercept;
-use Friendica\Test\Util\VFSTrait;
-
-abstract class ConsoleTest extends MockedTest
-{
-       use VFSTrait;
-       use AppMockTrait;
-
-       /**
-        * @var array The default argv for a Console Instance
-        */
-       protected $consoleArgv = [ 'consoleTest.php' ];
-
-       protected function setUp()
-       {
-               parent::setUp();
-
-               Intercept::setUp();
-
-               $this->setUpVfsDir();
-       }
-
-       /**
-        * Dumps the execution of an console output to a string and returns it
-        *
-        * @param Console $console The current console instance
-        *
-        * @return string the output of the execution
-        */
-       protected function dumpExecute($console)
-       {
-               Intercept::reset();
-               $console->execute();
-               $returnStr = Intercept::$cache;
-               Intercept::reset();
-
-               return $returnStr;
-       }
-}
diff --git a/tests/src/Core/Console/ServerBlockConsoleTest.php b/tests/src/Core/Console/ServerBlockConsoleTest.php
deleted file mode 100644 (file)
index 512a416..0000000
+++ /dev/null
@@ -1,337 +0,0 @@
-<?php
-
-namespace Friendica\Test\src\Core\Console;
-
-use Friendica\Core\Console\ServerBlock;
-
-/**
- * @runTestsInSeparateProcesses
- * @preserveGlobalState disabled
- */
-class ServerBlockConsoleTest extends ConsoleTest
-{
-       protected $defaultBlockList = [
-               [
-                       'domain' => 'social.nobodyhasthe.biz',
-                       'reason' => 'Illegal content',
-               ],
-               [
-                       'domain' => 'pod.ordoevangelistarum.com',
-                       'reason' => 'Illegal content',
-               ]
-       ];
-
-       protected function setUp()
-       {
-               parent::setUp();
-
-               $this->mockApp($this->root);
-       }
-
-       /**
-        * Test to list the default blocked servers
-        */
-       public function testBlockedServersList()
-       {
-               $this->configMock
-                       ->shouldReceive('get')
-                       ->with('system', 'blocklist')
-                       ->andReturn($this->defaultBlockList)
-                       ->once();
-
-               $console = new ServerBlock($this->consoleArgv);
-               $txt = $this->dumpExecute($console);
-
-               $output = <<<CONS
-+----------------------------+-----------------+
-| Domain                     | Reason          |
-+----------------------------+-----------------+
-| social.nobodyhasthe.biz    | Illegal content |
-| pod.ordoevangelistarum.com | Illegal content |
-+----------------------------+-----------------+
-
-
-CONS;
-
-               $this->assertEquals($output, $txt);
-       }
-
-       /**
-        * Test blockedservers add command
-        */
-       public function testAddBlockedServer()
-       {
-               $this->configMock
-                       ->shouldReceive('get')
-                       ->with('system', 'blocklist')
-                       ->andReturn($this->defaultBlockList)
-                       ->once();
-
-               $newBlockList = $this->defaultBlockList;
-               $newBlockList[] = [
-                       'domain' => 'testme.now',
-                       'reason' => 'I like it!',
-               ];
-
-               $this->configMock
-                       ->shouldReceive('set')
-                       ->with('system', 'blocklist', $newBlockList)
-                       ->andReturn(true)
-                       ->once();
-
-               $console = new ServerBlock($this->consoleArgv);
-               $console->setArgument(0, 'add');
-               $console->setArgument(1, 'testme.now');
-               $console->setArgument(2, 'I like it!');
-               $txt = $this->dumpExecute($console);
-
-               $this->assertEquals('The domain \'testme.now\' is now blocked. (Reason: \'I like it!\')' . PHP_EOL, $txt);
-       }
-
-       /**
-        * Test blockedservers add command with the default reason
-        */
-       public function testAddBlockedServerWithDefaultReason()
-       {
-               $this->configMock
-                       ->shouldReceive('get')
-                       ->with('system', 'blocklist')
-                       ->andReturn($this->defaultBlockList)
-                       ->once();
-
-               $newBlockList = $this->defaultBlockList;
-               $newBlockList[] = [
-                       'domain' => 'testme.now',
-                       'reason' => ServerBlock::DEFAULT_REASON,
-               ];
-
-               $this->configMock
-                       ->shouldReceive('set')
-                       ->with('system', 'blocklist', $newBlockList)
-                       ->andReturn(true)
-                       ->once();
-
-               $console = new ServerBlock($this->consoleArgv);
-               $console->setArgument(0, 'add');
-               $console->setArgument(1, 'testme.now');
-               $txt = $this->dumpExecute($console);
-
-               $this->assertEquals('The domain \'testme.now\' is now blocked. (Reason: \'' . ServerBlock::DEFAULT_REASON . '\')' . PHP_EOL, $txt);
-       }
-
-       /**
-        * Test blockedservers add command on existed domain
-        */
-       public function testUpdateBlockedServer()
-       {
-               $this->configMock
-                       ->shouldReceive('get')
-                       ->with('system', 'blocklist')
-                       ->andReturn($this->defaultBlockList)
-                       ->once();
-
-               $newBlockList = [
-                       [
-                               'domain' => 'social.nobodyhasthe.biz',
-                               'reason' => 'Illegal content',
-                       ],
-                       [
-                               'domain' => 'pod.ordoevangelistarum.com',
-                               'reason' => 'Other reason',
-                       ]
-               ];
-
-               $this->configMock
-                       ->shouldReceive('set')
-                       ->with('system', 'blocklist', $newBlockList)
-                       ->andReturn(true)
-                       ->once();
-
-               $console = new ServerBlock($this->consoleArgv);
-               $console->setArgument(0, 'add');
-               $console->setArgument(1, 'pod.ordoevangelistarum.com');
-               $console->setArgument(2, 'Other reason');
-               $txt = $this->dumpExecute($console);
-
-               $this->assertEquals('The domain \'pod.ordoevangelistarum.com\' is now updated. (Reason: \'Other reason\')' . PHP_EOL, $txt);
-       }
-
-       /**
-        * Test blockedservers remove command
-        */
-       public function testRemoveBlockedServer()
-       {
-               $this->configMock
-                       ->shouldReceive('get')
-                       ->with('system', 'blocklist')
-                       ->andReturn($this->defaultBlockList)
-                       ->once();
-
-               $newBlockList = [
-                       [
-                               'domain' => 'social.nobodyhasthe.biz',
-                               'reason' => 'Illegal content',
-                       ],
-               ];
-
-               $this->configMock
-                       ->shouldReceive('set')
-                       ->with('system', 'blocklist', $newBlockList)
-                       ->andReturn(true)
-                       ->once();
-
-               $console = new ServerBlock($this->consoleArgv);
-               $console->setArgument(0, 'remove');
-               $console->setArgument(1, 'pod.ordoevangelistarum.com');
-               $txt = $this->dumpExecute($console);
-
-               $this->assertEquals('The domain \'pod.ordoevangelistarum.com\' is not more blocked' . PHP_EOL, $txt);
-       }
-
-       /**
-        * Test blockedservers with a wrong command
-        */
-       public function testBlockedServersWrongCommand()
-       {
-               $console = new ServerBlock($this->consoleArgv);
-               $console->setArgument(0, 'wrongcommand');
-               $txt = $this->dumpExecute($console);
-
-               $this->assertStringStartsWith('[Warning] Unknown command', $txt);
-       }
-
-       /**
-        * Test blockedservers remove with not existing domain
-        */
-       public function testRemoveBlockedServerNotExist()
-       {
-               $this->configMock
-                       ->shouldReceive('get')
-                       ->with('system', 'blocklist')
-                       ->andReturn($this->defaultBlockList)
-                       ->once();
-
-               $console = new ServerBlock($this->consoleArgv);
-               $console->setArgument(0, 'remove');
-               $console->setArgument(1, 'not.exiting');
-               $txt = $this->dumpExecute($console);
-
-               $this->assertEquals('The domain \'not.exiting\' is not blocked.' . PHP_EOL, $txt);
-       }
-
-       /**
-        * Test blockedservers add command without argument
-        */
-       public function testAddBlockedServerMissingArgument()
-       {
-               $console = new ServerBlock($this->consoleArgv);
-               $console->setArgument(0, 'add');
-               $txt = $this->dumpExecute($console);
-
-               $this->assertStringStartsWith('[Warning] Add needs a domain and optional a reason.', $txt);
-       }
-
-       /**
-        * Test blockedservers add command without save
-        */
-       public function testAddBlockedServerNoSave()
-       {
-               $this->configMock
-                       ->shouldReceive('get')
-                       ->with('system', 'blocklist')
-                       ->andReturn($this->defaultBlockList)
-                       ->once();
-
-               $newBlockList = $this->defaultBlockList;
-               $newBlockList[] = [
-                       'domain' => 'testme.now',
-                       'reason' => ServerBlock::DEFAULT_REASON,
-               ];
-
-               $this->configMock
-                       ->shouldReceive('set')
-                       ->with('system', 'blocklist', $newBlockList)
-                       ->andReturn(false)
-                       ->once();
-
-               $console = new ServerBlock($this->consoleArgv);
-               $console->setArgument(0, 'add');
-               $console->setArgument(1, 'testme.now');
-               $txt = $this->dumpExecute($console);
-
-               $this->assertEquals('Couldn\'t save \'testme.now\' as blocked server' . PHP_EOL, $txt);
-       }
-
-       /**
-        * Test blockedservers remove command without save
-        */
-       public function testRemoveBlockedServerNoSave()
-       {
-               $this->configMock
-                       ->shouldReceive('get')
-                       ->with('system', 'blocklist')
-                       ->andReturn($this->defaultBlockList)
-                       ->once();
-
-               $newBlockList = [
-                       [
-                               'domain' => 'social.nobodyhasthe.biz',
-                               'reason' => 'Illegal content',
-                       ],
-               ];
-
-               $this->configMock
-                       ->shouldReceive('set')
-                       ->with('system', 'blocklist', $newBlockList)
-                       ->andReturn(false)
-                       ->once();
-
-               $console = new ServerBlock($this->consoleArgv);
-               $console->setArgument(0, 'remove');
-               $console->setArgument(1, 'pod.ordoevangelistarum.com');
-               $txt = $this->dumpExecute($console);
-
-               $this->assertEquals('Couldn\'t remove \'pod.ordoevangelistarum.com\' from blocked servers' . PHP_EOL, $txt);
-       }
-
-       /**
-        * Test blockedservers remove command without argument
-        */
-       public function testRemoveBlockedServerMissingArgument()
-       {
-               $console = new ServerBlock($this->consoleArgv);
-               $console->setArgument(0, 'remove');
-               $txt = $this->dumpExecute($console);
-
-               $this->assertStringStartsWith('[Warning] Remove needs a second parameter.', $txt);
-       }
-
-       /**
-        * Test the blockedservers help
-        */
-       public function testBlockedServersHelp()
-       {
-               $console = new ServerBlock($this->consoleArgv);
-               $console->setOption('help', true);
-               $txt = $this->dumpExecute($console);
-
-               $help = <<<HELP
-console serverblock - Manage blocked servers
-Usage
-       bin/console serverblock [-h|--help|-?] [-v]
-       bin/console serverblock add <server> <reason> [-h|--help|-?] [-v]
-       bin/console serverblock remove <server> [-h|--help|-?] [-v]
-
-Description
-       With this tool, you can list the current blocked servers
-    or you can add / remove a blocked server from the list
-
-Options
-    -h|--help|-? Show help information
-    -v           Show more debug information.
-
-HELP;
-
-               $this->assertEquals($help, $txt);
-       }
-}