title sort via accent-stripped dashed slug (fixes names, keeps numbers) (v1.9.1)
This commit is contained in:
@@ -112,9 +112,16 @@ class OrganonSortHelper extends Base
|
||||
}
|
||||
|
||||
/**
|
||||
* Number-aware title sort (strnatcasecmp, so "Task 2" precedes "Task 10"), then write positions.
|
||||
* Mirrors the native reorder scope (all tasks in the column+swimlane, no status filter). Core's
|
||||
* TaskReorderModel::reorderTasks is protected, so the 3-line position write is replicated here.
|
||||
* Title sort, then write positions. Mirrors the native reorder scope (all tasks in the
|
||||
* column+swimlane, no status filter). Core's TaskReorderModel::reorderTasks is protected, so the
|
||||
* 3-line position write is replicated here.
|
||||
*
|
||||
* Each title is reduced to a comparison slug -- lowercased, accent-stripped, spaces -> dashes --
|
||||
* then compared with strnatcasecmp. The dash is deliberate: strnatcasecmp SKIPS whitespace, so a
|
||||
* plain space would make "Luiz Eduardo" sort after "Luiza..." (it would compare "LuizEduardo" vs
|
||||
* "Luiza..."); a dash is not whitespace, so the separator is honoured, while strnatcasecmp still
|
||||
* groups digit runs ("Task 2" < "Task 10"). The result is case-insensitive, accent-insensitive,
|
||||
* whitespace-correct and number-aware.
|
||||
*/
|
||||
private function reorderByTitle($project_id, $swimlane_id, $column_id, $direction)
|
||||
{
|
||||
@@ -125,8 +132,13 @@ class OrganonSortHelper extends Base
|
||||
->eq('column_id', $column_id)
|
||||
->findAll();
|
||||
|
||||
foreach ($rows as &$row) {
|
||||
$row['sortkey'] = str_replace(' ', '-', $this->stripAccents(mb_strtolower((string) $row['title'], 'UTF-8')));
|
||||
}
|
||||
unset($row);
|
||||
|
||||
usort($rows, function ($a, $b) use ($direction) {
|
||||
$cmp = strnatcasecmp((string) $a['title'], (string) $b['title']);
|
||||
$cmp = strnatcasecmp($a['sortkey'], $b['sortkey']);
|
||||
|
||||
return $direction === 'desc' ? -$cmp : $cmp;
|
||||
});
|
||||
@@ -137,4 +149,28 @@ class OrganonSortHelper extends Base
|
||||
$position++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Flatten a string for sorting: strip accents to their base letter so accented names sort by that
|
||||
* base (Avila near A, not after Z). Uses ext-intl Normalizer when available (deterministic and
|
||||
* locale-independent), falling back to iconv //TRANSLIT (locale-dependent), then the raw string
|
||||
* (still sorts, just accent-naive). Case is already lowered by the caller.
|
||||
*
|
||||
* @param string $s
|
||||
* @return string
|
||||
*/
|
||||
private function stripAccents($s)
|
||||
{
|
||||
if (class_exists('Normalizer')) {
|
||||
$decomposed = \Normalizer::normalize($s, \Normalizer::FORM_D);
|
||||
|
||||
if ($decomposed !== false) {
|
||||
return preg_replace('/\p{Mn}/u', '', $decomposed);
|
||||
}
|
||||
}
|
||||
|
||||
$translit = @iconv('UTF-8', 'ASCII//TRANSLIT//IGNORE', $s);
|
||||
|
||||
return $translit !== false ? $translit : $s;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -162,7 +162,7 @@ class Plugin extends Base
|
||||
|
||||
public function getPluginVersion()
|
||||
{
|
||||
return '1.9.0';
|
||||
return '1.9.1';
|
||||
}
|
||||
|
||||
public function getPluginHomepage()
|
||||
|
||||
Reference in New Issue
Block a user