Forums / National / Russian / Тех. поддержка / Консолидация ресурсов

Прододжение темы про некорректную работу алгоритма косолидации

Macik
#1 2012-05-17 12:24

Установил последнее исправление №914

Не помогло. Включил отладку и залез в код. Вот, что выясняется:

if (preg_match_all('#\burl\((\'|")?([^\)"\']+)\1?\)#i', $file_code, $mt, PREG_SET_ORDER))
{
        foreach ($mt as $m)
	{
		$filename = empty($relative_path) ? $m[2] : $relative_path . '/' . $m[2];
		$filename = str_replace($current_path, '', realpath($filename));
		if (!$filename)
		{
			continue;
		}
		if ($filename[0] === '/')
		{
			$filename = mb_substr($filename, 1);
		}
		$file_code = str_replace($m[0], 'url("' . $filename . '")', $file_code);
	}
}

- проблема не в регулярном выражении, оно отрабатывает нормально (по крайней мере с последними правками).
- проблема в логике строк 4005-4007, т.к. на выходе имеем пустой $filename и как следствие выход из цикла без замены кода в CSS.

Теперь подробнее...

В итоге на одном (для примера) из шагов цикла имеем (строки 4005-4007) следующие входные данные:

$path = 'plugins/ratings/tpl/ratings.css';
$relative_path = '\plugins\ratings\tpl';
$m[2] = '../../../images/icons/default/delete.png';
т.е. учитывая путь в $m[2] мы на выходе должны иметь строку 'images/icons/default/delete.png', однако в строке 4006 происходит обнуление $filename (дальше естественно алгоритм уже «правильно» не работает).

Стал копать дальше пришел к выводу, что проблема в функции realpath(), для которой (по видимому) очень важно в каком формате передается путь. Т.к. у меня тестовый сервер работает под Windows, то часть путей (традиционно) имеют формат с обратным слэшем ("C:\dvp\VertrigoServ\www\sites\cot98\plugins\ratings\tpl").

В моем примере (в строке 4006) получается realpath('\plugins\ratings\tpl/../../../images/icons/default/delete.png') возвращает false.

Поэкпериментировал:

realpath('\plugins\ratings\tpl/../../../images/icons/default/delete.png') == false

realpath('plugins\ratings\tpl/../../../images/icons/default/delete.png') == false

realpath('/plugins/ratings/tpl/../../../images/icons/default/delete.png') == false

и только когда все слэши идут в одном формате и без открывающего слеша работает правильно:

realpath('plugins/ratings/tpl/../../../images/icons/default/delete.png') == 'C:\dvp\VertrigoServ\www\sites\cot98\images\icons\default\delete.png'

 

Так что, как решение проблемы надо проверять (и отрезать) ведущий слэш в $filename и конвертировать слэши в «прямые» перед передачей в realpath().

Добавлено 3 минуты спустя:

Да, и в $current_path слеши тоже придется заменить для единообразия и правильной работы str_replace(); в строке 4006.

https://github.com/macik
правильный хостинг — https://goo.gl/fjCa1F
This post was edited by Macik (2012-05-17 12:35, 12 years ago)
Trustmaster
#2 2012-05-17 16:43

Спасибо за исследование! Я бы продолжал безрезультатно пожимать плечами, т.к. Windows для разработки и тестирования не использую и не догадался бы, что дело в слешах.

В самое ближайшее время исправлю слеши на прямые и уберу слеш в начале.

May the Source be with you!
Macik
#3 2012-06-01 21:22

Проверил свежую версию. 

Еще не все чисто (точнее говоря все еще не работает под windows ):

при первом запуске (с включенной консолидацией) на теме HTMLkickstart вылезло вот такое: илл.  С этим пока не разбирался.

А вот с url ресурсами такая картина: илл. - туда попадает полный (файловый) путь, плюс ко всему он там «изувечен».

залез в код: 

Видимо дело вот в этой строке:
4018: $filename = str_replace($current_path, '', realpath($filename));

здесь str_replace не отрабатывает т.к. в $current_path у нас пусть с «правильными» (замененными ранее) слэшами, а realpath нам возвращает windows-style «xxx\xxx\».  Таким образом в $filename оказывается полный файловый путь с обратными слэшами.

 

Добавлено 10 минут спустя:

Поковырял ошибку с «@import» 

надо править регулярное выражение в 4004 строке:

preg_match_all('#@import\s+url\((\'|")?(.+?\.css)\1?\);#i', …

оно жадное и захватывает сразу 2 строки из файла themes/kickstart/style.css и получается:

$m[0] = '@import url(http://fonts.googleapis.com/css?family=Arimo:400,700);@import url(css/modalbox.css);'

что и вызывает ошибку с первого скриншота.

https://github.com/macik
правильный хостинг — https://goo.gl/fjCa1F
This post was edited by Macik (2012-06-01 21:32, 11 years ago)