ldc-legaulois/app/Lib/Helpers/CollectionHelper.php
2026-05-07 12:12:16 +02:00

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,
];
}
}