Use laravel/eloquent in Settings class, update related files and classes

This commit is contained in:
DariusIII
2017-06-28 09:03:51 +02:00
parent d1460a4617
commit a66032e668
8 changed files with 212 additions and 312 deletions
+1 -6
View File
@@ -1,12 +1,7 @@
<?php
/**
* Lithium: the most rad php framework
*
* @copyright Copyright 2015, Union of RAD (http://union-of-rad.org)
* @license http://opensource.org/licenses/bsd-license.php The BSD License
*/
require_once dirname(dirname(__DIR__)) . DIRECTORY_SEPARATOR . 'nntmux' . DIRECTORY_SEPARATOR . 'constants.php';
require_once dirname(dirname(__DIR__)) . DIRECTORY_SEPARATOR . 'configuration' . DIRECTORY_SEPARATOR . 'database.php';
/**
* This is the primary bootstrap file of your application, and is loaded immediately after the front
+51 -139
View File
@@ -1,42 +1,19 @@
<?php
/**
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program (see LICENSE.txt in the base directory. If
* not, see:
*
* @link <http://www.gnu.org/licenses/>.
* @author niel
* @copyright 2016 nZEDb
* Created by PhpStorm.
* User: darius
* Date: 19.6.17.
* Time: 15.17
*/
namespace app\extensions\command;
use app\extensions\console\Command;
use \app\extensions\util\Git;
use \app\extensions\util\Versions;
use \lithium\console\command\Help;
use \nntmux\db\DbUpdate;
use \Smarty;
use app\extensions\util\Git;
use app\extensions\util\Versions;
use nntmux\db\DbUpdate;
use Symfony\Component\Process\Process;
/**
* Update various aspects of your indexer.
*
* Actions:
* * all|nntmux Fetches current git repo, composer dependencies, and update latest Db patches.
* * db Update the Db with any patches not yet applied.
* * git Performs git pull.
* * predb Fetch and import TSV files into the predb table.
*
*@package app\extensions\command
*/
class Update extends Command
{
const UPDATES_FILE = NN_CONFIGS . 'updates.json';
@@ -53,22 +30,24 @@ class Update extends Command
private $gitBranch;
private $gitTag;
/**
* Constructor.
* NewUpdate constructor.
*
* @param array $config
*/
public function __construct(array $config = [])
public function __construct()
{
$defaults = [
'classes' => $this->_classes,
'git' => null,
'request' => null,
'response' => [],
];
parent::__construct($config + $defaults);
$this->setName('Update')
->setHelp('This function is used to update nntmux. Run it by typing: php tmux update and then nntmux or db as second argument. ie: php tmux update nntmux');
parent::__construct($defaults);
}
public function all()
@@ -80,7 +59,7 @@ class Update extends Command
{
// TODO Add check to determine if the indexer or other scripts are running. Hopefully
// also prevent web access.
$this->out('Checking database version...', 'primary');
$this->primary('Checking database version');
$versions = new Versions(['git' => ($this->git instanceof Git) ? $this->git : null]);
@@ -88,17 +67,18 @@ class Update extends Command
$currentDb = $versions->getSQLPatchFromDB();
$currentXML = $versions->getSQLPatchFromFile();
} catch (\PDOException $e) {
$this->out('Error fetching patch versions!', 'error');
$this->error('Error fetching patch versions!');
return 1;
}
$this->out("Db: $currentDb,\tFile: $currentXML");
$this->primary("Db: $currentDb,\tFile: $currentXML");
if ($currentDb < $currentXML) {
$db = new DbUpdate(['backup' => false]);
$db->processPatches(['safe' => false]);
} else {
$this->out('Up to date.', 'info');
$this->primary('Up to date.');
}
}
@@ -108,11 +88,12 @@ class Update extends Command
// also prevent web access.
$this->initialiseGit();
if (!in_array($this->git->getBranch(), $this->git->getBranchesMain(), false)) {
$this->out('Not on the stable or dev branch! Refusing to update repository', 'error');
$this->error('Not on the stable or dev branch! Refusing to update repository');
return;
}
$this->out($this->git->pull());
$this->primary($this->git->pull());
}
/**
@@ -123,67 +104,37 @@ class Update extends Command
try {
$output = $this->git();
if ($output === 'Already up-to-date.') {
$this->out($output, 'info');
$this->primary($output);
} else {
$status = $this->composer();
if ($status) {
$this->out('Composer failed to update!!', 'error');
$this->error('Composer failed to update!!');
return false;
} else {
$fail = $this->db();
if ($fail) {
$this->out('Db updating failed!!', 'error');
return 1;
}
$fail = $this->db();
if ($fail) {
$this->error('Db updating failed!!');
return 1;
}
};
}
$this->scripts();
$smarty = new Smarty();
$smarty = new \Smarty();
$smarty->setCompileDir(NN_SMARTY_TEMPLATES);
$cleared = $smarty->clearCompiledTemplate();
if ($cleared) {
$this->out('The Smarty compiled template cache has been cleaned for you', 'primary');
$this->primary('The Smarty compiled template cache has been cleaned for you');
} else {
$this->out('You should clear your Smarty compiled template cache at: ' .
NN_RES . 'smarty' . DS . 'templates_c',
'primary');
$this->primary('You should clear your Smarty compiled template cache at: ' .
NN_RES . 'smarty' . DS . 'templates_c'
);
}
} catch (\Exception $e) {
$this->error($e->getMessage());
}
}
/**
* Import/Update the predb table using tab separated value files.
*/
public function predb()
{
$this->out('predb not available yet!', 'error');
}
public function run($command = null)
{
if (!$command || !$this->request->args()) {
return $this->_help($command);
}
if (!$command) {
return $this->_help($command);
}
if ($this->_execute($command)) {
return true;
}
$this->error("{$command} could not be created.");
return false;
}
/**
* Issues the command to 'install' the composer package.
*
@@ -191,19 +142,27 @@ class Update extends Command
* option is added to the command to prevent development packages being also downloded.
*
* @return integer Return status from Composer.
* @throws \Symfony\Component\Process\Exception\LogicException
* @throws \Symfony\Component\Process\Exception\RuntimeException
*/
protected function composer()
{
$this->initialiseGit();
$command = 'composer install';
if (in_array($this->gitBranch, $this->git->getBranchesStable())) {
if (in_array($this->gitBranch, $this->git->getBranchesStable(), false)) {
$command .= ' --prefer-dist --no-dev';
} else {
$command .= ' --prefer-source';
}
$this->out('Running composer install process...', 'primary');
system($command, $status);
return $status;
$this->primary('Running composer install process...');
$process = new Process($command);
$process->run(function ($type, $buffer){
if (Process::ERR === $type) {
echo $buffer;
}
});
return $process->getOutput();
}
protected function initialiseGit()
@@ -212,51 +171,4 @@ class Update extends Command
$this->git = new Git();
}
}
/**
* Invokes the `Help` command.
* The invoked Help command will take over request and response objects of
* the originally invoked command. Thus the response of the Help command
* becomes the response of the original one.
*
* @return boolean
*/
protected function _help()
{
$help = new Help([
'request' => $this->request,
'response' => $this->response,
'classes' => $this->_classes
]);
return $help->run(get_class($this));
}
/**
* Class initializer. Parses template and sets up params that need to be filled.
*
* @return void
*/
protected function _init()
{
parent::_init();
if ($this->_config['git'] instanceof Git) {
$this->git =& $this->_config['git'];
}
if (file_exists(self::UPDATES_FILE)) {
$this->updates = json_decode(file_get_contents(self::UPDATES_FILE), true);
}
}
/**
* Fetches and executes scripts for customised updating tasks.
*/
protected function scripts()
{
if (![$this->updates]) {
$this->updates = ['script' => '0000-00-00 00:00:00'];
}
}
}
}
+2 -38
View File
@@ -42,49 +42,13 @@ class Verify extends \app\extensions\console\Command
'request' => null,
'response' => [],
];
$this->setName('verify')
->setHelp('This function is used to verify that settings table is properly populated');
parent::__construct($config + $defaults);
}
public function run()
{
if (!$this->request->args()) {
return $this->_help();
}
return false;
}
public function settingstable()
{
$dummy = Settings::hasAllEntries($this);
}
/**
* Invokes the `Help` command.
* The invoked Help command will take over request and response objects of
* the originally invoked command. Thus the response of the Help command
* becomes the response of the original one.
*
* @return boolean
*/
protected function _help()
{
$help = new Help([
'request' => $this->request,
'response' => $this->response,
'classes' => $this->_classes
]);
return $help->run(get_class($this));
}
/**
* Class initializer. Parses template and sets up params that need to be filled.
*
* @return void
*/
protected function _init()
{
parent::_init();
}
}
+24 -11
View File
@@ -20,35 +20,48 @@
*/
namespace app\extensions\console;
use Symfony\Component\Console\Output\ConsoleOutput;
use lithium\data\DocumentSchema;
class Command extends \lithium\console\Command
class Command extends \Illuminate\Console\Command
{
protected $_classes = [
'response' => 'app\extensions\console\Response'
'response' => Response::class
];
/**
* Command constructor.
*
* @param array $config
*/
public function __construct(array $config = array())
{
$defaults = ['request' => null, 'response' => [], 'classes' => $this->_classes];
parent::__construct($config + $defaults);
$this->setName('command');
parent::__construct();
$this->output = new ConsoleOutput();
}
public function info($text)
public function info($text, $verbosity = null)
{
if ($this->silent) {
if ($this->output->isQuiet()) {
return;
}
$this->out($text, 'info');
$this->output->writeln('<info>' . $text . '</info>', $verbosity);
}
public function primary($text)
{
if ($this->silent) {
if ($this->output->isQuiet()) {
return;
}
$this->out($text, 'primary');
$this->output->writeln('<comment>' . $text . '</comment>');
}
public function error($text, $verbosity = null)
{
if ($this->output->isQuiet()) {
return;
}
$this->output->writeln('<error>' . $text . '</error>', $verbosity);
}
}
?>
+23 -25
View File
@@ -19,9 +19,10 @@
namespace app\extensions\util;
use app\models\Settings;
use lithium\core\Object;
use nntmux\utility\Utility;
class Versions extends \lithium\core\Object
class Versions extends Object
{
/**
* These constants are bitwise for checking what has changed.
@@ -36,7 +37,7 @@ class Versions extends \lithium\core\Object
protected $changes = 0;
/**
* @var \app\extensions\util\Git object.
* @var Git object.
*/
protected $git;
@@ -69,7 +70,9 @@ class Versions extends \lithium\core\Object
* Checks the git's latest version tag against the XML's stored value. Version should be
* Major.Minor.Revision[.fix][-dev|-RCx]
*
* @return string|false version string if matched or false.
* @param bool $update
*
* @return false|string version string if matched or false.
*/
public function checkGitTagInFile($update = false)
{
@@ -140,7 +143,7 @@ class Versions extends \lithium\core\Object
$this->loadXMLFile();
$patch = $this->getSQLPatchFromDB();
if ($this->versions->sql->db->__toString() != $patch) {
if ($this->versions->sql->db->__toString() !== $patch) {
if ($verbose) {
echo "Updating Db revision to $patch" . PHP_EOL;
}
@@ -156,18 +159,13 @@ class Versions extends \lithium\core\Object
$this->loadXMLFile();
$lastFile = $this->getSQLPatchLast();
if ($lastFile !== false && $this->versions->sql->file->__toString() != $lastFile) {
if ($lastFile !== false && $this->versions->sql->file->__toString() !== $lastFile) {
if ($verbose === true) {
echo "Updating latest patch file to $lastFile" . PHP_EOL;
}
$this->versions->sql->file = $lastFile;
$this->changes |= self::UPDATED_SQL_FILE_LAST;
}
/*
if ($this->versions->sql->file->__toString() != $lastFile) {
$this->versions->sql->file = $lastFile;
$this->changes |= self::UPDATED_SQL_DB_PATCH;
}*/
}
public function getGitBranch()
@@ -199,7 +197,7 @@ class Versions extends \lithium\core\Object
$dbVersion = Settings::value('..sqlpatch', true);
if (!is_numeric($dbVersion)) {
throw new \Exception('Bad sqlpatch value');
throw new \RuntimeException('Bad sqlpatch value');
}
return $dbVersion;
@@ -223,7 +221,7 @@ class Versions extends \lithium\core\Object
$files = Utility::getDirFiles($options);
natsort($files);
return (preg_match($options['regex'], end($files), $matches)) ? (int)$matches['patch'] : false;
return preg_match($options['regex'], end($files), $matches) ? (int)$matches['patch'] : false;
}
public function getTagVersion()
@@ -245,7 +243,7 @@ class Versions extends \lithium\core\Object
*/
public function hasChanged()
{
return $this->changes != 0;
return $this->changes !== 0;
}
public function save($verbose = true)
@@ -253,18 +251,18 @@ class Versions extends \lithium\core\Object
if ($this->hasChanged()) {
if ($verbose === true && $this->changes > 0) {
if ($this->isChanged(self::UPDATED_GIT_TAG)) {
echo "Updated git tag version to " . $this->versions->git->tag . PHP_EOL;
echo 'Updated git tag version to ' . $this->versions->git->tag . PHP_EOL;
}
if ($this->isChanged(self::UPDATED_SQL_DB_PATCH)) {
echo "Updated Db SQL revision to " . $this->versions->sql->db . PHP_EOL;
echo 'Updated Db SQL revision to ' . $this->versions->sql->db . PHP_EOL;
}
if ($this->isChanged(self::UPDATED_SQL_FILE_LAST)) {
echo "Updated latest SQL file to " . $this->versions->sql->file . PHP_EOL;
echo 'Updated latest SQL file to ' . $this->versions->sql->file . PHP_EOL;
}
} else if ($this->changes == 0) {
echo "Version file already up to date." . PHP_EOL;
} else if ($this->changes === 0) {
echo 'Version file already up to date.' . PHP_EOL;
}
$this->xml->asXML($this->_config['path']);
$this->changes = false;
@@ -278,14 +276,14 @@ class Versions extends \lithium\core\Object
protected function initialiseGit()
{
if (!($this->git instanceof \app\extensions\util\Git)) {
$this->git = new \app\extensions\util\Git();
if (!($this->git instanceof Git)) {
$this->git = new Git();
}
}
protected function isChanged($property)
{
return (($this->changes & $property) == $property);
return (($this->changes & $property) === $property);
}
protected function loadXMLFile()
@@ -297,15 +295,15 @@ class Versions extends \lithium\core\Object
if ($this->xml === false) {
$this->error("Your versions XML file ($this->_config['path']) is broken, try updating from git.");
throw new \Exception("Failed to open versions XML file '{$this->_config['path']}'");
throw new \RuntimeException("Failed to open versions XML file '{$this->_config['path']}'");
}
if ($this->xml->count() > 0) {
$vers = $this->xml->xpath('/nntmux/versions');
if ($vers[0]->count() == 0) {
if ($vers[0]->count() === 0) {
$this->error("Your versions XML file ({$this->_config['path']}) does not contain version info, try updating from git.");
throw new \Exception("Failed to find versions node in XML file '{$this->_config['path']}'");
throw new \RuntimeException("Failed to find versions node in XML file '{$this->_config['path']}'");
} else {
$this->versions = &$this->xml->versions; // Create a convenience shortcut
}
@@ -319,7 +317,7 @@ class Versions extends \lithium\core\Object
{
parent::_init();
if ($this->_config['git'] instanceof \app\extensions\util\Git) {
if ($this->_config['git'] instanceof Git) {
$this->git =& $this->_config['git'];
}
}
+61 -91
View File
@@ -19,17 +19,19 @@
namespace app\models;
use Illuminate\Database\Eloquent\Model;
use nntmux\utility\Utility;
use app\extensions\console\Command;
/**
* Settings - model for settings table.
*
* li3 app completely ignore the 'setting' column and only uses 'section', 'subsection', and 'name'
* laravel app completely ignore the 'setting' column and only uses 'section', 'subsection', and 'name'
* for finding values/hints.
*
*@package app\models
*/
class Settings extends \lithium\data\Model
class Settings extends Model
{
const REGISTER_STATUS_OPEN = 0;
@@ -59,55 +61,42 @@ class Settings extends \lithium\data\Model
const ERR_BAD_YYDECODER_PATH = -10;
public $validates = [
'section' => [
[
'required' => false
]
],
'subsection' => [
[
'required' => false
]
],
'name' => [
[
'required' => true
],
[
'notEmpty',
'message' => 'You must supply a name for this setting.'
]
],
'value' => [
[
'required' => true
]
],
'hint' => [
[
'required' => true
],
[
'notEmpty',
'message' => 'You must supply a hint/description for this setting.'
]
],
'setting' => [
[
'required' => true
],
[
'notEmpty',
'message' => 'You must supply a name for this setting.'
]
],
];
/**
* @var Command
*/
protected $console;
/**
* @var array
*/
protected $primaryKey = ['section', 'subsection', 'name'];
protected $_meta = [
'key' => ['section', 'subsection', 'name']
];
/**
* @var string
*/
protected $table = 'settings';
/**
* @var bool
*/
protected $dateFormat = false;
/**
* @var bool
*/
public $timestamps = false;
/**
* @var bool
*/
public $incrementing = false;
/**
* @param Command $console
*
* @return bool
* @throws \Exception
* @throws \InvalidArgumentException
*/
public static function hasAllEntries($console = null)
{
$filepath = Utility::pathCombine(['db', 'schema', 'data', '10-settings.tsv'], NN_RES);
@@ -118,7 +107,7 @@ class Settings extends \lithium\data\Model
if (!is_array($settings)) {
var_dump($settings);
throw new \InvalidArgumentException("Settings is not an array!");
throw new \InvalidArgumentException('Settings is not an array!');
}
$setting = [];
@@ -126,8 +115,9 @@ class Settings extends \lithium\data\Model
$result = false;
if ($dummy !== null) {
if ($console !== null) {
$console->primary("Verifying settings table...");
$console->info("(section, subsection, name):");
$console = new Command();
$console->primary('Verifying settings table...');
$console->info('(section, subsection, name):');
}
$result = true;
foreach ($settings as $line) {
@@ -144,12 +134,12 @@ class Settings extends \lithium\data\Model
true);
if ($value === null) {
$result = false;
$message = "error";
$message = 'error';
}
if ($message != '' && $console !== null) {
$console->out(" {$setting['section']}, {$setting['subsection']}, {$setting['name']}: "
. "MISSING!");
if ($message !== '' && $console !== null) {
$console->error(" {$setting['section']}, {$setting['subsection']}, {$setting['name']}: "
. 'MISSING!');
}
}
}
@@ -157,29 +147,6 @@ class Settings extends \lithium\data\Model
return $result;
}
public static function init()
{
static::finder('setting',
function ($params, $next) {
$params['options']['conditions'] = self::settingToArray($params['options']['conditions']);
$params['type'] = 'first';
$array = array_diff_key(
$params['options'],
array_fill_keys(['conditions', 'fields', 'order', 'limit', 'page'], 0)
);
$params['options'] = array_diff_key($params['options'], $array);
$params['options']['fields'] = ['value', 'hint'];
$result = $next($params);
return $result;
}
);
}
/**
* Return a tree-like array of all or selected settings.
*
@@ -192,8 +159,8 @@ class Settings extends \lithium\data\Model
public static function toTree(array $options = [], $excludeUnsectioned = true)
{
$results = empty($options) ?
Settings::find('all') :
Settings::find('all', $options);
Settings::all():
Settings::all()->find($options);
$tree = [];
if (is_array($results)) {
@@ -205,7 +172,7 @@ class Settings extends \lithium\data\Model
}
} else {
throw new \RuntimeException(
"NO results from Settings table! Check your table has been created and populated."
'NO results from Settings table! Check your table has been created and populated.'
);
}
@@ -217,15 +184,15 @@ class Settings extends \lithium\data\Model
* either the value is passed to Settings::dottedToArray() for conversion. Otherwise the
* value is returned unchanged.
*
* @param $setting Setting array/string to check.
* @param $setting array|bool
*
* @return array|boolean
* @return array|bool
*/
public static function settingToArray($setting)
{
if (!is_array($setting)) {
$setting = self::dottedToArray($setting);
} elseif (count($setting) == 1) {
} elseif (count($setting) === 1) {
$setting = self::dottedToArray($setting[0]);
}
@@ -248,12 +215,17 @@ class Settings extends \lithium\data\Model
*/
public static function value($setting, $returnAlways = false)
{
$result = Settings::find('setting', ['conditions' => $setting, 'fields' => ['value']]);
$setting = self::settingToArray($setting);
$result = Settings::query()->where([
['section', '=', $setting['section']],
['subsection', '=', $setting['subsection']],
['name', '=', $setting['name']]
])->value('value');
if ($result !== false && $result->count() > 0) {
$value = $result->data()[0]['value'];
if ($result !== false) {
$value = $result;
} else if ($returnAlways === false) {
throw new \Exception("Unable to fetch setting from Db!");
throw new \RuntimeException('Unable to fetch setting from Db!');
} else {
$value = null;
}
@@ -288,5 +260,3 @@ class Settings extends \lithium\data\Model
}
}
Settings::init();
+24
View File
@@ -0,0 +1,24 @@
<?php
require_once dirname(__DIR__) . DIRECTORY_SEPARATOR . 'app' . DIRECTORY_SEPARATOR . 'libraries' . DIRECTORY_SEPARATOR . 'autoload.php';
use Illuminate\Database\Capsule\Manager as Capsule;
use Dotenv\Dotenv;
$dotenv = new Dotenv(dirname(__DIR__, 1));
$dotenv->load();
$capsule = new Capsule;
// Same as database configuration file of Laravel.
$capsule->addConnection([
'driver' => env('DB_SYSTEM'),
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '3306'),
'database' => env('DB_NAME', 'nntmux'),
'username' => env('DB_USER', 'root'),
'password' => env('DB_PASSWORD', ''),
'unix_socket' => env('DB_SOCKET', ''),
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci'
], 'default');
$capsule->bootEloquent();
$capsule->setAsGlobal();
+26 -2
View File
@@ -1,2 +1,26 @@
#!/bin/bash
libraries/lithium/console/li3 "$@"
#!/usr/bin/env php
<?php
require_once __DIR__ . '/app/config/bootstrap.php';
use app\extensions\command\Update;
use app\extensions\command\Verify;
$update = new Update();
$verify = new Verify();
if (isset($argv[1]) && ($argv[1] === 'update' || $argv[1] === 'verify')) {
if ($argv[1] === 'update') {
if ($argv[2] === 'nntmux') {
$update->nntmux();
}
if ($argv[2] === 'db') {
$update->db();
}
}
if ($argv[1] === 'verify') {
$verify->settingstable();
}
} else {
$update->error($update->getHelp());
}