tao-test/app/taoProctoring/model/ActivityMonitoringService.php

185 lines
6.6 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;
*
*
*/
namespace oat\taoProctoring\model;
use oat\generis\model\OntologyAwareTrait;
use oat\oatbox\service\ConfigurableService;
use oat\tao\model\user\TaoRoles;
use oat\taoProctoring\model\execution\DeliveryExecution;
use oat\taoProctoring\model\monitorCache\DeliveryMonitoringService;
use oat\taoEventLog\model\userLastActivityLog\UserLastActivityLog;
/**
* Service to manage and monitor assessment activity
*
* @author Aleh Hutnikau, <hutnikau@1pt.com>
*/
class ActivityMonitoringService extends ConfigurableService
{
use OntologyAwareTrait;
const SERVICE_ID = 'taoProctoring/ActivityMonitoringService';
/** Threshold in seconds */
const OPTION_ACTIVE_USER_THRESHOLD = 'active_user_threshold';
/** Interval of refreshing assessment activity graph in seconds. 0 - no auto refresh */
const OPTION_COMPLETED_ASSESSMENTS_AUTO_REFRESH = 'completed_assessments_auto_refresh';
/** Interval of refreshing assessment activity data in seconds. 0 - no auto refresh */
const OPTION_ASSESSMENT_ACTIVITY_AUTO_REFRESH = 'assessment_activity_auto_refresh';
/** Allow to specify custom activity widgets to be rendered */
const OPTION_USER_ACTIVITY_WIDGETS = 'userActivityWidgets';
/** State of awaiting assessment */
const STATE_AWAITING_ASSESSMENT = 'awaiting_assessments';
/** State of authorized assessment */
const STATE_AUTHORIZED_BUT_NOT_STARTED_ASSESSMENTS = 'authorized_but_not_started_assessments';
/** State of paused assessment */
const STATE_PAUSED_ASSESSMENTS = 'paused_assessments';
/** State of in progress assessment */
const STATE_IN_PROGRESS_ASSESSMENTS = 'in_progress_assessments';
/** Active proctors field */
const FIELD_ACTIVE_PROCTORS = 'active_proctors';
/** Active Test Takers field */
const FIELD_ACTIVE_TEST_TAKERS = 'active_test_takers';
/** Total assessments field */
const FIELD_TOTAL_ASSESSMENTS = 'total_assessments';
/** Deliveries statistics field*/
const FIELD_DELIVERIES_STATISTICS = 'deliveries_statistics';
/** Retired deliveries field*/
const FIELD_RETIRED_DELIVERIES = 'retired_deliveries';
/** Total current assessment field */
const FIELD_TOTAL_CURRENT_ASSESSMENTS = 'total_current_assessments';
const LABEL_RETIRED_DELIVERIES = 'Retired Deliveries';
const GROUPFIELD_USER_ACTIVITY = 'group_user_activity';
/**
* @var array list of all the statuses uris
*/
protected $deliveryStatuses = [
DeliveryExecution::STATE_AWAITING,
DeliveryExecution::STATE_AUTHORIZED,
DeliveryExecution::STATE_PAUSED,
DeliveryExecution::STATE_ACTIVE,
DeliveryExecution::STATE_TERMINATED,
DeliveryExecution::STATE_CANCELED,
DeliveryExecution::STATE_FINISHED,
];
/**
* ActivityMonitoringService constructor.
* @param array $options
*/
public function __construct(array $options = array())
{
parent::__construct($options);
$deliveryStatuses = [];
foreach ($this->deliveryStatuses as $deliveryStatus) {
$deliveryStatuses[] = new \core_kernel_classes_Resource($deliveryStatus);
}
$this->deliveryStatuses = $deliveryStatuses;
}
/**
* Return comprehensive activity monitoring data.
* @return array
*/
public function getData()
{
$awaiting = $this->getNumberOfAssessments(DeliveryExecution::STATE_AWAITING);
$authorized = $this->getNumberOfAssessments(DeliveryExecution::STATE_AUTHORIZED);
$paused = $this->getNumberOfAssessments(DeliveryExecution::STATE_PAUSED);
$active = $this->getNumberOfAssessments(DeliveryExecution::STATE_ACTIVE);
$current = $awaiting + $authorized + $paused + $active;
$assessments = [
self::GROUPFIELD_USER_ACTIVITY => [
self::FIELD_ACTIVE_PROCTORS => $this->getNumberOfActiveUsers(ProctorService::ROLE_PROCTOR),
self::FIELD_ACTIVE_TEST_TAKERS => $this->getNumberOfActiveUsers(TaoRoles::DELIVERY),
],
self::FIELD_TOTAL_ASSESSMENTS => $this->getNumberOfAssessments(),
self::FIELD_TOTAL_CURRENT_ASSESSMENTS => $current,
self::STATE_AWAITING_ASSESSMENT => $awaiting,
self::STATE_AUTHORIZED_BUT_NOT_STARTED_ASSESSMENTS => $authorized,
self::STATE_PAUSED_ASSESSMENTS => $paused,
self::STATE_IN_PROGRESS_ASSESSMENTS => $active
];
return $assessments;
}
/**
* @see \tao_helpers_Date::getTimeKeys()
* @deprecated
* @return array
*/
public function getTimeKeys(\DateInterval $interval, \DateTime $date = null, $amount = null)
{
return \tao_helpers_Date::getTimeKeys($interval, $date, $amount);
}
/**
* @param null|string $state
* @return int
*/
protected function getNumberOfAssessments($state = null)
{
$deliveryMonitoringService = $this->getServiceManager()->get(DeliveryMonitoringService::SERVICE_ID);
if ($state === null) {
return $deliveryMonitoringService->count();
} else {
return $deliveryMonitoringService->count([DeliveryMonitoringService::STATUS => $state]);
}
}
/**
* @param null|string $role
* @return int
*/
protected function getNumberOfActiveUsers($role = null)
{
/** @var UserLastActivityLog $userActivityService */
$userActivityService = $this->getServiceManager()->get(UserLastActivityLog::SERVICE_ID);
$now = microtime(true);
$filter = [
[UserLastActivityLog::EVENT_TIME, 'between', $now - $this->getOption(self::OPTION_ACTIVE_USER_THRESHOLD), $now]
];
if ($role !== null) {
$filter[] = [UserLastActivityLog::USER_ROLES, 'like', '%,' . $role . ',%'];
}
return $userActivityService->count($filter, ['group'=>UserLastActivityLog::USER_ID]);
}
}