Commit 3b625254 authored by Dainis Abols's avatar Dainis Abols
Browse files

Remade into custom caching system

v4.0.3
parent 2c30ea0e
......@@ -5,7 +5,7 @@ namespace Lu\LuNabamusic\Controller;
use Lu\LuNabamusic\Domain\Model\Play;
use Lu\LuNabamusic\Domain\Model\Top;
use Lu\LuNabamusic\Domain\Repository\SongRepository;
use TYPO3\CMS\Core\Cache\CacheManager;
use Lu\LuNabamusic\Helpers\CacheHelper;
use TYPO3\CMS\Core\Configuration\ExtensionConfiguration;
use TYPO3\CMS\Core\FormProtection\FormProtectionFactory;
use TYPO3\CMS\Core\Page\PageRenderer;
......@@ -94,7 +94,7 @@ class FrontController extends ActionController
// Preset used variables
$playModel = new Play();
$swap = $this->settings['pluginType'] ?? '';
$cache = GeneralUtility::makeInstance(CacheManager::class)->getCache('cache_naba_top');
$cacheHelper = new CacheHelper();
$data = [];
// Swap view types @TODO Make data gather to methods!
......@@ -148,7 +148,7 @@ class FrontController extends ActionController
];
} else {
$data['mostPlayedSongs'] = [
'songs' => $cache->get('most_played_songs') ?: $playModel->getMostPlayedSongs($limit),
'songs' => $cacheHelper->get('most_played_songs') ?: $playModel->getMostPlayedSongs($limit),
];
}
......@@ -179,7 +179,7 @@ class FrontController extends ActionController
];
} else {
$data['mostPlayedSongs'] = [
'songs' => $cache->get('todays_songs') ?: $playModel->getTodaysSongs(),
'songs' => $cacheHelper->get('todays_songs') ?: $playModel->getTodaysSongs(),
];
}
......@@ -207,14 +207,14 @@ class FrontController extends ActionController
*/
private function getTopSongs()
{
$cache = GeneralUtility::makeInstance(CacheManager::class)->getCache('cache_naba_top');
$data = $cache->get('naba_top_'.$this->settings['songsInTop']);
$cacheHelper = new CacheHelper();
$data = $cacheHelper->get('naba_top_'.$this->settings['songsInTop']);
$UriBuilder = $this->controllerContext->getUriBuilder()->reset()->setCreateAbsoluteUri(true);
// If songs list is not cached do it now
if(!$data) {
GeneralUtility::makeInstance(Top::class)->executeCron();
$data = $cache->get('naba_top_'.$this->settings['songsInTop']);
$data = $cacheHelper->get('naba_top_'.$this->settings['songsInTop']);
}
foreach ($data['songs'] as $key => $item) {
......
......@@ -108,6 +108,9 @@ class Play extends AbstractEntity
// Call song fetch option and fail if none available!
$apiSong = $this->fetchLiveEntry();
if (empty($apiSong)) {
// Update last song end time
$this->addEndTime();
return false;
}
......@@ -136,6 +139,9 @@ class Play extends AbstractEntity
// Check if song has changed
if ($apiSong['artist'] != $lastSong['artist'] && $apiSong['artist'] != $lastSong['artist']) {
// Update last song end time
$this->addEndTime();
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($this->tableName);
$affectedRows = $queryBuilder
->insert($this->tableName)
......@@ -145,6 +151,7 @@ class Play extends AbstractEntity
'title' => $apiSong['title'],
'first' => $firstTime,
'time' => $currentTime,
'endtime' => 0,
'prev' => $previousTime,
'checked' => 1,
'cron' => 1,
......@@ -191,12 +198,12 @@ class Play extends AbstractEntity
// If entry found, assign the name
while ($data = $programmResults->fetch()) {
$timeZone = date_default_timezone_get();
$newCDate = new \DateTime();
$newSDate = new \DateTime("@{$row['start_date']}", new \DateTimeZone('UTC'));
$newSDate->setTimeZone(new \DateTimeZone($timeZone));
$newEDate = new \DateTime("@{$row['end_date']}", new \DateTimeZone('UTC'));
$newEDate->setTimeZone(new \DateTimeZone($timeZone));
$newSDate = DateTime::createFromFormat('Y-m-d', $row['start_date'], new \DateTimeZone('UTC'));
$newEDate = new DateTime('today');
if (!empty($row['end_date'])) {
$newEDate = DateTime::createFromFormat('Y-m-d', $row['end_date'], new \DateTimeZone('UTC'));
}
// Check if day of week matches
if ($newSDate->format('w') <= $newCDate->format('w') && $newCDate->format('w') <= $newEDate->format('w')) {
......@@ -233,6 +240,11 @@ class Play extends AbstractEntity
$cachedSong = $currentSong;
}
// If last song has ended return programme title
if ($cachedSong['endtime'] != 0) {
return $this->getCurrentProgramme();
}
// Check if one-line return requested
if ($onLine) {
return $cachedSong['artist']." - ".$cachedSong['title'];
......@@ -423,4 +435,27 @@ class Play extends AbstractEntity
// Fetch config
$this->conf = GeneralUtility::makeInstance(ExtensionConfiguration::class)->get('lu_nabamusic');
}
/**
* Add end time to last played song
*/
private function addEndTime()
{
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable($this->tableName)->createQueryBuilder();
// Get last song uid
$queryBuilder->select('*')->orderBy('uid', 'DESC')->from($this->tableName)->setMaxResults(1);
$statement = $queryBuilder->execute();
$queryBuilder->update($this->tableName)
->where(
$queryBuilder->expr()->eq('uid', $statement->fetch()['uid'])
)
->andWhere(
$queryBuilder->expr()->eq('endtime', 0)
)
->set('endtime', time())
->execute();
}
}
......@@ -3,6 +3,7 @@
namespace Lu\LuNabamusic\Domain\Model;
use Lu\LuNabamusic\Domain\Repository\SongRepository;
use Lu\LuNabamusic\Helpers\CacheHelper;
use Lu\LuNabamusic\Interfaces\TableView;
use TYPO3\CMS\Core\Cache\CacheManager;
use TYPO3\CMS\Core\Configuration\ExtensionConfiguration;
......@@ -102,22 +103,22 @@ class Top extends AbstractEntity implements TableView
public function executeCron()
{
$objectManager = GeneralUtility::makeInstance(ObjectManager::class);
$cache = GeneralUtility::makeInstance(CacheManager::class)->getCache('cache_naba_top');
$songRepository = $objectManager->get(SongRepository::class);
$querySettings = $objectManager->get(Typo3QuerySettings::class);
$config = GeneralUtility::makeInstance(ExtensionConfiguration::class)->get('lu_nabamusic');
$cacheHelper = new CacheHelper();
$querySettings->setStoragePageIds([$config['top10StorageId']]);
$songRepository->setDefaultQuerySettings($querySettings);
$cache->set('naba_top_10', $this->buildSongList($songRepository, 10), [], $config['cacheTime']);
$cacheHelper->set('naba_top_10', $this->buildSongList($songRepository, 10));
$querySettings->setStoragePageIds([$config['top25StorageId']]);
$songRepository->setDefaultQuerySettings($querySettings);
$cache->set('naba_top_25', $this->buildSongList($songRepository, 25), [], $config['cacheTime']);
$cacheHelper->set('naba_top_25', $this->buildSongList($songRepository, 25));
$playModel = new Play();
$cache->set('todays_songs', $playModel->getTodaysSongs(), [], $config['cacheTime']);
$cache->set('most_played_songs', $playModel->getMostPlayedSongs(50), [], $config['cacheTime']);
$cacheHelper->set('todays_songs', $playModel->getTodaysSongs());
$cacheHelper->set('most_played_songs', $playModel->getMostPlayedSongs(50));
return true;
}
......
<?php
namespace Lu\LuNabamusic\Helpers;
/**
* Class CacheHelper
*
* @author Lauris Karklis <lauris,karklis@lu.lv>
* @owner University of Latvia
* @since 14.07.2021
*
* @package Lu\LuNabamusic\Helpers
*/
class CacheHelper
{
/**
* Table name
*
* @var string
*/
private $tableName = 'tx_lunabamusic_cache';
/**
* DB configuration
*
* @var mixed
*/
private $config;
/**
* PDO DB connector
*
* @var \PDO
*/
private \PDO $db;
/**
* CacheHelper constructor.
*/
public function __construct()
{
$this->config = require '/home/portal/typo3/typo3conf/LocalConfiguration.php';
$this->db = new \PDO(
'mysql:host='.$this->config['DB']['Connections']['Default']['host'].';dbname='.$this->config['DB']['Connections']['Default']['dbname'],
$this->config['DB']['Connections']['Default']['user'],
$this->config['DB']['Connections']['Default']['password']
);
}
/**
* Set cache
*
* @param $identifier
* @param $content
*/
public function set($identifier, $content)
{
// Read identifier
$query = $this->db->prepare("SELECT * FROM ".$this->tableName." WHERE identifier = :identifier");
$query->bindParam('identifier', $identifier, $this->db::PARAM_STR);
$query->execute();
if ($query->rowCount() == 0) {
// Make new entry
$query = $this->db->prepare("INSERT INTO ".$this->tableName." (crdate, identifier, content) VALUES (?, ?, ?)");
$query->execute([time(), $identifier, serialize($content)]);
} else {
// Update exiusting entry
$query = $this->db->prepare("UPDATE ".$this->tableName." SET crdate = :crdate, content = :content WHERE identifier = :identifier");
$content = serialize($content);
$time = time();
$query->bindParam('crdate', $time);
$query->bindParam('content', $content);
$query->bindParam('identifier', $identifier);
$query->execute();
}
}
/**
* Get cache
*
* @param $identifier
*
* @return false|mixed
*/
public function get($identifier)
{
// Read identifier
$query = $this->db->prepare("SELECT * FROM ".$this->tableName." WHERE identifier = :identifier");
$query->bindParam('identifier', $identifier, $this->db::PARAM_STR);
$query->execute();
// Return false ig nothing found
if ($query->rowCount() == 0) {
return false;
}
// Return cached data
return unserialize($query->fetch()['content']);
}
}
......@@ -4,19 +4,19 @@
## Version
4.0.2
4.0.3
## Dependencies
* TYPO3 v10+
* LU API v2.7+
* Calendarize v7+
## Author
Dainis Abols <dainis.abols@lu.lv>
Lauris Karklis <lauris.karklis@lu.lv>
## Template override constants
```
......@@ -24,7 +24,7 @@ Lauris Karklis <lauris.karklis@lu.lv>
view.templateRootPath = EXT:lu_nabamusic/Resources/Private/Templates/
view.partialRootPath = EXT:lu_nabamusic/Resources/Private/Partials/
view.layoutRootPath = EXT:lu_nabamusic/Resources/Private/Layouts/
settings.cssFile = EXT:lu_nabamusic/Resources/Public/Css/styles.css
settings.jsFile = EXT:lu_nabamusic/Resources/Public/JavaScript/scripts.js
}
......@@ -40,4 +40,3 @@ Lauris Karklis <lauris.karklis@lu.lv>
| streamServer | Streaming server endpoint |
| top10StorageId | Top 10 storage page id |
| top25StorageId | Top 25 storage page id |
| cacheTime | Time in seconds to keep tops in cache |
{
"name": "luitd/lu-nabamusic",
"version": "4.0.2",
"description": "Radio NABA plugin used for live stream, song tops and much more",
"type": "typo3-cms-extension",
"keywords": [
"TYPO3",
"extension"
],
"authors": [
{
"name": "Dainis Abols",
"email": "dainis@dainisabols.lv",
"role": "Developer"
},
{
"name": "Lauris Karklis",
"email": "lauris.karklis@lu.lv",
"role": "Developer"
}
],
"license": "GPL-3.0-or-later",
"require": {
"typo3/cms-core": "^10",
"luitd/lu-api": "^2.7"
},
"autoload": {
"psr-4": {
"Lu\\LuNabamusic\\": "Classes"
}
},
"replace": {
"typo3-ter/lu_nabamusic": "self.version"
},
"config": {
"vendor-dir": ".Build/vendor",
"bin-dir": ".Build/bin"
},
"scripts": {
"post-autoload-dump": [
"mkdir -p .Build/Web/typo3conf/ext/",
"[ -L .Build/Web/typo3conf/ext/lu_nabamusic ] || ln -snvf ../../../../. .Build/Web/typo3conf/ext/lu_nabamusic"
]
},
"extra": {
"typo3/cms": {
"extension-key": "lu_nabamusic",
"cms-package-dir": "{$vendor-dir}/typo3/cms",
"web-dir": ".Build/Web"
}
}
}
{
"name": "luitd/lu-nabamusic",
"version": "4.0.3",
"description": "Radio NABA plugin used for live stream, song tops and much more",
"type": "typo3-cms-extension",
"keywords": [
"TYPO3",
"extension"
],
"authors": [
{
"name": "Dainis Abols",
"email": "dainis@dainisabols.lv",
"role": "Developer"
},
{
"name": "Lauris Karklis",
"email": "lauris.karklis@lu.lv",
"role": "Developer"
}
],
"license": "GPL-3.0-or-later",
"require": {
"typo3/cms-core": "^10",
"luitd/lu-api": "^2.7"
},
"autoload": {
"psr-4": {
"Lu\\LuNabamusic\\": "Classes"
}
},
"replace": {
"typo3-ter/lu_nabamusic": "self.version"
},
"config": {
"vendor-dir": ".Build/vendor",
"bin-dir": ".Build/bin"
},
"scripts": {
"post-autoload-dump": [
"mkdir -p .Build/Web/typo3conf/ext/",
"[ -L .Build/Web/typo3conf/ext/lu_nabamusic ] || ln -snvf ../../../../. .Build/Web/typo3conf/ext/lu_nabamusic"
]
},
"extra": {
"typo3/cms": {
"extension-key": "lu_nabamusic",
"cms-package-dir": "{$vendor-dir}/typo3/cms",
"web-dir": ".Build/Web"
}
}
}
......@@ -18,6 +18,3 @@ top10StorageId =
# cat=Tops/set; type=string; label=Top 25 storage page id
top25StorageId =
# cat=Tops/set; type=string; label=Time in seconds to keep tops in cache
cacheTime =
......@@ -13,7 +13,7 @@ $EM_CONF[$_EXTKEY] = [
'modify_tables' => '',
'clearCacheOnLoad' => 1,
'lockType' => '',
'version' => '4.0.2',
'version' => '4.0.3',
'constraints' => [
'depends' => [
'typo3' => '10.0.0-10.9.99',
......
......@@ -23,10 +23,6 @@ call_user_func(
}
);
if (!is_array($GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['cache_naba_top'])) {
$GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['cache_naba_top'] = [];
}
// Initialize task scheduler
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['scheduler']['tasks']['Lu\\LuNabamusic\\Tasks\\SongGatherTask'] = [
'extension' => 'tx_lunabamusic',
......
......@@ -72,6 +72,7 @@ CREATE TABLE tx_lunabamusic_domain_model_play (
uid INT(11) NOT NULL AUTO_INCREMENT,
pid INT(11) DEFAULT 0 NOT NULL,
time INT(11) DEFAULT 0 NOT NULL,
endtime INT(11) DEFAULT 0 NOT NULL,
artist VARCHAR(100) DEFAULT '' NOT NULL,
title VARCHAR(100) DEFAULT '' NOT NULL,
prev INT(11) DEFAULT 0 NOT NULL,
......@@ -85,3 +86,16 @@ CREATE TABLE tx_lunabamusic_domain_model_play (
KEY skantitle (title),
KEY artisttitle (artist)
);
#
# Table structure for table 'tx_lunabamusic_cache'
#
CREATE TABLE tx_lunabamusic_cache
(
`id` INT(11) UNSIGNED DEFAULT 0 NOT NULL AUTO_INCREMENT,
`crdate` INT(11) DEFAULT 0 NOT NULL,
`identifier` VARCHAR(250) DEFAULT '' NOT NULL,
`content` LONGBLOB DEFAULT '' NOT NULL,
PRIMARY KEY (id)
);
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment