<?php

/*
** Fishlib - a collection of utilities for db-driven applications in PHP
** Copyright (C) 2002  LTWD, LLC DBA The Madfish Group
**
** This library is free software; you can redistribute it and/or
** modify it under the terms of the GNU Lesser General Public
** License as published by the Free Software Foundation; either
** version 2.1 of the License, or (at your option) any later version.
**
** This library is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
** Lesser General Public License for more details.
**
** You should have received a copy of the GNU Lesser General Public
** License along with this library; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

class FishUtil
{
    function &
check_session()
    {
        if (!isset(
$_SESSION))
        {
            if (
php_sapi_name() == 'cli')
            {
                global 
$_SESSION;
                
$_SESSION = array();
            }
            else
            {
                @
session_start();
                
$objects array_intersect(
                    
array_map('gettype'$_SESSION)
                    , array(
'object')
                );
                
$missing null;
                foreach (
$objects as $k => $type)
                {
                    
$v $_SESSION[$k];
                    if (
is_a($v'__PHP_Incomplete_Class'))
                    {
                        
$vprops get_object_vars($v);
                        
$missing $vprops['__PHP_Incomplete_Class_Name'];
                        
error_log("Ooops, forgot to include definition of '{$missing} class before starting session");
                        @include_once(
"{$missing}.class.php");
                        if (
class_exists($missing) === FALSE)
                            unset(
$_SESSION[$k]);
                    }
                }
                if (
$missing !== null)
                {
                    
// try that again - don't mask errors this time
                    
session_write_close();
                    
session_start();
                }
            }
        }
        return 
$_SESSION;
    }

    function 
array2mask($arr)
    {
        
$mask 0;
        foreach (
$arr as $v)
        {
            if (
$v 31)
                
user_error("Can't add value '$v' to mask"E_USER_ERROR);
            
$mask $mask pow(2,$v);
        }
        return 
$mask;
    }
    function 
mask2array($mask)
    {
        
$rbmask strrev(decbin($mask));
        
$len strlen($rbmask);
        
$arr = array();
        for (
$i 0$i $len$i++)
        {
            if (
$rbmask{$i})
                
$arr[] = $i;
        }
        return 
$arr;
    }

    function 
array_key_remove(&$args$keys=array(),$replacement=NULL)
    {
        
$out = array();
        if (!
is_array($args))
        {
            if (
is_object($args))
            {
                
$args = (array)$args;
            }
            else
            {
                
$bt debug_backtrace();
                
error_log("Don't call array_key_remove on something that's not array-ish :".var_export($args,TRUE).': backtrace='.var_export($bt,TRUE));
                return 
$out;
            }
        }
        if (!
is_array($keys))
        {
            if (!
is_array($replacement))
            {
                if (
array_key_exists($keys$args))
                {
                    
$out[$keys] = $args[$keys];
                    if (
$replacement !== NULL)
                        unset(
$args[$keys]);
                    else
                        
$args[$keys] = $replacement;
                }
                return 
$out;
            }
            else
            {
                
// have to look up the offset of the key to splice anyway...
                
$keys = array($keys);
            }
        }

        foreach ( 
array_intersect(array_keys($args), $keys) as $k => $v)
        {
            
$out[$v] = $args[$v];
            if (
$replacement === NULL)
                unset(
$args[$v]);
            else
                
array_splice($args,$k,1,$replacement);
        }
        return 
$out;
    }

    function 
array_key_value($args=array(), $name=''$default=''$mode='list')
    {
        if (!
is_array($args))
        {
            if (
is_object($args))
            {
                
settype($args,'array');
            }
            else
            {
                
$bt debug_backtrace();
                
error_log("Don't call array_key_value on something that's not array-ish :".var_export($args,TRUE).': backtrace='.var_export($bt,TRUE));
                return 
$default;
            }
        }
        if (!
is_array($name))
        {
            if (
array_key_exists($name,$args))
                
$default $args[$name];
            return 
$default;
        }
        
$results = array();
        
$keys array_keys($args);
        
$found array_intersect($name$keys);
        
$notfound array_diff($name$keys);
        foreach (
$found as $k)
            
$results[$k] = $args[$k];
        foreach (
$notfound as $k)
            
$results[$k] = $default;
        if (
$mode == 'list')
            return 
array_values($results);
        return 
$results;
    }

    function 
array_tonull()
    {
        
$tonull NULL;
        if (
$tonull === NULL)
        {
            
$tonull create_function('','return NULL;');
        }
        
$args func_get_args();
        
$keys = array();
        foreach (
$args as $arg)
        {
            if (
FishUtil::is_assoc($arg))
            {
                
$keys array_merge($keys,array_keys((array)$arg));
            }
            else
            {
                
$keys array_merge($keys,array_values((array)$arg));
            }
        }
        
// now that we have a list of keys, flip it around so that they *are* 
        // the keys of the array, and use array_map() to set the values of 
        // the array to NULL
        
$output array_map($tonullarray_flip($keys));
        return 
$output;
    }

    function 
get_session_id($session_id=NULL)
    {
        
// if a session ID has not been passed in, check _REQUEST
        
if (empty($session_id))
        {
            
$session_id array_key_value($_REQUEST'session_id'NULL);
        }
        if (
$session_id)
        {
            
session_id($session_id);
        }
        
$session_id session_id();
        if (empty(
$session_id))
        {
            
$unike implode('.'array_key_value($_SERVER, array('HTTP_USER_AGENT','REMOTE_ADDR','REMOTE_PORT'), '''list'));
            if (!isset(
$_SERVER['REMOTE_ADDR']) && php_sapi_name() == 'cli')
            {
                
// this is a UNIX-only hack so that running the CLI version twice 
                // from the same terminal session will give you the same ID
                
$tsess preg_replace('/[^0-9]/','',shell_exec('ps -$$ -o tsess'));
                
$unike $unike '.' $tsess;
            }
            
error_log('unike = '.$unike);
            
$session_id md5($unike);
            
session_id($session_id);
        }
        return 
$session_id;
    }

    function 
is_assoc($a)
    {
        if (!empty(
$a) && (is_array($a) || is_object($a)))
        {
            
$keys array_keys((array)$a);
            
$notskeys array_diff($keysarray_filter($keys,'is_string'));
            return empty(
$notskeys);
        }
        return 
FALSE;
    }


    function 
money($val=0)
    {
        return 
'$'.number_format(FishUtil::unmoney($val),2);
    }
    function 
unmoney($val=0)
    {
        return (float)
str_replace(array('$',','),array('',''),$val);
    }

    function 
monthabbrs($mon=NULL)
    {
        static 
$months = array(
            
=> 'Jan'
            
=> 'Feb'
            
=> 'Mar'
            
=> 'Apr'
            
=> 'May'
            
=> 'Jun'
            
=> 'Jul'
            
=> 'Aug'
            
=> 'Sep'
            
10 => 'Oct'
            
11 => 'Nov'
            
12 => 'Dec'
        
);
        return empty(
$months[$mon]) ? $months $months[$mon];
    }

    function 
monthnames($mon=NULL)
    {
        static 
$months = array(
            
=> 'January'
            
=> 'February'
            
=> 'March'
            
=> 'April'
            
=> 'May'
            
=> 'June'
            
=> 'July'
            
=> 'August'
            
=> 'September'
            
10 => 'October'
            
11 => 'November'
            
12 => 'December'
        
);
        return empty(
$months[$mon]) ? $months $months[$mon];
    }

    function 
notempty($v)
    {
        if (
is_string($v))
            
$v trim($v);
        return !empty(
$v);
    }

    function 
redirect($url='/')
    {
        
header("Location: $url");
        print <<<EOT
<blockquote>
<b>Click <a href="$url">here</a> to continue.</b>
</blockquote>
EOT;
        exit;
    }

    function 
check_timing($loc='')
    {
        
error_log(__FUNCTION__.':Fix this reference - no longer in FishUtil');
        require_once(
'fishdebug.class.php');
        return 
FishDebug::check_timing($loc);
    }

    function 
get_constant($constname='')
    {
        
error_log(__FUNCTION__.':Fix this reference - no longer in FishUtil');
        require_once(
'fisherror.class.php');
        return 
FishError::get_constant($constname);
    }

    function 
get_local_ref($ref='')
    {
        
error_log(__FUNCTION__.':Fix this reference - no longer in FishUtil');
        require_once(
'fishtext.class.php');
        return 
FishText::get_local_ref($ref);
    }

    function 
nlecho()
    {
        
$args func_get_args();
        
error_log(__FUNCTION__.':Fix this reference - no longer in FishUtil');
        require_once(
'fishdebug.class.php');
        return 
call_user_func_array(array('fishdebug','nlecho'), $args);
    }

    function 
states()
    {
        
error_log(__FUNCTION__.':Fix this reference - no longer in FishUtil');
        require_once(
'fishaddress.class.php');
        return 
FishAddress::states();
    }

    function 
provinces()
    {
        
error_log(__FUNCTION__.':Fix this reference - no longer in FishUtil');
        require_once(
'fishaddress.class.php');
        return 
FishAddress::provinces();
    }

    function 
countries()
    {
        
error_log(__FUNCTION__.':Fix this reference - no longer in FishUtil');
        require_once(
'fishaddress.class.php');
        return 
FishAddress::countries();
    }

    function 
force_download($filename$content=NULL)
    {
        
error_log(__FUNCTION__.':Fix this reference - no longer in FishUtil');
        require_once(
'fishrequest.class.php');
        return 
FishRequest::force_download($filename$content);
    }
}
?>