Location: PHPKode > projects > Ace Framework > Ace-master/Ace/Datagrid.php
<?php
/**
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * This software consists of voluntary contributions made by many individuals
 * and is licensed under the new BSD license.
 */

require_once 'Ace/Helpers/Javascript.php';
require_once 'Ace/Helpers/Tags.php';

/**
 * @package     Ace
 * @license     http://www.opensource.org/licenses/BSD-3-Clause New BSD license
 * @since       1.0
 */
abstract class Ace_Datagrid
{
    // Constants containing datagrid request parameters
    const REQUEST_PARAMETER_UID = 'uid';
    const REQUEST_PARAMETER_PAGE = 'p';
	const REQUEST_PARAMETER_ORDER = 'o';
	const REQUEST_PARAMETER_SORT = 's';
    const REQUEST_PARAMETER_SEARCH = 'search';
    const REQUEST_PARAMETER_CLEAR = 'clear';

    // Sorting constants
    const ASC = 'asc';
    const DESC = 'desc';

    // Comparators
    const EQUAL = '=';
    const LESS = '<';
    const GRATHER = '>';
    const GRATHER_EQUAL = '>=';
    const LESS_EQUAL = '<=';

    /**
     * Default datagrid decorator
     * @var string
     */
    protected static $default_decorator = 'Ace_Datagrid_Decorator';

    /**
     * Unique id for the datagrid
     * @var integer
     */
    protected $uid = null;

    /**
     * Array with columns and labels
     * @var array
     */
    protected $columns = array();

    /**
     * Columns options
     * @var array
     */
    protected $columns_options = array();

    /**
     * Columns values format
     * @var array
     */
    protected $columns_values_format = array();

    /**
     * Decorator class
     * @var string
     */
    protected $decorator = null;

    /**
     * Row limit
     * @var integer
     */
    protected $limit = 25;

    /**
     * Sorting column
     * @var string
     */
    protected $sort_by = null;

    /**
     * Sort order (asc or desc)
     * @var string
     */
    protected $sort_order = null;

    /**
     * Default sorting column
     * @var string
     */
    protected $default_sort_by = null;

    /**
     * Default sort order
     * @var string
     */
    protected $default_sort_order = null;

    /**
     * Page number
     * @var integer
     */
    protected $page = 1;

    /**
     * Datagrid pager
     * @var Ace_Pager_Adapter_Doctrine
     */
    protected $pager = null;

    /**
     * Search definition
     * @var array
     */
    protected $search_definition = array();

    /**
     * The search values
     * @var array
     */
    protected $search = array();

    /**
     * Contructor.
     *
     * @param mixed $uid
     */
    public function  __construct($uid = null)
    {
        $request = Ace_Context::getInstance()->getRequest();

        is_null($uid) ? $this->uid = Ace_Context::getInstance()->getRequest()->getParameter(self::REQUEST_PARAMETER_UID) : $this->uid = $uid;

        $this->page = $request->getParameter(self::REQUEST_PARAMETER_PAGE, 1);
        $this->sort_by = $request->getParameter(self::REQUEST_PARAMETER_SORT, null);
        $this->sort_order = $request->getParameter(self::REQUEST_PARAMETER_ORDER, null);
        $this->search = $request->getParameter(self::REQUEST_PARAMETER_SEARCH, null);
    }

    /**
     * Gets the datagrid attributes from session and save the new parameters
     *
     * @param boolean $clear
     */
    protected function session($clear = false)
    {
        $user = Ace_Context::getInstance()->getUser();
        $attribute_name = $this->uid;

        $session = $user->getDatagridAttribute($attribute_name);
        $session_items = explode('|', $session);

        if(Ace_Context::getInstance()->getRequest()->getParameter(self::REQUEST_PARAMETER_CLEAR) || $clear === true)
        {
            $user->setDatagridAttribute($attribute_name, '1|||');
        }
        else
        {
            if(count($session_items) > 3 && is_null($this->search))
            {
                $this->search = unserialize($session_items[3]);
            }

            if(count($session_items) >= 4 && is_null($this->sort_by) && is_null($this->sort_order))
            {
                $this->page = empty($session_items[0]) ? 1 : $session_items[0];
                $this->sort_by = empty($session_items[1]) ? null : $session_items[1];
                $this->sort_order = empty($session_items[2]) ? null : $session_items[2];
            }
            else
            {
                $session_value = $this->page . '|' . $this->sort_by . '|' . $this->sort_order . '|' . serialize($this->search);
                $user->setDatagridAttribute($attribute_name, $session_value);
            }
        }
    }

    /**
     * Search values in datagrid
     */
    protected function search()
    {
        if(is_array($this->search))
        {
            foreach($this->search as $key => $value)
            {
                if(array_key_exists($key, $this->columns))
                {
                    if($value !== '')
                    {
                        $this->filter($key, $value);
                    }
                }
                else
                {
                    // Unset value to have no errors
                    unset($this->search[$key]);
                }
            }
        }
    }

    /**
     * Strip comparator for if case
     *
     * @param string $comparator
     * @return string
     */
    protected function stripIf($comparator)
    {
        if($comparator == self::EQUAL)
        {
            return '==';
        }

        return $comparator;
    }

    /**
     * Returns the unique id.
     *
     * @return integer
     * @throws Ace_Exception
     */
    public function getUid()
    {
        if($this->uid)
        {
            return $this->uid;
        }
        else
        {
            throw new Ace_Exception('Datagrid UID was not found');
        }
    }

    /**
     * Returns the pager object.
     * @return Ace_Pager
     */
    public function getPager()
    {
        return $this->pager;
    }

    /**
     * Add the columns in the datagrid.
     *
     * Array values :
     *  * column_id => label
     *
     * @param array $columns
     */
    public function setColumns(array $columns)
    {
        $this->columns = $columns;
    }

    /**
     * Gets the columns.
     *
     * @return array
     */
    public function getColumns()
    {
        return $this->columns;
    }

    /**
     * Sets the columns options.
     *
     * Array values :
     *  * column_id = array('style' => 'width: 200px;')
     *
     * @param array $options
     */
    public function setColumnsOptions(array $options)
    {
        foreach($options as $column => $attributes)
        {
            $this->setColumnOptions($column, $attributes);
        }
    }

    /**
     * Sets the columns options for one column.
     *
     * @param string $column
     * @param array $options
     *
     * @see setColumnsOptions
     */
    public function setColumnOptions($column, array $options)
    {
        if(array_key_exists($column, $this->columns))
        {
            (!isset($this->columns_options[$column])) ? $this->columns_options[$column] = $options : $this->columns_options[$column] = array_merge($this->columns_options[$column], $options);
        }
        else
        {
            throw new InvalidArgumentException(sprintf('The column "%s" was not found', $column));
        }
    }

    /**
     * Gets the columns options.
     *
     * @param string $name
     * @return array
     */
    public function getColumnsOptions($name = null)
    {
        if(is_null($name))
        {
            return $this->columns_options;
        }
        else
        {
            if(array_key_exists($name, $this->columns_options))
            {
                return $this->columns_options[$name];
            }
            else
            {
                return array();
            }
        }
    }

    /**
     * Sets the formating codes for values.
     *
     * @param array $formats
     */
    public function setColumnsValuesFormat(array $formats)
    {
        $this->columns_values_format = $formats;
    }

    /**
     * Gets the formating codes for values.
     *
     * @param  string $column
     * @return mixed
     */
    public function getColumnValuesFormat($column = null)
    {
        if(is_null($column))
        {
            return $this->columns_values_format;
        }
        else
        {
            if(array_key_exists($column, $this->columns_values_format))
            {
                return $this->columns_values_format[$column];
            }
            else
            {
                return false;
            }
        }
    }

    /**
     * Sets the row limit.
     *
     * @param integer $limit
     */
    public function setLimit($limit)
    {
        $this->limit = $limit;
    }

    /**
     * Gets the datagrid decorator.
     *
     * @param null|string $decorator
     * @return Ace_Datagrid_Decorator
     */
    public function getDecorator($decorator = null)
    {
        if(is_null($this->decorator))
        {
            if(is_null($decorator))
            {
                return new self::$default_decorator($this);
            }
            else
            {
                $this->decorator = $decorator;
            }
        }

        if(class_exists($this->decorator))
        {
            $class = $this->decorator;
            return new $class($this);
        }
        else
        {
            throw new InvalidArgumentException(sprintf('The decorator "%s" doesn\'t exists', $this->decorator));
        }
    }

    /**
     * Prepare the datagrid.
     */
    public function prepare()
    {
        if(count($this->columns) > 0)
        {
            $this->session();
            
            if(is_null($this->sort_by))
            {
                $columns_keys = array_keys($this->columns);
                isset($this->default_sort_by) ? $this->sort_by = $this->default_sort_by : $this->sort_by = $columns_keys[0];
            }

            if(is_null($this->sort_order))
            {
                isset($this->default_sort_order) ? $this->sort_order = $this->default_sort_order : $this->sort_order = 'asc';
            }
        }
        else
        {
            throw new InvalidArgumentException('No columns are defined');
        }

        $this->search();
        $this->getIfHaveToBeSorted() ? $this->sort() : null;
    }

    /**
     * Sets the default sorting.
     *
     * @param string $sort_by
     * @param string $sort_order
     */
    public function setDefaultSorting($sort_by, $sort_order = 'asc')
    {
        if(array_key_exists($sort_by, $this->columns))
        {
            $this->default_sort_by = $sort_by;
            $this->default_sort_order = $sort_order;
        }
        else
        {
            throw new InvalidArgumentException(sprintf('The column "%s" was not found', $sort_by));
        }
    }

    /**
     * Gets the sorting by.
     *
     * @return string
     */
    public function getSortBy()
    {
        return $this->sort_by;
    }

    /**
     * Gets sort order.
     *
     * @return string
     */
    public function getSortOrder()
    {
        return $this->sort_order;
    }

    /**
     * Returns the default sorting column.
     *
     * @return string
     */
    public function getDefaultSortBy()
    {
        return $this->default_sort_by;
    }

    /**
     * Returns the default sort order.
     *
     * @return string
     */
    public function getDefaultSortOrder()
    {
        return $this->default_sort_order;
    }

    /**
     * Returns the search attributes
     *
     * @param  string $name
     * @return mixed
     */
    public function getSearchDefinition($name = null)
    {
        if(is_null($name))
        {
            return $this->search_definition;
        }
        else
        {
            if(array_key_exists($name, $this->search_definition))
            {
                return $this->search_definition[$name];
            }
            else
            {
                return array();
            }
        }
    }

    /**
     * Get search values
     *
     * @param  string $name
     * @return mixed
     */
    public function getSearchValues($name = null)
    {
        if(is_null($name))
        {
            return $this->search;
        }
        else
        {
            if(is_array($this->search) && array_key_exists($name, $this->search))
            {
                return $this->search[$name];
            }
            else
            {
                return null;
            }
        }
    }

    /**
     * Sets the search definition
     * 
     * @param array $search
     */
    public function setSearchDefinition($search)
    {
        foreach($search as $key => $type)
        {
            if(array_key_exists($key, $this->columns))
            {
                if(!is_array($type))
                {
                    $type = array('type' => $type);
                }
                
                if(array_key_exists('type', $type))
                {
                    $this->search_definition[$key] = $type;
                }
                else
                {
                    throw new InvalidArgumentException(sprintf('You have to provide "type" for the search definition of the column "%s"', $key));
                }
            }
            else
            {
                throw new InvalidArgumentException(sprintf('The column "%s" doesn\'t exist', $key));
            }
        }
    }

    /**
     * Render the datagrid.
     *
     * @param  string $uid Unique name for the datagrid container
     * @param  string $url Url of the datagrid
     * @return string
     */
    public static function render($uid, $url)
    {
        self::addStylesAndScripts();
        strpos($url, '?') ? $url.= '&' . self::REQUEST_PARAMETER_UID . '=' . $uid : $url.= '?' . self::REQUEST_PARAMETER_UID . '=' . $uid;
        return content_tag('div', javascript_tag(remote_function(array('update' => $uid, 'url' => $url, 'type' => 'synchronous'))), array('id' => $uid));
    }

    /**
     * Add the stylesheet and the javascripts to the response
     */
    public static function addStylesAndScripts()
    {
        $response = Ace_Context::getInstance()->getResponse();

        $response->addStylesheet(Ace_Registry::get('application.data.directory', '/data') . '/datagrid/css/datagrid.css');
        $response->addJavascript(Ace_Registry::get('application.data.directory', '/data') . '/datagrid/js/datagrid.js');
    }

    /**
     * Sets the default decorator
     * 
     * @param string $decorator
     */
    public static function setDefaultDecorator($decorator)
    {
        if(class_exists($decorator))
        {
            self::$default_decorator = $decorator;
        }
        else
        {
            throw new Ace_Exception(sprintf('The decorator "%s" dosen\' exists', $decorator));
        }
    }

    /**
     * Get if the datas must have to be sorted
     *
     * @return bool
     */
    public function getIfHaveToBeSorted()
    {
        foreach($this->columns as $column => $label)
        {
            if(array_key_exists($column, $this->columns_options))
            {
                if(array_key_exists('sorting', $this->columns_options[$column]))
                {
                    if($this->columns_options[$column]['sorting'])
                    {
                        return true;
                    }
                }
                else
                {
                    return true;
                }
            }
            else
            {
                return true;
            }
        }

        return false;
    }

    /**
     * Gets the results of the datagrid.
     */
    public abstract function getResults();

    /**
     * Sort values
     */
    protected abstract function sort();

    /**
     * Filter a search value
     */
    protected abstract function filter($key, $value);
}
Return current item: Ace Framework