title: Prestashop - Add additional fields on product combination
body: <p>I'm trying to add additional fields on my product combinations in order to have custom meta titles for the combinations.
  So I created this module:</p>
  <p><strong>My module definition:</strong></p>
  <pre class="lang-php prettyprint-override"><code>class CombinationCustomFields extends Module
  {
  
      public function __construct()
      {
          $this-&gt;name = 'combinationcustomfields';
          $this-&gt;tab = 'administration';
          $this-&gt;author = '';
          $this-&gt;version = '1.0';
          $this-&gt;need_instance = 0;
          $this-&gt;bootstrap = true;
  
          parent::__construct();
  
          $this-&gt;displayName = $this-&gt;l('Combination Custom Fields');
          $this-&gt;description = $this-&gt;l('Add additional fields on combinations');
          $this-&gt;ps_versions_compliancy = array('min' =&gt; '1.7.1', 'max' =&gt; _PS_VERSION_);
      }
  
      public function install()
      {
          if (!parent::install() || !$this-&gt;_installSql()
              || !$this-&gt;registerHook('displayAdminProductsCombinationBottom')
              || !$this-&gt;registerHook('actionAttributeCombinationSave')
          ) {
              return false;
          }
  
          return true;
      }
  
      public function uninstall()
      {
          return parent::uninstall() &amp;&amp; $this-&gt;_unInstallSql();
      }
  
      /**
       * Add database fields
       * @return boolean
       */
      protected function _installSql()
      {
          $sqlInstall = &quot;ALTER TABLE &quot; . _DB_PREFIX_ . &quot;product_attribute &quot;
              . &quot;ADD meta_title_fr VARCHAR(255) NULL, &quot;
              . &quot;ADD meta_title_en VARCHAR(255) NULL;&quot;;
  
          $returnSql = Db::getInstance()-&gt;execute($sqlInstall);
  
          return $returnSql;
      }
  
      /**
       * Remove database fields
       * @return boolean
       */
      protected function _unInstallSql()
      {
          $sqlInstall = &quot;ALTER TABLE &quot; . _DB_PREFIX_ . &quot;product_attribute &quot;
              . &quot;DROP meta_title_fr, &quot;
              . &quot;DROP meta_title_en&quot;;
  
          $returnSql = Db::getInstance()-&gt;execute($sqlInstall);
  
          return $returnSql;
      }
  
      public function hookDisplayAdminProductsCombinationBottom($params)
      {
          $combination = new Combination($params['id_product_attribute']);
          $this-&gt;context-&gt;smarty-&gt;assign(array(
                  'id_product_attribute' =&gt; $params['id_product_attribute'],
                  'meta_title_fr' =&gt; $combination-&gt;meta_title_fr,
                  'meta_title_en' =&gt; $combination-&gt;meta_title_en,
              )
          );
  
  
          return $this-&gt;display(__FILE__, 'views/templates/hook/combinationfields.tpl');
      }
  
  
      public function hookActionAttributeCombinationSave($params)
      {
          $combination = new Combination($params['id_product_attribute']);
          $this-&gt;context-&gt;smarty-&gt;assign(array(
                  'id_product_attribute' =&gt; $params['id_product_attribute'],
                  'meta_title_fr' =&gt; $combination-&gt;meta_title_fr,
                  'meta_title_en' =&gt; $combination-&gt;meta_title_en,
              )
          );
  
          $combination-&gt;meta_title_fr = Tools::getValue('meta_title_fr');
          $combination-&gt;meta_title_en = Tools::getValue('meta_title_en');
  
          $combination-&gt;save();
  
          return $this-&gt;display(__FILE__, 'views/templates/hook/combinationfields.tpl');
  
      }
  }
  </code></pre>
  <p><strong>My HTML for the admin hook:</strong></p>
  <pre class="lang-html prettyprint-override"><code>&lt;div class=&quot;m-b-1 m-t-1&quot;&gt;
      &lt;h2&gt;{l s='Combination Custom Fields' mod='combinationcustomfields'}&lt;/h2&gt;
      &lt;fieldset class=&quot;form-group&quot;&gt;
          &lt;div class=&quot;col-lg-12 col-xl-4&quot;&gt;
              &lt;label class=&quot;form-control-label&quot; for=&quot;combination_{$id_product_attribute}_attribute_meta_title_fr&quot;&gt;{l s='Meta title FR' mod='combinationcustomfields'}&lt;/label&gt;
              &lt;input class=&quot;form-control&quot; name=&quot;combination_{$id_product_attribute}[attribute_meta_title_fr]&quot; id=&quot;combination_{$id_product_attribute}_attribute_meta_title_fr&quot; type=&quot;text&quot; value=&quot;{if $meta_title_fr != ''}{$meta_title_fr}{/if}&quot;&gt;
              &lt;br /&gt;
          &lt;/div&gt;
          &lt;div class=&quot;col-lg-12 col-xl-4&quot;&gt;
              &lt;label class=&quot;form-control-label&quot; for=&quot;combination_{$id_product_attribute}_attribute_meta_title_en&quot;&gt;{l s='Meta title EN' mod='cmp_combination_customfields'}&lt;/label&gt;
              &lt;input class=&quot;form-control&quot; name=&quot;combination_{$id_product_attribute}[attribute_meta_title_en]&quot; id=&quot;combination_{$id_product_attribute}_attribute_meta_title_en&quot; type=&quot;text&quot; value=&quot;{if $meta_title_en != ''}{$meta_title_en}{/if}&quot;&gt;
              &lt;br /&gt;
          &lt;/div&gt;
      &lt;/fieldset&gt;
      &lt;div class=&quot;clearfix&quot;&gt;&lt;/div&gt;
  &lt;/div&gt;
  </code></pre>
  <p><strong>My override of the combination class:</strong></p>
  <pre class="lang-php prettyprint-override"><code>class Combination extends CombinationCore
  {
      public $meta_title_fr;
      public $meta_title_en;
      /**
       * @see ObjectModel::$definition
       */
      public static $definition = [
          'table' =&gt; 'product_attribute',
          'primary' =&gt; 'id_product_attribute',
          'fields' =&gt; [
              'id_product' =&gt; ['type' =&gt; self::TYPE_INT, 'shop' =&gt; 'both', 'validate' =&gt; 'isUnsignedId', 'required' =&gt; true],
              'location' =&gt; ['type' =&gt; self::TYPE_STRING, 'validate' =&gt; 'isGenericName', 'size' =&gt; 64],
              'ean13' =&gt; ['type' =&gt; self::TYPE_STRING, 'validate' =&gt; 'isEan13', 'size' =&gt; 13],
              'isbn' =&gt; ['type' =&gt; self::TYPE_STRING, 'validate' =&gt; 'isIsbn', 'size' =&gt; 32],
              'upc' =&gt; ['type' =&gt; self::TYPE_STRING, 'validate' =&gt; 'isUpc', 'size' =&gt; 12],
              'mpn' =&gt; ['type' =&gt; self::TYPE_STRING, 'validate' =&gt; 'isMpn', 'size' =&gt; 40],
              'quantity' =&gt; ['type' =&gt; self::TYPE_INT, 'validate' =&gt; 'isInt', 'size' =&gt; 10],
              'reference' =&gt; ['type' =&gt; self::TYPE_STRING, 'size' =&gt; 64],
              'supplier_reference' =&gt; ['type' =&gt; self::TYPE_STRING, 'size' =&gt; 64],
              'meta_title_fr' =&gt; ['type' =&gt; self::TYPE_STRING, 'size' =&gt; 64],
              'meta_title_en' =&gt; ['type' =&gt; self::TYPE_STRING, 'size' =&gt; 64],
  
              /* Shop fields */
              'wholesale_price' =&gt; ['type' =&gt; self::TYPE_FLOAT, 'shop' =&gt; true, 'validate' =&gt; 'isPrice', 'size' =&gt; 27],
              'price' =&gt; ['type' =&gt; self::TYPE_FLOAT, 'shop' =&gt; true, 'validate' =&gt; 'isNegativePrice', 'size' =&gt; 20],
              'ecotax' =&gt; ['type' =&gt; self::TYPE_FLOAT, 'shop' =&gt; true, 'validate' =&gt; 'isPrice', 'size' =&gt; 20],
              'weight' =&gt; ['type' =&gt; self::TYPE_FLOAT, 'shop' =&gt; true, 'validate' =&gt; 'isFloat'],
              'unit_price_impact' =&gt; ['type' =&gt; self::TYPE_FLOAT, 'shop' =&gt; true, 'validate' =&gt; 'isNegativePrice', 'size' =&gt; 20],
              'minimal_quantity' =&gt; ['type' =&gt; self::TYPE_INT, 'shop' =&gt; true, 'validate' =&gt; 'isUnsignedId', 'required' =&gt; true],
              'low_stock_threshold' =&gt; ['type' =&gt; self::TYPE_INT, 'shop' =&gt; true, 'allow_null' =&gt; true, 'validate' =&gt; 'isInt'],
              'low_stock_alert' =&gt; ['type' =&gt; self::TYPE_BOOL, 'shop' =&gt; true, 'validate' =&gt; 'isBool'],
              'default_on' =&gt; ['type' =&gt; self::TYPE_BOOL, 'allow_null' =&gt; true, 'shop' =&gt; true, 'validate' =&gt; 'isBool'],
              'available_date' =&gt; ['type' =&gt; self::TYPE_DATE, 'shop' =&gt; true, 'validate' =&gt; 'isDateFormat'],
          ],
      ];
  
  }
  </code></pre>
  <p>But when I save the product, the fields are in the request:</p>
  <p><a href="https://i.stack.imgur.com/DImQJ.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/DImQJ.png" alt="Fields" /></a></p>
  <p>But I have a 400 Error:</p>
  <p><a href="https://i.stack.imgur.com/Ex5w3.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/Ex5w3.png" alt="Error" /></a></p>
  <p>Any idea of my mistake here ?</p>
  <p>All the best and thanks in advance for you help :)</p>