<?php
/* $Id: files_func.inc.php,v 1.15 2003/11/25 13:44:45 k-fish Exp $ */

// define various constants
define('READ', 1);
define('WRIT', 2);
define('DELE', 4);
if(version_compare(phpversion(),'4.3.0') == -1){
    define('UPLOAD_ERR_OK', 0);
    define('UPLOAD_ERR_INI_SIZE', 1);
    define('UPLOAD_ERR_FORM_SIZE', 2);
    define('UPLOAD_ERR_PARTIAL', 3);
    define('UPLOAD_ERR_NO_FILE', 4);
}

function is_toplevel($id) {
    global $conn;

    $sql = "SELECT resides_in FROM mgw_files WHERE id=".(int)$id;
    if(!$res = $conn->Execute($sql)) exit(showSQLError($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
    $row = $res->FetchRow();

    return ($row['resides_in'] == 0) ? true : false;
}

function dirSelector($id, $dir_id){
    global $conn;

    $html = '<select name="files[file_location]">';
    if($dir_id != 0){
	$sql = "SELECT id, name FROM mgw_files WHERE type='d' AND id=".(int)$dir_id;
	if(!$res = $conn->Execute($sql)) exit(showSQLError($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
	$dir = $res->FetchRow();

	$html .= '<option value="'.$dir['id'].'" selected>'.$dir['name'].'</option>';
	$html .= '<option value="'.$dir['id'].'">&nbsp;-------------</option>';
    }
    else{
	$html .= '<option value="0" selected>/</option>';
	$html .= '<option value="0">&nbsp;-------------</option>';
    }
    $html .= '<option value="0">/</option>';

    $sql = "SELECT id, name FROM mgw_files WHERE type='d' AND resides_in=".(int)$id;
    if(!$res = $conn->Execute($sql)) exit(showSQLError($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
    while ($dir = $res->FetchRow()) {
	if (is_toplevel($dir["id"])) {
	    $html .= '<option value="'.$dir["id"].'">&nbsp;&nbsp;'.$dir["name"]."</option>\n";
	    print_dir_dropdown($dir["id"], 1, $html);
	}
    }

    return $html.'</select>';
}

function get_children($dir_id) {
    global $conn;
    $count=0;
    $sql = "SELECT id FROM mgw_files WHERE type='d' AND resides_in=".(int)$dir_id;
    if(!$res = $conn->Execute($sql)) exit(showSQLError($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
    $children = array();
    while ($row = $res->FetchRow()){
	$children[$count][0] = $row['id'];
	$count++;
    }
    return $children;
}

function print_dir_dropdown($dir_id, $count, &$html) {
    global $conn;
    $count++;
    $indent=$count*2;
    $spacing="";
    for ($x=0; $x<$indent; $x++) {
	$spacing.="&nbsp;";
    }
    $res = get_children($dir_id);
    for ($x=0; $x<count($res); $x++) {
	$dsql = "SELECT * FROM mgw_files WHERE id=".(int)$res[$x][0];
	if(!$dres = $conn->Execute($dsql)) exit(showSQLError($dsql, $conn->ErrorMsg(), __LINE__, __FILE__));
	$dir = $dres->FetchRow();
	$html .= '<option value="'.$dir["id"].'">'.$spacing.$dir["name"]."</option>";
	print_dir_dropdown($res[$x][0], $count, $html);
    }
}

function checkSessionDir() {
    if (!isset($_SESSION["MGW"]->settings["files"]["curr_dir_id"])) {
        $_SESSION["MGW"]->settings["files"]["curr_dir_name"] = "";
        $_SESSION["MGW"]->settings["files"]["curr_dir_id"] = 0;
    }
}

function deleteFile($file_id){
    global $conn;
    
    $sql="SELECT type, resides_in, name FROM mgw_files WHERE id = ".(int)$file_id;
    if(!$res = $conn->Execute($sql)) exit(showSQLerror($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
    $res = $res->FetchRow();
    if ($res["type"] == "f") {
        unlink(STORE_FOLDER . $res["resides_in"] . "-" . $res["name"]);
    }

    $sql="DELETE FROM mgw_files WHERE id = ".(int)$file_id;
    if(!$res = $conn->Execute($sql)) exit(showSQLerror($sql, $conn->ErrorMsg(), __LINE__, __FILE__));

    $sql="DELETE FROM mgw_files_grouprights WHERE for_file = ".(int)$file_id;
    if(!$res = $conn->Execute($sql)) exit(showSQLerror($sql, $conn->ErrorMsg(), __LINE__, __FILE__));

}

function recursiveDeleteDirectory($file_id){
    global $conn;
    
    $sql="SELECT type, id FROM mgw_files WHERE resides_in=".(int)$file_id; 
    if(!$res = $conn->Execute($sql)) exit(showSQLerror($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
    $count = $res->RecordCount();
    $res = $res->FetchRow();
    
    if ($count > 0) {
        if ($res["type"] == "d") {
            recursiveDeleteDirectory($res["id"]);
        } else {
            deleteFile($res["id"]);
        }
    }
    
    deleteFile($file_id);
}

function getGroupDetails($groupId) {
    global $conn;
    $sql = "SELECT name, description FROM mgw_groups WHERE id=" . (int) $groupId;
    if(($res = $conn->GetRow($sql)) === false) exit(showSQLerror($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
    return $res;
}

/**
 * Pretty-print the file, using the Horde::Mime::Viewer package.
 *
 * @param string ext File extension of the checked out file
 * @param resource fp File pointer to the head of the checked out copy
 * @return object The MIME_Viewer object which can be rendered or
 *                false on failure
 */
function prettyPrint($file, $id=0) {
    require('mime/Part.php');
    require('mime/Magic.php');
    require('mime/Viewer.php');

    $lns = '';
    $fp = fopen($file,'rb');
    $lns .= fread($fp, filesize($file));
    fclose($fp);

    $mime_type = MIME_Magic::filenameToMIME($file);
    if (!isset($mime_type)) {
	return false;
    }

    $mime = new MIME_Part($mime_type, $lns);
    $mime->setName($id);
    return MIME_Viewer::factory($mime);
}

/*
define('READ', 1<<0); //sets READ = 1 (at the bit level = 0001)
define('WRIT', 1<<1); // sets WRIT = 2 (at the bit level = 0010)
define('DELE', 1<<2); // sets DELE = 4 (at the bit level = 0100)

$rights = READ | WRIT; //sets $rights to 3 (bit level = 0011)

//this does an 'AND' bit-level comparison
$sql = "SELECT FROM table WHERE rights & $rights";

So if rights is READ+WRIT+DELE, or 0111, then the bitwise 'AND'
comparison between 0011 and 0111 = 0011 which is positive. if rights
were 1100 then the 'AND' comparison would result in 0000. If rights
were just READ, 0001, then the result would be 0001 which is still
positive.
*/
function getRightsFromDB($rights){
    $rs = array();
    $rs['o'] = (int) $rights['all_rights'];

    return $rs;
}

function checkRight($rights, $right=READ){
    return ($rights['usegr']) ? ($rights['g'] & $right) : ($rights['o'] & $right);
}

function hasRight($rights, $right=READ) {
    return ($rights & $right) > 0;
}

function getRightsFromForm($rights){
    $res = 0;
    if (isset($rights["r"]) && $rights["r"]=="on") $res += READ;
    if (isset($rights["w"]) && $rights["w"]=="on") $res += WRIT;
    if (isset($rights["d"]) && $rights["d"]=="on") $res += DELE;

    return $res;
}

function getUsername($id) {
	global $conn, $files_username_cache;
	
	if (isset($files_username_cache[$id])) {
		return $files_username_cache[$id];
	}
	$sql = "SELECT username FROM mgw_users WHERE id=" .(int)$id;
	if(($res = $conn->getOne($sql)) === false) exit(showSQLerror($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
	return $res;
}

// returns TRUE if the user has $right on $fileId
function checkForFileRight($fileId, $right=READ) {
	global $conn;
	
	// everone has access to the root.
	if ($fileId == 0) {
		return true;
	}
	
    $sql = "SELECT owner,all_rights FROM mgw_files WHERE id=".(int)$fileId;
    if(($row = $conn->getRow($sql)) === false) exit(showSQLerror($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
    
    if ($row['owner'] == $_SESSION["MGW"]->userid) {
    	// owner always has all rights
    	return true;    	
    }
    if (isset($row['all_rights']) && hasRight($row['all_rights'], $right)) {
    	// all rights are nice.
    	return true;
    }
    
    $sql = "SELECT for_group, rights FROM mgw_files_grouprights WHERE for_file=$fileId";   
    if(($groups = $conn->getAssoc($sql)) === false) exit(showSQLerror($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
    foreach($groups as $group => $details) {
    	if (in_array($group, $_SESSION["MGW"]->groups) && hasRight($details['rights'], $right)) {
    		return true;
    	}
    }
    
    // poor user.
    return false;
}

function performGroupRights($fileId, $grouprights) {
	global $conn;
	
	foreach ($grouprights as $groupid => $group) {
	    $rights = getRightsFromForm($group);
	    $sql = "SELECT id FROM mgw_files_grouprights WHERE for_file=".(int)$fileId." AND for_group=".(int)$groupid;
	    if(($id = $conn->GetOne($sql)) === false) {
	    	$nextId = mgw_genID("mgw__seq_files_grouprights");
	    	$sql = "INSERT INTO mgw_files_grouprights (id, for_file, for_group, rights) VALUES " .
	    	       "(" . (int)$nextId . "," . (int) $fileId . "," . (int)  $groupid . "," . (int)  $rights . ")";
	    	if(!$conn->Execute($sql)) exit(showSQLerror($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
	    }
	    else {
	        $sql = "UPDATE mgw_files_grouprights SET rights=$rights WHERE for_file=$fileId AND for_group=" . (int)$groupid;
	        if(!$conn->Execute($sql)) exit(showSQLerror($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
	    }
	}
}

function getRightsQuery($fileId){

    $sql= "SELECT DISTINCT mgw_files.*, mgw_users.username AS owner_name FROM mgw_files, mgw_groups_members, mgw_users, mgw_files_grouprights WHERE
            ((mgw_groups_members.userid = ".(int)$_SESSION["MGW"]->userid.") AND
             (mgw_groups_members.groupid = mgw_files_grouprights.for_group) OR mgw_files.all_rights > 0)
            AND (mgw_files.owner = mgw_users.id)
            AND (mgw_files.id = ".(int)$fileId.")

            GROUP BY mgw_files.id, mgw_files.project, mgw_files.task, mgw_files.category, mgw_files.msg_id, mgw_files.partno, mgw_files.type, mgw_files.resides_in, mgw_files.owner, mgw_files.name, mgw_files.mime_type, mgw_files.owner_rights, mgw_files.all_rights, mgw_files.created, mgw_files.modified, mgw_files.modified_by, mgw_files.links_to, mgw_users.username, mgw_files.size";
             
    return $sql;             
}

// return all files the user can see in the current dir.
function getFilesInDir() {
    global $conn;
    // get all files in the directory.
    $sql = "SELECT * FROM mgw_files WHERE (mgw_files.resides_in = ".(int)$_SESSION["MGW"]->settings["files"]["curr_dir_id"].") ORDER BY name";
    if(($files = $conn->getAll($sql)) === false) exit(showSQLerror($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
    $res = array();
    foreach ($files as $idx => $details) {
        // show files that user owns
		$rights = 0;
		// allow admin everything
    	if ($_SESSION["MGW"]->username == "admin")
    	  $rights = READ|WRIT|DELE;
        if ($details["owner"] == $_SESSION["MGW"]->userid) {
            // owners can do everything to files
            $rights = READ|WRIT|DELE;
        } 
		else {        
            // show files that the user can 'view' via a group setting
            $sql = "SELECT for_group,rights FROM mgw_files_grouprights WHERE for_file=" . (int)$details["id"];
            if(($groups = $conn->getAssoc($sql)) === false) exit(showSQLerror($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
            foreach ($groups as $group => $group_details) {
                if (in_array($group, $_SESSION['MGW']->groups) && ($group_details['rights'] & READ)) {
                    $rights |= $group_details['rights'];
               }
            }
		}
        // show files that have world view
        if ($details['all_rights'] & READ) {
            $rights |= $details['all_rights'];
        }
        
        if ($rights > 0) {
            $details['rights'] = $rights;
            $res[] = $details;
        }
    }
    return $res;         
}

function getRightsQuery2_old(){
	return "SELECT 
                DISTINCT mgw_files.*, 
                mgw_users.username AS owner_name,
            FROM 
                mgw_files, 
                mgw_files_grouprights,
                mgw_groups_members,
                mgw_users
            WHERE 
            (
                ((mgw_groups_members.userid = ".(int)$_SESSION["MGW"]->userid.") AND
                (mgw_groups_members.groupid = mgw_files_grouprights.for_group) OR mgw_files.all_rights > 0)
            ) AND (
                (mgw_files_grouprights.for_file = mgw_files.id) AND (mgw_files_grouprights.for_group 
            ) AND (
                (mgw_files.owner = mgw_users.id)
            ) AND (
                (mgw_files.resides_in = ".(int)$_SESSION["MGW"]->settings["files"]["curr_dir_id"].")
            )

            GROUP BY mgw_files.id, mgw_files.project, mgw_files.category, mgw_files.msg_id, mgw_files.partno, mgw_files.type, mgw_files.resides_in, mgw_files.owner, mgw_files.name, mgw_files.mime_type, mgw_files.owner_rights, mgw_files.all_rights, mgw_files.created, mgw_files.modified, mgw_files.modified_by, mgw_files.links_to, mgw_files.size, owner_name, mgw_files_grouprights.for_group ORDER BY mgw_files.type, mgw_files.name ASC
         ";
}

function getRightsQuery3(){
	global $conn;
	
    $qsearch = $conn->QMagic('%'.$_POST['searchterm'].'%');
    return "SELECT 
                DISTINCT mgw_files.*, 
                mgw_users.username AS owner_name,
                MAX(mgw_files_grouprights.rights) AS group_rights
            FROM 
                mgw_files, 
                mgw_files_grouprights,
                mgw_groups_members,
                mgw_users
            WHERE 
            (
                ((mgw_groups_members.userid = ".(int)$_SESSION["MGW"]->userid.") AND
                (mgw_groups_members.groupid = mgw_files_grouprights.for_group) OR mgw_files.all_rights > 0)
            ) AND (
                (mgw_files_grouprights.for_file = mgw_files.id)
            ) AND (
                (mgw_files.owner = mgw_users.id)
            ) AND (			  
			    (mgw_files.name LIKE $qsearch) OR
               	(mgw_files.project LIKE $qsearch) OR
				(mgw_files.category LIKE $qsearch)
			)

            GROUP BY mgw_files.id, mgw_files.project, mgw_files.category, mgw_files.msg_id, mgw_files.partno, mgw_files.type, mgw_files.resides_in, mgw_files.owner, mgw_files.name, mgw_files.mime_type, mgw_files.owner_rights, mgw_files.all_rights, mgw_files.created, mgw_files.modified, mgw_files.modified_by, mgw_files.links_to, mgw_files.size, owner_name, mgw_files_grouprights.for_group ORDER BY mgw_files.type, mgw_files.name ASC
         ";
}

function getRightsQuery4($fileId, $groupId) {
	$sql = "SELECT rights FROM mgw_files_grouprights " .
	       "WHERE for_file=" . (int) $fileId . 
	       " AND for_group=" . (int) $groupId;
	return $sql;
}

?>
