Хелпер против модели? Какой я должен использовать?

9

Я работаю с Instagram API в magento. Я даю купоны своим подписчикам в Instagram, если они следят за нашим магазином в Instagram.

Я делаю вызовы API для Instagram в PHP с помощью curl. В настоящее время я обертываю вызовы API во вспомогательные функции внутри моего пользовательского модуля. Должен ли я вместо этого обернуть эти вызовы в функцию внутри модели?

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

Правильно ли я помещаю эти вызовы API во вспомогательные функции? Когда я использую помощников в отличие от моделей?

<?php

class Company_SocialCoupons_InstagramController extends Mage_Core_Controller_Front_Action
{
    public function followAction() {

       $status = Mage::helper('socialcoupons/instagram')->getFollow();

       if ($status == 'follows') {

            // 1. ADD DATA TO MY DATABASE using my custom model
            //    - Ex. Mage::getModel('socialcoupons/instagram')->setInstagramId(*IGID*), etc. 
            // 2. CREATE COUPON
            // 3. EMAIL COUPON TO CUSTOMER
       }
}

class Company_SocialCoupons_Helper_Instagram extends Mage_Core_Helper_Abstract
{

public function getfollow() {

    $accessToken = $this->getAccessToken();
    $relationshipsUrl = 'https://api.instagram.com/v1/users/' . $this->getUserId() . '/relationship?access_token=' . $accessToken;

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $relationshipsUrl);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array('Accept: application/json'));
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    $jsonData = curl_exec($ch);
    curl_close($ch);

    $response = json_decode($jsonData, true);
    $status = $response['data']['outgoing_status'];
    return $status;
}

public function generateAccessToken($code) {

    // exchange code for access token
    $accessTokenUrl = 'https://api.instagram.com/oauth/access_token';
    $data = array(
        'client_id'     => $this->getClientId(),
        'client_secret' => $this->getClientSecret(),
        'code'          => $code,
        'grant_type'    => 'authorization_code',
        'redirect_uri'  => $this->getRedirectUri()
    );       

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $accessTokenUrl);
    curl_setopt($ch, CURLOPT_POST, count($data));
    curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
    curl_setopt($ch, CURLOPT_HTTPHEADER, array('Accept: application/json'));
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    $jsonData = curl_exec($ch);
    curl_close($ch);

    $response = json_decode($jsonData, true);

    if (isset($response['error_type'])) { // no error

        Mage::getSingleton('core/session')->unsInstagramAccessToken();
        Mage::getSingleton('core/session')->addError($response['error_message']);
        return $this->_redirect('*/*/authorize');  
    } 

    $accessToken = $response['access_token'];
    $id          = $response['user']['id'];
    $username    = $response['user']['username'];

    Mage::getSingleton('core/session')->setInstagramAccessToken($accessToken);      

    return array(
        'id'       => $id,
        'username' => $username
    );
}

}

Алекс Лакайо
источник

Ответы:

18

Сначала вы должны спросить себя, в чем разница между моделью и помощником. Самый распространенный ответ - «за моделью стоит таблица». Затем спросите себя «почему наблюдатели указаны в качестве моделей, а не помощников».

Помощники не должны существовать. Но наиболее распространенной практикой является ... когда вы не знаете, куда поместить какой-то код, вы помещаете его в помощник.
Это неправильно, на мой взгляд. Использование помощников не совсем в духе ООП. Вы просто группируете некоторые независимые функции внутри класса.

Но достаточно философских разговоров.
Я бы использовал модель. Главным образом потому, что помощники всегда одинокие. Mage::helper()всегда возвращает один и тот же экземпляр вспомогательного класса.
Для моделей вы можете получить новые экземпляры и синглтоны, в зависимости от того, что вам нужно. Так что это немного более гибко, используя модель.

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

Мариус
источник
Спасибо за это. Когда я создаю новый класс модели, который собирается просто выполнять вызовы APi, нужно ли мне расширять Mage_Core_Model_Abstract или мне не нужно ничего расширять?
Алекс Лакайо
3
Вам не нужно расширять абстрактную модель. Но вы можете расширить Varien_Object. Это может быть полезно, но не обязательно
Marius
2

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

Торговые модули
источник
2

Модель:

echo $MyModel->getUserName();

Helper:

echo $MyHelper->getFullname($SomeModelThatImplementsSomeStuff)..

Если у него есть ВНУТРЕННЕЕ СОСТОЯНИЕ, то это модель. Если это не так, это помощник со всеми математически правильными функциями, такими как sin(x)или str_tolower($text). Модель имеет внутреннее состояние, которое получает Помощник, - это состояние, введенное в качестве зависимости.

Роджер Кёлен
источник
1

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

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

шоколадно-Лоо
источник