пятница, 30 декабря 2011 г.

Бесплатная CMS Open Real Estate на Yii

Недавно, мы выпустили бесплатную CMS Open Real Estate на Yii. Открытый исходный код, open source. Это мой первый опыт, работы над open source проектом такого уровня.

В качестве системы контроля версий использовали Mercurial hg. По моему это самое лучшее решение, до этого пробовал CVS, SVN, GIT.

И самое главное набрался опыта работы с Yii framework и планирую продолжить работу с ним. Постепенно, понимаешь, насколько в нем все грамотно реализовано и сколько много труда в него вложено.

пятница, 21 октября 2011 г.

Как в Denwer импортировать через консоль дамп базы mysql

Поражаюсь какой у блогера тупой WYSWIG приходится раставлять тег br руками для переносов, потому что если сделать перенос по умолчанию какой есть в настройках, получается УЖАС.

Иногда приходится импортировать большие дампы sql, через phpmyadmin делать это проблематично, т.к. по умолчанию стоит ограничение на файлы не больше 2Мб. Сегодня надо было импортировать 90Мб, через консоль импортировалось без проблем.

Win+R, cmd, Enter

p:

cd P:\usr\local\mysql5\bin\
mysql_run_to_import_dumps.exe

mysql> \r base_name

mysql> \. dump_file



где p - виртуальный диск, создаваемый денвером
base_name - имя базы
dump_file - файл с дампом базы (включая путь)

Найдено здесь )

пятница, 14 октября 2011 г.

Как получить выбранные элементы checkbox в массив jQuery

var selectedItems = new Array();
$("input[@name='itemSelect[]']:checked").each(function() {selectedItems.push($(this).val());});
 
if (selectedItems .length == 0) {
    alert("Please select item(s) to delete.");
} else {
    $.ajax({
        type: "POST",
        url: "/ajax_do_something.php",
        data: "items=" + selectedItems.join('|'),
        dataType: "text",
        success: function (request) {
            document.location.reload();
        },
        error: function(request,error){
            alert('Error deleting item(s), try again later.');
        }
    })
} 
Нашел здесь

среда, 3 августа 2011 г.

Паттерн Одиночка - Singleton Pattern в PHP

Код - пример #1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<?php
// PHP5
class Logger {

    static private $instance = NULL;

    /* Возвращаем ссылку на одиночку  */
    static function getInstance() {
    
        /* Если объект еще не создан, создаем */
        if (self::$instance == NULL) {
            self::$instance = new Logger();
        }
        
        return self::$instance;
    }

    /* Запрещаем прямое создание */
    private function __construct() {
    
    }

    /* Запрещаем клонирование */
    private function __clone() {
    
    }

}

вторник, 31 мая 2011 г.

Абстрактная фабрика - (Abstract Factory)

Список паттернов
Код - пример #1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
<?php
/*

Абстрактная фабрика - (Abstract Factory)

Фабрика должна возвращать объекты. Но так как она абстрактная, то изначально нужно
описать абстрактный класс фабрики, и абстрактные объекты которые она будет производить. 

Дале мы описываем реализации классов фабрик на основе абстрактной фабрики и реализации класса объектов
которые она производит. Тем самым у нас есть различные варианты фабрик и объектов с одинковыми
интерфейсами, что может быть удобно.

Далее привожу код. Есть абстрактная фабрика машин. Абстрактный класс машин. Создаем классы фабрики
"ford" и "vaz" и классы ford_machine и vaz_machine. Фабрики будут производить объект "машины", но
свойство "начинака" этих "машин" будет отличаться, прям как в реальной жизни.

*/

abstract class abstract_machine_factory {
    function generate_sedan() {
        return new machine('sedan');
    }
    
    function generate_universal() {
        return new machine('universal');    
    }
    
    function generate_hatchback() {
        return new machine('hatchback');    
    }
}

abstract class abstract_machine {
    protected $_param;

    function __construct($type = 'sedan') {
        $this->_param = array();
        $this->_param['type'] = $type;
    }    
    
    function run() {
        echo 'brrrrrrrrrrrrrr ...';
    }
    
    function get_all_param() {
        return $this->_param;
    }
}

class vaz_machine extends abstract_machine {
    function __construct($type = 'sedan') {
        parent::__construct($type);

        $this->_param['firm'] = 'vaz';
    }

    function run() {
        echo 'tr tr pr tr tr pr ...';
    }
}

class vaz_factory extends abstract_machine_factory {
    function generate_sedan() {
        return new vaz_machine('vedro');
    }
    
    function generate_universal() {
        return new vaz_machine('taz');    
    }
    
    function generate_hatchback() {
        return new vaz_machine('korito');    
    }    
}

class ford_machine extends abstract_machine {
    function __construct($type = 'sedan') {
        parent::__construct($type);
        
        $this->_param['firm'] = 'ford';
    }

    function run() {
        echo 'rrrrrrrrrrrrrrrrr ...';
    }
}

class ford_factory extends abstract_machine_factory {
    function generate_sedan() {
        return new ford_machine('sedan', 'ford');
    }
    
    function generate_universal() {
        return new ford_machine('universal');    
    }
    
    function generate_hatchback() {
        return new ford_machine('hatchback');    
    }    
}

/* Фабрика ford_factory производит машины */
$ford_factory = new ford_factory();
$ford_machine = $ford_factory->generate_sedan();

deb($ford_machine->get_all_param());
deb($ford_machine->run());

/* Фабрика vaz_factory производит машины, функции одинаковые но результат (объекты) разные */
$vaz_factory = new vaz_factory();
$vaz_machine = $vaz_factory->generate_sedan();

deb($vaz_machine->get_all_param());
deb($vaz_machine->run());

/* В результате мы видим на экране:

Array
(
    [type] => sedan
    [firm] => ford
)

rrrrrrrrrrrrrrrrr ...

Array
(
    [type] => vedro
    [firm] => vaz
)

tr tr pr tr tr pr ...

*/

function deb($mVar) {
    echo("<PRE>");
    print_r($mVar);
    echo("</PRE>");
}


Список паттернов

Паттерны проектирования с примерами PHP

Чтобы получше разобраться с паттернами на PHP, решил их глубже изучить и написать простые примеры их реализации на PHP. Ниже список основных паттернов, буду по мере возможности добавлять ссылки на примеры с реализацией.


Порождающие паттерны.


Эта одна из категорий на которые разбивают шаблоны проектирования. В свою очередь эту категорию делят еще на два типа — паттерны порождающие объекты и паттерны порождающие классы. Первые создаются с помощью другого объекта, вторые с помощью наследования изменяют класс создаваемого объекта.
Основная идея порождающих паттернов заключается в том, что инстанцирование объектов происходит «за кадром», они скрывают в себе какие именно классы используются в приложении и детали их реализации, оставляя только интерфейсы к ним. По-идее это позволяет собрать полностью рабочее приложение из различных заготовленных заранее объектов, но по своему опыту скажу, что это практически невозможно без использования других типов шаблонов.

Их всего 5:
1. Абстрактная фабрика (Abstract Factory)
2. Одиночка (Singleton)
3. Прототип (Prototype)
4. Строитель (Builder)
5. Фабричный метод (Factory Method)


Структурные паттерны.


Здесь также есть два типа — паттерны уровня класса и паттерны уровня объекта. Самым ярким примером первых, на мой взгляд является «Адаптер». Общий смысл его в том, что если вдруг у нас есть класс и его интерфейсы не совместимы с другими библиотеками в нашей системе, то что бы разрешить этот конфликт, мы не изменяем код этого класса, а пишем для него адаптер. Очень часто этот паттерн применяется при написании библиотек, которые позволяют работать с различными СУБД. Паттерны уровня объекта позволяют достичь большей гибкости в приложения во время его выполнения. Наиболее популярный из них - «Декоратор».

Всего 7:
1. Адаптер (Adapter)
2. Декоратор (Decorator)
3. Заместитель (Proxy)
4. Компоновщик (Composite)
5. Мост (Bridge)
6. Приспособленец (Flyweight)
7. Фасад (Facade)


Паттерны поведения.


Основная идея паттернов этого типа — взаимодействие объектов и классов между собой. Но они также делятся на два уровня — паттерны поведения уровня класса и паттерны поведения уровня объекта. Здесь самое сложное это добиться наименьшей степени связанности компонентов системы друг с другом, потому что почти все объекты должны знать о существовании других и нести в себе эту информацию. Отсюда и появились такие сложные паттерны как «Посредник» и «Цепочка обязанностей».

Их 11:
1. Интерпретатор (Interpreter)
2. Итератор (Iterator)
3. Команда (Command)
4. Наблюдатель (Observer)
5. Посетитель (Visitor)
6. Посредник (Mediator)
7. Состояние (State)
8. Стратегия (Strategy)
9. Хранитель (Memento)
10. Цепочка обязанностей (Chain of Responsibility)
11. Шаблонный метод (Template Method)


скопипастил

четверг, 21 апреля 2011 г.

go.js - классы для JavaScript и другое

go.js - классы для JavaScript и другое
- Эмуляция "классов" - Наследовение - Связывание методов с контекстом объекта - Доступ к цепи предков и предыдущим реализациям методов - Статические методы, абстрактные классы, разрушение объектов - Печеньки - Стопрацентнае, на, покрытие юнит-тестами Брать здесь или клонировать тут

go.js - зачем оно нужно и как работает

go.js, это JavaScript-библиотека.

Все популярные JavaScript-библиотеки акцентируют внимание на взаимодействии с DOM, визуальных эффектах и достижении кроссбраузерности. В этих областях они достигли больших высот и пытаться воспроизводить данный функционал самостоятельно, достаточно бессмысленно. Лучше взять тот же jQuery.

go.js концентрируется на упрощении внутренних вещей языка, например, ООП. Подразумевается использование go.js вместе с какой-либо другой библиотекой.

Почему не взять надстройку над ООП из тех же MooTools или Prototype?

  1. Потому что брюзге-автору не нравятся многие моменты реализации этих надстроек.
  2. Например, в jQuery нет вообще ничего для ООП, а переходить на другую библиотеку только из-за ООП глупо. Подключать же вслед за jQuery ещё и Prototype с его объёмами и конфликтами, тоже не рационально.

Определение IP пользователя PHP

function ip() {
    if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
        $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
    } elseif (isset($_SERVER['HTTP_CLIENT_IP'])) {
        $ip = $_SERVER['HTTP_CLIENT_IP'];
    } else {
        $ip = $_SERVER['REMOTE_ADDR'];
    }
    return $ip;
}

суббота, 5 февраля 2011 г.

Клиентская и серверная валидация

Одна из наиболее частых задач в web-разработке - создание форм и проверка их на корректность вводимых данных. Для того чтобы это все было более юзабильно, есть специальный jQuery Validation Plugin. Этот плагин позволяет на стороне клиента, проверять форму на корректность вводимых данных, соответственно не требуется перезагрузка страницы.

Чтобы облегчить создание форм в web-приложениях, существуют различные библиотеки. Одна из них HTML_QuickForm2 и ее доработка jQuickForm которая должна была подружить, этот построитель форм с jQuery Validation Plugin. Вышло на мой взгляд не плохо, но слишком наворочено. К тому же автор давно не развивал это дополнение, последний раз когда я скачивал этот пакет, не работала клиентская валидация, а ведь изначально именно для этого и был разработанн этот пакет.

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

У всех этих "помошников" построителей форм, есть минусы - 1. Необходимо разбиратся с интерфейсами классов, как правило, сделано удобно, разобраться можно быстро 2. Сложности кастомизации, изменения дизайна форм 3. Все эти надстройки жрут ресурсы

После размышлений над этим, я создал небольшой класс, который занимается только валидацией, правила задаются аналогично jQuery Validation Plugin. Объект этого класса создает необходимый код JS для валидации на стороне клиента (если нужно) и также проверяет формы на стороне сервера по тем же правилам. Привожу пример -


<?php
header("Content-Type: text/html; charset=utf-8");
require 'valid/Valid.php';
require 'valid/ValidLang.php';

$oValid = new Valid($l);
$oValid->addRule('login', 'required');
$oValid->addRule('login', 'minlength', 5);
$oValid->addRule('pass', 'required');
$oValid->addRule('pass', 'minlength', 5);
$oValid->addRule('re_pass', 'equalTo', 'pass');
$oValid->addRule('email', 'required');
$oValid->addRule('email', 'email');

if (isset($_POST['login'])) {
   if ($oValid->check()) {
       // Здесь можно проверить дополнительно, на повторный логин и мыло например
       echo 'Валидация успешна';
       // Сохраняем данные, редиректим если надо
   }
}
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
   <head>
       <title>Valid - mini validator</title>
       <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
     
       <link rel="STYLESHEET" type="text/css" href="css/eform.css">
       <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script>
       <script type="text/javascript">
               !window.jQuery && document.write('<script src="js/jquery-1.4.3.min.js"><\/script>');
       </script>
       <script type="text/javascript" src="js/jquery.validate.pack.js"></script>
       <script type="text/javascript" src="js/jquery.form.js"></script>
   </head>
 
<body>

<form action="index.php" method="post" name="reg_form" id="reg_form" class="eForm">
   <fieldset>
       <legend><?php echo $l['index']['registration']; ?></legend>
       <p>
           <label for="login"><?php echo $l['index']['login']; ?></label>
           <input type="text" id="login" name="login" value="<?php echo $oValid->getReq('login');?>" />
           <?php echo $oValid->getErr('login');?>
       </p>
       <p>
           <label for="pass"><?php echo $l['index']['pass']; ?></label>
           <input type="password" id="pass" name="pass" value="" />
           <?php echo $oValid->getErr('pass');?>
       </p>
       <p>
           <label for="re_pass"><?php echo $l['index']['re_pass']; ?></label>
           <input type="password" id="re_pass" name="re_pass" value="" />
           <?php echo $oValid->getErr('re_pass');?>
       </p>
       <p>
           <label for="email"><?php echo $l['index']['email']; ?></label>
           <input type="text" id="email" name="email" value="<?php echo $oValid->getReq('email');?>" />
           <?php echo $oValid->getErr('email');?>
       </p>
       <p>
           <input type="submit" value="<?php echo $l['index']['registration']; ?>" class="noresize submit"/>
       </p>
   </fieldset>
</form>

<?php echo $oValid->getJS('reg_form'); ?>

</body>
</html>

Пример реализации можно посмотреть в моем mini MVC framework, там уже реализована регистрация, авторизация - mFram

среда, 2 февраля 2011 г.

Скролл к элементу DOM HTML

Переход к элементу с определённым id достигается очень просто: даётся ссылка с href="#id-элемента". Однако, иногда id у элемента нет. Используя jQuery перейти к определённому элементу можно так:

$("html,body").scrollTop($(myElement).offset().top);
$("html,body").animate({scrollTop: $(myElement).offset().top}, 1000);

Прочел у Sam-a

вторник, 1 февраля 2011 г.

Логирование ошибок в файл Denwer

Как оказалось Denwer не логирует php ошибки в файл, а штука очень даже нужная особенно на фоне борьбы с ошибками. Чтобы он начал логировать, нужно вставить вот такой фрагмент кода в файл .htaccess :
php_value error_reporting E_ALL
php_value display_errors Off
php_value display_startup_errors Off
php_value log_errors On
php_value log_errors_max_len 1024
php_value ignore_repeated_errors Off
php_value ignore_repeated_source Off
php_value report_memleaks On
php_value track_errors Off
php_value html_errors Off
php_value error_log "error.log"

вторник, 25 января 2011 г.

Фоны для вебдизайна

Скопипастил у Тормоза

Парсим курс валют

Код - пример #1
1
2
3
4
5
6
7
$url = 'http://www.cbr.ru/scripts/XML_daily.asp?date_req='.date("d/m/Y");
$buf = file_get_contents($url);
if($buf) {
 $xmldoc = new SimpleXMLElement($buf);
 $result = $xmldoc->Xpath("//Valute[@ID='R01239']"); //R01239 код евро
 echo $result[0]->Value;
}
Скопипастил

четверг, 13 января 2011 г.

Как называются радиобатоны по-русски?

Не задумывался над этим, спросили, откопал вот такие варианты - "Радио", "Переключатель", "Переключатель многопозиционый" )) но все таки правильный - "Радиокнопка"