214 lines
6.8 KiB
PHP
214 lines
6.8 KiB
PHP
<?php
|
|
|
|
namespace App\Lib\Helpers;
|
|
|
|
use Illuminate\Container\Container;
|
|
use Illuminate\Pagination\LengthAwarePaginator;
|
|
use Illuminate\Pagination\Paginator;
|
|
use Illuminate\Support\Collection;
|
|
|
|
class CollectionHelper
|
|
{
|
|
/**
|
|
* Paginate a collection.
|
|
*
|
|
* @param \Illuminate\Support\Collection $results
|
|
* @param integer $pageSize
|
|
* @return \Illuminate\Pagination\LengthAwarePaginator
|
|
*/
|
|
public static function paginate(Collection $results, int $pageSize): \Illuminate\Pagination\LengthAwarePaginator
|
|
{
|
|
$page = Paginator::resolveCurrentPage('page');
|
|
|
|
return self::paginateManually($results, $pageSize, $page);
|
|
}
|
|
|
|
/**
|
|
* Paginate a collection.
|
|
*
|
|
* @param \Illuminate\Support\Collection $results
|
|
* @param integer $pageSize
|
|
* @param integer $page
|
|
* @return \Illuminate\Pagination\LengthAwarePaginator
|
|
*/
|
|
public static function paginateManually(
|
|
Collection $results,
|
|
int $pageSize,
|
|
int $page = 1
|
|
): \Illuminate\Pagination\LengthAwarePaginator {
|
|
$total = $results->count();
|
|
|
|
return self::paginator($results->forPage($page, $pageSize), $total, $pageSize, $page, [
|
|
'path' => Paginator::resolveCurrentPath(),
|
|
'pageName' => 'page',
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Create a new length-aware paginator instance.
|
|
*
|
|
* @param \Illuminate\Support\Collection $items
|
|
* @param integer $total
|
|
* @param integer $perPage
|
|
* @param integer $currentPage
|
|
* @param array $options
|
|
* @return \Illuminate\Pagination\LengthAwarePaginator
|
|
*/
|
|
protected static function paginator(
|
|
Collection $items,
|
|
int $total,
|
|
int $perPage,
|
|
int $currentPage,
|
|
array $options
|
|
): \Illuminate\Pagination\LengthAwarePaginator {
|
|
return Container::getInstance()->makeWith(LengthAwarePaginator::class, [
|
|
'items' => $items,
|
|
'total' => $total,
|
|
'perPage' => $perPage,
|
|
'currentPage' => $currentPage,
|
|
'options' => $options
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Get an array of views for each recipe models given.
|
|
*
|
|
* @param \Illuminate\Pagination\LengthAwarePaginator $models
|
|
* @param string $path
|
|
* @param string $key
|
|
* @return array
|
|
*/
|
|
public static function getViewsFromPaginateModels(
|
|
LengthAwarePaginator $models,
|
|
string $path,
|
|
string $key
|
|
): array {
|
|
return $models->through(function ($model) use ($path, $key) {
|
|
return view($path, [$key => $model])->render();
|
|
})->toArray();
|
|
}
|
|
|
|
/**
|
|
* Get an array of views for each item in collection given.
|
|
*
|
|
* @param \Illuminate\Support\Collection $collection
|
|
* @param string $path
|
|
* @param string $key
|
|
* @return array
|
|
*/
|
|
public static function getViewsFromCollection(Collection $collection, string $path, string $key): array
|
|
{
|
|
return $collection->map(function ($item) use ($path, $key) {
|
|
return view($path, [$key => $item])->render();
|
|
})->toArray();
|
|
}
|
|
|
|
public static function mapSlidesToFields(array $fields): array
|
|
{
|
|
return collect($fields)
|
|
->filter(fn($field, $key) => str_starts_with($key, 'slider_image_'))
|
|
->filter(fn($field) => !empty($field['value']))
|
|
->sortKeys()
|
|
->map(fn($field) => [
|
|
'image' => [
|
|
'path' => $field['value'],
|
|
'title' => $field['title'] ?? '',
|
|
'alt' => $field['alt'] ?? '',
|
|
],
|
|
])
|
|
->values()
|
|
->toArray();
|
|
}
|
|
|
|
/**
|
|
* Transform and merge 2 arrays to get homogeneous result
|
|
*
|
|
* @param array $items sections array
|
|
* @param array $categories categories array
|
|
* @return array
|
|
*/
|
|
public static function mapItemsToCards(array $items, array $categories): array
|
|
{
|
|
$categoriesById = collect($categories)->keyBy('id');
|
|
$result = [];
|
|
|
|
foreach ($items as $item) {
|
|
$category = $categoriesById->get($item['category_id']);
|
|
if (!$category) {
|
|
continue;
|
|
}
|
|
$categoryKey = $category['name'];
|
|
$parsed = self::parseContent($item['content']);
|
|
|
|
$result[$categoryKey][] = [
|
|
'category' => $item['title'],
|
|
'icon' => [
|
|
'path' => $item['picture'],
|
|
'alt' => $item['picture_alt'],
|
|
'description' => $item['picture_title'],
|
|
],
|
|
'content' => [
|
|
[
|
|
'title' => $parsed['title'],
|
|
'points' => $parsed['points'],
|
|
'asterisc' => $parsed['asterisc'],
|
|
],
|
|
],
|
|
'class' => 'card-template-sm',
|
|
];
|
|
}
|
|
return $result;
|
|
}
|
|
|
|
|
|
private static function parseContent(string $html): array
|
|
{
|
|
$dom = new \DOMDocument();
|
|
@$dom->loadHTML(mb_convert_encoding($html, 'HTML-ENTITIES', 'UTF-8'));
|
|
|
|
// Extract h3
|
|
$title = '';
|
|
$h3 = $dom->getElementsByTagName('h3');
|
|
if ($h3->length > 0) {
|
|
$title = trim($h3->item(0)->textContent);
|
|
}
|
|
|
|
// Extract li
|
|
$points = [];
|
|
$liNodes = $dom->getElementsByTagName('li');
|
|
foreach ($liNodes as $li) {
|
|
$points[] = trim($dom->saveHTML($li));
|
|
}
|
|
|
|
// Extract last <p> *
|
|
$asteriscs = [];
|
|
$pNodes = $dom->getElementsByTagName('p');
|
|
foreach ($pNodes as $p) {
|
|
$text = trim($p->textContent);
|
|
if (str_starts_with($text, '*')) {
|
|
$asteriscs[] = trim($dom->saveHTML($p));
|
|
}
|
|
}
|
|
// if nothing to extract
|
|
if (empty($title) && empty($points)) {
|
|
$body = $dom->getElementsByTagName('body')->item(0);
|
|
$rawText = trim($body ? $body->textContent : strip_tags($html));
|
|
if (!empty($rawText)) {
|
|
$points[] = $rawText;
|
|
}
|
|
}
|
|
// If no h3 found, use first paragraph as title
|
|
if (empty($title)) {
|
|
$pNodes = $dom->getElementsByTagName('p');
|
|
|
|
if ($pNodes->length > 0) {
|
|
$title = trim($pNodes->item(0)->textContent);
|
|
}
|
|
}
|
|
return [
|
|
'title' => $title,
|
|
'points' => $points,
|
|
'asterisc' => $asteriscs,
|
|
];
|
|
}
|
|
}
|