воскресенье, 22 декабря 2013 г.

ubuntu 13.10 Отключить поиск в интернете

Для отключения поиска в интернете надо в консоли выполнить команду:

gsettings set com.canonical.Unity.Lenses disabled-scopes "['more_suggestions-amazon.scope', 'more_suggestions-u1ms.scope', 'more_suggestions-populartracks.scope', 'music-musicstore.scope', 'more_suggestions-ebay.scope', 'more_suggestions-ubuntushop.scope', 'more_suggestions-skimlinks.scope']"

четверг, 21 ноября 2013 г.

воскресенье, 17 ноября 2013 г.

angularjs ng-repeat ng-click

Для того что бы без проблем можно было вызвать  ng-click внутри ng-repeat, надо вместо переменных  в фигурных скобках писать просто переменные (вместо {{item.id}} просто item.id):

<li ng-repeat="item in items" ng-click="myMethod(item.id)">
   text
</li>

javascript foreach

Аналог php конструкции foreach в javascript:

var length = myArray.length, element = null;

for (var i = 0; i < length; i++) {
   element = myArray[i];
}

четверг, 14 ноября 2013 г.

javascript array_intersect()

Аналог php функции array_intersect в javascript:

function array_intersect(array1, array2)
{
   var result = array1.filter(function(n) {
      return array2.indexOf(n) !== -1;
   });

   return result;
}

javascript in_array()

Аналог php функции in_array в javascript:

function in_array(needle, haystack) {
   return haystack.indexOf(needle) !== -1;
}

воскресенье, 10 ноября 2013 г.

angularjs ng-repeat Не работает сортировка

angularjs 1.0.6

Столкнулся с тем что ангулар отказывается сортировать элементы при применении стандартного механизма сортировки:

data-ng-repeat="(key,region) in regions | orderBy:'name'"

Я присылаю данные с сервера в json и сразу показываю:

$http.get('/get.php).success(function(response){
 $scope.regions = response;
});


Оказалось что ангулар начинает сортировать только если массив данных для сортировки уже отсортирован по ключу.

Вот такие данные он сортировать отказывался:

[
 3 => [
 'id' => 3
 'name' => 'some3'
 ],
 1 => [
 'id' => 1
 'name' => 'some2'
 ],
 2 => [
 'id' => 2
 'name' => 'some2'
 ],
]

А такие прошли на ура:

[
 1 => [
 'id' => 1
 'name' => 'some1'
 ],
 2 => [
 'id' => 2
 'name' => 'some2'
 ],
 3 => [
 'id' => 3
 'name' => 'some3'
 ],
]

среда, 6 ноября 2013 г.

mariadb-client : Зависит: mariadb-client-5.5 (= 5.5.33a+maria-1~saucy) но он не будет установлен

Если при установке mariadb вылезли ошибки:

Пакеты, имеющие неудовлетворённые зависимости:
 mariadb-client : Зависит: mariadb-client-5.5 (= 5.5.33a+maria-1~saucy) но он не будет установлен
 mariadb-server : Зависит: mariadb-server-5.5 (= 5.5.33a+maria-1~saucy) но он не будет установлен



Решение:

Смотрим актуальные версии пакетов:

apt-cache show mysql-common | grep Version
apt-cache show libmysqlclient18 | grep Version


Пример:

ivan@ivan-desktop:~$ apt-cache show mysql-common | grep Version

Version: 5.5.34-0ubuntu0.13.10.1
Version: 5.5.33a+maria-1~saucy
Version: 5.5.32-0ubuntu7

ivan@ivan-desktop:~$ apt-cache show libmysqlclient18 | grep Version

Version: 5.5.34-0ubuntu0.13.10.1
Version: 5.5.33a+maria-1~saucy
Version: 5.5.32-0ubuntu7


Указываем точную версию пакетов, которые хотим установить:

apt-get install mariadb-server-5.5 mariadb-client-5.5 \
 libmysqlclient18=5.5.33a+maria-1~saucy \
 mysql-common=5.5.33a+maria-1~saucy


Нашел тут: http://askubuntu.com/questions/365992/ubuntu-13-10-installing-mariadb

Установка Nginx + PHP + MariaDB


MariaDB

Для ubuntu saucy

sudo apt-get install software-properties-common
sudo apt-key adv --recv-keys --keyserver hkp://keyserver.ubuntu.com:80 0xcbcb082a1bb943db
sudo add-apt-repository 'deb http://mirror.timeweb.ru/mariadb/repo/5.5/ubuntu saucy main'

sudo apt-get update
sudo apt-get install mariadb-server mariadb-client

Для других дистрибутивов надо смотреть инструкции https://downloads.mariadb.org/mariadb/repositories/



Nginx

sudo apt-get install nginx



PHP

sudo apt-get install php5-cli php5-common php5-mysql php5-gd php5-fpm php5-cgi php5-fpm php-pear php5-mcrypt php5-curl php5-imap php5-memcache php5-xsl php5-json


sudo gedit /etc/php5/fpm/php.ini

cgi.fix_pathinfo = 0



sudo gedit /etc/php5/fpm/pool.d/www.conf

security.limit_extensions = .php



sudo gedit /etc/nginx/sites-available/default

server {
listen 80;

index index.php index.html;

server_name *.localhost;

root /home/user/www/$subdomain;

set $subdomain "";

if ($host ~* ^([a-z0-9-\.]+)\.localhost$) {
set $subdomain $1;
}

location / {

try_files $uri $uri/ /index.php /index.html;

}

location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;

fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
}

location ~* \.(?:jpg|ico|gif|png|css|js|svg)$ {
access_log off;
expires 30d;
}
}

ubuntu mysqldiff

Для сравнения локальных баз данных надо набрать в консоли:

mysqldiff --user=root --password=mypass oldDatabase newDatabase


пятница, 1 ноября 2013 г.

phpExcel Получение буквы колонки по индексу

Так гораздо лучше, если приходится часто изменять количество колонок в таблице, а самих колнок достаточно большое количество

<?php
$ColumnIndex = 25;
$ColumnLetter = PHPExcel_Cell::stringFromColumnIndex($ColumnIndex);

воскресенье, 13 октября 2013 г.

angular ng:repeat Передать ключ элемента массива

Для того что бы в ng:repeat использовать ключи элементов, надо объявлять переменную для ключа в скобочках:

Пример:

<tr ng:repeat="(pid,p) in items">

пятница, 27 сентября 2013 г.

PHP Error[8]: unserialize(): Error at offset

Это значит что данные, которые вы пытаетесь распаковать повреждены.
Проверьте, сериализованные ли это данные и кодировку строки.

четверг, 26 сентября 2013 г.

git Удалить ветку в репозитории

Для удаления ветки в удалённом репозитории:

git push <source_name> --delete <branch_name>

Пример: git push origin --delete my_branch

Удаление в локальном репозитории:

git branch -D <branch_name>

Пример: git branch -D my_branch

вторник, 24 сентября 2013 г.

crontab Запуск задачи с параметром времени

Задача: запускать каждый месяц скрипт  и передавать в него параметром месяц, который был 2 месяца назад.

Решение:

0 0 1 * * e96-script /home/e96/e96.ru/www/cronscripts/monthsOrdersReport.php `date "+%m %Y" -d "2 month ago"`


Вместо 0 0 1 * * можно поставить @montly

пятница, 20 сентября 2013 г.

sphinx PDO::__construct(): Server sent charset (0)

Поставил sphinx на ubuntu из репозиториев и обнаружил на сайте такую ошибку

PDO::__construct(): Server sent charset (0)

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

После сборки из исходников проблема отпала сама собой, возможно дело в версии.

Установка sphinx из исходников (ubuntu)

Скачиваем здесь http://sphinxsearch.com/downloads/release исходники Source tarball (tar.gz)

Распаковываем и в папке с исходниками выполняем команды

(если стоит mariadb, как у меня)
sudo aptitude install libmariadbclient-dev libmariadbd-dev checkinstall

(если стоит mysql, не тестил, но должно так же работать)
sudo aptitude install libmysql++-dev libmysqlclient15-dev checkinstall

./configure

make

sudo checkinstall

Создаем конфиг в /usr/local/etc/sphinx.conf

Теперь запускаем индексацию

sudo /usr/local/bin/indexer --all

После индексации запускаем демон

sudo /usr/local/bin/searchd

четверг, 19 сентября 2013 г.

среда, 18 сентября 2013 г.

Странное поведение mysql datediff

Понадобилось выбрать все записи, дата создания которых больше 30 дней.
Дата создания хранится в поле типа datetime

Для начала написал

DATEDIFF(NOW() , creation_date) > 30

Выборка забрала не все записи, которые были нужны. Нехитрым тестами определил, какие записи выпадают и обнаружил что при вычитании из текущей даты значения по умолчанию (0000-00-00 00:00:00) возвращается null.

Решение очевидно.

(DATEDIFF(NOW() , creation_date) > 30) OR (ISNULL(DATEDIFF(NOW() , creation_date)))

Надо будет разобраться, почему так происходит. Возможно идет какое то преобразование к timestamp

вторник, 17 сентября 2013 г.

PHP Warning: Error while sending QUERY packet

При долгом выполнении скрипта может появиться такая ошибка.
Лечится периодическим пингом базы:


$mysqli = new mysqli($host, $user, $pass, $db);
$mysqli->ping()

среда, 11 сентября 2013 г.

php htmlspecialchars Вырезает русские символы

Если такое происходит, значит надо установить правильную кодировку для строки. Для htmlspecialchars по умолчанию кодировка utf8.

четверг, 5 сентября 2013 г.

mysql Регистрозависимый поиск like

Для того, что бы LIKE осуществлял регистрозависимый поиск, нужно что бы таблица была в кодировке utf8 или использовать LIKE BINARY

среда, 7 августа 2013 г.

facebook like button Сбросить кеш

Кеш сбросить можно сдесь: https://developers.facebook.com/tools/debug Надо просто вбить урл нужной страницы.

Это может понадобиться, если надо обновить, к примеру, тайтл кнопки.

понедельник, 29 июля 2013 г.

yii Как проверить маршрут

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

$_SERVER['HTTP_X_REWRITE_URL'] = $newUrl; //стандартных методов для присвоения урла в CHttpRequest не нашел, по этому сделал небольшой подлог, после всех манипуляций, значение можно будет восстановить.

$route = Yii::app()->urlManager->parseUrl(new CHttpRequest);
$controller=app()->createController($route);

if($controller)
{
    //если контроллер существует, можно, например, сделать редирект
    $this->redirect(app()->createUrl($newUrl));
}
else
{
    //если, нет, то что ни будь другое
}

воскресенье, 28 июля 2013 г.

yii Включение логирования запросов

Модели это хорошо, но посмотреть, какие запросы строит yii тоже иногда полезно =)

Для того, что бы включить логирование запросов в yii, надо в main.php прописать следующие настройки:

...
'preload'=>array('log'),
...

'db'=>array(
...
       // включаем профайлер
        'enableProfiling'=>true,


       // показываем значения параметров
        'enableParamLogging' => true,
...

),
...
'log'=>array(
'class'=>'CLogRouter',
'routes'=>array(
array(
'class'=>'CProfileLogRoute',
'levels'=>'profile',
'enabled'=>true,
),
),

),

среда, 24 июля 2013 г.

git Поиск коммита по названию(комментарию)

Если надо найти коммит по части строки в названии:

git log --grep="some_string"

Можно использовать более короткую запись

git log --pretty=format:"%s %H" | grep "some_string"

Просмотр коммита:

git show 1234567890 // 1234567890 - идентификатор коммита, конечно

среда, 17 июля 2013 г.

вторник, 2 июля 2013 г.

понедельник, 24 июня 2013 г.

The XSS Auditor refused to execute a script in

Обнаружил на сайте баг. При сохранении отваливается css и в консоль выдает примерно следующее:

The XSS Auditor refused to execute a script in 'http://site.com' because its source code was found within the request. The auditor was enabled as the server sent neither an 'X-XSS-Protection' nor 'Content-Security-Policy' header.

Как я понял, это новая "фича" хрома. Надеюсь, со временем доведут до ума.
Лечится отправкой с сервера заголовка X-XSS-Protection: 0

Пример:

header('X-XSS-Protection: 0');

воскресенье, 16 июня 2013 г.

yii Изменить папку assets

Для смены папки assets на что то другое в main.php надо добавить:

'components'=>array(
                'assetManager'=>array(
                          'basePath'=>'newPath',
                    ),
...

суббота, 15 июня 2013 г.

windows выполение в фоновом режиме

Для того что бы запустить приложение в фоновом режиме можно использовать hstart.
Штука удобная и интуитивно понятная, я запускал из консоли, но есть и графическая версия:

hstart /NOCONSOLE "batch_file_1.bat"

Или в моем случае, это был php скрипт

hstart /NOCONSOLE "php C:\script.php"

Есть хороший readme и примеры.

вторник, 11 июня 2013 г.

mysql Сбросить primary key

Для того что бы первичный ключ с автоинкрементом снова начал присваивать значения начиная с 1 нужно выполнить запрос

ALTER TABLE `ourTable` AUTO_INCREMENT = 1

воскресенье, 9 июня 2013 г.

Fatal error: Class 'Swift_DependencyContainer' not found

Если возникает такая ошибка, значит надо вместо swift_init.php подключать swift_required.php

Не правильно:

require_once 'swift/swift_init.php';

Правильно:

require_once 'swift/swift_required.php';

суббота, 8 июня 2013 г.

Хороший mysql клиент

Хороший на мой взгляд клиент для mysql это Valentina Studio. Пользуюсь им под виндой уже около месяца - двух, все нравится. Скачать можно на офф сайте. Иногда он даже обновляется =)

Окно выбора подключения


linux Как запустить php скрипт, что бы он выполнялся после закрытия консоли

Если понадобилось оставить скрипт работающим надолго, а сидеть с открытой консолью/работающим браузером не хочется, то всегда выручит nohup. В консоли надо набрать:

nohup php test.php &

И смело закрывать консоль. Скрипт не закончит работу, пока не сделает импорт/экспорт/спарсит все интернеты =)

пятница, 7 июня 2013 г.

windows7 Как использовать RDP client

В 7 винде для использования нативного клиента надо сначала включить Remote Desktop Protocol:

1) пуск - компьютер - ПКМ - свойства



2) Настройка удалённого доступа

Поставить галочку на против "Разрешить подключения удаленного помощника к этому компьютеру"

И на против "Разрешать подключения от компьютеров с любой версией удаленного рабочего стола(опаснее)"




Теперь надо запустить нативный клиент для подключения:

1) Пуск - Программы - стандартные - Подключение к удалённому рабочему столу

Во всплывшем окне надо ввести ip компьютера, к которому надо подключится


2) Нажимаем "Подключить"
3) Вводим логин и пароль

Готово.

qutim Не показывает контакты

После установка свежей убунты (13.04) установил из репозитория qutim, который отказался показывать мне контакты. Дело оказалось в том, что у меня был кутим 0.2. Получить 0.3 можно так:


sudo add-apt-repository ppa:qutim/qutim

sudo apt-get update

sudo apt-get install qutim

четверг, 6 июня 2013 г.

php Вопросики вместо русских символов

Если случилась такая проблема, то сразу после подключения надо указать кодировку для базы данных:

<?php

mysql_query('SET NAMES utf8');

?>

php Сделать первые буквы слов заглавными

Для того, что бы сделать все первые буквы слов заглавными, надо применить функцию ucwords(), или ucfirst() если нужно сделать заглавной только первую букву в строке:

<?php

echo ucfirst($str); // первая буква строки в верхнем регистре

echo ucwords($str); // все первые буквы слов в верхнем регистре

?>


Если ucwords, или ucfirst не работают, но вы всё сделали правильно, то скорее всего дело в том, что вы используете кодировку utf-8.

Для того что бы перевести все первые буквы слов в верхний регистр в кодировке utf-8 надо использовать mb_convert_case():

<?php

echo mb_convert_case($row->name, MB_CASE_TITLE, 'utf-8'); // аналог ucwords

?>


У этого подхода есть небольшой минус: mb_convert_case($row->name, MB_CASE_TITLE, 'utf-8') сначала переводит всю строку в нижний регистр, и только потом первые буквы слов в верхний.




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

<?php

echo mb_strtoupper(mb_substr($string, 0, 1, 'utf-8'), 'utf-8') . mb_substr($string, 1, mb_strlen($string), 'utf-8');

?>

вторник, 4 июня 2013 г.

php intval для больших чисел

Если вам надо проверить, к примеру, 12 значное число, то intval уже не подойдет

Для этого есть floatval()

четверг, 30 мая 2013 г.

php imagecolorat Всегда возвращает черный цвет

Если imagecolorat возвращает всегда 0, или какие то другие не корректные значения, надо вместо побитового сдвига использовать функцию imagecolorsforindex



Не правильно:

$imgObject = imagecreatefrompng('our.png');
$fillColor = imagecolorat($imgObject, 0, 0);

 $rgba = array(
    ($fillColor >> 16) & 0xFF,
    ($fillColor >> 8) & 0xFF,
     $fillColor & 0xFF,
    ($fillColor >> 24) & 0xFF
);




Правильно:

$imgObject = imagecreatefrompng('our.png');
$fillColor = imagecolorat($imgObject, 0, 0);
$colors = imagecolorsforindex($imgObject, $fillColor);

$rgba  = array(
   $colors['red'],
   $colors['green'],
   $colors['blue'],
    $colors['alpha']
);

среда, 29 мая 2013 г.

Установка ubuntu с флешки

Для установки убунты с флешки понадобится образ убунты, программа Universal-USB-Installer и флешка =) Можно вместо Universal USB Installer воспользоваться такой штукой как unetbootin, но я не пробовал.

После запуска выбираем файл образа, версию и букву диска, жмём Create и получаем флешку с убунтой, которую можно использовать как лайвсиди или для установки на компьютер.

З.Ы. Надо помнить, что перед установкой флешку надо форматировать в fat32, иначе ничего не получится.



Теперь надо перезагрузиться и выбрать в биосе загрузку с usb.

вторник, 28 мая 2013 г.

yii savewithrelated bug

Неожиданно для меня данное расширение отказалось правильно работать при сохранении новой модели со связью многие-ко-многим.

Это связно с тем, что в ESaveRelatedBehavior.php в строке 262
yii не может различить CManyManyRelation и CHasManyRelation

Я не придумал ничего лучше чем просто проверять primaryKey, не очень правильно, зато работает.

В protected/behaviors/ESaveRelatedBehavior.php стр. 262

} elseif ($relation instanceof CHasManyRelation) { // Handle has_many relations

Меняем на

} elseif ($relation instanceof CHasManyRelation && $this->owner->primaryKey) {


Готово.

понедельник, 27 мая 2013 г.

yii ajax загрузка файлов

Сначала надо подключить jquery.form.js

Затем в jquery.yiiactiveform.js

Меняем в функции $.fn.yiiactiveform.validate с 345 строки по 369

//$.ajax({
  $form.ajaxSubmit({
url : settings.validationUrl,
type : $form.attr('method'),
// data : $form.serialize() + extData,
        data : {ajax:$form.attr('id')},
dataType : 'json',
success : function (data) {
if (data !== null && typeof data === 'object') {
$.each(settings.attributes, function () {
if (!this.enableAjaxValidation) {
delete data[this.id];
}
});
successCallback($.extend({}, messages, data));
} else {
successCallback(messages);
}
},
error : function () {
if (errorCallback !== undefined) {
errorCallback();
}
}
});

И все работает. Теперь можно загружать файлы через аякс.

Решение нашел на форуме http://yiiframework.ru/forum/viewtopic.php?f=3&t=2521

суббота, 25 мая 2013 г.

apache Не видит папку или файл

Если апач не видит папку, посмотрите ее владельца, права и проверьте .htaccess внутри папки. Вполне возможно что внутри .htaccess перезаписывается какое ни будь значение, которое запрещено изменять. Для проверки просто временно очистите .htaccess, если папка появилась, то дело в нём.

Если апач не видит php файл, проверьте, что у него стоят права на исполнение и что отсутствуют права на запись у группы и остальных.

mysql Не сохраняет большие тексты

Максимальный размер поля типа text составляет 64 килобайта, если надо сохранить текст больше, выберите mediumtext или longtext.

среда, 22 мая 2013 г.

Установить facebook like button

Ддя того что бы поставить на сайт лайк фейсбука, надо зайти на страницу https://developers.facebook.com/docs/reference/plugins/like/
Воспользовавшись конфигуратором сгенерировать код кнопки и поставить его на страницу.

Например так:

После открывающего тега <body>


<div id="fb-root"></div>
<script>(function(d, s, id) {
  var js, fjs = d.getElementsByTagName(s)[0];
  if (d.getElementById(id)) return;
  js = d.createElement(s); js.id = id;
  js.src = "//connect.facebook.net/ru_RU/all.js#xfbml=1";
  fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));</script>


Туда, где должна находится кнопка лайка

<div class="fb-like" data-send="true" data-width="450" data-show-faces="true"></div>


Но это еще не всё.
На момент написания поста фейсбук еще не поправил кодогенератор и кое-что придется подправлять ручками.

В

<div class="fb-like" data-send="true" data-width="450" data-show-faces="true"></div>

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

<div class="fb-like" href="http://badphpcoder.blogspot.ru" data-send="true" data-width="450" data-show-faces="true"></div>


Вот конечный код с генерацией ссылки для текущей страницы:

<div class="fb-like" href="http://<?php echo $_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']; ?>" data-send="false" data-layout="button_count" data-width="450" data-show-faces="false"></div>

Теперь кнопка работает.

php Эмуляция функции mail

При разработке сайтов под windows часто требуется проверить отправку почты. Придумано большое количество заглушек для этого, но на мой взгляд самым удобным способом является использование программки smtp4dev. Она проста и удобна. Если использовать standalone версию, то она будет состоять всего лишь из одного файла smtp4dev.exe. После запуска сворачивается в трей и спокойно ждет, пока какой ни будь скрипт не использует функцию mail.

Скачать можно здесь.

Создание .htaccess windows

Напрямую через проводник создать .htaccess в windows не получится, для этого надо

1. Создать текстовый файл,
2. Открыть его в блокноте,
3. Файл -> Сохранить как
4. Выбрать тип файла "Все файлы (*.*)"
5 Сохранить с именем ".htaccess"

Готово.

Установка yii

Предполагается, что апач уже настроен и поднят, а по запросу http://localhost у вас открывается страница приветствия, к примеру C:\web\localhost

1. Скачаем самую свежую версию с офф сайта http://www.yiiframework.com/download
(это будет что то вроде yii-1.1.13.e9e4a0.tar.gz)

Тем, кто умеет пользоваться git или svn эта статья не понадобится =)



2. Создадим папку C:\web\localhost\yii_project



3. Разархивируем и скопируем подпапку framework из архива в C:\web\localhost\yii_project\framework



4. Открываем cmd и переходим в C:\web\localhost\yii_project\framework

cd C:\web\localhost\yii_project\framework



5. Создаем новый web проект под название mysite

yiic webapp C:\web\localhost\yii_project\mysite

Yii Спросит, создавать приложение, отвечайте "да":


Create a Web application under 'C:\web\yii_project\mysite'? (yes|no) [no]: yes

Теперь у нас есть сайт, который открывается по адресу http://localhost/yii_project/mysite


Далее пойдут необязательные пункты, которые хоть и не нужны для того, что бы просто установить yii, но обычно всегда выполняются.



6. Настройка yii на mysql


Изначально yii настроен на sqlite, ничего плохого в этом не вижу, но я привык работать с mysql.

В файле mysite\protected\config\main.php комментируем строки

/*

'db'=>array(
'connectionString' => 'sqlite:'.dirname(__FILE__).'/../data/testdrive.db',
),


*/


И раскомментируем

'db'=>array(
  'connectionString' => 'mysql:host=localhost;dbname=testdrive',
  'emulatePrepare' => true,
  'username' => 'root',
  'password' => '',
  'charset' => 'utf8',
),


Где
testdrive  - это имя вашей локальной базы данных
username - логин доступа к базе
password - пароль доступа к базе



7. Включение чпу

Всё в том же mysite\protected\config\main.php раскомментируем строчки

'urlManager'=>array(
  'urlFormat'=>'path',
  'rules'=>array(
    '<controller:\w+>/<id:\d+>'=>'<controller>/view',
    '<controller:\w+>/<action:\w+>/<id:\d+>'=>'<controller>/<action>',
    '<controller:\w+>/<action:\w+>'=>'<controller>/<action>',
  ),
),


И вставим строку 'showScriptName' => false,
Получится

'urlManager'=>array(
  'urlFormat'=>'path',
  'showScriptName' => false,
  'rules'=>array(
    '<controller:\w+>/<id:\d+>'=>'<controller>/view',
    '<controller:\w+>/<action:\w+>/<id:\d+>'=>'<controller>/<action>',
    '<controller:\w+>/<action:\w+>'=>'<controller>/<action>',
  ),
),


Это еще не все, yii настроен, но сам сервер не понимает запросы, для того что бы научить его, нужно положить в C:\web\localhost\yii_project\mysite файл .htaccess


RewriteEngine on

# если директория или файл существуют, использовать их напрямую
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# иначе отправлять запрос на файл index.php
RewriteRule . index.php


Если не знаете, как создать .htacces то вам сюда


Все, yii настроен.

среда, 15 мая 2013 г.

phpThumb Заливка прозрачным цветом

Обычная заливка в phpThumb делается с помощью метода pad(), который принимает третьим параметром массив цвета в RGB. Что бы научить его заливать прозрачным цветом, надо его немного изменить:

В GdThumb.inc.php на 164 строке

public function pad ($width, $height, $color=array(255, 255, 255))


Меняем на

public function pad ($width, $height, $color=array(255, 255, 255, 0))


А на 182 строке

        $fillColor = imagecolorallocate (
            $this->workingImage,
            $color[0],
            $color[1],
            $color[2]
        );


На

        $fillColor = imagecolorallocatealpha (
            $this->workingImage,
            $color[0],
            $color[1],
            $color[2],
            $color[3]
        );


В 198 строке добавляем

        if($color[3])
        {
            imagesavealpha($this->workingImage, true);
        }



Сохраняем.
Теперь в метод  pad() можно скармливать массив RGBA для заливки с прозрачностью.

понедельник, 13 мая 2013 г.

Вставить видео на сайт

Для вставки видео на сайт есть 2 способа:

1) Вставить видео с ютуба или любого другого сервиса

Для этого надо просто зайти на страницу с видео роликом, нажать "поделиться" и скопировать оттуда html код себе на страницу.

2) Использовать html5 плеер

Что бы вставить видео на сайт с помощью html5, нужно использовать html5 плеер. Одним из таких плееров является flowplayer. Он использует jquery, достаточно удобен на мой взгляд и хорошо документирован.

Пример использования:

В header вставляем:

<script type="text/javascript" src="js/flowplayer/flowplayer-3.2.2.min.js"></script>

В body, туда где будет наше видео:

    <a href="1.flw" style="display: block; width: 468px; height: 286px;" id="player">
        <img src="1.jpg" width="468" height="286" />
    </a>


Сама инициализация плеера:

    <script language="JavaScript">
        flowplayer("player", {
            src: "http://oursite.com/js/flowplayer/flowplayer-3.2.2.swf",
            wmode: "transparent"},
            {
            clip: {
                autoPlay: true,
                autoBuffering: false,
            },
            playlist: ["http://oursite.com/1.flw"]
        });
    </script>


Здесь вместо ссылки на файл 1.flw будет окно с плеером в котором пользователь сможет его посмотреть. До того, как будет воспроизведено видео пользователь увидит картинку 1.jpg. Для запуска видео ему нужно будет кликнуть по изображению.

пятница, 10 мая 2013 г.

jquery Прокрутка страницы

Для того что бы прокрутить экран до элемента надо использовать функцию animate().

Пример:



    $('a').click(function() {

        $('html, body').animate({
            scrollTop: $('#elementtoScrollToID').offset().top
        }, 'slow');

        return false;
    });


Для прокрутки до верха страницы:


    $('a').click(function() {
        $("html, body").animate({scrollTop: 0}, "slow");
        return false;
    });


php Не правильное время

Если php показывает не правильное время, когда вы используете date() или new DateTime()
Причин может быть несколько. Либо вы выбрали не правильный часовой пояс. либо ошиблись в формате даты.

Часовой пояс выставляется в php.ini:

[Date]
; Defines the default timezone used by the date functions
; http://php.net/date.timezone
date.timezone = Europe/Moscow


Ошибки в формате данных могут быть самые разнообразные, вот например моя:

echo date('Y-m-d H:m:s');


Вместо

echo date('Y-m-d H:i:s');


В итоге я всегда получал значение текущего месяца вместо минут.

Насильно обновить файлы через git pull

Для того что бы насильно обновить файлы до последней ревизии надо использовать


git fetch --all
git reset --hard origin/master


git fetch Загружает последнюю версию из всех репозиториев без попытки обновления проекта.
git reset Сбрасывает ветку master до только что скачанной ревизии.

четверг, 9 мая 2013 г.

php Установка sendmail на debian

Для того что бы отправлять почту через php надо сначала установить пакет sendmail:

apt-get install sendmail

Затем в /etc/php5/apache2/php.ini найти и поправить sendmail_path:

sendmail_path = /usr/sbin/sendmail -t -i

Установка завершена. Перезапускаем апач и пользуемся:

/etc/init.d/apache2 restart

html5 Геолокация (geolocation)

Для того что бы определить страну или город посетителя по ip можно использовать html5 + google maps api.

В простейшем случае нам надо всего лишь вызвать

navigator.geolocation.getCurrentPosition()

Пример:


navigator.geolocation.getCurrentPosition(foundLocation, noLocation);


function foundLocation(position)
{
    console.log(location.address.city);
}

function noLocation()
{
    console.log('no position');
}



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

Для того, что бы сделать код более универсальным, придется использовать сервис для обратного геокодирования, который предоставляет гугл:


navigator.geolocation.getCurrentPosition(foundLocation, noLocation);


function foundLocation(position)
{
    $.get('http://maps.googleapis.com/maps/api/geocode/json?latlng='+position.coords.latitude+','+position.coords.longitude+'&sensor=false', 


    function(response){
        console.log(response);
    });

}

function noLocation()
{
    console.log('no position');
}


В итоге у нас окажется объект response с кучей полезной информации расположении пользователя.

Вот что он вернул мне например, интересующие на данные находятся в results:

Object {results: Array[14], status: "OK"}
results: Array[14]
0: Object
1: Object
2: Object
3: Object
4: Object
5: Object
6: Object
7: Object
8: Object
9: Object
10: Object
11: Object
12: Object
13: Object
length: 14
__proto__: Array[0]
status: "OK"
__proto__: Object


Для работы всего этого дела надо не забыть подключить google maps api конечно же:

<script type="text/javascript" src="//maps.googleapis.com/maps/api/js?v=3.exp&amp;sensor=false&amp;libraries=places"></script>

среда, 8 мая 2013 г.

Ограничить по размерам google.maps.places.Autocomplete

Так как значение ширины высчитывается скриптом, напрямую задать его не удастся. Для того что бы сделать больше или меньше окно селекта google.maps.places.Autocomplete надо через css установить значения для минимальной/максимальной ширины для .pac-container

Пример:

.pac-container {
    min-width: 400px;
}

четверг, 2 мая 2013 г.

yii Некорректный запрос

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

Пример:

Метод

public function actionView($id)
{
      echo 'Это наш метод';
}


Не правильно:

site.com/controller/view

//Мы получим в ответ "Некорректный запрос", так как не указали id

Правильно:

site.com/controller/view/42

//Получим "Это наш метод"




Так же проверьте фильтры. Если, например, метод обозначен как ajaxOnly, то прямой его вызов так же будет генерировать 400 ошибку.

yii Не генерируется код валидации yiiactiveform

Сделал форму через виджет CActiveForm, но она упорно не хотела валидироваться, просмотрел html и выяснил, что не генерируется код валидации yiiactiveform.

После долгих экспериментов выяснилось, что виджету необходимо, что бы были поля error. А если они не нужны то их нужно специально отключать при вызове виджета:


<?php $form = $this->beginWidget('CActiveForm', array(
    'action' => Yii::app()->createUrl('subscribe/save'),
    'id' => 'form',
    'enableClientValidation' => true,
    'clientOptions' => array(
        'hideErrorMessage' => true, // вот эта волшебная опция
    ),
        )); ?>

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

Одинаковые комментарии facebook на каждой странице

Фейсбук это вам не вконтакте =)
Для того что бы на каждой странице были разные комментарии фейсбука, надо  в блоке

<div class="fb-comments" data-href="http://example.com" data-width="470" data-num-posts="10"></div>

Вставлять текущую страницу, для которой надо отображать комментарии.

Пример:

<div class="fb-comments" data-href="http://example.com/page/1" data-width="470" data-num-posts="10"></div>


<div class="fb-comments" data-href="http://example.com/page/2" data-width="470" data-num-posts="10"></div>


<div class="fb-comments" data-href="http://example.com/page/3" data-width="470" data-num-posts="10"></div>



Сделать это можно ручками =) Или вот так:

<div class="fb-comments" data-href="http://<?php echo $_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']; ?>" data-width="470" data-num-posts="10"></div>

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

php. Деление массива на 2

Для того что бы поделить массив на 2 части можно воспользоваться функцией array_chunk()

Пример:

$array = array('a', 'b', 'c', 'd');

$parts = array_chunk($array, count($array) / 2);

// $parts[0] = array(0 => 'a', 1 => 'b');
// $parts[1] = array(0 => 'c', 1 => 'd');

Если передать третьим аргументом true, то ключи массива будут сохранены:

// $parts[0] = array(0 => 'a', 1 => 'b');
// $parts[1] = array(2 => 'c', 3 => 'd');

суббота, 20 апреля 2013 г.

php. Вычесть из даты год, месяц, или день

Для того что бы получить дату которая была какое то время назад, можно сделать так:

//вычитаем год
$date = new DateTime();
$date->modify('-1 year');
echo $date->format('Y-m-d H:i:s');

//вычитаем месяц
$date = new DateTime();
$date->modify('-1 month');
echo $date->format('Y-m-d H:i:s');

//вычитаем день
$date = new DateTime();
$date->modify('-1 day');
echo $date->format('Y-m-d H:i:s');



С добавлением оно так же работает, надо просто заменить - на +.


среда, 17 апреля 2013 г.

mysql. Can't create table (errno: 121)

Если при попытке создании внешнего ключа возникает ошибка 121 значит ключ, который вы пытаетесь создать, уже существует. Попробуйте переименовать его во что ни будь более оригинальное.

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

mysql. "Can't create table errno: 150" или как добавить внешний ключ к существующей таблице.

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


ALTER TABLE comment
ADD CONSTRAINT fk_user_id
FOREIGN KEY (user_id) REFERENCES user(id)
ON UPDATE CASCADE
ON DELETE CASCADE;


Надо помнить, что foreign key не поддерживается в MyISAM, придется преобразовывать таблицы в InnoDB

Так же поля для внешнего ключа должны быть одинакового типа и размера. Например:
comment.user_id(UNSIGNED INT 11) и user.id(UNSIGNED INT 11)

Если вы вдруг в чём то ошиблись, то удалить внешний ключ можно так:

ALTER TABLE comment DROP FOREIGN KEY fk_user_id


google maps api автозаполнение. Поиск региона

Понадобилось сделать ввод города или страны,что бы при вводе первых букв показывались возможные значения. Лучшим вариантом показался google maps api autocomplete.

Для того что бы показывались только города и страны, выставляем type = (regions)

Код:

<script src="//maps.googleapis.com/maps/api/js?v=3.exp&sensor=false&libraries=places"></script>
<script>
      function initialize() {

        var input = document.getElementById('searchTextField');

        var options = {
          types: ['(regions)'],
        };

        var autocomplete = new google.maps.places.Autocomplete(input, options);

        google.maps.event.addListener(autocomplete, 'place_changed', function() {
          var place = autocomplete.getPlace(); //получаем место
          console.log(place);
          console.log(place.name);  //название места
          console.log(place.id);  //уникальный идентификатор места
        });

      }
      google.maps.event.addDomListener(window, 'load', initialize);
</script>


В html:

<input id="searchTextField" size="50" type="text" />



Для того что бы искать только по городам, выставляем type = (cities)

Об ограничениях.

Ограничения яндекса, это 10000 поисковых запросов в сутки с подтверждённым телефоном.
Гугла - 20 000 000 запросов в день.

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

robots.txt для яндекса и гугла

robots.txt имеет простую цель - показать роботам, что можно индексировать, а что нельзя.

Сначала обычно пишется, для кого правило, а потом само правило:


User-agent: * 
Disallow: /


* - Означает для всех
Disallow - запретить
/ - все директории, начиная с корня сайта



Disallow - запрещает доступ
Allow - разрешает



Вот возможные значения для яндекса:

YandexBot - основной индексирующий робот;
YandexMedia - робот, индексирующий мультимедийные данные;
YandexImages - индексатор Яндекс.Картинок;
YandexCatalog - "простукивалка" Яндекс.Каталога, используется для временного снятие с публикации недоступных сайтов в Каталоге;
YandexDirect - робот Яндекс.Директа, особым образом интерпретирует robots.txt;
YandexBlogs - робот поиска по блогам, индексирующий посты и комментарии;
YandexNews - робот Яндекс.Новостей;
YandexPagechecker - валидатор микроразметки;
YandexMetrika - робот Яндекс.Метрики;
YandexMarket - робот Яндекс.Маркета;
YandexCalendar - робот Яндекс.Календаря.




Googlebot - обозначение робота гугла
Googlebot-Image - гугловый робот для индексирования картинок


Sitemap - директива для обозначения пути до sitemap.xml
Пример: Sitemap: sitemaps.xml

Остальные директивы:

Host - используется для указания главного зеркала сайта роботу

Disallow: 
Host: www.host1.ru



Crawl-delay - задает таймаут между заказчками страниц для робота.

User-agent: Yandex
Crawl-delay: 2


Clean-param - директива, использующаяся для указания параметров, не влияющих на уникальность страницы

User-agent: Yandex
Disallow:
Clean-param: ref /some_dir/get_book.pl


linux Как архивировать папку

tar cvf folder.tar /path/to/folder - без сжатия

tar cvzf folder.tar.gz /path/to/folder - сжатие gzip

tar cvjf folder.tar.bz2 /path/to/folder - сжатие bzip2



Для получения полной справки используйте tar --help

linux Поиск по тексту из консоли

grep -rn 'search phrase' /directory

-r - флаг рекурсивного поиска
-n - флаг выдачи номера строки
'search phrase' - искомая фраза
/directory - директория в которой ищем

Ещё вместо директории можно перечислить файлы.

Более детальное описание можно найти вот здесь: info grep

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

html тег для скайпа

Обозначение номеров и аккаунтов скайпа в html делается так:


Звонок из скайпа одному пользователю

<a href="skype:user">user</a>

На телефон

<a href="skype:+12345678">+12345678</a>

Сразу нескольким

<a href="skype:skype:user1;user2;user3">conference</a>

Теперь при клике по этим ссылкам будут производится аналогичные действия как и для известного mailto

php mb_substr кракозябры в конце строки

Иногда после использования mb_substr в конце строки появляются непонятны символы, это происходит потому что php не правильно определяет кодировку. Надо её просто указать.

Пример:

mb_substr($text, 0, 10, 'utf-8');

Как в yii CListView убрать summary

В zii.widgets.CListView нет настройки, напрямую влияющей на отображение summary блока, но его можно убрать, немного подправив шаблон template

Пример:


    
    widget('zii.widgets.CListView', array(
            'dataProvider'=>$dataProvider,
            'itemView'=>'_view',
            'template'=>'{items}{pager}' <====== вот эти парни =)
    ));

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

Кидалы на фрилансе

Занялся я как то вёрсткой нафрилансе вместо обычного php программирования и был неприятно удивлен одним товарищем, который сначала просто прикидывался дурачком, а потом оказался кидалой, отказавшись платить мне деньги.

В целом заказ был на верстку и прикручивание этой вёрстки к cms. Когда я заподозрил неладное я предложил произвести оплату после выполнения вёрстки, а уже после неё завершить привязку к cms. Возражений не последовало и я сделал вёрстку. После этого товарищ отказался платить и  несколько раз "случайно" отрубал доступ к фтп. В итоге я отказался заканчивать работу без оплаты, а заказчик "разрешил" удалить всё, что я сделал. В итоге я потерял 4 часа рабочего времени и ничего не получил взамен. Интересно, что этот человек сказал, что если бы он меня хотел кинуть, то придумал бы 1000 способов для этого, но не собирается так поступать(это уже было после того как я понял что к чему).

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

Вёрстку в принципе нельзя никак защитить от копирования, если вы собираетесь давать её проверять. Так что в случае верстки лучше пользоваться всякими сделками без риска и тому подобным.

вторник, 12 марта 2013 г.

Indirect modification of overloaded element of CHttpSession has no effect

Yii не понимает, когда с Yii::app()->session работают как с многомерным массивом.
По этому вместо прямого присваивания

Yii::app()->session[$x][$y] = $z;

Надо использовать промежуточные массивы:

$array = Yii::app()->session[$x];
$array[$y] = $z;
Yii::app()->session[$x] = $array;

четверг, 7 марта 2013 г.

GIT. git-merge: not found


Использую Windows7, TortoiseGit.
При попытке выполнить pull появилась вот такая ошибка:


C:\Program Files\Git/libexec/git-core\git-pull: line 304: exec: git-merge: not found
fatal: 'pull' appears to be a git command, but we were not
able to execute it. Maybe git-pull is broken?

git did not exit cleanly (exit code 128) (17472 ms @ 07.03.2013 14:46:55)



Оказалось, надо в папке C:\Program Files\Git\bin
git.exe скопировать в git-merge.exe

Кстати там таким же образом уже обнаружились git-receive-pack.exe и git-upload-archive.exe.
Видимо в линуксе на месте этих экзешников ссылки.

пятница, 15 февраля 2013 г.

URL без указания протокола

Если в ссылке не указывать протокол, а вставить // вместо http:// то все будет работать нормально.
Например эти две ссылки будут работать одинаково

//google.com
http://google.com

Удобно, что не надо думать о протоколе, да и просто так короче.

Бибилитеки javascript размещённые на гугле

Бибилиотеки, которые можно подключать напрямую с гугла описаны здесь: https://developers.google.com/speed/libraries/devguide?hl=ru

Самую последюю версию jquery можно брать отсюда:
http://code.jquery.com/jquery-latest.min.js

Пример:

<script src="http://code.jquery.com/jquery-latest.min.js" type="text/javascript"></script>

суббота, 2 февраля 2013 г.

Установка APC для php5.3 под windows

http://downloads.php.net/pierre/

  • качаем php_apc-3.1.10-5.3-vc9-x86.zip (в моем случае. выбирать надо по компилятору и архитектуре)
  • распаковывем и копируем в php/ext/
  • пишем в php.ini extension=php_apc.dll 

Теперь перезапускаем апач и проверяем через phpinfo()

четверг, 24 января 2013 г.

jquery javascript Закрытие по клику вне элемента

Для закрытия по клику вне элемента надо повесить обработчик на $(document)

.menu_item_container - элемент, клик вне которого перехватываем

$(document).on('click.mWindow', function(e){
  if ($(e.target).closest('.menu_item_container').length == 0) {
   $('.menu_item_container').hide(); // тут вставляем любой наш обработчик
  }
});

суббота, 19 января 2013 г.

json на php и javacript jquery

Самый простой способ отсылки структурированных данных с php скрипта на javascript это json. Сначала надо закодировать данные на стороне сервера:

$data = array('param1' => $param1, 'param2' => $param2);
echo json_encode($data);

 
Потом принять данные на стороне клиента:
С помощью ajaxForm например

$('.get_paid_form').ajaxForm({
   success: function(response) {

    var json = $.parseJSON(response);

    alert('param1 = ' + json.param1);
    alert('param2 = ' + json.param2);


  }
});

среда, 16 января 2013 г.

Unable to execute UPDATE statement. [wrapped: SQLSTATE[HY000]: General error: 1030 Got error -1 from storage engine]

После восстановления базы данных забыл поменять
innodb_force_recovery = 1
на
innodb_force_recovery = 0
Из за чего база данных фактически несколько дней работала только в режиме чтения.

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

php. Доступ к сессии джумлы из своего скрипта

нашел на http://www.subclosure.com

В начале скрипта надо прописать

define('_JEXEC', 1);
define('DS', DIRECTORY_SEPARATOR);
define('JPATH_BASE', dirname(__FILE__));

require_once(JPATH_BASE .DS.'includes'.DS.'defines.php');
require_once(JPATH_BASE .DS.'includes'.DS.'framework.php');

$mainframe =&JFactory::getApplication('site');
$mainframe->initialise();

$session =&JFactory::getSession();
$user = $session->get('user');


В JPATH_BASE указываем путь до корневой директории джумлы

суббота, 12 января 2013 г.

Поиск файлов в linux консоли

Поиск файлов по содержимому:

grep "текст" ./* -r
 
Поиск файлов по имени:

find / -name 'file_name'
 
Поиск файлов по имени и только текстовые:

find / -type f -name 'file_name'

четверг, 10 января 2013 г.

Вставка кнопки paypal "buy now" с изменяемыми параметрами

Вставка кнопки paypal "buy now" с изменяемыми параметрами не сильно отличается от вставки обычной кнопки. Надо зайти "Merchant Services", потом выбрать "Create payment buttons for your website" и в Common payment buttons: выбрать "buy now".

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

По умолчанию paypal защищает кнопку от модификации, по этому на втором шаге надо убрать галочку "Save button at PayPal".

После того как будет сгенерирован код кнопки и показана форма с абракадаброй в параметрах надо нажать "Remove code protection" в верхнм правом углу формы. После этого параметры будут декодированы и вы сможете их изменять по своему усмотрению.

mysql. start: Job failed to start

Перестал  запускаться mysql на сервере, после

/etc/init.d/mysql restart

Ругался, что его надо запускать как сервис. После попытки запустить его как сервис командой

service mysql restart

Просто сказал, что

start: Job failed to start

Тогда я добавил в /etc/mysql/my.cnf вывод логов:

[mysqld_safe]
log-error=/var/log/mysql/error.log

 
[mysqld]
log-error=/var/log/mysql/error.log


После очередной попытки перезагрузить mysql в логах появились драгоценные записи:

InnoDB: Database page corruption on disk or a failed

В итоге решилось все добавлением в /etc/mysql/my.cnf строчки

[mysqld]
innodb_force_recovery = 1


После этого mysql успешно поднялся.

После восстановления базы параметр надо поставить обратно в 0, иначе будет невозможно записывать изменения в таблицы.

воскресенье, 6 января 2013 г.

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

Часто вместо создания сайтов приходится заниматься поддержкой. Исправлением чего то неработающего, или доработкой старого. Почему я не люблю этим заниматься? Да потому что от хороших сайтов разработчики не отказываются и на поддержку приходят сайты преимущественно имеющие существенные косяки в коде, или архитектуре. Я себя чувствую человеком, которому показывают на какашку и говорят: "У нас была раньше пирамидка, но почему-то сломалась, не могли бы вы починить? Сделать то надо совсем не много." И приходится, либо лепить из этой какашки пирамидку, пока она снова не развалится и брать большие деньги (не думаю, что найдутся люди, которые любят лепить из какашек пирамидки), либо отказываться. При чём сопровождается всё объяснениями заказчику, почему так всё дорого и медленно. И заказчик то, как правило виноват обычно только в том, что ему попался не квалифицированный программист и я с пониманием отношусь к отсутствию желания платить два раза за одно и тоже.