267 lines
11 KiB
PHP
267 lines
11 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\taoOutcomeUi\scripts\task;
|
|
|
|
use common_report_Report as Report;
|
|
use oat\generis\model\OntologyAwareTrait;
|
|
use oat\oatbox\action\Action;
|
|
use oat\tao\model\taskQueue\Task\WorkerContextAwareInterface;
|
|
use oat\tao\model\taskQueue\Task\WorkerContextAwareTrait;
|
|
use oat\taoOutcomeUi\model\export\DeliveryResultsExporterFactoryInterface;
|
|
use oat\taoOutcomeUi\model\export\ResultsExporter;
|
|
use oat\taoOutcomeUi\model\export\DeliveryCsvResultsExporterFactory;
|
|
use oat\taoOutcomeUi\model\export\SingleDeliverySqlResultsExporter;
|
|
use oat\taoOutcomeUi\model\export\DeliverySqlResultsExporterFactory;
|
|
use oat\taoOutcomeUi\model\ResultsService;
|
|
use Zend\ServiceManager\ServiceLocatorAwareTrait;
|
|
use Zend\ServiceManager\ServiceLocatorAwareInterface;
|
|
|
|
/**
|
|
* ExportDeliveryResults action, can be called either during a http request or from cli.
|
|
*
|
|
* Usage examples for CLI:
|
|
*
|
|
* If "--dir" is omitted, the file will be saved in the task queue storage.
|
|
*
|
|
* ```
|
|
* sudo -u www-data php index.php 'oat\taoOutcomeUi\scripts\task\ExportDeliveryResults' <deliveryOrClassId>
|
|
* sudo -u www-data php index.php 'oat\taoOutcomeUi\scripts\task\ExportDeliveryResults' <deliveryOrClassId> --dir=/home/user/exports
|
|
* sudo -u www-data php index.php 'oat\taoOutcomeUi\scripts\task\ExportDeliveryResults' <deliveryOrClassId> --columns=tt,delivery,grades,responses
|
|
* sudo -u www-data php index.php 'oat\taoOutcomeUi\scripts\task\ExportDeliveryResults' <deliveryOrClassId> --columns=all
|
|
* sudo -u www-data php index.php 'oat\taoOutcomeUi\scripts\task\ExportDeliveryResults' <deliveryOrClassId> --columns=tt,delivery,grades,responses --submittedVersion=lastSubmitted
|
|
* ```
|
|
* @author Gyula Szucs <gyula@taotesting.com>
|
|
*/
|
|
class ExportDeliveryResults implements Action, ServiceLocatorAwareInterface, WorkerContextAwareInterface
|
|
{
|
|
use ServiceLocatorAwareTrait;
|
|
use OntologyAwareTrait;
|
|
use WorkerContextAwareTrait;
|
|
|
|
/**
|
|
* Possible CLI values for columns
|
|
*/
|
|
const COLUMNS_CLI_VALUE_ALL = 'all';
|
|
const COLUMNS_CLI_VALUE_TEST_TAKER = 'tt';
|
|
const COLUMNS_CLI_VALUE_DELIVERY = 'delivery';
|
|
const COLUMNS_CLI_VALUE_GRADES = 'grades';
|
|
const COLUMNS_CLI_VALUE_RESPONSES = 'responses';
|
|
|
|
/**
|
|
* @var \core_kernel_classes_Resource
|
|
*/
|
|
private $resourceToExport;
|
|
private $exporterService;
|
|
private $columns = [];
|
|
private $submittedVersion;
|
|
private $destination;
|
|
private $filters = [];
|
|
private $format;
|
|
/**
|
|
* @var DeliveryResultsExporterFactoryInterface
|
|
*/
|
|
private $deliveryResultsExporterFactory;
|
|
|
|
/**
|
|
* @param array $params
|
|
* @return Report
|
|
*/
|
|
public function __invoke($params)
|
|
{
|
|
$this->loadExtensions();
|
|
|
|
try {
|
|
$this->parseParams($params);
|
|
|
|
if ($this->submittedVersion) {
|
|
$this->getExporterService()->setVariableToExport($this->submittedVersion);
|
|
}
|
|
|
|
$fileName = $this->getExporterService()
|
|
->setColumnsToExport($this->columns)
|
|
->setFiltersToExport($this->filters)
|
|
->export($this->destination);
|
|
|
|
$msg = $fileName
|
|
? $this->isWorkerContext()
|
|
? __('Results of "%s" successfully exported', $this->resourceToExport->getLabel())
|
|
: __('Results of "%s" successfully exported into "%s"', $this->resourceToExport->getLabel(), $fileName)
|
|
: __('Nothing to export for "%s"', $this->resourceToExport->getLabel());
|
|
|
|
return Report::createSuccess($msg, $fileName);
|
|
} catch (\Exception $e) {
|
|
return Report::createFailure($e->getMessage());
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @return ResultsExporter
|
|
* @throws \common_exception_NotFound
|
|
*/
|
|
private function getExporterService()
|
|
{
|
|
if (is_null($this->exporterService)) {
|
|
$this->exporterService = new ResultsExporter($this->resourceToExport, ResultsService::singleton(), $this->deliveryResultsExporterFactory);
|
|
$this->exporterService->setServiceLocator($this->getServiceLocator());
|
|
}
|
|
|
|
return $this->exporterService;
|
|
}
|
|
|
|
/**
|
|
* Load the required TAO extensions (for constants)
|
|
*/
|
|
private function loadExtensions()
|
|
{
|
|
$this->getServiceLocator()->get(\common_ext_ExtensionsManager::SERVICE_ID)->getExtensionById('taoOutcomeUi');
|
|
$this->getServiceLocator()->get(\common_ext_ExtensionsManager::SERVICE_ID)->getExtensionById('taoDeliveryRdf');
|
|
}
|
|
|
|
/**
|
|
* Checks and sets parameters.
|
|
*
|
|
* Params order:
|
|
* - $params[0]: delivery uri (required, string)
|
|
* - $params[1]: columns (optional, array|string)
|
|
* - $params[2]: submittedVersion (optional, string)
|
|
*
|
|
* @param array $params
|
|
*/
|
|
private function parseParams($params)
|
|
{
|
|
// Delivery or Class Uri
|
|
if (!isset($params[0])) {
|
|
throw new \InvalidArgumentException('Delivery or class uri missing. Please provide it as the first argument.');
|
|
}
|
|
|
|
$this->resourceToExport = $this->getResource($params[0]);
|
|
|
|
if ($this->isWorkerContext()) {
|
|
// Columns to be exported, if defined
|
|
if (isset($params[1]) && is_array($params[1])) {
|
|
$this->columns = $params[1];
|
|
}
|
|
|
|
// Submitted version of variables, if defined
|
|
if (isset($params[2])) {
|
|
$this->submittedVersion = $params[2];
|
|
}
|
|
|
|
if (isset($params[3])) {
|
|
$this->filters = $params[3];
|
|
}
|
|
|
|
if (isset($params[4]) && $params[4] === SingleDeliverySqlResultsExporter::RESULT_FORMAT) {
|
|
$this->deliveryResultsExporterFactory = new DeliverySqlResultsExporterFactory();
|
|
} else {
|
|
$this->deliveryResultsExporterFactory = new DeliveryCsvResultsExporterFactory();
|
|
}
|
|
} else {
|
|
// if the task is called from CLI
|
|
|
|
// remove first param, it is always the resource uri, no need to re-check
|
|
unset($params[0]);
|
|
|
|
// check params. running the command from CLI we have different params structure
|
|
foreach ($params as $param) {
|
|
list($option, $value) = explode('=', $param);
|
|
|
|
switch ($option) {
|
|
case '--columns':
|
|
$columns = explode(',', $value);
|
|
|
|
$invalidValues = array_diff($columns, $this->getPossibleColumnValues());
|
|
|
|
if (count($invalidValues)) {
|
|
throw new \InvalidArgumentException('Invalid columns value(s) "' . implode(', ', $invalidValues) . '". Valid options: ' . implode(', ', $this->getPossibleColumnValues()));
|
|
}
|
|
|
|
if (in_array(self::COLUMNS_CLI_VALUE_ALL, $columns)) {
|
|
// do nothing because SingleDeliveryResultsExporter will use all columns by default if no columns specified
|
|
break;
|
|
}
|
|
|
|
foreach ($columns as $column) {
|
|
switch ($column) {
|
|
case self::COLUMNS_CLI_VALUE_TEST_TAKER:
|
|
$this->columns = array_merge($this->columns, $this->getExporterService()->getTestTakerColumns());
|
|
break;
|
|
|
|
case self::COLUMNS_CLI_VALUE_DELIVERY:
|
|
$this->columns = array_merge($this->columns, $this->getExporterService()->getDeliveryColumns());
|
|
break;
|
|
|
|
case self::COLUMNS_CLI_VALUE_GRADES:
|
|
$this->columns = array_merge($this->columns, $this->getExporterService()->getGradeColumns());
|
|
break;
|
|
|
|
case self::COLUMNS_CLI_VALUE_RESPONSES:
|
|
$this->columns = array_merge($this->columns, $this->getExporterService()->getResponseColumns());
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case '--submittedVersion':
|
|
if (!in_array($value, [ResultsService::VARIABLES_FILTER_FIRST_SUBMITTED, ResultsService::VARIABLES_FILTER_LAST_SUBMITTED])) {
|
|
throw new \InvalidArgumentException('Invalid submitted version of variables "' . $value . '". Valid options: ' . implode(', ', [ResultsService::VARIABLES_FILTER_FIRST_SUBMITTED, ResultsService::VARIABLES_FILTER_LAST_SUBMITTED]));
|
|
}
|
|
|
|
$this->submittedVersion = $value;
|
|
break;
|
|
|
|
case '--dir':
|
|
if (!is_dir($value)) {
|
|
throw new \InvalidArgumentException('Invalid directory "' . $value . '" provided.');
|
|
}
|
|
|
|
if (!is_writable($value)) {
|
|
throw new \InvalidArgumentException('Directory "' . $value . '" not writable.');
|
|
}
|
|
$this->destination = $value;
|
|
break;
|
|
case '--start-from':
|
|
$this->filters['startfrom'] = $value;
|
|
break;
|
|
case '--start-to':
|
|
$this->filters['startto'] = $value;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @return array
|
|
*/
|
|
private function getPossibleColumnValues()
|
|
{
|
|
return [
|
|
self::COLUMNS_CLI_VALUE_ALL,
|
|
self::COLUMNS_CLI_VALUE_TEST_TAKER,
|
|
self::COLUMNS_CLI_VALUE_DELIVERY,
|
|
self::COLUMNS_CLI_VALUE_GRADES,
|
|
self::COLUMNS_CLI_VALUE_RESPONSES
|
|
];
|
|
}
|
|
}
|