<?PHP

#
#   FILE:  PrivilegeFactory.php
#
#   METHODS PROVIDED:
#       PrivilegeFactory()
#           - constructor
#       SomeMethod($SomeParameter, $AnotherParameter)
#           - short description of method
#
#   AUTHOR:  Edward Almasy
#
#   Part of the Collection Workflow Integration System
#   Copyright 2007 Edward Almasy and Internet Scout
#   http://scout.wisc.edu
#

  /**
   * Factory which extracts all defined privileges from the database
   * \nosubgrouping
   */

class PrivilegeFactory extends ItemFactory {

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

    /** @name Setup/Initialization */
    /*@{*/

    /** Object constructor */
    public function PrivilegeFactory()
    {
        $this->ItemFactory("Privilege", "CustomPrivileges", "Id", "Name");

        $AllConstants = get_defined_constants(TRUE);
        $UserConstants = $AllConstants["user"];

        foreach ($UserConstants as $Name => $Value)
        {
            if (strpos($Name, "PRIV_") === 0)
            {
                $this->PrivilegeConstants[$Value] = $Name;
            }
        }
    }

    /*@}*/

    /** @name Accessors */
    /*@{*/

    /**
     * Get all privileges
     * @param IncludePredefined (OPTIONAL)
     * @param ReturnObjects (OPTIONAL)
     * @return An array of privilege objects or strings with
     *   the priv id for the index
     */
    public function GetPrivileges($IncludePredefined = TRUE, $ReturnObjects = TRUE)
    {
        # if caller wants predefined privileges included
        if ($IncludePredefined)
        {
            # get complete list of privilege names
            $PrivNames = $this->GetItemNames();
        }
        else
        {
            # read in only custom privileges from DB
            $PrivNames = parent::GetItemNames();
        }

        # if caller requested objects to be returned
        if ($ReturnObjects)
        {
            # convert strings to objects and return to caller
            foreach ($PrivNames as $Id => $Name)
            {
                $PrivObjects[$Id] = new Privilege($Id);
            }
            return $PrivObjects;
        }
        else
        {
            # return strings to caller
            return $PrivNames;
        }
    }

    /**
     * Get the Privilege object with the given name.
     * @param $Name privilege name
     * @return a Privilege object or NULL if one doesn't exist with the name
     */
    public function GetPrivilegeWithName($Name)
    {
        global $G_PrivDescriptions;

        # predefined privilege constant name
        if (in_array($Name, $this->PrivilegeConstants))
        {
            $Id = array_search($Name, $this->PrivilegeConstants);
            $Privilege = new Privilege($Id);

            return $Privilege;
        }

        # predefined privilege constant description
        if (in_array($Name, $G_PrivDescriptions))
        {
            $ConstantName = array_search($Name, $G_PrivDescriptions);
            $Id = array_search($ConstantName, $this->PrivilegeConstants);
            $Privilege = new Privilege($Id);

            return $Privilege;
        }

        $CustomPrivileges = $this->GetPrivileges(FALSE, FALSE);

        # custom privilege name
        foreach ($CustomPrivileges as $Id => $PrivilegeName)
        {
            if ($Name == $PrivilegeName)
            {
                $Privilege = new Privilege($Id);

                return $Privilege;
            }
        }

        return NULL;
    }

    /**
     * Get the Privilege object with the given value.
     * @param $Value privilege value
     * @return a Privilege object or NULL if one doesn't exist with the value
     */
    public function GetPrivilegeWithValue($Value)
    {
        global $G_PrivDescriptions;

        # predefined privilege constant name
        if (array_key_exists($Value, $this->PrivilegeConstants))
        {
            $Privilege = new Privilege($Value);

            return $Privilege;
        }

        $CustomPrivileges = $this->GetPrivileges(FALSE, FALSE);

        # custom privilege name
        foreach ($CustomPrivileges as $Id => $PrivilegeName)
        {
            if ($Value == $Id)
            {
                $Privilege = new Privilege($Id);

                return $Privilege;
            }
        }

        return NULL;
    }

    /**
     * Get all predefined privilege constants and their values.
     * @return an array with the privilege ID as the key
     */
    public function GetPredefinedPrivilegeConstants()
    {
        return $this->PrivilegeConstants;
    }

    /**
    * Retrieve human-readable privilege names.  This method overloads the inherited
    * version from ItemFactory to add in the predefined privileges.
    * @param SqlCondition SQL condition (w/o "WHERE") for name retrieval. (OPTIONAL)
    * @return Array with item names as values and item IDs as indexes
    */
    function GetItemNames($SqlCondition = NULL)
    {
        $Names = parent::GetItemNames($SqlCondition);
        $Names = $Names + $GLOBALS["G_PrivDescriptions"];
        asort($Names);
        return $Names;
    }

    /*@}*/

    /** @name Predicates */
    /*@{*/

    /**
     * Determine if a privilege with the given name exists.
     * @param $Name privilege name
     * @return TRUE if a privilege with the given name exists
     */
    public function PrivilegeNameExists($Name)
    {
        global $G_PrivDescriptions;

        # predefined privilege constant name
        if (in_array($Name, $this->PrivilegeConstants))
        {
            return TRUE;
        }

        # predefined privilege constant description
        if (in_array($Name, $G_PrivDescriptions))
        {
            return TRUE;
        }

        $CustomPrivileges = $this->GetPrivileges(FALSE, FALSE);

        # custom privilege name
        if (in_array($Name, $CustomPrivileges))
        {
            return TRUE;
        }

        return FALSE;
    }

    /**
     * Determine if a privilege with the given value exists.
     * @param $Value privilege value
     * @return TRUE if a privilege with the given value exists
     */
    public function PrivilegeValueExists($Value)
    {
        # predefined privilege constant name
        if (array_key_exists($Value, $this->PrivilegeConstants))
        {
            return TRUE;
        }

        $CustomPrivileges = $this->GetPrivileges(FALSE);

        foreach ($CustomPrivileges as $Privilege)
        {
            if ($Value == $Privilege->Id())
            {
                return TRUE;
            }
        }

        return FALSE;
    }

    /*@}*/

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

    private $PrivilegeConstants = array();

}
