diff --git a/core/includes/module.inc b/core/includes/module.inc index 0ea8e7e..5a17873 100644 --- a/core/includes/module.inc +++ b/core/includes/module.inc @@ -1216,14 +1216,20 @@ function module_set_weight($module, $weight) { * An array of module configuration data sorted by weight and name. */ function module_config_sort($data) { + // PHP array sorting functions such as uasort() do not work with both keys and + // values at the same time, so we achieve weight and name sorting by computing + // strings with both information concatenated (weight first, name second) and + // use that as a regular string sort reference list via array_multisort(), + // compound of "[sign-as-integer][padded-integer-weight][name]"; e.g., given + // two modules and weights (spaces added for clarity): + // - Block with weight -5: 0 0000000000000000005 block + // - Node with weight 0: 1 0000000000000000000 node $sort = array(); foreach ($data as $name => $weight) { - // We can't use the sign directly because + (ASCII 43) is before - // - (ASCII 45). So negative nubmers get a 0, non-negative numbers - // a 1 prefix. + // Prefix negative weights with 0, positive weights with 1. + // +/- signs cannot be used, since + (ASCII 43) is before - (ASCII 45). $prefix = (int) ($weight >= 0); - // PHP_INT_MAX is at most 19 characters so make every number equally - // 19 digits long. + // The maximum weight is PHP_INT_MAX, so pad all weights to 19 digits. $sort[] = $prefix . sprintf('%019d', abs($weight)) . $name; } array_multisort($sort, SORT_STRING, $data);