Welcome Guest, Not a member yet? Register   Sign In
Foreaching a foreach
#1

[eluser]gmask[/eluser]
Hello.

I have a `links` table that holds all the links I add to my CMS. To display these links, I call a my links() function in my helper:
Code:
function links()
{
    // Get global settings
    $CI = & get_instance();
    $query = $CI->db->get('links');
    if($query->num_rows() > 0)
    {
        echo "<ul>\n";
        foreach($query->result() as $link)
        {
            echo "\t<li>".anchor($link->url, $link->title, 'title="'.$link->description.'" target="'.$link->target.'"')."</li>\n";
        }
        echo "</ul>\n";
    } else {
        echo '<p>No links available.</p>';
    }
}
The relevant fields contained in the `links` table:
Code:
id
title
url
category
The category field references another table, `categories`, via a slug key which is based on the URL's title:
Code:
id
title
slug
sorting

What I'd like to do is, rather than displaying the links in a single list, divide the list result into the proper link categories, and then sort the links based on the category's settings (each link category contains a field called `sorting`, which contains something like 'id desc', or 'title asc').

I'm guessing this can be accomplished with multiple foreach statements, but I have no idea how to do this, nor where to even start.

Thanks in advance for any assistance with this problem.
#2

[eluser]LuckyFella73[/eluser]
There are multiple ways to do that. I don't know how flexible you
want you code, here just 2 approches:

You can just order your db results by category to group all links
of one category.

An other way would be to go through the loop (all results) and set
up some array-container and if-lines and push the rows into the
appropreate containers [array_push()]. Later on you can access your array where
you want. Can be handy but if your categories change its not the best
solution.
#3

[eluser]gmask[/eluser]
[quote author="LuckyFella73" date="1285598885"]There are multiple ways to do that. I don't know how flexible you
want you code, here just 2 approches:

You can just order your db results by category to group all links
of one category.

An other way would be to go through the loop (all results) and set
up some array-container and if-lines and push the rows into the
appropreate containers [array_push()]. Later on you can access your array where
you want. Can be handy but if your categories change its not the best
solution.[/quote]
The first solution isn't a solution at all, since I want to divide the list into completely different sets (I'd like each new category field encountered to start a new <ul>, with its own order method as defined by the database, and its own $category->title for further distinction).

I don't understand the second solution you suggested, so I will go and read the documentation on array_push() now, this may be the trick. But why would it be a problem if my categories change? Would links get lost? What I do right now when updating a category is first search the existing links for any that are contained in that category, and update them as well with the new category information, that way nothing slips between the cracks. If that's not what you meant could you explain your solution in more detail please?

Thanks for the suggestions!
#4

[eluser]gmask[/eluser]
I actually have come up with an altogether different solution to this problem.

Instead of forcing the PHP to do the work, I decided to give the user (myself) some extra control by offering the ability to call all of the links of a specified category.

To display all links in the database:
Code:
<h2>Links</h2>
&lt;?php links(); ?&gt;

To display the links contained in the `blogroll` category:
Code:
<h2>Blogroll</h2>
&lt;?php links('blogroll'); ?&gt;

Helper:
Code:
function links($category = '')
{
    if($category == '')
    {
        $CI = & get_instance();
        $CI->db->order_by('id desc');
        $CI->db->where('category !=', 'uncategorized');
        $query = $CI->db->get('links');
        if($query->num_rows() > 0)
        {
            echo "<ul>\n";
            foreach($query->result() as $link)
            {
                echo "\t<li>".anchor($link->url, $link->title, 'title="'.$link->description.'" target="'.$link->target.'"')."</li>\n";
            }
            echo "</ul>\n";
        } else {
            echo '<p>No links available.</p>';
        }
    } else {
        $CI = & get_instance();
        $get_categories = $CI->db->get_where('categories', array('slug' => $category));
        $snappy = $get_categories->row();
        if($get_categories->num_rows() > 0)
        {
            $CI->db->order_by($snappy->link_sorting);
            $CI->db->where('category', $category);
            $query = $CI->db->get('links');
            if($query->num_rows() > 0)
            {
                echo "<ul>\n";
                foreach($query->result() as $link)
                {
                    echo "\t<li>".anchor($link->url, $link->title, 'title="'.$link->description.'" target="'.$link->target.'"')."</li>\n";
                }
                echo "</ul>\n";
            } else {
                echo '<p>No links available.</p>';
            }
        } else {
            echo '<p>No such category exists!';
        }
    }
}

Is there a problem with doing it this way?
#5

[eluser]LuckyFella73[/eluser]
Hi,

sorry for my last post - wasn't a good help I think ...

Here is an example of the array_push thing but better skip that ..
I would prefer to do it like in my second example.
Sure you can solve the problem it like you posted, I just think
its cleaner to put the main logic into the controller and let models
do the database stuff. As far as I know helpers shouldn't be used for
DB stuff to make them more undependent so that you can just use them
on other projects.

Here my examples (as mentioned before I would to like in the second example,
the first one is just to give you an example of array_push:
Code:
&lt;?php
# an array_push example:
$query = $this->your_model->get_links();
if ($query->num_rows() > 0)
{
    $lnk_cat_cars = array();
    $lnk_cat_bikes = array();
    
    foreach($query->result() as $row)
    {
        if ($row->category == 'cars')
        {
            array_push($lnk_cat_cars['link']) = $row->link;
            array_push($lnk_cat_cars['description']) = $row->description;
            array_push($lnk_cat_cars['title']) = $row->title;
        }
        if ($row->category == 'bikes')
        {
            array_push($lnk_cat_bikes['link']) = $row->link;
            array_push($lnk_cat_bikes['description']) = $row->description;
            array_push($lnk_cat_bikes['title']) = $row->title;
        }
    }
}



// or a shorter way to do that
$query_cars = $this->your_model->get_links('cars'); // filter results from DB in your model
$query_bikes = $this->your_model->get_links('bikes');

# then in your view can can place each linkbox where you want to and iterate through the result sets.
if($query_cars->num_rows() > 0)
{
    echo "<ul>\n";
    foreach($query_cars->result() as $link)
    {
        echo "\t<li>".anchor($link->url, $link->title, 'title="'.$link->description.'" target="'.$link->target.'"')."</li>\n";
    }
    echo "</ul>\n";
}
else
{
    echo '<p>No links available.</p>';
}
?&gt;




Theme © iAndrew 2016 - Forum software by © MyBB