File Manager
Upload
Current Directory: /home/lartcid/public_html/journal.lartc.id
[Back]
..
[Open]
Hapus
Rename
.htaccess
[Edit]
Hapus
Rename
.well-known
[Open]
Hapus
Rename
README.md
[Edit]
Hapus
Rename
api
[Open]
Hapus
Rename
cache
[Open]
Hapus
Rename
cgi-bin
[Open]
Hapus
Rename
classes
[Open]
Hapus
Rename
config.TEMPLATE.inc.php
[Edit]
Hapus
Rename
config.inc.php
[Edit]
Hapus
Rename
controllers
[Open]
Hapus
Rename
cypress.json
[Edit]
Hapus
Rename
dbscripts
[Open]
Hapus
Rename
docs
[Open]
Hapus
Rename
error_log
[Edit]
Hapus
Rename
favicon.ico
[Edit]
Hapus
Rename
index.php
[Edit]
Hapus
Rename
js
[Open]
Hapus
Rename
lib
[Open]
Hapus
Rename
locale
[Open]
Hapus
Rename
mini.php
[Edit]
Hapus
Rename
pages
[Open]
Hapus
Rename
php.ini
[Edit]
Hapus
Rename
plugins
[Open]
Hapus
Rename
public
[Open]
Hapus
Rename
registry
[Open]
Hapus
Rename
scheduledTaskLogs
[Open]
Hapus
Rename
schemas
[Open]
Hapus
Rename
styles
[Open]
Hapus
Rename
templates
[Open]
Hapus
Rename
tools
[Open]
Hapus
Rename
Edit File
<?php /** * @file pages/stats/PKPStatsHandler.inc.php * * Copyright (c) 2013-2021 Simon Fraser University * Copyright (c) 2003-2021 John Willinsky * Distributed under the GNU GPL v3. For full terms see the file docs/COPYING. * * @class PKPStatsHandler * @ingroup pages_stats * * @brief Handle requests for statistics pages. */ import('classes.handler.Handler'); import('classes.statistics.StatisticsHelper'); class PKPStatsHandler extends Handler { /** @copydoc PKPHandler::_isBackendPage */ var $_isBackendPage = true; /** * Constructor. */ public function __construct() { parent::__construct(); $this->addRoleAssignment( [ROLE_ID_SITE_ADMIN, ROLE_ID_MANAGER, ROLE_ID_SUB_EDITOR], ['editorial', 'publications', 'users', 'reports'] ); } /** * @see PKPHandler::authorize() * @param $request PKPRequest * @param $args array * @param $roleAssignments array */ public function authorize($request, &$args, $roleAssignments) { import('lib.pkp.classes.security.authorization.ContextAccessPolicy'); $this->addPolicy(new ContextAccessPolicy($request, $roleAssignments)); return parent::authorize($request, $args, $roleAssignments); } // // Public handler methods. // /** * Display editorial stats about the submission workflow process * * @param array $args * @param Request $request */ public function editorial($args, $request) { $dispatcher = $request->getDispatcher(); $context = $request->getContext(); if (!$context) { $dispatcher->handle404(); } $templateMgr = TemplateManager::getManager($request); $this->setupTemplate($request); $dateStart = date('Y-m-d', strtotime('-91 days')); $dateEnd = date('Y-m-d', strtotime('yesterday')); $args = [ 'contextIds' => [$context->getId()], ]; $totals = Services::get('editorialStats')->getOverview($args); $averages = Services::get('editorialStats')->getAverages($args); $dateRangeTotals = Services::get('editorialStats')->getOverview( array_merge( $args, [ 'dateStart' => $dateStart, 'dateEnd' => $dateEnd, ] ) ); // Stats that should be converted to percentages $percentageStats = [ 'acceptanceRate', 'declineRate', 'declinedDeskRate', 'declinedReviewRate', ]; // Stats that should be indented in the table $indentStats = [ 'submissionsDeclinedDeskReject', 'submissionsDeclinedPostReview', 'daysToAccept', 'daysToReject', 'declinedDeskRate', 'declinedReviewRate', 'submissionsInProgress', 'submissionsImported' ]; // Compile table rows $tableRows = []; foreach ($totals as $i => $stat) { $row = [ 'key' => $stat['key'], 'name' => __($stat['name']), 'total' => $stat['value'], 'dateRange' => $dateRangeTotals[$i]['value'], ]; if (in_array($stat['key'], $indentStats)) { $row['name'] = ' ' . $row['name']; } if (in_array($stat['key'], $percentageStats)) { $row['total'] = ($stat['value'] * 100) . '%'; $row['dateRange'] = ($dateRangeTotals[$i]['value'] * 100) . '%'; } $description = $this->_getStatDescription($stat['key']); if ($description) { $row['description'] = $description; } if (array_key_exists($stat['key'], $averages) && $averages[$stat['key']] !== -1 && $row['total'] > 0) { $row['total'] = __('stats.countWithYearlyAverage', [ 'count' => $stat['value'], 'average' => $averages[$stat['key']], ]); } $tableRows[] = $row; } // Get the worflow stage counts $activeByStage = []; foreach (Application::get()->getApplicationStages() as $stageId) { $activeByStage[] = [ 'name' => __(Application::get()->getWorkflowStageName($stageId)), 'count' => Services::get('editorialStats')->countActiveByStages($stageId, $args), 'color' => Application::get()->getWorkflowStageColor($stageId), ]; } $statsComponent = new \PKP\components\PKPStatsEditorialPage( $dispatcher->url($request, ROUTE_API, $context->getPath(), 'stats/editorial'), [ 'activeByStage' => $activeByStage, 'averagesApiUrl' => $dispatcher->url($request, ROUTE_API, $context->getPath(), 'stats/editorial/averages'), 'dateStart' => $dateStart, 'dateEnd' => $dateEnd, 'dateRangeOptions' => [ [ 'dateStart' => date('Y-m-d', strtotime('-91 days')), 'dateEnd' => $dateEnd, 'label' => __('stats.dateRange.last90Days'), ], [ 'dateStart' => date('Y-m-d', strtotime(date('Y') . '-01-01')), 'dateEnd' => $dateEnd, 'label' => __('stats.dateRange.thisYear'), ], [ 'dateStart' => date('Y-m-d', strtotime((date('Y') - 1) . '-01-01')), 'dateEnd' => date('Y-m-d', strtotime((date('Y') - 1) . '-12-31')), 'label' => __('stats.dateRange.lastYear'), ], [ 'dateStart' => date('Y-m-d', strtotime((date('Y') - 2) . '-01-01')), 'dateEnd' => date('Y-m-d', strtotime((date('Y') - 1) . '-12-31')), 'label' => __('stats.dateRange.lastTwoYears'), ], ], 'percentageStats' => $percentageStats, 'tableColumns' => [ [ 'name' => 'name', 'label' => __('common.name'), 'value' => 'name', ], [ 'name' => 'dateRange', 'label' => $dateStart . ' — ' . $dateEnd, 'value' => 'dateRange', ], [ 'name' => 'total', 'label' => __('stats.total'), 'value' => 'total', ], ], 'tableRows' => $tableRows, ] ); $templateMgr->setLocaleKeys([ 'stats.descriptionForStat', 'stats.countWithYearlyAverage', ]); $templateMgr->setState($statsComponent->getConfig()); $templateMgr->assign([ 'pageComponent' => 'StatsEditorialPage', 'pageTitle' => __('stats.editorialActivity'), ]); $templateMgr->display('stats/editorial.tpl'); } /** * Display published submissions statistics page * * @param $request PKPRequest * @param $args array */ public function publications($args, $request) { $dispatcher = $request->getDispatcher(); $context = $request->getContext(); if (!$context) { $dispatcher->handle404(); } AppLocale::requireComponents(LOCALE_COMPONENT_PKP_SUBMISSION); AppLocale::requireComponents(LOCALE_COMPONENT_APP_SUBMISSION); $templateMgr = TemplateManager::getManager($request); $this->setupTemplate($request); $dateStart = date('Y-m-d', strtotime('-31 days')); $dateEnd = date('Y-m-d', strtotime('yesterday')); $count = 30; $timeline = Services::get('stats')->getTimeline(STATISTICS_DIMENSION_DAY, [ 'assocTypes' => ASSOC_TYPE_SUBMISSION, 'contextIds' => $context->getId(), 'count' => $count, 'dateStart' => $dateStart, 'dateEnd' => $dateEnd, ]); $statsComponent = new \PKP\components\PKPStatsPublicationPage( $dispatcher->url($request, ROUTE_API, $context->getPath(), 'stats/publications'), [ 'timeline' => $timeline, 'timelineInterval' => STATISTICS_DIMENSION_DAY, 'timelineType' => 'abstract', 'tableColumns' => [ [ 'name' => 'title', 'label' => __('common.title'), ], [ 'name' => 'abstractViews', 'label' => __('submission.abstractViews'), 'value' => 'abstractViews', ], [ 'name' => 'galleyViews', 'label' => __('stats.fileViews'), 'value' => 'galleyViews', ], [ 'name' => 'pdf', 'label' => __('stats.pdf'), 'value' => 'pdfViews', ], [ 'name' => 'html', 'label' => __('stats.html'), 'value' => 'htmlViews', ], [ 'name' => 'other', 'label' => __('common.other'), 'value' => 'otherViews', ], [ 'name' => 'total', 'label' => __('stats.total'), 'value' => 'total', 'orderBy' => 'total', 'initialOrderDirection' => true, ], ], 'count' => $count, 'dateStart' => $dateStart, 'dateEnd' => $dateEnd, 'dateRangeOptions' => [ [ 'dateStart' => $dateStart, 'dateEnd' => $dateEnd, 'label' => __('stats.dateRange.last30Days'), ], [ 'dateStart' => date('Y-m-d', strtotime('-91 days')), 'dateEnd' => $dateEnd, 'label' => __('stats.dateRange.last90Days'), ], [ 'dateStart' => date('Y-m-d', strtotime('-12 months')), 'dateEnd' => $dateEnd, 'label' => __('stats.dateRange.last12Months'), ], [ 'dateStart' => '', 'dateEnd' => '', 'label' => __('stats.dateRange.allDates'), ], ], 'orderBy' => 'total', 'orderDirection' => true, ] ); $templateMgr->setState($statsComponent->getConfig()); $templateMgr->assign([ 'pageComponent' => 'StatsPublicationsPage', 'pageTitle' => __('stats.publicationStats'), 'pageWidth' => PAGE_WIDTH_WIDE, ]); $templateMgr->display('stats/publications.tpl'); } /** * Display users stats * * @param array $args * @param Request $request */ public function users(array $args, \Request $request) : void { $dispatcher = $request->getDispatcher(); $context = $request->getContext(); if (!$context) { $dispatcher->handle404(); } // The POST handler is here merely to serve a redirection URL to the Vue component if ($request->isPost()) { echo $dispatcher->url($request, ROUTE_API, $context->getPath(), 'users/report', null, null, $request->getUserVars()); exit; } $templateMgr = TemplateManager::getManager($request); $this->setupTemplate($request); $context = $request->getContext(); $selfUrl = $dispatcher->url($request, ROUTE_PAGE, $context->getPath(), 'stats', 'users'); $reportForm = new PKP\components\forms\statistics\users\ReportForm($selfUrl, $context); $templateMgr->setState([ 'components' => [ 'usersReportForm' => $reportForm->getConfig() ] ]); $templateMgr->assign([ 'pageTitle' => __('stats.userStatistics'), 'pageComponent' => 'StatsUsersPage', 'userStats' => array_map( function ($item) { $item['name'] = __($item['name']); return $item; }, Services::get('user')->getRolesOverview(['contextId' => $context->getId()]) ), ]); $templateMgr->display('stats/users.tpl'); } /** * Set up the basic template for reports. * @param $request PKPRequest */ function setupTemplate($request) { parent::setupTemplate($request); AppLocale::requireComponents(LOCALE_COMPONENT_PKP_MANAGER, LOCALE_COMPONENT_APP_SUBMISSION); } /** * Route to other Reports operations * * @param $args array * @param $request PKPRequest */ public function reports($args, $request) { $path = array_shift($args); switch ($path) { case '': case 'reports': $this->displayReports($args, $request); break; case 'report': $this->report($args, $request); break; case 'reportGenerator': $this->reportGenerator($args, $request); break; case 'generateReport': $this->generateReport($args, $request); break; default: assert(false); } } /** * Display report possibilities (report plugins) * * @param $args array * @param $request PKPRequest */ public function displayReports($args, $request) { $dispatcher = $request->getDispatcher(); $context = $request->getContext(); if (!$context) { $dispatcher->handle404(); } $templateMgr = TemplateManager::getManager($request); $this->setupTemplate($request); $reportPlugins = PluginRegistry::loadCategory('reports'); $templateMgr->assign('reportPlugins', $reportPlugins); $templateMgr->assign([ 'pageTitle' => __('manager.statistics.reports'), ]); $templateMgr->display('stats/reports.tpl'); } /** * Delegates to plugins operations * related to report generation. * @param $args array * @param $request Request */ public function report($args, $request) { $this->setupTemplate($request); $pluginName = $request->getUserVar('pluginName'); $reportPlugins = PluginRegistry::loadCategory('reports'); if ($pluginName == '' || !isset($reportPlugins[$pluginName])) { $request->redirect(null, null, 'stats', 'reports'); } $plugin = $reportPlugins[$pluginName]; $plugin->display($args, $request); } /** * Display page to generate custom reports. * @param $args array * @param $request Request */ function reportGenerator($args, $request) { $this->setupTemplate($request); AppLocale::requireComponents(LOCALE_COMPONENT_PKP_SUBMISSION, LOCALE_COMPONENT_APP_EDITOR); $templateMgr = TemplateManager::getManager($request); $templateMgr->assign([ 'breadcrumbs' => [ [ 'id' => 'reports', 'name' => __('manager.statistics.reports'), 'url' => $request->getRouter()->url($request, null, 'stats', 'reports'), ], [ 'id' => 'customReportGenerator', 'name' => __('manager.statistics.reports.customReportGenerator') ], ], 'pageTitle' => __('manager.statistics.reports.customReportGenerator'), ]); $templateMgr->display('stats/reportGenerator.tpl'); } /** * Generate statistics reports from passed * request arguments. * @param $args array * @param $request PKPRequest */ function generateReport($args, $request) { $this->setupTemplate($request); AppLocale::requireComponents(LOCALE_COMPONENT_PKP_SUBMISSION); $router = $request->getRouter(); $context = $router->getContext($request); import('classes.statistics.StatisticsHelper'); $statsHelper = new StatisticsHelper(); $metricType = $request->getUserVar('metricType'); if (is_null($metricType)) { $metricType = $context->getDefaultMetricType(); } // Generates only one metric type report at a time. if (is_array($metricType)) $metricType = current($metricType); if (!is_scalar($metricType)) $metricType = null; $reportPlugin = $statsHelper->getReportPluginByMetricType($metricType); if (!$reportPlugin || is_null($metricType)) { $request->redirect(null, null, 'stats', 'reports'); } $columns = $request->getUserVar('columns'); $filters = (array) json_decode($request->getUserVar('filters')); if (!$filters) $filters = $request->getUserVar('filters'); $orderBy = $request->getUserVar('orderBy'); if ($orderBy) { $orderBy = (array) json_decode($orderBy); if (!$orderBy) $orderBy = $request->getUserVar('orderBy'); } else { $orderBy = array(); } $metrics = $reportPlugin->getMetrics($metricType, $columns, $filters, $orderBy); $allColumnNames = $statsHelper->getColumnNames(); $columnOrder = array_keys($allColumnNames); $columnNames = array(); foreach ($columnOrder as $column) { if (in_array($column, $columns)) { $columnNames[$column] = $allColumnNames[$column]; } if ($column == STATISTICS_DIMENSION_ASSOC_TYPE && in_array(STATISTICS_DIMENSION_ASSOC_ID, $columns)) { $columnNames['common.title'] = __('common.title'); } } // Make sure the metric column will always be present. if (!in_array(STATISTICS_METRIC, $columnNames)) $columnNames[STATISTICS_METRIC] = $allColumnNames[STATISTICS_METRIC]; header('content-type: text/comma-separated-values'); header('content-disposition: attachment; filename=statistics-' . date('Ymd') . '.csv'); $fp = fopen('php://output', 'wt'); //Add BOM (byte order mark) to fix UTF-8 in Excel fprintf($fp, chr(0xEF).chr(0xBB).chr(0xBF)); fputcsv($fp, array($reportPlugin->getDisplayName())); fputcsv($fp, array($reportPlugin->getDescription())); fputcsv($fp, array(__('common.metric') . ': ' . $metricType)); fputcsv($fp, array(__('manager.statistics.reports.reportUrl') . ': ' . $request->getCompleteUrl())); fputcsv($fp, array('')); // Just for better displaying. $columnNames = array_merge(array(''), $columnNames); fputcsv($fp, $columnNames); foreach ($metrics as $record) { $row = array(); foreach ($columnNames as $key => $name) { if (empty($name)) { // Column just for better displaying. $row[] = ''; continue; } // Give a chance for subclasses to set the row values. if ($returner = $this->getReportRowValue($key, $record)) { $row[] = $returner; continue; } switch ($key) { case 'common.title': $assocId = $record[STATISTICS_DIMENSION_ASSOC_ID]; $assocType = $record[STATISTICS_DIMENSION_ASSOC_TYPE]; $row[] = $this->getObjectTitle($assocId, $assocType); break; case STATISTICS_DIMENSION_ASSOC_TYPE: $assocType = $record[STATISTICS_DIMENSION_ASSOC_TYPE]; $row[] = $statsHelper->getObjectTypeString($assocType); break; case STATISTICS_DIMENSION_CONTEXT_ID: $assocId = $record[STATISTICS_DIMENSION_CONTEXT_ID]; $assocType = Application::getContextAssocType(); $row[] = $this->getObjectTitle($assocId, $assocType); break; case STATISTICS_DIMENSION_SUBMISSION_ID: if (isset($record[STATISTICS_DIMENSION_SUBMISSION_ID])) { $assocId = $record[STATISTICS_DIMENSION_SUBMISSION_ID]; $assocType = ASSOC_TYPE_SUBMISSION; $row[] = $this->getObjectTitle($assocId, $assocType); } else { $row[] = ''; } break; case STATISTICS_DIMENSION_REGION: if (isset($record[STATISTICS_DIMENSION_REGION]) && isset($record[STATISTICS_DIMENSION_COUNTRY])) { $geoLocationTool = $statsHelper->getGeoLocationTool(); if ($geoLocationTool) { $regions = $geoLocationTool->getRegions($record[STATISTICS_DIMENSION_COUNTRY]); $regionId = $record[STATISTICS_DIMENSION_REGION]; if (strlen($regionId) == 1) $regionId = '0' . $regionId; if (isset($regions[$regionId])) { $row[] = $regions[$regionId]; break; } } } $row[] = ''; break; case STATISTICS_DIMENSION_PKP_SECTION_ID: $sectionId = null; if (isset($record[STATISTICS_DIMENSION_PKP_SECTION_ID])) { $sectionId = $record[STATISTICS_DIMENSION_PKP_SECTION_ID]; } if ($sectionId) { $row[] = $this->getObjectTitle($sectionId, ASSOC_TYPE_SECTION); } else { $row[] = ''; } break; case STATISTICS_DIMENSION_FILE_TYPE: if ($record[$key]) { $row[] = $statsHelper->getFileTypeString($record[$key]); } else { $row[] = ''; } break; default: $row[] = $record[$key]; break; } } fputcsv($fp, $row); } fclose($fp); } // // Protected methods. // /** * Get the row value based on the column key (usually assoc types) * and the current record. * @param $key string|int * @param $record array * @return string */ protected function getReportRowValue($key, $record) { return null; } /** * Get data object title based on passed * assoc type and id. * @param $assocId int * @param $assocType int * @return string */ protected function getObjectTitle($assocId, $assocType) { switch ($assocType) { case Application::getContextAssocType(): $contextDao = Application::getContextDAO(); /* @var $contextDao ContextDAO */ $context = $contextDao->getById($assocId); if (!$context) break; return $context->getLocalizedName(); case ASSOC_TYPE_SUBMISSION: $submissionDao = DAORegistry::getDAO('SubmissionDAO'); /* @var $submissionDao SubmissionDAO */ $submission = $submissionDao->getById($assocId, null, true); if (!$submission) break; return $submission->getLocalizedTitle(); case ASSOC_TYPE_SECTION: $sectionDao = Application::getSectionDAO(); $section = $sectionDao->getById($assocId); if (!$section) break; return $section->getLocalizedTitle(); case ASSOC_TYPE_SUBMISSION_FILE: $submissionFile = Services::get('submissionFile')->get($assocId); if (!$submissionFile) break; return $submissionFile->getLocalizedData('name'); } return __('manager.statistics.reports.objectNotFound'); } /** * Get a description for stats that require one * * @param string $key * @return void */ protected function _getStatDescription($key) { switch ($key) { case 'daysToDecision': return __('stats.description.daysToDecision'); case 'acceptanceRate': return __('stats.description.acceptRejectRate'); case 'declineRate': return __('stats.description.acceptRejectRate'); case 'submissionsSkipped': return __('stats.description.submissionsSkipped'); } return ''; } }
Simpan