Artikel alphabetisch sortieren
Quell-ID: GitHub Discussion #22
Use Case
Im Frontend sollen Artikel einer Kategorie nicht nach der Backend-Priorität, sondern alphabetisch nach Namen sortiert werden.
Verwendete AddOns
- REDAXO Core
Problemstellung
Die Standard-Methode getArticles() liefert Artikel nach der im Backend festgelegten Priorität:
$articles = rex_category::get("REX_CATEGORY_ID")->getArticles(true);
Lösung
Mit PHP’s usort() können die Artikel nach einem beliebigen Kriterium sortiert werden:
<?php
$articles = rex_category::get("REX_CATEGORY_ID")->getArticles(true);
usort($articles, function ($a, $b) {
return strcmp($a->getValue('name'), $b->getValue('name'));
});
// Ausgabe
foreach ($articles as $article) {
echo '<a href="' . $article->getUrl() . '">' . $article->getName() . '</a>';
}
Weitere Sortier-Beispiele
Sortierung nach Datum (absteigend)
<?php
usort($articles, function ($a, $b) {
return strtotime($b->getValue('createdate')) - strtotime($a->getValue('createdate'));
});
Sortierung nach Meta-Feld
<?php
usort($articles, function ($a, $b) {
return strcmp($a->getValue('art_custom_field'), $b->getValue('art_custom_field'));
});
Numerische Sortierung
<?php
usort($articles, function ($a, $b) {
return $a->getValue('art_order') <=> $b->getValue('art_order');
});
Besserer Ansatz
Als wiederverwendbare Funktion
<?php
class ArticleHelper
{
/**
* Sortiert Artikel nach einem beliebigen Feld
*
* @param rex_article[] $articles
* @param string $field
* @param string $direction 'asc' oder 'desc'
* @return rex_article[]
*/
public static function sortBy(array $articles, string $field = 'name', string $direction = 'asc'): array
{
usort($articles, function ($a, $b) use ($field, $direction) {
$valA = $a->getValue($field);
$valB = $b->getValue($field);
// Numerische Werte
if (is_numeric($valA) && is_numeric($valB)) {
$result = $valA <=> $valB;
} else {
// Textvergleich (case-insensitive für deutsche Umlaute)
$result = strcasecmp($valA, $valB);
}
return $direction === 'desc' ? -$result : $result;
});
return $articles;
}
}
// Verwendung
$articles = rex_category::get($categoryId)->getArticles(true);
$articles = ArticleHelper::sortBy($articles, 'name', 'asc');
Mit Collator für korrekte deutsche Sortierung
<?php
class ArticleHelper
{
public static function sortByName(array $articles, string $direction = 'asc'): array
{
$collator = new Collator('de_DE');
usort($articles, function ($a, $b) use ($collator, $direction) {
$result = $collator->compare($a->getName(), $b->getName());
return $direction === 'desc' ? -$result : $result;
});
return $articles;
}
}
Direkt per SQL (performanter bei vielen Artikeln)
<?php
$categoryId = rex_category::getCurrentId();
$sql = rex_sql::factory();
$articles = $sql->getArray('
SELECT id, name, createdate
FROM ' . rex::getTable('article') . '
WHERE parent_id = :category_id
AND status = 1
ORDER BY name ASC
', ['category_id' => $categoryId]);
foreach ($articles as $article) {
$articleObj = rex_article::get($article['id']);
echo '<a href="' . $articleObj->getUrl() . '">' . $article['name'] . '</a>';
}
Diese SQL-Variante ist bei großen Kategorien effizienter, da die Sortierung in der Datenbank erfolgt.