What I did wrong with Db::getInstance()->insert('product', $dimension)); not inserting data to database? - prestashop

I am developing a module that would save a custom field from product admin.. but my code is not inserting data into database.. below is my code.
public function hookActionProductUpdate($params)
{
if(Tools::isSubmit('submitDimension'))
{
$name = Tools::getValue('name');
$length = Tools::getValue('custom_length');
$width = Tools::getValue('custom_width');
if(empty($name) || !Validate::isGenericName($name))
$this->errors[] = $this->module->l('Invalid name');
if(empty($length) || !Validate::isGenericName($length))
$this->errors[] = $this->module->l('Invalid length');
if(empty($width) || !Validate::isGenericName($width))
$this->errors[] = $this->module->l('Invalid width');
if(!$this->errors)
{
$dimension = array(
'name' => $name,
'custom_length' => $length,
'custom_width' => $width
);
if(!Db::getInstance()->insert('product', $dimension));
$this->errors[] = Tools::displayError('Error while updating database');
}
}
}
Anyone can help me please..
Here is my install function
function install()
{
if (!parent::install() ||
!$this->alterProductTable() ||
!$this->registerHook('extraright') ||
!$this->registerHook('displayAdminProductsExtra') ||
!$this->registerHook('actionProductSave') ||
!$this->registerHook('actionProductUpdate') ||
!$this->registerHook('header')
)
return false;
return true;
}
Here is my alter table function
private function alterProductTable($method = 'add')
{
if($method = 'add')
$sql = '
ALTER TABLE '._DB_PREFIX_.'product
ADD COLUMN `custom_length` decimal(20,6) NOT NULL,
ADD COLUMN `custom_width` decimal(20,6) NOT NULL,
ADD COLUMN `name` VARCHAR(64) NOT NULL';
if(!Db::getInstance()->Execute($sql))
return false;
return true;
}
.. the columns are there..
And here is my display admin hook
public function hookDisplayAdminProductsExtra($params)
{
$name = Db::getInstance()->getValue('SELECT `name` FROM '._DB_PREFIX_.'product WHERE id_product = '.Tools::getValue('id_product'));
$length = Db::getInstance()->getValue('SELECT custom_length FROM '._DB_PREFIX_.'product WHERE id_product = '.(int)Tools::getValue('id_product'));
$width = Db::getInstance()->getValue('SELECT custom_width FROM '._DB_PREFIX_.'product WHERE id_product = '.(int)Tools::getValue('id_product'));
$this->context->smarty->assign(array(
'name' => $name,
'length' => $length,
'width' => $width
));
return $this->display(__FILE__, 'views/templates/hook/adminProductsExtra.tpl');
}
I have been looking at this for 2 days.. and I cant seem to find what I did wrong.. I have gone to prestashop forum but no help so far.. I hope I can get something from good people here. thanks in advance!

Do you check the Prestashop db best practice guide if not than please check first.
This is not the correct way to insert data you also need to mention fields in which you want to insert data particular table.
Best Practices of the Db Class - Prestashop

All is wrong, you are trying to insert data in a table which have many other fields required, and you are trying also to insert data in columns that doesn't exist in that table. The best way to create new products by code is using their object, like this...
$product = new Product()
$product->id_tax_rules_group = 1;
$product->redirect_type = '404';
$product->name = array(
$id_lang => 'Product name in this lang',
$id_lang => 'Product name in this lang',
);
/*
* And so on all the mandatory fields
*/
$product->save();

Related

Implement Phalcon 4 Database Existence validator (similar to Uniqueness)

Often I need to validate if given value is existing in certain column (attribute) of a table (model).
This can be useful in foreign keys of a model, to check if the given values exists.
Most probably the validation logic can be mostly the same as for Uniqueness, except the comparison here can be something like > 0.
A possible usage scenario could be like below:
$validator->add(
'organization_id',
new ExistenceOnDbValidator(
[
'model' => Organization::class,
'expr'=> ' id = %s ',
'excludeNullValue'=> true,
'message' => 'Organization does not exist.',
]
)
);
Finally I implemented myself a validator called ExistenceOnDbValidator and it works fine.
Usage
$validator = new Validation();
$validator->add(
'organization_id',
new ExistenceOnDbValidator(
[
'model' => Organization::class,
'expr' => ' id = %s ',
'ignoreNullValue' => false,
'message' => 'Selected organization does not exist.',
]
)
);
Implenentation
use Phalcon\Messages\Message;
use Phalcon\Validation;
use Phalcon\Validation\AbstractValidator;
use Phalcon\Validation\ValidatorInterface;
class ExistenceOnDb extends AbstractValidator implements ValidatorInterface
{
public function validate(Validation $validator, $attribute): bool
{
$expr = $this->getOption('expr');
$model = $this->getOption('model');
$value = $validator->getValue($attribute);
$ignoreNullValue = true;
if ($this->hasOption('ignoreNullValue')) {
$ignoreNullValue = $this->getOption('ignoreNullValue');
}
if ((is_null($value) || empty($value)) && $ignoreNullValue == true) {
return true;
}
$expr = sprintf(
$expr,
$value,
);
$result = $model::findFirst($expr);
if ((is_null($result) || empty($result))) {
$message = $this->getOption('message');
$validator->appendMessage(new Message($message));
return false;
}
return true;
}
}

get values between two dates in silverstripe

i have added two date fields. i want to retrieve the data between those two table.PaymentDate and ChequePostedDate are two fields. so i need to get the rows between two dates.
simply search content have two date fields. i want to retrieve the rows(data) between those two dates
public function __construct($modelClass, $fields = null, $filters = null) {
$fields = new FieldList(array(
DateField::create('PaymentDate','Payment Date : from')
->setConfig('dateformat', 'yyyy-MM-dd')
->setConfig('showcalendar', true)
->setAttribute('placeholder','YYYY-MM-DD')
->setDescription(sprintf(
_t('FormField.Example', 'e.g. %s', 'Example format'),
Convert::raw2xml(Zend_Date::now()->toString('yyyy-MM-dd'))
)),
DateField::create('ChequePostedDate','cr Date : to')
->setConfig('dateformat', 'yyyy-MM-dd')
->setConfig('showcalendar', true)
->setAttribute('placeholder','YYYY-MM-DD')
->setDescription(sprintf(
_t('FormField.Example', 'e.g. %s', 'Example format'),
Convert::raw2xml(Zend_Date::now()->toString('yyyy-MM-dd'))
)),
));
$filters = array(
'PaymentDate' => new PartialMatchFilter('PaymentDate'),
'ChequePostedDate' => new PartialMatchFilter('ChequePostedDate'),
);
parent::__construct($modelClass, $fields, $filters);
}
public function getQuery($searchParams, $sort = false, $limit = false, $existingQuery = null) {
$dataList = parent::getQuery($searchParams, $sort, $limit, $existingQuery);
$params = is_object($searchParams) ? $searchParams->getVars() : $searchParams;
$query = $dataList->dataQuery();
if(!is_object($searchParams)) {
if (isset($params['PaymentDate'])&& $params['ChequePostedDate'] ) {
$query->where('`PaymentNote`.PaymentDate BETWEEN \''.$params['PaymentDate'].' \' AND \''.$params['ChequePostedDate'].'\'');
}
}
return $dataList->setDataQuery($query);
}
}
You can also use WithinRangeFilter something like the following, but you need to use the setMin(), setMax() methods as per this forum response: https://www.silverstripe.org/community/forums/form-questions/show/11685
public function getQuery($searchParams, $sort = false, $limit = false, $existingQuery = null) {
$dataList = parent::getQuery($searchParams, $sort, $limit, $existingQuery);
$params = is_object($searchParams) ? $searchParams->getVars() : $searchParams;
$query = $dataList->dataQuery();
if(!is_object($searchParams)) {
if (!empty($params['PaymentDate'] && !empty($params['ChequePostedDate'])) {
return $dataList->filter('PaymentDate:WithinRange', [$params['PaymentDate'], $params['ChequePostedDate']]);
}
}
return $dataList;
}
i solved it..
simply remove $filters
$filters = array(
// 'PaymentDate' => new PartialMatchFilter('PaymentDate'),
//'ChequePostedDate' => new PartialMatchFilter('ChequePostedDate'),
);
then it works

Can't create product variant through API

Cant seem to create new product variant using shopify api.
This is my code:
global $shopifyClient;
$config['shopify_api_product_price'] = "/admin/products/128671451/variants.json";
$variant = array
(
'variant' => array ('price' => '3.00', 'option1' => 'test')
);
if( $shopifyClient == null )
return;
try{
$postVariant = $shopifyClient->call('POST', $config['shopify_api_product_price'], $variant);
return $postVariant;
}catch( ShopifyApiException $e ){
$e->getMessage();
}
return false;
Thanks in advance!

Magento API, Return Orders with NULL values

Using the magento api version 1 and soap.
Need to return all orders with 'coupon_code'=> NULL
The call I'm attempting:
$order_listAR = $proxy->call($sessionId, 'sales_order.list', array(array('coupon_code'=>array('null'=>'null'))));
The ouput I want returned is this:
array(237) {
["state"]=>
string(8) "complete"
["status"]=>
string(8) "complete"
["coupon_code"]=> NULL
So far this seems to work properly, but I'm not sure if ('null'=>'null') is the proper way to find NULL values in the array. Can someone explain why this works, and, or if this is the correct syntax? I don't have any margin for error on this.
Yes, the syntax you use is correct to filter against null.
array(
'coupon_code' => array(
'null' => 'this_value_doesnt_matter'
)
)
Magento maps* the API method sales_order.list to Mage_Sales_Model_Order_Api::items().
public function items($filters = null)
{
:
$collection = Mage::getModel("sales/order")->getCollection()
:
if (is_array($filters)) {
try {
foreach ($filters as $field => $value) {
if (isset($this->_attributesMap['order'][$field])) {
$field = $this->_attributesMap['order'][$field];
}
$collection->addFieldToFilter($field, $value);
}
} catch (Mage_Core_Exception $e) {
$this->_fault('filters_invalid', $e->getMessage());
}
}
:
}
The items() method uses a Mage_Sales_Model_Resource_Order_Collection to fetch the orders for the API call. That collection is based on Varien_Data_Collection_Db, so
$collection->addFieldToFilter($field, $value)
from above essentially does call
Varien_Data_Collection_Db::addFieldToFilter()
If you follow the latter, you'll hit Varien_Db_Adapter_Pdo_Mysql::prepareSqlCondition() in the end, params being
$fieldName = 'coupon_code'
$condition = array('null' => 'null')
Excerpt of that method:
public function prepareSqlCondition($fieldName, $condition)
{
$conditionKeyMap = array(
'eq' => "{{fieldName}} = ?",
:
'notnull' => "{{fieldName}} IS NOT NULL",
'null' => "{{fieldName}} IS NULL",
:
'sneq' => null
);
:
$query = '';
if (is_array($condition)) {
:
$key = key(array_intersect_key($condition, $conditionKeyMap));
if (isset($condition['from']) || isset($condition['to'])) {
:
} elseif (array_key_exists($key, $conditionKeyMap)) {
$value = $condition[$key];
if (($key == 'seq') || ($key == 'sneq')) {
:
}
$query = $this->_prepareQuotedSqlCondition($conditionKeyMap[$key], $value, $fieldName);
} else {
:
}
}
:
}
In your case _prepareQuotedSqlCondition() will be called with
$text = '{{fieldName}} IS NULL'
$value = 'null'
$fieldName = 'coupon_code'
which will result in $query = 'coupon_code IS NULL'.
If you take a closer look at the conversion method
protected function _prepareQuotedSqlCondition($text, $value, $fieldName)
{
$sql = $this->quoteInto($text, $value);
$sql = str_replace('{{fieldName}}', $fieldName, $sql);
return $sql;
}
you'll also see, why the value of the 'null' => 'null' key/value pair does not matter at all. That's because $text will be '{{fieldName}} IS NULL', i.e. not containing any binding ?.
Hence, there's nothing to replace for _quoteInto()^^
* see app/code/core/Mage/Sales/etc/api.xml

codeigniter pagination for a query

So far found plenty of help to get the pagination working for a get(table) command.
What I need is to pick only few of the entries from a couple of linked tables based on a sql where statement.
I guess the query command is the one to use but in this case how do I do the pagination since that command does not take extra parameters such $config['per_page']
Thanks for the help
Without any more info to go on I think that what you're looking for is something like the following.
public function pagination_example($account_id)
{
$params = $this->uri->ruri_to_assoc(3, array('page'));
$where = array(
'account_id' => $account_id,
'active' => 1
);
$limit = array(
'limit' => 10,
'offset' => (!empty($params['page'])) ? $params['page'] : 0
);
$this->load->model('pagination_model');
$data['my_data'] = $this->pagination_model->get_my_data($where, $limit);
foreach($this->uri->segment_array() as $key => $segment)
{
if($segment == 'page')
{
$segment_id = $key + 1;
}
}
if(isset($segment_id))
{
$config['uri_segment'] = $segment_id;
}
else
{
$config['uri_segment'] = 0;
}
$config['base_url'] = 'http://'.$_SERVER['HTTP_HOST'].'/controller_name/method_name/whatever_your_other_parameters_are/page/';
$config['total_rows'] = $this->pagination_model->get_num_total_rows();// Make a method that will figure out the total number
$config['per_page'] = '10';
$this->load->library('pagination');
$this->pagination->initialize($config);
$data['pagination'] = $this->pagination->create_links();
$this->load->view('pagination_example_view', $data);
}
// pagination_model
public function get_my_data($where = array(), $limit = array())
{
$this->db
->select('whatever')
->from('wherever')
->where($where)
->limit($limit['limit'], $limit['offset']);
$query = $this->db->get();
if($query->num_rows() > 0)
{
$data = $query->result_array();
return $data;
}
return FALSE;
}
This should at least get you on the right track
If this isn't what you're asking I'd happy to help more if you can be a little more specific. How about some of your code.
The only other options that I can think of would be to either code a count in your select statement or not limit the query and use array_slice to select a portion of the returned array.