X-Cart: shopping cart software

X-Cart forums (https://forum.x-cart.com/index.php)
-   Dev Questions (X-Cart 5) (https://forum.x-cart.com/forumdisplay.php?f=56)
-   -   ShopBy Brand - brand page layout changes (https://forum.x-cart.com/showthread.php?t=70447)

JannieB 11-07-2014 08:35 AM

ShopBy Brand - brand page layout changes
 
Hello,

I am using the ShopByBrand module for XC5.
I want to change the way the brands are displayed on the "All brands" page .... I have tried decoragting the BrandsPage class, but can't get any output...

What I am trying to acheive is a column based list showing juts Brand Names grouped by their inital letter, for instance

A
Abrand1
Abrand2
...

B
Bbrand1
Bbrand2
...

etc.

I have written the PHP code to output an array structure for this ... but nothing is coming out .. it relies on the getBrands function, but juts doesn't seem to be calling it ...

any clues?

Jan

xplorer 11-10-2014 03:59 AM

Re: ShopBy Brand - brand page layout changes
 
Hi Jan,

Here are the files that render the page:

1. skins/default/en/modules/QSL/ShopByBrand/brands_page/all_brands.tpl is the template that wraps the page data into HTML. It uses the BrandsPage class to get the page data and do necessary checks/logic against it.

2. XLite\Module\QSL\ShopByBrand\View\BrandsPage is the class that implement the logic to retrieve page data and do checks against it. The "getBrands()" method uses other classes to retrieve brands from the database. The "getBrandRows()" method prepare the data and split it into chunks (rows). There are other methods used by the template (check the template for their names).

From you description it looks like you are to "decorate" both the files from your module:
- you need the data displayed in a single column with every group having the "letter" title, so you should change the template file
- you need the data to be ordered by the brand name, so you should change the getBrands() method accordingly
- you need the data to be a plain list of brands, not a table with multiple columns, so you should change the getBrandRows() method as well (or create a new method and call it from your new template instead of this one)

JannieB 11-10-2014 04:36 AM

Re: ShopBy Brand - brand page layout changes
 
Thanks, would you mind looking at my code .... it doesn't cause any problems but doesn't seem to product any output!

This is my BrandsPage module:
Code:

/**
 * @inherit
 *
 * @LC_Dependencies ("QSL\ShopByBrand")
 */
class BrandsPage extends XLite\Module\QSL\ShopByBrand\View\BrandsPage implements \XLite\Base\IDecorator
{
   
    protected $columns;

 public function getColumnsCount()
    {
        return 4;
    }

    /**
    * take brands array and chunk by initial letter
    *
    * @return array
    */
    public function getBrandsAlpha()
    {
                if (!isset($this->brands)) {
                    $this->brands = getBrands();                       
                }
               
                $aBrands = $this->brands;               
        $aBrandsAlpha = array();
               
                foreach ($this->brands as $aBrand) {
                        $initial = substr($aBrand[0], 0, 1);
                        $aBrandsAlpha[$initial][] = $aBrand;
                }               
                return $aBrandsAlpha;
               
    }
       
       
        /**
    * Count the total number of cols.
    *
    * @return integer
    */
    public function countCols()
    {
        return isset($this->columns) ? count($this->columns) : count($this->getBrandCols());
    }

 
       
        public function getBrandCols()
    {
                if (!isset($this->columns)) {
                $this->columns = array_chunk($this->getBrandsAlpha, $this->getColumnsCount);
                }
                return $this->columns;               
    }
         
}


and this is the all_brands.tpl

Code:

<div class="all-brands-section">
    {foreach:getBrandCols(),colKey,colData}
            <div class="colQuarter">
                    {foreach: colData, alphaKey, alphaData}
                    <div class="aplhaBlock">{alphaKey}<br />
                                      {foreach: alphaData, _bKey, _brand}
                        <a href="{buildURL(#brand#,##,_ARRAY_(#brand_id#^_brand.0.brand_id))}" class="all-brands-brand-link" title="{_brand.0.getName()} (products: {_brand.productCount})">                     
                        <span class="all-brands-brand-name">{_brand.0.getName()}{if:isProductCountVisible()}<span class="product-count"> ({_brand.productCount})</span>{end:}</span>
                    </a>
               
                        {end:}
                </div>
              {end:}   
            </div>
    {end:}
</div>   


I am obviously missing something somewhere ....

Thanks for your help

xplorer 11-10-2014 04:46 AM

Re: ShopBy Brand - brand page layout changes
 
Code:

if (!isset($this->brands)) {
    $this->brands = getBrands();
}


Please check the var/log/ directory. I believe you should find a lot of "function getBrands() is not found" errors there.

Do you want to call the getBrands() method from the original class? If so, it should be "$this->getBrands()".

JannieB 11-11-2014 03:37 AM

Re: ShopBy Brand - brand page layout changes
 
Thanks.

I have changed my code but am still getting empty output:

Code:

  public function getBrandsAlpha()
    {
                if (!isset($this->brands)) {
                    $this->brands = $this->getBrands();                 
                }               
               
                $this->aBrandsAlpha = array();
               
                foreach ($this->brands as $k => $aBrand) {
                        $initial = substr($aBrand[0], 0, 1);
                        $this->aBrandsAlpha[$initial][] = $aBrand;
                }               
                return $this->aBrandsAlpha;
               
    }
       
        public function getBrandCols()
    {
                if (!isset($this->columns)) {
                $this->columns = array_chunk($this->getBrandsAlpha(), $this->getColumnsCount());
                }
                return $this->columns;               
    }


If I try and call the getBrandsAlpha function directly - I still get no output.

Where am I going wrong?

Jan

qualiteam 11-11-2014 09:34 PM

Re: ShopBy Brand - brand page layout changes
 
You may try to debug your code by inserting the following code to check what values your custom methods get as parameters, and what these methods return.

Code:

\XLite\Logger::logCustom('debug', var_export($variable, true));

The log file will be var/log/debug.log

If the variable is an object, the dump may become too large, or the script may even hang. So, instead of dumping object use their methods or functions like "count()".

JannieB 11-12-2014 04:24 AM

Re: ShopBy Brand - brand page layout changes
 
Thanks, that has been very helpful.

I realised that the getBrands() function returns an array with the brand id and not the brand name. So I now have my brands coming out in columns as required which is great ... but one question.

How can I get the brand name from within my class? I need to build an array with this structure:

array[initial letter](array[brand])

If I can get the brandname in my class then I can do this. I have tried using the getName function, but this doesn't seem to work (it's from a different class).

You can see the layout I am trying to acheive in the post at the start of this thread.

Help!

xplorer 11-12-2014 09:47 PM

Re: ShopBy Brand - brand page layout changes
 
The getBrands() function is a bit tricky as it returns not an array of brand objects directly, but an array of arrays having the brand model as object with the 0 key.

So, if you want to get the brand name this should work:
Code:

...
foreach ($this->brands as $k => $aBrand) {
    $name = $aBrand[0]->getName();
    ...               
}
...


JannieB 11-13-2014 03:35 AM

Re: ShopBy Brand - brand page layout changes
 
Excellent! I have now got this working.

I do have another question relating to brands and product filters, but I will start a new thread for that.

In case anyone is remotely interested, here is the final code (I put the "initial" in as a variable in the Brands array to make it easier to extract in the template):

These are the relevant functions in my class:
Code:

public function getBrandsAlpha()
    {
        if (!isset($this->brands)) {
                    $this->brands = $this->getBrands();                 
                }               
               
                $this->aBrandsAlpha = array();
               
                foreach ($this->brands as $k => $aBrand) {
                    $brandname = $aBrand[0]->getName();
                      $initial = substr($brandname, 0, 1);
                  $aBrand['initial'] = $initial;
                  $this->aBrandsAlpha[$initial][] = $aBrand;
                }       
       
                return $this->aBrandsAlpha;
       
    }

       
        public function getBrandCols()
    {
                $alphacount = count($this->getBrandsAlpha());
               
                if ($alphacount > 0) {$colcount = $alphacount/$this->getColumnsCount(); } else { $colcount = 1; }
                $colcount = round($colcount);
       
                if (!isset($this->columns)) {
                $this->columns = array_chunk($this->getBrandsAlpha(), $colcount);
                }
               
                return $this->columns;               
    }


and this is the all_brands.tpl code:

Code:

<div class="all-brands-section">
    {foreach:getBrandCols(),colIndex,_col}
            <div class="col{getColumnsCount()}th {getColCSSClass(colIndex)}">     
        {foreach:_col, aKey, _alpha} 
                <div class="alphaBlock">
                <div class="alphaHead">{_alpha.0.initial}</div>
                {foreach:_alpha,brandIndex,_brand}                       
                        <a href="{buildURL(#brand#,##,_ARRAY_(#brand_id#^_brand.0.brand_id))}" class="all-brands-brand-link" title="{_brand.0.getName()} (products: {_brand.productCount}) ">                     
                            <span class="all-brands-brand-name">{_brand.0.getName()}{if:isProductCountVisible()}<span class="product-count"> ({_brand.productCount})</span>{end:}</span>
                        </a>
                  {end:} 
            </div>
        {end:}     
            </div>
    {end:}
</div>


On to the next challenge ....


All times are GMT -8. The time now is 11:08 PM.

Powered by vBulletin Version 3.5.4
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.