четверг, 19 декабря 2013 г.

вторник, 10 декабря 2013 г.

Magento: add to email template custom block

It's can by:
{{block type='core/template' area='frontend' template='email/my_email_block.phtml' order=$order shipment=$shipment }}
Then in the template file email/my_email_block.phtml
-> You can access the Shipment object by using $this->getShipment().
-> You can access the Order object by using $this->getOrder().

понедельник, 18 ноября 2013 г.

htaccess. URL rewrite. 301 redirect. Куча потраченного времени.

Прежде чем начать следует заметить, что браузер кэширует 301 редирект, после которого переход на новую страницу будет проходить без участия apache. Для этого можно установить дополнения к браузеру, которые чистят кэш (например close and forget). Также для тестирования понадобится - чтение HTTP заголовков, в которых будет четко написано: происходил ли редирект, откуда, куда (add-ons "Live HTTP Headers"). В случае неудачи, не забываем смотерть в логи апача.
Также перед началом работы следует убедиться, что mod_rewrite-enable. И принудительно включить его еще раз.
sudo a2enmod rewrite;
В локальный хост следует не забыть установить  AllowOverride All . И только потом:
sudo service apache2 restart
 Затем пару пробничков. В .htaccess файле:

RewriteEngine   on
RewriteRule     ^(.+)\.htm$  http://%{HTTP_HOST} [R=permanent]
 Этот пример, делает редирект на index.html, когда пользователь не дописал расширение html до конца (забыв про последнюю букву).
Константа %{HTTP_HOST} - возвращает главный адрес сайта. Перед ней желательно ставить http:// , а то будет происходить путаница и возвращаемый адрес, будет считаться путем к файлу.

Следует заметить, что в RewriteRule , стандартно обрабатываются только URI и символ начала строки "^", будет означать начало не всего адреса URL(www.google.com/map/haha), а только начало URI(/map/haha). Для полного обрабатывания, следует явно указывать http, www.
 Следующий пример, будет прит недописанных htm, будет дописывать букву "l":
     RewriteEngine   on
     RewriteRule     ^(.+)\.htm$  $1.html [R=permanent]
где $1 - переменная содержащая результат с первой группы(первых скобочек в первом параметре  RewriteRule .
Также встречаются %1 переменные ,которые указыват первую группу в RewriteCond. (Но это нужно более точно уточнить)

вторник, 12 ноября 2013 г.

Remove child block by layout update or programmatically

By using layout update:
<reference name="left">
     <reference name="enterprisesearch.leftnav">
           <action method="unsetChild"><alias>category_filter</alias></action>
     </reference>
</reference>
Programmatically:
$this->getLayout()->getBlock('enterprisesearch.leftnav')->unsetChild('category_filter');

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

Overriding a Magento Core Controller or a Controller Action

<!– For whole controller –>
<rewrite>
<yournamespace_yourmodule_sales_order >
<from><![CDATA[#^/admin/sales_order/ #]]></from>
<to>/ yourmodule /sales_order/ </to>
</ yournamespace_yourmodule_sales_order >
</rewrite>

<!– For a action in a controller –>
<rewrite>
< yournamespace_yourmodule_sales_order_pdfdocs>
<from><![CDATA[#^/admin/sales_order/pdfdocs#]]></from>
<to>/ yourmodule /sales_order/pdfdocs</to>
</ yournamespace_yourmodule_sales_order_pdfdocs >
</rewrite>


<!--Another Way-->

In your Local/Core/etc/config.xml, define your controller within the router to be overridden.
<config>
    ...
    <frontend> // Use <admin> for backend routers
        <routers>
            <core> // <-- this is the router name
                <args>
                    <modules>
                        <local_core before="Mage_Core">Local_Core</local_core>
                    </modules>
                </args>
            </core>
        </routers>
    </frontend>
    ...
</config>
Magento will now check Local/Core/controllers before Mage/Core/controllers for URL paths starting with core (the router name). Your PHP class above is already correct.
This is only gently hinted at about halfway down this page where it says:
Since Magento 1.3 you can simply add your module to the frontend router. Rewrites are not neccessary any more.

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

Magento. Заполнение home page.

Написать завтра.

Magento. Добавление статического блока.

Если нужно добавить статический блок  для этого нужно в update/install script или где нибудь еще написать вот это:
Mage::getModel('cms/block')
    ->load('footer_nav_menu')
    ->delete()
;//если такой блок уже существует удаляем его из бд.
$content = <<<HTML
 <ul>
      <li>
        Haha
        <ul>
          <li><a href="#">Notre mission</a></li>
          <li><a href="#">Nos boutiques</a></li>
        </ul>
      </li>
      <li>
         SERVICES
        <ul>
          <li><a href="#">Programme de fidélité</a></li>
          <li><a href="#">Guides conseils</a></li>
        </ul>
      </li>
      <li>
        QUESTIONS
        <ul>
          <li><a href="#">FAQ</a></li>
        </ul>
      </li>
    </ul>
HTML;
Mage::getModel('cms/block')->setData(array(
    'title'      => 'footer_nav_menu',
    'identifier' => 'footer_nav_menu',
    'content'    => $content,
    'is_active'  => 1,
    'stores'     => array(Mage_Core_Model_App::ADMIN_STORE_ID)
))
    ->save();

Переменная $content говорит сама за себя, что нужно с ней делать. Понятное дело, что не необходимости данный скрипт выполнять каждый раз при запуске магенты.
Следующим шагом будет создание блока в layout.
Найдя блок в котором мы собираемся отобразить блок, пишем в layout'e следующий код:
                <block type="cms/block" name="footer_nav_menu">
                    <action method="setBlockId">
                        <block_id>footer_nav_menu</block_id>
                    </action>
                </block>
Далее запомнив родительский блок нашего ноовго блока, переходим в его phtml и выводим его содержимое:
  <nav id="footer-links">
    <?php echo $this->getChildHtml('footer_nav_menu') ?>
  </nav>
Вот и все!

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

Правило 30 секунд.

Нашел классный комент:

Правило 30 секунд заключается в том, что если посторонний программист за 30 секунд не может разобраться в том, что делает метод, то его нужно переписывать. Если метод длинный, то разбить на несколько более мелких с говорящими именами. Если метод короткий, то значит что-то не так с naming’ом.
Прыгать по методам интересно будет, когда их нужно будет править, или когда интересны будут детали реализации. А для того, чтобы понять, что делает код в общем, достаточно хороших имен и короткого метода.
Кстати, у тебя этот прием использован во втором примере: WritePageNumberOnBitmap ты вынес в отдельную функцию, хотя вызывается она всего в одном месте. Точно так же стоит поступать и с остальными, т.е. получится что-то вроде (за синтаксис не пинать, ибо на Delphi уже больше 10 лет не писал).

Mail. Easy Send and Get Mails from local web-server.

Если нужно посмотреть отправленые emails с локального сервера и очень не хочеться устанавливать всякие sendmail'ы, которые, кстати нужно правильно настроить. Есть очень простой способ. Во всех файлах php.ini (в ubuntu их почему-то несколько)  и добавить следующую строчку:
sendmail_path = "cat >> /directories/to/mail/file/php.mail.log"
Потом создать указанные директории, сделать  для них нужные права доступа. И при отправке email's , например, из php скрипта, все будет ДОзаписываться в файл php.mail.log

Magento EAV in Database. Способ поиска ошибок, спомощью запросов к бд.

       Структура очень проста. Есть название атрибута, у которого есть собственный id. Узнать его можно в таблице eav_attribute. Соответственно смотрим на заголовки полей и ориентируемся. Поле entity_type_id указывает к чему относится атрибут, например к customer'ам = 1 или products = 4 (Тут могу ошибится). При создании атрибута указывается его тип: int, text, varchar, datatime и другие.. его тоже необходимо знать.
     Затем, зная всю ту информацию об искомом атрибуте, которая была описана выше, начинаем сам поиск. Если entity_type_id=1, то имена таблиц которые будут хранить значения атрибутов, будут начинаться с customer_entity (для 4 это catalog_category_entity). Далее зная тип атрибута находишь таблицу название которой содержит соответсвующий тип. А затем зная attribut_id находиш строку и смотриш значение. Так же следует учитывать, что это EAV,  и один на один attribute id будет несколько значений. Там нужно ориентироваться по назвнием полей.

     Все это (это запись и все остальные) я пишу для себя и языком понятным только мне для того, что бы в первую очередь, быстро вспомнить, если что-то забыл. А также для того, чтобы лучше запомнить новую информацию.

    Узнал о новом способе поиска ошибок, неполадок (раньше не приходилось пользоваться и не хотелось сильно углублятся в дебри классов). Каждая модель генерирует MySQL запрос в базу данных.  Например в модели order'ов, есть методы getSelect() и assemble(), которые вернут полный Select запрос. Потом копируя в phpmyadmin пробуешь его с разными значениями. Вычисляешь каких значений не хватает, или наооборот какие значения лишние и делаешь  соответсвующий вывод.
     Как я писал ранее, я уже все забыл про то, как magenta взаимодействует с БД. И поэтому нужно все заново изучить, потому что описанные выше методы не у всех моледей есть (а может я спешил и не там попробовал). В общем все нужно изучить заново.

Magento EAV Attribute for Customer

      Недавно столкнулся с проблемой. Был создан атрибут для customer'a. В него записывалось значение, он сохранялся в бд (видно через phpmyadmin), но при загрузке у него было нулевое значение. Самое интересное, что другие атрибуты, котрые были добавлены до меня, тоже странно работали. Но, все таки работали.
      Самое первое, как я понял нужно делать, это обновлять кэш (в т.ч. удалять папку cache), а также делать обновление index'сов. 
      Решение проблемы, было очень простым. 
      Сначала нужно взять коллекцию пользователей:
protected function _getCustomers()
    {
        $collection = Mage::getResourceModel('customer/customer_collection');
        $collection
            ->addAttributeToSelect('loyalty_reward_buy_start_date')
            ->addAttributeToSelect('loyalty_reward_buy_end_date')
            ->addAttributeToSelect('loyalty_reward_buy_points')
            ->addAttributeToSelect('loyalty_reward_total_points')
            ->addAttributeToSelect('loyalty_reward_buy_level')
            ->addAttributeToSelect('loyalty_reward_all_coupons')
            ->addAttributeToSelect('preferred_store_id')
        ;
        $collection->getSelect()->where('is_active = 1');
        return $collection;
    }
И, как видно из кода, нужно было добавить имя атрибута, в запрос используя метод addAttributeToSelect. Потом, из коллекции, выбираешь нужного customer'a и в нем благополучно будут загружены указаные атрибуты. Которые потом изменяешь и благополучно сохраняешь спомощью save(). 
Из этой проблемы я также выяснил, что плохо изучил взаимодействие magento с БД.

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

curl and tor

Установка тора
apt-get install tor
Для использования курла через тор:
<?php
$url = "http://2ip.ru/";
$proxy = "127.0.0.1:9050";

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_PROXY, $proxy);
curl_setopt($ch, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5);
$result = curl_exec($ch);
curl_close($ch);
echo $result;
?>
 
 
Other variant: 
<?php
$url = "ya.ru";

$paths = array('/usr/bin/curl',
               '/usr/local/bin/curl',
               '/bin/curl',
               '/usr/sbin/curl',
               '/usr/local/sbin/curl',
               '/sbin/curl',
               'c:/windows/curl.exe');
foreach( $paths as $c ){
 if(@file_exists($c)){ $curl = $c; break;  }
}
if(!isset($curl)) die("NO cURL!");

system("$curl --url \"$url\" --socks4a 127.0.0.1:9050");
?>
Тор находится в:
  • Protocol: socks5
  • Host: localhost
  • Port: 9050

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

PHP опреатор ===

Продолжая эту тему. На php.net наткнулся на оператор "===". Жаль, что я совершенно забыл про него:


$a === $b
Тождественно равно TRUE если $a равно $b и имеет тот же тип.
Следует запомнить различие с:
$a == $b Равно TRUE если $a равно $b после преобразования типов.
Ведь при преобразовании типов false =0.

Так же другие операторы сравнения:
$a == $bРавноTRUE если $a равно $b после преобразования типов.
$a===$bТождественно равноTRUE если $a равно $b и имеет тот же тип.
$a != $bНе равноTRUE если $a не равно $b после преобразования типов.
$a <> $bНе равноTRUE если $a не равно $b после преобразования типов.
$a!== $bТождественно не равноTRUE если $a не равно $b или они разных типов.
$a < $bМеньшеTRUE если $a строго меньше $b.
$a > $bБольшеTRUE если $a строго больше $b.
$a <= $bМеньше или равноTRUE если $a меньше или равно $b.
$a >= $bБольше или равноTRUE если $a больше или равно $b.

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

PHP: русские символы и strtolower

Однажды заметил, что strtolower русские символы не приводит к нижнему регистру. Погуглив, обнаружил, что желательно дополнительно использовать функцию setlocale и устанавливать CP1251 кодировку.
После использования этой функции ничего не поменялось. Оказывается нужной кодировки может не быть в ОС. У меня Ubuntu. Установил нужную кодировку, в итоге опять не работает. В общем перепробовал много разных вариантов, существует довольно простой и главное рабочий:
$word=mb_strtolower($word,mb_detect_encoding($word));
Теперь все заработало!

PHP: отличие 0 от false

Как известно, в PHP: 0, false, NULL - являются одним и тем-же. Но довольно часто необходимо четко различать 0 от false. Например в таком случае. Существует строка str и существует - str2. Необходимо узнать: является ли строка str2 подстрокой str1. Это можно сделать с помощью функции strpos.

$str="Сергей" ;
          $str2="Сер";
          $pos=strpos($str,$str2);

Которая может вернуть позицию вхождения подстроки, либо может вернуть false - если подстрока в строке вообще не существует. Но тут также есть загвоздка. А что, если позиция вхождения подстроки будет равна 0?
Далее следует проверка. Неопытный программист, коим являюсь я сделает так:
if($pos!=false){
           //делаем то и то..
          }

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

Избавление от этой проблемы приходит с использованием функции is_bool($a), которая возвращает true в случае если ТИП $a является boolean. Поэтому вместо предыдущего if пишем следующее:
if( ! is_bool($pos)){
          //что-то делаем..
          }


Вообще в PHP четко следует знать и следить за состоянием переменных и элементов массивов. И использовать следующие ряд функций: is_null(), empty(), isset().

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

Раз и навсегда. Передача массива char в функцию. C C++

#include <stdio.h>
#include <string.h>

void mm(int *a){
*a+=15;
}

void writ(char *a){
    printf("\n %s \n",a);
}

char * tt(char *a){
    strcat(a,"bb");
    return a;
}

    int main()
    {
    int a=10;
    mm(&a);
    printf("%i",a);
    char b[]={"hahahhaa\0"};
    writ(b);
    printf("%s",tt(b));
    printf("\n %s \n",b);   
    return 0;
    }
    

воскресенье, 24 марта 2013 г.

While(1) ??????

Когда используешь While(1) (gcc ubuntu), оказывается в командной строке в теле этого бесконечного цикла, автоматически будет работать ввод символов, а ввывод символов работать не будет. Вполне возможно, что их как-то и можно выводить, но мне это уже не интересно..
Хотя такое происходит не во всех случаях... почему-то именно в программировании TCP. Это очень глупо с моей стороны -плохо знаю С.

V-USB. AVR. LibUSB. Ubuntu

Откомпилировал я прогу hidtool, которая идет в примерах библиотеки V-USB, и столкнулся с такой ошибкой (в виндовсе такого нет):

Error sending message: error sending control message: Device or resource busy
error writing data: Communication error with device
Ответ был найден здесь: http://forums.obdev.at/viewtopic.php?t=1474 .

Упрошенный вид кода таков:
usb_set_configuration(dev, 1);
while(usb_claim_interface(dev, 0)!= 0){
    if(usb_detach_kernel_driver_np(dev, 0)<0) printf("Error 123");
}
Вписывается он после: dev = openDevice();
Возникает потому что:

Postby christian » Wed May 28, 2008 5:22 pm
The first error indicates that Linux insists that you claim an interface. That's somewhat strange, since it should be possible to query the device's string descriptors (through endpoint 0) when the device is otherwise busy.
Полезные ссылки:
http://codebot.wordpress.com/2010/01/05/libusb-dokumentaciya/
http://microsin.ru/content/view/955/44/

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

C/C++ чем * отличается от &

Статья
В С/С++ существует понятие указателя. Указатель – это переменная, значением которой является адрес некоторого объекта (обычно другой переменной) в памяти компьютера.

int *a; //создается указатель  с типом данных int

Тип данных определяет возможные действия над указателем. Так же не стоит забывать про void.

int b=2;//создаем переменную со значением 2

a=&b;//записываем в указатель а АДРЕС значения переменной b

То есть оператор & возвращает адрес переменной.

Теперь небольшой фокус:
int *a;
int b=2;
a=&b;
 
int v;
v=*a;//в значение переменной v будет находиться 2

//, здесь*a -называется разыменованием

//тоесть по сути это равнозначно v=b; 


Теперь самое интересное! Операции над указателями.

Над указателями определено 5 основных операций.
1)    Определение адреса указателя: &p, где p – указатель (&p – адрес ячейки, в которой находится указатель).

2)     Присваивание. Указателю можно присвоить адрес переменной p=&q, где p – указатель, q – идентификатор переменной.

3) Определение значения, на которое ссылается указатель: *p (операция косвенной адресации).

4) Увеличение (уменьшение) указателя. Увеличение выполняется как с помощью операции сложения (+), так и с помощью операции инкремента (++). Уменьшение – с помощью операции вычитания (–) либо декремента (––).

Например, пусть p1 – указатель, тогда р1++ перемещает указатель на:
     -1 байт, если *p1 имеет тип char; 
  -4 байта, если *p1 имеет тип int (в 32 разрядной операционной системе) или 2 байта (в 16 разрядной операционной системе);
  -4 байта, если *p1 имеет тип float.

5)    Разность двух указателей. Пусть р1 и р2 – указатели одного и того же типа. Можно определить разность р1 и р2, чтобы найти, на каком расстоянии друг от друга находятся элементы массива.

вторник, 19 февраля 2013 г.

Написание прилжений "Клиент-Сервер". Часть 0.

Полезные ссылки:

1.
2. Достаточно интересная.
3. Еще более интересная ссылка
4.
5.
6.
7. Самая полезная ссылка.(ВЫсший приоритет)

План действий:
Узнать мне поможет из winapi?
Смогу ли я это реализовать в линухе?
Что такое сокет? (Ответ)
Сокет Беркли. Очень интересное решение.

Как я начал cgi учить.

Что бы запустить cgi в линухе нужно создать виртуальный хост(local.dip.com). Потом в папке /etc/apache2/sites-enabled/ открыть файл настроек твоего хоста ocal.dip.com. И в нем глянуть на

ScriptAlias /cgi-bin/ /var/www/local.dip.com/cgi-bin/
<Directory «/var/www/local.dip.com/cgi-bin/»>
AllowOverride None
Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
Order allow,deny
Allow from all
</Directory>


/var/www/local.dip.com/cgi-bin/ -путь где будут лежать скрипты.

Затем я создал простенькую С программу:
#include <stdio.h>
int main(void) {
  printf("Content-Type: text/plain;charset=us-ascii\n\n");
  printf("Hello, world!\n\n");
  return 0;
}
И откомпилировал ее в  /var/www/local.dip.com/cgi-bin/ с именем a.out .

И в браузере  прописываем local.dip.com/cgi-bin/a.out. И должно появиться Hello World!

Вспомогательные ссылки:

http://httpd.apache.org/docs/2.2/howto/cgi.html
http://dedicatesupport.com/archives/52