Spreadsheet_Excel_Writer генерит пустой файл

В общем была проблема после переезда на другой хостинг, на timeweb. Попросил поставить Spreadsheet_Excel_Writer, ТП быстро отреагировала и поставила библиотеку, но она напроч отказывалась писать в файл. Т.е. файл генерила, но данные не записывались в файл. Я не дождался ответа в выходной день, оказывается у них админы в выходные не работают, поставил другую библиотеку для работы с Exel, PHPExcel называется. В работе даже полегче чем выше указанная. Она потребовала настройки mbstring.func_overload != 2, что и было сделано, оказалось что и Spreadsheet_Excel_Writer не работала по той же причине, в общем проблема тут mbstring.func_overload

Выводим в header.php компонент с параметрами переданными в теле странцы

Итак чтобы не забывать и постоянно не вспоминать как это делается запишу.
Нам нужно в хидере вывести какую либо информацию, но не просто вставить компонент в шаблон, а передавать в этот компонент какие-то параметры которые мы получаем только в теле страницы.

Делается это так. Пишется функция вида

function componentHeader($text)
{
	global $APPLICATION;
	$arParams = $APPLICATION->GetPageProperty('PARAMS');
	if(is_array($arParams))
	{
		ob_start();
			$APPLICATION->IncludeComponent('demo:test', '', $arParams);
			$contentTime = ob_get_contents();
		ob_end_clean();
		return $contentTime;
	}
}

кладем ее как через init.php и в хидере выводим $APPLICATION->AddBufferContent(«componentHeader»); должно работать.

Мини GetList для файлов

В исходниках битрикса есть CAllFile::GetList($arOrder, $arFilter, $arParams); но он видимо служит для внутреннего использования и не описан в документации. Нам нужно выбрать описание по 10 файлам за раз, этот метод, в качестве параметра фильтра массив из ID файлов не принял. Пришлось накидать свою функцию.

function __arfileGetList($ar_FileID)
{
	if(is_array($ar_FileID) && count($ar_FileID) > 0)
	{
		global $DB;
		$rs_File = $DB->Query(
			"SELECT * FROM b_file WHERE ID IN 
                               (". implode(',', $ar_FileID). ")",
			false,
			"FILE: ".__FILE__." LINE: ".__LINE__
		);
		while($ar_File = $rs_File->Fetch())
		{
			$ar_Result[] = $ar_File;
		}

		if(is_array($ar_Result) && count($ar_Result) > 0)
			return $ar_Result;
	}
}

P/S
Не забудте проверить $ar_FileID, чтобы там были именно ID файлов…

Битрикс и большой кэш по ID

Итак представим что у вас или у вашего клиента большой, высоко-посещаемый сайт. Также представим инфоблок в котором больше 80k элементов. Наверняка у этих элементов есть детальное описание  и я уверен 99,9% что ID кэша это ID вашего элемента.

Итак у нас получается что в папке допустим /bitrix/cache/object_80k/ — 80 000 папок с кэшем, т.е.

/bitrix/catche/object_80k/1

/bitrix/catche/object_80k/2

/bitrix/catche/object_80k/3

/bitrix/catche/object_80k/n

/bitrix/catche/object_80k/80 000

Какой бы у вас не был сервер, поиск папки в общем списке из 80k занимает время. Плюс если сайт посещаемый то вы догадываетесь что происходит, нагрузка на ровном месте, даже я бы сказал в том месте где мы пытаемся ее уменьшить.

Итак решение, на мой взгляд просто очень красивое и элегантное, его подсказал мой коллега  Николай Рыжонин.

function __getGenerationCachePath($id)
{
    $hash = md5($id);
    $path = substr($hash,-4,2).'/'.substr($hash,-2);
    return $path;
}

Пример:

$ob_Cache     = new CPHPCache;
$i_CacheTime  = 3600;
$s_CacheID    = $ID;
$s_CachePatch = "/object_80k/" . __getGenerationCachePath($ID) . "/" . $ID . "/";
if($ob_Cache->InitCache($i_CacheTime, $s_CacheID, $s_CachePatch))
{
    $ar_Cache  = $ob_Cache->GetVars();
    $ar_Result = $ar_Cache['ITEAM'];
}
else
{
    $ar = ''; // выборка
    if($obCityCache->StartDataCache())
    {
        $obCityCache->EndDataCache(array('ITEAM' => $ar));
    }
}

Итак функция создаст путь вида /object_80k/as/df/ID и тем самым разобьет 80k папок на под папки, тем самым уменьшит время поиска кэша и общую нагрузку на сервер.

Да и еще важный момент, функция написана с учетом что ID > 100 000k. хотя тем кому это пригодится это не важно…

str_replace, если работаем с массивами

Сегодня заметил небольшую особенность в стандартной php функции, которую раньше как-то не замечал. Вылез баг в замене значения по маске через  str_replace. Код выглядит вот так :

    $ar_ResultList[] = str_replace(
	array("#ID#", "", "", "", "#CODE#", 
"#CITY_CODE#", "#DETAIL_URL#", "#HOTEL_CODE#"),
	$ar_ObjectFiled,
	$s_LinkTemplates
   );

Это уже исправленный код, т.е если мы ищем и заменяем в массиве то ключи должны совпадать и по расположению, т.е. по ключам.

1c-Битрикс, плохо или хорошо для разработчика?

Хочу высказать наболевшую мысль. С битриксом я работаю уже 4-ый год, и все бы хорошо, но, есть одна большая проблема, для меня по крайне мере. Так все время приходится работать именно с этой CMS, мало того что становится просто скучно, но и еще идет деградации как разработчика.

Я каждый раз радуюсь когда приходится решать какие-то не стандартные задачи, это подстегивает и пинает мозги. Надоел GetList и $arResult. Хочется чего-то новенького….

1c-Битрикс, работаем с агентами [bitrix api]

Для новичков так сказать, про агенты.

Что такое агенты в битриксе?

— Это функция которая будет запущена в определенное время, поддерживает периодичность запуска.

Если вам нужно динамически добавлять агентов, то есть для это API. Если вам просто нужно прикрутить один или два агента то прошу под кат, там по шагам разберемся с этим вопросом.

Continue reading

Установка Adobe AIR Ubuntu 9.10 64x

1. Качаем бинарник с http://get.adobe.com/ru/air/
2. Размешаем файл AdobeAIRInstaller.bin в папке пользователя, например home/user/AdobeAIRInstaller.bin
3. Открываем терминал
4. chmod +x AdobeAIRInstaller.bin
5. sudo ./AdobeAIRInstaller.bin

6. ВАЖНО!

$ sudo cp /usr/lib/libadobecertstore.so /usr/lib32