no IE6

Безусловно в жизни web разработчика ie6 это проблема. Для меня все версии ie, мягко говоря, не вызывают доверия. Снипед для ie6, но я жду не дождусь когда и от ie7 я с большим удовольствием его поставлю. От ie8 и выше, жить становится лучше.

Пишем в /bitrix/php_interface/init.php что-то типа:

	$user_agent = $_SERVER['HTTP_USER_AGENT'];
	if (stripos($user_agent, 'MSIE 6.0') !== false && stripos($user_agent, 'MSIE 8.0') === false && stripos($user_agent, 'MSIE 7.0') === false)
		header ("Location: /ie6/ie6.html");

Создаем папку типа /ie6/ и редиректим всех «счастливых» обладателей туда. Ну чтобы их совсем не обижать добавим специальную заглушку типа этой

AJAX навигация по меткам

Итак задача, нужно сохранять состояние страницы после ajax запроса. Для этого приспособили метки у ссылок, URL будет вот такого вида http://site.ru/#/key:val/key1:val1/keyN:valN/

В js далеко не гуру, но все работает и нативно.

var Navigation = function()
{
this.isHash = function(){return (window.location.href.indexOf('#') !== -1 && window.location.hash.length > 1);};

/**
* Возвращает все параметры из url в виде объекта
*/
this.getQueryParams = function(){
if(this.isHash())
{
var _ar = window.location.hash.replace('#', '').split('/');
var _ob = {};

for(var i=0; i < _ar.length; i++){
if(_ar[i] !== "")
_ob[i] = _ar[i];
}

var returnObject = {};
for(var j in _ob){

if (_ob.hasOwnProperty(j)) {
var _ar_params = _ob[j].split(':');
returnObject[_ar_params[0]] = _ar_params[1];
}
}

return returnObject;
}

return false;
};

/**
* Устанавливает строку параметров, если есть сотрет что было
*/
this.setHash = function(objectParsms){

var ar = [], j = 0;
for(var i in objectParsms){
j++; ar[j] = i + ':' + objectParsms[i];
}

var hashString = ar.join('/');

if(hashString.length > 0)
window.location.hash = '#' + hashString + '/';
};

this._isEmptyObject = function(Obj)
{
var i = 0;
for(var o in Obj){
i++;
}

return i;
};

this._isKeyObject = function(obj, key){

for(var o in obj)
{
if(o === key)
return true;
}

return false;
};

/**
* Добавляет параметр в url, если параметр уже есть то заменит значение на новое
*/
this.addHashParam = function(objectParams){

if(this.isHash())
{
var params = this.getQueryParams();

for(var o in objectParams){
if(this._isKeyObject(params, o)){
params[o] = objectParams[o];
}
}

var arRes = [], k = 0;
for(var or in params){
k++;arRes[k] = or + ':' + params[or];
}

var str_hash = arRes.join('/');

var ar = [], j = 0;
for(var i in objectParams){
if(!this._isKeyObject(params, i)){
j++; ar[j] = i + ':' + objectParams[i];
}
}

if(ar.length > 0){
str_hash += ar.join('/') + '/';
}
else{
str_hash += '/';
}

window.location.hash = str_hash;
}
else
{
this.setHash(objectParams);
}
};

/**
* Удаляет параметр из url можно указывать несколько, принимает массив ключей
*/
this.delHashParams = function(arParams){
if(this.isHash())
{
var params = this.getQueryParams();

for(var a = 0; a <= arParams.length; a++){
delete params[arParams[a]];
}

if(this._isEmptyObject(params) > 0)
this.setHash(params);
else
window.location.hash = '';
};
};
};

Делать такую навигацию весьма трудоемко, но позволяет немного шире использовать ajax.

Предзагрузка изображений js [snippets]

2 рабочие функции для пред загрузки картинок, нативная и jQuery.

	

function preload(images) {
   if (typeof document.body == "undefined") return;
 	    try {

 	        var div = document.createElement("div");
 	        var s = div.style;
 	            s.position = "absolute";
 	        s.top = s.left = 0;
 	        s.visibility = "hidden";
 	        document.body.appendChild(div);
         div.innerHTML = "";
 	        var lastImg = div.lastChild;
 	        lastImg.onload = function() { document.body.removeChild(document.body.lastChild); };
 	     }
 	     catch(e) {
 	        // Error. Do nothing.
     }
 	}
 	});

	jQuery.preloadImages = function () {
	    var images = (typeof arguments[0] == 'object') ? arguments[0] : arguments;
	    for (var i = 0; i < images.length; i++) {
	        jQuery("").attr("src", images[i]);
	    }
	}

Найдено на просторах.
http://clip2net.com/clip/m11386/1304961837-clip-11kb.png

Конвертер валют для Bitrix [php, js]

Конвертер валют Битрикс

Конвертер валют Битрикс

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

В битриксе есть модуль «Валюты» он нам нужен для back-end нашего конвертера. Для автоматического обновления есть скрипт который обновляет курс, его можно запускать кроном или агентом, я выбрал крон. Там же в модуле валюты есть список курсов, с названиями и значениями курса по умолчанию, по большому счету нам нужны только названия валют оттуда. Его пришлось собирать ручками, по этому в архиве положу csv файл, загрузите его сами. Теперь когда back-end готов можно перейти к компоненту.

Компонент обрабатывает данные из модуля, он должен быть постоянно кэшированным так как при вычислении коэффициента для каждой валюты, создается большой кол-во запросов, благо они мелкие и легкие. Кэш компонента очищается при отработки скрипта на кроне, в коде это можно найти. Логика компонента возвращает 2 json объекта с которыми мы в дальнейшем работаем в шаблоне. В общем смотрим что получилось, улучшать там есть что, буду раз замечаниям.

Скачать архив

В папке cron скрипт для пересчета валюты, в flag флаги, их нужно положить в upload или поправить пути. Не забудьте подключить jQuery.

 

Send mail with attachment php

function XMailAttach($from, $to, $subj, $text, $ar_File)  
{  
	$un        = strtoupper(uniqid(time()));  
	$head      = "From: $from\n";  
	$head     .= "To: $to\n";  
	$head     .= "Subject: $subj\n";  
	$head     .= "X-Mailer: PHPMail Tool\n";  
	$head     .= "Reply-To: $from\n";  
	$head     .= "Mime-Version: 1.0\n";  
	$head     .= "Content-Type:multipart/mixed;";  
	$head     .= "boundary=\"----------".$un."\"\n\n";  
	$zag       = "------------".$un."\nContent-Type:text/html;\n";  
	$zag      .= "Content-Transfer-Encoding: 8bit\n\n$text\n\n";  
								 
	foreach ($ar_File as $file)
	{
		$f         = fopen($file, "rb");  
		$zag      .= "------------".$un."\n";  
		$zag      .= "Content-Type: application/octet-stream;";  
		$zag      .= "name=\"".basename($file)."\"\n";  
		$zag      .= "Content-Transfer-Encoding:base64\n";  
		$zag      .= "Content-Disposition:attachment;";  
		$zag      .= "filename=\"".basename($file)."\"\n\n";  
		$zag      .= chunk_split(base64_encode(fread($f,filesize($file))))."\n";  
	}
								 
	if (!mail($to, $subj, $zag, $head))  
	 	return false;  
	else  
		return true;  
}

Сколько лет пользователю сайта?

Немного лениво выглядит профиль пользователя на сайте, когда вместо надписи о количестве лет выводится дата его рождения. Снипед, для Битрикса, жаль что нету API функции.

if(strlen($ar_UserCabinet['PERSONAL_BIRTHDAY']) > 0)
{
	$ar_UserDateTo  = explode('.', $ar_UserCabinet['PERSONAL_BIRTHDAY']);
	$s_MetaDateTo   = mktime(0, 0, 0, $ar_UserDateTo[1], $ar_UserDateTo[0], $ar_UserDateTo[2]);
	$s_MetaDateFrom = mktime(0, 0, 0, date('m'), date('d'), date('Y'));
	$i_Meta = ($s_MetaDateFrom - $s_MetaDateTo) / 31276800;

	# проверим был ли у пользователя день рождения, если еще небыло то -1
	$s_DateRog = mktime(0, 0, 0, $ar_UserDateTo[1], $ar_UserDateTo[0], date('Y'));
	if($s_DateRog > $s_MetaDateFrom)
		$i_Meta -= 1;

	$arResult['USER_BIRTHDAY'] = intval($i_Meta);
}

Немного о bash

По умолчанию команды сохраняются после закрытия терминала, причем файл не дописывается, а переписывается, чтобы это исправить нужно в файл ~/.bashrc добавить:

shopt -s histappend
PROMPT_COMMAND='history -a'

bash попытается исправить неправильный пусть указанный в команде cd если прописать в тот же файл это:

shopt -s cdspell

Можно запретить писать в историю подряд идущие одинаковые команды:

export HISTCONTROL="ignoredups"

Заперт логирования команд:

export HISTIGNORE="&:ls:[bf]g:exit"

Не разрывать многострочные команды:

shopt -s cmdhist

Перед командой можно писать дату ее выполнения:

export HISTTIMEFORMAT='%h %d %H:%M:%S '

оригинал статьи

Вывод в заголовок диапазона элементов [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);
}