Location: PHPKode > projects > phlyMail Lite > phlymail/shared/lib/basemethods.php
<?php
/**
 * @package phlyMail Nahariya 4.0+ Default Branch
 * @subpackage Basic functionalities
 * @copyright 2004-2010 phlyLabs, Berlin (http://phlylabs.de)
 * @version 0.1.9 2010-09-01
 */
class basics
{
    /**
     * Evaluate, whether a given parameter is TRUE or FALSE
     * @access  public
     * @param   Parameter (String, number or boolean)
     * @return  true | false
     * @since   0.0.1
     */
    static public function eval_param($param)
    {
        if (true === $param) return true;
        return (in_array($param, array('1', 1, 'yes', 'y')));
    }

    /**
     * Save configuration options in the global.choices.ini.php or any other file
     * of a similar structure. The saved format is a sectioned .ini file
     *
     * @param  string  $file  Path to the confugration file
     * @param  array   $data  Payload to write
     * [@param  boolean  $replace  If true, it replaces the passed data in the original file; Default: true]
     * [@param  octal  $chmod  Set this chmod value when creating the file]
     * @return  boolean  true on success, false otherwise
     * @since 0.0.2
     */
    static public function save_config($file, $data, $replace = true, $chmod = 0755)
    {
        if (!$chmod) $chmod = 0755;
        $old_umask = umask(0);
        if ($replace) {
            $original = (file_exists($file) && is_readable($file)) ? parse_ini_file($file, 1) : array();
            foreach ($data as $k => $v) {
                if (is_array($v)) {
                    foreach($v as $k2 => $v2) { $original[$k][$k2] = $v2; }
                } else {
                    $original[$k] = $v;
                }
            }
        } else {
            $original = &$data;
        }
        if (!file_exists($file)) {
            touch($file);
            @chmod($file, $chmod);
        }
        $fid = fopen($file, 'w');
        if (!is_resource($fid)) return false;
        // Trying to lock the file... But don't care, if not possible. Prevents the user from a lot of PITA
        @flock($fid, LOCK_EX);
        fputs($fid, ';<?php die(); ?>'.LF);
        foreach ($original as $k => $v) {
            if (is_array($v)) {
                fputs($fid, '['.$k.']'.LF);
                foreach ($v as $k2 => $v2) fputs($fid, $k2.' = '.(preg_match('![^0-9]!i', $v2) ? '"'.$v2.'"'.LF : $v2.LF));
            } else {
                fputs($fid, $k.' = '.(preg_match('![^0-9]!i', $v) ? '"'.$v.'"'.LF : $v.LF));
            }
        }
        fclose($fid);
        umask($old_umask);
        return true;
    }

    /**
     * Recursively create directoires
     * @param string $dirname complete pathname
     *[@param octal  $perms  Pass specific permissions here; Default: $GLOBALS['_PM_']['core']['dir_umask'] ]
     * @return mixed Either false on errors or the dirname itself on success
     * @since  0.0.4
     */
    static public function create_dirtree($dirname = '', $perms = null)
    {
        if (is_null($perms)) $perms = $GLOBALS['_PM_']['core']['dir_umask'];
        $basedir = @ini_get('open_basedir');
        if (substr($dirname, 0, strlen($basedir)) == $basedir) {
            $createdir = substr($dirname, strlen($basedir), strlen($dirname) - strlen($basedir));
            $checkme = $basedir;
        } else {
            $createdir = $dirname;
            $checkme = '';
        }
        $createme = explode('/', $createdir);
        foreach ($createme as $k => $v) {
            if ($v == '') continue; // Empty fields can also be in the beginning (absolute paths)
            if (0 != $k) $checkme .= '/';
            $checkme .= $v;
            if (!is_dir($checkme)) {
                $umask = umask(0);
                $state = @mkdir($checkme, $perms);
                umask($umask);
                if (!$state) return false;
            }
        }
        return $dirname;
    }

    /**
     * Attempts to empty and remove the given dir, should also work with bigger dir structures
     * @param  string  Path to the directory to delete
     * @return  void
     * @since  0.0.4
     */
    static public function removedir($path)
    {
        $d = opendir($path);
        while (false !== ($file = readdir($d))) {
            $name = $path.'/'.$file;
            if ('.' == $file || '..' == $file) continue;
            if (is_dir($name)) { self::removedir($name); } else { unlink($name); }
        }
        closedir($d);
        rmdir($path);
    }

    /**
     * Bypass a weakness of PHP's unserialize when dealing mit probably mangled binary data
     *
     * @param string $str The serialized data
     * @return string The unserialized data
     * @since 0.0.9
     */
    static public function mb_unserialize($str)
    {
        if (!strlen($str)) return array();
        return unserialize(preg_replace('!s:(\d+):"(.*?)";!se', "'s:'.strlen('$2').':\"$2\";'", $str));
    }

    /**
     * Generates an UUID
     *
     * @author     Anis uddin Ahmad <hide@address.com>
     * @param      string  an optional prefix
     * @return     string  the formatted uuid
     */
    static public function uuid($prefix = '')
    {
        $chars = sha1(self::strong_uniqid());
        $uuid  = substr($chars, 0, 8) . '-' . substr($chars, 8, 4) . '-' . substr($chars, 12, 4) . '-'
                . substr($chars, 16, 4) . '-' . substr($chars, 20, 12);
        return strval($prefix) . $uuid;
    }

    static public function strong_uniqid($maxLength = null)
    {
        $entropy = '';
        // try ssl first
        if (function_exists('openssl_random_pseudo_bytes')) {
            $entropy = openssl_random_pseudo_bytes(64, $strong);
            // skip ssl since it wasn't using the strong algo
            if ($strong !== true) {
                $entropy = '';
            }
        }

        // add some basic mt_rand/uniqid combo
        $entropy .= uniqid(mt_rand(), true);

        // try to read from the windows RNG
        if (class_exists('COM')) {
            try {
                $com = new COM('CAPICOM.Utilities.1');
                $entropy .= base64_decode($com->GetRandom(64, 0));
            } catch (Exception $ex) {
            }
        }

        // try to read from the unix RNG
        if (@is_readable('/dev/urandom')) {
            $h = fopen('/dev/urandom', 'rb');
            $entropy .= fread($h, 64);
            fclose($h);
        }

        $hash = hash('whirlpool', $entropy);
        if ($maxLength) {
            return substr($hash, 0, $maxLength);
        }
        return $hash;
    }

    /**
     * Shorthanded version of fxl_date_conv. This unnecessarily was a full blown
     * class, whereas it could all be put into a single method.
     *
     * @param mixed $date  A date string you wish to convert or an assoc. array holding all the date parts
     * @param string $format  The format as of PHP's date() function
     * @return mixed  FALSE on failure, string on success
     * @since 0.1.0
     */
    static public function format_date($date, $format)
    {
        $year = $month = $day = $hour = $minute = $second = 0;
        if (is_array($date)) {
            foreach ($date as $k => $v) ${$k} = $v;
        } else {
            $date = trim($date);
            if (preg_match('/^(0?\d|[12]\d|3[01])\.(0?\d|1[012])\.(\d+)(?: ([0\s]?[\d]|1\d|2[0-3]):([0\s]?\d|[0-5]\d)(?::([0\s]?\d|[0-5]\d))?)?$/', $date, $m)) {
                array_shift($m);
                if (count($m) >= 3 && checkdate($m[1], $m[0], $m[2])) list ($day, $month, $year, $hour, $minute, $second) = array_pad($m, 6, 0);
            } elseif (preg_match('/^(\d+)-([0\s]\d|1[012])-[\s]?(0?\d|[12]\d|3[01])(?:[\sT]([0\s]?\d|1\d|2[0-3]):([0\s]?\d|[0-5]\d)(?::([0\s]?\d|[0-5]\d))?)?$/', $date, $m)) {
                array_shift($m);
                if (count($m) >= 3 && checkdate($m[1], $m[2], $m[0])) list ($year, $month, $day, $hour, $minute, $second) = array_pad($m, 6, 0);
            } elseif (preg_match('/^(0?\d|[12]\d|3[01])\.(0?\d|1[12])\.$/', $date, $m)) {
                array_shift($m);
                $m[2] = date('Y');
                if (count($m) == 3 && checkdate($m[1], $m[0], $m[2])) list ($day, $month, $year, $hour, $minute, $second) = array_pad($m, 6, 0);
            } else {
                return false;
            }
        }
        if (!$month) return false;
        return date($format, mktime($hour, $minute, $second, $month, $day, $year));
    }

    /**
     * Sends an HTPP request to a foreign host. It should support most of the HTTP 1.0
     * request methods and is even capable of following one 301 response (not more redirections yet).
     *
     * @param array $req holds
     *  - 'host' string Hostname (without http and stuff)
     *  - 'port' int; defaults to 80
     *  - 'path' string; e.g. '/myscript.php'
     *  - 'query' string Data to submit to the host, must be already in the form 'param1=value&param2=value2'
     *  - 'method' string  One of the HTTP methods, if none given, GET is assumed
     *  - 'connect_host' string  Hostname or IP to connect to; if defined, 'host' is given in the HTTP header
     *  Optionally passing a fully valid URI is okay, too
     *[@param string $header Pass a variable here to get the complete HTTP response headers back for your own processing]
     *[@param int $errno  Pass a variable here to receive the errno, if the fsockopen fails]
     *[@param string $errstr Pass a variable here to receive the errstr, if the fsockopen fails]
     * @return string $captured Captured HTTP response body on success, FALSE on failure
     */
    static public function http_request($req, &$header = null, &$errno = null, &$errstr = null)
    {
        $allowMeth = array('HEAD', 'GET', 'POST', 'PUT', 'DELETE', 'OPTIONS', 'MKCOL', 'LOCK', 'UNLOCK');
        // PATCH, PROPFIND, PROPPATCH, COPY, MOVE for WebDAV are not supproted yet
        if (is_string($req)) {
            $req = @parse_url($req);
            if (false === $req) return false; // Did not work out
        }
        if (empty($req)) return false; // No data to work upon

        $req['port'] = (isset($req['port'])) ? intval($req['port']) : 80;
        if (!isset($req['path'])) $req['path'] = '/';
        $req['method'] = (isset($req['method']) && in_array(strtoupper($req['method']), $allowMeth)) ? strtoupper($req['method']) : 'GET';
        $req['connect_host'] = (isset($req['connect_host'])) ? $req['connect_host'] : $req['host'];

        $fp = fsockopen($req['connect_host'], $req['port'], $errno, $errstr, 15);
        if (!$fp) return false;
        switch ($req['method']) {
        case 'GET': case 'OPTIONS': case 'DELETE': case 'MKCOL': case 'LOCK': case 'UNLOCK':
            fputs($fp, $req['method'].' '.$req['path'].(strlen($req['query']) ? '?'.$req['query'] : '').' HTTP/1.0'.CRLF
                    .'Host: '.$req['host'].CRLF.CRLF);
            break;
        default:
            fputs($fp, $req['method'].' '.$req['path'].' HTTP/1.0'.CRLF);
            fputs($fp, 'Host: '.$req['host'].CRLF);
            fputs($fp, 'Content-Type: application/x-www-form-urlencoded'.CRLF);
            fputs($fp, 'Content-Length: '.strlen($req['query']).CRLF);
            fputs($fp, 'Connection: close'.CRLF.CRLF);
            fputs($fp, $req['query']);
        }
        while (!feof($fp) && ($line = fgets($fp, 4096)) && ($line != CRLF)) $header .= $line;
        if (preg_match('!HTTP/1\.[01]\ (301)!', $header)) {
            fclose($fp);
            preg_match('!^Location\:\ (.+)$!Um', $header, $found);
            foreach (parse_url(trim($found[1])) as $k => $v) $req[$k] = $v;
            $fp = fsockopen($req['host'], $req['port'], $errno, $errstr, 15);
            switch ($req['method']) {
            case 'GET': case 'OPTIONS': case 'DELETE': case 'MKCOL': case 'LOCK': case 'UNLOCK':
                fputs($fp, $req['method'].' '.$req['path'].(strlen($req['query']) ? '?'.$req['query'] : '').' HTTP/1.0'.CRLF
                        .'Host: '.$req['host'].CRLF.CRLF);
                break;
            default:
                fputs($fp, $req['method'].' '.$req['path'].' HTTP/1.0'.CRLF);
                fputs($fp, 'Host: '.$req['host'].CRLF);
                fputs($fp, 'Content-Type: application/x-www-form-urlencoded'.CRLF);
                fputs($fp, 'Content-Length: '.strlen($req['query']).CRLF);
                fputs($fp, 'Connection: close'.CRLF.CRLF);
                fputs($fp, $req['query']);
            }
            $header = '';
            while (!feof($fp) && ($line = fgets($fp, 4096)) && ($line != CRLF)) $header .= $line;
        }
        if (!preg_match('!HTTP/1\.[01]\ (200|304)!', $header)) return false;
        $captured = '';
        while (!feof($fp)) $captured .= fread($fp, 8192);
        fclose($fp);
        return $captured;
    }

    /**
     * Creates a thumbnail from a source file and returns it with some info as a string.
     * If the source is not an image or not accessible the function returns false
     *
     * @param string $file Path to the source file
     * @param int $width Maximum width of the bounding box
     * @param int $height Maximum height of the bounding box
     * @return array
     * 'size' => The length of thumbnail string
     * 'mime' => The MIME type of the thumbnail
     * 'stream' => The thumbnail itself as a string
     */
    static public function create_thumbnail($file, $width, $height)
    {
        // File not accessible
        if (!file_exists($file) || !is_readable($file)) return false;
        // Images get a nice thumbnail, additionally we gather some info for the indexer
        $ii = getimagesize($file);
        // Only try creating the thumbnail with the correct GD support.
        // GIF got dropped a while ago, then reappeared again; JPEG or PNG might not be compiled in
        if ($ii[2] == 1 && !function_exists('imagecreatefromgif')) $ii[2] = 0;
        if ($ii[2] == 2 && !function_exists('imagecreatefromjpeg')) $ii[2] = 0;
        if ($ii[2] == 3 && !function_exists('imagecreatefrompng')) $ii[2] = 0;
        if ($ii[2] == 15 && !function_exists('imagecreatefromwbmp')) $ii[2] = 0;
        // Not a supported source image file type
        if (false === $ii || $ii[2] < 1 || $ii[2] > 3) return false;
        // Cannot create true color thumbnail resource
        if (!function_exists('imagecreatetruecolor')) return false;
        $ti = $ii;
        if ($ti[0] > $width || $ti[1] > $height) {
            $wf = $ti[0] / $width; // Calculate width factor
            $hf = $ti[1] / $height; // Calculate height factor
            if ($wf >= $hf && $wf > 1) {
                $ti[0] /= $wf;
                $ti[1] /= $wf;
            } elseif ($hf > 1) {
                $ti[0] /= $hf;
                $ti[1] /= $hf;
            }
            $ti[0] = round($ti[0], 0);
            $ti[1] = round($ti[1], 0);
        }
        if ($ii[2] == 1) {
            $si = imagecreatefromgif($file);
        } elseif ($ii[2] == 2) {
            $si = imagecreatefromjpeg($file);
        } elseif ($ii[2] == 3) {
            $si = imagecreatefrompng($file);
        } elseif ($ii[2] == 15) {
            $si = imagecreatefromwbmp($file);
        }
        // Creation of resource failed
        if (!$si) return false;
        $tn = imagecreatetruecolor($ti[0], $ti[1]);
        imagecopyresampled($tn, $si, 0, 0, 0, 0, $ti[0], $ti[1], $ii[0], $ii[1]);
        // Get the thumbnail and populate thumbinfo
        ob_start();
        if (imagetypes() & IMG_JPG) {
            $thmime = 'image/jpeg';
            imagejpeg($tn, null, 75);
        } elseif (imagetypes() & IMG_PNG) {
            $thmime = 'image/png';
            imagepng($tn, null);
        } elseif (imagetypes() & IMG_GIF) {
            $thmime = 'image/gif';
            imagegif($tn, null);
        }
        $thstream = ob_get_clean();
        imagedestroy($tn);
        return array('size' => strlen($thstream), 'mime' => $thmime, 'width' => $ti[0], 'height' => $ti[1], 'stream' => $thstream);
    }

    /**
     * query the Google Maps Geocoder
     * It's highly recommended to cache the result, as Google limits the number of
     * geocode requests per day.
     *
     * @param array $obj  Holds the relevant address info. Keys:
     * - 'zip' => German PLZ or the city as a string, e.g. Berlin
     * - 'address' => string Street and no, e.g. Alexanderstrass 1
     * - 'country' => Optiional, Default: Germany
     * - 'apikey' => The Google Maps API key for the domain you query the coder for
     * @return array|false  Array with the keys 'longitude' and 'latitude' on success or false on error
     * @since 0.1.3
     */
    static public function queryGoogleGeoCoder($obj)
    {
        if (empty($obj) || !isset($obj['zip']) || !isset($obj['apikey'])) return false;
        $zip = ($obj['zip']) ? $obj['zip'] : 'Berlin';
        $country = isset($obj['country']) && $_REQUEST['country'] ? $_REQUEST['cuntry'] : 'Germany';
        $response = basics::http_request(array
                ('host' => 'maps.google.com'
                ,'path' => '/maps/geo'
                ,'query' => 'q='.urlencode($obj['address']).',+'.urlencode($zip).',+'.urlencode($country).'&output=xml&key='.$obj['apikey']
                ,'method' => 'GET'
                ), $header);
        if (preg_match('!\<coordinates\>([-0-9.,]+)\<\/coordinates\>!U', $response, $found)) {
            $coords = explode(',', $found[1]);
            if (isset($coords[1])) return array('longitude' => $coords[0], 'latitude' => $coords[1]);
        }
        return false;
    }
}
?>
Return current item: phlyMail Lite