Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
MartkCz committed Sep 16, 2021
0 parents commit 5e44ac3
Show file tree
Hide file tree
Showing 15 changed files with 392 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.idea
composer.lock
vendor
11 changes: 11 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"name": "webchemistry/components",
"require": {
"php": ">=8.0"
},
"autoload": {
"psr-4": {
"Utilitte\\Components\\": "src"
}
}
}
37 changes: 37 additions & 0 deletions src/DI/ComponentsExtension.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php declare(strict_types = 1);

namespace Utilitte\Components\DI;

use Nette\DI\CompilerExtension;
use Utilitte\Components\Comments\Factory\CommentComponentFactory;
use Utilitte\Components\Comments\Factory\CommentFormComponentFactory;
use Utilitte\Components\Comments\Factory\CommentsComponentFactory;
use Utilitte\Components\Comments\Factory\CommentsLayoutComponentFactory;
use Utilitte\Components\Rating\RatingComponentFactory;

final class ComponentsExtension extends CompilerExtension
{

public function loadConfiguration(): void
{
$builder = $this->getContainerBuilder();

// rating
$builder->addFactoryDefinition($this->prefix('rating'))
->setImplement(RatingComponentFactory::class);

// comments
// $builder->addFactoryDefinition($this->prefix('comments.factory.comment'))
// ->setImplement(CommentComponentFactory::class);
//
// $builder->addFactoryDefinition($this->prefix('comments.factory.comments'))
// ->setImplement(CommentsComponentFactory::class);
//
// $builder->addFactoryDefinition($this->prefix('comments.factory.commentsLayout'))
// ->setImplement(CommentsLayoutComponentFactory::class);
//
// $builder->addFactoryDefinition($this->prefix('comments.factory.commentForm'))
// ->setImplement(CommentFormComponentFactory::class);
}

}
13 changes: 13 additions & 0 deletions src/Rating/Entity/RatingEntityInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php declare(strict_types = 1);

namespace Utilitte\Components\Rating\Entity;

interface RatingEntityInterface
{

/**
* Returns true if changed
*/
public function changeValue(int $value): bool;

}
44 changes: 44 additions & 0 deletions src/Rating/Model/DoctrineRatingModel.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php declare(strict_types = 1);

namespace Utilitte\Components\Rating\Model;

use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
use Doctrine\ORM\EntityManagerInterface;
use Utilitte\Components\Rating\Entity\RatingEntityInterface;
use Utilitte\Doctrine\DoctrineIdentityExtractor;

abstract class DoctrineRatingModel implements RatingModelInterface
{

public function __construct(
private EntityManagerInterface $em,
private DoctrineIdentityExtractor $doctrineIdentityExtractor,
)
{
}

public function voteByEntity(RatingEntityInterface $entity, int $value): void
{
$persisted = $this->em->find(
get_class($entity),
$this->doctrineIdentityExtractor->extractIdentities($entity, true)
);

if ($persisted) {
if ($persisted->changeValue($value)) {
$this->em->persist($persisted);
} else {
$this->em->remove($persisted);
}
} else {
$this->em->persist($entity);
}

try {
$this->em->flush();
} catch (UniqueConstraintViolationException) {
// nothing, already exists
}
}

}
12 changes: 12 additions & 0 deletions src/Rating/Model/RatingModelInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php declare(strict_types = 1);

namespace Utilitte\Components\Rating\Model;

interface RatingModelInterface
{

public function isVoteValueValid(int $value): bool;

public function vote(object $source, int $value): VoteResult;

}
25 changes: 25 additions & 0 deletions src/Rating/Model/VoteResult.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php declare(strict_types = 1);

namespace Utilitte\Components\Rating\Model;

final class VoteResult
{

public function __construct(
private int $difference,
private int $voted,
)
{
}

public function getDifference(): int
{
return $this->difference;
}

public function getVoted(): int
{
return $this->voted;
}

}
89 changes: 89 additions & 0 deletions src/Rating/RatingComponent.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
<?php declare(strict_types = 1);

namespace Utilitte\Components\Rating;

use Nette\Application\UI\Control;
use Nette\Security\User;
use Utilitte\Components\Rating\Model\RatingModelInterface;
use Utilitte\Components\Rating\ValueObject\Rating;
use Utilitte\Components\Utility\TControl;

final class RatingComponent extends Control
{

use TControl;

/** @var callable[] */
private array $onVoted = [];

private bool $set = false;

private int $increase = 0;

public function __construct(
private RatingModelInterface $model,
private Rating $rating,
private User $user,
)
{
}

public function addIncrease(int $amount): self
{
$this->increase += $amount;

return $this;
}

public function onVoted(callable $callback): void
{
$this->onVoted[] = $callback;
}

public function render(): void
{
$template = $this->getTemplate();
$template->setFile($this->getFile(__DIR__ . '/templates/rating.latte'));

if (!$this->set) {
$template->rating = $this->rating->getRating() + $this->increase;
$template->voted = $this->rating->getVoted();
}

$template->increase = $this->increase;
$template->canVote = $this->rating->canVote();

$template->render();
}

public function handleVote(int $value): void
{
$ajax = $this->getPresenter()->isAjax();
if (!$this->model->isVoteValueValid($value)) {
if ($ajax) {
return;
}

$this->redirect('this');
}

$result = $this->model->vote($this->rating->getSource(), $value);

foreach ($this->onVoted as $callback) {
$callback();
}

if ($ajax) {
$template = $this->getTemplate();
$template->rating = $this->rating->getRating() + $result->getDifference() + $this->increase;
$template->voted = $result->getVoted();

$this->set = true;

$this->redrawControl();
} else {
$this->redirect('this');
}
}

}
13 changes: 13 additions & 0 deletions src/Rating/RatingComponentFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php declare(strict_types = 1);

namespace Utilitte\Components\Rating;

use Utilitte\Components\Rating\Model\RatingModelInterface;
use Utilitte\Components\Rating\ValueObject\Rating;

interface RatingComponentFactory
{

public function create(RatingModelInterface $model, Rating $rating): RatingComponent;

}
37 changes: 37 additions & 0 deletions src/Rating/ValueObject/Rating.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php declare(strict_types = 1);

namespace Utilitte\Components\Rating\ValueObject;

final class Rating
{

public function __construct(
private object $source,
private int $rating,
private ?int $voted = null,
private bool $canVote = true,
)
{
}

public function canVote(): bool
{
return $this->canVote;
}

public function getSource(): object
{
return $this->source;
}

public function getRating(): int
{
return $this->rating;
}

public function getVoted(): ?int
{
return $this->voted;
}

}
7 changes: 7 additions & 0 deletions src/Rating/templates/rating.latte
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{if $user->isLoggedIn()}
<a n:href="vote! 1" n:tag-if="$voted !== 1">+</a>
<a n:href="vote! -1" n:tag-if="$voted !== -1">-</a>
{/if}

{$rating}

18 changes: 18 additions & 0 deletions src/Tabs/Tab.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php declare(strict_types = 1);

namespace Utilitte\Components\Tabs;

use Nette\Application\UI\Link;

final class Tab
{

public function __construct(
public string $name,
public Link $link,
public array $options,
)
{
}

}
52 changes: 52 additions & 0 deletions src/Tabs/TabsComponent.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?php declare(strict_types = 1);

namespace Utilitte\Components\Tabs;

use Nette\Application\UI\Control;
use Nette\Application\UI\Link;
use Utilitte\Components\Utility\TControl;

final class TabsComponent extends Control
{

use TControl;

/** @var Tab[] */
private array $tabs = [];

private bool $compareParameters = true;

public function add(string $name, Link $link, array $options = []): self
{
$this->tabs[] = new Tab($name, $link, $options);

return $this;
}

public function setCompareParameters(bool $compareParameters): self
{
$this->compareParameters = $compareParameters;

return $this;
}

private function isCurrentLink(Link $link): bool
{
return $this->getPresenter()->isLinkCurrent(
$link->getDestination(),
$this->compareParameters ? $link->getParameters() : []
);
}

public function render(): void
{
$template = $this->getTemplate();
$template->setFile($this->getFile(__DIR__ . '/templates/tabs.latte'));

$template->tabs = $this->tabs;
$template->addFunction('isCurrentLink', fn (Link $link) => $this->isCurrentLink($link));

$template->render();
}

}
9 changes: 9 additions & 0 deletions src/Tabs/templates/tabs.latte
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<div class="grid-cols-1">
<div class="tabs">
{foreach $tabs as $tab}
{var $isCurrent = isCurrentLink($tab->link)}

<a href="{$tab->link}" n:class="tab, $isCurrent ? active">{$tab->name}</a>
{/foreach}
</div>
</div>
Loading

0 comments on commit 5e44ac3

Please sign in to comment.