<?php
/**
 * phpaga
 *
 * Persons management functionality.
 *
 * This file contains the necessary routines to manage persons.
 *
 * @author Florian Lanthaler <florian@phpaga.net>
 * @version $Id: persons.php 653 2005-10-03 21:53:26Z worf $
 *
 * Copyright (c) 2002, Florian Lanthaler <florian@phpaga.net>
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *    * Redistributions of source code must retain the above copyright
 *      notice, this list of conditions and the following disclaimer.
 *
 *    * Redistributions in binary form must reproduce the above copyright
 *      notice, this list of conditions and the following disclaimer in
 *      the documentation and/or other materials provided with the
 *      distribution.
 *
 *    * Neither the name of Florian Lanthaler nor the names of his
 *      contributors may be used to endorse or promote products derived
 *      from this software without specific prior written permission.
 *
 * 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.
 */


/**
 * Gets the total hours worked by a person
 *
 * @param int     $peID      Person ID
 * @param string  $duration  Duration
 *
 * @return int    $result    A result code.
 *
 * @author Florian Lanthaler <florian@phpaga.net>
 * @since phpaga 0.1
 */

function phpaga_persons_getHours ($peID = 0, &$duration)
{
    $duration = "";

    if (!isset($peID) || !is_numeric($peID))
        return PHPAGA_ERR_PROJECT_INVALIDID;

    phpaga_db_connect($db);

    $query = "SELECT SUM(op_duration) AS duration ".
        "FROM operations ".
        "WHERE pe_id = ".$db->quoteSmart($peID);

    $result = $db->query($query);

    if (DB::isError($result))
        return PHPAGA_ERR_DB_EXEC_QUERY;

    if ($result->numRows() < 1)
        $duration = phpaga_minutes2duration(0);
    else
        if ($qrow = $result->fetchRow())
            if ($qrow["duration"] == "")
                $duration = phpaga_minutes2duration(0);
            else
                $duration = phpaga_minutes2duration($qrow["duration"]);

    $result->free();
    return PHPAGA_ERR_NONE;
}


/**
 * Gets a person's statistics from the database.
 *
 * @param int    $peID    Person's ID
 * @param array  $upeStat Person's statistics
 *
 * @return int   $result  A result code.
 *
 * @author Florian Lanthaler <florian@phpaga.net>
 * @since phpaga 0.1
 */

function phpaga_persons_getStat ($peID,
                                 &$peStat)
{
    $peStat = array();
    $errors = 0;

    if (!isset($peID) || (!is_numeric($peID)))
        return PHPAGA_ERR_PERSON_INVALIDID;

    phpaga_db_connect($db);

    /* count total number of operations */

    $query = "SELECT count(op_id) AS totaloperations ".
        "FROM operations ".
        "WHERE pe_id = ".$db->quoteSmart($peID);

    $result = $db->query($query);

    if ($result != false)
    {

        $qrow = $result->fetchRow();
        $result->free();

        if ($qrow)
            if ($qrow["totaloperations"] != "")
                $peStat["operations"] = $qrow["totaloperations"];
            else
                $peStat["operations"] = "-";
    }

    phpaga_persons_getHours($peID, $duration);
    $peStat["hours"] = $duration;

    return PHPAGA_ERR_NONE;
}


/**
 * Gets a list of person categories from the database and returns them
 * as the content of an array.
 *
 * @param array  $pecatList  Array of person categories
 *
 * @return int   $result     A result code.
 *
 * @author Florian Lanthaler <florian@phpaga.net>
 * @since phpaga 0.1
 */

function phpaga_persons_getCategoryList (&$pecatList)
{
    $pecatList = array();

    phpaga_db_connect($db);

    $query = "SELECT pecat_id, pecat_title ".
        "FROM personcat ".
        "ORDER BY pecat_title";

    $result = $db->query($query);

    if (DB::isError($result))
        return PHPAGA_ERR_DB_EXEC_QUERY;

    while ($qrow = $result->fetchRow())
    {
        phpaga_sanitizearray($qrow);
        $pecatList[$qrow["pecat_id"]] = $qrow["pecat_title"];
    }

    $result->free();
    return PHPAGA_ERR_NONE;
}


/**
 * Checks if all fields of a person contain valid values.
 *
 * @param  array  $peInfo  Array containing the project's information.
 *
 * @return array  $errors   Array containing error codes
 *
 * @author Florian Lanthaler <florian@phpaga.net>
 * @since phpaga 0.1
 */

function phpaga_persons_validdata ($peInfo)
{

    $errors = array();

    if (!is_array($peInfo))
        $peInfo = array($peInfo);

    if (isset($peInfo["pe_email"]) && strlen($peInfo["pe_email"])
        && !phpaga_checkemailaddress($peInfo["pe_email"]))
        $errors[] = PHPAGA_ERR_INVALID_EMAIL;

    if (!isset($peInfo["pe_lastname"]) || !strlen($peInfo["pe_lastname"]))
        $errors[] = PHPAGA_ERR_PERSON_INVALIDLASTNAME;

    if (isset($peInfo["ctr_id"]) && !is_numeric($peInfo["ctr_id"]))
        $errors[] = PHPAGA_ERR_COUNTRY_INVALIDID;

    if (isset($peInfo["pecat_id"]) && strlen($peInfo["pecat_id"]) && !is_numeric($peInfo["pecat_id"]))
        $errors[] = PHPAGA_ERR_PECAT_INVALIDID;

    if (isset($peInfo["pe_hourlyrate"]) && strlen($peInfo["pe_hourlyrate"]) && !is_numeric($peInfo["pe_hourlyrate"]))
        $errors[] = PHPAGA_ERR_INVALID_HOURLYRATE;

    return $errors;
}


/**
 * Adds a person to the database
 *
 * @param array  $peInfo         Array containing the person information
 * @param int    $peID           ID of the freshly inserted person
 *
 * @return int   $result         A result code.
 *
 * @author Florian Lanthaler <florian@phpaga.net>
 * @since phpaga 0.1
 */

function phpaga_persons_add ($peInfo, &$peID)
{

    $peID = "";

    $result = phpaga_persons_validdata($peInfo);

    if (count ($result) > 0)
        return $result;

    phpaga_db_connect($db);

    $peID = $db->nextId("persons_pe_id");

    if (!isset($peInfo["pe_lastname"]) || !strlen($peInfo["pe_lastname"]))
        $peInfo["pe_lastname"] = NULL;

    if (!isset($peInfo["pe_firstname"]) || !strlen($peInfo["pe_firstname"]))
        $peInfo["pe_firstname"] = NULL;

    if (!isset($peInfo["pe_address"]) || !strlen($peInfo["pe_address"]))
        $peInfo["pe_address"] = NULL;

    if (!isset($peInfo["pe_address2"]) || !strlen($peInfo["pe_address2"]))
        $peInfo["pe_address2"] = NULL;

    if (!isset($peInfo["pe_city"]) || !strlen($peInfo["pe_city"]))
        $peInfo["pe_city"] = NULL;

    if (!isset($peInfo["pe_zip"]) || !strlen($peInfo["pe_zip"]))
        $peInfo["pe_zip"] = NULL;

    if (!isset($peInfo["pe_region"]) || !strlen($peInfo["pe_region"]))
        $peInfo["pe_region"] = NULL;

    if (!isset($peInfo["ctr_id"]) || !is_numeric($peInfo["ctr_id"]))
        $peInfo["ctr_id"] = NULL;

    if (!isset($peInfo["pecat_id"]) || !is_numeric($peInfo["pecat_id"]))
        $peInfo["pecat_id"] = NULL;

    if (!isset($peInfo["pe_taxnr"]) || ! strlen($peInfo["pe_taxnr"]))
        $peInfo["pe_taxnr"] = NULL;

    if (!isset($peInfo["pe_url"]) || !strlen($peInfo["pe_url"]))
        $peInfo["pe_url"] = NULL;

    if (!isset($peInfo["pe_phonework"]) || !strlen($peInfo["pe_phonework"]))
        $peInfo["pe_phonework"] = NULL;

    if (!isset($peInfo["pe_phonemobile"]) || !strlen($peInfo["pe_phonemobile"]))
        $peInfo["pe_phonemobile"] = NULL;

    if (!isset($peInfo["pe_phonehome"]) || !strlen($peInfo["pe_phonehome"]))
        $peInfo["pe_phonehome"] = NULL;

    if (!isset($peInfo["pe_fax"]) || !strlen($peInfo["pe_fax"]))
        $peInfo["pe_fax"] = NULL;

    if (!isset($peInfo["pe_email"]) || !strlen($peInfo["pe_email"]))
        $peInfo["pe_email"] = NULL;

    if (!isset($peInfo["cpn_id"]) || !is_numeric($peInfo["cpn_id"]))
        $peInfo["cpn_id"] = NULL;

    if (!isset($peInfo["jcat_id"]) || !is_numeric($peInfo["jcat_id"]))
        $peInfo["jcat_id"] = NULL;

    if (!isset($peInfo["pe_hourlyrate"]) || !is_numeric($peInfo["pe_hourlyrate"]))
        $peInfo["pe_hourlyrate"] = NULL;

    if (!isset($peInfo["pe_note"]) || !strlen($peInfo["pe_note"]))
        $peInfo["pe_note"] = NULL;

    if (!isset($peInfo["pe_fotoname"]) || !strlen($peInfo["pe_fotoname"]))
        $peInfo["pe_fotoname"] = NULL;

    if (!isset($peInfo["pe_pe_id"]))
        $peInfo["pe_pe_id"] = $peID;

    $fields = array("pe_id" => $peID,
                    "pe_lastname" => $peInfo["pe_lastname"],
                    "pe_firstname" => $peInfo["pe_firstname"],
                    "pe_address" => $peInfo["pe_address"],
                    "pe_address2" => $peInfo["pe_address2"],
                    "pe_city" => $peInfo["pe_city"],
                    "pe_zip" => $peInfo["pe_zip"],
                    "pe_region" => $peInfo["pe_region"],
                    "ctr_id" => $peInfo["ctr_id"],
                    "pecat_id" => $peInfo["pecat_id"],
                    "pe_hourlyrate" => $peInfo["pe_hourlyrate"],
                    "pe_taxnr" => $peInfo["pe_taxnr"],
                    "pe_url" => $peInfo["pe_url"],
                    "pe_phonework" => $peInfo["pe_phonework"],
                    "pe_phonemobile" => $peInfo["pe_phonemobile"],
                    "pe_phonehome" => $peInfo["pe_phonehome"],
                    "pe_fax" => $peInfo["pe_fax"],
                    "pe_email" => $peInfo["pe_email"],
                    "cpn_id" => $peInfo["cpn_id"],
                    "jcat_id" => $peInfo["jcat_id"],
                    "pe_note" => $peInfo["pe_note"],
                    "pe_fotoname" => $peInfo["pe_fotoname"],
                    "pe_pe_id" => $peInfo["pe_pe_id"]
        );

    $result = $db->autoExecute("persons", $fields, DB_AUTOQUERY_INSERT);

    if (DB::isError($result))
        return PHPAGA_ERR_DB_EXEC_QUERY;
    else
        return PHPAGA_ERR_NONE;
}


/**
 * Updates a person
 *
 * @param array  $peInfo Array containing the person information
 *
 * @return int   $result  A result code.
 *
 * @author Florian Lanthaler <florian@phpaga.net>
 * @since phpaga 0.1
 */

function phpaga_persons_update ($peInfo)
{


    $result = phpaga_persons_validdata ($peInfo);

    if (count ($result) > 0)
        return $result;

    phpaga_db_connect($db);

    if (!isset($peInfo["pe_lastname"]) || !strlen($peInfo["pe_lastname"]))
        $peInfo["pe_lastname"] = NULL;

    if (!isset($peInfo["pe_firstname"]) || !strlen($peInfo["pe_firstname"]))
        $peInfo["pe_firstname"] = NULL;

    if (!isset($peInfo["pe_address"]) || !strlen($peInfo["pe_address"]))
        $peInfo["pe_address"] = NULL;

    if (!isset($peInfo["pe_address2"]) || !strlen($peInfo["pe_address2"]))
        $peInfo["pe_address2"] = NULL;

    if (!isset($peInfo["pe_city"]) || !strlen($peInfo["pe_city"]))
        $peInfo["pe_city"] = NULL;

    if (!isset($peInfo["pe_zip"]) || !strlen($peInfo["pe_zip"]))
        $peInfo["pe_zip"] = NULL;

    if (!isset($peInfo["pe_region"]) || !strlen($peInfo["pe_region"]))
        $peInfo["pe_region"] = NULL;

    if (!isset($peInfo["ctr_id"]) || !is_numeric($peInfo["ctr_id"]))
        $peInfo["ctr_id"] = NULL;

    if (!isset($peInfo["pecat_id"]) || !is_numeric($peInfo["pecat_id"]))
        $peInfo["pecat_id"] = NULL;

    if (!isset($peInfo["pe_taxnr"]) || ! strlen($peInfo["pe_taxnr"]))
        $peInfo["pe_taxnr"] = NULL;

    if (!isset($peInfo["pe_url"]) || !strlen($peInfo["pe_url"]))
        $peInfo["pe_url"] = NULL;

    if (!isset($peInfo["pe_phonework"]) || !strlen($peInfo["pe_phonework"]))
        $peInfo["pe_phonework"] = NULL;

    if (!isset($peInfo["pe_phonemobile"]) || !strlen($peInfo["pe_phonemobile"]))
        $peInfo["pe_phonemobile"] = NULL;

    if (!isset($peInfo["pe_phonehome"]) || !strlen($peInfo["pe_phonehome"]))
        $peInfo["pe_phonehome"] = NULL;

    if (!isset($peInfo["pe_fax"]) || !strlen($peInfo["pe_fax"]))
        $peInfo["pe_fax"] = NULL;

    if (!isset($peInfo["pe_email"]) || !strlen($peInfo["pe_email"]))
        $peInfo["pe_email"] = NULL;

    if (!isset($peInfo["cpn_id"]) || !is_numeric($peInfo["cpn_id"]))
        $peInfo["cpn_id"] = NULL;

    if (!isset($peInfo["jcat_id"]) || !is_numeric($peInfo["jcat_id"]))
        $peInfo["jcat_id"] = NULL;

    if (!isset($peInfo["pe_hourlyrate"]) || !is_numeric($peInfo["pe_hourlyrate"]))
        $peInfo["pe_hourlyrate"] = NULL;

    if (!isset($peInfo["pe_note"]) || !strlen($peInfo["pe_note"]))
        $peInfo["pe_note"] = NULL;

    $fields = array("pe_id" => $peInfo["pe_id"],
                    "pe_lastname" => $peInfo["pe_lastname"],
                    "pe_firstname" => $peInfo["pe_firstname"],
                    "pe_address" => $peInfo["pe_address"],
                    "pe_address2" => $peInfo["pe_address2"],
                    "pe_city" => $peInfo["pe_city"],
                    "pe_zip" => $peInfo["pe_zip"],
                    "pe_region" => $peInfo["pe_region"],
                    "ctr_id" => $peInfo["ctr_id"],
                    "pecat_id" => $peInfo["pecat_id"],
                    "pe_hourlyrate" => $peInfo["pe_hourlyrate"],
                    "pe_taxnr" => $peInfo["pe_taxnr"],
                    "pe_url" => $peInfo["pe_url"],
                    "pe_phonework" => $peInfo["pe_phonework"],
                    "pe_phonemobile" => $peInfo["pe_phonemobile"],
                    "pe_phonehome" => $peInfo["pe_phonehome"],
                    "pe_fax" => $peInfo["pe_fax"],
                    "pe_email" => $peInfo["pe_email"],
                    "cpn_id" => $peInfo["cpn_id"],
                    "jcat_id" => $peInfo["jcat_id"],
                    "pe_note" => $peInfo["pe_note"]
        );

    /* update pe_fotoname only if it is set, do not overwrite it if it
     * is left out */

    if (isset($peInfo["pe_fotoname"]))
    {
        if (isset($peInfo["pe_fotoname"]) && strlen($peInfo["pe_fotoname"]) && ($peInfo["pe_fotoname"] != -1))
            /* image has been replaced */
            $fields["pe_fotoname"] = $peInfo["pe_fotoname"];
        else
            /* image has been deleted */
            $fields["pe_fotoname"] = null;

        /* unlink old image */

        $pres = $db->getOne("SELECT pe_fotoname FROM persons WHERE pe_id = ".
                            $db->quoteSmart($peInfo["pe_id"]));

        if (!DB::isError($pres) && strlen($pres))
            unlink(PHPAGA_PICTUREPATH.$pres);
    }

    $result = $db->autoExecute("persons", $fields, DB_AUTOQUERY_UPDATE,
                               "pe_id = ".$db->quoteSmart($peInfo["pe_id"]));

    if (DB::isError($result))
        return PHPAGA_ERR_DB_EXEC_QUERY;
    else
        return PHPAGA_ERR_NONE;
}


/**
 * Gets a list (array) of all persons of a certain category or company
 * (from $offset to $limit, if set)
 *
 * @param array  $rows      Array containing the results
 * @param int    $count     Number of records matching the query
 * @param int    $pecat     person category
 * @param int    $pecpn     company
 * @param int    $offset    Offset
 * @param int    $limit     Limit
 *
 * @return int   $result    A result code.
 *
 * @author Florian Lanthaler <florian@phpaga.net>
 * @since phpaga 0.1
 */

function phpaga_persons_list (&$rows,
                              &$count,
                              $pecat,
                              $pecpn,
                              $offset = 0,
                              $limit = 0)
{
    $rows = array();
    $count = 0;
    $where = array();

    phpaga_db_connect($db);

    /* total number of matching records */

    $countquery = "SELECT COUNT(pe_id) AS count_pe "."FROM persons ";

    /* select records from persons table */

    $query =
        "SELECT persons.pe_id, pe_lastname, pe_firstname, pe_address, pe_address2, ".
        "pe_city, pe_region, pe_zip, persons.ctr_id, ctr_name, ctr_code, ".
        "persons.pecat_id, pecat_title, pe_taxnr, pe_url,  ".
        "pe_phonework, pe_phonemobile, pe_phonehome, ".
        "pe_fax, pe_email, persons.jcat_id, persons.cpn_id, ".
        "pe_note, cpn_name, jcat_title ".
        "FROM persons ".
        "LEFT JOIN personcat ON personcat.pecat_id = persons.pecat_id ".
        "LEFT JOIN countries ON countries.ctr_id = persons.ctr_id ".
        "LEFT JOIN companies ON companies.cpn_id = persons.cpn_id ".
        "LEFT JOIN jobcat ON jobcat.jcat_id = persons.jcat_id ";

    if (strlen($pecat))
        $where[] = "(persons.pecat_id = ".$db->quoteSmart($pecat).") ";

    if (strlen($pecpn))
        $where[] = "(persons.cpn_id = ".$db->quoteSmart($pecpn).") ";

    if (count($where) > 0)
    {
        $countquery .= "WHERE ".implode(" AND ", $where)." ";
        $query .= "WHERE ".implode(" AND ", $where)." ";
    }

    $query .= "ORDER BY pe_lastname, pe_firstname, pe_city, ctr_name ";

    /* first do the count stuff */
    $result = $db->query($countquery);

    if ((!DB::isError($result)) && ($result->numRows() > 0)
        && ($countrow = $result->fetchRow()))
    {
        $count = $countrow["count_pe"];
    }

    /* limit the number of results starting from $offset if both
     * $offset and $limit are set and valid */

    if (isset($offset) && is_numeric($offset) && isset($limit) &&
        is_numeric($limit) && ($limit > 0))

        $result = $db->limitQuery($query, $offset, $limit);
	else
	    $result = $db->query($query);

    if (DB::isError($result))
        return PHPAGA_ERR_DB_EXEC_QUERY;

    if ($result->numRows() < 1)
        return PHPAGA_ERR_DB_NO_ROWS;

    while ($qrow = $result->fetchRow())
    {

        phpaga_sanitizearray($qrow);

        $h_person = "";

        $qrow["pe_person"] =
			phpaga_persons_formatname ($qrow["pe_lastname"],
                                       $qrow["pe_firstname"]);

        $qrow["pe_location"] =
            phpaga_getLocation ($qrow["pe_city"],
                                $qrow["pe_region"]);

        $qrow["pe_full_location"] =
            phpaga_getFullLocation ($qrow["pe_city"],
                                    $qrow["pe_region"],
                                    $qrow["pe_zip"],
                                    $qrow["ctr_name"]);

        $rows[] = $qrow;
    }

    phpaga_sanitizearray($rows);

    $result->free();
    return PHPAGA_ERR_NONE;
}


/**
 * Gets a person's information
 *
 * @param int    $peID   person ID
 * @param array  $peInfo Array containing the results.
 *
 * @return int   $result  A result code.
 *
 * @author Florian Lanthaler <florian@phpaga.net>
 * @since phpaga 0.1
 */

function phpaga_persons_getInfo ($peID = 0,
                                 &$peInfo)
{
    $peInfo = array();
    $dummy = "";
    $pe_duration = "";

    if (!isset($peID) || !is_numeric($peID))
        return PHPAGA_ERR_PERSON_INVALIDID;

    phpaga_db_connect($db);

    $query =
        "SELECT p.pe_id, p.pe_lastname, p.pe_firstname, ".
		"p.pe_address, p.pe_address2, p.pe_city, p.pe_zip, p.pe_region, ".
		"p.ctr_id, ctr_name, ctr_code, ".
		"p.pecat_id, pecat_title, p.pe_taxnr, p.pe_url, ".
        "p.pe_phonework, p.pe_phonemobile, p.pe_phonehome, ".
        "p.pe_fax, p.pe_email, p.jcat_id, p.cpn_id, ".
        "p.pe_fotoname, p.pe_note, p.pe_hourlyrate, cpn_name, jcat_title, ".
        "p.pe_pe_id, p2.pe_id as owner_pe_id, p2.pe_lastname as owner_pe_lastname, ".
        "p2.pe_firstname as owner_pe_firstname ".
		"FROM persons p ".
        "LEFT JOIN personcat ON personcat.pecat_id = p.pecat_id ".
        "LEFT JOIN countries ON countries.ctr_id = p.ctr_id ".
        "LEFT JOIN companies ON companies.cpn_id = p.cpn_id ".
		"LEFT JOIN jobcat ON jobcat.jcat_id = p.jcat_id ".
        "LEFT JOIN persons p2 ON p2.pe_id = p.pe_pe_id ".
		"WHERE p.pe_id = ".$db->quoteSmart($peID);

    $result = $db->query($query);

    if (DB::isError($result))
        return PHPAGA_ERR_DB_EXEC_QUERY;

    if ($result->numRows() < 1)
        return PHPAGA_ERR_DB_NO_ROWS;

    if ($qrow = $result->fetchRow())
    {
        $qrow["pe_person"] =
            phpaga_persons_formatname($qrow["pe_lastname"],
                                      $qrow["pe_firstname"]);

        $qrow["owner_pe_person"] =
            phpaga_persons_formatname($qrow["owner_pe_lastname"],
                                      $qrow["owner_pe_firstname"]);


        $qrow["pe_location"] =
            phpaga_getLocation($qrow["pe_city"],
                               $qrow["pe_region"]);

        $qrow["pe_full_location"] =
            phpaga_getFullLocation($qrow["pe_city"],
                                   $qrow["pe_region"],
                                   $qrow["pe_zip"],
                                   $qrow["ctr_name"]);

        /* has this person worked and if yes how much */
        $dummy = phpaga_persons_getHours($qrow["pe_id"], $pe_duration);

        if (($dummy == PHPAGA_ERR_NONE)
            && ((int) phpaga_duration2minutes($pe_duration) > 0))
        {
            $qrow["pe_duration_hrs"] = $pe_duration;
            $qrow["pe_duration"] = phpaga_duration2minutes($pe_duration);
        }
        else
        {
            $qrow["pe_duration"] = 0;
            $qrow["pe_duration_hrs"] = phpaga_minutes2duration($pe_duration);
        }

        /* If the foto file does not exist then set pe_fotoname to null */
        if (!isset($qrow["pe_fotoname"])
            || !strlen($qrow["pe_fotoname"])
            || !@is_file(PHPAGA_PICTUREPATH.$qrow["pe_fotoname"])
            || !@is_readable(PHPAGA_PICTUREPATH.$qrow["pe_fotoname"]))

            $qrow["pe_fotoname"] = null;

        $persprj = array();
        $dummy2 = phpaga_projects_getpersonprojects($persprj, $peID);
        if (($dummy2 == PHPAGA_ERR_NONE))
            $qrow["projects"] = $persprj;

        $peInfo = $qrow;
    }

    phpaga_sanitizeArray($peInfo);

    $result->free();
    return PHPAGA_ERR_NONE;
}


/**
 * Loads all person categories into an array.
 *
 * @param array  $pecatInfo   Array containing the results
 *
 * @return int   $result       A result code.
 *
 * @author Florian Lanthaler <florian@phpaga.net>
 * @since phpaga 0.1
 */

function phpaga_persons_getPecats (&$pecatInfo)
{
    $pecatInfo = array();

    phpaga_db_connect($db);

    $query = "SELECT pecat_id, pecat_title ".
        "FROM personcat ORDER BY pecat_title ";

    $result = $db->query($query);

    if (DB::isError($result))
        return PHPAGA_ERR_DB_EXEC_QUERY;

    if ($result->numRows() < 1)
        return PHPAGA_ERR_DB_NO_ROWS;

    while ($qrow = $result->fetchRow())
    {
        phpaga_sanitizearray($qrow);
        $pecatInfo[] = $qrow;
    }

    $result->free();
    return PHPAGA_ERR_NONE;
}


/**
 * Add a new person category.
 *
 * @param  string  $pecat_title  Person category to be added
 *
 * @return int     $result       A result code.
 *
 * @author Florian Lanthaler <florian@phpaga.net>
 * @since phpaga 0.1
 */

function phpaga_persons_addPecat ($pecat_title)
{

    if (!isset($pecat_title) || !strlen($pecat_title))
        return PHPAGA_ERR_PECAT_INVALIDTITLE;

    phpaga_db_connect($db);

    $fields = array("pecat_id" => $db->nextId("personcat_pecat_id"),
                    "pecat_title" => $pecat_title
        );

    $result = $db->autoExecute("personcat", $fields, DB_AUTOQUERY_INSERT);

    if (DB::isError($result))
        return PHPAGA_ERR_DB_EXEC_QUERY;
    else
        return PHPAGA_ERR_NONE;
}


/**
 * Delete a person category.
 *
 * @param  int     $pecat_id    Person category to be deleted
 *
 * @return int     $result      A result code.
 *
 * @author Florian Lanthaler <florian@phpaga.net>
 * @since phpaga 0.1
 */

function phpaga_persons_deletePecat ($pecat_id)
{
    if (!isset($pecat_id) || !is_numeric($pecat_id))
        return PHPAGA_ERR_PECAT_INVALIDID;

    phpaga_db_connect($db);

    /* first check, if this pecat is needed by any table relationship
     * if it is not needed, then delete it, otherwise don't */

    $query = "SELECT pe_id ".
        "FROM persons WHERE pecat_id = ".$db->quoteSmart($pecat_id);

    $result = $db->query($query);

    if (DB::isError($db))
        return PHPAGA_ERR_DB_EXEC_QUERY;

    /* any record matching the query? in that case we cannot delete
     * this person category, as there are dependencies
     */

    if ($result->numRows() > 0)
        return PHPAGA_ERR_DEL_DEPENDENCIES;

    $query = "DELETE FROM personcat WHERE pecat_id = ".$db->quoteSmart($pecat_id);

    $result = $db->query($query);

    if (DB::isError($result))
        return PHPAGA_ERR_DB_EXEC_QUERY;
    else
        return PHPAGA_ERR_NONE;
}


/**
 * Loads all job categories into an array.
 *
 * @param array  $jcatInfo   Array containing the results
 *
 * @return int   $result       A result code.
 *
 * @author Florian Lanthaler <florian@phpaga.net>
 * @since phpaga 0.1
 */

function phpaga_persons_getJobcats (&$jcatInfo)
{
    $jcatInfo = array();

    phpaga_db_connect($db);

    $query = "SELECT jcat_id, jcat_title ".
        "FROM jobcat ORDER BY jcat_title ";

    $result = $db->query($query);

    if (DB::isError($result))
        return PHPAGA_ERR_DB_EXEC_QUERY;

    if ($result->numRows() < 1)
        return PHPAGA_ERR_DB_NO_ROWS;

    while ($qrow = $result->fetchRow())
    {
        phpaga_sanitizearray($qrow);
        $jcatInfo[] = $qrow;
    }

    $result->free();
    return PHPAGA_ERR_NONE;
}


/**
 * Add a new job category.
 *
 * @param  string  $jcat_title   Job category to be added
 *
 * @return int     $result       A result code.
 *
 * @author Florian Lanthaler <florian@phpaga.net>
 * @since phpaga 0.1
 */

function phpaga_persons_addJobcat ($jcat_title)
{

    if (!isset($jcat_title) || !strlen($jcat_title))
        return PHPAGA_ERR_JOBCAT_INVALIDTITLE;

    phpaga_db_connect($db);

    $fields = array("jcat_id" => $db->nextId("jobcat_jcat_id"),
                    "jcat_title" => $jcat_title
        );

    $result = $db->autoExecute("jobcat", $fields, DB_AUTOQUERY_INSERT);

    if (DB::isError($result))
        return PHPAGA_ERR_DB_EXEC_QUERY;
    else
        return PHPAGA_ERR_NONE;
}


/**
 * Delete a job category.
 *
 * @param  int     $jcat_id     Job category to be deleted
 *
 * @return int     $result      A result code.
 *
 * @author Florian Lanthaler <florian@phpaga.net>
 * @since phpaga 0.1
 */

function phpaga_persons_deleteJobcat ($jcat_id)
{
    if (!isset($jcat_id) || !is_numeric($jcat_id))
        return PHPAGA_ERR_JOBCAT_INVALIDID;

    phpaga_db_connect($db);

    /* first check, if this jcat is needed by any table relationship
     * if it is not needed, then delete it, otherwise don't */

    $query = "SELECT pe_id ".
        "FROM persons WHERE jcat_id = ".$db->quoteSmart($jcat_id);

    $result = $db->query($query);

    if (DB::isError($db))
        return PHPAGA_ERR_DB_EXEC_QUERY;

    /* any record matching the query? in that case we cannot delete
     * this job category, as there are dependencies
     */

    if ($result->numRows() > 0)
        return PHPAGA_ERR_DEL_DEPENDENCIES;

    $query = "DELETE FROM jobcat WHERE jcat_id = ".$db->quoteSmart($jcat_id);

    $result = $db->query($query);

    if (DB::isError($result))
        return PHPAGA_ERR_DB_EXEC_QUERY;
    else
        return PHPAGA_ERR_NONE;
}


/**
 * Return a person's name formatted according to PHPAGA_PENAME_FORMAT
 *
 * @param  string  $lastname   Person's last name
 * @param  string  $firstname  Person's first name
 *
 * @return string  $name       Formatted name
 *
 * @author Florian Lanthaler <florian@phpaga.net>
 * @since phpaga 0.1.2
 */

function phpaga_persons_formatname ($lastname = "", $firstname = "")
{

    $formattedname = "";

    /* format the name if both last and first name are defined, otherwise
     * just return whatever is available
     */

    if (strlen($lastname) && strlen($firstname))
    {
        $formattedname = str_replace("%LASTNAME", $lastname, PHPAGA_PENAME_FORMAT);
        $formattedname = str_replace("%FIRSTNAME", $firstname, $formattedname);
    }
    elseif (strlen($lastname))
        $formattedname = $lastname;
    elseif (strlen($firstname))
        $formattedname = $firstname;

    return $formattedname;
}


/**
 * Delete a person. A person can only be deleted if there are no dependencies
 * left (check companies, operations, persons (owner), projects,
 * users (user and owner).
 *
 * @param  int     $pe_id       Person ID
 *
 * @return int     $result      A result code.
 *
 * @author Florian Lanthaler <florian@phpaga.net>
 * @since phpaga 0.1
 */

function phpaga_persons_delete ($pe_id)
{

    if (!isset($pe_id) || !is_numeric($pe_id))
        return PHPAGA_ERR_PERSON_INVALIDID;

    phpaga_db_connect($db);

    $where = "WHERE pe_id = ".$db->quoteSmart($pe_id);

    /* check if this person is needed by any table relationship if it
     * is not needed, then delete it, otherwise don't */

    /* check companies relationship */

    $query = "SELECT cpn_id FROM companies $where";

    $result = $db->query($query);

    if (DB::isError($db))
        return PHPAGA_ERR_DB_EXEC_QUERY;

    if ($result->numRows() > 0)
        return PHPAGA_ERR_DEL_DEPENDENCIES;

    /* check operations relationship */

    $query = "SELECT op_id FROM operations $where";

    $result = $db->query($query);

    if (DB::isError($db))
        return PHPAGA_ERR_DB_EXEC_QUERY;

    if ($result->numRows() > 0)
        return PHPAGA_ERR_DEL_DEPENDENCIES;

    /* check persons (owner) relationship */

    $query = "SELECT pe_id FROM persons where pe_pe_id = ".
        $db->quoteSmart($pe_id);

    $result = $db->query($query);

    if (DB::isError($db))
        return PHPAGA_ERR_DB_EXEC_QUERY;

    if ($result->numRows() > 0)
        return PHPAGA_ERR_DEL_DEPENDENCIES;

    /* check projects relationship */

    $query = "SELECT prj_id FROM projects $where";

    $result = $db->query($query);

    if (DB::isError($db))
        return PHPAGA_ERR_DB_EXEC_QUERY;

    if ($result->numRows() > 0)
        return PHPAGA_ERR_DEL_DEPENDENCIES;

    /* check projects memberships */

    $query = "SELECT prj_id FROM project_members $where";

    $result = $db->query($query);

    if (DB::isError($db))
        return PHPAGA_ERR_DB_EXEC_QUERY;

    if ($result->numRows() > 0)
        return PHPAGA_ERR_DEL_DEPENDENCIES;

    /* check users (user) relationship */

    $query = "SELECT usr_id FROM users $where";

    $result = $db->query($query);

    if (DB::isError($db))
        return PHPAGA_ERR_DB_EXEC_QUERY;

    if ($result->numRows() > 0)
        return PHPAGA_ERR_DEL_DEPENDENCIES;

    /* check users (owner) relationship */

    $query = "SELECT usr_id FROM users WHERE usr_pe_id = ".$db->quoteSmart($pe_id);;

    $result = $db->query($query);

    if (DB::isError($db))
        return PHPAGA_ERR_DB_EXEC_QUERY;

    if ($result->numRows() > 0)
        return PHPAGA_ERR_DEL_DEPENDENCIES;

    /* it is safe to delete the person as it is not needed by any
     * relationship
     */

    $query = "DELETE FROM persons $where";

    $result = $db->query($query);

    if (DB::isError($result))
        return PHPAGA_ERR_DB_EXEC_QUERY;
    else
        return PHPAGA_ERR_NONE;

}


/**
 * Gets all persons matching the search parmeters
 * (from $offset to $limit, if set)
 *
 * @param array  $rows      Array containing the results
 * @param int    $count     Number of records matching the query
 * @param array  $prsInfo   Person information
 * @param array  $prsIds    IDs of the resulting persons
 * @param int    $order     Specifies the order by field
 *
 * @param int    $offset    Offset (optional)
 * @param int    $limit     Limit (optional)
 *
 * @return int   $result    A result code.
 *
 * @author Mark Parssey <markpa@users.sourceforge.net>
 * @since phpaga 0.3
 */

function phpaga_persons_search (&$rows,
                                 &$count,
                                 &$prsIds,
                                 $prsInfo,
                                 $order = 0,
                                 $offset = "",
                                 $limit = "")
{

    $count = 0;
    $rows = array();
    $prsIds = array();
    $where = array();
    $where_clause = "";

    phpaga_db_connect($db);

    /* total number of matching records? */

    $countquery = "SELECT COUNT(persons.pe_id) AS count_pe ".
        "FROM persons ";

    /* select records from persons table */

    $query =
        "SELECT persons.pe_id, pe_lastname, pe_firstname, pe_address, pe_address2, ".
        "pe_city, pe_region, pe_zip, persons.ctr_id, ctr_name, ctr_code, ".
        "persons.pecat_id, pecat_title, pe_taxnr, pe_url,  ".
        "pe_phonework, pe_phonemobile, pe_phonehome, ".
        "pe_fax, pe_email, persons.jcat_id, persons.cpn_id, ".
        "pe_note, cpn_name, jcat_title, pe_pe_id ".
        "FROM persons ".
        "LEFT JOIN personcat ON personcat.pecat_id = persons.pecat_id ".
        "LEFT JOIN countries ON countries.ctr_id = persons.ctr_id ".
        "LEFT JOIN companies ON companies.cpn_id = persons.cpn_id ".
        "LEFT JOIN jobcat ON jobcat.jcat_id = persons.jcat_id ";

    /* collect elements of the where clause */

    if (isset($prsInfo["pe_lastname"]) && strlen($prsInfo["pe_lastname"]))
        $where[] = "persons.pe_lastname LIKE '%".$db->escapeSimple($prsInfo["pe_lastname"])."%'";;

    if (isset($prsInfo["pe_firstname"]) && strlen($prsInfo["pe_firstname"]))
        $where[] = "persons.pe_firstname LIKE '%".$db->escapeSimple($prsInfo["pe_firstname"])."%'";;

    if (isset($prsInfo["pe_address"]) && strlen($prsInfo["pe_address"]))
        $where[] = "persons.pe_address LIKE '%".$db->escapeSimple($prsInfo["pe_address"])."%'";;

    if (isset($prsInfo["pe_address2"]) && strlen($prsInfo["pe_address2"]))
        $where[] = "persons.pe_address2 LIKE '%".$db->escapeSimple($prsInfo["pe_address2"])."%'";;

    if (isset($prsInfo["pe_city"]) && strlen($prsInfo["pe_city"]))
        $where[] = "persons.pe_city LIKE '%".$db->escapeSimple($prsInfo["pe_city"])."%'";;

    if (isset($prsInfo["pe_zip"]) && strlen($prsInfo["pe_zip"]))
        $where[] = "persons.pe_zip LIKE '%".$db->escapeSimple($prsInfo["pe_zip"])."%'";;

    if (isset($prsInfo["pe_region"]) && strlen($prsInfo["pe_region"]))
        $where[] = "persons.pe_region LIKE '%".$db->escapeSimple($prsInfo["pe_region"])."%'";;

    if (isset($prsInfo["ctr_id"]) && is_numeric($prsInfo["ctr_id"]))
        $where[] = "persons.ctr_id = ".$db->quoteSmart($prsInfo["ctr_id"]);

    if (isset($prsInfo["cpn_id"]) && is_numeric($prsInfo["cpn_id"]))
        $where[] = "persons.cpn_id = ".$db->quoteSmart($prsInfo["cpn_id"]);

    if (isset($prsInfo["pecat_id"]) && is_numeric($prsInfo["pecat_id"]))
        $where[] = "persons.pecat_id = ".$db->quoteSmart($prsInfo["pecat_id"]);

    if (isset($prsInfo["pe_email"]) && strlen($prsInfo["pe_email"]))
        $where[] = "persons.pe_email LIKE '%".$db->escapeSimple($prsInfo["pe_email"])."%'";;

    if (isset($prsInfo["jcat_id"]) && is_numeric($prsInfo["jcat_id"]))
        $where[] = "persons.jcat_id = ".$db->quoteSmart($prsInfo["jcat_id"]);

    /* build the where clause */
    if (count($where) > 0)
    {
        $query .= "WHERE ".implode(" AND ", $where)." ";
        $countquery .= "WHERE ".implode(" AND ", $where)." ";
    }

    $query .= " ORDER BY ";

    /* build the order-by clause */
    /* check validity of order value, eventually set it to default  */

    if (($order == "") || ($order == 0) || !is_numeric($order))
        $order = ORDER_PE_NAME_ASC;

    switch ($order)
    {
        case ORDER_PE_NAME_ASC:
            $query .= "pe_lastname ASC, pe_firstname ASC";
            break;
        case ORDER_PE_NAME_DESC:
            $query .= "pe_lastname DESC, pe_firstname DESC";
            break;
        case ORDER_PE_ADDRESS_ASC:
            $query .= "pe_address ASC";
            break;
        case ORDER_PE_ADDRESS_DESC:
            $query .= "pe_address DESC";
            break;
        case ORDER_PE_CITY_ASC:
            $query .= "pe_city ASC";
            break;
        case ORDER_PE_CITY_DESC:
            $query .= "pe_city DESC";
            break;
        case ORDER_PE_COUNTRY_ASC:
            $query .= "ctr_name ASC";
            break;
        case ORDER_PE_COUNTRY_DESC:
            $query .= "ctr_name DESC";
            break;
        case ORDER_PE_COMPANY_ASC:
            $query .= "cpn_name ASC";
            break;
        case ORDER_PE_COMPANY_DESC:
            $query .= "cpn_name DESC";
            break;
        case ORDER_PE_EMAIL_ASC:
            $query .= "pe_email ASC";
            break;
        case ORDER_PE_EMAIL_DESC:
            $query .= "pe_email DESC";
            break;
        default:
            $query .= "pe_lastname ASC, pe_firstname ASC";
            break;
    }

    /* first do the count stuff */

    $result = $db->query($countquery);

    if ((!DB::isError($result)) && ($result->numRows() > 0)
        && ($countrow = $result->fetchRow()))
    {
        $count = $countrow["count_pe"];
    }

    /* limit the number of results starting from $offset if both $offset
     * and $limit are set and valid */

    if (isset($offset) && is_numeric($offset) && isset($limit)
        && is_numeric($limit) && ($limit > 0))

        $result = $db->limitQuery($query, $offset, $limit);
    else
        $result = $db->query($query);

    if (DB::isError($result))
        return PHPAGA_ERR_DB_EXEC_QUERY;

    if ($result->numRows() < 1)
        return PHPAGA_ERR_DB_NO_ROWS;

    while ($qrow = $result->fetchRow())
    {

        $h_person = "";
        phpaga_sanitizearray($qrow);

        $qrow["pe_person"] = phpaga_persons_formatname($qrow["pe_lastname"],
                                                       $qrow["pe_firstname"]);
        $qrow["pe_long_address"] = ($qrow["pe_address"]);
				if (isset($qrow["pe_address2"]) && ($qrow["pe_address2"] != ""))
						$qrow["pe_long_address"] .= "\n\r".$qrow["pe_address2"];

        $rows[] = $qrow;
        $prsIds[] = $qrow["pe_id"];
    }

    $result->free();
    return PHPAGA_ERR_NONE;
}

/**
 * Determine whether some person is the owner of a person record. If
 * pe_pe_id is omitted, the current user's pe_id is used.
 *
 * @param bool   &$isowner  Is pe_id the owner of pe_id?
 * @param int    $pe_id     Person ID of the record
 *
 * @param int    $pe_pe_id  Person ID  of the owner (optional, if omitted, the
 *                          current user's pe_id is used)
 *
 * @return int   $result    A result code.
 *
 * @author Florian Lanthaler <florian@phpaga.net>
 * @since phpaga 0.3
 */

function phpaga_persons_isowner (&$isowner, $pe_id, $pe_pe_id = null)
{

    $isowner = false;

    if (($pe_pe_id == null) && isset($_SESSION["auth_user"])
        && isset($_SESSION["auth_user"]["pe_id"])
        && is_numeric($_SESSION["auth_user"]["pe_id"]))

        $pe_pe_id = $_SESSION["auth_user"]["pe_id"];

    phpaga_db_connect($db);

    $recpe_id = $db->getOne("SELECT pe_pe_id FROM persons WHERE pe_id = ".
                            $db->quoteSmart($pe_id));

    if (DB::isError($recpe_id))
        return PHPAGA_ERR_DB_EXEC_QUERY;

    $isowner = ($recpe_id == $pe_pe_id);

    return PHPAGA_ERR_NONE;
}

?>