<?PHP
#
#   FILE:  ControlledNameFactory.php
#
#   Part of the Collection Workflow Integration System (CWIS)
#   Copyright 2011-2013 Edward Almasy and Internet Scout Research Group
#   http://scout.wisc.edu/cwis/
#

/**
* Factory for manipulating ControlledName objects.
*/
class ControlledNameFactory extends ItemFactory
{

    # ---- PUBLIC INTERFACE --------------------------------------------------

    /**
    * Constructor for ControlledNameFactory class.
    * @param int $FieldId ID of Controlled Name metadata field.  (OPTIONAL)
    */
    public function __construct($FieldId = NULL)
    {
        # save field ID for our later use
        $this->FieldId = $FieldId;

        # set up item factory base class
        parent::__construct("ControlledName", "ControlledNames",
                "ControlledNameId", "ControlledName", FALSE,
                ($FieldId ? "FieldId = ".intval($FieldId) : NULL));
    }

    /**
    * Determine how many resources have controlled names (associated with this
    *   metadata field) assigned to them.
    * @return Count of resources with names assigned.
    **/
    public function GetUsageCount()
    {
        return $this->DB->Query(
                "SELECT COUNT(DISTINCT RNI.ResourceId) AS ResourceCount"
                ." FROM ResourceNameInts RNI, ControlledNames CN"
                ." WHERE CN.FieldId = ".intval($this->FieldId)
                ." AND RNI.ControlledNameId = CN.ControlledNameId"
                ." AND RNI.ResourceId >= 0",
                "ResourceCount");
    }


    /**
    * Retrieve recently used items matching a search string.
    * @param string $SearchString String to match
    * @param int $NumberOfResults Number of results to return.  (OPTIONAL,
    *       defaults to 5)
    * @param array $IdExclusions List of IDs of items to exclude.
    * @param array $ValueExclusions List of names of items to exclude.
    * @return array List of item names, with item IDs for index.
    */
    public function FindMatchingRecentlyUsedValues($SearchString, $NumberOfResults=5,
            $IdExclusions=array(), $ValueExclusions=array() )
    {
        # return no results if empty search string passed in
        if (!strlen(trim($SearchString))) {  return array();  }

        $IdExclusionSql = (count($IdExclusions)>0)
                ? "AND ControlledNameId NOT IN ("
                        .implode(',', array_map('intval', $IdExclusions)).")"
                : "";

        $ValueExclusionSql = (count($ValueExclusions)>0)
                ? "AND ControlledName NOT IN ("
                        .implode(',', array_map(
                        function($v){ return "'".addslashes($v)."'"; },
                        $ValueExclusions) ).")"
                : "";

        # mark all search elements as required
        $SearchString = preg_replace("%\S+%", "+\$0", $SearchString);

        $QueryString =
            "SELECT ControlledNameId, ControlledName FROM ControlledNames "
            ."WHERE FieldId=".$this->FieldId
            ." AND LastAssigned IS NOT NULL"
            ." AND MATCH(ControlledName) AGAINST ('"
                    .addslashes(trim($SearchString))."' IN BOOLEAN MODE)"
            ." ".$IdExclusionSql
            ." ".$ValueExclusionSql
            ." ORDER BY LastAssigned DESC LIMIT ".$NumberOfResults;

        $this->DB->Query($QueryString);

        $Names = $this->DB->FetchColumn("ControlledName", "ControlledNameId");

        return $Names;
    }

    # ---- PRIVATE INTERFACE -------------------------------------------------

    private $FieldId;
}
