Files
pathfinder/app/main/controller/api/setup.php
Mark Friedrich 964dd0f7c9 - Enhancement, new admin "cronjob" dashboard on /setup page, closed #871
- Improved `/setup` page, show DB table `charset`/`collation` info
- Upgraded "[_Peity_](http://benpickles.github.io/peity)" js lib `v3.2.1` → `v3.3.0`
2019-10-30 23:12:25 +01:00

424 lines
15 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
/**
* Created by PhpStorm.
* User: Exodus 4D
* Date: 27.05.2018
* Time: 14:17
*/
namespace Controller\Api;
use Controller;
use lib\Config;
use lib\Cron;
use Model;
class Setup extends Controller\Controller {
/**
* get HTML table <tr>´s for all cronjobs
* @param \Base $f3
*/
public function cronTable(\Base $f3){
$return = (object) [];
$return->error = [];
$return->jobsData = Cron::instance()->getJobsConfig();
$return->html = $this->getCronHtml($return->jobsData);
echo json_encode($return);
}
/**
* toggle "isPaused" for a cronjob by its name
* @param \Base $f3
*/
public function cronPause(\Base $f3){
$postData = (array)$f3->get('POST');
$return = (object) [];
$return->error = [];
if($jobName = (string)$postData['job']){
$cron = Cron::instance();
if($job = $cron->getJob($jobName)){
if($job->valid()){
$job->isPaused = !$job->isPaused;
$job->save();
$return->jobsData = $cron->getJobsConfig([$jobName]);
$return->html = $this->getCronHtml($return->jobsData);
}
}
}
echo json_encode($return);
}
/**
* execute a cronjob by its name
* -> runs sync
* -> max execution time might be lower than CLI calls!
* @param \Base $f3
*/
public function cronExecute(\Base $f3){
$postData = (array)$f3->get('POST');
$return = (object) [];
$return->error = [];
if($jobName = (string)$postData['job']){
$cron = Cron::instance();
if($job = $cron->getJob($jobName)){
if($job->valid()){
$cron->execute($jobName, false);
$return->jobsData = $cron->getJobsConfig([$jobName]);
$return->html = $this->getCronHtml($return->jobsData);
}
}
}
echo json_encode($return);
}
/**
* get HTML for cronJobs
* @param array $jobsData
* @return string
*/
protected function getCronHtml(array $jobsData) : string {
$tplData = [
'cronConfig' => [
'jobs' => $jobsData,
'settings' => $this->getF3()->constants(Cron::instance(), 'DEFAULT_')
],
'tplCounter' => $this->counter(),
'tplConvertBytes' => function(){
return call_user_func_array([\lib\format\Number::instance(), 'bytesToString'], func_get_args());
}
];
return \Template::instance()->render('templates/ui/cron_table_row.html', null, $tplData, 0);
}
/**
* build search index from existing data (e.g. Systems)
* OR import data from ESI (e.g. Structures)
* -> optional build/import smaller chunks of data
* @param \Base $f3
* @throws \Exception
*/
public function buildIndex(\Base $f3){
$postData = (array)$f3->get('POST');
$type = (string)$postData['type'];
$countAll = (int)$postData['countAll'];
$count = (int)$postData['count'];
$offset = (int)$postData['offset'];
$return = (object) [];
$return->error = [];
$return->type = $type;
$return->count = $count;
$return->offset = $offset;
$return->countAll = $countAll;
$return->countBuild = 0;
$return->countBuildAll = 0;
$return->progress = 0;
/**
* sum array values
* @param int $carry
* @param int $value
* @return int
*/
$sum = function(int $carry, int $value) : int {
$carry += $value;
return $carry;
};
/**
* calc percent
* @param int $countAll
* @param int $count
* @return int
*/
$percent = function(int $countAll, int $count){
return $countAll ? floor((100/$countAll) * $count) : 0;
};
$controller = new Controller\Ccp\Universe();
switch($type){
case 'Systems':
$length = 100;
$buildInfo = $controller->buildSystemsIndex($offset, $length);
$return->offset = $buildInfo['offset'];
$return->countAll = $buildInfo['countAll'];
$return->countBuild = $buildInfo['countBuild'];
$return->countBuildAll = $return->offset;
break;
case 'Wormholes':
$groupId = Config::ESI_GROUP_WORMHOLE_ID;
$length = 10;
$buildInfo = $controller->setupGroup($groupId, $offset, $length, true);
$return->offset = $buildInfo['offset'];
$return->countAll = $buildInfo['countAll'];
$return->countBuild = $buildInfo['count'];
$return->countBuildAll = $return->offset;
break;
case 'Structures':
$categoryId = Config::ESI_CATEGORY_STRUCTURE_ID;
$length = 1;
$buildInfo = $controller->setupCategory($categoryId, $offset, $length);
$categoryUniverseModel = Model\Universe\AbstractUniverseModel::getNew('CategoryModel');
$categoryUniverseModel->getById($categoryId, 0);
$return->offset = $buildInfo['offset'];
$return->countBuild = $buildInfo['count'];
$return->countBuildAll = $return->offset;
$return->subCount = [
'countBuildAll' => $categoryUniverseModel->getTypesCount(false)
];
break;
case 'Ships':
$categoryId = Config::ESI_CATEGORY_SHIP_ID;
$length = 2;
$buildInfo = $controller->setupCategory($categoryId, $offset, $length);
$categoryUniverseModel = Model\Universe\AbstractUniverseModel::getNew('CategoryModel');
$categoryUniverseModel->getById($categoryId, 0);
$return->offset = $buildInfo['offset'];
$return->countBuild = $buildInfo['count'];
$return->countBuildAll = $return->offset;
$return->subCount = [
'countBuildAll' => $categoryUniverseModel->getTypesCount(false)
];
break;
case 'SystemStatic':
$length = 300;
$buildInfo = $this->setupSystemStaticTable($offset, $length);
$return->offset = $buildInfo['offset'];
$return->countAll = $buildInfo['countAll'];
$return->countBuild = $buildInfo['count'];
$return->countBuildAll = $return->offset;
break;
case 'SystemNeighbour':
$length = 1500;
$buildInfo = $this->setupSystemJumpTable($offset, $length);
$return->offset = $buildInfo['offset'];
$return->countAll = $buildInfo['countAll'];
$return->countBuild = $buildInfo['count'];
$return->countBuildAll = $return->offset;
break;
}
$return->progress = $percent($return->countAll, $return->countBuildAll);
if($return->countBuildAll < $return->countAll){
$return->count++;
}
echo json_encode($return);
}
/**
* clear search index
* @param \Base $f3
* @throws \Exception
*/
public function clearIndex(\Base $f3){
$postData = (array)$f3->get('POST');
$type = (string)$postData['type'];
$return = (object) [];
$return->error = [];
$return->type = $type;
$return->count = 0;
$return->countAll = 0;
$return->countBuild = 0;
$return->countBuildAll = 0;
$return->progress = 0;
$controller = new Controller\Ccp\Universe();
switch($type) {
case 'Systems':
$controller->clearSystemsIndex();
$systemUniverseModel = Model\Universe\AbstractUniverseModel::getNew('SystemModel');
$return->countAll = $systemUniverseModel->getRowCount();
break;
case 'SystemNeighbour':
$systemNeighbourModel = Model\Universe\AbstractUniverseModel::getNew('SystemNeighbourModel');
$systemNeighbourModel->truncate();
$return->countAll = (int)$f3->get('REQUIREMENTS.DATA.NEIGHBOURS');
break;
}
echo json_encode($return);
}
/**
* import static 'system_static` table data from *.csv
* @param int $offset
* @param int $length
* @return array
* @throws \Exception
*/
protected function setupSystemStaticTable(int $offset = 0, int $length = 0) : array {
$info = ['countAll' => 0, 'countChunk' => 0, 'count' => 0, 'offset' => $offset];
/**
* @var $systemStaticModel Model\Universe\SystemStaticModel
*/
$systemStaticModel = Model\Universe\AbstractUniverseModel::getNew('SystemStaticModel');
if(!empty($csvData = $systemStaticModel::getCSVData($systemStaticModel->getTable()))){
$info['countAll'] = count($csvData);
if($length){
$csvData = array_slice($csvData, $offset, $length);
}
$info['countChunk'] = count($csvData);
$cols = ['typeId' => [], 'systemId' => []];
foreach($csvData as $data){
$validColCount = 0;
$systemStaticModel->getById((int)$data['id'], 0);
$systemStaticModel->id = (int)$data['id'];
foreach($cols as $col => &$invalidIds){
if($systemStaticModel->exists($col)){
$colVal = (int)$data[$col];
if(!in_array($colVal, $invalidIds)){
$relModel = $systemStaticModel->rel($col);
$relModel->getById($colVal, 0);
if($relModel->valid()){
$systemStaticModel->$col = $relModel;
$validColCount++;
}else{
$invalidIds[] = $colVal;
break;
}
}else{
break;
}
}
}
if($validColCount == count($cols)){
$systemStaticModel->save();
}
$systemStaticModel->reset();
$info['count']++;
$info['offset']++;
}
}
return $info;
}
/**
* This function is just for setting up the cache table 'system_neighbour' which is used
* for system jump calculation. Call this function manually when CCP adds Systems/Stargates
* @param int $offset
* @param int $length
* @return array
*/
protected function setupSystemJumpTable(int $offset = 0, int $length = 0) : array {
$info = ['countAll' => 0, 'countChunk' => 0, 'count' => 0, 'offset' => $offset];
$universeDB = $this->getDB('UNIVERSE');
$query = "SELECT SQL_CALC_FOUND_ROWS
`system`.`id` `systemId`,
`system`.`name` `systemName`,
`system`.`constellationId` `constellationId`,
ROUND( `system`.`securityStatus`, 4) `trueSec`,
`constellation`.`regionId` `regionId`,
(
SELECT
GROUP_CONCAT( NULLIF(`sys_inner`.`id`, NULL) SEPARATOR ':')
FROM
`stargate` INNER JOIN
`system` `sys_inner` ON
`sys_inner`.`id` = `stargate`.`destinationSystemId`
WHERE
`stargate`.`systemId` = `system`.`id`
) `jumpNodes`
FROM
`system` INNER JOIN
`constellation` ON
`constellation`.`id` = `system`.`constellationId`
WHERE
`constellation`.`regionId` != :regionIdJove1 AND
`constellation`.`regionId` != :regionIdJove2 AND
`constellation`.`regionId` != :regionIdJove3 AND
(
`system`.`security` = :ns OR
`system`.`security` = :ls OR
`system`.`security` = :hs
)
HAVING
`jumpNodes` IS NOT NULL
";
$args = [
':regionIdJove1' => 10000017,
':regionIdJove2' => 10000019,
':regionIdJove3' => 10000004,
':ns' => '0.0',
':ls' => 'L',
':hs' => 'H'
];
if($length){
$query .= ' LIMIT :limit';
$args[':limit'] = $length;
if($offset){
$query .= ' OFFSET :offset';
$args[':offset'] = $offset;
}
}
$rows = $universeDB->exec($query, $args);
if(!empty($countRes = $universeDB->exec("SELECT FOUND_ROWS() `count`")) && isset($countRes[0]['count'])){
$info['countAll'] = (int)$countRes[0]['count'];
}
if($info['countChunk'] = count($rows)){
$placeholderStr = function(string $str) : string {
return ':' . $str;
};
$updateRule = function(string $str) : string {
return $str . " = VALUES(" . $str . ")";
};
$universeDB->begin();
foreach($rows as $row){
$info['count']++;
$info['offset']++;
if(!$row['jumpNodes']){
// should never happen!
continue;
}
$columns = array_keys($row);
$columnsQuoted = array_map($universeDB->quotekey, $columns);
$placeholder = array_map($placeholderStr, $columns);
$args = array_combine($placeholder, $row);
$updateSql = array_map($updateRule, $columns);
$sql = "INSERT INTO
system_neighbour(" . implode(', ', $columnsQuoted) . ")
VALUES(" . implode(', ', $placeholder) . ")
ON DUPLICATE KEY UPDATE
" . implode(', ', $updateSql);
$universeDB->exec($sql, $args);
}
$universeDB->commit();
}
return $info;
}
}