0

I have this code:

if ($object_id != $cur_object_id) {
                        ?>

                    <div class="workbench_object_wrap">
                        <p class="text_center"><u><?php echo $object_name; ?></u></p>

                        <div class="workbench_object_img">
                            <img style="max-width: 100px; max-height:100px;" src="<?php echo $src. "2.png";?>">
                        </div>
                        <div class="workbench_object_info_wrap">
                            <div class="workbench_object_info">
                            <?php
                        }

                                ?>
                                <p><?php echo $material_name; ?><i style="float:right;"><?php echo $material_amount; ?></i></p>
                                <?php

                                if ($object_id != $cur_object_id) {
                                ?>
                                <div class="craft">
                                    <button id= "craft-<?php echo $object_id; ?>" class="craft" onclick="craft(this);">Craft</button>
                                </div>
                            </div>
                        </div>
                    </div>
                    <?php
                    $cur_object_id = $object_id;
                    }

Which is inside a while loop that iterates over everything returned by the database query.

So I want the $object_name to appear once for each object. Each object has some names: $material_name. And after all those material names has been printed, I want the div to close itself and print craft only once for every object.

This image represents the output I get from the database. As you can see, the same object_id appears twice, and therefore I have made the $cur_object_id since I only want the object name once (Royal Chair) however I want both of the material names (Stone and Birch Log) to be displayed BEFORE the last div is closed.

This is what the database call returns

This is probably done with some boolean values checking if the object_id is still the same or some logic like that but I just can't figure a way to accomplish this. Thanks in advance!

2
  • Can you add the database query you're performing in order to load the data? It looks like you are joining objects to categories and materials, in which case it would make sense that you would get multiple entries for the same object if they are made out of multiple materials Commented Apr 23, 2014 at 15:17
  • Yeah but that is what I want, I just don't want to display it. I just want to display ALL material names for every object name. Object Royal Chair has 2 material names, the royal chair shall be displayed once and its materials shall both be displayed underneath. Commented Apr 23, 2014 at 15:21

1 Answer 1

1

Here's where I think you're going wrong...

It looks like you have a database structure looking kind of like this:

objects
-------
object_id, name

categories
----------
category_id, name

materials
---------
material_id, name

category_objects
----------------
category_id, object_id

object_materials
----------------
material_id, object_id

In order to load all of the data you want to display, you're probably performing a single query like this:

$results = query(
    'SELECT * FROM objects o
    INNER JOIN object_materials om ON om.object_id = o.object_id
    INNER JOIN materials m ON om.material_id = m.material_id

    INNER JOIN category_objects co ON co.object_id = o.object_id
    INNER JOIN categories c ON c.category_id = co.category_id'
);

Not only will this give you duplicate results for materials, but it will also give you duplicate results when you start putting objects in multiple categories. Try breaking this up into multiple queries:

$objects = query('SELECT * FROM objects');

// Iterate over each object and load the category/materials for 
// each object individually
    $categories = query(
        'SELECT * FROM categories c
            INNER JOIN category_objects co ON co.category_id = c.category_id
        WHERE co.object_id = ?',
        $object['id']
    );

    $materials = query(
        'SELECT * FROM materials m
            INNER JOIN object_materials om ON om.material_id = m.material_id
        WHERE mo.object_id = ?',
        $object['id']
    );

Then you can individually iterate over each of those result sets and display them however you like. You may be able to get away with using a single query to do this, but it won't be at all clear to the guy coming in behind you later, or even to you 6 months from now when/if a bug is discovered.

Update

It's not exactly clear from your question how you're querying or what markup you're displaying this in, but here's some pseudo-code that should work for you if you want to keep going the way you are. I'm using a table element to display the results here, but you can modify it to suit your needs.

echo '<table>';
$currentObjectId = null;
$currentCategoryId = null;
$currentMaterialId = null;

// Iterate over your result set
// Each object here is a tuple representing joined entities from the 
// objects, categories and materials tables
foreach($objects as $object) { 
    echo '<tr>';

    if(!$currentObjectId || $currentObjectId != $object['id']) {
        echo '<td>' . $object['name'] . '</td>';
    } else {
        echo '<td></td>';
    }

    if(!$currentCategoryId || $currentCategoryId != $object['category_id']) {
        echo '<td>' . $object['category_name'] . '</td>';
    } else {
        echo '<td></td>';
    }

    if(!$currentMaterialId || $currentMaterialId != $object['material_id']) {
        echo '<td>' . $object['material_name'] . '</td>';
    } else {
        echo '<td></td>';
    }

    echo '</tr>';
}

echo '</table>';
Sign up to request clarification or add additional context in comments.

2 Comments

Hello Watcher, thanks for the great tips and the good explanation! I get everything that I need from the database as it is right now (sorry if that wasn't explained precisely) I just can't get the PHP to display the things that are returned correctly. Creating two queries is a way to go as well, but wouldn't I be able to do this with one too? I just need something that can check if the object_id has changed or not, before displaying the other image I guess.
Will this print the material only onces? uh I am not quite sure I understand it correctly. Well I have edited my code to show exactly how my example is, don't worry about the database output, it gets everything it needs. But it shows the second material name and src out of the last div and not inside it. Thanks again

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.