mirror of https://github.com/FriendsOfTYPO3/tea.git synced 2024-11-22 16: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 Context $context;
private TeaRepository $teaRepository; protected TeaRepository $teaRepository;
public function __construct(Context $context, TeaRepository $teaRepository) public function __construct(Context $context, TeaRepository $teaRepository)
{ {
@ -60,7 +60,7 @@ class FrontEndEditorController extends ActionController
/** /**
* @throws \RuntimeException * @throws \RuntimeException
*/ */
private function checkIfUserIsOwner(Tea $tea): void protected function checkIfUserIsOwner(Tea $tea): void
{ {
if ($tea->getOwnerUid() !== $this->getUidOfLoggedInUser()) { if ($tea->getOwnerUid() !== $this->getUidOfLoggedInUser()) {
throw new \RuntimeException('You do not have the permissions to edit this tea.', 1687363749); 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; 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. // 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; $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' => [ '1' => [
'showitem' => 'showitem' =>
'--div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:general, '--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, --div--;LLL:EXT:tea/Resources/Private/Language/locallang_db.xlf:tx_tea_domain_model_product_tea.tabs.access,
--palette--;;hidden, --palette--;;hidden,
--palette--;;access,', --palette--;;access,',
@ -202,6 +202,16 @@ $tca = [
'hideSuggest' => true, '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> <source>Title</source>
<target>Titel</target> <target>Titel</target>
</trans-unit> </trans-unit>
<trans-unit id="plugin.tea.property.stars">
<source>Stars</source>
<target>Sterne</target>
</trans-unit>
<trans-unit id="plugin.frontEndEditor.index.heading"> <trans-unit id="plugin.frontEndEditor.index.heading">
<source>My teas</source> <source>My teas</source>
<target>Meine Tees</target> <target>Meine Tees</target>
@ -55,6 +59,10 @@
<source>Actions</source> <source>Actions</source>
<target>Aktionen</target> <target>Aktionen</target>
</trans-unit> </trans-unit>
<trans-unit id="plugin.frontEndEditor.action.rating">
<source>Rating</source>
<target>Bewertung</target>
</trans-unit>
<trans-unit id="plugin.frontEndEditor.action.edit"> <trans-unit id="plugin.frontEndEditor.action.edit">
<source>Edit</source> <source>Edit</source>
<target>Bearbeiten</target> <target>Bearbeiten</target>

View file

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

View file

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

View file

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

View file

@ -25,6 +25,17 @@
<f:render partial="FrontEndEditor/ValidationResult" arguments="{property: 'description'}"/> <f:render partial="FrontEndEditor/ValidationResult" arguments="{property: 'description'}"/>
</div> </div>
</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> </fieldset>
<div class="d-flex justify-content-end mt-3 mb-3"> <div class="d-flex justify-content-end mt-3 mb-3">

View file

@ -26,6 +26,9 @@
<th scope="col" colspan="2"> <th scope="col" colspan="2">
<f:translate key="plugin.frontEndEditor.action.actions"/> <f:translate key="plugin.frontEndEditor.action.actions"/>
</th> </th>
<th scope="col" colspan="2">
<f:translate key="plugin.frontEndEditor.action.rating"/>
</th>
</tr> </tr>
<f:for each="{teas}" as="tea"> <f:for each="{teas}" as="tea">
<tr> <tr>
@ -46,6 +49,14 @@
class="btn btn-danger"/> class="btn btn-danger"/>
</f:form> </f:form>
</td> </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> </tr>
</f:for> </f:for>
</table> </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> <h2>
<f:translate key="plugin.tea.heading"/> <f:translate key="plugin.tea.heading"/>
</h2> </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"> <table class="table">
<thead> <thead>
<tr> <tr>

View file

@ -3,6 +3,7 @@
declare(strict_types=1); declare(strict_types=1);
use TTN\Tea\Controller\FrontEndEditorController; use TTN\Tea\Controller\FrontEndEditorController;
use TTN\Tea\Controller\RatingController;
use TTN\Tea\Controller\TeaController; use TTN\Tea\Controller\TeaController;
use TYPO3\CMS\Extbase\Utility\ExtensionUtility; use TYPO3\CMS\Extbase\Utility\ExtensionUtility;
@ -17,6 +18,7 @@ ExtensionUtility::configurePlugin(
// all actions // all actions
[ [
TeaController::class => 'index', TeaController::class => 'index',
RatingController::class => 'filter'
], ],
// non-cacheable actions // non-cacheable actions
[ [
@ -43,11 +45,13 @@ ExtensionUtility::configurePlugin(
// all actions // all actions
[ [
FrontEndEditorController::class => 'index, edit, update, create, new, delete', FrontEndEditorController::class => 'index, edit, update, create, new, delete',
RatingController::class => 'filter,rating'
], ],
// non-cacheable actions // non-cacheable actions
[ [
// All actions need to be non-cacheable because they either contain dynamic data, // 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). // 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', 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, description varchar(2000) DEFAULT '' NOT NULL,
image int(11) unsigned DEFAULT '0' NOT NULL, image int(11) unsigned DEFAULT '0' NOT NULL,
owner int(11) unsigned DEFAULT '0' NOT NULL, owner int(11) unsigned DEFAULT '0' NOT NULL,
stars int(11) unsigned DEFAULT NULL,
KEY owner (owner) KEY owner (owner)
); );