php

Битрикс ЧПУ, правила urlrewrite.php

Самые часто используемые правила ЧПУ в битриксе это страницы детального описания элемента, например /section/125/ 125 это ID элемента, в основном это дополнительные разделы сайта, для магазинов используется комплексный компонент каталога и там 1 правило для всего компонента, но речь не о ней.

Continue reading

XML to Array and Array to XML

Сейчас много приходится работать с XML (интеграция 1C-Битрикс и 1С), сложная логика проекта не позволяет использовать типового импорта, и задача стоит как можно больше перенести на сторону 1с, ну суть не в этом, задача постоянно парсить XML или собирать и отдавать в 1с, хочу сохранить пару очень удобных классов которые как раз подходят для этих задач. Array2XML и XML2Array

Ссылка 1
Ссылка 2

Особенность Add2BasketByProductID() [bitrix api]

Итак есть одна особенность у это функции, которая так облегчает нам жизнь. И так суть в том, что когда вы добавляете товар в корзину в кол-ве 10 штук, туда попадает 1 или 4 и т.д. В общем кол-во не всегда правильное и это сбивает с толку.

Continue reading

Предыдущий следующий элемент массива по кругу [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];
	}

CIBlockElement::SetPropertyValues()

Следует отметить вот такой порядок параметров

CIBlockElement::SetPropertyValues(
    $i_ElementID, 
    $i_IblockID, 
    array('PROPERTY_CODE' => 'PROPERTY_VALUE')
);

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

Это напоминает логику работы CIBlockElement::Update(), если не все свойства указать в PROPERTY_VALUES.

Проверка вхождения пользователя в определенныу группу [bitrix api]

Думаю метод проверки пользователя в определенной группе обязан быть в API, но его почему-то там не оказалось, есть пару(CUser::GetUserGroupArray(),
CUser::GetUserGroup(), CUser::GetUserGroupString()) методов для выборки всех групп пользователя. Чтобы сделать проверку с помощью этих методов нужны дополнительные манипуляции.

Предложу решение:

/**
* Функция проверки нахождения пользователя в определенной группе
* @param {intva} $i_GroupID - ID группы
* @param {intval} $i_UserID - ID пользователя, если не указан, то текущий 
* @return {bool}
*/ 
function isUserGroupID($i_GroupID, $i_UserID = false)
{
    if(!$i_UserID && $GLOBALS['USER']->IsAuthorized())
        $i_UserID = intval($GLOBALS['USER']->GetID());        

    if($i_UserID)            
        return  in_array($i_GroupID, CUser::GetUserGroup(intval($i_UserID)));
}

var_dunp( isUserGroupID(1, 1) ); // true

Проверка активности элемента по дате [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);
}

Отделение десятых, сотых, тысячных от числа символом [javascript]

Функция вставляет (в данном случае точку) после десятой, сотой, и тысячной доли числа.

var __formatSumm = function(sum)
{
    var c = sum.length, s = sum, m = "", i = 0; 
    while(c--){if(i==3){m+='.'+s[c];i=0;}else{m += s[c];}i++;}	
    return m.split("").reverse().join("");
}

1.000
10.000
100.000

1.000.000
10.000.000
100.000.000

1.000.000.000
10.000.000.000
100.000.000.000

UP

Для php

function __formatSumm($s)
{
    $c  = strlen($s); 
    $ar = preg_split('//', $s, -1, PREG_SPLIT_NO_EMPTY);
    $i  = 0; 
    while($c--){if($i == 3){ $m .='.'.$ar[$c]; $i = 0;}else{ $m .= $ar[$c];}$i++;}	
		
    return strrev($m); 
}