name: faktore/cta-banner
title: CTA Banner
description: 'A banner with selectable BG color and RTE text editor'
group: common
prefixFields: true
prefixType: vendor
fields:
- identifier: background
type: Select
renderType: selectSingle
items:
- label: 'Magenta (Standard)'
value: bg-brand-primary
- label: 'Turquoise '
value: bg-brand-secondary
- identifier: bodytext
useExistingField: true
enableRichtext: true
<?php
protected static array $gamesSteps = [
GetGames::class,
GetTeams::class,
GetSeasons::class,
BuildGamesDataHandlerArray::class,
BuildTeamsDataHandlerArray::class,
BuildSeasonTeamsDataHandlerArray::class,
BuildSeasonsDataHandlerArray::class,
GetTeamLogos::class,
SetGameSeasonTeamRelations::class,
SetGameSeasonRelations::class,
SetSeasonTeamSeasonRelations::class,
SetSeasonTeamTeamRelations::class,
ImportData::class
];
<?php
protected static array $standingsPipeline = [
GetStandings::class,
GetTeams::class,
GetTeamLogos::class,
GetSeasons::class,
BuildSeasonsDataHandlerArray::class,
BuildStandingsDataHandlerArray::class,
BuildTeamsDataHandlerArray::class,
BuildSeasonTeamsDataHandlerArray::class,
SetStandingSeasonRelations::class,
SetStandingSeasonTeamRelations::class,
SetSeasonTeamTeamRelations::class,
ImportData::class
];
May 13th, 2024 / Faktor E GmbH
<?php
class BlogPost
{
private Author $author;
private string $title;
private string $content;
private \DateTime $date;
// [...]
public function getData(): array
{
return [
'author' => $this->author->getFullName(),
'title' => $this->getTitle,
'content' => $this->getContent,
'timestamp' => $this->date->getTimestamp()
];
}
public function printJson(): string
{
return json_encode($this->getData());
}
public function printHtml(): string
{
return ' [...] ';
}
}
<?php
class BlogPost
{
// [...]
public function getData(): array
{
return [
'author' => $this->author->getFullName(),
'title' => $this->getTitle,
'content' => $this->getContent,
'timestamp' => $this->date->getTimestamp()
];
}
}
interface PrintableBlogPost
{
public function print(BlogPost $blogPost);
}
class JsonBlogPostPrinter implements PrintableBlogPost
{
public function print(BlogPost $blogPost): string
{
return json_encode($blogPost->getData());
}
}
class HtmlBlogPostPrinter implements PrintableBlogPost
{
public function print(BlogPost $blogPost): string
{
return ' [...] ';
}
}
<?php
class Square
{
public int $length;
public function construct($int length): void
{
$this->length = $length;
}
}
class Circle
{
public int $radius;
public function construct(int $radius): void
{
$this->radius = $radius;
}
}
<?php
class Rectangle
{
public int $height;
public int $width;
public function construct(int $height, int $width): void
{
$this->height = $height;
$this->width = $width;
}
}
class Triangle
{
// [...]
}
<?php
class AreaCalculator
{
protected $shapes;
public function __construct(array $shapes = [])
{
$this->shapes = $shapes;
}
public function sum(): int
{
foreach ($this->shapes as $shape) {
if ($shape instanceof Square::class)) {
$area[] = pow($shape->length, 2);
} elseif ($shape instanceof Circle::class) {
$area[] = pi() * pow($shape->radius, 2);
} elseif ($shape instanceof Rectangle::class) {
$area[] = $shape->height * $shape->width;
} // [...]
}
return array_sum($area);
}
}
<?php
interface ShapeInterface
{
public function area(): int;
}
class Square implements ShapeInterface { // [...] }
class Circle implements ShapeInterface { // [...] }
class Square
{
// [...]
public function area(): int
{
return pow($this->length, 2);
}
}
class AreaCalculator
{
// [...]
public function sum(): int
{
foreach ($this->shapes as $shape) {
$area[] = $shape->area();
}
return array_sum($area);
}
}
If it looks like a duck, swims like a duck,
quacks like a duck, but needs batteries
–
you probably have the wrong abstraction.
<?php
class Rectangle
{
protected int $width;
protected int $height;
public function setWidth(int $width): void
{
$this->width = $width;
}
public function setHeight(int $height): void
{
$this->height = $height;
}
public function calculateArea(): int
{
return $this->width * $this->height;
}
}
class Square extends Rectangle
{
public function setWidth(int $width): void
{
$this->width = $width;
$this->height = $width;
}
public function setHeight(int $height): void
{
$this->width = $height;
$this->height = $height;
}
}
<?php
class Rectangle implements CalculableArea
{
protected int $width;
protected int $height;
public function __construct(int $width, int $height)
{
$this->width = $width;
$this->height = $height;
}
public function calculateArea(): int
{
return $this->width * $this->height;
}
}
class Square implements CalculableArea
{
protected int $edge;
public function __construct(int $edge)
{
$this->edge = $edge;
}
public function calculateArea(): int
{
return $this->edge ** 2;
}
}
interface CalculableArea
{
public function calculateArea(): int;
}
<?php
interface Exportable
{
public function getPdf();
public function getCsv();
}
class Invoice implements Exportable
{
public function getPdf()
{
// ...
}
public function getCsv()
{
// ...
}
}
class CreditNote implements Exportable
{
public function getPdf()
{
//...
}
public function getCsv()
{
throw new \NotUsedFeatureException();
}
}
<?php
interface ExportablePdf
{
public function getPdf();
}
interface ExportableCsv
{
public function getCsv();
}
class Invoice implements ExportablePdf, ExportableCsv
{
public function getPdf()
{
// ...
}
public function getCsv()
{
// ...
}
}
class CreditNote implements ExportablePdf
{
public function getPdf()
{
//...
}
}
<?php
class MySQLConnection
{
public function connect()
{
return 'Database connection';
}
}
class PersistenceService
{
public function __construct(
private readonly MySQLConnection $dbConnection
) {}
}
<?php
class SqLiteConnection
{
public function connect()
{
return 'Database connection';
}
}
<?php
interface DbConnectionInterface
{
public function connect();
}
class MySQLConnection implements DbConnectionInterface
{
public function connect()
{
return 'Database connection';
}
}
class SqLiteConnection implements DbConnectionInterface
{
public function connect()
{
return 'Database connection';
}
}
class PersistenceService
{
public function __construct(
private readonly DbConnectionInterface $dbConnection
) {}
}
namespace Faktore\Sitepackage\Http\Adapter;
use Faktore\Sitepackage\Http\ApiRequest;
use Psr\Http\Message\ResponseInterface;
interface ApiAdapterInterface
{
public function sendRequest(
ApiRequest $request
): ResponseInterface;
}
namespace Faktore\Sitepackage\Http;
use Faktore\Sitepackage\Exception;
use Faktore\Sitepackage\Http\Adapter\ApiAdapterInterface;
use Psr\Http\Message\ResponseInterface;
class ApiClient
{
public function __construct(
protected readonly ApiAdapterInterface $apiAdapter
) {}
/**
* @throws Exception
*/
public function sendApiRequest(
ApiRequest $apiRequest
): ApiResponse
{
$response = $this->apiAdapter
->sendRequest($apiRequest);
return $this->processResponse($response);
}
// [...]
}
namespace Faktore\Sitepackage\Http\Adapter;
use Faktore\Sitepackage\Http\ApiRequest;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\GuzzleException;
use Psr\Http\Message\ResponseInterface;
use TYPO3\CMS\Core\Utility\GeneralUtility;
class GuzzleApiAdapter implements ApiAdapterInterface
{
protected Client $httpClient;
public function __construct()
{
$this->httpClient = GeneralUtility::makeInstance(Client::class);
}
/**
* @throws GuzzleException
*/
public function sendRequest(ApiRequest $request): ResponseInterface
{
$url = $request->getUri();
$method = $request->getMethod();
$headers = $request->getHeaders();
return $this->httpClient->request(
$method, $url, ['headers' => $headers]
);
}
}
namespace Faktore\Sitepackage\Http\Builder;
use Faktore\Sitepackage\Exception;
use Faktore\Sitepackage\Http\ApiRequest;
class ApiRequestBuilder implements ApiRequestBuilderInterface
{
protected ?string $url = null;
protected ?string $method = null;
protected array $headers = [];
public function setUrl(string $url): self
{
$this->url = $url;
return $this;
}
// [...]
/**
* @throws Exception
*/
public function build(): ApiRequest
{
if (empty($this->url) || empty($this->method)) {
throw new Exception(
'URL and method must be set before building the ApiRequest.',
1708543432
);
}
return new ApiRequest(
uri: $this->url,
method: $this->method,
headers: $this->headers
);
}
}
<?php
declare(strict_types=1);
namespace Faktore\Sitepackage\Pipeline;
use Faktore\Sitepackage\Domain\Configuration\ConfigurationCollectionInterface;
use Faktore\Sitepackage\Exception;
use ReflectionClass;
use TYPO3\CMS\Core\Utility\GeneralUtility;
class PipelineFactory
{
/**
* @param string $type
* @param ConfigurationCollectionInterface $configurations
* @return PipelineInterface
* @throws Exception
*/
public static function get(
string $type,
ConfigurationCollectionInterface $configurations
): PipelineInterface
{
$className = GeneralUtility::underscoredToUpperCamelCase($type) . 'Pipeline';
$fullyQualifiedClassName = 'Faktore\\Sitepackage\\Pipeline\\' . $className;
if(class_exists($fullyQualifiedClassName)) {
$reflection = new ReflectionClass($fullyQualifiedClassName);
if(!$reflection->implementsInterface(PipelineInterface::class)) {
throw new Exception('Class needs to implement the PipelineInterface.', 1707941729);
}
return GeneralUtility::makeInstance($fullyQualifiedClassName, $configurations);
}
throw new Exception("Class with name `$className` does not exist.", 1707941730);
}
}
class ParameterResolver
{
protected ?ArrayIterator $parameterProviders = null;
public function __construct(iterable $parameterProviders)
{
// Sorting by priority and some Symfony related stuff
}
/**
* @throws Exception
*/
public function resolve(string $apiName, string $parameterName): ParameterProviderInterface
{
foreach ($this->parameterProviders as $provider) {
$concreteProvider = clone $provider;
if ($concreteProvider->supports($apiName, $parameterName)) {
$concreteProvider->setParameterName($parameterName);
return $concreteProvider;
}
$concreteProvider = null;
unset($concreteProvider);
}
throw new Exception(
'No provider found to handle parameter with the name ' . $parameterName, 1713358720
);
}
// ResolveMultiple()
}