В общем была проблема после переезда на другой хостинг, на timeweb. Попросил поставить Spreadsheet_Excel_Writer, ТП быстро отреагировала и поставила библиотеку, но она напроч отказывалась писать в файл. Т.е. файл генерила, но данные не записывались в файл. Я не дождался ответа в выходной день, оказывается у них админы в выходные не работают, поставил другую библиотеку для работы с Exel, PHPExcel называется. В работе даже полегче чем выше указанная. Она потребовала настройки mbstring.func_overload != 2, что и было сделано, оказалось что и Spreadsheet_Excel_Writer не работала по той же причине, в общем проблема тут mbstring.func_overload
programming languages
Выводим в 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 );
Это уже исправленный код, т.е если мы ищем и заменяем в массиве то ключи должны совпадать и по расположению, т.е. по ключам.
Немного о типах PHP
Оператор сравнения (==)
Проверка переменных:
Взято отсюда http://www.webpeeps.ru/article/17/
Класс для сортировки массива, usort [php]
Пример реализации выборки из нескольких инфоблоков с постраничной навигацией и сортировкой.
Задача:
1) Выбрать список элементов из нескольких инфоблоков в таблицу;
2) Иметь возможность сортировки элементов;
3) Должна работать постраничная навигация
Итак этот пример можно использовать при небольшом кол-ве выбираемых элементов, думаю максимум до 100, естественно с кэшированием.
Первым делом нужно выбрать все данные в ассоциативный массив, например вот такой:
[ITEAM] => Array ( [0] => Array ( [CITY_NAME] => value [CITY_DETAIL_URL] => value [OBJECT_NAME] => value [OBJECT_ID] => 2487 [DATE_CREATE] => 02.07.2006 [STATUS] => Y [PAID_STATUS] => Y [DATEIL_OBJECT_URL] => value ) [1] => Array ( [CITY_NAME] => value [CITY_DETAIL_URL] => value [OBJECT_NAME] => value [OBJECT_ID] => 2489 [DATE_CREATE] => 02.07.2006 [STATUS] => Y [PAID_STATUS] => N [DATEIL_OBJECT_URL] => value )
Ajax и IE7: Ошибка c00ce56e и как ее исправить, в Bitrix не исключение…
Ошибка эта возникает, когда сервер передает IE неизвестную кодировку. То есть, возможна ситуация, когда на одном сервере ваш скрипт будет работать нормально, а на другом — возникнет подобная ошибка.
То есть, передается, как правило — «utf8» а по стандарту должно «utf-8«. То есть, на этот раз Internet Explorer ведет себя вполне корректно (хотя, мог бы и простить, как делает FireFox, например), а гнилые помидоры — тому, кто настраивал web-сервер.
Как исправить? Варианта два:
- Поправить настройки Apache
- B самом начале серверного скрипта Ajax принудительно указать кодировку: header(‘Content-type: text/html; charset=utf-8’);
Поскольку, мы можем не знать настроек сервера, где будет работать наш скрипт, указание данного заголовка header(‘Content-type: text/html; charset=utf-8’);, я считаю, обязательно.
В битриксе это ошибка возникает допустим при обращение аяксом к компоненте в которой подключается js, без js все работает. Так что или выносим js из компонента или пользуемся советами выше.
решение нашли тут
Инфоблоки +, события [bitrix api]
Хочу предостеречь от очень каверзной особенности работы с расширенными инфоблоками у Битрикса, так называемыми Инфоблоками +.
Если вы используете обработчик на редактирование элемента OnBeforeIBlockElementUpdate, и изменяете в нем хоть одно свойство, то вам нужно указать в массиве параметров все свойства этого элемента. Иначе они будут затерты.
Это происходит только на инфоблоках + и не с включенным документооборотом для этого инфоблока. Все дело в массиве PROPERTY_VALUES, в котором вы меняете значение какого-то свойства. Подвох в том что вы не используете метод $el->Update($ID, $arParams) в самом обработчике, и это ошибка трудно уловима, по сути обработчик переопределяет $arParams[‘PROPERTY_VALUES’], по этому в нем будет только ваше изменение из обработчика. В этом случае, если вы будете использовать $el->Update($ID, $arParams) к этому инфоблоку в другом месте, свойства будут сбрасываться.
События хорошая штука, но нужно внимательнее сними работать, ими не стоит злоупотреблять.
Битрикс AJAX [bitrix-ajax-api]
Почему-то многие не охотно используют битриксовую библиотеку аякса, почти всегда делая предпочтения в сторону Jquery или других js библиотек. Не сомненно что Jquery очень не плохая библиотека и отлично работает с ajax, но чтобы свободно разрабатывать сайты не 1с-Битрикс надо знать родное API.
Пост для новичков, думаю будет полезно. Рассматриваем только ajax-овую часть библиотеки, ее основу.