вторник, 30 апреля 2013 г.

перекодировать кучу файлов из cp-1251 в utf-8

sudo apt-get install recode
find . -name "*.php" -print0|xargs -0 recode windows1251..utf8

виртуальный хост для битрикса в utf-8

самая мерзкая легаси в битриксе это то что для его установки в utf-8 требуется внести изменения в php.ini после чего у вас на остальных виртуальных хостах могут перестать работать сайты особенное если в базе хранятся сериализованные строки для того чтобы этого избежать создайте для битрикса виртуальный хост примерно следующего содержания

 
<VirtualHost *:80>
 ServerName biznes.loc
 DocumentRoot /home/user/www/bitrix_biznes
 <Directory /home/user/www/bitrix_biznes> 
  Options FollowSymLinks
  AllowOverride ALL
 </Directory>
 <IfModule mod_php5.c>
     php_value default_charset utf-8
     php_admin_value mbstring.func_overload 2
     php_value mbstring.internal_encoding utf-8
     php_admin_value realpath_cache_size "4096k"
 </IfModule>
</VirtualHost>

вторник, 16 апреля 2013 г.

создание дополнительных параметров для темы компонета

в папку с конкретной темой положить файл ./.parameters.php и и файлы ./lang/ru/.parameters.php ./lang/en/.parameters.php

./.parameters.php

 
<?if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true) die();
$properties = CIBlockProperty::GetList(Array("sort"=>"asc", "name"=>"asc"), Array("ACTIVE"=>"Y", "IBLOCK_ID"=>$arCurrentValues["IBLOCK_ID"]));
while ($prop_fields = $properties->GetNext()){
  $elements[$prop_fields["ID"]]=$prop_fields["NAME"];
}
$arTemplateParameters = array(
 "PROPERTY_ADRESS" => Array(
  "NAME" => GetMessage("T_PROPERTY_ADRESS"),
  "TYPE" => "LIST",
  "VALUES" => $elements,
  "REFRESH" => "Y",
 ),
 "PROPERTY_PHONE" => Array(
  "NAME" => GetMessage("T_PROPERTY_PHONE"),
  "TYPE" => "LIST",
  "VALUES" => $elements,
  "REFRESH" => "Y",
 ),
 "PROPERTY_FAX" => Array(
  "NAME" => GetMessage("T_PROPERTY_FAX"),
  "TYPE" => "LIST",
  "VALUES" => $elements,
  "REFRESH" => "Y",
 ),
 "PROPERTY_EMAIL" => Array(
  "NAME" => GetMessage("T_PROPERTY_EMAIL"),
  "TYPE" => "LIST",
  "VALUES" => $elements,
  "REFRESH" => "Y",
 ),
);
?>
./lang/ru/.parameters.php

 
<?
$MESS["T_PROPERTY_ADRESS"] = "Свойства адреса";
$MESS["T_PROPERTY_PHONE"] = "Свойства телефон";
$MESS["T_PROPERTY_FAX"] = "Свойства факса";
$MESS["T_PROPERTY_EMAIL"] = "Свойства Email";
?>
./lang/en/.parameters.php

 
<?
$MESS["T_PROPERTY_ADRESS"] = "property adress";
$MESS["T_PROPERTY_PHONE"] = "proropery phone";
$MESS["T_PROPERTY_FAX"] = "property fax";
$MESS["T_PROPERTY_EMAIL"] = "property Email";
?>

понедельник, 15 апреля 2013 г.

Устанавливаем redmine на ubuntu

устанавливаем и конфигурируем redmine через aptitude 
sudo aptitude install redmine-mysql

sudo aptitude install redmine

установливаем модуль для апача
sudo apt-get install libapache2-mod-passenger

включаем мод rewrite если не включен
sudo a2enmod passenger rewrite

создаем виртуальную секцию
<VirtualHost *:80>
    ServerName redmine.loc
    DocumentRoot "/usr/share/redmine/public"
    PassengerResolveSymlinksInDocumentRoot on
    Options Indexes ExecCGI FollowSymLinks
</VirtualHost>
правим hosts файл если надо sudo vim /etc/hosts
127.0.0.1 redmine.loc

пятница, 12 апреля 2013 г.

паттерн одиночка

паттерн одиночка
 
 class Singleton {

    protected static $instance;  
    private function __construct() {  }
    private function __clone() {  }
    private function __wakeup() {  }
    public static function getInstance() {
        if ( is_null(self::$instance) ) {
            self::$instance = new self;
        }
        return self::$instance;
    }

    public function method() {
       //вумный код;
    }

}

Singleton::getInstance()->method();


pattern

четверг, 11 апреля 2013 г.

создаем ajax в битрикс

первое и основное ajax должен всегда быть не навязчевым. а теперь как это реализовать
создадим пустую тему в битрекс у меня вот здесь
/bitrix/templates/AJAX_HTML
в данной теме создадим папку sub_themes (/bitrix/templates/AJAX_HTML/sub_themes)
делаем следующий header.php

 
if(!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true)die();
IncludeTemplateLangFile(__FILE__);


/**
 * благодоря данному подходу можно создавать не только пустой шаблон но и обертывать код например наример различным кодом окон
 * Class get_sub_themes_singleton
 */
class get_sub_themes_singleton {
    protected static $instance;  // object instance

    private $list_theme;
    private $sub_theme;
    private $dir_sub_theme;
    private $params;

    private function __construct(){}
    private function __clone(){}
    private function __wakeup(){}

    public static function getInstance() {
        if (is_null(self::$instance)) {
            self::$instance = new get_sub_themes_singleton;
        }
        return self::$instance;
    }

    public function set_sub_theme($sub_theme){
        //поставить при повышенных требованиях к безопасности
        if (!empty($this->list_theme) && !empty($this->list_theme[$sub_theme])){
            $this->sub_theme = $this->list_theme[$sub_theme];
        }
        return self::$instance;
    }
    public function set_dir_sub_theme($dir_sub_theme){
        if (is_dir($dir_sub_theme)){
            $this->dir_sub_theme = $dir_sub_theme;
        }else{
            die("not found sub themes");
        }
        return self::$instance;
    }

    public function set_list_theme($list_theme){
        $this->list_theme = $list_theme;
        return self::$instance;
    }
    public function get_header(){
        //include("");
        //echo $this->sub_theme;
        if (file_exists($this->dir_sub_theme.$this->sub_theme."/header.php")){
            include_once($this->dir_sub_theme.$this->sub_theme."/header.php");
        }
    }
    public function get_footer(){
        if (file_exists($this->dir_sub_theme.$this->sub_theme."/footer.php")){
            include($this->dir_sub_theme.$this->sub_theme."/footer.php");
        }
    }


    public function set_params($key, $value){
        $this->params[$key]=$value;
        return self::$instance;
    }
    public function get_params($key){
        return $this->params[$key];
    }
    public function theme_exists($theme){
        if (!empty($this->list_theme[$theme])){
            return true;
        }else{
            return false;
        }
    }


}

///////////////////////////////////////////////////////////////////////////

get_sub_themes_singleton::getInstance()
    ->set_dir_sub_theme(dirname(__FILE__)."/sub_themes/")
    ->set_list_theme(array(
                    "full_html"     =>"full_html",
                    "work_arena"    =>"work_arena",
                    "simple_windows"=>"simple_windows",
                    ))->set_sub_theme("full_html");

//подключаем тему из url
//хотя можно поставить и в куках
if (!empty($_REQUEST['theme']) &&  get_sub_themes_singleton::getInstance()->theme_exists($_REQUEST['theme'])){
     get_sub_themes_singleton::getInstance()->set_sub_theme($_REQUEST['theme']);
}

get_sub_themes_singleton::getInstance()->get_header();

И такой footer,php
 
get_sub_themes_singleton::getInstance()->get_footer();

в папке /bitrix/templates/AJAX_HTML/sub_themes создаем подтемы с оформлением окон и не забываем указывать темы в через метод set_list_theme (сами темы состоят из header.php и footer.php)
данную тему настраиваем в настройках сайта и указываем что она должна применяться при наличии параметра ajax=Y в url
в футере основной темы создаем базовую парковочную зону (хотя не обязательно так как вы сами будете определять куда загружать контент)
 
<div class="parking_zone"
     closeajax=".parking_zone"
     closebind="click"
    >
</div>
</body>

в header основной темы вставляем следующий jquery скрипт
 
       <script type="text/javascript">
            /**
             * превращаем обычные ссылки в ajax
             */
            $(function(){
                $(".ajax_link").live("click",function(){
                    var parking_zone=$(this).attr("parking_zone");
                    var close_element_control=$(parking_zone).attr("closeajax");
                    var action_close=$(parking_zone).attr("closebind");
                    $(close_element_control).bind(action_close, function(){
                        $(parking_zone).hide();
                    });
                    $(parking_zone).load($(".ajax_link").attr("ajaxhref"), function() {
                        $(parking_zone).show();//настройка анимации окон
                    });
                    return false;
                });

            });
        </script>
и на конец создаем обработчик например на странице
 
 <span class="region-select-a">
<a id = "testid"
      class="ajax_link"
      href="/vibor_regiona/"
      ajaxhref="/vibor_regiona/?ajax=Y&theme=simple_windows&<?=(empty($_REQUEST['параметр'])?"":'region_geo_location='.$_REQUEST['параметр']);?>"
      parking_zone=".parking_zone"
      >blabla</a></span>
вот вроде все

вторник, 9 апреля 2013 г.

раздача прав в консоли

раньше я раздовал права в консоли так
для файлов
find . -type f -exec chmod 666 {} \;
для директорий
find . -type d -exec chmod 777 {} \;

но теперь нашел более оптимальный и быстрый
для файлов

find . -type а -print0|xargs -0 chmod 666
для директорий
find . -type d -print0|xargs -0 chmod 777

в результате создается меньше процессов chmod скорость бьет все рекорды
ps:
иногда необходимо раздавать права от root тогда при попытке использования
find . -type d -print0|xargs -0 sudo chmod 777
chmod выдает sudo: unable to execute /bin/chmod: Argument list too long
мы фактически исчерпываем лимит на длину командной строки (спасибо xargs) 
выход один сначала сделать sudo su; а затем find . -type d -print0|xargs -0 chmod 777




PHP: The Right Way блог програмышки
Яндекс.Метрика