<?php
/**
 * phpaga
 *
 * File management functionality.
 *
 * This file contains the necessary routines to manage uploaded files.
 *
 * @author Florian Lanthaler <florian@phpaga.net>
 * @version $Id$
 *
 * Copyright (c) 2005, 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.
 */


/**
 * Adds a new file to the database.
 *
 * @param  array   $user     Array containing file information.
 *
 * @return int     $id       New file Id or a PhPagaError.
 *
 * @author Florian Lanthaler <florian@phpaga.net>
 * @since phpaga 0.3
 */

function phpaga_files_add($file)
{

    if (!isset($file['file_original_name']) || !strlen($file['file_original_name'])
        || !isset($file['file_local_name']) || !strlen($file['file_local_name'])
        || !isset($file['file_rel_type']) || !is_numeric($file['file_rel_type'])
        || !isset($file['file_rel_id']) || !is_numeric($file['file_rel_id']))

        return PhPagaError::raiseErrorByCode(PHPAGA_ERR_INVALID_PARAMTYPE);

    if (!isset($file['pe_id']) || !is_numeric($file['pe_id']))
        $file['pe_id'] = $_SESSION['auth_user']['pe_id'];

    $d = new PhPagaDbData;

    $id = $d->nextId('files_file_id');

    $fields = array('file_id'=> $id,
                    'pe_id' => $file['pe_id'],
                    'file_original_name' => $file['file_original_name'],
                    'file_local_name' => $file['file_local_name'],
                    'file_rel_type' => $file['file_rel_type'],
                    'file_rel_id' => $file['file_rel_id'],
                    'file_mimetype' => $file['file_mimetype']);

    $r = $d->insert('files', $fields);

    if (PhPagaError::isError($r))
        return $r;

    return $id;
}


/**
 * Get a list with information about all files that belong to a
 * certain relation.
 *
 * @param  int     $file_rel_type   Type of the related object
 * @param  int     $file_rel_id     ID of the related object
 *
 * @return array   $files           File(s) information. A PhPagaError object on failure.
 *
 * @author Florian Lanthaler <florian@phpaga.net>
 * @since phpaga 0.3
 */

function phpaga_files_getAllRel ($file_rel_type, $file_rel_id)
{

    global $phpaga_preview_types;
    global $phpaga_mime_image_types;

    $files = array();

    if (!isset($file_rel_type) || !is_numeric($file_rel_type) || !isset($file_rel_id) || !is_numeric($file_rel_id))
        return PhPagaError::raiseErrorByCode(PHPAGA_ERR_INVALID_PARAMTYPE);

    if (PHPAGA_DB_SYSTEM == 'pgsql')
        $t_file_added = "to_char(file_added, 'yyyy-mm-dd hh24:mi:ss'::text) as file_added";
    else
        $t_file_added = 'file_added';

    $query = 'SELECT file_id, '.$t_file_added.', files.pe_id, file_original_name,
        file_local_name, file_mimetype, persons.pe_lastname, persons.pe_firstname
        FROM files
        LEFT JOIN persons ON persons.pe_id = files.pe_id
        WHERE file_rel_type = ?
        AND file_rel_id = ?';

    $d = new PhPagaDbData;
    $result = $d->queryAll($query, array($file_rel_type, $file_rel_id));

    if (PhPagaError::isError($result))
        return $result;

    foreach ($result as $qrow) {
        $qrow['pe_person'] = phpaga_persons_formatname($qrow['pe_lastname'], $qrow['pe_firstname']);
        $qrow['preview'] = in_array($qrow['file_mimetype'], $phpaga_preview_types);
        $qrow['is_image'] = in_array($qrow['file_mimetype'], $phpaga_mime_image_types);

        $files[] = $qrow;
    }

    return $files;
}


/**
 * Get the information about a specific file.
 *
 * @param  int     $file_id   File ID
 *
 * @return array   &$file     File information. A PhPagaError object on failure.
 *
 * @author Florian Lanthaler <florian@phpaga.net>
 * @since phpaga 0.3
 */

function phpaga_files_getInfo($file_id)
{

    $file = array();

    if (!isset($file_id) || !is_numeric($file_id))
        return PhPagaError::raiseErrorByCode(PHPAGA_ERR_INVALID_PARAMTYPE);

    if (PHPAGA_DB_SYSTEM == 'pgsql')
        $t_file_added = "to_char(file_added, 'yyyy-mm-dd hh24:mi:ss'::text) as file_added";
    else
        $t_file_added = 'file_added';

    $d = new PhPagaDbData;

    $query = 'SELECT file_id, '.$t_file_added.', files.pe_id, file_original_name,
        file_local_name, file_mimetype, persons.pe_lastname, persons.pe_firstname,
        file_rel_type, file_rel_id
        FROM files
        LEFT JOIN persons ON persons.pe_id = files.pe_id
        WHERE file_id = ?';

    $file = $d->queryRow($query, $file_id);

    if (PhPagaError::isError($file))
        return $file;

    $file['pe_person'] = phpaga_persons_formatname($file['pe_lastname'], $file['pe_firstname']);

    return $file;
}


/**
 * Deletes a file both from the file system and from the database.
 *
 * @param int    $file_id    File ID
 *
 * @return bool  $result     True if successful, PhPagaError otherwise.
 *
 * @author Florian Lanthaler <florian@phpaga.net>
 * @since phpaga 0.3
 */

function phpaga_files_delete($file_id)
{

    if (!isset($file_id) || !is_numeric($file_id))
        return PhPagaError::raiseErrorByCode(PHPAGA_ERR_INVALID_PARAMTYPE);

   $file  = phpaga_files_getInfo($file_id);

    if (PhPagaError::isError($file))
        return $file;

    if (file_exists(PHPAGA_FILEPATH.$file["file_rel_type"]."/".$file["file_rel_id"]."/".$file["file_local_name"]) &&
        !unlink(PHPAGA_FILEPATH.$file["file_rel_type"]."/".$file["file_rel_id"]."/".$file["file_local_name"]))

        return PhPagaError::raiseErrorByCode(PHPAGA_ERR_FILE_REMOVE);

    $d = new PhPagaDbData;

    $result = $d->execute('DELETE FROM files WHERE file_id = ?', $file_id);

    if (PhPagaError::isError($result))
        return $result;

    return true;
}


/**
 * Returns a file upload status message.
 *
 * @param int     $id        Status ID
 *
 * @return string $status    Status message
 *
 * @author Florian Lanthaler <florian@phpaga.net>
 * @since phpaga 0.3
 */

function phpaga_files_getuploadstatusmessage($id) {

    $status = null;

    switch ($id) {

        case UPLOAD_ERR_OK:
            break;

        case UPLOAD_ERR_NO_FILE:
            break;

        case UPLOAD_ERR_INI_SIZE:
            $status = _("The uploaded file exceeds the upload_max_filesize directive in php.ini.");
            break;

        case UPLOAD_ERR_PARTIAL:
            $status = _("The uploaded file was only partially uploaded.");
            break;

        case UPLOAD_ERR_NO_TMP_DIR:
            $status = _("Missing a temporary folder.");
            break;

        case UPLOAD_ERR_CANT_WRITE:
            $status = _("Failed to write file to disk.");
            break;

        default:
            $status = _("Unknown error.");
            break;
    }

    return $status;
}

?>
