I'll start off by saying, Yes, I've searched this... I'm reading books about programming to increase my knowledge. Right now I have not found an answer to this question. I have a working solution to my application but it looks a mess. This is PHP.
Situation: I am creating an application that includes a dynamic menu (food) that pulls from 3 tables in a database:
menu_types:
id name
1 Bar
2 Kitchen
menu_categories:
id name type_id
1 Salads 2
2 Teas 1
3 Pastries 2
menu_items
id name cat_id description price image
1 Caesar 1 'hail Caesar' $5.00 'image location'
2 Greek 1 'Plato's fav' $3.00 'image location'
3 Cinnamon Roll 3 'lots-o-sugar' $2.50 'image location'
There's more data, but I think you get the idea on the tables.
My menu would look something like this: (HTML page) Teas, Salads, and Pastries would be links that when clicked only show their items. Below is a rough example, let's say salads are the current page.
**Bar** 'Caesar image', Caesar, hail Caesar, $5.00
Teas 'Greek image', Greek, Plato's fav, $3.00
**Kitchen**
Salads
Pastries
Currently I build this all in one class. One object. I end up building three arrays
$this->types = array(
[0] => array(
'id' => 1,
'name' => 'Bar'
),
[1] => array(
'id' => 2,
'name' => 'Kitchen'
)
);
$this->categories = array(
[Bar] => array(
'id' => 2,
'name' => 'Teas',
'type_id' => 1
)
),
[Kitchen] => array(
'id' => 1,
'name' => 'Salads',
'type_id' => 2
),
array(
'id' => 3,
'name' => 'Patries',
'type_id' => 2
)
);
And $this->items has it's own array with $this->category[id] as it's main key.
This all gets extremely messy though. And trying to iterate through these arrays for the different parts of the menu is terrible. I didn't include the code because I feel like this whole thought process is fundamentally wrong. I'm not looking for someone to give me a full blown code example, just help me with the thought process. I think that's the hardest part of coding, thinking of a solution to the problem.
in summary I'm looking to create a dynamic menu that filters both the items based on category and the categories based on the types
for fun, here is the code I was using:
menu.php
<?php
class menu{
private $category;
private $size;
private $types;
private $categories;
private $items = array();
public function __construct(){
$this->setTypes();
$this->setCategories();
$this->setItems();
}
private function setTypes(){
$sql = "SELECT * FROM bbc_menu_types";
$this->types = db::rowAsAssocArray($sql);
}
public function getTypes(){
return $this->types;
}
private function setCategories(){
for ($i = 0; $i < count($this->types); $i++){
$typeId = $this->types[$i]['id'];
$sql = "SELECT * FROM bbc_menu_categories WHERE type_id = $typeId";
$this->categories[$this->types[$i]['name']] = db::rowAsAssocArray($sql);
}
}
public function getCategories(){
return $this->categories;
}
public function setItems(){
foreach ($this->categories as $key => $value){
for ($i = 0; $i < count($value); $i++){
$catId = $value[$i]['id'] . '<br />';
settype($catId, 'integer');
$sql = "SELECT * FROM bbc_menu_items WHERE category_id = $catId";
$this->items[$this->categories[$key][$i]['name']] = db::rowAsAssocArray($sql);
}
}
}
public function getItems(){
return $this->items;
}
}
?>
db.pgp (excerpt)
public static function rowAsAssocArray($sql){
try{
//do not touch
$data=null;
$stmt = self::$link->prepare($sql);
$stmt->execute();
while ($result = $stmt->fetchAll(PDO::FETCH_ASSOC)){
foreach ($result as $key => $value){
$data[] = $value;
}
}
return $data;
}
catch (PDOException $e){
print $e->getMessage();
}
}
html (expert)
<?php
$i=0;
foreach ($types as $value){
echo "<li><h3>" . $types[$i]['name'] . "</h3></li>";
$i2 = 0;
while ($i2 <count($categories[$types[$i]['name']])){
if ($_GET['cat'] === strtolower($categories[$types[$i]['name']][$i2]['name'])){
echo "<li class='active'><a href='?rt=menu&cat=";
} else {
echo "<li><a href='?rt=menu&cat=";
}
echo strtolower($categories[$types[$i]['name']][$i2]['name']) . "'>" . $categories[$types[$i]['name']][$i2]['name'] . "</a></li>";
$i2++;
}
$i++;
}
?>
</ul>
</nav>
</div><!-- end menu-links -->
</div><!-- end col -->
<div class="col-sm-12 col-md-9">
<div class="menu-links-big">
<?php
$i = 0;
while ($i < count($items[ucfirst($_GET['cat'])])){
?>
<div class="menu-item">
<img src="<?php echo $items[ucfirst($_GET['cat'])][$i]['image']; ?>" alt="" class="img-thumbnail shadow alignleft">
<h3><?php echo $items[ucfirst($_GET['cat'])][$i]['name']; ?></h3>
<p><?php echo $items[ucfirst($_GET['cat'])][$i]['description']; ?></p>
<div class="price"><?php echo '$' . $items[ucfirst($_GET['cat'])][$i]['price']; ?></div>
</div><!-- end item -->
<?php
$i++;
}
?>
Like I said... A mess... There is obvious cleaning that could be done. And there is cleaning and refactoring on top of that. I'm aware. I just finished getting ti to work before I decided to ask about it.
$rowarray.$someCategory->getItems()gives you an array of all the items in that category). There's literally no logic coding required on your side then, just declaring the classes and fields.