Associative array's loaded from database and display as 'columns' - php

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.

Related

Sum of Foreach Loop

I'm trying to total a bill balance with a program I'm working on in PHP.
The code I use to pull the pricing is as such.
public function PackagePricing($arg) {
$query = <<<SQL
SELECT packageID
FROM customer_packages
WHERE active = :true
AND customerID = :arg
SQL;
$resource = $this->db->db->prepare( $query );
$resource->execute( array (
":true" => 1,
":arg" => 1,
));
foreach($resource as $row) {
self::GetPricing($row['packageID']);
}
}
public function GetPricing($arg) {
$query = <<<SQL
SELECT price
FROM products
WHERE id = :arg
SQL;
$resource = $this->db->db->prepare( $query );
$resource->execute( array (
":arg" => $arg,
));
$totalBill = 0;
foreach($resource as $row) {
$totalBill+= $row['price'];
}
echo $totalBill;
}
Now by my understanding this should work, but what I'm getting in turn is:
On the right you can see the billing total and rather than totaling out it's giving me each individually.
The error seems quite obvious. Here's your sequence in different words :
Get all packages ID.
Foreach package ID, get the price of the item (only one result is returned)
For that single result, add up all the prices (you only get one). Print it and go back to 2.
What you see is not 2 prices that have been added as strings in some sort of way. You simply prints subsequently 2 different prices. 10 & 30
GetPricing should return a price, and the foreach loop that calls it should make the sum.
$total = 0;
foreach($resource as $row)
{
$total += self::GetPricing($row['packageID']);
}
Hope this helps.

Add property of each element in array to a new array

I'm using CakePHP to create a products database system. In CakePHP, I have an array of all products in the 'products' table. Each product (an element in the 'products' array) has a function 'toArray()'. This converts the product into an associative array. How could I take an array of all the products and add the 'toArray()' of each product to a new array. This is my current flow:
$products = [$product1, $product2, $product3];
$newArr = [];
foreach($products as $product) {
$newArr[] = $product->toArray();
}
Is there a one-liner for something like this?
I don't think you could quite oneline this (without functionalizing it, anyway), but you don't need to duplicate data unless you need to keep the original format as well as the reformatted version.
foreach($products as $key => $product){
$products[$key] = $product->toArray();
}
Will change your exisiting array to the reformatted version.

Multiple Keys to an array in if/else search

My code is pretty basic. I'm using an array to generate a datasheet for a product based on it's SKU and a filepath.
My array looks like this:
$a=array(
"/images/ManualSheets/factSheetCLASSIC.pdf"=>"KE800/6",
"/images/ManualSheets/factSheetMICRO.pdf"=>"KE800/12",
"/images/ManualSheets/factSheetSMALL.pdf"=>"KE4000/12",
"/images/ManualSheets/factSheetMEDIUM.pdf"=>"KE8000/12",
);
Where the first Key is the filepath, and the second Key is the SKU (as generated by the system) I then use an if/else to generate a button - so if a product is not in the array it returns a blank value and doesn't have a button which leads to nowhere
$factsheetweblink_url = array_search($product_sku,$a);
if ($factsheetweblink_url==false) {
echo " ";
}
else {
echo "<div class='productpagestockistBTN'>
<img src='/images/FactSheet_btn.png' >
</div>";
}
?>
This code works fine. The catch comes when I have products with different SKUs but the same datasheet file, (same brand and make but a different model). Currently I can only get it to work by uploading multiple copies of the datasheets with different names, but it's becoming a big waste of space.
I have tried using an array as a key to hold multiple values to the one key..
"/images/ManualSheets/factSheetMEDIUM.pdf"=> array("KE8000/12","KE7000/12"),
but it doesn't seem to be working... I'm not quite sure if I need to refine my if statement to search within the sub arrays as well or..?
Any help would be appreciated, thanks in advance.
You should use arrays like this:
$products = array(
0 => array(
"pdf" => "/images/ManualSheets/factSheetCLASSIC.pdf",
"skus" => array("KE800/6","KE900/6")
),
1 => array(
"pdf" => "/images/ManualSheets/factSheetCLASSIC3.pdf",
"skus" => array("KE100/6","KE200/6"))
);
This is because array_search returns just first row whit that key.
Then just do your own search function like:
function findBySku($items, $sku) {
$pdf = ""; // return empty if not found.
foreach($items as $row) {
if (in_array($sku, $row['skus'])) {
$pdf = $row['pdf'];
break;
}
}
return $pdf;
}
and call that function:
$pdf = findBySku($products, "some sku");

Magento gather attributes as multidimensional array keys

I need to gather all of the available attributes for the given product and then create a multidimensional array with them. Hopefully you can create a multidimensional array with more than two dimensions? The resulting array declarations should look like this:
$simpleArray[$child->getVendor()][$child->getColor()]=$child->getPrice();
First I'm gathering all the attributes then adding them to a string where I can call each one later:
$_product = $this->getProduct();
$_attributes = Mage::helper('core')->decorateArray($this->getAllowAttributes());
//Gather all attribute labels for given product
foreach($_attributes as $_attribute){
$attributeString .= '[$child -> get' . ucfirst($_attribute->getLabel()) . '()]';
}
Then I'm attempting to append that string to the array to declare it:
foreach($childProducts as $child) { //cycle through simple products to find applicable
//CAITLIN you are going to need way to search for other attributes, GET list of attributes
$simpleArray. $attributeString =$child->getPrice();
}
Mage::log('The attributeString is '. $simpleArray. $attributeString, null, 'caitlin.log'); //This is logging as "The attributeString is Array74"
Any suggestions?
You'll need to use recursion to do what you're requesting without knowing the attribute names while writing the code.
This will loop through and provide all of the child product prices, in a multi dimensional array based on the configurable attributes. It assumes that $_product is the current product.
$attrs = $_product->getTypeInstance(true)->getConfigurableAttributesAsArray($_product);
$map = array();
foreach($attrs as $attr) {
$map[] = $attr['attribute_code'];
}
$childPricing = array();
$childProducts = $_product->getTypeInstance()->getUsedProducts();
foreach($childProducts as $_child) {
// not all of the child's attributes are accessible, unless we properly load the full product
$_child = Mage::getModel('catalog/product')->load($_child->getId());
$topLevel = array($child->getData($map[sizeof($map)]) => $_child->getPrice());
array_pop($map);
$childProducts = array_merge($childProducts,$this->workThroughAttrMap($map,$_child,$topLevel));
}
//print_r childProducts to test, later do whatever you were originally planning with it.
In the same controller include this:
protected function workThroughAttrMap(&$map,$child,$topLevel) {
$topLevel = array($child->getData($map[sizeof($map)]) => $topLevel);
array_pop($map);
if(sizeof($map) > 0) return workThroughAttrMap($map,$child,$topLevel);
else return $topLevel;
}
I haven't tested this code so there may be a few minor bugs.
There are a few things you could do to make the code a bit cleaner, such as moving the first $topLevel code into the function, making that an optional parameter and initializing it with the price when it doesn't exist. I also haven't included any error checking (if the product isn't configurable, the child product doesn't have its price set, etc).

PHP MySQL building a 3 Tier multi dimensional array

So I have my query, its returning results as expect all is swell, except today my designer through in a wrench. Which seems to be throwing me off my game a bit, maybe its cause Im to tired who knows, anyway..
I am to create a 3 tier array
primary category, sub category (which can have multiples per primary), and the item list per sub category which could be 1 to 100 items.
I've tried foreach, while, for loops. All typically starting with $final = array(); then the loop below that.
trying to build arrays like:
$final[$row['primary]][$row['sub']][] = $row['item]
$final[$row['primary]][$row['sub']] = $row['item]
I've tried defining them each as there own array to use array_push() on. And various other tactics and I am failing horribly. I need a fresh minded person to help me out here. From what type of loop would best suit my need to how I can construct my array(s) to build out according to plan.
The Desired outcome would be
array(
primary = array
(
sub = array
(
itemA,
itemB,
itemC
),
sub = array
(
itemA,
itemB,
itemC
),
),
primary = array
(
sub = array
(
itemA,
itemB,
itemC
),
sub = array
(
itemA,
itemB,
itemC
),
),
)
Something like this during treatment of your request :
if (!array_key_exists($row['primary'], $final)) {
$final[$row['primary']] = array();
}
if (!array_key_exists($row['sub'], $final[$row['primary']])) {
$final[$row['primary']][$row['sub']] = array();
}
$final[$row['primary']][$row['sub']][] = $row['item'];
Something like this....
$final =
array(
'Primary1'=>array(
'Sub1'=>array("Item1", "Item2"),
'Sub2'=>array("Item3", "Item4")
),
'Primary2'=>array(
'Sub3'=>array("Item5", "Item6"),
'Sub4'=>array("Item7", "Item8")
),
);
You can do it using array_push but it's not that easy since you really want an associative array and array_push doesn't work well with keys. You could certainly use it to add items to your sub-elements
array_push($final['Primary1']['Sub1'], "Some New Item");
If I understand you correctly, you want to fetch a couple of db relations into an PHP Array.
This is some example code how you can resolve that:
<?php
$output = array();
$i = 0;
// DB Query
while($categories) { // $categories is an db result
$output[$i] = $categories;
$ii = 0;
// DB Query
while($subcategories) { // $subcategories is an db result
$output[$i]['subcategories'][$ii] = $subcategories;
$iii = 0;
// DB Query
while($items) { // $items is an db result
$output[$i]['subcategories'][$ii]['items'][$iii] = $items;
$iii++;
}
$ii++;
}
$i++;
}
print_r($output);
?>

Categories