Показаны сообщения с ярлыком Быдлокод. Показать все сообщения
Показаны сообщения с ярлыком Быдлокод. Показать все сообщения

среда, 6 апреля 2016 г.

Режим mysql 5.6/5.7, после обновления с 5.5 (sql-mode)

На сервере стоял mysql 5.5 (Debian 8), но в этой версии есть ограничение на дефолтные значения TIMESTAMP, оно было снято в mysql 5.6.5

В 5.5 выдавало ошибку:
Incorrect table definition; there can be only one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause

А вот выдержка из документации
Changes in MySQL 5.6.5 (2012-04-10, Milestone 8)

Previously, at most one TIMESTAMP column per table could be automatically initialized or updated to the current date and time. This restriction has been lifted. Any TIMESTAMP column definition can have any combination of DEFAULT CURRENT_TIMESTAMP and ON UPDATE CURRENT_TIMESTAMP clauses. In addition, these clauses now can be used with DATETIME column definitions. For more information, see Automatic Initialization and Updating for TIMESTAMP and DATETIME.

 Если уж обновлять mysql, то сразу до 5.7, но на хостинге много стареньких сайтиков, перепиливать их все не хотелось, к тому же проблему нужно было решить прямо сейчас, после обновления до 5.6/5.7, mysql более строго относится к вводимым данным, например нельзя добавить запись без указания значения того поля, где не задано значение по умолчанию:
Field XXX doesn't have a default value

А еще нельзя передать пустую строку в поля, где тип float/integer:
Incorrect integer value ” for column XXX at row M



Для того, чтобы mysql молча съедал все эти запросы и корректно работали сайты - нужно прописать в my.ini в секцию [mysqld]:
sql-mode=""


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

среда, 12 февраля 2014 г.

PHPExel default codepage кодировка по умолчанию

При чтении файла отображались иероглифы, оказалось что файл экселя был кривым и кодировка в заголовке не была указана, по умолчанию PHPExel включает кодировку cp1252, тогда как в православной виндовой кириллице cp1251.

Открываем файл Reader/Exel5.php
и находим по слову 1252
Исправляем параметр на CP1251 и вуаля, бракованый XLS (генерируемый непонятной складской программой у поставщиков).


Далее я столкнулся еще с одной проблемой - когда определенная кодировка оказывается неподдерживаемой, хотя на деле cp1251.

Файл PHPExcel/Shared/CodePage.php, примерно после 89 строки нужно добавить выделенную красным цветом строку:

            case 32769:    throw new Exception('Code page 32769 not supported.');
                                            break;    //    ANSI Latin I (BIFF2-BIFF3)
            case 65001:    return 'UTF-8';        break;    //    Unicode (UTF-8)
            default: return 'CP1251';
        }

        throw new Exception('Unknown codepage: ' . $codePage);

четверг, 15 августа 2013 г.

Коробочный мини-сервер, оптимизация Debian (initrd rc инициализация)

Началось всё с того, что я решил выпилить из системы всё лишние и так сказать немного сделать ее ближе ко всяким openwrt, у меня есть nettop на атоме, который не блещет производительностью и я на нем решил сделать специфическую систему, которая будет работать только в качестве веб-сервера.



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

План таков:

1. Ставим Debian 7 в минимальной конфигурации без всяких там иксов
2. Если не установлен, то ставим initramfs-tools
3. По желанию можно поставить утилитки hddtemp, smartmontool, lm-sensors, hdparm, только я их все выпилил из сервисов.
4. Выпиливаем "лишние" сервисы из автозапуска
5. Выпиливаем лишние модули из initrd
6. Убиваем лишние операции в инициализации на стадии init.rd

Теперь немного про инициализацию, она состоит из нескольких этапов

1. Загружается GRUB
2. Грузится ядро
3. Загружается initrd, в котором стартовый набор модулей (в дебиане все модули там лежат), потом на этой же стадии происходит подгрузка всех модулей, монтирование дисков, запуск udev и определение оборудования.
4. Переход на уровень rcS и выполнение скриптов из /etc/rcS.d
5. Загружается всё, что находится в /etc/rc2.d/ там у нас всякие веб-сервера, ssh демоны и т.д.
6. Выводится приглашение и предложение залогиниться!


Облегчение автозапуска
автозапуск/завершение/перезагрузка прописаны в /etc/rc*.d/ директориях в виде символических ссылок (ярлыков) на папку /etc/init.d/ если символическая ссылка начинается на S то выполняется запуск, если K то завершение.
Выключение это /etc/rc0.d/, включение /etc/rc2.d/, перезагрузка /etc/rc6.d/.

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

Сделайте резеврную копию /etc, а то вдруг что то удалите лишнее или напортачите
tar -zcf etc.tgz /etc

Главный контролирующий скрипт это /etc/inittab в нем запускаются стадии, в нем же и запускаются терминалы (getty), если вы обладаете небольшими навыками в BASH, то можете перепилить все скрипты инициализации на свой лад, всё зависит от вас.


Займемся initrd

Но на этапе rc2 выполняется порой лишь самая малая часть действий, например у меня стартуется crontab, nginx, mysql, postfix - это занимает меньше времени чем первый этап, на котором происходит подготовка системы, монтирование дисков, опрос железа и многое другое, но если мы поставили задачу сделать систему для неттопа, конфигурация которого не будет изменяться, а весь udev можно заменить на несколько строчек modprobe, еще в дебиане на всякий случай в initrd помещаются абсолютно все модули из системы.

Прежде чем приступать к манипуляциям.
После любого изменения конфигурации initrd нужно обновлять файл образа командой
update-initramfs -u

При любом критичном эксперименте желательно иметь резервную копию образа, создать его можно командой
cp /boot/initrd.img-3.2.0-4-amd64 /boot/initrd.img

и при невозможности запуститься - можно в GRUP нажать кнопку e  и отредактировать путь до initrd и нажав ctrl+x

Так же сделайте на всякий случай резервную копию /etc и /usr/share/initramfs-tools/ мы там можем удалить много лишнего, а достать это будет негде.

1. Облегчение initrd
сперва получим список всех загруженных сейчас модулей (которые нужны) и закинем этот список в конфиг
lsmod | tail -n +2 | sort | awk '{print $1;}' > /etc/initramfs-tools/modules

А потом откроем файлик /etc/initramfs-tools/initramfs.conf
и параметр
MODULES=most
приведем к виду
MODULES=list

Смысл этой модификации в том, что в initrd будут запаковываться только модули из списка /etc/initramfs-tools/modules

2. Init-скрипты
Все скрипты находятся в директории /usr/share/initramfs-tools/
В этой директории есть основной контролирующий скрипт init, есть директория scripts в которой скрипты инициализации, есть еще всякие хуки и др.

Спасибо за информацию этому блогу http://www.ylsoftware.com/news/469 там же вы можете прочитать некоторые другие подробности про initrd.

Я решил выпилить всё лишнее вплоть до udev из своего сервера "типа коробочный роутер".

Без udev не работают uuid дисков и поэтому нужно сперва в файле /etc/default/grub раскомментировать строку:
GRUB_DISABLE_LINUX_UUID=true
далее выполнить команду update-grub2

а далее модифицировать /etc/fstab изменив там все UUID на названия дисков типа /dev/sda1 /dev/sda2 ....

после этого наша система готова работать без udev, но тут нужно обратить внимание что без udev подгрузку модулей вы должны делать сами командой modprobe, определить что вам нужно грузить а что нет можно по выводу lsmod с еще включенным udev

Создадим скрипт загрузки модулей
echo '#!/bin/sh' > /usr/share/initramfs-tools/scripts/modprobe

Добавим в него все загруженные на данный момент модули
lsmod | tail -n +2 | sort | awk '{print "modprobe "$1;}'>> /usr/share/initramfs-tools/scripts/modprobe

И сделаем этот скрипт исполняемым
chmod +x /usr/share/initramfs-tools/scripts/modprobe

А теперь самое интересное, я решил снести всё из  /usr/share/initramfs-tools/init
и вписать туда следующий код
#!/bin/sh
mkdir -p /sys /proc /tmp /var/lock
mount -t sysfs -o nodev,noexec,nosuid sysfs /sys
mount -t proc -o nodev,noexec,nosuid proc /proc
mount -t devtmpfs -o size=10M,mode=0755 none /dev
mkdir /dev/pts
mount -t devpts -o noexec,nosuid,gid=5,mode=0620 devpts /dev/pts || true
mount -t tmpfs -o "nosuid,size=20%,mode=0755" tmpfs /run
mkdir -m 0755 /run/initramfs
export ROOT=



# Parse command line options
for x in $(cat /proc/cmdline); do
        case $x in
        root=*)
                ROOT=${x#root=}
                        ;;
        esac
done

./scripts/modprobe


mount $ROOT /root
mount -n -o move /run /root/run
mount -n -o move /sys /root/sys
mount -n -o move /proc /root/proc
mount -n -o move /dev /root/dev

exec switch_root /root /sbin/init "$@" </root/dev/console >/root/dev/console 




После этого можно выпилить udev из автозапуска, удалив из /etc/rcS.d/ симлинк на udev

Теперь обновляем initrd и перезагружаемся
update-initramfs -u && reboot

После данных модификаций у нас система работает без udev и всё оборудование работает, а так как у нас "вещь в себе", то больше ни чего не нужно, сервак работает, сервисы запущены, лишние мы повыпиливали и еще повыпиливаем и еще ядро обязательно пересоберем и пропатчим всяко-разно.

Далее нам предстоит оптимизировать /etc/rcS.d/ там у нас есть всякие монтирования nfs сетевых хранилищ и много чего другого.

Apache и PHP нам тоже придется немного оптимизировать выпилив лишние модули, если интересны дальнейшие опыты в данной теме - пишите комментарии и я продолжу, а пока я тестирую полученную систему на продакшн-системе








вторник, 13 августа 2013 г.

Функция парсинга URL и разбиение

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

Ловите функцию

function parse_address($str)
{
    preg_match("!((http|ftp|https){0,1}://([^/]+))*(/.*)!sim",$str,$a);
    return array('url'=>$a[0],'protocol'=>$a[2],'domain'=>$a[3],'query'=>$a[4]);
}

Данная функция возвращает протокол из юрл, доменное имя и запрос.


Применение:
$u="http://domain.ru/pictures/1.jpg";
$z=parse_address($u);
echo $z['protocol']; //выведет http
echo $z['domain']; //выведет domain.ru
echo $z['query'];  //выведет /pictures/1.jpg


Данная функция применима к относительным и абсолютным URL

Напиcал эту функцию, пока ехал в маршрутке)))

суббота, 16 марта 2013 г.

Загрузка файлов кнопкой и глюк в Opera

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

При клике по кнопке срабатывает клик по форме загрузки файла (которая скрыта).

При выборе файла в диалоге загрузки происходит выполнение JavaScript функции.

Но если вы сделаете style="display:none" то в нашей любимой опере это не будет работать, для оперы скрытие объекта без его исключения из DOM нужно делать следующим CSS хаком:

visibility:hidden;position:absolute;top:0;

В общем это решение будет выглядеть так: 

<form method="POST" enctype="multipart/form-data" action="/index.php" id="form1">

<button type="button" onclick="$(\'input#fff').click();">Загрузить</button>

<input id="fff" type="file" name="file_inp

style="visibility:hidden;position:absolute;top:0;" onchange="$('#form1').submit();">

</form>

Для работы метода, требуется библиотека JQuery

 
В Opera эта ошибка выглядит так:
click bubbling
Event handler
(Missing source file)

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

WebAsyst Shop Script проверка обязательных полей

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

Материал актуален для версии 305

В общем задачи такие:
  • В корзине в адресе убрать всё лишнее (страна, область, имя ...)
  • Изменить порядок полей
Чтобы подправить форму адреса и информации о покупателе, нужно править
published/SC/html/scripts/templates/frontend/checkout.your_info.html
published/SC/html/scripts/templates/frontend/address_form.html


После этого система будет ругаться на незаполненные поля, которых нет, проверка полей адреса осуществляется в файле
 published/SC/html/scripts/classes/class.address.php 
в функции checkInfo()


Если нужно например добавлять водянные знаки (watermark) к картинкам при загрузке, то вы можете внедриться в файл
published/SC/html/scripts/modules/products/_methods/b_product_settings.php

там есть функция upload_picture($action_source = ACTCTRL_AJAX) которая отвечает за загрузки и подготовку картинок для товара.

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

xls2csv (catdoc) - транслит при конвертации из Apache

Есть у меня импортер, который запускается из кронтаба, xls файл скачивается wget-ом и перегоняется при помощи xls2csv в текст, а потом парсится.

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

LANG=ru_RU.UTF-8

А потом запускать конвертер catdoc.



P.S. Используйте мои статьи, но не забывайте оставлять ссылку на первоисточник.

пятница, 7 декабря 2012 г.

PHPExel Wrap + Merge + Auto Height

В  Exel есть такая трабла, для объединенных (merge) ячеек при установке переноса по словам, высота (height) не устанавливается автоматически, но ее можно рассчитать при помощи примерно такого костыля:


$line_height = 12; //высота одной строки текста (one line height)
$in_line = 50; // примерное количество символов для одной строки (chars in one line)

$h = ceil(strlen(utf8_decode($text))/$in_line)*$line_height;

$aSheet->getRowDimension($str_number)->setRowHeight($h);

вторник, 17 июля 2012 г.

WebAsyst Shop Script сравнение продуктов из разных категорий.

1. Открываем файл 
published/SC/html/scripts/modules/product/_methods/comparison_products.php
приводим начало файла к такому виду (бордовым цветом помечены те строки, которые добавил, остальное вставлено для того, чтобы вы могли сориентироваться куда вставлять)

<?php
$Register = &Register::getInstance();
/*@var $Register Register*/
$PostVars = $Register->get(VAR_POST);
$smarty = &$Register->get(VAR_SMARTY);
/*@var $smarty Smarty*/


/*Add by Pavel Belyaev*/
if (isset($PostVars["comparison_products"]))
{
    if (isset($_SESSION["comparison_products"])) $_SESSION["comparison_products"].=" ".trim($PostVars["comparison_products"]);
    else $_SESSION["comparison_products"]=trim($PostVars["comparison_products"]);
}
else
{    
    $_SESSION["comparison_products"] = "";
    header ("location:/");
}

$productIDArray = array_unique(explode( " ", $_SESSION["comparison_products"]));
$_SESSION["comparison_products"] = implode (" ", $productIDArray);
if (count($productIDArray)>8) $_SESSION["comparison_products"] = "";
/*end add*/

$showProductCategoryPath = true;
$products = array();

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

2. Открываем файл 
published/SC/html/scripts/templates/frontend/comparison_products.html

В конец дописываем


<center>
    <form metod="post" action="/category/1/compare/">
        <input type="submit" value="Очистить список сравнения">
    </form>
</center>





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

четверг, 12 июля 2012 г.

tinyMCE и Jquery Form Plugin

Суть проблемы такова: при отправке формы при помощи ajax плагина jquery поля, которые с tinymce редактором, отправляются устаревшие.

Для того, чтобы разобраться в проблеме, посмотрим как устроен tinymce, он скрывает (не путать с удалением) нужные <textarea> и на их месте создает свой блок с текстовым редактором. Улавливая событие отправки формы, tinymce вставляет из своих блоков текст в блок <textarea> и отправляет форму.

А плагин JqueryForm переопределяет событие отправки на себя, тем самым tinymce не успевает вписать изменения и форма отправляется со старыми данными в textarea, решение вопроса такое:

 $(document).ready(function()
{
       $('#ajax_form').submit(function() {     
            tinyMCE.triggerSave();
            $(this).ajaxSubmit();
            return false;
       })
});




P.S. (Как всегда не всё по плану)
Я не сразу нагуглил эту инфу и решил написать свой аналог tinyMCE.triggerSave(), может кому то пригодится в целях изучения jquery


function text_save_tiny (obj)
{

  $(obj).find('textarea').each( 
  function(){
  //если у textarea нет id, делаем id=name
  if (!$(this).attr('id')) $(this).attr('id',$(this).attr('name'));                $(this).val(tinyMCE.get($(this).attr('id')).getContent());
});

}

четверг, 26 апреля 2012 г.

Масштабирование картинок (пропорционально) средствами JavaScript

В общем ситуация такая - есть всякие разные картинки, и вам их нужно вписать в блоки
фиксированного размера. Как быть? Если задать ширину и высоту в тегах <img>, то пропорцию не сохраним, если прописать только ширину или только высоту, то если ширина больше высоты или наоборот, то картинка может вылезти за пределы блока, выход может и быдлокодинговый, но работает.

function auto_size (img,max_width,max_height)
{
if (img.width>maxwidth) 
{
width = img.width; height = img.height;
img.width = maxwidth;
img.height = (maxwidth*height)/width;
}
if (img.height>maxheight) 
{
width = img.width; height = img.height;
img.height = maxheight;
img.width = (maxheight*width)/height;
}
}


У тега img пишем <img onload="javascript:autosize(this,250,500)" src="...." >
Где 250 это максимальная ширина картинки, а 500 - максимальная высота, если картинка вылезет по какой то из сторон за пределы блока, то она пропорционально уменьшится.


Что делать, если лень писать onload для каждой картинки?


На помощь приходит Jquery и вот такая функция


$(window).load(function() {
$('.class img').each(function(){
 auto_size ($(this)[0],195,200);
});
});

Для всех картинок, вложенных в класс будет применена эта функция


P.S. Нужно еще придумать механизм, при котором эти картинки сперва будут невидимыми, а потом масштабироваться и отображаться, т.к. картинки отображаются до того как страница загрузится и отображаются не совсем красиво.