tao-test/app/generis/common/oatbox/extension/script/ScriptAction.php

232 lines
6.5 KiB
PHP

<?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; under version 2
* of the License (non-upgradable).
*
* 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; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Copyright (c) 2017 (original work) Open Assessment Technologies SA (under the project TAO-PRODUCT);
*
*/
namespace oat\oatbox\extension\script;
use oat\oatbox\extension\AbstractAction;
use common_report_Report as Report;
/**
* abstract base for extension scripts.
*
* @author Jérôme Bogaerts <jerome@taotesting.com>
*/
abstract class ScriptAction extends AbstractAction
{
private $options;
private $optionsDescription;
abstract protected function provideOptions();
abstract protected function provideDescription();
/**
* Run Script.
*
* Run the userland script. Implementers will use this method
* to implement the main logic of the script.
*
* @return \common_report_Report
*/
abstract protected function run();
/**
* Invoke
*
* This method makes the script invokable programatically.
*
* @return \common_report_Report
*/
public function __invoke($params)
{
$this->optionsDescription = $this->provideOptions();
$beginScript = microtime(true);
// Display help?
if ($this->displayUsage($params)) {
return $this->usage();
}
// Build option container.
try {
$this->options = new OptionContainer(
$this->optionsDescription,
$params
);
} catch (\Exception $e) {
return new Report(
Report::TYPE_ERROR,
$e->getMessage()
);
}
// Run the userland script.
$report = $this->run();
$endScript = microtime(true);
if ($this->showTime()) {
$report->add(
new Report(
Report::TYPE_INFO,
'Execution time: ' . self::secondsToDuration($endScript - $beginScript)
)
);
}
return $report;
}
protected function hasOption($optionName)
{
return $this->options->has($optionName);
}
protected function getOption($optionName)
{
return $this->options->get($optionName);
}
protected function provideUsage()
{
return [];
}
protected function provideUsageOptionName()
{
return 'help';
}
protected function showTime()
{
return false;
}
private function displayUsage(array $params)
{
$usageDescription = $this->provideUsage();
if (!empty($usageDescription) && is_array($usageDescription)) {
if (!empty($usageDescription['prefix']) && in_array('-' . $usageDescription['prefix'], $params)) {
return true;
} elseif (!empty($usageDescription['longPrefix']) && in_array('--' . $usageDescription['longPrefix'], $params)) {
return true;
}
}
return false;
}
private function usage()
{
$report = new Report(
Report::TYPE_INFO,
$this->provideDescription() . "\n"
);
$optionsDescription = $this->optionsDescription;
$optionsDescription[$this->provideUsageOptionName()] = $this->provideUsage();
$required = new Report(Report::TYPE_INFO, 'Required Arguments:');
$optional = new Report(Report::TYPE_INFO, 'Optional Arguments:');
foreach ($optionsDescription as $optionName => $optionParams) {
// Deal with prefixes.
$prefixes = [];
$optionDisplay = (!empty($optionParams['flag'])) ? '' : " ${optionName}";
if (!empty($optionParams['prefix'])) {
$prefixes[] = '-' . $optionParams['prefix'] . "${optionDisplay}";
}
if (!empty($optionParams['longPrefix'])) {
$prefixes[] = '--' . $optionParams['longPrefix'] . "${optionDisplay}";
}
$optionMsg = implode(', ', $prefixes);
if (isset($optionParams['defaultValue'])) {
$optionMsg .= ' (default: ' . self::valueToString($optionParams['defaultValue']) . ')';
}
$optionReport = new Report(Report::TYPE_INFO, $optionMsg);
if (!empty($optionParams['description'])) {
$optionReport->add(
new Report(Report::TYPE_INFO, $optionParams['description'])
);
}
$targetReport = (empty($optionParams['required'])) ? $optional : $required;
$targetReport->add($optionReport);
}
if ($required->hasChildren()) {
$report->add($required);
}
if ($optional->hasChildren()) {
$report->add($optional);
}
// A little bit of formatting...
if ($required->hasChildren() && $optional->hasChildren()) {
$required->add(new Report(Report::TYPE_INFO, ""));
}
return $report;
}
private static function valueToString($value)
{
$string = "\"${value}\"";
switch (gettype($value)) {
case 'boolean':
$string = ($value === true) ? 'true' : 'false';
break;
case 'integer':
case 'double':
$string = $value;
}
return $string;
}
/**
* Seconds to Duration
*
* Format a given number of $seconds into a duration with format [hours]:[minutes]:[seconds].
*
* @param $seconds
* @return string
*/
private static function secondsToDuration($seconds)
{
$seconds = intval($seconds);
$hours = floor($seconds / 3600);
$minutes = floor(($seconds / 60) % 60);
$seconds = $seconds % 60;
return "${hours}h ${minutes}m {$seconds}s";
}
}