I have a query which gives me a tuple of a discount added into database.
Here's the query
$discount_info = $this->autoload_model->get_data_from_table("td_discount,td_userdiscount","*",
"td_discount.discount_id = td_userdiscount.discount_id
AND td_discount.discount_code = '$coupon'")->result_array();
Now i have script which does the specific function.
There will be a condition, if the value of a index will be 1, then the code snippet is like this
if($discount_info[0]['discount_on']=="3")
{
$discount_product = $discount_info[0]['discount_product']; // its an id(autoincrement value)//
if($discount_info[0]['applicable_type']==1)
{
$item_info = $this->autoload_model->get_data_From_table("td_product","*","product_id = '$discount_product'")->result_array();
foreach($this->cart->contents() as $ci)
{
if($ci['name'] = $item_info[0]['product_name']
{
// get the cart_item with the highest price if the product name matches//
}
}
}
}
My cart structure is like this
$data = array(
'id' => $id,
'qty' => $qty,
'price' => $price,
'name' => $name,
'options' => array(
'picture'=>$img,
'item_slug'=>$slug,
'item_color'=>$color,
'item_size'=>$size,
'unit_price'=>$price,
'order_type'=>$order_type,
'product_type'=>$pro_type,
'unit_discount' => 0.00,
'item_discount' => 0.00,
'discount_type' => '',
)
);
Now, its all set up, but I just can't get the login which I shall put over here
// get the cart_item with the highest price if the product name
I imagine you could just define a
$highest = array('price' => 0);
before the loop and then inside the loop go:
// get the cart_item with the highest price if the product name matches//
if ($ci['price'] > $highest['price']) {
$highest = $ci;
}
That way $highest would contain the best match at the end.
Related
I'm looking to add a Phone number field to the Woocommerce settings page. I can get the field to add to the settings list, but it gets appended to the bottom of the entire tab. Ideally I'd like to add the field in the Store Address sections on the general tab.
Here's what I'm using now (trimmed down):
add_filter('woocommerce_general_settings', 'woocommerce_add_phone');
function woocommerce_add_phone($settings) {
$settings[] = array(
'title' => 'Phone Number',
'type' => 'text',
);
$sections[] = array( 'type' => 'sectionend', 'id' => 'store_address' );
return $settings;
}
I made an attempt at using array_splice but couldn't get anywhere with it.
Any advice would be greatly appreciated.
This can be done in a simple way targeting the woocommerce_store_postcode field ID to insert the Store phone custom field in this general settings at the right location:
add_filter('woocommerce_general_settings', 'general_settings_shop_phone');
function general_settings_shop_phone($settings) {
$key = 0;
foreach( $settings as $values ){
$new_settings[$key] = $values;
$key++;
// Inserting array just after the post code in "Store Address" section
if($values['id'] == 'woocommerce_store_postcode'){
$new_settings[$key] = array(
'title' => __('Phone Number'),
'desc' => __('Optional phone number of your business office'),
'id' => 'woocommerce_store_phone', // <= The field ID (important)
'default' => '',
'type' => 'text',
'desc_tip' => true, // or false
);
$key++;
}
}
return $new_settings;
}
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
Tested and work… You will get something like:
LoicTheAztec code works fine but I wanted to find a solution without looping. Here is my version:
function add_phone_number_settings($settings) {
// Search array for the id you want
$key = array_search('woocommerce_store_postcode', array_column($settings, 'id')) + 1;
$custom_setting[] = array(
'title' => __('Phone Number'),
'desc' => __("Enter shop phone number"),
'id' => 'woocommerce_store_phone_number',
'default' => '',
'type' => 'text',
'desc_tip' => true,
);
// Merge with existing settings at the specified index
$new_settings = array_merge(array_slice($settings, 0, $key), $custom_setting, array_slice($settings, $key));
return $new_settings;
}
add_filter('woocommerce_general_settings', 'add_phone_number_settings');
This code will add your phone number after the post code element in the Store Address section. I borrowed the splice function from here.
add_filter('woocommerce_general_settings', 'woocommerce_general_settings_add_phone_number');
function woocommerce_general_settings_add_phone_number($settings) {
$phone_number = array(
'title' => __( 'Phone Number', 'woocommerce' ),
'desc' => __( 'Add your phone number.', 'woocommerce' ),
'id' => 'woocommerce_store_phone_number',
'default' => '',
'type' => 'text',
'desc_tip' => false,
);
$array_pos = 0;
foreach ($settings as $key => $value) {
if ( $value['id'] == 'woocommerce_store_postcode' ) {
$array_pos = $key;
break;
}
}
$settings = array_insert( $settings, $phone_number, $array_pos + 1 );
return $settings;
}
/*
Array insert
#array the array to add an element to
#element the element to add to the array
#position the position in the array to add the element
*/
if(!function_exists('array_insert')) {
function array_insert($array, $element, $position) {
// if the array is empty just add the element to it
if(empty($array)) {
$array[] = $element;
// if the position is a negative number
} elseif(is_numeric($position) && $position < 0) {
// if negative position after count
if(count($array) + $position < 0) {
$position = 0;
} else {
$position = count($array) + $position;
}
// try again with a positive position
$array = array_insert($array, $element, $position);
// if array position already set
} elseif(isset($array[$position])) {
// split array into two parts
$split1 = array_slice($array, 0, $position, true);
$split2 = array_slice($array, $position, null, true);
// add new array element at between two parts
$array = array_merge($split1, array($position => $element), $split2);
// if position not set add to end of array
} elseif(is_null($position)) {
$array[] = $element;
// if the position is not set
} elseif(!isset($array[$position])) {
$array[$position] = $element;
}
// clean up indexes
$array = array_values($array);
return $array;
}
}
I have three colums which has same values for two of the rows. I want to print only one of a same row out of the two same rows using a php while loop statement. This is how the data is
ID values
1 MINI
1 MINI
2 MINI
I want to print all of these but only once with same rows based on the ID
ID Values
1 MINI
2 MINI
I can actually use DISTINCT OR GROUP BY in mysql query to find the expected answer above but I really need to use a php while statement.
This is what I have been trying my hands on
$query="SELECT * from table";
$sR=$db->query($query);
$array=array();
while($sRow=mysqli_fetch_assoc($sR)){
$ID=$searchRow['ID'];
$values=$searchRow['Values'];
$array[$ID][]=$ID;
$array2[$ID][]=$values;
}
foreach($array as $ID => $item){
$value=$array[$ID];
foreach($item as $newItem){
if($newItem===$newItem){
echo '---'.$newItem;
break;
}
}
}
This is what I am trying hands on but it doesn't seem to work as expected, I would need help on it. Thanks soo much.
When I do things like this I use a "Previous ID"-variable, in this case $PRID, to check if the ID is a duplicate. The SQL query has to be ordered by ID to make this work.
$query="SELECT * FROM table ORDER BY ID";
$sR=$db->query($query);
$array=array();
$PRID=0;
while($sRow=mysqli_fetch_assoc($sR)){
$ID=$searchRow['ID'];
$values=$searchRow['Values'];
if($ID>$PRID){
$array[$ID][]=$ID;
$array2[$ID][]=$values;
}
$PRID=$ID;
}
foreach($array as $ID => $item){
$value=$array[$ID];
foreach($item as $newItem){
if($newItem===$newItem){
echo '---'.$newItem;
break;
}
}
}
just try option 1 or option 2
$query="SELECT * FROM table ORDER BY ID";
$sR=$db->query($query);
$array = array();
// first option, expected output
// array(
// 0 => 'value',
// 1 => 'value'
// )
foreach($sR as $value) {
$array[$value['ID']] = $value['Values'];
}
var_dump($array);
$array2 = array();
// second option
foreach($sR as $value) {
$array2[$value['ID']] = array(
'ID' => $value['ID'],
'Value' => $value['Value']
);
}
var_dump($array2);
// expected output
// array(
// 0 => array(
// 'ID' => 0,
// 'Value' => 'value'
// ),
// 1 => array(
// 'ID' => 1,
// 'Value' => 'value'
// )
// )
first let me explain what I am trying to achieve:
I've got an array of user items, consisting of an ID(item_id) and quantity(e.g. 10 items)
If a user purchases an item, it's added to the array including the quantity.
If a user purchases an (in the array) existing item, '1' is added to the quantity.
I got really close with the help of this post: Checking if array value exists in a PHP multidimensional array
this is the code I am using right now:
$item_id = arg(1);
$quantity = '1';
$found = false;
$bought_items = null;
$data = null;
foreach ($user_items as $key => $data) {
if ($data['a'] == $item_id) {
// The item has been found => add the new points to the existing ones
$data['b'] += 1;
$found = true;
break; // no need to loop anymore, as we have found the item => exit the loop
}
}
if ($found === false) {
$bought_items = array('a' => $item_id, 'b' => $quantity);
}
$array = array($bought_items, $data);
If the item_id is non existing, it is added to the array
If the item_id is existing, the quantity will 'receive' +1
so far so good
now the actual problem, let's sketch the scenario:
I purchase item 500 -> array contains: id=500, quantity=1
I purchase item 500 -> array contains: id=500, quantity=2
I purchase item 600 -> array contains: id=500, quantity=2, id=600, quantity=1
after this it goes wrong
I then purchase item 500 or 600, the other item is removed from the array.
So when I purchase item 500, item 600 and its quantities are removed from the array.
I've been puzzling for hours but can't find the mistake, I know I'm overlooking something logical. I think it's going wrong in the for each.
If bought_items is an array then you're overriding your values rather then adding them to the array.
$bought_items = array('a' => $item_id, 'b' => $quantity);
should be:
$bought_items[] = array('a' => $item_id, 'b' => $quantity);
I tried for example this, and it works, so u can change to own use. The code of another post is useless for your purpose
$item_id = 500;
$quantity = 1;
$user_items = array(400, 300, 200, 500, 500, 200, 500, 500);
$found = FALSE;
$bought_items = null;
$data = null;
foreach ($user_items as $data) {
if ($data == $item_id) {
// The item has been found => add the new points to the existing ones
$quantity += 1;
$bought_items[$data]['a'] = $data;
$bought_items[$data]['b'] = $quantity;
$found = TRUE;
}
if ($found === FALSE) {
$bought_items[$data] = array('a' => $data, 'b' => $quantity);
}
$found = FALSE;
}
print_r($bought_items);
Output:
array(4) {
400 => array(2) {
a => 400
b => 1
}
300 => array(2) {
a => 300
b => 1
}
200 => array(2) {
a => 200
b => 3
}
500 => array(2) {
a => 500
b => 5
}
}
I have a data set stored in an array that references itself with parent-child ids:
id, parent_id, title etc. The top tier has a parent_id of 0, and there can be countless parent-child relationships.
So I'm sorting through this array with a foreach loop within a recursive function to check each array element against its parent element, and I think I've been staring at this method too long.
I do end up with the elements in the correct order, but I can't seem to get my lists nested correctly, which makes me think that the method doesn't really work.
Is this the best route to take?
What can I do to improve and fix this method
Is there another trick that I can apply?
Here is my source:
<div>
<div>Subpages</div>
<ul>
<?php subPages($this->subpages->toArray(), 0) ?>
</ul>
<br>
Add New Subpage
</div>
<?php
function subPages($subpages, $parent){
foreach($subpages as $key => &$page){
$newParent = $page['id'];
//If the current page is the parrent start a new list
if($page['id'] == $parent)
{
//Echo out a new list
echo '<ul>';
echo '<li class="collapsed">';
echo '+';
echo ''.$page['title'].'';
subPages($subpages, $newParent);
echo '</li>';
echo '</ul>';
}
//If the page's parent id matches the parent provided
else if($page['parent_id'] == $parent)
{
//Echo out the link
echo '<li class="collapsed">';
echo '+';
echo ''.$page['title'].'';
//Set the page as the new parent
$newParent = $page['id'];
//Remove page from array
unset($subpages[$key]);
//Check the rest of the array for children
subPages($subpages, $newParent);
echo '</li>';
}
}
}
?>
As always, any assistance is appreciated. Please let me know if something isn't clear.
I doubt that you guys are still looking for a real answer to this, but it might help out others with the same problem. Below is a recursive function to resort an array placing children beneath parents.
$initial = array(
array(
'name' => 'People',
'ID' => 2,
'parent' => 0
),
array(
'name' => 'Paul',
'ID' => 4,
'parent' => 2
),
array(
'name' => 'Liz',
'ID' => 5,
'parent' => 2
),
array(
'name' => 'Comus',
'ID' => 6,
'parent' => 3
),
array(
'name' => 'Mai',
'ID' => 7,
'parent' => 2
),
array(
'name' => 'Titus',
'ID' => 8,
'parent' => 3
),
array(
'name' => 'Adult',
'ID' => 9,
'parent' => 6
),
array(
'name' => 'Puppy',
'ID' => 10,
'parent' => 8
),
array(
'name' => 'Programmers',
'ID' => 11,
'parent' => 4
) ,
array(
'name' => 'Animals',
'ID' => 3,
'parent' => 0
)
);
/*---------------------------------
function parentChildSort_r
$idField = The item's ID identifier (required)
$parentField = The item's parent identifier (required)
$els = The array (required)
$parentID = The parent ID for which to sort (internal)
$result = The result set (internal)
$depth = The depth (internal)
----------------------------------*/
function parentChildSort_r($idField, $parentField, $els, $parentID = 0, &$result = array(), &$depth = 0){
foreach ($els as $key => $value):
if ($value[$parentField] == $parentID){
$value['depth'] = $depth;
array_push($result, $value);
unset($els[$key]);
$oldParent = $parentID;
$parentID = $value[$idField];
$depth++;
parentChildSort_r($idField,$parentField, $els, $parentID, $result, $depth);
$parentID = $oldParent;
$depth--;
}
endforeach;
return $result;
}
$result = parentChildSort_r('ID','parent',$initial);
print '<pre>';
print_r($result);
print '</pre>';
It's a wind down method that removes elements from the original array and places them into result set in the proper order. I made it somewhat generic for you, so it just needs you to tell it what your 'ID' field and 'parent' fields are called. Top level items are required to have a parent_id (however you name it) of 0. I also add a depth marker to each item so that you can format on output.
I will try to help you.
It is possible to compose such relations in one pass:
/**
* Used for "recursive" folding of layout items
* Algorithm of infinite tree (non recursive method)
*
* #param array $items
* #return array
*/
function _foldItems($items) {
$result = array();
foreach ($items as $key => $item) {
$itemName = $item['name'];
if (!isset($item['parent']))
continue;
else {
$parentName = $item['parent']; // it can be either `name` or some `id` of the parent item
if (isset($result[$itemName][$item['sequence']])) {
// Done to eliminate `Warning: Cannot use a scalar value as an array in atLeisure_PropertyImport.class.php`
// Sometimes elements already in the list and have [name] => $count and next line tries to put item in array (item becomes parent)
if ( isset($result[$parentName][$item['parentSequence']]['items'][$itemName]) AND
is_scalar($result[$parentName][$item['parentSequence']]['items'][$itemName])
)
$result[$parentName][$item['parentSequence']]['items'][$itemName] = array();
$result[$parentName][$item['parentSequence']]['items'][$itemName][$item['sequence']] = $result[$itemName][$item['sequence']];
unset($result[$itemName][$item['sequence']]);
} else
$result[$parentName][$item['parentSequence']]['items'][$itemName] = $item['count'];
unset($items[$key]);
} // if //
if (empty($result[$itemName]))
unset($result[$itemName]);
} // foreach //
foreach ($items as $item) { // enumerating rest of the items (single items)
$itemName = $item['itemName'];
if (!isset($result[$itemName]))
$result[$itemName][$item['sequence']] = $item['count'];
}
return $result;
}
Example can be a bit hard to read and to understand because there is really too much code, but I've made this function not so long ago for one project and it seems to be work successfully.
NOTE: It will also work if there are several same items linked to one parent item. It uses item sequence number to avoid aliasing similar values into one.
How to update an item quantity if the product already exists in shopping cart?
Here's my add to cart function:
public function add() {
$product= $this->products_model->listProduct($this->input->post('id_product'));
$data = array(
'id' => $this->input->post('id_product'),
'qty' => $this->input->post('qty'),
'price' => $product->price,
'name' => $product->title );
$this->cart->insert($data);
redirect('product/'.$product->id.'/'.url_title($product->title, 'dash', TRUE));
}
With this function, if the product exists in the cart, let's say with quantity of 8, if i add the same product with quantity of 1 it'll be 1 and not 9.
Thanks in advance.
#AFRC
you can try
public function add() {
$flag = TRUE;
$dataTmp = $this->cart->contents();
foreach ($dataTmp as $item) {
if ($item['id'] == 'sku_123ABC') {
echo "Found Id so updatig quantity";
$qtyn = $item['qty'] + 1;
$this->update($item['rowid'], $qtyn);
$flag = FALSE;
break;
}
}
if ($flag) {
$data = array(
'id' => 'sku_123ABC',
'qty' => 1,
'price' => 39.95,
'name' => 'T-Shirt',
);
$this->cart->insert($data);
echo "Inserting as not found in the cart";
}
echo "Add1 called";
}
I don't see where $produto is defined, shouldn't it be, instead, $product->price and $product->title, respectively?
According to the docs :
Important: The first four array
indexes above (id, qty, price, and
name) are required. If you omit any of
them the data will not be saved to the
cart.
Be sure to check if they're acqually set (maybe look for spelling errors, like, I shoot in the dark, 'qtd' instead of 'qty', or something like that).
Moreover, if you want to UPDATE a product already present, you need to use $this->cart->update() instead of $this->cart->insert()
Just check with this if you have options
$rowid == md5($items['id'].implode('', $items['options']));
if not
$rowid == md5($items['id']);
use this code for add to cart
if (count($this->cart->contents())>0){
foreach ($this->cart->contents() as $item){
if ($item['id']==$product->id){
$data = array('rowid'=>$item['rowid'],'qty'=>++$item['qty']);
$this->cart->update($data);
}else{
$data = array('id'=>$product->id,'qty'=>1,'price'=>$product->price,'name'=>$product->id,'options'=>array('image'=>$product->thumb,'product_name'=>$product->title));
$this->cart->insert($data);
}
}
I used AFRC's answer to create the code below, it may be helpful. Thanks for your reply it really helped me! You can call the cart function below if there is an id present matching in your cart update will occur, otherwise insert will. It'll also display the cart view reguardless of insert, update, or just display. Please note i have a separate function get_specific_craft that is being used to get the slug items data (such as price and name).
public function cart($slug = "")
{
if($slug != "")
{
$craft = $this->crafts_model->get_specific_craft($slug);
$flag = TRUE;
foreach ($this->cart->contents() as $item)
{
if ($item['id'] == $slug)
{
$qtyn = $item['qty'] + 1;
$dat = array(
'rowid' => $item['rowid'],
'qty' => $qtyn
);
$this->cart->update($dat);
$flag = FALSE;
break;
}
}
if ($flag)
{
$crt = array(
'id' => $craft['id'],
'qty' => 1,
'price' => $craft['price'],
'name' => $craft['name']
//'options' => array('Size' => 'L', 'Color' => 'Red')
);
$this->cart->insert($crt);
}
}
$this->load->view('cart' , $this->data);
}