<?php

/**
 * The definition for the contact_query class.
 *
 * @package CGContacts
 * @category Utilities
 * @author  calguy1000 <calguy1000@cmsmadesimple.org>
 * @copyright Copyright 2014 by Robert Campbell
 */

namespace CGContacts;

/**
 * This class contains all of the parameters required to collect a series of contacts matching a criteria.
 *
 * @property int[] $idlist Array of integer ids to return.  If set, the name, fullname, category, and catchildren properties are reset.
 * @property int $limit The maximum number of records to return.  The default value is 500.
 * @property int $offset The start position within the matched values to return.  The default value is 0
 * @property string $sortby The column to sort on.  Possible values are: modified,fullname,nickname,display_name,title,company,role.  The default value is modified.
 * @property string $sortorder The sort order.  Possible values are ASC and DESC.  Default value is 'ASC';
 * @proeprty string $name Search on name (or parts of a name).  Wildcard characters are accepted.  If set, the idlist and fullname properties are reset.
 * @property string $category A comma separated list of category names, or ids to filter upon.
 * @property int $modified_since Filter all contacts that were last modified after this unix timestamp.
 * @property string propclass[0-9]
 * @property string propval[0-9]
 * @property bool $catchildren Optionally include, or exclude the children categories of the specified categories from the results.  Default value is false.
 */
final class contact_query extends \CGExtensions\query\query
{
    /**
     * @ignore
     */
    private $_data = array('modified_since'=>null,'idlist'=>null,'limit'=>500,'offset'=>0,'sortby'=>'fullname','sortorder'=>'asc','category'=>null,'catchildren'=>null,
                           'feu_uid'=>null,'name'=>null,'fullname'=>null,'props'=>array(),'uselike'=>false);

    /**
     * Constructor.
     *
     * @param array $parms An array of properties for this object.
     */
    public function __construct($parms = array())
    {
        foreach( $parms as $key => $val ) {
            if( !in_array($key,array_keys($this->_data)) ) continue; // ignore unknowns
            $this[$key] = $val;
        }
    }

    /**
     * @ignore
     */
    public function OffsetGet($key)
    {
        if( array_key_exists($key,$this->_data) ) return $this->_data[$key];
    }

    /**
     * @ignore
     */
    public function OffsetSet($key,$value)
    {
        switch( $key ) {
        case 'idlist':
            if( is_array($value) && count($value) ) {
                // clean up the idlist
                $tmp = array();
                foreach( $value as $one ) {
                    $one = (int) $one;
                    $tmp[] = $one;
                }
                $tmp = array_unique($tmp);
                if( count($tmp) ) $this->_data[$key] = $tmp;
            }
            $this->_data['name'] = null;
            $this->_data['category'] = null;
            $this->_data['catchildren'] = null;
            break;

        case 'uselike':
            $this->_data[$key] = cms_to_bool($value);
            break;

        case 'modified_since':
            if( !$value ) {
                $value = strtotime($value);
            }
            $this->_data[$key] = $value;
            break;

        case 'fullname':
            $value = trim($value);
            $this->_data[$key] = $value;
            $this->_data['idlist'] = null;
            $this->_data['name'] = null;
            break;

        case 'name':
            $value = trim($value);
            $this->_data[$key] = $value;
            $this->_data['idlist'] = null;
            $this->_data['fullname'] = null;
            break;

        case 'feu_uid':
            $value = (int) $value;
            $this->_data[$key] = $value;
            break;

        case 'category':
            $this->_data[$key] = $value;
            $this->_data['idlist'] = null;
            break;

        case 'catchildren':
            $this->_data[$key] = \cge_utils::to_bool($value);
            $this->_data['idlist'] = null;
            break;

        case 'limit':
            $value = max(1,min(1000,(int)$value));
            $this->_data[$key] = $value;
            break;

        case 'offset':
            $val = max(0,min(9000000,(int)$value));
            $this->_data[$key] = $value;
            break;

        case 'sortby':
            $value = trim(strtolower($value));
            switch( $value ) {
            case 'modified':
            case 'fullname':
            case 'nickname':
            case 'display_name': // special value
            case 'title':
            case 'company':
            case 'role':
                $this->_data[$key] = $value;
                break;

            default:
                throw new \CmsInvalidDataException('Invalid sortby value '.$value.' for '.__CLASS__);
            }
            break;

        case 'sortorder':
            $value = trim(strtoupper($value));
            switch( $value ) {
            case 'ASC':
            case 'DESC':
                $this->_data[$key] = $value;
                break;

            default:
                throw new \CmsInvalidDataException('Invalid sortorder value '.$value.' for '.__CLASS__);
            }
            break;

        default:
            if( startswith($key,'propclass') || startswith($key,'propval') || startswith($key,'proplabel') ) {
                $this->_data['props'][$key] = $val;
            }
            else {
                throw new \CmsInvalidDataException($key.' is not a valid property for a '.__CLASS__.' object');
            }
        }
    }

    /**
     * @ignore
     */
    public function OffsetExists($key)
    {
        if( isset($this->_data[$key]) ) return TRUE;
        return FALSE;
    }

    /**
     * @ignore
     */
    public function OffsetUnset($key)
    {
        // do nothing
    }

    /**
     * Execute the query.
     *
     * @return contact_resultset
     */
    public function &execute()
    {
        $rs = new contact_resultset($this);
        return $rs;
    }
} // end of class

?>
