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

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

Magento: меняем фотографии товара, для Configurable продуктов

Сегодня попробуем сделать следующее:

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

1) Откроем файл
app/design/frontend/*/*/template/catalog/product/view.phtml

Заменим


var optionsPrice = new Product.OptionsPrice(getJsonConfig() ?>);

на


var optionsPrice = new Product.OptionsPrice(getJsonConfig() ?>);
var assocIMG =  
getTypeId() == "configurable") {
        echo "{";
        $associated_products = $_product->loadByAttribute('sku', $_product->getSku())->getTypeInstance()->getUsedProducts();
        foreach ($associated_products as $assoc)
            $dados[] = $assoc->getId().":'".($assoc->image == "no_selection" || $assoc->image == "" ? $this->helper('catalog/image')->init($_product, 'image', $_product->image)->resize(365,400) : $this->helper('catalog/image')->init($assoc, 'image', $assoc->image)->resize(365,400))."'";
    } else {
        $dados[] =  "''";
    }
    echo implode(',', $dados );     
    if ($_product->getTypeId() == "configurable") {
        echo "}";
    }

2) Oткроем
app/design/frontend/*/*/template/catalog/product/view/type/options/configurable.phtml

Заменим

var spConfig = new Product.Config(getJsonConfig() ?>);

на

var spConfig = new Product.Config(getJsonConfig() ?>);
var selectedAssocProducts = {};


3) Файл
js/varien/configurable.js

a) Добавляем в самое начало файла

if(typeof selectedAssocProducts=='undefined') {
    var selectedAssocProducts = {};
}


b) В функцию configureElement : function(element), сразу после this.reloadPrice() добавляем


if (!element.value || element.value.substr(0,6) == 'choose') return; // Selected "choose option"
var attributeId = element.id.replace(/[a-z]*/, '');
for (var a in this.config.attributes)
{
    for (i = 0; i < this.config.attributes[a].options.length; i++)
    {
        if (this.config.attributes[a].options[i].id != element.value) continue;
        selectedAssocProducts[a] = this.config.attributes[attributeId].options[i].products;
    }
}
var productNo = intersect(selectedAssocProducts) || selectedAssocProducts[attributeId][0];
$('image').src = assocIMG[productNo];
c) Меняем метод resetChildren : function(element) на
resetChildren : function(element){
    delete selectedAssocProducts[element.config.id]; 
    if(element.childSettings) {       
        for(var i=0;i < element.childSettings.length;i++){
	    element.childSettings[i].selectedIndex = 0;
	    element.childSettings[i].disabled = true;               
	    delete selectedAssocProducts[element.childSettings[i].config.id]; 
	    if(element.config){
	        this.state[element.config.id] = false;                   
            }
        }
    }},
d) В конец файда добавляем:
function intersect(ar) // ar can be an array of arrays or an asssociative array
      {
          if (ar == null) return false;
          var a = new Array();
          if (ar.length == undefined) // Associate Array
          {       
              for (var i in ar)
               a.push(ar[i]);       
          }     
          else
           a = ar;
         
          if (a.length == 1) return false; // Single array ? Nothing to intersect with
          var common = new Array();
          function loop(a, index, s_index, e_index)
          {               
              if (index == null) index = 0;
              if (s_index == null) s_index = 0;
              if (e_index == null) e_index = a[index].length;
              if (index == a.length - 1) return;           
              for (var i = s_index; i < e_index; i++)
              {
                  if (common.indexOf(a[index][i]) != -1) continue;
                  for (var j = 0; j < a[index + 1].length; j++)
                  {
                      if (a[index][i] != a[index+1][j]) continue;                       
                      loop(a, index + 1, j, j + 1);
                      if (index + 1 == a.length - 1) { common.push(a[index][i]); break; }                       
                  }
              }           
          }       
          loop(a);
          return common;
      }

Сохраняем все. И готово.

Не забывайте! что мы правили js файл configurable.js следовательно если Вы решите обновить систему, то этот файл потрется. Не забудьте сделать копию предварительно.

Взято, ПРОВЕРЕНО, изменено и переведено отсюда 

четверг, 18 марта 2010 г.

Magento. Задать и получить Product QTY

Стоит следующая задача:

Задать и получить Product QTY.

Сначала попробовал сделать это через $product->getQty();

Но как оказалось все данные что связанные с Inventory хранятся в другой модели. Поэтому делаем так:

   $stock = Mage::getModel('cataloginventory/stock_item')->loadByProduct($productId); 
   $stock->getQty(); // получаем QTY
   $stock->setQty(1); // задаем QTY
   $stock->save(); // Обязательно сохранись, если были внесены изменения

Собственно вот.

среда, 10 марта 2010 г.

Ebay Api. Отсылаем запросы

Все запросы в eBay Api. Отсылаются в виде XML


Приведу пример:
// Указываем ключи, полученные на developers.ebay.com

        $this->devID = 'DEV ID';
        $this->compatabilityLevel = 681;
        $this->appID = 'APP ID';
        $this->certID = 'CERT ID';
        $this->serverUrl = 'https://api.sandbox.ebay.com/ws/api.dll';
        $this->siteUrl = 'http://cgi.sandbox.ebay.com/ws/eBayISAPI.dll?ViewItem&item=';
        $this->globalUserToken ='YOURTOKEN';
        $this->auth_url="https://signin.sandbox.ebay.com/ws/eBayISAPI.dll?SignIn&";  
        $this->Runame="YOUR RUNAME";

        // Функция которая принимает XML - запрос: $requestBody;
        // $type - это тип запроса. "AddItem, GetCategories .........."
        // $siteID - Id магазина с которым собираемся работать
        public function sendHttpRequest($requestBody, $type = '', $siteID = 0)
        {
         $this->siteID = $siteID;
         $this->verb = $type;
         //build eBay headers using variables passed via constructor
                // создаем Xедеры
         $headers = $this->buildEbayHeaders();

         //initialise a CURL session
         $connection = curl_init();
         //set the server we are using (could be Sandbox or Production server)
         curl_setopt($connection, CURLOPT_URL, $this->serverUrl);

         //stop CURL from verifying the peer's certificate
         curl_setopt($connection, CURLOPT_SSL_VERIFYPEER, 0);
         curl_setopt($connection, CURLOPT_SSL_VERIFYHOST, 0);

         //set the headers using the array of headers
         curl_setopt($connection, CURLOPT_HTTPHEADER, $headers);

         //set method as POST
         curl_setopt($connection, CURLOPT_POST, 1);

  
         //set the XML body of the request
         curl_setopt($connection, CURLOPT_POSTFIELDS, $requestBody);

         //set it to return the transfer as a string from curl_exec
          curl_setopt($connection, CURLOPT_RETURNTRANSFER, 1);

         //curl_multi_info_read($connection);
         //Send the Request
         $response = curl_exec($connection);
         //close the connection
         curl_close($connection);

         return $response;
        }

        private function buildEbayHeaders()
        {
          $headers = array (
          //Regulates versioning of the XML interface for the API
          'X-EBAY-API-COMPATIBILITY-LEVEL: ' . $this->compatabilityLevel,
   
          //set the keys
          'X-EBAY-API-DEV-NAME: ' . $this->devID,
          'X-EBAY-API-APP-NAME: ' . $this->appID,
          'X-EBAY-API-CERT-NAME: ' . $this->certID,
   
         //the name of the call we are requesting
          'X-EBAY-API-CALL-NAME: ' . $this->verb,   
   
         //SiteID must also be set in the Request's XML
         //SiteID = 0  (US) - UK = 3, Canada = 2, Australia = 15, ....
         //SiteID Indicates the eBay site to associate the call with
         'X-EBAY-API-SITEID: ' . $this->siteID,
         );

         return $headers;
       }


Это методы класса, которые обрабатывают запрос, отсылают его на Ebay и возвращают ответ.

Продолжение следует.

вторник, 22 декабря 2009 г.

Youtube API, Поиск по видео

Вот столкнулся недавно с задачей, поиска видео на Youtube из моего приложения.

Как оказалось задача проста. В Youtube Api с использованием PHP все вызовы идут с использованием Zend Framewokr.

Вот собственно функция для поиска видео:

function searchAndPrint($searchTerms)
{
  $yt = new Zend_Gdata_YouTube(); 
  $query = $yt->newVideoQuery();
  $query->setOrderBy('viewCount');
  $query->setRacy('include');
  $query->setVideoQuery($searchTerms);
  $videoFeed = $yt->getVideoFeed($query);
  printVideoFeed($videoFeed, 'Search results for: ' . $searchTerms);
}

Где функция вывода на экран (printVideoFeed):

function printVideoFeed($videoFeed, $displayTitle = null) 
{
  $count = 1;
  if ($displayTitle === null) {
    $displayTitle = $videoFeed->title->text;
  }
  echo '

' . $displayTitle . "

\n"; echo "
\n";
  foreach ($videoFeed as $videoEntry) {
    echo 'Entry # ' . $count . "\n";
    printVideoEntry($videoEntry);
    echo "\n";
    $count++;
  }
  echo "
\n"; }
 
 
function printVideoEntry($videoEntry, $tabs = "") 
{
  // the videoEntry object contains many helper functions that access the underlying mediaGroup object
  echo $tabs . 'Video: ' . $videoEntry->getVideoTitle() . "\n";
  echo $tabs . "\tDescription: " . $videoEntry->getVideoDescription() . "\n";
  echo $tabs . "\tCategory: " . $videoEntry->getVideoCategory() . "\n";
  echo $tabs . "\tTags: " . implode(", ", $videoEntry->getVideoTags()) . "\n";
  echo $tabs . "\tWatch page: " . $videoEntry->getVideoWatchPageUrl() . "\n";
  echo $tabs . "\tFlash Player Url: " . $videoEntry->getFlashPlayerUrl() . "\n";
  echo $tabs . "\tDuration: " . $videoEntry->getVideoDuration() . "\n";
  echo $tabs . "\tView count: " . $videoEntry->getVideoViewCount() . "\n";
  echo $tabs . "\tRating: " . $videoEntry->getVideoRatingInfo() . "\n";
  echo $tabs . "\tGeo Location: " . $videoEntry->getVideoGeoLocation() . "\n";
  
  // see the paragraph above this function for more information on the 'mediaGroup' object
  // here we are using the mediaGroup object directly to its 'Mobile RSTP link' child
 foreach ($videoEntry->mediaGroup->content as $content) {
    if ($content->type === "video/3gpp") {
      echo $tabs . "\tMobile RTSP link: " . $content->url . "\n";
    }
  }
  
  echo $tabs . "\tThumbnails:\n";
  $videoThumbnails = $videoEntry->getVideoThumbnails();

  foreach($videoThumbnails as $videoThumbnail) {
    echo $tabs . "\t\t" . $videoThumbnail['time'] . " - " . $videoThumbnail['url'];
    echo " height=" . $videoThumbnail['height'];
    echo " width=" . $videoThumbnail['width'];
    echo "\n";
  }
} 

Вот собственно и все. А дальше уже оформляйте вывод как вам нравится:). Удачи

понедельник, 21 сентября 2009 г.

Локализация модуля Magento

Решил написать про локализацию своего модуля в Magento.

На первый взгляд задача проста, но я не сразу понял как....

Сначала создаем папку, если таковой нет в /locale/ с названием вашей локали.

На моем примере русский язык - папка "ru_RU". Затем в этой папке создаем файл для вашего модуля. В принципе название можно выбирать любое, но рекомендуют называть Company_Module.csv. (Company - название Вашей компании, Module - название модуля).

В Magento локализация основана на Английском. То есть содержимое файла должно выглядеть следующим образом:


"Attributes for template","Аттрибуты для шаблона"
"Test", "Тест"
"Your english text", "Ваш русский текст"

В коде же вы пишете

echo Mage::helper('moduleName')->__('Attributes for template');


где moduleName - название Вашего модуля.

Также в конфиг файл модуля (/app/code/local/Company/Module/etc/config.xml)

вставляете следующие строки (если их нет)


<translate>
<modules>
<ebay>
<files>
<default>Company_Module.csv</default>
</files>
</ebay>
</modules>
</translate>


Далее меняете локализацию в настройках и должно все заработать.

П.С. Незабудьте перелогинится и обновить Кеш.

вторник, 21 июля 2009 г.

Magento - создание своего модуля

Если Вам необходимо создать в Magento собственный модуль, и Вы никогда этого не делали до этого, я рекомендую воспользоваться утилиткой 'Module creator'. Которую можно скачать здесь.


Также на этой страничке есть и английская документация по ее работе.


Я опишу ее работу.

1) Скачиваем модуль с сайта
2) Копируем програму к себе на сервер и запускем index.php файл.

Видим перед собой:

Здесь мы вводим:

Namespace: Имя Вашей компании*
Module: Название модуля*
Magento Directory: директория где расположен установленный magento магазин.
Design: название темы, которую должен использовать модуль (по-умолчанию 'default')

* - совет: писать названия в таком формате: Xxxxxxx. (первый символ большой, остальные маленькие, и использовать только символы [A-Z])

Все, жмем 'create' и создаем модуль.

Созданый модуль (модели, контроллеры), будет находиться по-адресу:

/code/local/Название компании/Название модуля

Http адрес модуля, будет:

http://your-site/your-module-name

понедельник, 15 июня 2009 г.

Подмена родного контроллера (controller) в Magento своим.

Напишу как подменить родной контроллер в Magento, своим, без изменения родного кода магазина.

На примере подмены контроллера для корзины.

1.Сначала нужно создать непосредственно файлы модуля

1. Magento/app/code/local/MyNameSpace/MyModule/etc/config.xml
2. Magento/app/code/local/MyNameSpace/MyModule/controllers/Checkout/CartController.php
3. Magento/app/etc/modules/MyNameSpace_All.xml


2. Cоздаем /etc/config.xml в нашем модуле



  1. <?xml version="1.0"?>
  2. <config>
  3. <modules>
  4. <MyNameSpace_MyModule>
  5. <version>0.1.0</version>
  6. </MyNameSpace_MyModule>
  7. </modules>
  8. <global>
  9. <rewrite>
  10. <!-- Это имя класса для Вашего контроллера -->
  11. <mynamespace_mymodule_checkout_cart>
  12. <from><![CDATA[#^/checkout/cart/#]]></from>
  13. <!-- Путь к родному контроллеру который требуется подменить
  14. to - путь к нашему контрллеру
  15. -->
  16. <to>/mymodule/checkout_cart/</to>
  17. </mynamespace_mymodule_checkout_cart>
  18. </rewrite>
  19. </global>
  20. <!--
  21. Если Вы хотите переписать admin контроллер, то нужно написать admin вместо frontend
  22. -->
  23. <frontend>
  24. <routers>
  25. <mynamespace_mymodule>
  26. <use>standard</use>
  27. <args>
  28. <module>MyNameSpace_MyModule</module>
  29. <frontName>mymodule</frontName>
  30. </args>
  31. </mynamespace_mymodule>
  32. </routers>
  33. </frontend>
  34. </config>

3. Изменение /app/code/local/MyNameSpace/MyModule/controllers/Checkout/CartController.php

Это наш контролер


2. # Controllers are not autoloaded so we will have to do it manually:
3. require_once 'Mage/Checkout/controllers/CartController.php';
4. class MyNameSpace_MyModule_Checkout_CartController extends Mage_Checkout_CartController
5. {
6. # Overloaded indexAction
7. public function indexAction()
8. {
9. # Just to make sure
10. error_log('Yes, I did it!');
11. parent::indexAction();
12. }
13.}


4. Создаем конфиг файл, чтобы наш модуль активировался /app/etc/modules/MyNameSpace_All.xml


  1. <?xml version="1.0"?>
  2. <config>
  3. <modules>
  4. <MyNameSpace_MyModule>
  5. <active>true</active>
  6. <codePool>local</codePool>
  7. </MyNameSpace_MyModule>
  8. </modules>
  9. </config>



5. И последнее модифицирование файла, для того чтобы все блоки в родном контроллере, адекватно работали и в нашем созданом
Magento/app/design/frontend/[myinterface]/[mytheme]/layout/checkout.xml


  1. <mynamespace_mymodule_checkout_cart_index>
  2. <update handle="checkout_cart_index"/>
  3. </mynamespace_mymodule_checkout_cart_index>



Вот собственно и все, после всех манипуляций, все должно заработать

среда, 15 апреля 2009 г.

Magento Commerce. Введение

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

Из-за этого мне приходиться разбираться со структурой магазина самому. Копаясь в туче исходного кода, библиотеках, контроллерах и можелях этого магазина.

Именно по этому я хочу делать некоторые заметки про магазин, которые потом могут стать полезными не только мне, но и кому лиюо еще.

Начнем с введения, что такое Magento Commerce.

Magento — интернет-магазин с открытым исходным кодом, распространяющееся в соответствии с Open Software License (OSL 3.0). Это программное обеспечение создано с использованием Zend Framework. На конкурсе Sourceforge Community Choice Awards 2008 Magento занял первое место в номинации «лучший новый проект».

Архитектура:

Можно сказать что система написана на Zend Framework, но видно разработчики решили выделитсья и изменили Фреймворк, назвав его Mage. Но в принципе прктически все функции и классы что были доступны в Zend доступны и здесь.

Архитектура самих папок устроена почти как в Зенде, следующим образом:
Есть папка "core" в которой храняться все модули. Каждый же модуль имеет свой набор контроллеров, блоком, моделей и хелперов.

Пр:

core /
moduleName/
controllers/
blocks/
modules/
helpers/
etc/

Также есть папка где храняться темплейты:

design/

И Xml файлы которые конфигурируют магазин

etc/

Java Script

Магазин использует библиотеки Prototype

Возможности

Основные

  • * Пакеты дизайна(англ.)
  • * Множество валют(англ.)
  • * Множество сайтов на одной системе(англ.)
  • * Многоязычность(англ.)
  • * Методы оплаты и доставки(англ.)

Панель администратора

  • * Маркетинговые инструменты
  • o Многоуровневое ценообразование
  • o Купоны
  • o Правила ценообразования
  • * Отчеты
  • o Отчеты продаж
  • o Отчет по корзинам покупателя
  • o Отчет о списке отмеченного товара
  • o Отчет о Отзывах
  • o Отчет по Тэгам
  • o Отчет по Поиску
  • * Определение налоговых ставок
  • o Определение правил для региона, страны или почтового кода.
  • o Создание классов налога, например «Нормальный» или «Оптовый»
  • o Определение правил налога, например «Налог на одежду», также можно связать различные группы товаров с классами налогов.
  • * Продукты и каталог
  • o Возможность задания различных атрибутов (свойств) для товара.
  • o Группировка товара в комплекты.
  • o Конфигурируемые продукты — продукты с выборочными свойствами (например цвет, размер и т. д.)
  • o Сортировка товара по предопределенным атрибутам. Атрибуты доступные для сортировки определяются в панели администрирования.
  • * Система управления контентом
  • * Группы покупателей
  • * Импорт/Экспорт (В данный момент импорт товаров работает в ограниченом варианте, возможно внесение товаров, но не обновление)
  • * Система контроля доступа

Возможности покупателей

  • * Поисковая оптимизация (SEO)
  • * Связь с покупателем
  • o Сообщения по электронной почте
  • o Новостная рассылка по электронной почте
  • * Доставка по нескольким адресам
  • * Поиск
  • * Сравнение продуктов
  • * Наслоенная навигация
  • * Тэги для продуктов
  • * Отзывы о Продуктах
  • * Список отмеченного товара
  • * Оформление заказа
  • * Корзина покупок
  • * Аккаунты покупателей

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

суббота, 7 февраля 2009 г.

Ebay Api Введение

По работе, мне пришлось столкнуться с аукционом Ebay, а точнее с Ebay Api о существовании которого я раньше не догадывался. Думаю что такое Ebay.com знают все пользователи интернета. А если не знают, то объясню – это самый крупный интернет-аукцион в мире, имеющий кучу возможностей, и позволяющий продать или купить все что угодно (в разумных пределах конечно).

И у этого самого аукциона, как оказалось, имеется свое Api , которое позволяет получать полный доступ к базе данных аукциона и оперировать нужной информацией.
Для того чтобы начать работать, необходимо зарегистрироваться на сайте http://developer.ebay.com/

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

API делиться несколько разделов, в зависимости от функций, вот основные из них:
  • Shopping API – позволяет производить поиск по аукционам, просматривать аукционы
  • Merchandising API – позволяет получать информацию по популярным аукционам, и текущим сделкам.
  • Trading API – позволяет получить доступ к защищенным данным, производить авторизацию, получать данный пользователя

Языки программирования, для которых существует API:
  • 1) .NET, C#, ASP, VB
  • 2) PHP
  • 3) Java
  • 4) JavaScript

Меня будет интересовать PHP.

Работа всей системы построена на XML запросах, т.е. мы генерируем какую-либо XML , по определенным правилам, отсылаем ее на Ebay, и получаем ответ на наш запрос, также в виде XML. Если вы не знаете правильно ли вы сгенерировали XML есть возможность проверить ее тут https://developer.ebay.com/DevZone/build-test/test-tool/ (естественно необходимо авторизироваться) Также на сайте http://developer.ebay.com/ можно скачать примеры использования API.

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

Пример:



Как видно из этого скрина, есть 2 вида ключей, это Production keys и Sandbox Key. Чтобы было понятно, Production keys – это ключи, которые позволяют работать с сайтом ebay.com. A Sandbox Key – это для работы с sandbox.ebay.com, сайтом который предназначен для разработчиков, так называемая тестовая площадка.
Если вы хотите использовать Trading API, то также прийдется сгенерировать User Tokens.

В следующей статье расскажу как производить XML запросы и обрабатывать ответы. Пока.

понедельник, 13 октября 2008 г.

CodeIgniter - работа с шаблонами

По просьбе Виктора, напишу как он работает с шаблонами.
А происходит єто очень и очень просто.

1) Мы создаем нужный нас HTML код и сохраняем его в папке views (отображения).
2) Как уже описывалось ранее это полностью объектно ориентированный фреймворк. Следовательно, в нужном месте нашего класса мы просто напросто подключаем наш HTML файл следующим образом

$this->load->view("otobragenie",$data)

Где otobragenie название Вашего файла.
А $data - ассоциативный массив.
Для примера:

$data['alex']="123";
$data['test']="1234";

Который в Вашем шаблоне будет доступный в виде

$alex и $test

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

Если Вы предпочитаете использовать теги принятые в шаблонизаторах (например { и } ) то в CodeIgniter существует свой класс Template Parser

среда, 1 октября 2008 г.

Фреймворк CodeIgniter

Вот по совету хорошего друга решил посмотреть что это за штука такая, и как оказалось совет был хороший:)

Цитата:

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

  • используется модель MVC (Модель-Отображение-Контроллер), хорошо зарекомендовавшая себя при разработке приложений самой разной направленности;
  • поддерживается множество баз данных (MySQL, PostgreSQL, MSSQL, SQLite, Oracle);
  • отлично написанная документация с примерами позволит быстро освоить фреймворк;
  • CodeIgniter очень быстр в работе. Его считают эталоном скорости генерации страниц;

Начав изучать мне очень понравилась сама структура Фреймворка.

Для примера:

1) Строка адреса записывается в виде:
http://127.0.0.1/admin/admin_pages/test/id/id1/string
Где admin_pages - название класса, совпадающее с названием файла
test - любая функция в єтом классе
id/id1/string - параметры, которые принимает указанная ранее функция.

Вобщем очень удобно и понятно.

2) Отделение HTML кода от ПХП.
3) И что очень мне понравилось, что он не привязывает программиста к свои правилам, а наоборот дает полную свободу.

Русский сайт:
http://www.code-igniter.ru/