0

Firstly to show you what I am trying to achieve in the view, a list of extras grouped by type.

<ul>
{foreach $extras as $extra_type}
<li>
    <h2>{$extra_type.title}</h2>
    <ul>
        {foreach $extra_type.extras as $extra}
        <li>
            {$extra.name}
        </li>
        {/foreach}
    </ul>
</li>
{/foreach}
</ul>

I have the following which is creating duplicate extras, although I don't think that it's good practice to overwrite the $extras array each time. Is there a better way of doing this? I would prefer to only make 1 query to the database.

$stmnt = "SELECT e.*, ed.extra_description_name, ed.extra_description_description,
            et.extra_type_title, ep.extra_price_amount, c.currency_htmlcode
          FROM product_extras pe
          LEFT JOIN extras e ON e.extra_id = pe.extra_id
          LEFT JOIN extra_descriptions ed ON ed.extra_id = pe.extra_id
          LEFT JOIN extra_prices ep ON ep.extra_id = pe.extra_id
          LEFT JOIN extra_types et ON et.extra_type_id = e.extra_type_id
          LEFT JOIN currencies c ON c.currency_id = ep.currency_id
          WHERE pe.product_id = '{$this->id}' AND e.extra_status = 'ENABLED'
            AND ed.language_id = 1 AND ep.currency_id = 1";

if ($isPublished) {
    $stmnt .= "
        AND IF(e.extra_publish_from IS NOT NULL, e.extra_publish_from, NOW()) <= NOW()
        AND IF(e.extra_publish_until IS NOT NULL, e.extra_publish_until, NOW()) >= NOW()";
}

$stmnt .= " ORDER BY e.extra_type_id, pe.product_extra_ordering, ed.extra_description_name";

$cache  = Cache::getInstance()->newObject(300);
$sig = Cache::getCacheName(sha1($stmnt));

if (!$res = $cache->load($sig)) {
    $res = $db->fetchAll($stmnt);
    $cache->save($res, $sig);
}

if(!empty($res))  {
    foreach($res as $row) {
        $extra[] = array(
            'id'        => $row['extra_id'],
            'type'      => $row['extra_type_title'],
            'weight'    => $row['extra_weight'],
            'image'      => $row['extra_image'],
            'name'      => $row['extra_description_name'],
            'description'   => $row['extra_description_description'],
            'price'     => Formatter::getInstance()->outFormat("currency", $row['extra_price_amount']),
            'currency'  => $row['currency_htmlcode']
        );

        $extras[$row['extra_type_id']] = array(
            'title' => $row['extra_type_title'],
            'extras' => $extra
        );
    }
}

If it helps this is the DB

--
-- Table structure for table `extras`
--

CREATE TABLE IF NOT EXISTS `extras` (
  `extra_id` int(11) NOT NULL AUTO_INCREMENT,
  `extra_weight` float(4,1) NOT NULL COMMENT 'Weight in KG',
  `extra_image` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `extra_available_all_countries` tinyint(1) NOT NULL,
  `extra_type_id` int(11) DEFAULT NULL,
  `extra_publish_from` int(11) DEFAULT NULL,
  `extra_publish_until` int(11) DEFAULT NULL,
  `extra_created` datetime NOT NULL,
  `extra_created_by` int(11) NOT NULL,
  `extra_modified` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `extra_modified_by` int(11) NOT NULL,
  `extra_status` enum('ENABLED','DISABLED') COLLATE utf8_unicode_ci NOT NULL,
  PRIMARY KEY (`extra_id`),
  KEY `extra_typeFK` (`extra_type_id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

-- --------------------------------------------------------

--
-- Table structure for table `extra_types`
--

CREATE TABLE IF NOT EXISTS `extra_types` (
  `extra_type_id` int(11) NOT NULL AUTO_INCREMENT,
  `extra_type_title` varchar(120) COLLATE utf8_unicode_ci NOT NULL,
  PRIMARY KEY (`extra_type_id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

2 Answers 2

0

Your loop is malformed

<ul> {foreach $extras as $extra_type} <li>
    <h2>{$extra_type.title}</h2>
    <ul>
        {foreach $extra_type.extras as $extra}
        <li>
            {$extra.name}
        </li>
        {/foreach}
    </ul> </li> {/foreach}

note $extra_type.extras into the second foreach.

May be your template engine don't support the grammar

0

I gave up and moved the logic into the view was a lot easier.

<ul>
{foreach $extras as $extra}
    {if $_extra_type != $extra.type || $extra@first}
    <li>
        <h2>{$extra.type}</h2>
        <ul>
        {/if}

            <li>
                {$extra.type} - {$extra.name}
            </li>

        {if $_extra_type != $extra.type || $extra@last}
        </ul>
    </li>
    {/if}
    {assign var="_extra_type" value=$extra.type}
{/foreach}
</ul>


if(!empty($res))  {
    foreach($res as $row) {
        $extras[] = array(
            'id'            => $row['extra_id'],
            'type'          => $row['extra_type_title'],
            'weight'        => $row['extra_weight'],
            'image'         => $row['extra_image'],
            'name'          => $row['extra_description_name'],
            'description'   => $row['extra_description_description'],
            'price'         => Formatter::getInstance()->outFormat("currency", $row['extra_price_amount']),
            'currency'      => $row['currency_htmlcode']
        );
    }
}

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.