<?php
namespace Lia\Compo;
class ResourceSorter extends \Lia\Compo{
protected $didSet=false;
protected $orders=['css'=>[], 'js'=>[]];
public function onReady(){
$lia = $this->lia;
$lia->addApi('lia:resource.sortbasename',[$this,'setResourceOrder']);
$lia->addApiMethod('lia:resource.sortbasename', 'setResourceOrder');
}
/**
* Give an array of file names in the order they should be sent to the browser
*
* @param $ext the file extension js or css
* @param $names an array of relative file paths, in the order you want them. There MUST NOT be leading `/`. There MAY be as many `/` as you like
* @param $prepend TRUE to put these $names BEFORE any previous names set this way. FALSE to put these names at the end. WILL replace any identical names for sorting
*/
public function setResourceOrder($ext,$names, $prepend=true){
$ext = strtolower($ext);
if (!$this->didSet){
$this->lia->setResourceSorter($ext, [$this, 'getSortedFiles']);
}
$names = array_reverse($names);
foreach ($names as $n){
if ($index=array_search($n,$this->orders)){
unset($this->orders[$ext][$index]);
}
array_unshift($this->orders[$ext], $n);
}
}
public function getSortedFiles($unsortedFiles){
//@TODO add support for file paths using backslash separators like C:\Whatever\Folder\File.js
if (count($unsortedFiles)==0)return;
$f = array_values($unsortedFiles)[0];
$ext = pathinfo($f, PATHINFO_EXTENSION);
$ext = strtolower($ext);
$orders = $this->orders[$ext];
$counts = [];
foreach ($orders as $o){
$c = count(explode('/', $o));
$counts[$c] = $c;
}
ksort($counts);
$counts = array_reverse($counts, true);
$filesOrder = array_flip($orders);
$sorted = [];
$append = [];
foreach ($unsortedFiles as $f){
$parts = explode('/', $f);
foreach ($counts as $c){
$bits = array_slice($parts, -$c);
$piece = implode('/', $bits);
if (isset($filesOrder[$piece])){
$index = $filesOrder[$piece];
$sorted[$index] = $f;
continue 2;
}
}
$append[] = $f;
}
ksort($sorted);
$sorted = [...$sorted, ...$append];
return $sorted;
}
}