2017-01-13 18 views
0

Я добавил пользовательское поле с именем «deldate» в таблицу «ps_orders», и я добавил текстовое поле на странице «OPC». Теперь, когда я нажимаю кнопку подтверждения заказа, значение в текстовом поле должно быть сохранено в поле «deldate» таблицы ps_orders. Текстовое поле отлично отображается, но в каких файлах мне нужно внести изменения, чтобы сохранить значение текстового поля в таблице? (Тема по умолчанию один.)Как вставить значение в пользовательское поле в таблице в Prestashop?

snap of textbox

snap of custom field in table.

класс/заказ/order.php

class OrderCore extends ObjectModel 
{ 
public $deldate; 
} 

И

public static $definition = array( 
'fields' => array( 
'deldate'=> array('type' => self::TYPE_STRING), 
), 
) 

Шоппинг-cart.tpl

<div class="box"> 
<div class="required form-group"> 
<form method="post"> 
<label for="Fecha de entrega deseada">{l s='Desired delivery date' mod='deldate'}</label> 
<input type="text" id="deldate" name="deldate" class="form-control" value="hello" /> 
</form> 
</div> 

</div> 
+0

Моим друг, вы пропустили всю «модель» и «контроллер» коду :), вы должны изменить контроллер, я предполагаю, что 'ParentOrderController' и модель 'Order' – sarcom

+0

привет, я вносил изменения в класс/order/order.php, но позже я получаю сообщение об ошибке банка/валидации во время подтверждения заказа. –

+0

Опубликуйте свои изменения, чтобы мы могли помочь вам – sarcom

ответ

1

Хорошо, я выяснил решение ... Если вы хотите добавить некоторую информацию в заказ в процессе оформления заказа, вы должны сохранить эту информацию в другом месте, если вы посмотрите, что таблица корзин очень похожа на таблицу заказов. Зачем вам это нужно? Потому что у вас нет заказа перед подтверждением клиентом, поэтому до тех пор, пока проверка не будет завершена, информация не может быть сохранена в таблице заказов.

Итак, создайте поле в базе данных, в этом случае вы должны добавить ps_orders и в ps_cart. (В вашем случае я предлагаю использовать поле DATETIME)

Во-вторых, переопределять класс Order:

class Order extends OrderCore 
{ 
    public function __construct($id = null, $id_lang = null) 
    { 
     self::$definition['fields']['deldate'] = array('type' => self::TYPE_DATE); 

     parent::__construct($id, $id_lang); 
    } 
} 

и Cart класс:

class Cart extends CartCore 
{ 
    public function __construct($id = null, $id_lang = null) 
    { 
     self::$definition['fields']['deldate'] = array('type' => self::TYPE_DATE); 

     parent::__construct($id, $id_lang); 
    } 
} 

Теперь мы должны сохранить поле во время процесса проверки, поэтому мы переопределяем OrderController:

class OrderController extends OrderControllerCore 
{ 
    public function processAddress() 
    { 
     parent::processAddress(); 

     // Here we begin our story 
     if(Tools::getIsset('deldate')) // Check if the field isn't empty 
     { 
      $deldate = Tools::getValue('deldate'); 

      // Here you must parse and check data validity (I leave to you the code) 
      /* ... */ 

      // Assign the data to context cart 
      $this->context->cart->deldate = $deldate; 
      // Save information 
      $this->context->cart->update(); 
     } 
    } 
} 

Теперь вам нужно «перевезти» эту информацию из корзины в заказ, это будет сделано через класс PaymentModule, в частности с помощью метода validateOrder.

Итак, другое переопределение:

class PaymentModule extends PaymentModuleCore 
{ 
    public function validateOrder($id_cart, $id_order_state, $amount_paid, $payment_method = 'Unknown', $message = null, $extra_vars = array(), $currency_special = null, $dont_touch_amount = false, $secure_key = false, Shop $shop = null) 
    { 
     $result = parent::validateOrder($id_cart, $id_order_state, $amount_paid, $payment_method, $message, $extra_vars, $currency_special, $dont_touch_amount, $secure_key, $shop); 

     if($result) 
     { 
      $oldcart = new Cart($id_cart); 
      $neworder = new Order($this->currentOrder); 
      $neworder->deldate = $oldcart->deldate; 
      $neworder->update(); 
      return true; // important 
     } 
     else 
     { 
      return $result; 
     } 
    } 
} 

После всего этого у вас есть deldate поля сохранено.Тем не менее, я абсолютно не предлагаю этот метод, это более безопасно и просто с модулем и крючками ... Но это еще одна история :)

Это будет работать только с пятиступенчатой ​​проверкой.

Для следующих строк кода, Боже, спаси меня ...

Если вы хотите, чтобы работы с OPC вы должны пачкать руки с JS и переопределить OrderOpcController. Начните с JS, редактировать order-opc.js в JS папку с поддержкой тему, найти bindInputs функцию и добавить эти строки кода:

function bindInputs() 
{ 
    /* ... */ 

    $('#deldate').on('change', function(e){ 
     updateDelDateInput(); // custom function to update deldate 
    }); 
} 

затем добавить в файл пользовательскую функцию:

function updateDelDateInput() 
{ 
    $.ajax({ 
      type: 'POST', 
      headers: { "cache-control": "no-cache" }, 
      url: orderOpcUrl + '?rand=' + new Date().getTime(), 
      async: false, 
      cache: false, 
      dataType : "json", 
      data: 'ajax=true&method=updateDelDate&deldate=' + encodeURIComponent($('#deldate').val()) + '&token=' + static_token , 
      success: function(jsonData) 
      { 
       if (jsonData.hasError) 
       { 
        var errors = ''; 
        for(var error in jsonData.errors) 
         //IE6 bug fix 
         if(error !== 'indexOf') 
          errors += $('<div />').html(jsonData.errors[error]).text() + "\n"; 
        alert(errors); 
       } 
       // Here you can add code to display the correct updating of field 
      }, 
      error: function(XMLHttpRequest, textStatus, errorThrown) { 
       if (textStatus !== 'abort') 
        alert("TECHNICAL ERROR: unable to save message \n\nDetails:\nError thrown: " + XMLHttpRequest + "\n" + 'Text status: ' + textStatus); 
      } 
     }); 
} 

Тогда переопределить OrderOpcController, скопировать все метод init и изменить строку кода, как показано ниже:

class OrderOpcController extends OrderOpcControllerCore 
{ 
    public function init() 
    { 
     // parent::init(); // comment or delete this line 
     FrontController::init(); // Very important! 
     // Then in this switch `switch (Tools::getValue('method'))` add your case 
     /* ... */ 
     case 'updateDelDate': 
      if(Tools::isSubmit('deldate')) 
      { 
       $deldate = urldecode(Tools::getValue('deldate')); 

       // Here you must parse and check data validity (I leave to you the code) 
       /* ... */ 

       // Assign the data to context cart 
       $this->context->cart->deldate = $deldate; 
       // Save information 
       $this->context->cart->update(); 
       $this->ajaxDie(true); 
      } 
     break; 
     /* ... */ 
    } 
} 

Очевидно, что необходимо переопределить Order, Cart и PaymentModule.

PS: Я надеюсь, что ничего не забыл.

+0

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

+0

Здесь я использую OPC Checkout. И я поместил код текстового кода в Shopping-cart.tpl, который я сделал, как вы сказали, но значения еще не сохранены. Я добавил код shopping-cart.tpl также в сообщении. –

+0

Как я писал, этот метод работает только с пятиступенчатой ​​проверкой, есть еще один код для записи OPC :) – sarcom

0

Попробуйте это переопределение из класса ордена

class Order extends OrderCore 
{ 

    public function __construct($id = null, $id_lang = null) 
    { 
     parent::__construct($id, $id_lang); 

     self::$definition['fields']['deldate'] = array('type' => self::TYPE_STRING); 
     Cache::clean('objectmodel_def_Order'); 

    } 

} 

Кэша :: чистота необходимо, потому что getDefinition пытается извлечь из кэша и кэш устанавливается без переопределения на родителях :: __ построить

затем я попытался создать новый пустой заказ и получить поле определения, и он показал там, поэтому он должен сохранить в MySQL

$order = new Order(); 
var_dump(ObjectModel::getDefinition($order));exit;