1
votes

I'm trying to implement a function to be able to add directional (up / down) icons next to each of the table headers for a pagination table within CakePHP.

My current code is as follows:

$sort_key = $this->Paginator->sortKey();
$type = $this->Paginator->sortDir() === 'asc' ? 'up' : 'down';

function sortArrows($key, $title, $sort_key, $type)
{

    $type_opposite = ($type === 'asc' ? 'down' : 'up');

    if($key == $sort_key)
    {
        $icon = "&nbsp;<i class='fa fa-angle-" . $type . "'></i>";
    }
    else
    {
        $icon = "&nbsp;<i class='fa fa-angle-" . $type_opposite  . "'></i>";
    }

    return "'$key', '$title' " . "$icon";
}

Which I am calling on the page as (on each of the table header fields):

<?php echo $this->Paginator->sort(sortArrows('street_suburb', 'Suburb', $sort_key, $type), array('escape' => false)); ?>

This produces the following error:

Notice (8): Array to string conversion [CORE/Cake/View/Helper/HtmlHelper.php, line 372]

I think I am quite close to what I need, I just cannot figure out what I am returning incorrectly from the function to get this to work.

Thanks

2
CakePHP already provides the sort arrow requirements in form of css classes you can leverage. No need to rebuilt the same this complicated with custom PHP code.mark
Does it? I could't find anything about this on the cakephp docs.sluggerdog
Yes, it automatically sets the asc/desc classes. Check the source code after paginating. This you can leverage - and is a more sane and advanced approach than injecting custom strings of HTML.mark
Ahh thanks. I see that now. Using that instead.sluggerdog

2 Answers

1
votes

Inspired by your solution I have created a Helper extending PaginatorHelper to solve the problem.

Here is the code of file name MyPaginatorHelper.php:

<?php

namespace App\View\Helper;

use Cake\View\Helper\PaginatorHelper;
use Cake\Utility\Inflector;

class MyPaginatorHelper extends PaginatorHelper
{

    public function sort($key, $title = null, array $options = [])
    {
        if (empty($title)) {
            $title = $key;

            if (strpos($title, '.') !== false) {
                $title = str_replace('.', ' ', $title);
            }

            $title = __(Inflector::humanize(preg_replace('/_id$/', '', $title)));
        }

        $sortKey = $this->sortKey();
        if (strpos($sortKey, '.') !== false) {
            $sortKey = substr($sortKey, strpos($sortKey, '.')+1);
        }

        $sortDir = $this->sortDir() === 'asc' ? 'up' : 'down';

        if($key == $sortKey)
        {
            $title .= "&nbsp;<i class='fa fa-angle-" . $sortDir . "'></i>";
            $options['escape'] = false;
        }

        return parent::sort($key, $title, $options);
    }
}

To use this helper you have to add this line in the AppView::initialize() method:

$this->loadHelper('Paginator', ['className' => 'MyPaginator']);

And then all the Paginator->sort() calls will have this feature by default.

0
votes

I ended up coming up with a solution however I don't know if it is the best way around it. It does work however.

<?php
    $sort_key = $this->Paginator->sortKey();
    $type = $this->Paginator->sortDir() === 'asc' ? 'up' : 'down';
    function sortArrows($key, $title, $sort_key, $type)
    {

        if($key == $sort_key)
        {
            $icon = "&nbsp;<i class='fa fa-angle-" . $type . "'></i>";
            return $title . " " . $icon;
        }
        else
        {
            return $title;
        }


    }
    ?>

Called like:

<?php echo $this->Paginator->sort('street_suburb', sortArrows('street_suburb', 'Suburb', $sort_key, $type), array('escape' => false)); ?>