Multidimensional array sort with UTF8 collator locale special characters

The ‘correct’ alphabetical sorting is highly dependent on the locale.  Some countries sort the special characters to the end and some not.  A variety of so called solutions were found on the web, but few were clean enough and covered my special case.  A generic multidimensional array needed to be sorted by a realtime set of fields with variable sort directions.

A combination of  a uasort with a user defined comparision function that used php’s collator class saved the day.  A swap routine helped achieve any change in sort direction.

Do please let me know if there is a cleaner more efficient way to sort multidimensional arrays by user defined columns with user defined sort directions in wordpress for a locale defined by wordpress.

Multidimensional array sort with UTF8 collator locale special characters
Test data sorted under different locales

I had to resort to globals to pass the ‘realtime’ sortfields and the locale (array(field1=>sortdirection, etc).

The quick test function was:

function do_sort(&$arr, $locale, $sortfields) {
global $collator, $sortfields;
$collator = new collator($locale);
if (empty($sortfields or !is_array($sortfields))) return $arr;
uasort ($arr, function ( $a, $b) {
global $collator, $sortfields;
foreach ($sortfields as $fld1 => $sort1) {
// really only until return!
if (empty ($a[$fld1])) $aa = '';
else $aa = $a[$fld1];
if (empty ($b[$fld1])) $bb = '';
else $bb = $b[$fld1];
if ($sort1 == SORT_DESC) amr_swap($aa, $bb);
$cmp = $collator->compare($aa, $bb);
if (!($cmp == 0)) return $cmp;
}
return $cmp;
}
);
return $arr;
}

The test code is provided in a test_utf8_sort2 Zip for your fun.

Some reference links noted during the process:

  • https://stackoverflow.com/questions/41602514/custom-collation-with-php-using-usort
  • custom alphabet function: https://stackoverflow.com/questions/7929796/how-can-i-sort-an-array-of-utf-8-strings-in-php
  • https://stackoverflow.com/questions/38171550/trying-to-sort-a-multidimensional-array-by-a-sub-value-with-special-characters
  • https://stackoverflow.com/questions/18210189/mysql-order-by-on-column-with-unicode-characters
  • https://mathiasbynens.be/notes/mysql-utf8mb4#comment-83
  • https://stackoverflow.com/questions/43212197/sorting-php-array-with-locale-setting
  • use db rather with unicode: https://wordpress.stackexchange.com/questions/170450/alphabetical-sorting-local-language

For wordpress queries, what was not working in the wp users screen sortable columns, did work when queried directly:

SELECT * FROM `beta_usermeta` WHERE `meta_key` = "first_name" ORDER BY `meta_value` COLLATE utf8mb4_unicode_520_ci

 

Dead shortcodes and how to find them

Have you ever looked at your plugin list and wondered whether you actually using it anywhere?  Or perhaps deactivated a plugin or swopped themes without realising that you  now have a dead shortcode on a page or post somewhere telling the world that you really aren’t on  top of things in your websites.

Yes well, it happens.  This little plugin may help.

amr-shortcodes searchs through your published or future posts, pages etc looking for shortcodes.  It then lists the pages and the shortcodes that appear on them, with handly little links to edit the post.  It will also flag with a red cross if wordpress does not know about that shortcode anymore – ie the shortcode is dead and there is no function that will switch out the shortcode text for some wonderful other text.

It does not automatically delete the dead text, because you reallly should look at the page or post and delete any surrounding text as well that may no longer be relevant.

And then, just because it might be interesting, I added a tab so you can see the available shortcodes.

View and Manage shortcodes

amr-shortcodes

 

 

A simple little plugin

I’m kinda astounded at how popular the amr-shortcode-any-widget plugin is. The concept and execution is so fairly simple – clever perhaps 😉  but simple.

All it really does is

  • use wp  function to add a sidebar so that any widget settings can be setup using the widgets code
  • add a wordpress shortcode that will use wp functions to run the widget or widget area.  It’ll catch the widget output (so it doesn’t appear at top of the content) and return is as the shortcode so the widget output will appear where you put the shortode.

It certainly doesn’t have any css, any javascript, any jquery, any real settings.  It doesn’t save or create any new files, or impact the .htaccess, or permalinks.  It actually doesn’t do very much at all – truly.

If deactivating the plugin gets rid of an error, it is highly likely that it is because the widget you had in the shortcode sidebar is no longer being used.

Why did it come about?

It started when I wanted a quick fix. I wanted to use Justin Tadlock’s query posts widget plugin – but in a page – to save me having to code up a special template or shortcode.  I realised the key difference between shortcode and widgets and pondered how one could get around this situation where a developer had not offered both a widget and a shortcode or template.

So what is the difference between a widget and a shortcode?

Widgets when called, echo the html straight out. Each piece is output as it is calculated or extracted.

Shortcodes on the other work out the html for each piece and keep building a set of html. The shortcode function returns the total html to the calling code (wordpress). WordPress replaces the [shortcode text] with the html. It does this when it applies the ‘the_content’ filter to the_content.

Know you know this, you can debug these situations:

If you ever see a shortcode plugin that generates the output at the top of the content instead of where the shortcode is, then you know the developer hasn’t quite figured that he or she needs to ‘return’ the html, not ‘echo’ it.

And if the shortcode text just sits there doing nothing after you publish your page, then you know that the theme developer is either ‘not doing it right’ OR perhaps some other plugin is interfering, possibly removing the  ‘the_content’ filters.

How to catch the echoed output and have it appear in the right place?

OK, now the next handy piece is that php lets one buffer the output, rather then letting it echo out directly. So this plugin buffers the output, calls the widget and returns the widget output as the shortcode return value. It does not ‘flush’ the output (else we’d have two lots of the widget html)

Hmm widget settings? how to handle those?

Then I had to find a way for the user to specify the settings for the widget without getting too complicated.

A ‘dummy’ sidebar or widget area was the answer. Users have the same familiar interface. They can test their chosen widget in a normal sidebar and once it works, juts drag and drop that widget into the dummy sidebar.

The plugin knows nothing… well almost nothing

So the plugin does NOT know what widgets are being used, and doesn’t need to know – it’s just calling the widget and catching the widget output to stop it dumping at the top of the content. It then tosses the widget output back out to the shortcode function for wordpress to swop the shortcode text with the output.

That’s the basics.

After that came the extra features that people requested:

  • multiple instances of the same widget meant that id’s had to be used instead of widget names
  • themes where the sidebar background and text was opposite to the page meant that it would be handly to have easy ways to change the css that was being applied, for those who didn’t know how or didnt want to have to add css. Basically one can avoid some css being applied by removing widget classes or changing the html that surrounds the widget – the html tags that the theme is using.
  • then my personal bugbear was when widgets got ‘lost’ when a new theme was tried. So there is a bit of cleverness there to try to remember the widgets being used and add them back in after a new theme activation,
  • and most recently of course the wonderful suggestion to show the widget id at the bottom of the widgets to simplify finding out what id wordpress has assigned to it.

So while it has all these parameters for the shortcode and actually has two shortcodes ( a widget area one too just for fun), all it really does with them, is pass them over to wordpress to pass to the widget, just as wordpress would do when it calls the sidebar code.

Simple.