Adding values to act as breaks in array_merge dropdown - php

I have three arrays getting different post types, which are then merged for a drop down in the Wordpress admin. I'm trying to insert empty values/breaks to make the drop down easier to read.
Here are the arrays and the array_merge:
// creating an array of pages
$featpages = array();
$pages = get_pages();
$pages[""] = "";
foreach ($pages as $page) {
$featpages[ $page->post_title ] = $page->ID;
}
// creating an array of posts
$postargs = array('numberposts' => 0);
$featposts = array();
$posts = get_posts($postargs);
$posts[""] = "";
foreach ($posts as $post) {
$featposts[ $post->post_title ] = $post->ID;
}
// creating an array of activities
$actargs = array('post_type' => 'activity', 'numberposts' => 0);
$featacts = array();
$acts = get_posts($actargs);
$acts[""] = "";
foreach ($acts as $act) {
$featacts[ $act->post_title ] = $act->ID;
}
// creating a combined array of pages and tours
$links = array_merge((array)$featpages, (array)$featacts, (array)$featposts);
I was hoping the [""] = "";for each one would add an empty row between each set, but it only works for one - I guess because they look the same to the array_merge?

[""] = ""; will overwrite the next one
Use [] = ''; instead

Related

Create array out of two arrays

I need to create an array out of two arrays. I tried to use array_merge but it doesn't work.
With the first array, I pull all IDS of custom posts.
$all_posts = get_posts(array(
'fields' => 'id',
'posts_per_page' => -1,
'post_type' => 'items'
));
$ids = array();
foreach($all_posts as $a){
$id[] = array("id"=>$a->ID);
}
With second array I get only items assigned to that page:
$items = get_field('items');
$assigned_items= array();
foreach($items as $p){
$id = $p["select_item"][0]->ID;
$price= $p["price"];
$live = $p["live"];
$assigned_items[]=array("id"=>$id, "price"=>$available, "live"=>$live);
}
$price and $live variables are boolean.
Now I need to create an array out of these two. As the first array pulls all items, I need to merge with id in the second array. $price and $live could be one true one false.
I need to create an array with all ids from $ids array and add $price and $live elements to it from the second array if the ids are the same. If id doesn't exist in the second array, both price and live are false in the final output.
You need something like this, I also made some improvement to your code and check if there is any post or item before loop (to avoiding warning from php) also better error handling.
<?php
$ids = $assigned_items = $merged = array();
$all_posts = get_posts(array(
'fields' => 'id',
'posts_per_page' => -1,
'po|st_type' => 'items'
));
if($all_posts) {
foreach($all_posts as $a){
// $id[] = array("id"=>$a->ID);
$merged[$a->ID]["id"] = $a->ID;
}
$items = get_field('items');
if($items) {
foreach($items as $p){
$id = $p["select_item"][0]->ID;
$price= $p["price"];
$live = $p["live"];
// $assigned_items[]=array("id"=>$id, "price"=>$available, "live"=>$live);
$merged[$id]["price"] = $price;
$merged[$id]["live"] = $live;
} else {
// no item ...
}
}
} else {
// no post ...
}
if you assign your second iteration object, to the key in the array, you can easily merge them.
$assigned_items[$p["select_item"][0]->ID] = ['id' => $id, 'price' => $available, 'live' => $live];
Now you could join them, by accessing the assigned items by the id. Combining the arrays with the + operator.
foreach ($all_posts as $post) {
$combined = (array) $post + $assigned_items[$poost->ID] ?? [];
}
This would also eliminate you, from doing the $ids iteration.

type: error message: [ ] operator not supported for string

I'm getting information from database, saving it in array and echoing it in a form with loop structure and I'm having problems when I try to save the modified information to database.
I'm getting this error:
message: [] operator not supported for string
$this->db->select('*');
$this->db->from('tbl_memory_questions');
$this->db->order_by('rand()');
$this->db->limit(1);
$GetWordsFromdb = $this->db->where('memQuesType', 'Words');
$GetWord = $GetWordsFromdb->get(); print_r($GetWord->result());exit;
$GetWords = array();
$MemQuesId = "";
$GetsetId = "";
$memQuesImgUrl = "";
foreach ($GetWord->result() as $row) {
$GetWords[] = $row->memQuesType;
$MemQuesId = $row->memQuesId;
$GetsetId = $row->setId;
$GetsetIdarray[] = $row->setId;
$GetmemQuesImgUrl[] = $row->memQuesImgUrl;
$worddata[] = array(
'GetWords' => $row->memQuesType,
'MemQuesId' => $row->memQuesId,
'GetsetId' => $row->setId,
'GetmemuesImgUrl' => $row->memQuesImgUrl);
}
I expect errorless word shuffle from database and show me the next page
could somebody give me hint what i'm going wrong?
You need to define $worddata as an array before you start referring to its elements by using the brackets. You are also failing to define $GetsetIdarray and $GetmemQuesImgUrl as arrays before trying to append elements to those vars.
$this->db->select('*');
$this->db->from('tbl_memory_questions');
$this->db->order_by('rand()');
$this->db->limit(1);
$GetWordsFromdb = $this->db->where('memQuesType', 'Words');
$GetWord = $GetWordsFromdb->get(); print_r($GetWord->result());exit;
$GetWords = array();
$MemQuesId = "";
$GetsetId = "";
$memQuesImgUrl = "";
$worddata = array(); // define these as arrays before you start
$GetsetIdarray = array(); // trying to append elements
$GetmemQuesImgUrl = array();
foreach ($GetWord->result() as $row) {
$GetWords[] = $row->memQuesType;
$MemQuesId = $row->memQuesId;
$GetsetId = $row->setId;
$GetsetIdarray[] = $row->setId;
$GetmemQuesImgUrl[] = $row->memQuesImgUrl;
$worddata[] = array(
'GetWords' => $row->memQuesType,
'MemQuesId' => $row->memQuesId,
'GetsetId' => $row->setId,
'GetmemuesImgUrl' => $row->memQuesImgUrl);
}

How to compare two values from different foreach loop in PHP?

Here is My codes,
My question is if $company_id from foreach one equal to $Company_id from foreach two then echo company_name.
$ids = array();
$x = array();
$a = array();
foreach($companieslist as $keys=>$company) {
$x[$company->company_id] = [
'id' => $company->company_id,
'name' => $company->company_name
];
}
$entry = $a[$id];
foreach($uploads as $keys=>$general){
$ids[] = $general->Contract_Id;
$c_id = $general->Company_id;
....
Just talking from the performance side, what you should do is extract the company ids from the second batch to an array first, like this
$companies = array();
foreach ( $uploads as $keys => $general ) {
array_push( $companies, $general->Company_id );
}
Now, in the first foreach loop, you can just check if the company id exists in this $companies array, and then decide what to do
foreach($companieslist as $keys=>$company){
if(in_array($company->company_id,$companies)){
echo "Found {$company->company_id}<br/>\n";
}
}

How to store product quantities in an array

I have a data array that totals all the items in the cart for all the products as one number.
I've been trying to figure out a way to get a data array count() all the different totals of all the different items in the cart and have them presented in my data layer comma separated. I hope that makes sense.
if ($order->getId()) {
$items = $order->getAllVisibleItems();
$itemIds = array();
$itemNames = array();
$itemPrices = array();
$itemMargins = array();
$itemTypes = array();
$itemGenders = array();
$itemSports = array();
$itemCategoryIds = array();
$itemCategoryNames = array();
/** #var Mage_Sales_Model_Quote_Item $item */
foreach ($items as $item) {
// Get the parent item - it is NOT included in the quote due to
// customizations made by the OrganicInternet module for simple
// product pricing. So I had to come up with another way to get it.
$options = $item->getProductOptions();
$parent = $item->getProduct();
if (array_key_exists('info_buyRequest', $options)) {
if (array_key_exists('cpid', $options['info_buyRequest'])) {
$parentId = $options['info_buyRequest']['cpid'];
$parent = Mage::getModel('catalog/product')->getCollection()
->addAttributeToSelect('name')
->addAttributeToSelect('season')
->addAttributeToSelect('gender')
->addAttributeToSelect('sport')
->addAttributeToFilter('entity_id', $parentId)
->getFirstItem();
}
}
$itemIds[] = $item->getSku();
$itemNames[] = $parent->getName();
$itemPrices[] = $item->getBasePrice() ?: 0;
$itemMargins[] = $this->_calculateMargin($parent, null, $item);
$itemTypes[] = $parent->getAttributeText('season');
$itemGenders[] = $parent->getAttributeText('gender');
$itemSports[] = $parent->getAttributeText('sport') ?: 'Other';
$categories = $this->_getAllCategoryIdsAndNames($item->getProduct());
$itemCategoryIds[] = $categories['id'];
$itemCategoryNames[] = $categories['name'];
}
// # Products
$data['u1'] = count($items);
The above will return:
dataLayer = [{"visitorLoginState":"Logged out","visitorType":"NOT LOGGED IN","visitorLifetimeValue":0,"visitorExistingCustomer":"No","u1":2,"u2":["889623392590","889623135517"]
It shows a total of 2 products for the U1 variable and the two sku's for the u2 variable in the data array.
If i have multiple products for the first sku i want it to seperate the quantities. ie.. "u1":1,1,3
Would i use array_sumor some type of multi-dimensional array to acquire my needs?
If i have multiple products for the first sku i want it to seperate
the quantities. ie.. "u1":1,1,3
It is not exactly clear to me is the relationship between sku and product and which variables in your array refer to which. I make the following presumptions:
1) A product is equivalent to one $items element
2) A sku is a unique $itemIds[] value
I use the array key as a simple way to keep track for each unique sku and the value to keep track of the product count for the sku.
if ($order->getId()) {
$items = $order->getAllVisibleItems();
$itemIds = array();
$itemNames = array();
$itemPrices = array();
$itemMargins = array();
$itemTypes = array();
$itemGenders = array();
$itemSports = array();
$itemCategoryIds = array();
$itemCategoryNames = array();
// My addition (UPDATE: fixed to the correct variable name)
$uniqueItemIds = array();
/** #var Mage_Sales_Model_Quote_Item $item */
foreach ($items as $item) {
// Get the parent item - it is NOT included in the quote due to
// customizations made by the OrganicInternet module for simple
// product pricing. So I had to come up with another way to get it.
$options = $item->getProductOptions();
$parent = $item->getProduct();
if (array_key_exists('info_buyRequest', $options)) {
if (array_key_exists('cpid', $options['info_buyRequest'])) {
$parentId = $options['info_buyRequest']['cpid'];
$parent = Mage::getModel('catalog/product')->getCollection()
->addAttributeToSelect('name')
->addAttributeToSelect('season')
->addAttributeToSelect('gender')
->addAttributeToSelect('sport')
->addAttributeToFilter('entity_id', $parentId)
->getFirstItem();
}
}
// *******************************
// My addition / changes
$sku = $item->getSku();
$itemIds[] = $sku; // I don't use this but keep $itemIds for compatibility
// use the array key to track counts for each sku
if (!isset($uniqueItemIds[$sku])){
$uniqueItemIds[$sku] = 1; // UPDATE: fixed to start at 1 not 0
} else {
$uniqueItemIds[$sku]++;
}
// *******************************
$itemNames[] = $parent->getName();
$itemPrices[] = $item->getBasePrice() ?: 0;
$itemMargins[] = $this->_calculateMargin($parent, null, $item);
$itemTypes[] = $parent->getAttributeText('season');
$itemGenders[] = $parent->getAttributeText('gender');
$itemSports[] = $parent->getAttributeText('sport') ?: 'Other';
$categories = $this->_getAllCategoryIdsAndNames($item->getProduct());
$itemCategoryIds[] = $categories['id'];
$itemCategoryNames[] = $categories['name'];
}
// show # Products
// "u1":1,1,3 NOTE: this should be a string => "u1":"1,1,3"
$data['u1'] = "";
foreach ($uniqueItemIds as $key => $val)
// show unique skus in u2
$data['u2'][] = $key;
// show counts for each sku in u1
if (strlen($data['u1'] == 0)){
$data['u1'] = (string)$value;
} else {
$data['u1'] .= ("," . $value);
}
}
How about something like...
if ($order->getId()) {
.....
.....
.....
/** #var Mage_Sales_Model_Quote_Item $item */
$sku_based_array = array();
foreach ($items as $item) {
......
......
......
$categories = $this->_getAllCategoryIdsAndNames($item->getProduct());
$itemCategoryIds[] = $categories['id'];
$itemCategoryNames[] = $categories['name'];
if (isset($sku_based_array[$item->getSku()])) {
$sku_based_array[$item->getSku()] = $sku_based_array[$item->getSku()]++;
} else {
$sku_based_array[$item->getSku()] = 1;
}
}
// # Products
$data['u1'] = array_values($sku_based_array);
Looking at the code it looks like it will only every return one product as the $parent variable is overwritten to get a first item. I have added a new variable named $itemProductCounts this will be returned to the output $data array as itemProductCounts I suspect this will always equal one.
<?php
if ($order->getId()) {
$items = $order->getAllVisibleItems();
$itemIds = array();
$itemNames = array();
$itemPrices = array();
$itemMargins = array();
$itemTypes = array();
$itemGenders = array();
$itemSports = array();
$itemCategoryIds = array();
$itemCategoryNames = array();
$itemProductCounts = array();
/** #var Mage_Sales_Model_Quote_Item $item */
foreach ($items as $item) {
// Get the parent item - it is NOT included in the quote due to
// customizations made by the OrganicInternet module for simple
// product pricing. So I had to come up with another way to get it.
$options = $item->getProductOptions();
$parent = $item->getProduct();
if (array_key_exists('info_buyRequest', $options)) {
if (array_key_exists('cpid', $options['info_buyRequest'])) {
$parentId = $options['info_buyRequest']['cpid'];
$parent = Mage::getModel('catalog/product')->getCollection()
->addAttributeToSelect('name')
->addAttributeToSelect('season')
->addAttributeToSelect('gender')
->addAttributeToSelect('sport')
->addAttributeToFilter('entity_id', $parentId)
->getFirstItem();
}
}
$itemIds[] = $item->getSku();
$itemNames[] = $parent->getName();
$itemPrices[] = $item->getBasePrice() ?: 0;
$itemMargins[] = $this->_calculateMargin($parent, null, $item);
$itemTypes[] = $parent->getAttributeText('season');
$itemGenders[] = $parent->getAttributeText('gender');
$itemSports[] = $parent->getAttributeText('sport') ?: 'Other';
$categories = $this->_getAllCategoryIdsAndNames($item->getProduct());
$itemCategoryIds[] = $categories['id'];
$itemCategoryNames[] = $categories['name'];
$itemProductCounts[$item->getSku()] = count($parent);
}
// # Products
$data['u1'] = count($items);
$data['itemProductCounts'] = $itemProductCounts;
With that all being said, the code above should get you close to what you need, you should replace the line $itemProductCounts[$item->getSku()] = count($parent); with the correct array with the product counts for that SKU.
Part of the issue with your data here is that everything in an $item is hidden behind an accessor. Rather than creating multitudes of arrays, I would suggest either creating a new object to house the information, or just modifying the $item directly.
Messing with the object directly has the risk of you accidentally using a variable name that exists in a protected or private scope though, so probably best to use your own, like so.
if ($order->getId()) {
$items = $order->getAllVisibleItems();
// only need one array, no need for all data points to have their own
$myItems = [];
/** #var Mage_Sales_Model_Quote_Item $item */
foreach ($items as $item) {
// basic shell
$myItem = [];
// get $options and $parent
// ...
// build your own data object
$myItem['sku'] = $item->getSku();
$myItem['name'] = $parent->getName();
$myItem['price'] = $item->getBasePrice() ?: 0;
$myItem['margin'] = $this->_calculateMargin($parent, null, $item);
$myItem['type'] = $parent->getAttributeText('season');
$myItem['gender'] = $parent->getAttributeText('gender');
$myItem['sport'] = $parent->getAttributeText('sport') ?: 'Other';
$categories = $this->_getAllCategoryIdsAndNames($item->getProduct());
$myItem['categoryId'] = $categories['id'];
$myItem['categoryName'] = $categories['name'];
$myItems[] = $myItem;
}
// At this point, $myItems is manipulable by all the array_* functions
// number of items e.g. 3
$data['u1'] = count($myItems);
// array of skus e.g. ["889623392590","889623392590","889623135517"]
// note: can use objects for $myItem if on PHP 7
// if you like -> notation better (in the loop)
$skus = array_column($myItems, 'sku');
// array of skus with counts e.g. ["889623392590" => 2, "889623135517" => 1]
$skus_with_counts = array_count_values($skus);
// just the counts (assuming indexes on other arrays must match) e.g. [2, 1]
// note: might be useful if you want to keep the counts as an array in dataLayer
$sku_counts = array_values($skus_with_counts);
// if you want this as a comma-separated list for u1, e.g. "2,1"
// note: will also work if you implode $skus_with_counts
$data['u1'] = implode(',', $sku_counts);
// get a list of unique SKUs (both will work), e.g. ["889623392590","889623135517"]
$data['u2'] = array_unique($skus);
$data['u2'] = array_keys($skus_with_counts);
}
Most of these kinds of PHP functions will work on your other data types as well if you want to do counting and clustering, and as you point out, you can run sum operations over them as well if you wish.
PHP array manipulation references: array_column, array_count_values, array_values, implode, array_unique, array_keys.
As a sidebar, Mage_Sales_Model_Quote_Item does have a getParentItemId() method available and a getQtyOptions method, which returns both the quantity and the product model.
I think you are mixing things.
In a simple sistem you should have:
Order has an array of OrderedItems
Each OrderedItem stores ProductObject and OrderedQuantity
And the ProductObject contains all product data.
So in your example instead of counting SKUs you must have $item->quantity field and you should work with that when you add/delete/edit order contents.

Trying to do multidimentional array in PHP but something going wrong

I have an array that I declare like this:
$health_array = array( );
For every iteration I try to put these 3 items in it like this:
$health_array["num_problems"] = $num_problems;
$health_array["category_id"] = $category_id;
$health_array["category_name"] = $category_name;
But when I loop through the array I get gibberish. Here is how I loop through it:
foreach ($health_array as $i => $row)
{
echo '<p>'.$row['category_name'].' '.$row['category_id'].' '.$row['num_problems'].'</p>';
}
Any idea what I am doing wrong?
Thanks!!
Your problem comes from the fact that you want to do a multi-dimensional array and you're creating a monodimensional one, by overwriting each time the same 3 elements.
You should do something like:
$health_array = array();
$tmp = array();
$tmp["num_problems"] = 5;
$tmp["category_id"] = 8;
$tmp["category_name"] = "something";
$health_array[] = $tmp;
$tmp["num_problems"] = 15;
$tmp["category_id"] = 22;
$tmp["category_name"] = "something else";
$health_array[] = $tmp;
foreach ($health_array as $h)
{
echo $h["num_problems"]." - ".$h["category_id"]." - ".$h["category_name"]."<br />";
}
For every iteration I try to put these 3 items in it like this:
$health_array["num_problems"] = $num_problems;
$health_array["category_id"] = $category_id;
$health_array["category_name"] = $category_name;
It looks like you meant to build your array like this instead:
$health_array[] = array(
"num_problems" => $num_problems,
"category_id" => $category_id,
"category_name" => $category_name
);
This makes an array of arrays, where previously you were overwriting the keys of the same array for each iteration.

Categories