I am creating a script for PrestaShop 1.6 that inserts data into a table.
My table is made in this way:
id: int AUTO INCREMENT
desc: string
As I enter a description I would get back the ID value.
On can not use the standard because it blocked by PrestaShop.
I find this a situation:
$sql = "INSERT INTO `"._DB_PREFIX_."table`(`desc`) VALUES ('".$this->desc."')";
$restpo = Db::getInstance()->execute($sql);
var_dump($restpo);
But I have an answer only a boolean.
Can you suggest something?
You can use the:
$id = (int)Db::getInstance()->Insert_ID();
For example, in the Cart class:
$last_id = (int)Db::getInstance()->Insert_ID();
I also recommend the use of the function insert, for example in the Carrier class:
$values = array();
foreach ($shops as $id_shop) {
$values[] = array(
'id_carrier' => (int)$this->id,
'id_tax_rules_group' => (int)$id_tax_rules_group,
'id_shop' => (int)$id_shop,
);
}
$res = Db::getInstance()->insert('carrier_tax_rules_group_shop', $values);
Then use the Insert_ID to get the last one.
Use $id = Db::getInstance()->Insert_ID(); after executing your SQL.
PrestaShop's DB class provides the last inserted id via
Db::getInstance()->Insert_ID();
method.
Related
Not sure how to title this properly but here's the issue I am running into currently. I built a cart and checkout system and it loads all the data into a database when it finalized the order. To save some space, I stored just the item IDs originally but then I ran into the issue of if I deleted the item from the database (because it was discontinued or whatever) then it wouldn't return the info I needed. And if they ordered more then 1 item the database record would be wrong. So I stored the data like so:
Itemid:Quantity:Price:name, itemid2:quantity2:price2:name2
OR
1:3:20.00:Flower Hat, 2:1:17.75:diamonds
The issue I have right now that I need help with is this. I need to seperate the four values into variables like $price, $item, $id, $ammount so I can display them on the order history page and I need to loop through all items on the array so I can print a row for each item with all four fields respective to that item.
I use strpos already to get the shipping info from the same database field which is formatted as METHOD:Price but since I have 3 :'s on my string I'm not sure how to go through each one. Thanks.
Here's a function
function parseItems($dbjunk){
$cart = array();
$items = explode(",",$dbjunk);
foreach($items as $i){
$chunks = explode(":", $i);
$cart[] = array(
"ItemID" => $chunks[0] ,
"Quantity" => $chunks[1] ,
"Price" => $chunks[2] ,
"name" => $chunks[3]
);
}
return $cart;
}
Example usage:
$dbjunk = "Itemid:Quantity:Price:name, itemid2:quantity2:price2:name2";
$parsed = parseItems($dbjunk);
print_r($parsed);
See: https://3v4l.org/rBkXF
If you need variables instead of an array you can use list(), like this..
$dbjunk = "Itemid:Quantity:Price:name, itemid2:quantity2:price2:name2";
$parsed = parseItems($dbjunk);
foreach($parsed as $p){
list($itemID, $Quantity, $Price, $name) = array_values($p);
var_dump($itemID, $Quantity, $Price, $name);
}
see: https://3v4l.org/l4vsn
You should not physically delete items from your database. Instead, put a new column named 'is_active' or something like that to indicate whether the product is active/non-deleted.
Answering your question, here is my suggestion:
$orderString = '1:3:20.00:Flower Hat, 2:1:17.75:diamonds';
$items = array();
foreach(explode(', ', $orderString) as $itemString) {
$itemData = explode(':', $itemString);
$items[] = array(
'id' => $itemData[0],
'amount' => $itemData[1],
'value' => $itemData[2],
'description' => $itemData[3]
);
}
with this code, you will obtain an array with the data of all the items in the string, no matter how much items are in the string
try something like
$data = 1:3:20.00:Flower Hat, 2:1:17.75:diamonds
list($price, $item, $uid, $id, $ammount) = explode(":", $data);
echo $user;
echo $item;
Read about First Normal Form. Basically, you want to store one value in one field. So, instead of this:
shipping = "method:price"
You want something like this:
shipping_method = "method"
shipping_price = "price"
Don't concern yourself with space -- it's essentially free nowadays.
Regarding your deleted items dilemma, your initial implementation was the way to go:
I stored just the item IDs originally
In addition to reverting to this technique, I would recommend two things:
Add a boolean field to your item table to represent if the item is currently available or not. This gives you the additional feature of being able to toggle items on/off without having to delete/insert records and change ids.
Before deleting an item, check to see if it's ever been ordered. If not, it's ok to delete. If so, instead just deactivate it.
I have a view with a form to input a percentage of discount/rise and apply it to a list of products stored in a table of a database, here is the code of the controller which I explain below:
$rise = 1+$this->input->post('rise')/100;
$this->db->where('client',$this->session->userdata('id_client'));
$query = $this->db->get('products');
foreach ($query->result() as $row){
$price = array(
'price' => $row->price*$rise
);
$this->db->where('id',$row->id);
$this->db->update('products',$price);
}
redirect('site/select_client');
First set the rise, then get from the products table all the ones that correspond to the client that we are working on (stored as session variable), an for each one set the array to update and update in for the product that has the corresponding id. (the table has the columns id, client, name and price). After that it should redirect to another controller.
It shows no error but no changes are made on the database.
I modified your code, please use this and check. it will work correctly.
$rise = $this->input->post('rise')/100;
$this->db->where('client',$this->session->userdata('id_client'));
$query = $this->db->get('products');
foreach ($query->result() as $row){
$price=$row->price + ($row->price * $rise);
$price = array(
'price' => $price
);
$this->db->where('id',$row->id);
$this->db->update('products',$price);
}
I need to insert some values to custom database table based on the values of changed custom field, if the specific custom field value (in a custom shipping method) had changed.I need to check this in my Observer.php event that I'm firing is admin_system_config_changed_section_carriers for getting values from the field and insert values to the table
is there any possible way to do this ?
EDIT:
here is my observer function
public function handle_adminSystemConfigChangedSection($observer){
$post = Mage::app()->getRequest()->getPost();
$firstBarcodeFlatrate = $post['groups']['flatrate']['fields']['barcode_start']['value'];
$lastBarcodeFlatrate = $post['groups']['flatrate']['fields']['barcode_end']['value'];
$flatrateRange = range($firstBarcodeFlatrate,$lastBarcodeFlatrate);
$shippingMethod = 'flatrate';
foreach($flatrateRange as $barcodes){
$insertData = array(
'barcode' => $barcodes,'shipping_method' => $shippingMethod,'status' => 1,
);
$model = Mage::getModel('customshippingmethods/customshippingmethods')->setData($insertData);
try {
$model->save();
} catch (Exception $e){
echo $e->getMessage();
}
}
as you can see above database query will update each time I save the configuration but I just need to run the query iff $firstBarcodeFlatrate value had changed
I would probably go with two options:
1. Cache the last value of $firstBarcodeFlatrate
$cacheId = 'first_barcode_flatrate_last_value';
$cache = Mage::app()->getCache();
$lastValue = $cache->load($cacheId);
if (!$lastValue) {
//We don't have cached last value, we need to run the query and cache it:
//Cache the value:
$cache->save($firstBarcodeFlatrate, $cacheId, array('first_barcode_flatrate_last_value'), null);
//Run the query here
} else {
//We have last value, we need to check if it has been changed:
if($lastValue != $firstBarcodeFlatrate) {
//Update the cached value:
$cache->save($firstBarcodeFlatrate, $cacheId, array('first_barcode_flatrate_last_value'), null);
//Run the query here.
}
}
Option 2 is to create another table with a single row and two fields or add another system config field that will store the last used value. Then before the running the query, you will check this value if it's different than $firstBarcodeFlatrate you will run the query, otherwise you won't, though I think the caching will do the job for you.
I am trying to create an overview of product properties, for an invoice system.
So far, most things are comming together using classes and PDO.
I have the following issue.
In my class, i've created a function that builds my products array.
It loads some information from the database, to build this array.
This array, i want to use to display all the products i have selected:
$prod1 - $prod1Name - $prod1Descr - $prod1Price
$prod2 - $prod2name - $prod2Descr - $prod2Price
etc.
I figured that the Associative array would help me creating columns.
Though the problem is, that i do not understand a bit how to create multiple lines and columns this way.
I was thinking of something like:
$prod[1]["name"] - $prod[1]["descr"] - etc
Then to use this in a foreach loop to create as many new lines as required.
The only thing i could come up with is on my index.php (as shown below), cause using an index (the [1] defenition) does not seem to work the way i think it should be implemented.
For my understanding, i assigend the var in my class as an array, then redefine an array when loading the database information.
Could anyone tell me how i could try to solve this issue?
I have the following class:
<?
class Invoice{
var $vendorID;
var $product = array();
function product_array(){
global $db;
$query = $db->conn->prepare('
SELECT ProductName, ProductDescription, ProductDuration, ProductPriceInclVat, ProductPriceExclVat, ProductVatType
FROM products WHERE VendorID = :VendorID
');
$array = array (
'VendorID' => $this->vendorID
);
$query->execute($array);
$result = $query->fetchall();
if (empty($result)){
echo"Could not find any products matching your criteria.";
die;
} else {
foreach($result as $row) {
$this->product = array("Name" => $row['ProductName'],
"Description" => $row['ProductDescription'],
"Duration" => $row['ProductDuration'],
"PriceExclVat" => $row['ProductPriceExclVat'],
"PriceInclVat" => $row['ProductPriceInclVat'],
"VatType" => $row['ProductVatType']
);
}
}
}
}
?>
and then i have the following code on my index.php:
<?
$invoice = new Invoice();
foreach ($invoice->product as $key => $value){
echo $key . "<br>";
echo $value . "$value";
echo "<br>";
}
?>
When you are assigning the result arrays to the product property you are overwriting the array every time. You need to append to the array instead, so something like:
$this->product = array();
foreach($result as $row) {
$this->product[] = array(...);
}
Alternatively, you could just assign the results of fetchAll to the product property if you don't need to rename the field keys (or you could alias them in the SQL).
$query = $db->conn->prepare('
SELECT ProductName as Name,
ProductDescription as Description,
ProductDuration as Duration,
ProductPriceInclVat as PriceInclVat,
ProductPriceExclVat as PriceExclVat,
ProductVatType as VatType
FROM products WHERE VendorID = :VendorID
');
$array = array (
'VendorID' => $this->vendorID
);
$query->execute($array);
$product = $query->fetchall(PDO::FETCH_ASSOC);
The $product is now in the format you require.
After this you can avoid foreach loop in class invoice.
Other thing i noticed that you have made function product_array() which is not called,
so in index.php you are getting empty array (defined in class Invoice).
So in Invoice class it should be
$product = product_array()
and product_array function should return the value.
I am adding data to three tables, I needed to get the last ID of the first table to use in the second table, which was successful with $this->db->insert_id() function, Trying that with the second table still gives me the ID of the first table. The arrangement of my code is:
function addcrm() {
//Post data collection array from the webform form
$customerdata = array(
"salutation"=>$this->input->post('salutation'),
"mobilenumber"=>$this->input->post('mobilenumber'),
"emailaddress"=>$this->input->post('emailaddress')
);
$this->db->insert('api_customer', $customerdata);
$customer=$this->db->insert_id();
$leaddata = array(
"fieldrep"=>$this->input->post('fieldrep'),
"fk_customerID"=>$customer,
"te"=>$this->input->post('takage'),
"othercost"=>$this->input->post('othercost')
);
$this->db->insert('api_lead', $leaddata);
$leadID = $this->db->insert_id();
for ($i =0; $i<count($_POST['w_product']); $i++){
$productdata = array(
"name" => $_POST['w_product'][$i],
"type" => $_POST['w_type'][$i],
"cost" => $_POST['w_cost'][$i],
"fk_leadID"=> $leadID
);
$this->db->insert('api_prod',$productdata);
}
$url = base_url('cXXXXXXXXXXXXXX);
redirect($url);
}
You are missing something obviously in the second call. ;)
$customer = $this->db->insert_id();
$leadIdD = $this->db->insert_id;
See? :)
Try working with the following methods:
$this->db->start_cache(); // Before query
$this->db->stop_cache(); // After query
$this->db->flush_cache(); // Clear query
This way you make clear and flushed queries.
if you are using an auto increment table you may try using MYSQL_LAST_INSERT_ID();
http://dev.mysql.com/doc/refman/5.0/en/information-functions.html