Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
4 / 4
CRAP
100.00% covered (success)
100.00%
1 / 1
Sort
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
4 / 4
4
100.00% covered (success)
100.00%
1 / 1
 expression
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
1
 collation
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 indexName
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 valid
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3declare(strict_types=1);
4
5namespace Cosray\Title;
6
7use Cosray\Field\Field;
8
9/**
10 * Canonical SQL for ordering nodes by their materialized title in a given
11 * locale. The same expression backs the per-locale sort indexes and the
12 * queries that use them, so an `ORDER BY` matches its index exactly.
13 *
14 * Locale ids are inlined into the SQL (they are trusted config values, like
15 * the field read path in Finder\CompilesField), so every id passes through
16 * {@see self::valid()} first.
17 */
18class Sort
19{
20    /**
21     * Sort key for one locale: the title in that locale, falling back to the
22     * neutral key, with blanks treated as absent.
23     */
24    public static function expression(string $localeId, string $column = 'title'): string
25    {
26        return sprintf(
27            "COALESCE(NULLIF(%s->>'%s', ''), NULLIF(%s->>'%s', ''))",
28            $column,
29            $localeId,
30            $column,
31            Field::NEUTRAL_LOCALE,
32        );
33    }
34
35    /**
36     * ICU collation name for locale-correct ordering, e.g. `de-x-icu`.
37     */
38    public static function collation(string $localeId): string
39    {
40        return $localeId . '-x-icu';
41    }
42
43    /**
44     * Unprefixed index name for a locale's sort index.
45     */
46    public static function indexName(string $localeId): string
47    {
48        return 'ix_nodes_title_' . str_replace('-', '_', $localeId);
49    }
50
51    /**
52     * A locale id safe to inline into SQL and to use in an identifier.
53     */
54    public static function valid(string $localeId): bool
55    {
56        return preg_match('/^[A-Za-z][A-Za-z0-9_-]*$/', $localeId) === 1;
57    }
58}