✨ Cockpit integration
This commit is contained in:
2
.idea/phpunit.xml
generated
2
.idea/phpunit.xml
generated
@@ -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>
|
||||||
|
@@ -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');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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',
|
||||||
],
|
],
|
||||||
]);
|
]);
|
||||||
|
@@ -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;
|
||||||
|
@@ -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
|
||||||
);
|
);
|
||||||
|
@@ -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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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,
|
||||||
|
];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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 }}
|
||||||
|
Reference in New Issue
Block a user