[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-----