лайфхак Список доставок та оплат в OpenCart 3 будь де

Baco

Baco

architect
#1
Доброго дня, шановні читачі, недавно зіштовхнувся з такою частою проблемою, як "відображення списку оплат та доставок на певних сторінках вітрини".
Так як список доставок, можна отримати, маючи дані "країни та області", та список оплат вже потрібно витягувати, маючи загальну суму ($total), без котрої не можна отримати всі дані.
Якщо змоделювати ситуацію по типу "виводити список доставок та оплат на сторінці товару", то можна за загальну суму $total взяти ціну самого товару, а дані краіни та області брати з налаштувань по замовчуванню:
PHP:
$default_country_id = $this->config->get('config_country_id');
$default_zone_id = $this->config->get('config_zone_id');
тепер, щоб отримати список даних нам потрібно визначити, як саме ми це робитимемо, зазвичай, я роблю це через окремий метод, по типу getShippingMethodsByDefault прямо в контроллері потрібної сторінки, але то довше розписувати, та й там зі своїми шаблонами підвантаження, я спробую описати загальний алгоритм, а майстер зможе це вже оформити як слід... отже:
працюємо з контроллером: catalog\controller\product\product.php
знаходимо нейтральний сектор в коді та додаємо семантичний коментар по типу: //Здесь был Вася //SOF shipping methods
далі, нам потрібно створити массив, куди додамо дані по замовчуванню, для отримання списку потрібних доставок:
PHP:
$address = array();
$address['country_id'] = $this->config->get('config_country_id');
$address['zone_id'] = $this->config->get('config_zone_id');
тепер важливим кроком буде підвантаження моделі з розширеннями, для отримання встановлених доставок:
PHP:
$this->load->model('setting/extension');
ну і сама логіка отримання:
PHP:
$data['shipping_methods'] = array();
// оголошуєм массив, в котрий помістимо наш список доставок
if ($address) {
    $method_data = array();
    $results = $this->model_setting_extension->getExtensions('shipping');
    // в змінну $results отримуємо список "встановлених" доставок
    foreach ($results as $result) {
        if ($this->config->get('shipping_' . $result['code'] . '_status')) {
        // перевіряємо, чи включений "статус" доставки
            $this->load->model('extension/shipping/' . $result['code']);
            $quote = $this->{'model_extension_shipping_' . $result['code']}->getQuote($address);
            // отримаємо детальну інформацію по кожній із доставок
            if ($quote) {
                if (isset($quote['quote'])) {
                    foreach ($quote['quote'] as $code => $full_method) {
                        $method_data[$full_method['code']] = array(
                            'title'      => $full_method['title'],
                            'cost'       => $full_method['cost']
                        );
                    }
                }                            
            }
        }
    }
    // заносимо весь список (код, як ключ, назва методу доставки та вартість) в массив 'shipping_methods'
    $data['shipping_methods'] = $method_data;
}
наприкінці рекомендую додати аналогічний семантичний коментар, щоб інший розробник міг розуміти, що блок по доставкам завершено, по типу: //EOF shipping methods
ну і в фіналі, в самому tpl\twig файлі нам потрібно тільки перебрати та вивести дані массиву 'shipping_methods', тому переходимо в catalog\view\theme\YOU_THEME\template\product\product.twig, знаходимо потрібний сектор в коді, та додаємо наступний код:
HTML:
{% if shipping_methods %}
    <div id="input-shipping-method" class="form-control">';
    {% for key, shipping in shipping_methods %}
        <span id="{{ key }}" data-summ="{{ shipping.cost }}">{{ shipping.title }}</span>
    {% endfor %}
    </div>
{% endif %}
де {{ key }} - код доставки, {{ shipping.cost }} - вартість, ну і {{ shipping.title }} - назва способу доставки
 
OP
Baco

Baco

architect
Thread Starter #2
для отримання списку оплат, нам потрібно додати змінну з неформатованою ціною в контроллері catalog\controller\product\product.php
я б додав, наприклад, після: $data['model'] = $product_info['model'];
PHP:
// SOF not formatted price
$base_price = $product_info['price'];
// EOF not formatted price
далі, у відповідності до попереднього пункту, я б знайшов місце, де додати логіку поміщення списку оплат в массив, враховуючи те, що для отримання даних потрібна модель
$this->load->model('setting/extension');
та массив з геоданими $address, тому рекомендував би код, котрий напишу нижче, додавати після блоку з доставками:
PHP:
$data['payment_methods'] = array();
if ($address) {             
    $method_data = array();
    $results = $this->model_setting_extension->getExtensions('payment');                 
    foreach ($results as $result) {
        if ($this->config->get('payment_' . $result['code'] . '_status')) {                 
            $this->load->model('extension/payment/' . $result['code']);
            $method = $this->{'model_extension_payment_' . $result['code']}->getMethod($address, $base_price); // в якості $total відправляємо ціну товару
            if ($method) {
                $method_data[$result['code']] = $method;                     
            }                 
        }
    }             
    $sort_order = array();
    foreach ($method_data as $key => $value) {
        $sort_order[$key] = $value['sort_order'];
    }
    array_multisort($sort_order, SORT_ASC, $method_data); 
    $data['payment_methods'] = $method_data;
}
і відповідно вже в twig\tpl файлі, виводити по аналогії з доставками:

HTML:
{% if payment_methods %}
    <div id="input-payment-method" class="form-control">';
    {% for key, payment in payment_methods %}
        <span id="{{ key }}" data-summ="{{ payment.cost }}">{{ payment.title }}</span>
    {% endfor %}
    </div>
{% endif %}
 
Зверху