I have the following code which gets me a list of manufacturers:
$attribute = Mage::getModel('eav/entity_attribute')
->loadByCode('catalog_product', 'manufacturer');
$valuesCollection = Mage::getResourceModel('eav/entity_attribute_option_collection')
->setAttributeFilter($attribute->getData('attribute_id'))
->setStoreFilter(0, false);
$preparedManufacturers = array();
foreach($valuesCollection as $value) {
$preparedManufacturers[$value->getOptionId()] = $value->getValue();
}
if (count($preparedManufacturers)) {
echo "<h2>Manufacturers</h2><ul>";
foreach($preparedManufacturers as $optionId => $value) {
echo "<li>" . $value . " - (ID:" . $optionId . ")</li>";
}
echo "</ul>";
}
How do I get the first product of each manufacturer?
Thanks
try this
if (count($preparedManufacturers)) {
echo "<h2>Manufacturers</h2><ul>";
foreach($preparedManufacturers as $optionId => $value) {
<!-- add the this code for get first item id -->
$firstProductId=Mage::getModel('catalog/product')->getCollection()
->addStoreFilter(0)
->addAttributeToFilter('manufacturer',$optionId)->getFirstItem()->getId();
echo "<li>" . $value . " - (ID:" . $optionId . ")</li>";
}
echo "</ul>";
}
Related
I have a problem: i want to detect all redirections of a 3xx response code and separate each header of URL. I investigated that get_headers function follows redirections and put it in an array of each component of redirection. I know that "fb.com" redirects 3 times as you can see on this page:
I want to do the same thing of that page, and am trying to do so:
But my PHP code seems to be wrong. Here it is:
<?php
$header = array();
$header[] = array();
$header_url = #get_headers('http://fb.com',1);
/*
foreach ($header_url as $key => $value){
echo $key . " = " . $value . "<br />";
}
*/
$a = 0;
foreach($header_url as $key => $value){
if(is_int($key)){
$header[$a][] = $value;
$a++;
} else if(!is_int($key) && !is_object($key)){
$header[0][$key] = $value;
} else if(!is_int($key) && is_object($key)){
foreach ($key as $key2 => $value2){
$header[$key2][$key] = $value2;
}
}
}
echo "<h1>ONE</h1>";
foreach ($header[0] as $key => $value) {
echo $key . " = " . $value . "<br />";
}
echo "<h1>TWO</h1>";
foreach ($header[1] as $key => $value) {
echo $key . " = " . $value . "<br />";
}
echo "<h1>THREE</h1>";
foreach ($header[2] as $key => $value) {
echo $key . " = " . $value . "<br />";
}
?>
I would appreciate help on what i am doing wrong.
THANKS SO MUCH AND HAVE A NICE DAY DEV!
I have these arrays:
$payments = array(1=>'Cash',2=>Cheque,3=>credit,4=>other);
$selected = array(2,1);
foreach($payments as $key=>$value) {
foreach($selected as $id) {
if ($key == $id) {
echo $id . "is selected" . '<br>';
}
else{
echo $id . " is not selected" . '<br>';
}
}
}
what expected:
1 is selected
2 is not selected
3 is not selected
4 is selected
but i got:
1 is not selected
1 is selected
2 is selected
2 is not selected
3 is not selected
3 is not selected
4 is not selected
4 is not selected
what's the wrong in my loops?
You don't need inner loop:
$payments = array(1=>'Cash',2=>Cheque,3=>credit,4=>other);
$selected = array(2,1);
foreach($payments as $key=>$value) {
if (in_array($key, $selected)( {
echo $key . "is selected" . '<br>';
} else {
echo $key . " is not selected" . '<br>';
}
}
You could simply use in_array() to check if an element is selected:
$payments = array(1=>'Cash',2=>'Cheque',3=>'credit',4=>'other');
$selected = array(2,1);
foreach($payments as $key=>$value) {
if (in_array($key, $selected)) {
echo $value . "is selected" . '<br>';
} else {
echo $value . " is not selected" . '<br>';
}
}
By the way, you need quotes around the payment method names.
You can use in_array() instead, so you can omit your inner loop:
foreach($payments as $key=>$value) {
if (in_array($key, $selected)) {
echo $id . "is selected" . '<br>';
}else{
echo $id . " is not selected" . '<br>';
}
}
Example
UPDATE: an alternative solution. Not better (maybe), but different :)
$payments = array(1=>'Cash', 2=>'Cheque', 3=>'Credit', 4=>'Other');
$selected = array('Cash','Cheque');
foreach($selected as $chosen){
$selected_values = array_search($chosen, $payments);
echo "Number ". $selected_values." (".$chosen.") is selected.<br>";
}
You can see the output here
Old solution (as everyone else...)
$payments = array(1=>'Cash', 2=>'Cheque',3=>'Credit',4=>'Other');
$selected = array(2,1);
foreach($payments as $key=>$value) {
if (in_array($key, $selected)) {
echo $key. " is selected" . '<br>';
}else{
echo $key. " is not selected" . '<br>';
}
}
I have an associative array that is I am creating from an ODBC query with the following code:
while ($row=odbc_fetch_array($oexec)) {
if(empty($group[$row['gmm']])) {
$group[$row['gmm']] = array();
}
if(empty($group[$row['gmm']][$row['acctg_dept_nbr'] . " - " . $row['acctg_dept_desc']])) {
$group[$row['gmm']][$row['acctg_dept_nbr'] . " - " . $row['acctg_dept_desc']] = array();
}
if(empty($group[$row['gmm']][$row['acctg_dept_nbr'] . " - " . $row['acctg_dept_desc']][$row['dept_catg_grp_desc']])) {
$group[$row['gmm']][$row['acctg_dept_nbr'] . " - " . $row['acctg_dept_desc']][$row['dept_catg_grp_desc']] = array();
}
if(empty($group[$row['gmm']][$row['acctg_dept_nbr'] . " - " . $row['acctg_dept_desc']][$row['dept_catg_grp_desc']][$row['dept_category_desc']])) {
$group[$row['gmm']][$row['acctg_dept_nbr'] . " - " . $row['acctg_dept_desc']][$row['dept_catg_grp_desc']][$row['dept_category_desc']] = array();
}
if(empty($group[$row['gmm']][$row['acctg_dept_nbr'] . " - " . $row['acctg_dept_desc']][$row['dept_catg_grp_desc']][$row['dept_category_desc']][$row['dept_subcatg_desc']])) {
$group[$row['gmm']][$row['acctg_dept_nbr'] . " - " . $row['acctg_dept_desc']][$row['dept_catg_grp_desc']][$row['dept_category_desc']][$row['dept_subcatg_desc']] = array();
}
$group[$row['gmm']][$row['acctg_dept_nbr'] . " - " . $row['acctg_dept_desc']][$row['dept_catg_grp_desc']][$row['dept_category_desc']][$row['dept_subcatg_desc']]['total_ty_yest_sales'] = $row['total_ty_yest_sales'];
$group[$row['gmm']][$row['acctg_dept_nbr'] . " - " . $row['acctg_dept_desc']][$row['dept_catg_grp_desc']][$row['dept_category_desc']][$row['dept_subcatg_desc']]['total_wo_dotcom_ty_yest_sales'] = $row['total_wo_dotcom_ty_yest_sales'];
$group[$row['gmm']][$row['acctg_dept_nbr'] . " - " . $row['acctg_dept_desc']][$row['dept_catg_grp_desc']][$row['dept_category_desc']][$row['dept_subcatg_desc']]['east_ty_yest_sales'] = $row['east_ty_yest_sales'];
$group[$row['gmm']][$row['acctg_dept_nbr'] . " - " . $row['acctg_dept_desc']][$row['dept_catg_grp_desc']][$row['dept_category_desc']][$row['dept_subcatg_desc']]['central_ty_yest_sales'] = $row['central_ty_yest_sales'];
$group[$row['gmm']][$row['acctg_dept_nbr'] . " - " . $row['acctg_dept_desc']][$row['dept_catg_grp_desc']][$row['dept_category_desc']][$row['dept_subcatg_desc']]['west_ty_yest_sales'] = $row['west_ty_yest_sales'];
$group[$row['gmm']][$row['acctg_dept_nbr'] . " - " . $row['acctg_dept_desc']][$row['dept_catg_grp_desc']][$row['dept_category_desc']][$row['dept_subcatg_desc']]['dotcom_ty_yest_sales'] = $row['dotcom_ty_yest_sales'];
}
This gives me an array where:
$myArray = Array(GMM => Array(acctg_dept_nbr => Array(dept_category_desc => Array(dept_subcatg_desc => Array(value1,value2,value3)))))
I want to sum the values at every level. So for every acctg_dept_nbr[dept_category_desc][dept_subcatg_desc] I want to sum value1,value2,value3. Same for the GMM level and down to the dept_subcatg_desc level. Summing the dept_subcatg_desc level wasn't a problem. I dug around and found how to sum the dept_category_desc level, but am having trouble applying that method recursively.
Here is the code that puts the values into a table:
foreach($group as $gmm => $acctg_dept_nbrs) {
echo "<tr class=\"header\">
<td>" . $gmm . "</td>\n";
foreach ($acctg_dept_nbrs as $acctg_dept_nbr => $dept_catg_grp_descs) {
echo "<tr class=\"header\">\n
<td style=\"padding-left: 1em;\">" . $acctg_dept_nbr . "</td>\n";
foreach($dept_catg_grp_descs as $dept_catg_grp_desc => $dept_category_descs) {
echo "<tr class=\"header\">\n
<td style=\"padding-left: 2em;\">" . $dept_catg_grp_desc . "</td>\n";
//echo "<td>" . array_sum(array_walk_recursive($dept_category_descs,function($item) {return $item['total_ty_yest_sales'];})) . "</td>";
foreach($dept_category_descs as $dept_category_desc => $dept_subcatg_descs) {
echo "<tr class=\"header\">\n
<td style=\"padding-left: 3em;\">" . $dept_category_desc . "</td>\n";
echo "<td>" . array_sum(array_map(function($item) {return $item['total_ty_yest_sales'];},$dept_subcatg_descs)) . "</td>";
echo "<td>" . array_sum(array_map(function($item) {return $item['east_ty_yest_sales'];},$dept_subcatg_descs)) . "</td>";
echo "<td>" . array_sum(array_map(function($item) {return $item['central_ty_yest_sales'];},$dept_subcatg_descs)) . "</td>";
echo "<td>" . array_sum(array_map(function($item) {return $item['west_ty_yest_sales'];},$dept_subcatg_descs)) . "</td>";
foreach($dept_subcatg_descs as $dept_subcatg_desc => $values) {
echo "<tr>\n
<td style=\"padding-left: 4em;\">" . $dept_subcatg_desc . "</td>\n";
$sum = $values['total_ty_yest_sales'];
echo "<td>".$sum."</td>";
$sum = $values['east_ty_yest_sales'];
echo "<td>".$sum."</td>";
$sum = $values['central_ty_yest_sales'];
echo "<td>".$sum."</td>";
$sum = $values['west_ty_yest_sales'];
echo "<td>".$sum."</td>";
}
}
}
}
}
The commented out line is the problem for me now. This:
array_sum(array_map(function($item) {return $item['west_ty_yest_sales'];},$dept_subcatg_descs))
works fine at that level, but not at the higher levels. I have also tried to tweak this function to no avail:
function array_map_recursive($callback, $array) {
foreach ($array as $key => $value) {
if (is_array($array[$key])) {
$array[$key] = array_map_recursive($callback, $array[$key]);
}
else {
$array[$key] = call_user_func($callback, $array[$key]);
}
}
return $array;
}
How can I make this work so that regardless of level it will dig down and sum the values for that portion of the array?
function array_map_recursive($callback, $array)
{
$func = function ($item) use (&$func, &$callback) {
return is_array($item) ? array_map($func, $item) : call_user_func($callback, $item);
};
return array_map($func, $array);
}
function array_map_recursive($callback, $array)
{
if(is_array($callback)){
foreach ($callback as $function){
$array = array_map_recursive($function, $array);
}
return $array;
}
$func = function ($item) use (&$func, &$callback) {
return is_array($item) ? array_map($func, $item) : call_user_func($callback, $item);
};
return array_map($func, $array);
}
This way you can call the function passing more functions.. ex:
$rowData = array_map_recursive(['utf8_decode', 'trim'], $rowData);
Or simple call just one:
$rowData = array_map_recursive('trim', $rowData);
It can be a little difficult if we add multiple arrays to the function. But with only one, there is no problem at all.
function array_map_recursive(&$arr, $fn) {
return array_map(function($item) use($fn){
return is_array($item) ? array_map_recursive($item, $fn) : $fn($item);
}, $arr);
}
$array = array_map_recursive($array, function($item){
//TODO logic here
});
filter_var can essentially be used to accomplish this
function array_map_recursive(callable $func, array $array) {
return filter_var($array, FILTER_CALLBACK, ['options' => $func]);
}
There is one big drawback...
The callback will receive the value as a string.
and the leafs can't be objects
As you can see on http://www.mattmaclennan.co.uk/a2 ... when you hover over "New Motorcycles", it has the array numbers, and not the labels as required. Also, the categories need to be grouped into their IDs. Below is what I have tried.
<?
$output = mysqli_query("SELECT * FROM bikes, bikeTypes WHERE bikes.model_id = bikeTypes.model_id");
$result = array();
while($row = mysqli_fetch_array($output))
{
$result[] = $row;
}
//var_dump($result);
foreach ($result as $key => $val) {
echo "<li><a href='test.php?id=" . $val['model_id'] . "'>".$key.'</a><ul>';
echo "<li><a href='details.php?id=" . $val['bike_id'] . "'>" . $val['bikeName'] . "</a></li>";
echo '</ul>';
echo '</li>';
}
?>
The category field is called 'model'. Thanks for any help!
Thats because you're display the $key, instead of the $value.
<?
$output = mysqli_query("SELECT * FROM bikes, bikeTypes WHERE bikes.model_id = bikeTypes.model_id");
while($row = mysqli_fetch_array($output))
{
echo "<li><a href='test.php?id=" . $row['model_id'] . "'>".$row['???'].'</a><ul>';
echo "<li><a href='details.php?id=" . $row['bike_id'] . "'>" . $row['bikeName'] . "</a></li>";
echo '</ul>';
echo '</li>';
}
?>
Below is some code I've written that is effective, but makes too many database queries. Is there a way I could optimize and reduce the number of queries but have conditional statements still be as effective as below?
I pasted the code repeated a few times just for good measure.
echo "<h3>Pool Packages</h3>";
echo "<ul>";
foreach ($items as $item):
$this->db->where('id', $item['id']);
$query = $this->db->get('items')->row();
if ($item['quantity'] > 1 && $item['quantity'] == TRUE && $query->category == "Pool Packages") {
$newprice = $item['quantity'] * $query->price;
$totals[] = $newprice;
}
else {
$newprice = $query->price;
$totals[] = $newprice;
}
if ($query->category == "Pool Packages") {
echo "<li>" . $query->name . " (QTY: " . $item['quantity'] . " x = " . str_ireplace(" ", "", money_format('%(#10n', $newprice)) . ")</li>";
}
else { }
endforeach;
echo "</ul>";
echo "<h3>Water Features</h3>";
echo "<ul>";
foreach ($items as $item):
$this->db->where('id', $item['id']);
$query = $this->db->get('items')->row();
if ($item['quantity'] > 1 && $item['quantity'] == TRUE && $query->category == "Water Features") {
$newprice = $item['quantity'] * $query->price;
$totals[] = $newprice;
}
else {
$newprice = $query->price;
$totals[] = $newprice;
}
if ($query->category == "Water Features") {
echo "<li>" . $query->name . " (QTY: " . $item['quantity'] . " x = " . str_ireplace(" ", "", money_format('%(#10n', $newprice)) . ")</li>";
}
else { }
endforeach;
echo "</ul>";
echo "<h3>Waterfall Rock Work</h3>";
echo "<ul>";
foreach ($items as $item):
$this->db->where('id', $item['id']);
$query = $this->db->get('items')->row();
if ($item['quantity'] > 1 && $item['quantity'] == TRUE) {
$newprice = $item['quantity'] * $query->price;
$totals[] = $newprice;
}
else {
$newprice = $query->price;
$totals[] = $newprice;
}
if ($query->category == "Waterfall Rock Work") {
echo "<li>" . $query->name . " (QTY: " . $item['quantity'] . " x = " . str_ireplace(" ", "", money_format('%(#10n', $newprice)) . ")</li>";
}
else { }
endforeach;
echo "</ul>";
echo "<h3>Sheer Descents</h3>";
echo "<ul>";
foreach ($items as $item):
$this->db->where('id', $item['id']);
$query = $this->db->get('items')->row();
if ($item['quantity'] > 1 && $item['quantity'] == TRUE && $query->category == "Sheer Descents") {
$newprice = $item['quantity'] * $query->price;
$totals[] = $newprice;
}
else {
$newprice = $query->price;
$totals[] = $newprice;
}
if ($query->category == "Sheer Descents") {
echo "<li>" . $query->name . " (QTY: " . $item['quantity'] . " x = " . str_ireplace(" ", "", money_format('%(#10n', $newprice)) . ")</li>";
}
else { }
endforeach;
echo "</ul>";
echo "<h3>Booster Pump</h3>";
echo "<ul>";
foreach ($items as $item):
$this->db->where('id', $item['id']);
$query = $this->db->get('items')->row();
if ($item['quantity'] > 1 && $item['quantity'] == TRUE && $query->category == "Booster Pump") {
$newprice = $item['quantity'] * $query->price;
$totals[] = $newprice;
}
else {
$newprice = $query->price;
$totals[] = $newprice;
}
if ($query->category == "Booster Pump") {
echo "<li>" . $query->name . " (QTY: " . $item['quantity'] . " x = " . str_ireplace(" ", "", money_format('%(#10n', $newprice)) . ")</li>";
}
else { }
endforeach;
echo "</ul>";
echo "<h3>Pool Concrete Decking</h3>";
echo "<ul>";
foreach ($items as $item):
$this->db->where('id', $item['id']);
$query = $this->db->get('items')->row();
if ($item['quantity'] > 1 && $item['quantity'] == TRUE && $query->category == "Pool Concrete Decking") {
$newprice = $item['quantity'] * $query->price;
$totals[] = $newprice;
}
else {
$newprice = $query->price;
$totals[] = $newprice;
}
if ($query->category == "Pool Concrete Decking") {
echo "<li>" . $query->name . " (QTY: " . $item['quantity'] . " x = " . str_ireplace(" ", "", money_format('%(#10n', $newprice)) . ")</li>";
}
else { }
endforeach;
echo "</ul>";
echo "<h3>Solar Heating</h3>";
echo "<ul>";
foreach ($items as $item):
$this->db->where('id', $item['id']);
$query = $this->db->get('items')->row();
if ($item['quantity'] > 1 && $item['quantity'] == TRUE && $query->category == "Solar Heating") {
$newprice = $item['quantity'] * $query->price;
$totals[] = $newprice;
}
else {
$newprice = $query->price;
$totals[] = $newprice;
}
if ($query->category == "Solar Heating") {
echo "<li>" . $query->name . " (QTY: " . $item['quantity'] . " x = " . str_ireplace(" ", "", money_format('%(#10n', $newprice)) . ")</li>";
}
else { }
endforeach;
echo "</ul>";
echo "<h3>Raised Bond Beam</h3>";
echo "<ul>";
foreach ($items as $item):
$this->db->where('id', $item['id']);
$query = $this->db->get('items')->row();
if ($item['quantity'] > 1 && $item['quantity'] == TRUE && $query->category == "Raised Bond Beam") {
$newprice = $item['quantity'] * $query->price;
$totals[] = $newprice;
}
else {
$newprice = $query->price;
$totals[] = $newprice;
}
if ($query->category == "Raised Bond Beam") {
echo "<li>" . $query->name . " (QTY: " . $item['quantity'] . " x = " . str_ireplace(" ", "", money_format('%(#10n', $newprice)) . ")</li>";
}
else { echo "<li>None</li>"; }
endforeach;
echo "</ul>";
It goes on beyond this to several more categories, but I don't know how to handle looping through this best. Thanks!
You could build the html in a variable so you only loop once. Here's a quick and dirty example just to show you what I'm talking about:
$html = '';
$oldCat = '';
foreach ($items as $item) {
$this->db->where('id', $item['id']);
$query = $this->db->get('items')->row();
if ($oldCat != $query->category) {
$html .= "</ul>\n";
$html .= "<h3>".$query->category."</h3>\n<ul>\n";
$oldCat = $query->category;
}
if ($item['quantity'] > 0) {
$newprice = $item['quantity'] * $query->price;
$totals[] = $newprice;
}
$html .= "<li>" . $query->name . " (QTY: " . $item['quantity'] . " x = " . str_ireplace(" ", "", money_format('%(#10n', $newprice)) . ")</li>\n";
}
// strip leading /ul, append a /ul, echo html
You could store all the rows into a separate array during the first loop and then reference the array throughout all the other loops rather than fetching the same information over and over, assuming you're select * which you probably are.
Or, if there are not many items more than the ones you're fetching, you could use a single query to fetch all of the rows at once (you're using only one query) and loop through that to store all the values in an array $array[$row['id']] = $row (or something similar) then simply reference all those rows in the array in each of your loops.
You need to start thinking in terms of sets instead of loops. Write a stored proc that takes the array either as a varchar (or in SQL Server 2008 you can use a table valued input parameter, don't know about other dbs).
Then split the string into a temp table and return all the records in one select joining to the temp table. Even if you need to return separate record sets, doing it in a stored proc will reduce the network traffic in.
you should use a join from items to category and get all the items, then you can sort them out into a multi-dimensional array and then loop through that for output.
Im not sure what youre classes db connection is doing but but lets assume we want all items with thier category:
$sql = "SELECT item.*, category.name as category from item, category WHERE item.category_id = category.item_id";
// ill use PDO for db access here...
$db = new PDO($connString, $username, $password);
$items = array(); // our array indexed by category.
foreach($db->query($sql) as $item) {
if(!array_key_exists($items, $item['category']) {
$items[$item['category']] = array();
}
$items[$item['category']][] = $item;
}
// now loop through $items using the similar stuff you did for output previously.
// note instead of doing the conditionals for pricing and stuff here you may want to
// do that in the loop above and put it in the array before hand... it will keep the
// output loop cleaner.