Add field in product Prestashop 1.7
Asked Answered
S

2

5

Why is prestashop don't save my modification into database? Using prestashop 1.7

/override/classes/Product.php

class Product extends ProductCore {
public $por_gan; public function __construct ($idProduct = null, $idLang = null, $idShop = null) {
$definition = self::$definition;
$definition['fields']['por_gan'] = array('type' => self::TYPE_INT, 'required' => false);

parent::__construct($idProduct, $idLang, $idShop); } }

In ProductInformation.php

->add('por_gan', 'Symfony\Component\Form\Extension\Core\Type\NumberType', array(
        'required' => false,
        'label' => $this->translator->trans('Beneficio', [], 'Admin.Catalog.Feature'),
        'constraints' => array(
            new Assert\NotBlank(),
            new Assert\Type(array('type' => 'numeric'))
        ),          
    ))

In form.html.twing

<div class="col-md-6">
        <label class="form-control-label">% de beneficio</label
        {{ form_widget(form.step1.por_gan) }}
</div>

Thanks

Shunt answered 28/4, 2017 at 8:35 Comment(3)
Have you tried deleting the cached class files and re-indexing them?Grout
Prestashop 1.7 does not have cached class filesShunt
When i create class override in PS 1.7, i delete this cached class file : app/cache/dev/class_index.phpif you're in dev mode, otherwise : app/cache/prod/class_index.phpPomiculture
C
11

I’ve successfully added an extra tab in admin product page. It's working fine. I think a better approach would be to create a module in order to make that modification easier to maintain.

Or you can use displayAdminProductsExtra hook, actionProductUpdate hook and actionProductAdd

The extra field is : frais_a_prevoir

I show all the files to modify but you have to check where the modification should be done inside the file (make a search and you will find)

Override /classes/Product.php

In class /classes/Product.php, there are 3 modifications to do :

1)

/** @var string Frais à prévoir */
    public $frais_a_prevoir;

2)

'frais_a_prevoir' => array('type' => self::TYPE_HTML, 'lang' => true, 'validate' => 'isCleanHtml'),

3)

$sql->select(
            'p.*, product_shop.*, stock.out_of_stock, IFNULL(stock.quantity, 0) as quantity, pl.`description`, pl.`description_short`, pl.`frais_a_prevoir`, pl.`link_rewrite`, pl.`meta_description`,
            pl.`meta_keywords`, pl.`meta_title`, pl.`name`, pl.`available_now`, pl.`available_later`, image_shop.`id_image` id_image, il.`legend`, m.`name` AS manufacturer_name,
            (DATEDIFF(product_shop.`date_add`,
                DATE_SUB(
                    "'.$now.'",
                    INTERVAL '.$nb_days_new_product.' DAY
                )
            ) > 0) as new'
        );

In /src/PrestaShopBundle/Resources/views/Admin/Product/form.html.twig

<ul class="nav nav-tabs bordered">
                      <li id="tab_description_short" class="nav-item"><a href="#description_short" data-toggle="tab" class="nav-link description-tab active">{{ 'Summary'|trans({}, 'Admin.Catalog.Feature') }}</a></li>
                      <li id="tab_description" class="nav-item"><a href="#description" data-toggle="tab" class="nav-link description-tab">{{ 'Description'|trans({}, 'Admin.Global') }}</a></li>
                      <li id="tab_frais_a_prevoir" class="nav-item"><a href="#frais_a_prevoir" data-toggle="tab" class="nav-link description-tab">{{ 'frais_a_prevoir'|trans({}, 'Admin.Global') }}</a></li>
                    </ul>

                    <div class="tab-content bordered">
                      <div class="tab-pane panel panel-default active" id="description_short">
                        {{ form_widget(form.step1.description_short) }}
                      </div>
                      <div class="tab-pane panel panel-default " id="description">
                        {{ form_widget(form.step1.description) }}
                      </div>
                      <div class="tab-pane panel panel-default " id="frais_a_prevoir">
                        {{ form_widget(form.step1.frais_a_prevoir) }}
                      </div>
                    </div>

In /src/PrestaShopBundle/Form/Admin/Product/productInformation.php

->add('frais_a_prevoir', 'PrestaShopBundle\Form\Admin\Type\TranslateType', array(
                    'type' => 'Symfony\Component\Form\Extension\Core\Type\TextareaType',
                    'options' => [
                        'attr' => array('class' => 'autoload_rte'),
                        'required' => false
                    ],
                    'locales' => $this->locales,
                    'hideTabs' => true,
                    'label' => $this->translator->trans('frais_a_prevoir', [], 'Admin.Global'),
                    'required' => false
                ))

in src/PrestaShopBundle/Model/Product/AdminModelAdapter.php:

$this->translatableKeys = array(
            'name',
            'description',
            'description_short',
            'frais_a_prevoir',
            'link_rewrite',
            'meta_title',
            'meta_description',
            'available_now',
            'available_later',
            'tags',
        );

        //define unused key for manual binding
        $this->unmapKeys = array('name',
            'description',
            'description_short',
            'frais_a_prevoir',
            'images',
            'related_products',
            'categories',
            'suppliers',
            'display_options',
            'features',
            'specific_price',
            'virtual_product',
            'attachment_product',
        );

2)

'frais_a_prevoir' => $this->product->frais_a_prevoir,

In database, add a column frais_a_prevoir in table product_lang

Clubbable answered 1/7, 2017 at 14:10 Comment(18)
Great answer Sebastian. It should be marked as the correct one. Thanks for your help.Wilkins
@Sébastien I used actionProductUpdate hook in a module like in Presta 1.7 but it didn't work, I search for the hook in AdminProductController.php it is used only on the ajaxProcessProductQuantity method it's strangePapa
As for my question here #46728093 any help for a more abstract way if at least appreciatedFarming
Hey @Sébastien Gicquel, I have followed your guide but it seem can not save frais_a_prevoir to database.Mannose
@Mannose Sorry, my answer is almost 9 months old so I i find it hard to know what is not working for you but i’m sure it was working on my project. Are you sure you have followed all the steps ? It was working on a Prestashop 1.7.0.5Pomiculture
thanks @SébastienGicquel, I have tested. Your solution works with version 1.7.2Mannose
@Mannose Great ! I think we should do a module for that but didn’t have time to do it.Pomiculture
@SébastienGicquel I have used hook & override mechanisms instead, because of modifying Prestashop core makes me confused. Your solution raises that idea :-) thanks again.Mannose
@m0z4rt, could you please tell me if it is possible to override forms in /src/Prestashop? Any links pleaseNomination
hi @whitelettersinblankpapers, I guess that it is impossible to override any forms in /src/Prestashop, however to can use hook mechanism to extend functionality.Mannose
hi @m0z4rt, thank you for your reply. I am currently using hookDisplayAdminProductsMainStepLeftColumnBottom to render a Smarty template that contains the extra custom input field. But I feel it will be better to use Symfony workflow inside module in such situation, kind of adding the customFormType to formBuilder with validation rules, then adding the Form object , creating the View and sending it to a Twig template. Is such thing feasible in your opinion?Nomination
hi @whitelettersinblankpapers, sorry, I haven't tried your roadmap yet. I usually define hook template by myself.Mannose
@m0z4rt, me too I will stick to defining template by myself I have spent 2 days trying to do things the Symfony way but to no avail. Again thanks sir.Nomination
hi @Sébastien Gicquel, its working fine in the backend. But in frontend that new field is not available in the product object. can i do anything for frontend?Emlyn
@Emlyn It should work but my answer is almost 1 year old and I don't remember exactly what I've done. You need to use a twig variable in your tpl, like {$product.frais_a_prevoir nofilter}in product.tplPomiculture
Hi @Sébastien Gicquel, can you please give a sample to add a new field in product add/edit page using the hooks 'displayAdminProductsExtra hook', 'actionProductUpdate hook' and 'actionProductAdd'.Emlyn
@SébastienGicquel Thanks a lot, everything is working fine. I am on 1.7.4.4 though, and there are a few differences, especially with the localization of the file form.html.twig which is now at PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels (and you choose between options, essentials, etc.).Girt
@Girt Could you please let me know what other differences there are regarding 1.7.4.4? I have followed this precisely and the field shows up in product admin, and if I enter a value manually in the database it will show in that field, but when I save, it does not update.Unicycle
K
6

Here is an option to do this using module and does not change core files

in your MyModule.php

use PrestaShopBundle\Form\Admin\Type\TranslateType;
use PrestaShopBundle\Form\Admin\Type\FormattedTextareaType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\Extension\Core\Type\FormType;
public function hookDisplayAdminProductsExtra($params)
{
    $productAdapter = $this->get('prestashop.adapter.data_provider.product');
    $product = $productAdapter->getProduct($params['id_product']);

    $formData = [
       'ebay_reference' => $product->ebay_reference,
    ];
    $formFactory = $this->get('form.factory');
    $form = $formFactory->createBuilder(FormType::class, $formData)
        ->add('ebay_reference', TranslateType::class, array(
            'required' => false,
            'label' => 'Ebay reference',
            'locales' => Language::getLanguages(),
            'hideTabs' => true,
            'required' => false
        ))
    ->getForm()
    ;
    return $this->get('twig')->render(_PS_MODULE_DIR_.'MyModule/views/display-admin-products-extra.html.twig', [
        'form' => $form->createView()
    ]) ;

}
public function hookActionAdminProductsControllerSaveBefore($params)
{
    $productAdapter = $this->get('prestashop.adapter.data_provider.product');
    $product = $productAdapter->getProduct($_REQUEST['form']['id_product']);
    foreach(Language::getLanguages() as $language){
        $product->ebay_reference[ $language['id_lang'] ] = 
            $_REQUEST['form']['ebay_reference'][$language['id_lang']];
    }
    $product->save();

}

in your display-admin-products-extra.html.twig

<div class="row" >
    <div class="col-md-12">
        <div class="form-group">
            <h3>Ebay reference</h3>
            {{ form_errors(form.ebay_reference) }}
            {{ form_widget(form.ebay_reference) }}
        </div>
    </div>
</div>
Kickapoo answered 15/11, 2018 at 13:9 Comment(3)
There is a duplicate array key 'required' into your form builder array. And this 2 classes seems not used in your sample: PrestaShopBundle\Form\Admin\Type\FormattedTextareaType; Symfony\Component\Form\Extension\Core\Type\TextareaType;Sporulate
Hi, I am unable to save product.Prosciutto
When you save the product or submit the form you generate, Prestashop returns an error: "product: The CSRF token is invalid. Please try to resubmit the form"Balcom

© 2022 - 2024 — McMap. All rights reserved.