php

Предыдущий следующий элемент массива по кругу [php]

Для формирования ссылок на детальных страниц нужно искать предыдущий и следующий элемент, для построения url.

Это первое способ, собрать все ID в массив и найти prev и next. Второй способ если у вас много элементов, использовать pagination (постраничну навигацию) с настройкой списка в 1 элемент.

Snippet для 1 случая:

// массив с ID
$ar_ElementID = array();

// текущий ID (должен присутствовать в $ar_ElementID)
$i_CurrentID = 777

// находим текущий ключ
$i_KeyCurrent =	array_search($i_CurrentID, $ar_ElementID);

// кол-во элементов в массиве
$i_CountElement = count($ar_ElementID);


/* коротко */

	// слудеющий ID	
	$i_NextID = ( $i_KeyCurrent !== ($i_CountElement -1) ) 
		? $ar_ElementID[$i_KeyCurrent + 1] : 0;

	// предыдущий ID
	$i_PrevID = ( $i_KeyCurrent == 0 ) 
		? $ar_ElementID[$i_CountElement - 1] : $ar_ElementID[$i_KeyCurrent - 1];


/* длинно */

	// слудеющий ID	
	if($i_KeyCurrent !== ($i_CountElement -1) )
	{
		$i_NextID = $ar_ElementID[ $i_KeyCurrent + 1 ];
	}	
	else 
	{
		$i_NextID = 0;
	}	
		
	// предыдущий ID
	if($i_KeyCurrent == 0 )
	{
		$i_PrevID = $ar_ElementID[$i_CountElement - 1];
	}	
	else
	{
		$i_PrevID = $ar_ElementID[$i_KeyCurrent - 1];
	}

Проверка активности элемента по дате [bitrix api]

В методе CIBlockElement::GetList() есть параметр фильтра для выборки активных элементов по дате. Т.е. проверка происходит еще в запросе и не надо в списке нечего проверять дополнительно.

Если вам нужно обратная сторона действия с фильтрацией по дате активности, то у вас это не получится сделать. Мной ожидалось поведение, что если
заменить Y на N то выборка отдаст только не активные по дате элементы, но к сожалению это не так, читаем еще раз док и убеждаемся в этом.

ACTIVE_DATE — непустое значение задействует фильтр по датам активности.
Будут выбраны активные по датам элементы.Если значение не установлено («»), фильтрация по датам активности не производится;

Приходится делать полную выборку и проверят уже в результате что конечно не очень хорошо.

function __isElelementDateActive($s_DateFrom, $s_DateTo)
{
    $stmp_DateFrom = MakeTimeStamp($s_DateFrom, "DD.MM.YYYY HH:MI:SS");
    $stmp_DateTo   = MakeTimeStamp($s_DateTo, "DD.MM.YYYY HH:MI:SS");
    $stmp_Date     = MakeTimeStamp(date('d.m.Y H:i:s'), "DD.MM.YYYY HH:MI:SS");

    return ($stmp_Date > $stmp_DateFrom && $stmp_Date < $stmp_DateTo);
}
+ бонус, проверка если дата истекает за 1 день
function __isOneDayShowElement($s_DateTo)
{
    $stmp_DateTo   = MakeTimeStamp($s_DateTo, "DD.MM.YYYY");
    $stmp_Date     = MakeTimeStamp(date('d.m.Y'), "DD.MM.YYYY");

    return (($stmp_DateTo - $stmp_Date) == 86400);
}
+ дата и время

function isDateTimeActive($date_from, $date_to)
{
    $ar_From    	= explode(' ', $date_from);
    $ar_DateFrom    = explode('.', $ar_From[0]);
    $ar_TimeFrom    = explode(':', $ar_From[1]);

    $ar_To      	= explode(' ', $date_to);
    $ar_DateTo    	= explode('.', $ar_To[0]);
    $ar_TimeTo    	= explode(':', $ar_To[1]);

    $ar_Date        = explode('.', date('d.m.Y'));
    $ar_Time        = explode(':', date('H:i:s'));

    $s_MetaDateFrom = mktime($ar_TimeFrom[0], $ar_TimeFrom[1], $ar_TimeFrom[2], $ar_DateFrom[1], $ar_DateFrom[0], $ar_DateFrom[2]);
    $s_MetaDateTo   = mktime($ar_TimeTo[0],   $ar_TimeTo[1],   $ar_TimeTo[2],   $ar_DateTo[1],   $ar_DateTo[0],   $ar_DateTo[2]);
    $s_MetaDate     = mktime($ar_Time[0],     $ar_Time[1],     $ar_Time[2],     $ar_Date[1],     $ar_Date[0],     $ar_Date[2]);

    return ($s_MetaDate >= $s_MetaDateFrom && $s_MetaDate <= $s_MetaDateTo);
}

Тот еще COUNT

Иногда бывает под вечер зависнешь на какой-нибудь проверке и не можешь понять почему логика не складывается. Оказывается просто потому что,  не логично работают некоторые участки системы.

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

[source language=’php’]
//$i = 1.05; // true
//$i = 1;  // true
//$i = ‘1’; // true
$i = array();// false
var_dump(count($i) > 0);
[/source]

Логичнее наверное сделать что если переменная не массив, то возвращать NULL или false, так нет же надо возвращать 1.

Если var не является массивом или объектом, реализующим интерфейс Countable, будет возвращена 1. За одним исключением: если varNULL, то будет возвращён 0.

Вывод в заголовок диапазона элементов [c 10 по 20]

Задача, вывести в пагинацию и в заголовок диапазон в котором находится пользователь в текущий момент т.е.  в конец добавлять текущую позицию в списке,  список [c 10 по 20]

Вот наброски кода который решает эту задачу $rs_Element объект типа arResult

if(is_array($ar_Navigatonparams))
{
    $ar_NavParams = array(
        'NavPageNomer'    => $rs_Element->NavPageNomer,
        'NavPageSize'     => $rs_Element->NavPageSize,
        'NavRecordCount'  => $rs_Element->NavRecordCount,
        'nEndPage'        => $rs_Element->nEndPage
    );

    function navigationIntervalList($ar_NavParams)
    {
        if(isset($_REQUEST['PAGEN_1']) && intval($_REQUEST['PAGEN_1']) > 0)
        {
            if(intval($ar_NavParams['NavPageNomer'])  > 1)
            {
                $_s = ($ar_NavParams['NavPageNomer'] * $ar_NavParams['NavPageSize']) - $ar_NavParams['NavPageSize'] + 1;
                $_p = $ar_NavParams['NavPageNomer'] * $ar_NavParams['NavPageSize'];

                if($ar_NavParams['nEndPage'] == $ar_NavParams['NavPageNomer'])
                    $_p = $ar_NavParams['NavRecordCount'];

                return 'список с '.$_s.' по '.$_p;
            }
        }
    }

    $s_nav = navigationIntervalList($ar_NavParams);
    $s_Nav = (!empty($s_nav)) ? ' / '.$s_nav : '';
    $s_Tit = (!empty($s_nav)) ? ', '.$s_nav : '';

    $APPLICATION->AddChainItem($s_TitleNavchain.$s_Nav);
    $APPLICATION->SetTitle($s_TitleNavchain.$s_Tit);
}

Мини 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 файлов…

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

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

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

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

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

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

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

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

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

Continue reading

Создаем опции для пользователя. cохранение настроек страницы для авторизованных пользователей [bitrix api]

В битриксе есть не задокументированный инструмент для весьма интересной задачи. Допустим нам нужно открыть ту страницу сайта на которой последний раз был пользователь. Или настроить фильтры на списках элементов, т.е. задача где-то хранить последние значения по нужным движениям пользователя на сайте, чтобы когда он вернулся восстановить прежний вид. Это бывает нужно не так часто но нужно иметь ввиду что для этого есть таблица и API с которой вполне можно работать не изобретая своего велика.

Итак класс находится в файле require_once($_SERVER[«DOCUMENT_ROOT»].BX_ROOT.»/modules/main/classes/».$GLOBALS[«DBType»].»/favorites.php»);

Основные методы записи и чтения

function CUserOptions::SetOption($category, $name, $value, $bCommon=false, $user_id=false)

function CUserOptions::GetOption($category, $name, $default_value=false, $user_id=false)

В классе есть еще методы, подробно все освещать не буду так как хочу попробовать использовать этот класс, и написать подробно как и где его можно применять.