[Tiki-devel] Unicode aware natcasesort() and PluginSort for next Tiki version

Volker Wysk <post-hhF2Jplw28UoZk/[email protected]>
Newsgroups gmane.comp.cms.tiki.devel
Message-ID <[email protected]>
Hi!

My mb_natcasesort() function and the fixed sort plugin should go into Tiki
26. I've attached both again.

I can't make a merge request right now, because I have to figure out first,
how to run Apache with multiple PHP versions.

mb_natcasesort() should go to the Tiki libraries, because it is of general
interest.

So, could someone of the developers please add both to Tiki 26?

Cheers,
Volker

_______________________________________________
TikiWiki-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/tikiwiki-devel
mb_natcasesort.php (application/x-php, 2.3 KB)
<?php

// Do a natural, locale aware and case-insenstitive sort of an array of strings.
//
// "Natural" means that numbers inside the strings are sorted by their value, not by the digits they contain. For
// instance, "10" is ordered after "2".
//
// When the "intl" PHP extension is available, the sort is done Unicode aware. The "$lang" argument is the language
// for which to order. Accented characters, like "ä", are ordered like their non-accented counterpart, like "a".
// For the "$lang" argument, "false" can be specified. In this case, the function investigates the language of the
// current user and uses that.
//
// When intl isn't available, mb_natcasesort() function falls back to the the natcasesort() function. This one
// isn't Unicode aware. Accented characters get ordered at the end. The "$lang" argument is ignored in this case.
//
// In case of success, true is returned. In case of an error, false is returned. This are the return values of the
// collator_asort() function from the intl extension. When the "intl" extension isn't available, the result always
// is "true".
//
// The natsort() function orders all capital letters before all lower-case letters. There's no Unicode aware
// counterpart, because natural languages appear to always order case-insensitively. The Collator class is like
// this. So we can't have a mb_natsort() function.

function mb_natcasesort(string $lang, array &$array): bool
{
    if (extension_loaded("intl")) {

        if ($lang == false) {
            $tikilib  = TikiLib::lib('tiki');
            $loginlib = TikiLib::lib('login');

            $user = $loginlib->getUser();
            $lang = $tikilib->get_language($user);
        }

        $coll = collator_create($lang);
        collator_set_attribute($coll, Collator::NUMERIC_COLLATION, Collator::ON);
        collator_set_attribute($coll, Collator::CASE_FIRST, Collator::LOWER_FIRST);
        collator_set_attribute($coll, Collator::ALTERNATE_HANDLING, Collator::SHIFTED);

        return collator_asort($coll, $array);

    } else {
        natcasesort($array); // always returns true
        return true;
    }
}



// Test

$arr = array("BBB", "bbb", "ß", "abb", "AAA", "äba", "xx100xx", "xx99xx", '"abc"', '_abc');

//mb_natcasesort("de_DE", $arr);
//mb_natcasesort(false, $arr);
mb_natcasesort("en_EN", $arr);

print_r($arr);
wikiplugin_sort.php (application/x-php, 3.6 KB)
<?php

// (c) Copyright by authors of the Tiki Wiki CMS Groupware Project
//
// All Rights Reserved. See copyright.txt for details and a complete list of authors.
// Licensed under the GNU LESSER GENERAL PUBLIC LICENSE. See license.txt for details.
// $Id$

// This plugin takes a block of Tiki content and sorts it line-wise.

function wikiplugin_sort_info()
{
    return [
        'name' => tra('Sort'),
        'documentation' => 'PluginSort',
        'description' => tra('Sort lines of text'),
        'prefs' => [ 'wikiplugin_sort' ],
        'body' => tra('Data to sort, one entry per line.'),
        'filter' => 'text',
        'iconname' => 'sort-desc',
        'introduced' => 1,
        'tags' => [ 'basic' ],
        'params' => [
            'sort' => [
                'required' => false,
                'name' => tra('Order'),
                'description' => tra('Set the sort order of lines of content (default is ascending)'),
                'since' => '1',
                'filter' => 'alpha',
                'default' => 'asc',
                'options' => [
                    ['text' => '', 'value' => ''],
                    ['text' => tra('Ascending'), 'value' => 'asc'],
                    ['text' => tra('Descending'), 'value' => 'desc'],
                    ['text' => tra('Reverse'), 'value' => 'reverse'],
                    ['text' => tra('Shuffle'), 'value' => 'shuffle']
                ]
            ]
        ]
    ];
}



// Do a natural, locale aware and case-insenstitive sort of an array of strings.
//
// "Natural" means that numbers are sorted by their value, not by the digits they contain. For instance, "10" is
// ordered after "2".
//
// The "lang" argument is the language for which to order. Accented characters, like "ä", are ordered like their
// non-accented counterpart, like "a". In the non-locale aware natcasesort() function, accented characters get
// ordered at the end. That's not right for non-English languages.
//
// For the "lang" argument, "false" can be specified. In this case, the function investigates the language of the
// current user and uses that.
//
// For success, true is returned. In case of an error, false is returned. This are the return values of the
// collator_asort() function from the intl extension.

function mb_natcasesort(string $lang, array &$array): bool
{
    if ($lang == false) {
        $tikilib  = TikiLib::lib('tiki');
        $loginlib = TikiLib::lib('login');

        $user = $loginlib->getUser();
        $lang = $tikilib->get_language($user);
    }

    $coll = collator_create($lang);
    collator_set_attribute($coll, Collator::NUMERIC_COLLATION, Collator::ON);
    collator_set_attribute($coll, Collator::CASE_FIRST, Collator::LOWER_FIRST);
    collator_set_attribute($coll, Collator::ALTERNATE_HANDLING, Collator::SHIFTED);

    return collator_asort($coll, $array);
}



function wikiplugin_sort($data, $params)
{
    extract($params, EXTR_SKIP);

    $sort = (isset($sort)) ? $sort : "asc";
    $lines = preg_split("/\n+/", $data, -1, PREG_SPLIT_NO_EMPTY); // separate lines into array

    if ($sort == "asc") {
        // Sort ascending
        mb_natcasesort(false, $lines);
    } elseif ($sort == "desc") {
        // Sort descending
        mb_natcasesort(false, $lines);
        $lines = array_reverse($lines);
    } elseif ($sort == "reverse") {
        // Reverse the lines
        $lines = array_reverse($lines);
    } elseif ($sort == "shuffle") {
        // Shuffle the lines
        srand((float) microtime() * 1000000);
        shuffle($lines);
    }

    reset($lines);

    if (is_array($lines)) {
        $data = implode("\n", $lines);
    }

    $data = trim($data);
    return $data;
}
signature.asc (application/pgp-signature, 833 B)
-----BEGIN PGP SIGNATURE-----

iQIzBAABCgAdFiEE6QXGh82Ov3+2nrxp+K4ydFOsHoUFAmS1aEYACgkQ+K4ydFOs
HoVx4g/9EyCQTFuaqYSzUDEY1gZM3ZZJcYttl01IlX0MRqSLBt3kGU6Sz1ntZDYN
8Fkif91afclOqJizYOOGFB+sVz7gusLYpEO0Q0ntp/o4Log9vStDX7qqPx7ALDXK
U4CViRPeFG79pMkaLIwWCcWN+Sv70sS8HiNEb4NJRb1/4kmyI59DCk+uPMXa5ii7
7JyFLMgX37uNe4MFqU98mmlIdnjYGl6gIxaTH0lTY2qld2DWfghlON9CAF/ehGE9
3P9yl25BS/cNj8nN20YNlFDWIPvvCvfJZXu2f5jJxSjh9cMrtwe/VAJiDELAWGGc
mwRY+MHGEoHHwPwhtWE4R6nzkAzpOuB0O4bKG30Uqo3zXY12oukRopP4kYcvfiL+
atBJlBKV4DhZQNywGF12AhvHT85hpVm6AM0K//xU+FlVCZeRgGgyL36Tjw/SvoCl
qqJ7ERgtksXqRrm2OV5zaHHnX+7CFT+P1JIJHTkyReszk0qzRkXjjz5USlIlQ/I+
bU6xRHwoNLzU0W29MyDXKfeaWoEGS2zFwn95e+RpPkK0nYuCbrOg/cqYaE7BswOa
FURhEdlXXCU6zwgt9nBYiC3ZnVVo7uDbdns+2NanifQMdPnber0wqisOGaZLu0rH
pYnvapQ0KLY6bh5oXT/jnurrKMlgdOx/DJtiA65XmF1rcTYiSNU=
=3xlj
-----END PGP SIGNATURE-----
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.