Commit 502646cf authored by Stefan Busemann's avatar Stefan Busemann
Browse files

Merge branch 'task/integrate-roadmap-extension' into 'develop'

Integrate typo3_roadmap extension

Closes #7, #10, #6, #13, #11, #14, #18, #19, #15, #21, #22, #23, #24, #25, #26, and #9

See merge request services/typo3.org/typo3.org!416
parents 36e6a529 15e96c1f
Pipeline #10248 passed with stages
in 5 minutes and 52 seconds
This diff is collapsed.
<?php
declare(strict_types = 1);
namespace T3o\Typo3Roadmap\Controller;
/**
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/
use T3o\Typo3Roadmap\Domain\Repository\FeatureAreaRepository;
use T3o\Typo3Roadmap\Domain\Repository\FeatureRepository;
use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
/**
* FeatureController
*/
class FeatureController extends ActionController
{
/**
* featureRepository
*
* @var \T3o\Typo3Roadmap\Domain\Repository\FeatureRepository
*/
protected $featureRepository = null;
/**
* featureAreaRepository
*
* @var \T3o\Typo3Roadmap\Domain\Repository\FeatureAreaRepository
*/
protected $featureAreaRepository = null;
public function injectFeatureRepository(FeatureRepository $featureRepository): void
{
$this->featureRepository = $featureRepository;
}
public function injectFeatureAreaRepository(FeatureAreaRepository $featureAreaRepository): void
{
$this->featureAreaRepository = $featureAreaRepository;
}
/**
* action listFeatures
*/
public function listFeaturesAction(): void
{
if ($this->settings['featurearea'] !== '') {
$featureArea = $this->featureAreaRepository->findByUid((int)$this->settings['featurearea']);
$this->view->assign('featureArea', $featureArea);
}
$features = $this->featureRepository->findByFilter($this->settings);
$this->view->assign('features', $features);
}
/**
* action showRecord
*/
public function showFeatureRecordsAction(): void
{
$features = [];
$ids = explode(',', $this->settings['feature']);
foreach ($ids as $id) {
$features[$id] = $this->featureRepository->findByUid((int)$id);
}
$this->view->assign('features', $features);
}
/**
* action showRecord
*/
public function showFeatureAreaRecordsAction(): void
{
$featureAreas = [];
$ids = explode(',', $this->settings['featureArea']);
foreach ($ids as $id) {
$featureAreas[$id] = $this->featureAreaRepository->findByUid((int)$id);
}
$this->view->assign('featureAreas', $featureAreas);
}
}
<?php
declare(strict_types = 1);
namespace T3o\Typo3Roadmap\Controller;
/**
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/
use T3o\Typo3Roadmap\Domain\Model\MajorVersion;
use T3o\Typo3Roadmap\Domain\Repository\MajorVersionRepository;
use T3o\Typo3Roadmap\Domain\Repository\PhpVersionRepository;
use TYPO3\CMS\Core\Page\PageRenderer;
use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
/**
* Class \T3o\Typo3Roadmap\Controller\RoadmapController
* @author Sebastian Diez
*/
class RoadmapController extends ActionController
{
/*
* Color Codes for the charts
*/
const COLOR_CODE_REGULAR = '#69A550';
const COLOR_CODE_SECURITY = '#FF8700';
const COLOR_CODE_ELTS = '#ffb767';
const COLOR_CODE_SPRINT = '#e6e6e6';
const COLOR_CODE_STABILIZATION = '#983030';
/**
* majorVersionRepository
*
* @var \T3o\Typo3Roadmap\Domain\Repository\MajorVersionRepository
*/
protected $majorVersionRepository = null;
/**
* majorVersionRepository
*
* @var \T3o\Typo3Roadmap\Domain\Repository\PhpVersionRepository
*/
protected $phpVersionRepository = null;
public function injectMajorVersionRepository(MajorVersionRepository $majorVersionRepository): void
{
$this->majorVersionRepository = $majorVersionRepository;
}
public function injectPhpVersionRepository(PhpVersionRepository $phpVersionRepository): void
{
$this->phpVersionRepository = $phpVersionRepository;
}
/**
* action roadmap
*/
public function roadmapAction(): void
{
$majorVersions = array_reverse($this->majorVersionRepository->findAll()->toArray());
$this->view->assign('majorVersions', $majorVersions);
$phpVersions = $this->phpVersionRepository->findAll()->toArray();
$this->view->assign('phpVersions', $phpVersions);
$this->renderCharts($majorVersions);
}
/**
* Renders the LTS charts
*
* @param MajorVersion[] $majorVersions
*/
protected function renderCharts($majorVersions): void
{
/** @var PageRenderer $pageRenderer */
$pageRenderer = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(PageRenderer::class);
$pageRenderer->addJsFooterLibrary('amcharts', 'EXT:typo3_roadmap/Resources/Public/JavaScript/amcharts.min.js');
$pageRenderer->addJsFooterLibrary('amcharts_serial', 'EXT:typo3_roadmap/Resources/Public/JavaScript/serial.min.js');
$pageRenderer->addJsFooterLibrary('amcharts_gantt', 'EXT:typo3_roadmap/Resources/Public/JavaScript/gantt.min.js');
$pageRenderer->addJsFooterLibrary('amcharts_lightheme', 'EXT:typo3_roadmap/Resources/Public/JavaScript/lighttheme.min.js');
$pageRenderer->addJsFooterLibrary('amcharts_export', 'EXT:typo3_roadmap/Resources/Public/JavaScript/export.min.js');
$pageRenderer->addCssFile('EXT:typo3_roadmap/Resources/Public/Css/export.css');
// @TODO comment css
$data = $this->generateChartArray($majorVersions);
$this->view->assign('data', $data);
$chartJs = '
AmCharts.useUTC = true;
var today = new Date();
var chart = AmCharts.makeChart("charts", {
"type": "gantt",
"theme": "light",
"period": "YYYY",
"dataDateFormat": "YYYY-MM-DD",
"pathToImages": "/typo3conf/ext/typo3_roadmap/Resources/Public/Images/",
"columnWidth": 0.65,
"precision": 1,
"valueAxis": {
"type": "date",
"autoGridCount": false,
"gridCount": 24,
"guides": [
{
"value": today,
"toValue": today,
"lineAlpha": 1,
"lineThickness": 1,
"inside": true,
"labelRotation": 90,
"label": "Today",
"above": true
}
]
},
"graph": {
"fillAlphas": 1,
"balloonText": "<b>[[task]]</b>: [[open]]-[[value]]"
},
"rotate": true,
"categoryField": "version",
"segmentsField": "segments",
"colorField": "color",
"startDateField": "start",
"endDateField": "end",
"dataProvider": ' . json_encode($data) . ',
"valueScrollbar": {
"autoGridCount": true,
"color": "#555555"
},
"chartCursor": {
"cursorColor": "#55bb76",
"valueBalloonsEnabled": false,
"cursorAlpha": 0,
"valueLineAlpha": 0.5,
"valueLineBalloonEnabled": true,
"valueLineEnabled": true,
"zoomable": false,
"valueZoomable": true
},
"export": {
"enabled": false,
"menu": [
"PNG","PDF", "SVG"
]
}
});
';
$pageRenderer->addJsFooterInlineCode('ltsChart', $chartJs);
}
/**
* Central date formatter
*
* @param int $timeStamp
*
* @return bool|string
*/
protected function dateFromTimestamp($timeStamp = 0): ?string
{
$date = date('Y-m-d', $timeStamp);
return $date ?: null;
}
/**
* Creates the raw JSON data for the chart
* This is rather complex so take your time
*
* @param MajorVersion[] $majorVersions
*
* @return array
*/
protected function generateChartArray($majorVersions): array
{
$data = [];
foreach ($majorVersions as $index => $majorVersion) {
$firstStart = (int)$majorVersion->getDevelopmentStart();
$data[$index]['version'] = $majorVersion->getTitle();
foreach ($majorVersion->getMinorVersions() as $minorIndex => $minorVersion) {
/* @var \T3o\Typo3Roadmap\Domain\Model\MinorVersion $minorVersion */
$realDate = (int)$minorVersion->getEstimated();
if ((int)$minorVersion->getReleased() >= (int)$minorVersion->getEstimated()) {
$realDate = (int)$minorVersion->getReleased();
}
// Check if we are in the first loop
if ($minorIndex === 0) {
$sprintStart = $firstStart = (int)$majorVersion->getDevelopmentStart();
} else {
/* @var \T3o\Typo3Roadmap\Domain\Model\MinorVersion $minorVersion */
$previousMinorVersion = $majorVersion->getMinorVersions()[$minorIndex - 1];
$sprintStart = $previousMinorVersion->getEstimated();
if ((int)$previousMinorVersion->getReleased() >= (int)$previousMinorVersion->getEstimated()) {
$sprintStart = (int)$previousMinorVersion->getReleased();
}
}
//Sprint Segment
$data[$index]['segments'][] = [
'start' => $this->dateFromTimestamp($sprintStart),
'end' => $this->dateFromTimestamp($realDate - 1209600),
'color' => self::COLOR_CODE_SPRINT,
'task' => 'Sprint Phase ' . $minorVersion->getVersion()
];
//Stabilization Segment
$data[$index]['segments'][] = [
'start' => $this->dateFromTimestamp($realDate - 1209600),
'end' => $this->dateFromTimestamp($realDate),
'color' => self::COLOR_CODE_STABILIZATION,
'task' => 'Stabilization Phase ' . $minorVersion->getVersion()
];
// Set the last release date as start of maintenance
$firstStart = $realDate;
}
/**
* Set Maintenance Times
*/
// Regular Maintenance
$data[$index]['segments'][] = [
'start' => $this->dateFromTimestamp($firstStart),
'end' => $this->dateFromTimestamp($majorVersion->getRegularSupport()),
'color' => self::COLOR_CODE_REGULAR,
'task' => 'Regular Maintenance'
];
// Security Maintenance
$data[$index]['segments'][] = [
'start' => $this->dateFromTimestamp($majorVersion->getRegularSupport()),
'end' => $this->dateFromTimestamp($majorVersion->getPrioritySupport()),
'color' => self::COLOR_CODE_SECURITY,
'task' => 'Priority bugfixes'
];
// ELTS Maintenance
if ($majorVersion->getExtendedSupport() > 0) {
$data[$index]['segments'][] = [
'start' => $this->dateFromTimestamp($majorVersion->getPrioritySupport()),
'end' => $this->dateFromTimestamp($majorVersion->getExtendedSupport()),
'color' => self::COLOR_CODE_ELTS,
'task' => 'Extended support (optional)'
];
}
}
return $data;
}
}
<?php
declare(strict_types = 1);
namespace T3o\Typo3Roadmap\Domain\Model;
/**
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/
use TYPO3\CMS\Extbase\Annotation as Extbase;
use TYPO3\CMS\Extbase\DomainObject\AbstractEntity;
use TYPO3\CMS\Extbase\Persistence\ObjectStorage;
/**
* Feature
*/
class Feature extends AbstractEntity
{
/**
* header
*
* @var string
* @Extbase\Validate("NotEmpty")
*/
protected $header = '';
/**
* description
*
* @var string
* @Extbase\Validate("NotEmpty")
*/
protected $description = '';
/**
* images
*
* @var \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\TYPO3\CMS\Extbase\Domain\Model\FileReference>
* @TYPO3\CMS\Extbase\Annotation\ORM\Cascade("remove")
*/
protected $images = null;
/**
* link
*
* @var string
*/
protected $link = '';
/**
* typo3releaseminorversion
*
* @var \T3o\Typo3Roadmap\Domain\Model\MinorVersion
*/
protected $typo3releaseminorversion = null;
/**
* typo3releasemajorversion
*
* @var \T3o\Typo3Roadmap\Domain\Model\MajorVersion
*/
protected $typo3releasemajorversion = null;
/**
* featureArea
*
* @var \T3o\Typo3Roadmap\Domain\Model\FeatureArea
*/
protected $featureArea = null;
/**
* __construct
*/
public function __construct()
{
//Do not remove the next line: It would break the functionality
$this->initStorageObjects();
}
/**
* Initializes all ObjectStorage properties
* Do not modify this method!
* It will be rewritten on each save in the extension builder
* You may modify the constructor of this class instead
*/
protected function initStorageObjects(): void
{
$this->images = new ObjectStorage();
$this->typo3releasemajorversion = new ObjectStorage();
$this->typo3releaseminorversion = new ObjectStorage();
}
/**
* Returns the header
*
* @return string $header
*/
public function getHeader(): string
{
return $this->header;
}
/**
* Sets the header
*
* @param string $header
*/
public function setHeader(string $header): void
{
$this->header = $header;
}
/**
* Returns the description
*
* @return string $description
*/
public function getDescription(): string
{
return $this->description;
}
/**
* Sets the description
*
* @param string $description
*/
public function setDescription(string $description): void
{
$this->description = $description;
}
/**
* Returns the link
*
* @return string $link
*/
public function getLink(): string
{
return $this->link;
}
/**
* Sets the link
*
* @param string $link
*/
public function setLink(string $link): void
{
$this->link = $link;
}
/**
* Returns the featureArea
*
* @return \T3o\Typo3Roadmap\Domain\Model\FeatureArea $featureArea
*/
public function getFeatureArea(): FeatureArea
{
return $this->featureArea;
}
/**
* Sets the featureArea
*
* @param \T3o\Typo3Roadmap\Domain\Model\FeatureArea $featureArea
*/
public function setFeatureArea(FeatureArea $featureArea)
{
$this->featureArea = $featureArea;
}
/**
* Returns the typo3releaseminorversion
*
* @return \T3o\Typo3Roadmap\Domain\Model\MinorVersion
*/
public function getTypo3releaseminorversion(): MinorVersion
{
return $this->typo3releaseminorversion;
}
/**
* Sets the typo3releaseminorversion
*
* @param \T3o\Typo3Roadmap\Domain\Model\MinorVersion $typo3releaseminorversion
*/
public function setTypo3releaseminorversion(MinorVersion $typo3releaseminorversion): void
{
$this->typo3releaseminorversion = $typo3releaseminorversion;
}
/**
* Returns the typo3releasemajorversion
*
* @return \T3o\Typo3Roadmap\Domain\Model\MajorVersion
*/
public function getTypo3releasemajorversion(): MajorVersion
{
return $this->typo3releasemajorversion;
}
/**
* Sets the typo3releasemajorversion
*
* @param \T3o\Typo3Roadmap\Domain\Model\MajorVersion $typo3releasemajorversion
*/
public function setTypo3releasemajorversion(MajorVersion $typo3releasemajorversion): void
{
$this->typo3releasemajorversion = $typo3releasemajorversion;
}
/**
* Returns the images