Cockpit integration

This commit is contained in:
2024-11-07 21:34:32 +01:00
parent d3eccf99f0
commit a4b336b3fd
8 changed files with 153 additions and 41 deletions

2
.idea/phpunit.xml generated
View File

@@ -9,8 +9,8 @@
<option value="$PROJECT_DIR$/classes/external/fakerphp/faker/tests" /> <option value="$PROJECT_DIR$/classes/external/fakerphp/faker/tests" />
<option value="$PROJECT_DIR$/classes/external/guzzlehttp/promises/tests" /> <option value="$PROJECT_DIR$/classes/external/guzzlehttp/promises/tests" />
<option value="$PROJECT_DIR$/classes/external/guzzlehttp/psr7/tests" /> <option value="$PROJECT_DIR$/classes/external/guzzlehttp/psr7/tests" />
<option value="$PROJECT_DIR$/classes/external/bramus/router/tests" />
<option value="$PROJECT_DIR$/classes/external/scssphp/server/tests" /> <option value="$PROJECT_DIR$/classes/external/scssphp/server/tests" />
<option value="$PROJECT_DIR$/classes/external/bramus/router/tests" />
</list> </list>
</option> </option>
</component> </component>

View File

@@ -68,8 +68,9 @@ class CockpitApi
/** /**
* @throws GuzzleException * @throws GuzzleException
* @throws Exception * @throws Exception
* @return Article[]
*/ */
public function getArticles(): Article|array public function getArticles(): array
{ {
$res = $this->client->request('GET', $this->getApiPath('itemsByModel', ['model' => 'article']), [ $res = $this->client->request('GET', $this->getApiPath('itemsByModel', ['model' => 'article']), [
'headers' => [ 'headers' => [
@@ -130,7 +131,6 @@ class CockpitApi
$return = []; $return = [];
foreach ($array['data'] as $data) { foreach ($array['data'] as $data) {
$json = json_encode($data); $json = json_encode($data);
dump($json);
$return[] = SerializerBuilder::create()->build()->deserialize($json, $type, 'json'); $return[] = SerializerBuilder::create()->build()->deserialize($json, $type, 'json');
} }

View File

@@ -1,5 +1,7 @@
<?php <?php
declare(strict_types=1);
namespace Application\Controller; namespace Application\Controller;
use Application\Content\CockpitApi; use Application\Content\CockpitApi;
@@ -8,7 +10,6 @@ use GuzzleHttp\Exception\GuzzleException;
class ArticleController extends MainController class ArticleController extends MainController
{ {
/** /**
* @throws Exception * @throws Exception
* @throws GuzzleException * @throws GuzzleException
@@ -17,15 +18,20 @@ class ArticleController extends MainController
{ {
$article = (new CockpitApi())->getArticle($this->getRouteParams('id')); $article = (new CockpitApi())->getArticle($this->getRouteParams('id'));
$this->getBreadcrumbs()->addBreadcrumb(
$article->getTitle(),
$article->getUrl()
);
$this->pushToStash('article', [ $this->pushToStash('article', [
'subtitle' => $this->faker->sentence(2), 'subtitle' => 'TODO: Subtitle',
'title' => $article->getTitle(), 'title' => $article->getTitle(),
'lead' => $this->faker->paragraph(), 'lead' => $article->getExcerpt(),
'text' => $article->getText(), 'text' => $article->getText(),
'image' => [ 'image' => [
'src' => 'https://picsum.photos/seed/' . $this->faker->randomDigit() . '/1920/1080', 'src' => $article->getImage()->getImageUrl(),
'width' => 1920, 'width' => $article->getImage()->getWidth(),
'height' => 1080, 'height' => $article->getImage()->getHeight(),
'alt' => 'lorem ipsum', 'alt' => 'lorem ipsum',
], ],
]); ]);

View File

@@ -1,27 +1,33 @@
<?php <?php
declare(strict_types=1);
namespace Application\Controller; namespace Application\Controller;
use Application\Generator\Article; use Application\Content\CockpitApi;
use Application\Helper\NumberHash;
use Exception; use Exception;
use GuzzleHttp\Exception\GuzzleException;
class HomeController extends MainController class HomeController extends MainController
{ {
/** /**
* @throws Exception * @throws Exception
* @throws GuzzleException
*/ */
protected function action(): void protected function action(): void
{ {
$this->pushToStash('articles', $this->generateArticles()); $this->pushToStash('articles', $this->getArticles());
} }
private function generateArticles(): array /**
* @throws GuzzleException
*/
private function getArticles(): array
{ {
$return = []; $return = [];
for ($i = 0; $i < 10; $i++) { foreach ((new CockpitApi())->getArticles() as $article) {
$return[] = (new Article(NumberHash::numHash("home_$i")))->getTeaserData(); $return[] = $article->getTeaserData();
} }
return $return; return $return;

View File

@@ -10,8 +10,6 @@ use Twig\Error\LoaderError;
use Twig\Error\RuntimeError; use Twig\Error\RuntimeError;
use Twig\Error\SyntaxError; use Twig\Error\SyntaxError;
use Twig\Loader\FilesystemLoader; use Twig\Loader\FilesystemLoader;
use Faker\Factory;
use Faker\Generator;
abstract class MainController abstract class MainController
{ {
@@ -50,13 +48,6 @@ abstract class MainController
*/ */
private array $route_parameters = array(); private array $route_parameters = array();
/**
* Fake data generator.
*
* @var Generator
*/
protected Generator $faker;
/** /**
* Breadcrumbs. * Breadcrumbs.
* *
@@ -73,8 +64,6 @@ abstract class MainController
public function __invoke(array $parameters = array()): void public function __invoke(array $parameters = array()): void
{ {
$this->route_parameters = $parameters; $this->route_parameters = $parameters;
$this->faker = Factory::create();
$this->faker->seed(1234567);
$this->preAction(); $this->preAction();
$this->action(); $this->action();
$this->postAction(); $this->postAction();
@@ -150,7 +139,7 @@ abstract class MainController
$this->pushToStash( $this->pushToStash(
'meta', 'meta',
[ [
'title' => $this->faker->domainName(), 'title' => 'News Page | Your #1 News Source',
], ],
self::STASH_GLOBAL self::STASH_GLOBAL
); );

View File

@@ -4,6 +4,7 @@ declare(strict_types=1);
namespace Application\Models; namespace Application\Models;
use Exception;
use JMS\Serializer\Annotation\SerializedName; use JMS\Serializer\Annotation\SerializedName;
use JMS\Serializer\Annotation\Type; use JMS\Serializer\Annotation\Type;
@@ -13,39 +14,95 @@ class Article
#[SerializedName('authors')] #[SerializedName('authors')]
#[Type('array<' . Author::class . '>')] #[Type('array<' . Author::class . '>')]
protected array $authors; protected ?array $authors = null;
#[SerializedName('headline')] #[SerializedName('headline')]
#[Type('string')] #[Type('string')]
protected string $headline; protected ?string $headline = null;
#[SerializedName('excerpt')] #[SerializedName('excerpt')]
#[Type('string')] #[Type('string')]
protected string $excerpt; protected ?string $excerpt = null;
#[SerializedName('image')] #[SerializedName('image')]
#[Type(Image::class)] #[Type(Image::class)]
protected Image $image; protected ?Image $image = null;
#[SerializedName('text')] #[SerializedName('text')]
#[Type('string')] #[Type('string')]
protected string $text; protected ?string $text = null;
/** /**
* Return the title / headline. * Return the title / headline.
* *
* @return string * @return string|null
*/ */
public function getTitle(): string { public function getTitle(): string|null
{
return $this->headline; return $this->headline;
} }
/** /**
* Return the text / article body text. * Return the text / article body text.
* *
* @return string * @return string|null
*/ */
public function getText(): string { public function getText(): string|null
{
return $this->text; return $this->text;
} }
/**
* Get the excerpt / teaser text.
*
* @return string|null
*/
public function getExcerpt(): string|null
{
return $this->excerpt;
}
public function getImage(): Image|null
{
return $this->image;
}
public function getTeaserData(): array
{
return [
'headline' => $this->getHeadline(),
'kicker' => $this->getKicker(),
'excerpt' => $this->getExcerpt(),
'teaserImage' => $this->getTeaserImage(),
'url' => $this->getUrl(),
];
}
private function getIdentifier(): string
{
return $this->metaId;
}
private function getHeadline(): ?string
{
return $this->headline;
}
private function getKicker(): ?string
{
return $this->excerpt;
}
/**
* @throws Exception
*/
private function getTeaserImage(): array
{
return $this->image->getTeaserData();
}
public function getUrl(): string
{
return '/article/test_article-' . $this->getIdentifier();
}
} }

View File

@@ -4,6 +4,8 @@ declare(strict_types=1);
namespace Application\Models; namespace Application\Models;
use Application\AppEnvironment;
use Exception;
use JMS\Serializer\Annotation\SerializedName; use JMS\Serializer\Annotation\SerializedName;
use JMS\Serializer\Annotation\Type; use JMS\Serializer\Annotation\Type;
@@ -44,12 +46,12 @@ class Image
private array $colors; private array $colors;
#[SerializedName('width')] #[SerializedName('width')]
#[Type('string')] #[Type('int')]
private string $width; private int $width;
#[SerializedName('height')] #[SerializedName('height')]
#[Type('string')] #[Type('int')]
private string $height; private int $height;
#[SerializedName('altText')] #[SerializedName('altText')]
#[Type('string')] #[Type('string')]
@@ -62,4 +64,56 @@ class Image
#[SerializedName('folder')] #[SerializedName('folder')]
#[Type('string')] #[Type('string')]
private string $folder; private string $folder;
/**
* Return the URL to the original asset.
*
* @return string
* @throws Exception
*/
public function getImageUrl(): string
{
$apiPath = AppEnvironment::getInstance()->getVariable('COCKPIT_API_PATH');
$url = parse_url($apiPath, PHP_URL_SCHEME) . '://';
$url .= parse_url($apiPath, PHP_URL_HOST) . '/storage/uploads';
$url .= $this->path;
return $url;
}
/**
* Return original image width in pixel.
*
* @return int
*/
public function getWidth(): int
{
return $this->width;
}
/**
* Return original image height in pixel.
*
* @return int
*/
public function getHeight(): int
{
return $this->height;
}
/**
* Get teaser data array ready to be used within the template.
*
* @return array
* @throws Exception
*/
public function getTeaserData(): array
{
return [
'src' => $this->getImageUrl(),
'width' => $this->getWidth(),
'height' => $this->getHeight(),
'alt' => $this->altText,
];
}
} }

View File

@@ -6,7 +6,7 @@
<div class="o-card__image" style="background-image: url('{{ image.src }}')"></div> <div class="o-card__image" style="background-image: url('{{ image.src }}')"></div>
<div class="o-card__text"> <div class="o-card__text">
<div class="o-card__headline"> <div class="o-card__headline">
<h3>{{ headline }}</h3> <h3><a href="{{ url }}">{{ headline }}</a></h3>
</div> </div>
<div class="o-card__teaser"> <div class="o-card__teaser">
{{ text }} {{ text }}