среда, 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 следовательно если Вы решите обновить систему, то этот файл потрется. Не забудьте сделать копию предварительно.

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

понедельник, 15 августа 2011 г.

Открываем все внешние ссылки в новом окне. jQuery

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

Чтобы сделать это быстро и с малыми трудозатратами, можно использовать следующий код, написанный на jQuery.



$(document).ready(function() { 
  $("a[href^=http]").each( //поиск всех "a" что имеют ссылки
    function(){
      if(this.href.indexOf(location.hostname) == -1) {
        $(this).attr('target', '_blank'); // и если host отличается от текущего, то перенапрявляем на новую страницу
      }
    })
});


Вот и все


четверг, 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";
  }
} 

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

воскресенье, 13 декабря 2009 г.

Приезд в Германию (краткая история)

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

Так как я уже тут 2 месяца, то в кратце рааскажу о них.

Приехали мы сюда 19ого октября. В количестве 4ех человек. До начала учебы было еще 2 недели. И поселились в монастыре:). Такой стандартный монастырь, с монашками. Комфорт конечно что надо, все чистенько, в каждом номере душ.., но и стоит не самое дешевое, но и не самое дорогое, 18 Евро за ночь. В общем жилье было временное, всего на 2 дня, так что мы не жаловались. Ждали приезда еще 2их человек. Ну а как они приехали, конечно не обошлось без ящика пива, и отмечания приезда.., и сна по несколько человек на одной кровати, ибо официально нас там жило четверо, а неофициально семеро).

Затем мы переехали в Vallendar. Это пригород Кобленца, и очень далеко от универа, 1 час езды. Но там и подешевле было, хоть и по 2 человека в номере. Жили там 2 недели, параллельно искав где-бы снять квартирку. Мы вроде и не тихие были, но вроде никто и не жаловался.

А через 2 недели мы нашли 2 квартиры, 2х и 3х комнатную. Но в итоге сдали нам только одну.., не любят тут немцы студентов). Не доверяют чтоли, наверно они правы. Мы уже и не знали что делать, как нам предложили квартиру русские, на 2 месяца.., что как в итоге выяснилось было зря, но тогда мы согласились. Т.к. очень не дорого...., а зря потому что после того как вьехали, тепло в квартире включали еще месяц.

Во время всего этого началась учеба, которая ни привнесла чего-то необычного, очень рутинно, и на самом деле очень не интересно.  Интересно начнется когда надо будет сдавать экзамен на немецком, которого мы не знаем.

За 2 месяца мы обжились, прикупили мебели, провели интернет, нашли новых знакомых. (естественно русских, которых тут иногда кажется больше чем немцев). Так что выходные в скуке не проходят. В общем как это ни казалось непривычным, начинаешь понимать что жить тут вполне можно, и наверно не так уж тут и плохо. Единственное что город маленький, делать тут нечего особо.

Вот пока в кратце)

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

Восcтановление удаленных разделов. Ubuntu

Сегодня пытался поставить Windows на свой второй винчестер и случайно удалил все разделы на нем. А ведь там хранилася вся важная мне информация...
В общем начал искать методы как восстановить все, и нашел!!! Им и поделюсь.

Как оказалось все чертовски просто.

1) Сначала находим через менеджер пакетов и устанавливает утилиту GPART (не путать с GParted).

2)  Затем выполняем команду gpart /dev/sdb (sdb - название вашего привода)
После некоторых раздумий (у меня лично думало около часа). На экран выводиться следующее:



Guessed primary partition table:
Primary partition(1)
   type: 007(0x07)(OS/2 HPFS, NTFS, QNX or Advanced UNIX)
   size: 89996mb #s(184313682) s(106494948-290808629)
   chs:  (1023/254/63)-(1023/254/63)d (6629/1/1)-(18101/254/63)r

Primary partition(2)
   type: 131(0x83)(Linux ext2 filesystem)
   size: 9005mb #s(18442616) s(290808630-309251245)
   chs:  (1023/254/63)-(1023/254/63)d (18102/0/1)-(19249/254/59)r

Primary partition(3)
   type: 130(0x82)(Linux swap or Solaris/x86)
   size: 1623mb #s(3325448) s(309251250-312576697)
   chs:  (1023/254/63)-(1023/254/63)d (19250/0/1)-(19456/254/56)r

Primary partition(4)
   type: 000(0x00)(unused)
   size: 0mb #s(0) s(0-0)
   chs:  (0/0/0)-(0/0/0)d (0/0/0)-(0/0/0)r 

Программка сама нашла удаленные разделы. Тут мы видим тип системы и ее размер.

3) Если нас все устраивает, выполняем команду


gpart -W /dev/hdb /dev/hdb

Ждем еще часик, и вуаля!!! Винчестер как новенький:)

Удачи!