Move Console namespace one level up

This commit is contained in:
Philipp Holzer 2019-05-02 23:17:35 +02:00
parent 2628da422a
commit d716a3326f
No known key found for this signature in database
GPG key ID: 517BE60E2CE5C8A5
23 changed files with 46 additions and 44 deletions

View 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()

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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');
}
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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 [];
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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]);
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}
}

View file

@ -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));
}
}

View file

@ -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.');
}
}
}