mirror of https://github.com/FriendsOfTYPO3/tea.git synced 2024-11-22 10:36:13 +01:00

[TASK] add rating functionality as use case for #893

Ref:#893
This commit is contained in:
Eike Starkmann 2023-11-27 15:44:16 +01:00
parent 58971754c4
commit d9c723e2a3
14 changed files with 159 additions and 4 deletions

View file

@ -19,7 +19,7 @@ class FrontEndEditorController extends ActionController
{
private Context $context;
private TeaRepository $teaRepository;
protected TeaRepository $teaRepository;
public function __construct(Context $context, TeaRepository $teaRepository)
{
@ -60,7 +60,7 @@ class FrontEndEditorController extends ActionController
/**
* @throws \RuntimeException
*/
private function checkIfUserIsOwner(Tea $tea): void
protected function checkIfUserIsOwner(Tea $tea): void
{
if ($tea->getOwnerUid() !== $this->getUidOfLoggedInUser()) {
throw new \RuntimeException('You do not have the permissions to edit this tea.', 1687363749);

View file

@ -0,0 +1,28 @@
<?php
namespace TTN\Tea\Controller;
use Psr\Http\Message\ResponseInterface;
use TTN\Tea\Domain\Model\Product\Tea;
use TTN\Tea\Domain\Repository\Product\TeaRepository;
use TYPO3\CMS\Core\Context\Context;
use TYPO3\CMS\Extbase\Persistence\Generic\QueryResult;
class RatingController extends FrontEndEditorController
{
public function ratingAction(Tea $tea, int $stars)
{
$this->checkIfUserIsOwner($tea);
$tea->setStars($stars);
$this->teaRepository->update($tea);
return $this->redirect('index','FrontEndEditor');
}
public function filterAction(int $stars)
{
$this->view->assign('teas', $this->teaRepository->findByStars($stars));
return $this->htmlResponse();
}
}

View file

@ -32,6 +32,11 @@ class Tea extends AbstractEntity
*/
protected $image;
/**
* @var int
*/
protected $stars = null;
// Note: We cannot use `@var` for the more specific type annotation here as this confuses the Extbase type mapper.
/**
@ -90,4 +95,23 @@ class Tea extends AbstractEntity
{
$this->ownerUid = $ownerUid;
}
/**
* @return int|null
*/
public function getStars(): ?int
{
return $this->stars;
}
/**
* @param int|null $stars
* @return void
*/
public function setStars(?int $stars): void
{
$this->stars = $stars;
}
}

View file

@ -25,7 +25,7 @@ $tca = [
'1' => [
'showitem' =>
'--div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:general,
title, description, image, owner,
title, description, image, stars, owner,
--div--;LLL:EXT:tea/Resources/Private/Language/locallang_db.xlf:tx_tea_domain_model_product_tea.tabs.access,
--palette--;;hidden,
--palette--;;access,',
@ -202,6 +202,16 @@ $tca = [
'hideSuggest' => true,
],
],
'stars' => [
'exclude' => true,
'label' => 'LLL:EXT:tea/Resources/Private/Language/locallang_db.xlf:tx_tea_domain_model_product_tea.stars',
'config' => [
'type' => 'input',
'size' => 8,
'eval' => 'trim',
'max' => 255,
]
],
],
];

View file

@ -27,6 +27,10 @@
<source>Title</source>
<target>Titel</target>
</trans-unit>
<trans-unit id="plugin.tea.property.stars">
<source>Stars</source>
<target>Sterne</target>
</trans-unit>
<trans-unit id="plugin.frontEndEditor.index.heading">
<source>My teas</source>
<target>Meine Tees</target>
@ -55,6 +59,10 @@
<source>Actions</source>
<target>Aktionen</target>
</trans-unit>
<trans-unit id="plugin.frontEndEditor.action.rating">
<source>Rating</source>
<target>Bewertung</target>
</trans-unit>
<trans-unit id="plugin.frontEndEditor.action.edit">
<source>Edit</source>
<target>Bearbeiten</target>

View file

@ -35,6 +35,10 @@
<source>Visible</source>
<target>Sichtbar</target>
</trans-unit>
<trans-unit id="tx_tea_domain_model_product_tea.stars">
<source>Stars</source>
<target>Sterne</target>
</trans-unit>
</body>
</file>
</xliff>

View file

@ -36,12 +36,18 @@
<trans-unit id="plugin.frontEndEditor.property.title">
<source>Title</source>
</trans-unit>
<trans-unit id="plugin.frontEndEditor.property.stars">
<source>Stars</source>
</trans-unit>
<trans-unit id="plugin.frontEndEditor.edit.heading">
<source>Edit tea</source>
</trans-unit>
<trans-unit id="plugin.frontEndEditor.action.actions">
<source>Actions</source>
</trans-unit>
<trans-unit id="plugin.frontEndEditor.action.rating">
<source>Rating</source>
</trans-unit>
<trans-unit id="plugin.frontEndEditor.action.edit">
<source>Edit</source>
</trans-unit>

View file

@ -27,6 +27,9 @@
<trans-unit id="tx_tea_domain_model_product_tea.hidden">
<source>Visible</source>
</trans-unit>
<trans-unit id="tx_tea_domain_model_product_tea.stars">
<source>Stars</source>
</trans-unit>
</body>
</file>
</xliff>

View file

@ -25,6 +25,17 @@
<f:render partial="FrontEndEditor/ValidationResult" arguments="{property: 'description'}"/>
</div>
</div>
<div class="row mb-3">
<label for="{idPrefix}-stars" class="col-sm-2 col-form-label">
<f:translate key="{propertyLabelPrefix}.stars"/>
</label>
<div class="col-sm-10">
<f:form.textfield property="stars" id="{idPrefix}-stars" maxlength="5"
class="form-control" errorClass="is-invalid" required="required"/>
<f:render partial="FrontEndEditor/ValidationResult" arguments="{property: 'stars'}"/>
</div>
</div>
</fieldset>
<div class="d-flex justify-content-end mt-3 mb-3">

View file

@ -26,6 +26,9 @@
<th scope="col" colspan="2">
<f:translate key="plugin.frontEndEditor.action.actions"/>
</th>
<th scope="col" colspan="2">
<f:translate key="plugin.frontEndEditor.action.rating"/>
</th>
</tr>
<f:for each="{teas}" as="tea">
<tr>
@ -46,6 +49,14 @@
class="btn btn-danger"/>
</f:form>
</td>
<td>
<f:link.action action="rating" controller="Rating" arguments="{tea:tea,stars:1}">1</f:link.action>
<f:link.action action="rating" controller="Rating" arguments="{tea:tea,stars:2}">2</f:link.action>
<f:link.action action="rating" controller="Rating" arguments="{tea:tea,stars:3}">3</f:link.action>
<f:link.action action="rating" controller="Rating" arguments="{tea:tea,stars:4}">4</f:link.action>
<f:link.action action="rating" controller="Rating" arguments="{tea:tea,stars:5}">5</f:link.action>
({tea.stars})
</td>
</tr>
</f:for>
</table>

View file

@ -0,0 +1,41 @@
<!DOCTYPE html>
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" data-namespace-typo3-fluid="true">
<f:layout name="Default"/>
<f:section name="main">
<h2>
<f:translate key="plugin.tea.heading"/>
</h2>
<f:link.action action="filter" controller="Rating" arguments="{stars:1}">1</f:link.action>
<f:link.action action="filter" controller="Rating" arguments="{tea:tea,stars:2}">2</f:link.action>
<f:link.action action="filter" controller="Rating" arguments="{tea:tea,stars:3}">3</f:link.action>
<f:link.action action="filter" controller="Rating" arguments="{tea:tea,stars:4}">4</f:link.action>
<f:link.action action="filter" controller="Rating" arguments="{tea:tea,stars:5}">5</f:link.action>
<table class="table">
<thead>
<tr>
<th>
<f:translate key="plugin.tea.property.uid"/>
</th>
<th>
<f:translate key="plugin.tea.property.title"/>
</th>
</tr>
</thead>
<tbody>
<f:for each="{teas}" as="tea">
<tr>
<td>
{tea.uid}
</td>
<td>
<f:link.action action="show" arguments="{tea: tea}" pageUid="{settings.singleViewPageUid}">
{tea.title}
</f:link.action>
</td>
</tr>
</f:for>
</tbody>
</table>
</f:section>
</html>

View file

@ -6,7 +6,11 @@
<h2>
<f:translate key="plugin.tea.heading"/>
</h2>
<f:link.action action="filter" controller="Rating" arguments="{stars:1}">1</f:link.action>
<f:link.action action="filter" controller="Rating" arguments="{tea:tea,stars:2}">2</f:link.action>
<f:link.action action="filter" controller="Rating" arguments="{tea:tea,stars:3}">3</f:link.action>
<f:link.action action="filter" controller="Rating" arguments="{tea:tea,stars:4}">4</f:link.action>
<f:link.action action="filter" controller="Rating" arguments="{tea:tea,stars:5}">5</f:link.action>
<table class="table">
<thead>
<tr>

View file

@ -3,6 +3,7 @@
declare(strict_types=1);
use TTN\Tea\Controller\FrontEndEditorController;
use TTN\Tea\Controller\RatingController;
use TTN\Tea\Controller\TeaController;
use TYPO3\CMS\Extbase\Utility\ExtensionUtility;
@ -17,6 +18,7 @@ ExtensionUtility::configurePlugin(
// all actions
[
TeaController::class => 'index',
RatingController::class => 'filter'
],
// non-cacheable actions
[
@ -43,11 +45,13 @@ ExtensionUtility::configurePlugin(
// all actions
[
FrontEndEditorController::class => 'index, edit, update, create, new, delete',
RatingController::class => 'filter,rating'
],
// non-cacheable actions
[
// All actions need to be non-cacheable because they either contain dynamic data,
// or because they are specific to the logged-in FE user (while FE content is cached by FE groups).
FrontEndEditorController::class => 'index, edit, update, create, new, delete',
RatingController::class => 'rating'
]
);

View file

@ -3,6 +3,7 @@ CREATE TABLE tx_tea_domain_model_product_tea (
description varchar(2000) DEFAULT '' NOT NULL,
image int(11) unsigned DEFAULT '0' NOT NULL,
owner int(11) unsigned DEFAULT '0' NOT NULL,
stars int(11) unsigned DEFAULT NULL,
KEY owner (owner)
);