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

/**
* CWIS-specific user factory class.
*/
class CWUserFactory extends UserFactory
{
    # ---- PUBLIC INTERFACE --------------------------------------------------

    /**
    * Construct the user factory object.
    */
    public function __construct()
    {
        parent::UserFactory();
        $this->ResourceFactory = new ResourceFactory(MetadataSchema::SCHEMAID_USER);
    }

    /**
    * Get a list of users sorted by how many resources they have added or
    * edited, starting with those who have added/edited the most.
    * @param int $Limit The maximum number of users to return.  (OPTIONAL,
    *       defaults to 5.)
    * @return array List of users, with user IDs for the index and CWUser
    *       objects for the values.
    */
    function GetTopContributors($Limit = 5)
    {
        # assume no users will be found
        $Users = array();

        # fetch the top contributors
        $this->DB->Query("SELECT U.*"
                ." FROM APUsers U, Resources R"
                ." WHERE U.UserId = R.LastModifiedById"
                ." GROUP BY R.LastModifiedById"
                ." ORDER BY COUNT(*) DESC"
                ." LIMIT ".intval($Limit));
        $UserIds = $this->DB->FetchColumn("UserId");

        # for each user id found
        foreach ($UserIds as $UserId)
        {
            $Users[$UserId] = new CWUser($UserId);
        }

        # return the newest users
        return $Users;
    }

    /**
    * Get the users sorted by when they last added or edited a resource
    * starting with those who added/edited a resource most recently.
    * @param int $Limit The maximum number of users to return.  (OPTIONAL,
    *       defaults to 5.)
    * @return array List of users, with user IDs for the index and CWUser
    *       objects for the values.
    */
    function GetMostRecentContributors($Limit = 5)
    {
        # assume no users will be found
        $Users = array();

        # fetch the top contributors
        $this->DB->Query("SELECT U.*"
                ." FROM APUsers U, Resources R"
                ." WHERE U.UserId = R.LastModifiedById"
                ." GROUP BY U.UserId"
                ." ORDER BY MAX(R.DateLastModified) DESC"
                ." LIMIT ".intval($Limit));
        $UserIds = $this->DB->FetchColumn("UserId");

        # for each user id found
        foreach ($UserIds as $UserId)
        {
            $Users[$UserId] = new CWUser($UserId);
        }

        # return the newest users
        return $Users;
    }

    # ---- OVERRIDDEN METHODS ------------------------------------------------

    /**
    * Create a new user. The second password and e-mail address parameters are
    * intended for second copies of each entered by the user.
    * @param string $UserName Login name for new user.
    * @param string $Password Password for new user.
    * @param string $PasswordAgain Second copy of password entered by user.
    * @param string $EMail E-mail address for new user.
    * @param string $EMailAgain Second copy of e-mail address entered by user.
    * @param bool $IgnoreErrorCodes Array containing any error codes that should
    *       be ignored.  (OPTIONAL)
    * @return CWUser object or array of error codes.
    */
    function CreateNewUser(
            $UserName, $Password, $PasswordAgain, $EMail, $EMailAgain,
            $IgnoreErrorCodes = NULL)
    {
        # add the user to the APUsers table
        $User = parent::CreateNewUser(
            $UserName,
            $Password,
            $PasswordAgain,
            $EMail,
            $EMailAgain,
            $IgnoreErrorCodes);

        # user account creation did not succeed, so return the error codes
        if (!($User instanceof User))
        {
            return $User;
        }

        # create the user resource
        $Resource = Resource::Create(MetadataSchema::SCHEMAID_USER);

        # set the user ID for the resource
        $Resource->Set("UserId", $User->Id());

        $Schema = new MetadataSchema(MetadataSchema::SCHEMAID_USER);
        $TimestampFields = $Schema->GetFields(MetadataSchema::MDFTYPE_TIMESTAMP);

        # update timestamps as required
        foreach ($TimestampFields as $Field)
        {
            if ($Field->UpdateMethod()
                == MetadataField::UPDATEMETHOD_ONRECORDEDIT)
            {
                $Resource->Set($Field, "now");
            }
        }

        # make the user resource permanent
        $Resource->IsTempResource(FALSE);

        # get the CWUser object for the user
        $CWUser = new CWUser(intval($User->Id()));

        # couldn't get the CWUser object
        if ($CWUser->Status() != U_OKAY)
        {
            return array($CWUser->Status());
        }

        # return new user object to caller
        return $CWUser;
    }

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

    /**
    * The resource factory for user resources.
    */
    protected $ResourceFactory;

}
