mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-12-27 09:09:04 +01:00
create a new 1.4 branch
This commit is contained in:
parent
feb4e7bdb9
commit
5d61c28498
2046
egw-pear/HTTP/WebDAV/Server.php
Normal file
2046
egw-pear/HTTP/WebDAV/Server.php
Normal file
File diff suppressed because it is too large
Load Diff
801
egw-pear/HTTP/WebDAV/Server/Filesystem.php
Normal file
801
egw-pear/HTTP/WebDAV/Server/Filesystem.php
Normal file
@ -0,0 +1,801 @@
|
||||
<?php
|
||||
|
||||
require_once "HTTP/WebDAV/Server.php";
|
||||
require_once "System.php";
|
||||
|
||||
/**
|
||||
* Filesystem access using WebDAV
|
||||
*
|
||||
* @access public
|
||||
* @author Hartmut Holzgraefe <hartmut@php.net>
|
||||
* @version @package-version@
|
||||
*/
|
||||
class HTTP_WebDAV_Server_Filesystem extends HTTP_WebDAV_Server
|
||||
{
|
||||
/**
|
||||
* Root directory for WebDAV access
|
||||
*
|
||||
* Defaults to webserver document root (set by ServeRequest)
|
||||
*
|
||||
* @access private
|
||||
* @var string
|
||||
*/
|
||||
var $base = "";
|
||||
|
||||
/**
|
||||
* MySQL Host where property and locking information is stored
|
||||
*
|
||||
* @access private
|
||||
* @var string
|
||||
*/
|
||||
var $db_host = "localhost";
|
||||
|
||||
/**
|
||||
* MySQL database for property/locking information storage
|
||||
*
|
||||
* @access private
|
||||
* @var string
|
||||
*/
|
||||
var $db_name = "webdav";
|
||||
|
||||
/**
|
||||
* MySQL table name prefix
|
||||
*
|
||||
* @access private
|
||||
* @var string
|
||||
*/
|
||||
var $db_prefix = "";
|
||||
|
||||
/**
|
||||
* MySQL user for property/locking db access
|
||||
*
|
||||
* @access private
|
||||
* @var string
|
||||
*/
|
||||
var $db_user = "root";
|
||||
|
||||
/**
|
||||
* MySQL password for property/locking db access
|
||||
*
|
||||
* @access private
|
||||
* @var string
|
||||
*/
|
||||
var $db_passwd = "";
|
||||
|
||||
/**
|
||||
* Serve a webdav request
|
||||
*
|
||||
* @access public
|
||||
* @param string
|
||||
*/
|
||||
function ServeRequest($base = false)
|
||||
{
|
||||
// special treatment for litmus compliance test
|
||||
// reply on its identifier header
|
||||
// not needed for the test itself but eases debugging
|
||||
foreach (apache_request_headers() as $key => $value) {
|
||||
if (stristr($key, "litmus")) {
|
||||
error_log("Litmus test $value");
|
||||
header("X-Litmus-reply: ".$value);
|
||||
}
|
||||
}
|
||||
|
||||
// set root directory, defaults to webserver document root if not set
|
||||
if ($base) {
|
||||
$this->base = realpath($base); // TODO throw if not a directory
|
||||
} else if (!$this->base) {
|
||||
$this->base = $this->_SERVER['DOCUMENT_ROOT'];
|
||||
}
|
||||
|
||||
// establish connection to property/locking db
|
||||
mysql_connect($this->db_host, $this->db_user, $this->db_passwd) or die(mysql_error());
|
||||
mysql_select_db($this->db_name) or die(mysql_error());
|
||||
// TODO throw on connection problems
|
||||
|
||||
// let the base class do all the work
|
||||
parent::ServeRequest();
|
||||
}
|
||||
|
||||
/**
|
||||
* No authentication is needed here
|
||||
*
|
||||
* @access private
|
||||
* @param string HTTP Authentication type (Basic, Digest, ...)
|
||||
* @param string Username
|
||||
* @param string Password
|
||||
* @return bool true on successful authentication
|
||||
*/
|
||||
function check_auth($type, $user, $pass)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* PROPFIND method handler
|
||||
*
|
||||
* @param array general parameter passing array
|
||||
* @param array return array for file properties
|
||||
* @return bool true on success
|
||||
*/
|
||||
function PROPFIND(&$options, &$files)
|
||||
{
|
||||
// get absolute fs path to requested resource
|
||||
$fspath = $this->base . $options["path"];
|
||||
|
||||
// sanity check
|
||||
if (!file_exists($fspath)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// prepare property array
|
||||
$files["files"] = array();
|
||||
|
||||
// store information for the requested path itself
|
||||
$files["files"][] = $this->fileinfo($options["path"]);
|
||||
|
||||
// information for contained resources requested?
|
||||
if (!empty($options["depth"])) { // TODO check for is_dir() first?
|
||||
|
||||
// make sure path ends with '/'
|
||||
$options["path"] = $this->_slashify($options["path"]);
|
||||
|
||||
// try to open directory
|
||||
$handle = @opendir($fspath);
|
||||
|
||||
if ($handle) {
|
||||
// ok, now get all its contents
|
||||
while ($filename = readdir($handle)) {
|
||||
if ($filename != "." && $filename != "..") {
|
||||
$files["files"][] = $this->fileinfo($options["path"].$filename);
|
||||
}
|
||||
}
|
||||
// TODO recursion needed if "Depth: infinite"
|
||||
}
|
||||
}
|
||||
|
||||
// ok, all done
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get properties for a single file/resource
|
||||
*
|
||||
* @param string resource path
|
||||
* @return array resource properties
|
||||
*/
|
||||
function fileinfo($path)
|
||||
{
|
||||
// map URI path to filesystem path
|
||||
$fspath = $this->base . $path;
|
||||
|
||||
// create result array
|
||||
$info = array();
|
||||
// TODO remove slash append code when base clase is able to do it itself
|
||||
$info["path"] = is_dir($fspath) ? $this->_slashify($path) : $path;
|
||||
$info["props"] = array();
|
||||
|
||||
// no special beautified displayname here ...
|
||||
$info["props"][] = $this->mkprop("displayname", strtoupper($path));
|
||||
|
||||
// creation and modification time
|
||||
$info["props"][] = $this->mkprop("creationdate", filectime($fspath));
|
||||
$info["props"][] = $this->mkprop("getlastmodified", filemtime($fspath));
|
||||
|
||||
// type and size (caller already made sure that path exists)
|
||||
if (is_dir($fspath)) {
|
||||
// directory (WebDAV collection)
|
||||
$info["props"][] = $this->mkprop("resourcetype", "collection");
|
||||
$info["props"][] = $this->mkprop("getcontenttype", "httpd/unix-directory");
|
||||
} else {
|
||||
// plain file (WebDAV resource)
|
||||
$info["props"][] = $this->mkprop("resourcetype", "");
|
||||
if (is_readable($fspath)) {
|
||||
$info["props"][] = $this->mkprop("getcontenttype", $this->_mimetype($fspath));
|
||||
} else {
|
||||
$info["props"][] = $this->mkprop("getcontenttype", "application/x-non-readable");
|
||||
}
|
||||
$info["props"][] = $this->mkprop("getcontentlength", filesize($fspath));
|
||||
}
|
||||
|
||||
// get additional properties from database
|
||||
$query = "SELECT ns, name, value
|
||||
FROM {$this->db_prefix}properties
|
||||
WHERE path = '$path'";
|
||||
$res = mysql_query($query);
|
||||
while ($row = mysql_fetch_assoc($res)) {
|
||||
$info["props"][] = $this->mkprop($row["ns"], $row["name"], $row["value"]);
|
||||
}
|
||||
mysql_free_result($res);
|
||||
|
||||
return $info;
|
||||
}
|
||||
|
||||
/**
|
||||
* detect if a given program is found in the search PATH
|
||||
*
|
||||
* helper function used by _mimetype() to detect if the
|
||||
* external 'file' utility is available
|
||||
*
|
||||
* @param string program name
|
||||
* @param string optional search path, defaults to $PATH
|
||||
* @return bool true if executable program found in path
|
||||
*/
|
||||
function _can_execute($name, $path = false)
|
||||
{
|
||||
// path defaults to PATH from environment if not set
|
||||
if ($path === false) {
|
||||
$path = getenv("PATH");
|
||||
}
|
||||
|
||||
// check method depends on operating system
|
||||
if (!strncmp(PHP_OS, "WIN", 3)) {
|
||||
// on Windows an appropriate COM or EXE file needs to exist
|
||||
$exts = array(".exe", ".com");
|
||||
$check_fn = "file_exists";
|
||||
} else {
|
||||
// anywhere else we look for an executable file of that name
|
||||
$exts = array("");
|
||||
$check_fn = "is_executable";
|
||||
}
|
||||
|
||||
// now check the directories in the path for the program
|
||||
foreach (explode(PATH_SEPARATOR, $path) as $dir) {
|
||||
// skip invalid path entries
|
||||
if (!file_exists($dir)) continue;
|
||||
if (!is_dir($dir)) continue;
|
||||
|
||||
// and now look for the file
|
||||
foreach ($exts as $ext) {
|
||||
if ($check_fn("$dir/$name".$ext)) return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* try to detect the mime type of a file
|
||||
*
|
||||
* @param string file path
|
||||
* @return string guessed mime type
|
||||
*/
|
||||
function _mimetype($fspath)
|
||||
{
|
||||
if (@is_dir($fspath)) {
|
||||
// directories are easy
|
||||
return "httpd/unix-directory";
|
||||
} else if (function_exists("mime_content_type")) {
|
||||
// use mime magic extension if available
|
||||
$mime_type = mime_content_type($fspath);
|
||||
} else if ($this->_can_execute("file")) {
|
||||
// it looks like we have a 'file' command,
|
||||
// lets see it it does have mime support
|
||||
$fp = popen("file -i '$fspath' 2>/dev/null", "r");
|
||||
$reply = fgets($fp);
|
||||
pclose($fp);
|
||||
|
||||
// popen will not return an error if the binary was not found
|
||||
// and find may not have mime support using "-i"
|
||||
// so we test the format of the returned string
|
||||
|
||||
// the reply begins with the requested filename
|
||||
if (!strncmp($reply, "$fspath: ", strlen($fspath)+2)) {
|
||||
$reply = substr($reply, strlen($fspath)+2);
|
||||
// followed by the mime type (maybe including options)
|
||||
if (preg_match('|^[[:alnum:]_-]+/[[:alnum:]_-]+;?.*|', $reply, $matches)) {
|
||||
$mime_type = $matches[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($mime_type)) {
|
||||
// Fallback solution: try to guess the type by the file extension
|
||||
// TODO: add more ...
|
||||
// TODO: it has been suggested to delegate mimetype detection
|
||||
// to apache but this has at least three issues:
|
||||
// - works only with apache
|
||||
// - needs file to be within the document tree
|
||||
// - requires apache mod_magic
|
||||
// TODO: can we use the registry for this on Windows?
|
||||
// OTOH if the server is Windos the clients are likely to
|
||||
// be Windows, too, and tend do ignore the Content-Type
|
||||
// anyway (overriding it with information taken from
|
||||
// the registry)
|
||||
// TODO: have a seperate PEAR class for mimetype detection?
|
||||
switch (strtolower(strrchr(basename($fspath), "."))) {
|
||||
case ".html":
|
||||
$mime_type = "text/html";
|
||||
break;
|
||||
case ".gif":
|
||||
$mime_type = "image/gif";
|
||||
break;
|
||||
case ".jpg":
|
||||
$mime_type = "image/jpeg";
|
||||
break;
|
||||
default:
|
||||
$mime_type = "application/octet-stream";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $mime_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* GET method handler
|
||||
*
|
||||
* @param array parameter passing array
|
||||
* @return bool true on success
|
||||
*/
|
||||
function GET(&$options)
|
||||
{
|
||||
// get absolute fs path to requested resource
|
||||
$fspath = $this->base . $options["path"];
|
||||
|
||||
// sanity check
|
||||
if (!file_exists($fspath)) return false;
|
||||
|
||||
// is this a collection?
|
||||
if (is_dir($fspath)) {
|
||||
return $this->GetDir($fspath, $options);
|
||||
}
|
||||
|
||||
// detect resource type
|
||||
$options['mimetype'] = $this->_mimetype($fspath);
|
||||
|
||||
// detect modification time
|
||||
// see rfc2518, section 13.7
|
||||
// some clients seem to treat this as a reverse rule
|
||||
// requiering a Last-Modified header if the getlastmodified header was set
|
||||
$options['mtime'] = filemtime($fspath);
|
||||
|
||||
// detect resource size
|
||||
$options['size'] = filesize($fspath);
|
||||
|
||||
// no need to check result here, it is handled by the base class
|
||||
$options['stream'] = fopen($fspath, "r");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* GET method handler for directories
|
||||
*
|
||||
* This is a very simple mod_index lookalike.
|
||||
* See RFC 2518, Section 8.4 on GET/HEAD for collections
|
||||
*
|
||||
* @param string directory path
|
||||
* @return void function has to handle HTTP response itself
|
||||
*/
|
||||
function GetDir($fspath, &$options)
|
||||
{
|
||||
$path = $this->_slashify($options["path"]);
|
||||
if ($path != $options["path"]) {
|
||||
header("Location: ".$this->base_uri.$path);
|
||||
exit;
|
||||
}
|
||||
|
||||
// fixed width directory column format
|
||||
$format = "%15s %-19s %-s\n";
|
||||
|
||||
$handle = @opendir($fspath);
|
||||
if (!$handle) {
|
||||
return false;
|
||||
}
|
||||
|
||||
echo "<html><head><title>Index of ".htmlspecialchars($options['path'])."</title></head>\n";
|
||||
|
||||
echo "<h1>Index of ".htmlspecialchars($options['path'])."</h1>\n";
|
||||
|
||||
echo "<pre>";
|
||||
printf($format, "Size", "Last modified", "Filename");
|
||||
echo "<hr>";
|
||||
|
||||
while ($filename = readdir($handle)) {
|
||||
if ($filename != "." && $filename != "..") {
|
||||
$fullpath = $fspath."/".$filename;
|
||||
$name = htmlspecialchars($filename);
|
||||
printf($format,
|
||||
number_format(filesize($fullpath)),
|
||||
strftime("%Y-%m-%d %H:%M:%S", filemtime($fullpath)),
|
||||
"<a href='$name'>$name</a>");
|
||||
}
|
||||
}
|
||||
|
||||
echo "</pre>";
|
||||
|
||||
closedir($handle);
|
||||
|
||||
echo "</html>\n";
|
||||
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* PUT method handler
|
||||
*
|
||||
* @param array parameter passing array
|
||||
* @return bool true on success
|
||||
*/
|
||||
function PUT(&$options)
|
||||
{
|
||||
$fspath = $this->base . $options["path"];
|
||||
|
||||
if (!@is_dir(dirname($fspath))) {
|
||||
return "409 Conflict";
|
||||
}
|
||||
|
||||
$options["new"] = ! file_exists($fspath);
|
||||
|
||||
$fp = fopen($fspath, "w");
|
||||
|
||||
return $fp;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* MKCOL method handler
|
||||
*
|
||||
* @param array general parameter passing array
|
||||
* @return bool true on success
|
||||
*/
|
||||
function MKCOL($options)
|
||||
{
|
||||
$path = $this->base .$options["path"];
|
||||
$parent = dirname($path);
|
||||
$name = basename($path);
|
||||
|
||||
if (!file_exists($parent)) {
|
||||
return "409 Conflict";
|
||||
}
|
||||
|
||||
if (!is_dir($parent)) {
|
||||
return "403 Forbidden";
|
||||
}
|
||||
|
||||
if ( file_exists($parent."/".$name) ) {
|
||||
return "405 Method not allowed";
|
||||
}
|
||||
|
||||
if (!empty($this->_SERVER["CONTENT_LENGTH"])) { // no body parsing yet
|
||||
return "415 Unsupported media type";
|
||||
}
|
||||
|
||||
$stat = mkdir($parent."/".$name, 0777);
|
||||
if (!$stat) {
|
||||
return "403 Forbidden";
|
||||
}
|
||||
|
||||
return ("201 Created");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* DELETE method handler
|
||||
*
|
||||
* @param array general parameter passing array
|
||||
* @return bool true on success
|
||||
*/
|
||||
function DELETE($options)
|
||||
{
|
||||
$path = $this->base . "/" .$options["path"];
|
||||
|
||||
if (!file_exists($path)) {
|
||||
return "404 Not found";
|
||||
}
|
||||
|
||||
if (is_dir($path)) {
|
||||
$query = "DELETE FROM {$this->db_prefix}properties
|
||||
WHERE path LIKE '".$this->_slashify($options["path"])."%'";
|
||||
mysql_query($query);
|
||||
System::rm("-rf $path");
|
||||
} else {
|
||||
unlink($path);
|
||||
}
|
||||
$query = "DELETE FROM {$this->db_prefix}properties
|
||||
WHERE path = '$options[path]'";
|
||||
mysql_query($query);
|
||||
|
||||
return "204 No Content";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* MOVE method handler
|
||||
*
|
||||
* @param array general parameter passing array
|
||||
* @return bool true on success
|
||||
*/
|
||||
function MOVE($options)
|
||||
{
|
||||
return $this->COPY($options, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* COPY method handler
|
||||
*
|
||||
* @param array general parameter passing array
|
||||
* @return bool true on success
|
||||
*/
|
||||
function COPY($options, $del=false)
|
||||
{
|
||||
// TODO Property updates still broken (Litmus should detect this?)
|
||||
|
||||
if (!empty($this->_SERVER["CONTENT_LENGTH"])) { // no body parsing yet
|
||||
return "415 Unsupported media type";
|
||||
}
|
||||
|
||||
// no copying to different WebDAV Servers yet
|
||||
if (isset($options["dest_url"])) {
|
||||
return "502 bad gateway";
|
||||
}
|
||||
|
||||
$source = $this->base .$options["path"];
|
||||
if (!file_exists($source)) return "404 Not found";
|
||||
|
||||
$dest = $this->base . $options["dest"];
|
||||
$new = !file_exists($dest);
|
||||
$existing_col = false;
|
||||
|
||||
if (!$new) {
|
||||
if ($del && is_dir($dest)) {
|
||||
if (!$options["overwrite"]) {
|
||||
return "412 precondition failed";
|
||||
}
|
||||
$dest .= basename($source);
|
||||
if (file_exists($dest)) {
|
||||
$options["dest"] .= basename($source);
|
||||
} else {
|
||||
$new = true;
|
||||
$existing_col = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!$new) {
|
||||
if ($options["overwrite"]) {
|
||||
$stat = $this->DELETE(array("path" => $options["dest"]));
|
||||
if (($stat{0} != "2") && (substr($stat, 0, 3) != "404")) {
|
||||
return $stat;
|
||||
}
|
||||
} else {
|
||||
return "412 precondition failed";
|
||||
}
|
||||
}
|
||||
|
||||
if (is_dir($source) && ($options["depth"] != "infinity")) {
|
||||
// RFC 2518 Section 9.2, last paragraph
|
||||
return "400 Bad request";
|
||||
}
|
||||
|
||||
if ($del) {
|
||||
if (!rename($source, $dest)) {
|
||||
return "500 Internal server error";
|
||||
}
|
||||
$destpath = $this->_unslashify($options["dest"]);
|
||||
if (is_dir($source)) {
|
||||
$query = "UPDATE {$this->db_prefix}properties
|
||||
SET path = REPLACE(path, '".$options["path"]."', '".$destpath."')
|
||||
WHERE path LIKE '".$this->_slashify($options["path"])."%'";
|
||||
mysql_query($query);
|
||||
}
|
||||
|
||||
$query = "UPDATE {$this->db_prefix}properties
|
||||
SET path = '".$destpath."'
|
||||
WHERE path = '".$options["path"]."'";
|
||||
mysql_query($query);
|
||||
} else {
|
||||
if (is_dir($source)) {
|
||||
$files = System::find($source);
|
||||
$files = array_reverse($files);
|
||||
} else {
|
||||
$files = array($source);
|
||||
}
|
||||
|
||||
if (!is_array($files) || empty($files)) {
|
||||
return "500 Internal server error";
|
||||
}
|
||||
|
||||
|
||||
foreach ($files as $file) {
|
||||
if (is_dir($file)) {
|
||||
$file = $this->_slashify($file);
|
||||
}
|
||||
|
||||
$destfile = str_replace($source, $dest, $file);
|
||||
|
||||
if (is_dir($file)) {
|
||||
if (!is_dir($destfile)) {
|
||||
// TODO "mkdir -p" here? (only natively supported by PHP 5)
|
||||
if (!@mkdir($destfile)) {
|
||||
return "409 Conflict";
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!@copy($file, $destfile)) {
|
||||
return "409 Conflict";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$query = "INSERT INTO {$this->db_prefix}properties
|
||||
SELECT *
|
||||
FROM {$this->db_prefix}properties
|
||||
WHERE path = '".$options['path']."'";
|
||||
}
|
||||
|
||||
return ($new && !$existing_col) ? "201 Created" : "204 No Content";
|
||||
}
|
||||
|
||||
/**
|
||||
* PROPPATCH method handler
|
||||
*
|
||||
* @param array general parameter passing array
|
||||
* @return bool true on success
|
||||
*/
|
||||
function PROPPATCH(&$options)
|
||||
{
|
||||
global $prefs, $tab;
|
||||
|
||||
$msg = "";
|
||||
$path = $options["path"];
|
||||
$dir = dirname($path)."/";
|
||||
$base = basename($path);
|
||||
|
||||
foreach ($options["props"] as $key => $prop) {
|
||||
if ($prop["ns"] == "DAV:") {
|
||||
$options["props"][$key]['status'] = "403 Forbidden";
|
||||
} else {
|
||||
if (isset($prop["val"])) {
|
||||
$query = "REPLACE INTO {$this->db_prefix}properties
|
||||
SET path = '$options[path]'
|
||||
, name = '$prop[name]'
|
||||
, ns= '$prop[ns]'
|
||||
, value = '$prop[val]'";
|
||||
} else {
|
||||
$query = "DELETE FROM {$this->db_prefix}properties
|
||||
WHERE path = '$options[path]'
|
||||
AND name = '$prop[name]'
|
||||
AND ns = '$prop[ns]'";
|
||||
}
|
||||
mysql_query($query);
|
||||
}
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* LOCK method handler
|
||||
*
|
||||
* @param array general parameter passing array
|
||||
* @return bool true on success
|
||||
*/
|
||||
function LOCK(&$options)
|
||||
{
|
||||
// get absolute fs path to requested resource
|
||||
$fspath = $this->base . $options["path"];
|
||||
|
||||
// TODO recursive locks on directories not supported yet
|
||||
if (is_dir($fspath) && !empty($options["depth"])) {
|
||||
return "409 Conflict";
|
||||
}
|
||||
|
||||
$options["timeout"] = time()+300; // 5min. hardcoded
|
||||
|
||||
if (isset($options["update"])) { // Lock Update
|
||||
$where = "WHERE path = '$options[path]' AND token = '$options[update]'";
|
||||
|
||||
$query = "SELECT owner, exclusivelock FROM {$this->db_prefix}locks $where";
|
||||
$res = mysql_query($query);
|
||||
$row = mysql_fetch_assoc($res);
|
||||
mysql_free_result($res);
|
||||
|
||||
if (is_array($row)) {
|
||||
$query = "UPDATE {$this->db_prefix}locks
|
||||
SET expires = '$options[timeout]'
|
||||
, modified = ".time()."
|
||||
$where";
|
||||
mysql_query($query);
|
||||
|
||||
$options['owner'] = $row['owner'];
|
||||
$options['scope'] = $row["exclusivelock"] ? "exclusive" : "shared";
|
||||
$options['type'] = $row["exclusivelock"] ? "write" : "read";
|
||||
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
$query = "INSERT INTO {$this->db_prefix}locks
|
||||
SET token = '$options[locktoken]'
|
||||
, path = '$options[path]'
|
||||
, created = ".time()."
|
||||
, modified = ".time()."
|
||||
, owner = '$options[owner]'
|
||||
, expires = '$options[timeout]'
|
||||
, exclusivelock = " .($options['scope'] === "exclusive" ? "1" : "0")
|
||||
;
|
||||
mysql_query($query);
|
||||
|
||||
return mysql_affected_rows() ? "200 OK" : "409 Conflict";
|
||||
}
|
||||
|
||||
/**
|
||||
* UNLOCK method handler
|
||||
*
|
||||
* @param array general parameter passing array
|
||||
* @return bool true on success
|
||||
*/
|
||||
function UNLOCK(&$options)
|
||||
{
|
||||
$query = "DELETE FROM {$this->db_prefix}locks
|
||||
WHERE path = '$options[path]'
|
||||
AND token = '$options[token]'";
|
||||
mysql_query($query);
|
||||
|
||||
return mysql_affected_rows() ? "204 No Content" : "409 Conflict";
|
||||
}
|
||||
|
||||
/**
|
||||
* checkLock() helper
|
||||
*
|
||||
* @param string resource path to check for locks
|
||||
* @return bool true on success
|
||||
*/
|
||||
function checkLock($path)
|
||||
{
|
||||
$result = false;
|
||||
|
||||
$query = "SELECT owner, token, created, modified, expires, exclusivelock
|
||||
FROM {$this->db_prefix}locks
|
||||
WHERE path = '$path'
|
||||
";
|
||||
$res = mysql_query($query);
|
||||
|
||||
if ($res) {
|
||||
$row = mysql_fetch_array($res);
|
||||
mysql_free_result($res);
|
||||
|
||||
if ($row) {
|
||||
$result = array( "type" => "write",
|
||||
"scope" => $row["exclusivelock"] ? "exclusive" : "shared",
|
||||
"depth" => 0,
|
||||
"owner" => $row['owner'],
|
||||
"token" => $row['token'],
|
||||
"created" => $row['created'],
|
||||
"modified" => $row['modified'],
|
||||
"expires" => $row['expires']
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* create database tables for property and lock storage
|
||||
*
|
||||
* @param void
|
||||
* @return bool true on success
|
||||
*/
|
||||
function create_database()
|
||||
{
|
||||
// TODO
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* indent-tabs-mode:nil
|
||||
* End:
|
||||
*/
|
237
egw-pear/HTTP/WebDAV/Tools/_parse_lockinfo.php
Normal file
237
egw-pear/HTTP/WebDAV/Tools/_parse_lockinfo.php
Normal file
@ -0,0 +1,237 @@
|
||||
<?php
|
||||
//
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP Version 4 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1997-2003 The PHP Group |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | This source file is subject to version 2.02 of the PHP license, |
|
||||
// | that is bundled with this package in the file LICENSE, and is |
|
||||
// | available at through the world-wide-web at |
|
||||
// | http://www.php.net/license/2_02.txt. |
|
||||
// | If you did not receive a copy of the PHP license and are unable to |
|
||||
// | obtain it through the world-wide-web, please send a note to |
|
||||
// | license@php.net so we can mail you a copy immediately. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Authors: Hartmut Holzgraefe <hholzgra@php.net> |
|
||||
// | Christian Stocker <chregu@bitflux.ch> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id: _parse_lockinfo.php,v 1.4 2006/10/10 11:53:17 hholzgra Exp $
|
||||
//
|
||||
|
||||
/**
|
||||
* helper class for parsing LOCK request bodies
|
||||
*
|
||||
* @package HTTP_WebDAV_Server
|
||||
* @author Hartmut Holzgraefe <hholzgra@php.net>
|
||||
* @version @package-version@
|
||||
*/
|
||||
class _parse_lockinfo
|
||||
{
|
||||
/**
|
||||
* success state flag
|
||||
*
|
||||
* @var bool
|
||||
* @access public
|
||||
*/
|
||||
var $success = false;
|
||||
|
||||
/**
|
||||
* lock type, currently only "write"
|
||||
*
|
||||
* @var string
|
||||
* @access public
|
||||
*/
|
||||
var $locktype = "";
|
||||
|
||||
/**
|
||||
* lock scope, "shared" or "exclusive"
|
||||
*
|
||||
* @var string
|
||||
* @access public
|
||||
*/
|
||||
var $lockscope = "";
|
||||
|
||||
/**
|
||||
* lock owner information
|
||||
*
|
||||
* @var string
|
||||
* @access public
|
||||
*/
|
||||
var $owner = "";
|
||||
|
||||
/**
|
||||
* flag that is set during lock owner read
|
||||
*
|
||||
* @var bool
|
||||
* @access private
|
||||
*/
|
||||
var $collect_owner = false;
|
||||
|
||||
/**
|
||||
* constructor
|
||||
*
|
||||
* @param string path of stream to read
|
||||
* @access public
|
||||
*/
|
||||
function _parse_lockinfo($path)
|
||||
{
|
||||
// we assume success unless problems occur
|
||||
$this->success = true;
|
||||
|
||||
// remember if any input was parsed
|
||||
$had_input = false;
|
||||
|
||||
// open stream
|
||||
$f_in = fopen($path, "r");
|
||||
if (!$f_in) {
|
||||
$this->success = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// create namespace aware parser
|
||||
$xml_parser = xml_parser_create_ns("UTF-8", " ");
|
||||
|
||||
// set tag and data handlers
|
||||
xml_set_element_handler($xml_parser,
|
||||
array(&$this, "_startElement"),
|
||||
array(&$this, "_endElement"));
|
||||
xml_set_character_data_handler($xml_parser,
|
||||
array(&$this, "_data"));
|
||||
|
||||
// we want a case sensitive parser
|
||||
xml_parser_set_option($xml_parser,
|
||||
XML_OPTION_CASE_FOLDING, false);
|
||||
|
||||
// parse input
|
||||
while ($this->success && !feof($f_in)) {
|
||||
$line = fgets($f_in);
|
||||
if (is_string($line)) {
|
||||
$had_input = true;
|
||||
$this->success &= xml_parse($xml_parser, $line, false);
|
||||
}
|
||||
}
|
||||
|
||||
// finish parsing
|
||||
if ($had_input) {
|
||||
$this->success &= xml_parse($xml_parser, "", true);
|
||||
}
|
||||
|
||||
// check if required tags where found
|
||||
$this->success &= !empty($this->locktype);
|
||||
$this->success &= !empty($this->lockscope);
|
||||
|
||||
// free parser resource
|
||||
xml_parser_free($xml_parser);
|
||||
|
||||
// close input stream
|
||||
fclose($f_in);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* tag start handler
|
||||
*
|
||||
* @param resource parser
|
||||
* @param string tag name
|
||||
* @param array tag attributes
|
||||
* @return void
|
||||
* @access private
|
||||
*/
|
||||
function _startElement($parser, $name, $attrs)
|
||||
{
|
||||
// namespace handling
|
||||
if (strstr($name, " ")) {
|
||||
list($ns, $tag) = explode(" ", $name);
|
||||
} else {
|
||||
$ns = "";
|
||||
$tag = $name;
|
||||
}
|
||||
|
||||
|
||||
if ($this->collect_owner) {
|
||||
// everything within the <owner> tag needs to be collected
|
||||
$ns_short = "";
|
||||
$ns_attr = "";
|
||||
if ($ns) {
|
||||
if ($ns == "DAV:") {
|
||||
$ns_short = "D:";
|
||||
} else {
|
||||
$ns_attr = " xmlns='$ns'";
|
||||
}
|
||||
}
|
||||
$this->owner .= "<$ns_short$tag$ns_attr>";
|
||||
} else if ($ns == "DAV:") {
|
||||
// parse only the essential tags
|
||||
switch ($tag) {
|
||||
case "write":
|
||||
$this->locktype = $tag;
|
||||
break;
|
||||
case "exclusive":
|
||||
case "shared":
|
||||
$this->lockscope = $tag;
|
||||
break;
|
||||
case "owner":
|
||||
$this->collect_owner = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* data handler
|
||||
*
|
||||
* @param resource parser
|
||||
* @param string data
|
||||
* @return void
|
||||
* @access private
|
||||
*/
|
||||
function _data($parser, $data)
|
||||
{
|
||||
// only the <owner> tag has data content
|
||||
if ($this->collect_owner) {
|
||||
$this->owner .= $data;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* tag end handler
|
||||
*
|
||||
* @param resource parser
|
||||
* @param string tag name
|
||||
* @return void
|
||||
* @access private
|
||||
*/
|
||||
function _endElement($parser, $name)
|
||||
{
|
||||
// namespace handling
|
||||
if (strstr($name, " ")) {
|
||||
list($ns, $tag) = explode(" ", $name);
|
||||
} else {
|
||||
$ns = "";
|
||||
$tag = $name;
|
||||
}
|
||||
|
||||
// <owner> finished?
|
||||
if (($ns == "DAV:") && ($tag == "owner")) {
|
||||
$this->collect_owner = false;
|
||||
}
|
||||
|
||||
// within <owner> we have to collect everything
|
||||
if ($this->collect_owner) {
|
||||
$ns_short = "";
|
||||
$ns_attr = "";
|
||||
if ($ns) {
|
||||
if ($ns == "DAV:") {
|
||||
$ns_short = "D:";
|
||||
} else {
|
||||
$ns_attr = " xmlns='$ns'";
|
||||
}
|
||||
}
|
||||
$this->owner .= "</$ns_short$tag$ns_attr>";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
178
egw-pear/HTTP/WebDAV/Tools/_parse_propfind.php
Normal file
178
egw-pear/HTTP/WebDAV/Tools/_parse_propfind.php
Normal file
@ -0,0 +1,178 @@
|
||||
<?php
|
||||
//
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP Version 4 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1997-2003 The PHP Group |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | This source file is subject to version 2.02 of the PHP license, |
|
||||
// | that is bundled with this package in the file LICENSE, and is |
|
||||
// | available at through the world-wide-web at |
|
||||
// | http://www.php.net/license/2_02.txt. |
|
||||
// | If you did not receive a copy of the PHP license and are unable to |
|
||||
// | obtain it through the world-wide-web, please send a note to |
|
||||
// | license@php.net so we can mail you a copy immediately. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Authors: Hartmut Holzgraefe <hholzgra@php.net> |
|
||||
// | Christian Stocker <chregu@bitflux.ch> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id: _parse_propfind.php,v 1.4 2006/10/10 11:53:17 hholzgra Exp $
|
||||
//
|
||||
|
||||
/**
|
||||
* helper class for parsing PROPFIND request bodies
|
||||
*
|
||||
* @package HTTP_WebDAV_Server
|
||||
* @author Hartmut Holzgraefe <hholzgra@php.net>
|
||||
* @version @package-version@
|
||||
*/
|
||||
class _parse_propfind
|
||||
{
|
||||
/**
|
||||
* success state flag
|
||||
*
|
||||
* @var bool
|
||||
* @access public
|
||||
*/
|
||||
var $success = false;
|
||||
|
||||
/**
|
||||
* found properties are collected here
|
||||
*
|
||||
* @var array
|
||||
* @access public
|
||||
*/
|
||||
var $props = false;
|
||||
|
||||
/**
|
||||
* internal tag nesting depth counter
|
||||
*
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $depth = 0;
|
||||
|
||||
|
||||
/**
|
||||
* constructor
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function _parse_propfind($path)
|
||||
{
|
||||
// success state flag
|
||||
$this->success = true;
|
||||
|
||||
// property storage array
|
||||
$this->props = array();
|
||||
|
||||
// internal tag depth counter
|
||||
$this->depth = 0;
|
||||
|
||||
// remember if any input was parsed
|
||||
$had_input = false;
|
||||
|
||||
// open input stream
|
||||
$f_in = fopen($path, "r");
|
||||
if (!$f_in) {
|
||||
$this->success = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// create XML parser
|
||||
$xml_parser = xml_parser_create_ns("UTF-8", " ");
|
||||
|
||||
// set tag and data handlers
|
||||
xml_set_element_handler($xml_parser,
|
||||
array(&$this, "_startElement"),
|
||||
array(&$this, "_endElement"));
|
||||
|
||||
// we want a case sensitive parser
|
||||
xml_parser_set_option($xml_parser,
|
||||
XML_OPTION_CASE_FOLDING, false);
|
||||
|
||||
|
||||
// parse input
|
||||
while ($this->success && !feof($f_in)) {
|
||||
$line = fgets($f_in);
|
||||
if (is_string($line)) {
|
||||
$had_input = true;
|
||||
$this->success &= xml_parse($xml_parser, $line, false);
|
||||
}
|
||||
}
|
||||
|
||||
// finish parsing
|
||||
if ($had_input) {
|
||||
$this->success &= xml_parse($xml_parser, "", true);
|
||||
}
|
||||
|
||||
// free parser
|
||||
xml_parser_free($xml_parser);
|
||||
|
||||
// close input stream
|
||||
fclose($f_in);
|
||||
|
||||
// if no input was parsed it was a request
|
||||
if(!count($this->props)) $this->props = "all"; // default
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* start tag handler
|
||||
*
|
||||
* @access private
|
||||
* @param resource parser
|
||||
* @param string tag name
|
||||
* @param array tag attributes
|
||||
*/
|
||||
function _startElement($parser, $name, $attrs)
|
||||
{
|
||||
// name space handling
|
||||
if (strstr($name, " ")) {
|
||||
list($ns, $tag) = explode(" ", $name);
|
||||
if ($ns == "")
|
||||
$this->success = false;
|
||||
} else {
|
||||
$ns = "";
|
||||
$tag = $name;
|
||||
}
|
||||
|
||||
// special tags at level 1: <allprop> and <propname>
|
||||
if ($this->depth == 1) {
|
||||
if ($tag == "allprop")
|
||||
$this->props = "all";
|
||||
|
||||
if ($tag == "propname")
|
||||
$this->props = "names";
|
||||
}
|
||||
|
||||
// requested properties are found at level 2
|
||||
if ($this->depth == 2) {
|
||||
$prop = array("name" => $tag);
|
||||
if ($ns)
|
||||
$prop["xmlns"] = $ns;
|
||||
$this->props[] = $prop;
|
||||
}
|
||||
|
||||
// increment depth count
|
||||
$this->depth++;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* end tag handler
|
||||
*
|
||||
* @access private
|
||||
* @param resource parser
|
||||
* @param string tag name
|
||||
*/
|
||||
function _endElement($parser, $name)
|
||||
{
|
||||
// here we only need to decrement the depth count
|
||||
$this->depth--;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
?>
|
223
egw-pear/HTTP/WebDAV/Tools/_parse_proppatch.php
Normal file
223
egw-pear/HTTP/WebDAV/Tools/_parse_proppatch.php
Normal file
@ -0,0 +1,223 @@
|
||||
<?php
|
||||
//
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP Version 4 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1997-2003 The PHP Group |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | This source file is subject to version 2.02 of the PHP license, |
|
||||
// | that is bundled with this package in the file LICENSE, and is |
|
||||
// | available at through the world-wide-web at |
|
||||
// | http://www.php.net/license/2_02.txt. |
|
||||
// | If you did not receive a copy of the PHP license and are unable to |
|
||||
// | obtain it through the world-wide-web, please send a note to |
|
||||
// | license@php.net so we can mail you a copy immediately. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Authors: Hartmut Holzgraefe <hholzgra@php.net> |
|
||||
// | Christian Stocker <chregu@bitflux.ch> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id: _parse_proppatch.php,v 1.6 2006/10/10 11:53:17 hholzgra Exp $
|
||||
//
|
||||
|
||||
/**
|
||||
* helper class for parsing PROPPATCH request bodies
|
||||
*
|
||||
* @package HTTP_WebDAV_Server
|
||||
* @author Hartmut Holzgraefe <hholzgra@php.net>
|
||||
* @version @package-version@
|
||||
*/
|
||||
class _parse_proppatch
|
||||
{
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @var
|
||||
* @access
|
||||
*/
|
||||
var $success;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @var
|
||||
* @access
|
||||
*/
|
||||
var $props;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @var
|
||||
* @access
|
||||
*/
|
||||
var $depth;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @var
|
||||
* @access
|
||||
*/
|
||||
var $mode;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @var
|
||||
* @access
|
||||
*/
|
||||
var $current;
|
||||
|
||||
/**
|
||||
* constructor
|
||||
*
|
||||
* @param string path of input stream
|
||||
* @access public
|
||||
*/
|
||||
function _parse_proppatch($path)
|
||||
{
|
||||
$this->success = true;
|
||||
|
||||
$this->depth = 0;
|
||||
$this->props = array();
|
||||
$had_input = false;
|
||||
|
||||
$f_in = fopen($path, "r");
|
||||
if (!$f_in) {
|
||||
$this->success = false;
|
||||
return;
|
||||
}
|
||||
|
||||
$xml_parser = xml_parser_create_ns("UTF-8", " ");
|
||||
|
||||
xml_set_element_handler($xml_parser,
|
||||
array(&$this, "_startElement"),
|
||||
array(&$this, "_endElement"));
|
||||
|
||||
xml_set_character_data_handler($xml_parser,
|
||||
array(&$this, "_data"));
|
||||
|
||||
xml_parser_set_option($xml_parser,
|
||||
XML_OPTION_CASE_FOLDING, false);
|
||||
|
||||
while($this->success && !feof($f_in)) {
|
||||
$line = fgets($f_in);
|
||||
if (is_string($line)) {
|
||||
$had_input = true;
|
||||
$this->success &= xml_parse($xml_parser, $line, false);
|
||||
}
|
||||
}
|
||||
|
||||
if($had_input) {
|
||||
$this->success &= xml_parse($xml_parser, "", true);
|
||||
}
|
||||
|
||||
xml_parser_free($xml_parser);
|
||||
|
||||
fclose($f_in);
|
||||
}
|
||||
|
||||
/**
|
||||
* tag start handler
|
||||
*
|
||||
* @param resource parser
|
||||
* @param string tag name
|
||||
* @param array tag attributes
|
||||
* @return void
|
||||
* @access private
|
||||
*/
|
||||
function _startElement($parser, $name, $attrs)
|
||||
{
|
||||
if (strstr($name, " ")) {
|
||||
list($ns, $tag) = explode(" ", $name);
|
||||
if ($ns == "")
|
||||
$this->success = false;
|
||||
} else {
|
||||
$ns = "";
|
||||
$tag = $name;
|
||||
}
|
||||
|
||||
if ($this->depth == 1) {
|
||||
$this->mode = $tag;
|
||||
}
|
||||
|
||||
if ($this->depth == 3) {
|
||||
$prop = array("name" => $tag);
|
||||
$this->current = array("name" => $tag, "ns" => $ns, "status"=> 200);
|
||||
if ($this->mode == "set") {
|
||||
$this->current["val"] = ""; // default set val
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->depth >= 4) {
|
||||
$this->current["val"] .= "<$tag";
|
||||
if (isset($attr)) {
|
||||
foreach ($attr as $key => $val) {
|
||||
$this->current["val"] .= ' '.$key.'="'.str_replace('"','"', $val).'"';
|
||||
}
|
||||
}
|
||||
$this->current["val"] .= ">";
|
||||
}
|
||||
|
||||
|
||||
|
||||
$this->depth++;
|
||||
}
|
||||
|
||||
/**
|
||||
* tag end handler
|
||||
*
|
||||
* @param resource parser
|
||||
* @param string tag name
|
||||
* @return void
|
||||
* @access private
|
||||
*/
|
||||
function _endElement($parser, $name)
|
||||
{
|
||||
if (strstr($name, " ")) {
|
||||
list($ns, $tag) = explode(" ", $name);
|
||||
if ($ns == "")
|
||||
$this->success = false;
|
||||
} else {
|
||||
$ns = "";
|
||||
$tag = $name;
|
||||
}
|
||||
|
||||
$this->depth--;
|
||||
|
||||
if ($this->depth >= 4) {
|
||||
$this->current["val"] .= "</$tag>";
|
||||
}
|
||||
|
||||
if ($this->depth == 3) {
|
||||
if (isset($this->current)) {
|
||||
$this->props[] = $this->current;
|
||||
unset($this->current);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* input data handler
|
||||
*
|
||||
* @param resource parser
|
||||
* @param string data
|
||||
* @return void
|
||||
* @access private
|
||||
*/
|
||||
function _data($parser, $data)
|
||||
{
|
||||
if (isset($this->current)) {
|
||||
$this->current["val"] .= $data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* indent-tabs-mode:nil
|
||||
* End:
|
||||
*/
|
824
egw-pear/Log.php
Normal file
824
egw-pear/Log.php
Normal file
@ -0,0 +1,824 @@
|
||||
<?php
|
||||
/**
|
||||
* $Header: /repository/pear/Log/Log.php,v 1.64 2006/10/08 23:03:15 jon Exp $
|
||||
* $Horde: horde/lib/Log.php,v 1.15 2000/06/29 23:39:45 jon Exp $
|
||||
*
|
||||
* @version $Revision: 1.64 $
|
||||
* @package Log
|
||||
*/
|
||||
|
||||
define('PEAR_LOG_EMERG', 0); /** System is unusable */
|
||||
define('PEAR_LOG_ALERT', 1); /** Immediate action required */
|
||||
define('PEAR_LOG_CRIT', 2); /** Critical conditions */
|
||||
define('PEAR_LOG_ERR', 3); /** Error conditions */
|
||||
define('PEAR_LOG_WARNING', 4); /** Warning conditions */
|
||||
define('PEAR_LOG_NOTICE', 5); /** Normal but significant */
|
||||
define('PEAR_LOG_INFO', 6); /** Informational */
|
||||
define('PEAR_LOG_DEBUG', 7); /** Debug-level messages */
|
||||
|
||||
define('PEAR_LOG_ALL', bindec('11111111')); /** All messages */
|
||||
define('PEAR_LOG_NONE', bindec('00000000')); /** No message */
|
||||
|
||||
/* Log types for PHP's native error_log() function. */
|
||||
define('PEAR_LOG_TYPE_SYSTEM', 0); /** Use PHP's system logger */
|
||||
define('PEAR_LOG_TYPE_MAIL', 1); /** Use PHP's mail() function */
|
||||
define('PEAR_LOG_TYPE_DEBUG', 2); /** Use PHP's debugging connection */
|
||||
define('PEAR_LOG_TYPE_FILE', 3); /** Append to a file */
|
||||
|
||||
/**
|
||||
* The Log:: class implements both an abstraction for various logging
|
||||
* mechanisms and the Subject end of a Subject-Observer pattern.
|
||||
*
|
||||
* @author Chuck Hagenbuch <chuck@horde.org>
|
||||
* @author Jon Parise <jon@php.net>
|
||||
* @since Horde 1.3
|
||||
* @package Log
|
||||
*/
|
||||
class Log
|
||||
{
|
||||
/**
|
||||
* Indicates whether or not the log can been opened / connected.
|
||||
*
|
||||
* @var boolean
|
||||
* @access private
|
||||
*/
|
||||
var $_opened = false;
|
||||
|
||||
/**
|
||||
* Instance-specific unique identification number.
|
||||
*
|
||||
* @var integer
|
||||
* @access private
|
||||
*/
|
||||
var $_id = 0;
|
||||
|
||||
/**
|
||||
* The label that uniquely identifies this set of log messages.
|
||||
*
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $_ident = '';
|
||||
|
||||
/**
|
||||
* The default priority to use when logging an event.
|
||||
*
|
||||
* @var integer
|
||||
* @access private
|
||||
*/
|
||||
var $_priority = PEAR_LOG_INFO;
|
||||
|
||||
/**
|
||||
* The bitmask of allowed log levels.
|
||||
*
|
||||
* @var integer
|
||||
* @access private
|
||||
*/
|
||||
var $_mask = PEAR_LOG_ALL;
|
||||
|
||||
/**
|
||||
* Holds all Log_observer objects that wish to be notified of new messages.
|
||||
*
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $_listeners = array();
|
||||
|
||||
/**
|
||||
* Maps canonical format keys to position arguments for use in building
|
||||
* "line format" strings.
|
||||
*
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $_formatMap = array('%{timestamp}' => '%1$s',
|
||||
'%{ident}' => '%2$s',
|
||||
'%{priority}' => '%3$s',
|
||||
'%{message}' => '%4$s',
|
||||
'%{file}' => '%5$s',
|
||||
'%{line}' => '%6$s',
|
||||
'%{function}' => '%7$s',
|
||||
'%\{' => '%%{');
|
||||
|
||||
|
||||
/**
|
||||
* Attempts to return a concrete Log instance of type $handler.
|
||||
*
|
||||
* @param string $handler The type of concrete Log subclass to return.
|
||||
* Attempt to dynamically include the code for
|
||||
* this subclass. Currently, valid values are
|
||||
* 'console', 'syslog', 'sql', 'file', and 'mcal'.
|
||||
*
|
||||
* @param string $name The name of the actually log file, table, or
|
||||
* other specific store to use. Defaults to an
|
||||
* empty string, with which the subclass will
|
||||
* attempt to do something intelligent.
|
||||
*
|
||||
* @param string $ident The identity reported to the log system.
|
||||
*
|
||||
* @param array $conf A hash containing any additional configuration
|
||||
* information that a subclass might need.
|
||||
*
|
||||
* @param int $level Log messages up to and including this level.
|
||||
*
|
||||
* @return object Log The newly created concrete Log instance, or
|
||||
* null on an error.
|
||||
* @access public
|
||||
* @since Log 1.0
|
||||
*/
|
||||
function &factory($handler, $name = '', $ident = '', $conf = array(),
|
||||
$level = PEAR_LOG_DEBUG)
|
||||
{
|
||||
$handler = strtolower($handler);
|
||||
$class = 'Log_' . $handler;
|
||||
$classfile = 'Log/' . $handler . '.php';
|
||||
|
||||
/*
|
||||
* Attempt to include our version of the named class, but don't treat
|
||||
* a failure as fatal. The caller may have already included their own
|
||||
* version of the named class.
|
||||
*/
|
||||
if (!class_exists($class)) {
|
||||
include_once $classfile;
|
||||
}
|
||||
|
||||
/* If the class exists, return a new instance of it. */
|
||||
if (class_exists($class)) {
|
||||
$obj = &new $class($name, $ident, $conf, $level);
|
||||
return $obj;
|
||||
}
|
||||
|
||||
$null = null;
|
||||
return $null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to return a reference to a concrete Log instance of type
|
||||
* $handler, only creating a new instance if no log instance with the same
|
||||
* parameters currently exists.
|
||||
*
|
||||
* You should use this if there are multiple places you might create a
|
||||
* logger, you don't want to create multiple loggers, and you don't want to
|
||||
* check for the existance of one each time. The singleton pattern does all
|
||||
* the checking work for you.
|
||||
*
|
||||
* <b>You MUST call this method with the $var = &Log::singleton() syntax.
|
||||
* Without the ampersand (&) in front of the method name, you will not get
|
||||
* a reference, you will get a copy.</b>
|
||||
*
|
||||
* @param string $handler The type of concrete Log subclass to return.
|
||||
* Attempt to dynamically include the code for
|
||||
* this subclass. Currently, valid values are
|
||||
* 'console', 'syslog', 'sql', 'file', and 'mcal'.
|
||||
*
|
||||
* @param string $name The name of the actually log file, table, or
|
||||
* other specific store to use. Defaults to an
|
||||
* empty string, with which the subclass will
|
||||
* attempt to do something intelligent.
|
||||
*
|
||||
* @param string $ident The identity reported to the log system.
|
||||
*
|
||||
* @param array $conf A hash containing any additional configuration
|
||||
* information that a subclass might need.
|
||||
*
|
||||
* @param int $level Log messages up to and including this level.
|
||||
*
|
||||
* @return object Log The newly created concrete Log instance, or
|
||||
* null on an error.
|
||||
* @access public
|
||||
* @since Log 1.0
|
||||
*/
|
||||
function &singleton($handler, $name = '', $ident = '', $conf = array(),
|
||||
$level = PEAR_LOG_DEBUG)
|
||||
{
|
||||
static $instances;
|
||||
if (!isset($instances)) $instances = array();
|
||||
|
||||
$signature = serialize(array($handler, $name, $ident, $conf, $level));
|
||||
if (!isset($instances[$signature])) {
|
||||
$instances[$signature] = &Log::factory($handler, $name, $ident,
|
||||
$conf, $level);
|
||||
}
|
||||
|
||||
return $instances[$signature];
|
||||
}
|
||||
|
||||
/**
|
||||
* Abstract implementation of the open() method.
|
||||
* @since Log 1.0
|
||||
*/
|
||||
function open()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Abstract implementation of the close() method.
|
||||
* @since Log 1.0
|
||||
*/
|
||||
function close()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Abstract implementation of the flush() method.
|
||||
* @since Log 1.8.2
|
||||
*/
|
||||
function flush()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Abstract implementation of the log() method.
|
||||
* @since Log 1.0
|
||||
*/
|
||||
function log($message, $priority = null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* A convenience function for logging a emergency event. It will log a
|
||||
* message at the PEAR_LOG_EMERG log level.
|
||||
*
|
||||
* @param mixed $message String or object containing the message
|
||||
* to log.
|
||||
*
|
||||
* @return boolean True if the message was successfully logged.
|
||||
*
|
||||
* @access public
|
||||
* @since Log 1.7.0
|
||||
*/
|
||||
function emerg($message)
|
||||
{
|
||||
return $this->log($message, PEAR_LOG_EMERG);
|
||||
}
|
||||
|
||||
/**
|
||||
* A convenience function for logging an alert event. It will log a
|
||||
* message at the PEAR_LOG_ALERT log level.
|
||||
*
|
||||
* @param mixed $message String or object containing the message
|
||||
* to log.
|
||||
*
|
||||
* @return boolean True if the message was successfully logged.
|
||||
*
|
||||
* @access public
|
||||
* @since Log 1.7.0
|
||||
*/
|
||||
function alert($message)
|
||||
{
|
||||
return $this->log($message, PEAR_LOG_ALERT);
|
||||
}
|
||||
|
||||
/**
|
||||
* A convenience function for logging a critical event. It will log a
|
||||
* message at the PEAR_LOG_CRIT log level.
|
||||
*
|
||||
* @param mixed $message String or object containing the message
|
||||
* to log.
|
||||
*
|
||||
* @return boolean True if the message was successfully logged.
|
||||
*
|
||||
* @access public
|
||||
* @since Log 1.7.0
|
||||
*/
|
||||
function crit($message)
|
||||
{
|
||||
return $this->log($message, PEAR_LOG_CRIT);
|
||||
}
|
||||
|
||||
/**
|
||||
* A convenience function for logging a error event. It will log a
|
||||
* message at the PEAR_LOG_ERR log level.
|
||||
*
|
||||
* @param mixed $message String or object containing the message
|
||||
* to log.
|
||||
*
|
||||
* @return boolean True if the message was successfully logged.
|
||||
*
|
||||
* @access public
|
||||
* @since Log 1.7.0
|
||||
*/
|
||||
function err($message)
|
||||
{
|
||||
return $this->log($message, PEAR_LOG_ERR);
|
||||
}
|
||||
|
||||
/**
|
||||
* A convenience function for logging a warning event. It will log a
|
||||
* message at the PEAR_LOG_WARNING log level.
|
||||
*
|
||||
* @param mixed $message String or object containing the message
|
||||
* to log.
|
||||
*
|
||||
* @return boolean True if the message was successfully logged.
|
||||
*
|
||||
* @access public
|
||||
* @since Log 1.7.0
|
||||
*/
|
||||
function warning($message)
|
||||
{
|
||||
return $this->log($message, PEAR_LOG_WARNING);
|
||||
}
|
||||
|
||||
/**
|
||||
* A convenience function for logging a notice event. It will log a
|
||||
* message at the PEAR_LOG_NOTICE log level.
|
||||
*
|
||||
* @param mixed $message String or object containing the message
|
||||
* to log.
|
||||
*
|
||||
* @return boolean True if the message was successfully logged.
|
||||
*
|
||||
* @access public
|
||||
* @since Log 1.7.0
|
||||
*/
|
||||
function notice($message)
|
||||
{
|
||||
return $this->log($message, PEAR_LOG_NOTICE);
|
||||
}
|
||||
|
||||
/**
|
||||
* A convenience function for logging a information event. It will log a
|
||||
* message at the PEAR_LOG_INFO log level.
|
||||
*
|
||||
* @param mixed $message String or object containing the message
|
||||
* to log.
|
||||
*
|
||||
* @return boolean True if the message was successfully logged.
|
||||
*
|
||||
* @access public
|
||||
* @since Log 1.7.0
|
||||
*/
|
||||
function info($message)
|
||||
{
|
||||
return $this->log($message, PEAR_LOG_INFO);
|
||||
}
|
||||
|
||||
/**
|
||||
* A convenience function for logging a debug event. It will log a
|
||||
* message at the PEAR_LOG_DEBUG log level.
|
||||
*
|
||||
* @param mixed $message String or object containing the message
|
||||
* to log.
|
||||
*
|
||||
* @return boolean True if the message was successfully logged.
|
||||
*
|
||||
* @access public
|
||||
* @since Log 1.7.0
|
||||
*/
|
||||
function debug($message)
|
||||
{
|
||||
return $this->log($message, PEAR_LOG_DEBUG);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the string representation of the message data.
|
||||
*
|
||||
* If $message is an object, _extractMessage() will attempt to extract
|
||||
* the message text using a known method (such as a PEAR_Error object's
|
||||
* getMessage() method). If a known method, cannot be found, the
|
||||
* serialized representation of the object will be returned.
|
||||
*
|
||||
* If the message data is already a string, it will be returned unchanged.
|
||||
*
|
||||
* @param mixed $message The original message data. This may be a
|
||||
* string or any object.
|
||||
*
|
||||
* @return string The string representation of the message.
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
function _extractMessage($message)
|
||||
{
|
||||
/*
|
||||
* If we've been given an object, attempt to extract the message using
|
||||
* a known method. If we can't find such a method, default to the
|
||||
* "human-readable" version of the object.
|
||||
*
|
||||
* We also use the human-readable format for arrays.
|
||||
*/
|
||||
if (is_object($message)) {
|
||||
if (method_exists($message, 'getmessage')) {
|
||||
$message = $message->getMessage();
|
||||
} else if (method_exists($message, 'tostring')) {
|
||||
$message = $message->toString();
|
||||
} else if (method_exists($message, '__tostring')) {
|
||||
if (version_compare(PHP_VERSION, '5.0.0', 'ge')) {
|
||||
$message = (string)$message;
|
||||
} else {
|
||||
$message = $message->__toString();
|
||||
}
|
||||
} else {
|
||||
$message = print_r($message, true);
|
||||
}
|
||||
} else if (is_array($message)) {
|
||||
if (isset($message['message'])) {
|
||||
$message = $message['message'];
|
||||
} else {
|
||||
$message = print_r($message, true);
|
||||
}
|
||||
}
|
||||
|
||||
/* Otherwise, we assume the message is a string. */
|
||||
return $message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Using debug_backtrace(), returns the file, line, and enclosing function
|
||||
* name of the source code context from which log() was invoked.
|
||||
*
|
||||
* @param int $depth The initial number of frames we should step
|
||||
* back into the trace.
|
||||
*
|
||||
* @return array Array containing three strings: the filename, the line,
|
||||
* and the function name from which log() was called.
|
||||
*
|
||||
* @access private
|
||||
* @since Log 1.9.4
|
||||
*/
|
||||
function _getBacktraceVars($depth)
|
||||
{
|
||||
/* Start by generating a backtrace from the current call (here). */
|
||||
$backtrace = debug_backtrace();
|
||||
|
||||
/*
|
||||
* If we were ultimately invoked by the composite handler, we need to
|
||||
* increase our depth one additional level to compensate.
|
||||
*/
|
||||
if (strcasecmp(@$backtrace[$depth+1]['class'], 'Log_composite') == 0) {
|
||||
$depth++;
|
||||
}
|
||||
|
||||
/*
|
||||
* We're interested in the frame which invoked the log() function, so
|
||||
* we need to walk back some number of frames into the backtrace. The
|
||||
* $depth parameter tells us where to start looking. We go one step
|
||||
* further back to find the name of the encapsulating function from
|
||||
* which log() was called.
|
||||
*/
|
||||
$file = @$backtrace[$depth]['file'];
|
||||
$line = @$backtrace[$depth]['line'];
|
||||
$func = @$backtrace[$depth + 1]['function'];
|
||||
|
||||
/*
|
||||
* However, if log() was called from one of our "shortcut" functions,
|
||||
* we're going to need to go back an additional step.
|
||||
*/
|
||||
if (in_array($func, array('emerg', 'alert', 'crit', 'err', 'warning',
|
||||
'notice', 'info', 'debug'))) {
|
||||
$file = @$backtrace[$depth + 1]['file'];
|
||||
$line = @$backtrace[$depth + 1]['line'];
|
||||
$func = @$backtrace[$depth + 2]['function'];
|
||||
}
|
||||
|
||||
/*
|
||||
* If we couldn't extract a function name (perhaps because we were
|
||||
* executed from the "main" context), provide a default value.
|
||||
*/
|
||||
if (is_null($func)) {
|
||||
$func = '(none)';
|
||||
}
|
||||
|
||||
/* Return a 3-tuple containing (file, line, function). */
|
||||
return array($file, $line, $func);
|
||||
}
|
||||
|
||||
/**
|
||||
* Produces a formatted log line based on a format string and a set of
|
||||
* variables representing the current log record and state.
|
||||
*
|
||||
* @return string Formatted log string.
|
||||
*
|
||||
* @access private
|
||||
* @since Log 1.9.4
|
||||
*/
|
||||
function _format($format, $timestamp, $priority, $message)
|
||||
{
|
||||
/*
|
||||
* If the format string references any of the backtrace-driven
|
||||
* variables (%5, %6, %7), generate the backtrace and fetch them.
|
||||
*/
|
||||
if (strpos($format, '%5') || strpos($format, '%6') || strpos($format, '%7')) {
|
||||
list($file, $line, $func) = $this->_getBacktraceVars(2);
|
||||
}
|
||||
|
||||
/*
|
||||
* Build the formatted string. We use the sprintf() function's
|
||||
* "argument swapping" capability to dynamically select and position
|
||||
* the variables which will ultimately appear in the log string.
|
||||
*/
|
||||
return sprintf($format,
|
||||
$timestamp,
|
||||
$this->_ident,
|
||||
$this->priorityToString($priority),
|
||||
$message,
|
||||
isset($file) ? $file : '',
|
||||
isset($line) ? $line : '',
|
||||
isset($func) ? $func : '');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the string representation of a PEAR_LOG_* integer constant.
|
||||
*
|
||||
* @param int $priority A PEAR_LOG_* integer constant.
|
||||
*
|
||||
* @return string The string representation of $level.
|
||||
*
|
||||
* @since Log 1.0
|
||||
*/
|
||||
function priorityToString($priority)
|
||||
{
|
||||
$levels = array(
|
||||
PEAR_LOG_EMERG => 'emergency',
|
||||
PEAR_LOG_ALERT => 'alert',
|
||||
PEAR_LOG_CRIT => 'critical',
|
||||
PEAR_LOG_ERR => 'error',
|
||||
PEAR_LOG_WARNING => 'warning',
|
||||
PEAR_LOG_NOTICE => 'notice',
|
||||
PEAR_LOG_INFO => 'info',
|
||||
PEAR_LOG_DEBUG => 'debug'
|
||||
);
|
||||
|
||||
return $levels[$priority];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the the PEAR_LOG_* integer constant for the given string
|
||||
* representation of a priority name. This function performs a
|
||||
* case-insensitive search.
|
||||
*
|
||||
* @param string $name String containing a priority name.
|
||||
*
|
||||
* @return string The PEAR_LOG_* integer contstant corresponding
|
||||
* the the specified priority name.
|
||||
*
|
||||
* @since Log 1.9.0
|
||||
*/
|
||||
function stringToPriority($name)
|
||||
{
|
||||
$levels = array(
|
||||
'emergency' => PEAR_LOG_EMERG,
|
||||
'alert' => PEAR_LOG_ALERT,
|
||||
'critical' => PEAR_LOG_CRIT,
|
||||
'error' => PEAR_LOG_ERR,
|
||||
'warning' => PEAR_LOG_WARNING,
|
||||
'notice' => PEAR_LOG_NOTICE,
|
||||
'info' => PEAR_LOG_INFO,
|
||||
'debug' => PEAR_LOG_DEBUG
|
||||
);
|
||||
|
||||
return $levels[strtolower($name)];
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the log mask for the given priority.
|
||||
*
|
||||
* This method may be called statically.
|
||||
*
|
||||
* @param integer $priority The priority whose mask will be calculated.
|
||||
*
|
||||
* @return integer The calculated log mask.
|
||||
*
|
||||
* @access public
|
||||
* @since Log 1.7.0
|
||||
*/
|
||||
function MASK($priority)
|
||||
{
|
||||
return (1 << $priority);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the log mask for all priorities up to the given priority.
|
||||
*
|
||||
* This method may be called statically.
|
||||
*
|
||||
* @param integer $priority The maximum priority covered by this mask.
|
||||
*
|
||||
* @return integer The resulting log mask.
|
||||
*
|
||||
* @access public
|
||||
* @since Log 1.7.0
|
||||
*
|
||||
* @deprecated deprecated since Log 1.9.4; use Log::MAX() instead
|
||||
*/
|
||||
function UPTO($priority)
|
||||
{
|
||||
return Log::MAX($priority);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the log mask for all priorities greater than or equal to the
|
||||
* given priority. In other words, $priority will be the lowest priority
|
||||
* matched by the resulting mask.
|
||||
*
|
||||
* This method may be called statically.
|
||||
*
|
||||
* @param integer $priority The minimum priority covered by this mask.
|
||||
*
|
||||
* @return integer The resulting log mask.
|
||||
*
|
||||
* @access public
|
||||
* @since Log 1.9.4
|
||||
*/
|
||||
function MIN($priority)
|
||||
{
|
||||
return PEAR_LOG_ALL ^ ((1 << $priority) - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the log mask for all priorities less than or equal to the
|
||||
* given priority. In other words, $priority will be the highests priority
|
||||
* matched by the resulting mask.
|
||||
*
|
||||
* This method may be called statically.
|
||||
*
|
||||
* @param integer $priority The maximum priority covered by this mask.
|
||||
*
|
||||
* @return integer The resulting log mask.
|
||||
*
|
||||
* @access public
|
||||
* @since Log 1.9.4
|
||||
*/
|
||||
function MAX($priority)
|
||||
{
|
||||
return ((1 << ($priority + 1)) - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set and return the level mask for the current Log instance.
|
||||
*
|
||||
* @param integer $mask A bitwise mask of log levels.
|
||||
*
|
||||
* @return integer The current level mask.
|
||||
*
|
||||
* @access public
|
||||
* @since Log 1.7.0
|
||||
*/
|
||||
function setMask($mask)
|
||||
{
|
||||
$this->_mask = $mask;
|
||||
|
||||
return $this->_mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current level mask.
|
||||
*
|
||||
* @return interger The current level mask.
|
||||
*
|
||||
* @access public
|
||||
* @since Log 1.7.0
|
||||
*/
|
||||
function getMask()
|
||||
{
|
||||
return $this->_mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the given priority is included in the current level mask.
|
||||
*
|
||||
* @param integer $priority The priority to check.
|
||||
*
|
||||
* @return boolean True if the given priority is included in the current
|
||||
* log mask.
|
||||
*
|
||||
* @access private
|
||||
* @since Log 1.7.0
|
||||
*/
|
||||
function _isMasked($priority)
|
||||
{
|
||||
return (Log::MASK($priority) & $this->_mask);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current default priority.
|
||||
*
|
||||
* @return integer The current default priority.
|
||||
*
|
||||
* @access public
|
||||
* @since Log 1.8.4
|
||||
*/
|
||||
function getPriority()
|
||||
{
|
||||
return $this->_priority;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the default priority to the specified value.
|
||||
*
|
||||
* @param integer $priority The new default priority.
|
||||
*
|
||||
* @access public
|
||||
* @since Log 1.8.4
|
||||
*/
|
||||
function setPriority($priority)
|
||||
{
|
||||
$this->_priority = $priority;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a Log_observer instance to the list of observers that are listening
|
||||
* for messages emitted by this Log instance.
|
||||
*
|
||||
* @param object $observer The Log_observer instance to attach as a
|
||||
* listener.
|
||||
*
|
||||
* @param boolean True if the observer is successfully attached.
|
||||
*
|
||||
* @access public
|
||||
* @since Log 1.0
|
||||
*/
|
||||
function attach(&$observer)
|
||||
{
|
||||
if (!is_a($observer, 'Log_observer')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->_listeners[$observer->_id] = &$observer;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a Log_observer instance from the list of observers.
|
||||
*
|
||||
* @param object $observer The Log_observer instance to detach from
|
||||
* the list of listeners.
|
||||
*
|
||||
* @param boolean True if the observer is successfully detached.
|
||||
*
|
||||
* @access public
|
||||
* @since Log 1.0
|
||||
*/
|
||||
function detach($observer)
|
||||
{
|
||||
if (!is_a($observer, 'Log_observer') ||
|
||||
!isset($this->_listeners[$observer->_id])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
unset($this->_listeners[$observer->_id]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Informs each registered observer instance that a new message has been
|
||||
* logged.
|
||||
*
|
||||
* @param array $event A hash describing the log event.
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
function _announce($event)
|
||||
{
|
||||
foreach ($this->_listeners as $id => $listener) {
|
||||
if ($event['priority'] <= $this->_listeners[$id]->_priority) {
|
||||
$this->_listeners[$id]->notify($event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether this is a composite class.
|
||||
*
|
||||
* @return boolean True if this is a composite class.
|
||||
*
|
||||
* @access public
|
||||
* @since Log 1.0
|
||||
*/
|
||||
function isComposite()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets this Log instance's identification string.
|
||||
*
|
||||
* @param string $ident The new identification string.
|
||||
*
|
||||
* @access public
|
||||
* @since Log 1.6.3
|
||||
*/
|
||||
function setIdent($ident)
|
||||
{
|
||||
$this->_ident = $ident;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current identification string.
|
||||
*
|
||||
* @return string The current Log instance's identification string.
|
||||
*
|
||||
* @access public
|
||||
* @since Log 1.6.3
|
||||
*/
|
||||
function getIdent()
|
||||
{
|
||||
return $this->_ident;
|
||||
}
|
||||
}
|
231
egw-pear/Log/composite.php
Normal file
231
egw-pear/Log/composite.php
Normal file
@ -0,0 +1,231 @@
|
||||
<?php
|
||||
/**
|
||||
* $Header: /repository/pear/Log/Log/composite.php,v 1.28 2006/06/29 07:12:34 jon Exp $
|
||||
* $Horde: horde/lib/Log/composite.php,v 1.2 2000/06/28 21:36:13 jon Exp $
|
||||
*
|
||||
* @version $Revision: 1.28 $
|
||||
* @package Log
|
||||
*/
|
||||
|
||||
/**
|
||||
* The Log_composite:: class implements a Composite pattern which
|
||||
* allows multiple Log implementations to receive the same events.
|
||||
*
|
||||
* @author Chuck Hagenbuch <chuck@horde.org>
|
||||
* @author Jon Parise <jon@php.net>
|
||||
*
|
||||
* @since Horde 1.3
|
||||
* @since Log 1.0
|
||||
* @package Log
|
||||
*
|
||||
* @example composite.php Using the composite handler.
|
||||
*/
|
||||
class Log_composite extends Log
|
||||
{
|
||||
/**
|
||||
* Array holding all of the Log instances to which log events should be
|
||||
* sent.
|
||||
*
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $_children = array();
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a new composite Log object.
|
||||
*
|
||||
* @param boolean $name This parameter is ignored.
|
||||
* @param boolean $ident This parameter is ignored.
|
||||
* @param boolean $conf This parameter is ignored.
|
||||
* @param boolean $level This parameter is ignored.
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function Log_composite($name, $ident = '', $conf = array(),
|
||||
$level = PEAR_LOG_DEBUG)
|
||||
{
|
||||
$this->_ident = $ident;
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens all of the child instances.
|
||||
*
|
||||
* @return True if all of the child instances were successfully opened.
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function open()
|
||||
{
|
||||
/* Attempt to open each of our children. */
|
||||
$this->_opened = true;
|
||||
foreach ($this->_children as $id => $child) {
|
||||
$this->_opened &= $this->_children[$id]->open();
|
||||
}
|
||||
|
||||
/* If all children were opened, return success. */
|
||||
return $this->_opened;
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes all of the child instances.
|
||||
*
|
||||
* @return True if all of the child instances were successfully closed.
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function close()
|
||||
{
|
||||
/* Attempt to close each of our children. */
|
||||
$closed = true;
|
||||
foreach ($this->_children as $id => $child) {
|
||||
$closed &= $this->_children[$id]->close();
|
||||
}
|
||||
|
||||
/* Track the _opened state for consistency. */
|
||||
$this->_opened = false;
|
||||
|
||||
/* If all children were closed, return success. */
|
||||
return $closed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Flushes all child instances. It is assumed that all of the children
|
||||
* have been successfully opened.
|
||||
*
|
||||
* @return True if all of the child instances were successfully flushed.
|
||||
*
|
||||
* @access public
|
||||
* @since Log 1.8.2
|
||||
*/
|
||||
function flush()
|
||||
{
|
||||
/* Attempt to flush each of our children. */
|
||||
$flushed = true;
|
||||
foreach ($this->_children as $id => $child) {
|
||||
$flushed &= $this->_children[$id]->flush();
|
||||
}
|
||||
|
||||
/* If all children were flushed, return success. */
|
||||
return $flushed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends $message and $priority to each child of this composite. If the
|
||||
* children aren't already open, they will be opened here.
|
||||
*
|
||||
* @param mixed $message String or object containing the message
|
||||
* to log.
|
||||
* @param string $priority (optional) The priority of the message.
|
||||
* Valid values are: PEAR_LOG_EMERG,
|
||||
* PEAR_LOG_ALERT, PEAR_LOG_CRIT,
|
||||
* PEAR_LOG_ERR, PEAR_LOG_WARNING,
|
||||
* PEAR_LOG_NOTICE, PEAR_LOG_INFO, and
|
||||
* PEAR_LOG_DEBUG.
|
||||
*
|
||||
* @return boolean True if the entry is successfully logged.
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function log($message, $priority = null)
|
||||
{
|
||||
/* If a priority hasn't been specified, use the default value. */
|
||||
if ($priority === null) {
|
||||
$priority = $this->_priority;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the handlers haven't been opened, attempt to open them now.
|
||||
* However, we don't treat failure to open all of the handlers as a
|
||||
* fatal error. We defer that consideration to the success of calling
|
||||
* each handler's log() method below.
|
||||
*/
|
||||
if (!$this->_opened) {
|
||||
$this->open();
|
||||
}
|
||||
|
||||
/* Attempt to log the event using each of the children. */
|
||||
$success = true;
|
||||
foreach ($this->_children as $id => $child) {
|
||||
$success &= $this->_children[$id]->log($message, $priority);
|
||||
}
|
||||
|
||||
$this->_announce(array('priority' => $priority, 'message' => $message));
|
||||
|
||||
/* Return success if all of the children logged the event. */
|
||||
return $success;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this is a composite.
|
||||
*
|
||||
* @return boolean True if this is a composite class.
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function isComposite()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets this identification string for all of this composite's children.
|
||||
*
|
||||
* @param string $ident The new identification string.
|
||||
*
|
||||
* @access public
|
||||
* @since Log 1.6.7
|
||||
*/
|
||||
function setIdent($ident)
|
||||
{
|
||||
/* Call our base class's setIdent() method. */
|
||||
parent::setIdent($ident);
|
||||
|
||||
/* ... and then call setIdent() on all of our children. */
|
||||
foreach ($this->_children as $id => $child) {
|
||||
$this->_children[$id]->setIdent($ident);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a Log instance to the list of children.
|
||||
*
|
||||
* @param object $child The Log instance to add.
|
||||
*
|
||||
* @return boolean True if the Log instance was successfully added.
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function addChild(&$child)
|
||||
{
|
||||
/* Make sure this is a Log instance. */
|
||||
if (!is_a($child, 'Log')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->_children[$child->_id] = &$child;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a Log instance from the list of children.
|
||||
*
|
||||
* @param object $child The Log instance to remove.
|
||||
*
|
||||
* @return boolean True if the Log instance was successfully removed.
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function removeChild($child)
|
||||
{
|
||||
if (!is_a($child, 'Log') || !isset($this->_children[$child->_id])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
unset($this->_children[$child->_id]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
204
egw-pear/Log/console.php
Normal file
204
egw-pear/Log/console.php
Normal file
@ -0,0 +1,204 @@
|
||||
<?php
|
||||
/**
|
||||
* $Header: /repository/pear/Log/Log/console.php,v 1.23 2006/06/29 07:09:21 jon Exp $
|
||||
*
|
||||
* @version $Revision: 1.23 $
|
||||
* @package Log
|
||||
*/
|
||||
|
||||
/**
|
||||
* The Log_console class is a concrete implementation of the Log::
|
||||
* abstract class which writes message to the text console.
|
||||
*
|
||||
* @author Jon Parise <jon@php.net>
|
||||
* @since Log 1.1
|
||||
* @package Log
|
||||
*
|
||||
* @example console.php Using the console handler.
|
||||
*/
|
||||
class Log_console extends Log
|
||||
{
|
||||
/**
|
||||
* Handle to the current output stream.
|
||||
* @var resource
|
||||
* @access private
|
||||
*/
|
||||
var $_stream = STDOUT;
|
||||
|
||||
/**
|
||||
* Should the output be buffered or displayed immediately?
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $_buffering = false;
|
||||
|
||||
/**
|
||||
* String holding the buffered output.
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $_buffer = '';
|
||||
|
||||
/**
|
||||
* String containing the format of a log line.
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $_lineFormat = '%1$s %2$s [%3$s] %4$s';
|
||||
|
||||
/**
|
||||
* String containing the timestamp format. It will be passed directly to
|
||||
* strftime(). Note that the timestamp string will generated using the
|
||||
* current locale.
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $_timeFormat = '%b %d %H:%M:%S';
|
||||
|
||||
/**
|
||||
* Constructs a new Log_console object.
|
||||
*
|
||||
* @param string $name Ignored.
|
||||
* @param string $ident The identity string.
|
||||
* @param array $conf The configuration array.
|
||||
* @param int $level Log messages up to and including this level.
|
||||
* @access public
|
||||
*/
|
||||
function Log_console($name, $ident = '', $conf = array(),
|
||||
$level = PEAR_LOG_DEBUG)
|
||||
{
|
||||
$this->_id = md5(microtime());
|
||||
$this->_ident = $ident;
|
||||
$this->_mask = Log::UPTO($level);
|
||||
|
||||
if (!empty($conf['stream'])) {
|
||||
$this->_stream = $conf['stream'];
|
||||
}
|
||||
|
||||
if (isset($conf['buffering'])) {
|
||||
$this->_buffering = $conf['buffering'];
|
||||
}
|
||||
|
||||
if (!empty($conf['lineFormat'])) {
|
||||
$this->_lineFormat = str_replace(array_keys($this->_formatMap),
|
||||
array_values($this->_formatMap),
|
||||
$conf['lineFormat']);
|
||||
}
|
||||
|
||||
if (!empty($conf['timeFormat'])) {
|
||||
$this->_timeFormat = $conf['timeFormat'];
|
||||
}
|
||||
|
||||
/*
|
||||
* If output buffering has been requested, we need to register a
|
||||
* shutdown function that will dump the buffer upon termination.
|
||||
*/
|
||||
if ($this->_buffering) {
|
||||
register_shutdown_function(array(&$this, '_Log_console'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
function _Log_console()
|
||||
{
|
||||
$this->close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Open the output stream.
|
||||
*
|
||||
* @access public
|
||||
* @since Log 1.9.7
|
||||
*/
|
||||
function open()
|
||||
{
|
||||
$this->_opened = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the output stream.
|
||||
*
|
||||
* This results in a call to flush().
|
||||
*
|
||||
* @access public
|
||||
* @since Log 1.9.0
|
||||
*/
|
||||
function close()
|
||||
{
|
||||
$this->flush();
|
||||
$this->_opened = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Flushes all pending ("buffered") data to the output stream.
|
||||
*
|
||||
* @access public
|
||||
* @since Log 1.8.2
|
||||
*/
|
||||
function flush()
|
||||
{
|
||||
/*
|
||||
* If output buffering is enabled, dump the contents of the buffer to
|
||||
* the output stream.
|
||||
*/
|
||||
if ($this->_buffering && (strlen($this->_buffer) > 0)) {
|
||||
fwrite($this->_stream, $this->_buffer);
|
||||
$this->_buffer = '';
|
||||
}
|
||||
|
||||
return fflush($this->_stream);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes $message to the text console. Also, passes the message
|
||||
* along to any Log_observer instances that are observing this Log.
|
||||
*
|
||||
* @param mixed $message String or object containing the message to log.
|
||||
* @param string $priority The priority of the message. Valid
|
||||
* values are: PEAR_LOG_EMERG, PEAR_LOG_ALERT,
|
||||
* PEAR_LOG_CRIT, PEAR_LOG_ERR, PEAR_LOG_WARNING,
|
||||
* PEAR_LOG_NOTICE, PEAR_LOG_INFO, and PEAR_LOG_DEBUG.
|
||||
* @return boolean True on success or false on failure.
|
||||
* @access public
|
||||
*/
|
||||
function log($message, $priority = null)
|
||||
{
|
||||
/* If a priority hasn't been specified, use the default value. */
|
||||
if ($priority === null) {
|
||||
$priority = $this->_priority;
|
||||
}
|
||||
|
||||
/* Abort early if the priority is above the maximum logging level. */
|
||||
if (!$this->_isMasked($priority)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Extract the string representation of the message. */
|
||||
$message = $this->_extractMessage($message);
|
||||
|
||||
/* Build the string containing the complete log line. */
|
||||
$line = $this->_format($this->_lineFormat,
|
||||
strftime($this->_timeFormat),
|
||||
$priority, $message) . "\n";
|
||||
|
||||
/*
|
||||
* If buffering is enabled, append this line to the output buffer.
|
||||
* Otherwise, print the line to the output stream immediately.
|
||||
*/
|
||||
if ($this->_buffering) {
|
||||
$this->_buffer .= $line;
|
||||
} else {
|
||||
fwrite($this->_stream, $line);
|
||||
}
|
||||
|
||||
/* Notify observers about this log message. */
|
||||
$this->_announce(array('priority' => $priority, 'message' => $message));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
230
egw-pear/Log/daemon.php
Normal file
230
egw-pear/Log/daemon.php
Normal file
@ -0,0 +1,230 @@
|
||||
<?php
|
||||
// $Id: daemon.php,v 1.2 2005/02/26 14:48:58 chagenbu Exp $
|
||||
|
||||
/**
|
||||
* The Log_daemon class is a concrete implementation of the Log::
|
||||
* abstract class which sends messages to syslog daemon on UNIX-like machines.
|
||||
* This class uses the syslog protocol: http://www.ietf.org/rfc/rfc3164.txt
|
||||
*
|
||||
* @author Bart van der Schans <schans@dds.nl>
|
||||
* @version $Revision: 1.2 $
|
||||
* @package Log
|
||||
*/
|
||||
class Log_daemon extends Log
|
||||
{
|
||||
/**
|
||||
* Integer holding the log facility to use.
|
||||
* @var string
|
||||
*/
|
||||
var $_name = LOG_DAEMON;
|
||||
|
||||
/**
|
||||
* Var holding the resource pointer to the socket
|
||||
* @var resource
|
||||
*/
|
||||
var $_socket;
|
||||
|
||||
/**
|
||||
* The ip address or servername
|
||||
* @see http://www.php.net/manual/en/transports.php
|
||||
* @var string
|
||||
*/
|
||||
var $_ip = '127.0.0.1';
|
||||
|
||||
/**
|
||||
* Protocol to use (tcp, udp, etc.)
|
||||
* @see http://www.php.net/manual/en/transports.php
|
||||
* @var string
|
||||
*/
|
||||
var $_proto = 'udp';
|
||||
|
||||
/**
|
||||
* Port to connect to
|
||||
* @var int
|
||||
*/
|
||||
var $_port = 514;
|
||||
|
||||
/**
|
||||
* Maximum message length in bytes
|
||||
* @var int
|
||||
*/
|
||||
var $_maxsize = 4096;
|
||||
|
||||
/**
|
||||
* Socket timeout in seconds
|
||||
* @var int
|
||||
*/
|
||||
var $_timeout = 1;
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a new syslog object.
|
||||
*
|
||||
* @param string $name The syslog facility.
|
||||
* @param string $ident The identity string.
|
||||
* @param array $conf The configuration array.
|
||||
* @param int $maxLevel Maximum level at which to log.
|
||||
* @access public
|
||||
*/
|
||||
function Log_daemon($name, $ident = '', $conf = array(),
|
||||
$level = PEAR_LOG_DEBUG)
|
||||
{
|
||||
/* Ensure we have a valid integer value for $name. */
|
||||
if (empty($name) || !is_int($name)) {
|
||||
$name = LOG_SYSLOG;
|
||||
}
|
||||
|
||||
$this->_id = md5(microtime());
|
||||
$this->_name = $name;
|
||||
$this->_ident = $ident;
|
||||
$this->_mask = Log::UPTO($level);
|
||||
|
||||
if (isset($conf['ip'])) {
|
||||
$this->_ip = $conf['ip'];
|
||||
}
|
||||
if (isset($conf['proto'])) {
|
||||
$this->_proto = $conf['proto'];
|
||||
}
|
||||
if (isset($conf['port'])) {
|
||||
$this->_port = $conf['port'];
|
||||
}
|
||||
if (isset($conf['maxsize'])) {
|
||||
$this->_maxsize = $conf['maxsize'];
|
||||
}
|
||||
if (isset($conf['timeout'])) {
|
||||
$this->_timeout = $conf['timeout'];
|
||||
}
|
||||
$this->_proto = $this->_proto . '://';
|
||||
|
||||
register_shutdown_function(array(&$this, '_Log_daemon'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
function _Log_daemon()
|
||||
{
|
||||
$this->close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens a connection to the system logger, if it has not already
|
||||
* been opened. This is implicitly called by log(), if necessary.
|
||||
* @access public
|
||||
*/
|
||||
function open()
|
||||
{
|
||||
if (!$this->_opened) {
|
||||
$this->_opened = (bool)($this->_socket = @fsockopen(
|
||||
$this->_proto . $this->_ip,
|
||||
$this->_port,
|
||||
$errno,
|
||||
$errstr,
|
||||
$this->_timeout));
|
||||
}
|
||||
return $this->_opened;
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the connection to the system logger, if it is open.
|
||||
* @access public
|
||||
*/
|
||||
function close()
|
||||
{
|
||||
if ($this->_opened) {
|
||||
$this->_opened = false;
|
||||
return fclose($this->_socket);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends $message to the currently open syslog connection. Calls
|
||||
* open() if necessary. Also passes the message along to any Log_observer
|
||||
* instances that are observing this Log.
|
||||
*
|
||||
* @param string $message The textual message to be logged.
|
||||
* @param int $priority (optional) The priority of the message. Valid
|
||||
* values are: LOG_EMERG, LOG_ALERT, LOG_CRIT,
|
||||
* LOG_ERR, LOG_WARNING, LOG_NOTICE, LOG_INFO,
|
||||
* and LOG_DEBUG. The default is LOG_INFO.
|
||||
* @access public
|
||||
*/
|
||||
function log($message, $priority = null)
|
||||
{
|
||||
/* If a priority hasn't been specified, use the default value. */
|
||||
if ($priority === null) {
|
||||
$priority = $this->_priority;
|
||||
}
|
||||
|
||||
/* Abort early if the priority is above the maximum logging level. */
|
||||
if (!$this->_isMasked($priority)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* If the connection isn't open and can't be opened, return failure. */
|
||||
if (!$this->_opened && !$this->open()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Extract the string representation of the message. */
|
||||
$message = $this->_extractMessage($message);
|
||||
|
||||
/* Set the facility level. */
|
||||
$facility_level = intval($this->_name) +
|
||||
intval($this->_toSyslog($priority));
|
||||
|
||||
/* Prepend ident info. */
|
||||
if (!empty($this->_ident)) {
|
||||
$message = $this->_ident . ' ' . $message;
|
||||
}
|
||||
|
||||
/* Check for message length. */
|
||||
if (strlen($message) > $this->_maxsize) {
|
||||
$message = substr($message, 0, ($this->_maxsize) - 10) . ' [...]';
|
||||
}
|
||||
|
||||
/* Write to socket. */
|
||||
fwrite($this->_socket, '<' . $facility_level . '>' . $message . "\n");
|
||||
|
||||
$this->_announce(array('priority' => $priority, 'message' => $message));
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a PEAR_LOG_* constant into a syslog LOG_* constant.
|
||||
*
|
||||
* This function exists because, under Windows, not all of the LOG_*
|
||||
* constants have unique values. Instead, the PEAR_LOG_* were introduced
|
||||
* for global use, with the conversion to the LOG_* constants kept local to
|
||||
* to the syslog driver.
|
||||
*
|
||||
* @param int $priority PEAR_LOG_* value to convert to LOG_* value.
|
||||
*
|
||||
* @return The LOG_* representation of $priority.
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
function _toSyslog($priority)
|
||||
{
|
||||
static $priorities = array(
|
||||
PEAR_LOG_EMERG => LOG_EMERG,
|
||||
PEAR_LOG_ALERT => LOG_ALERT,
|
||||
PEAR_LOG_CRIT => LOG_CRIT,
|
||||
PEAR_LOG_ERR => LOG_ERR,
|
||||
PEAR_LOG_WARNING => LOG_WARNING,
|
||||
PEAR_LOG_NOTICE => LOG_NOTICE,
|
||||
PEAR_LOG_INFO => LOG_INFO,
|
||||
PEAR_LOG_DEBUG => LOG_DEBUG
|
||||
);
|
||||
|
||||
/* If we're passed an unknown priority, default to LOG_INFO. */
|
||||
if (!is_int($priority) || !in_array($priority, $priorities)) {
|
||||
return LOG_INFO;
|
||||
}
|
||||
|
||||
return $priorities[$priority];
|
||||
}
|
||||
|
||||
}
|
141
egw-pear/Log/display.php
Normal file
141
egw-pear/Log/display.php
Normal file
@ -0,0 +1,141 @@
|
||||
<?php
|
||||
/**
|
||||
* $Header: /repository/pear/Log/Log/display.php,v 1.9 2006/06/29 07:09:21 jon Exp $
|
||||
*
|
||||
* @version $Revision: 1.9 $
|
||||
* @package Log
|
||||
*/
|
||||
|
||||
/**
|
||||
* The Log_display class is a concrete implementation of the Log::
|
||||
* abstract class which writes message into browser in usual PHP maner.
|
||||
* This may be useful because when you use PEAR::setErrorHandling in
|
||||
* PEAR_ERROR_CALLBACK mode error messages are not displayed by
|
||||
* PHP error handler.
|
||||
*
|
||||
* @author Paul Yanchenko <pusher@inaco.ru>
|
||||
* @since Log 1.8.0
|
||||
* @package Log
|
||||
*
|
||||
* @example display.php Using the display handler.
|
||||
*/
|
||||
class Log_display extends Log
|
||||
{
|
||||
/**
|
||||
* String to output before an error message
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $_error_prepend = '';
|
||||
|
||||
/**
|
||||
* String to output after an error message
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $_error_append = '';
|
||||
|
||||
/**
|
||||
* String used to represent a line break.
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $_linebreak = "<br />\n";
|
||||
|
||||
/**
|
||||
* Constructs a new Log_display object.
|
||||
*
|
||||
* @param string $name Ignored.
|
||||
* @param string $ident The identity string.
|
||||
* @param array $conf The configuration array.
|
||||
* @param int $level Log messages up to and including this level.
|
||||
* @access public
|
||||
*/
|
||||
function Log_display($name = '', $ident = '', $conf = array(),
|
||||
$level = PEAR_LOG_DEBUG)
|
||||
{
|
||||
$this->_id = md5(microtime());
|
||||
$this->_ident = $ident;
|
||||
$this->_mask = Log::UPTO($level);
|
||||
|
||||
if (isset($conf['error_prepend'])) {
|
||||
$this->_error_prepend = $conf['error_prepend'];
|
||||
} else {
|
||||
$this->_error_prepend = ini_get('error_prepend_string');
|
||||
}
|
||||
|
||||
if (isset($conf['error_append'])) {
|
||||
$this->_error_append = $conf['error_append'];
|
||||
} else {
|
||||
$this->_error_append = ini_get('error_append_string');
|
||||
}
|
||||
|
||||
if (isset($conf['linebreak'])) {
|
||||
$this->_linebreak = $conf['linebreak'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens the display handler.
|
||||
*
|
||||
* @access public
|
||||
* @since Log 1.9.6
|
||||
*/
|
||||
function open()
|
||||
{
|
||||
$this->_opened = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the display handler.
|
||||
*
|
||||
* @access public
|
||||
* @since Log 1.9.6
|
||||
*/
|
||||
function close()
|
||||
{
|
||||
$this->_opened = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes $message to the text browser. Also, passes the message
|
||||
* along to any Log_observer instances that are observing this Log.
|
||||
*
|
||||
* @param mixed $message String or object containing the message to log.
|
||||
* @param string $priority The priority of the message. Valid
|
||||
* values are: PEAR_LOG_EMERG, PEAR_LOG_ALERT,
|
||||
* PEAR_LOG_CRIT, PEAR_LOG_ERR, PEAR_LOG_WARNING,
|
||||
* PEAR_LOG_NOTICE, PEAR_LOG_INFO, and PEAR_LOG_DEBUG.
|
||||
* @return boolean True on success or false on failure.
|
||||
* @access public
|
||||
*/
|
||||
function log($message, $priority = null)
|
||||
{
|
||||
/* If a priority hasn't been specified, use the default value. */
|
||||
if ($priority === null) {
|
||||
$priority = $this->_priority;
|
||||
}
|
||||
|
||||
/* Abort early if the priority is above the maximum logging level. */
|
||||
if (!$this->_isMasked($priority)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Extract the string representation of the message. */
|
||||
$message = $this->_extractMessage($message);
|
||||
|
||||
/* Build and output the complete log line. */
|
||||
echo $this->_error_prepend .
|
||||
'<b>' . ucfirst($this->priorityToString($priority)) . '</b>: '.
|
||||
nl2br(htmlspecialchars($message)) .
|
||||
$this->_error_append . $this->_linebreak;
|
||||
|
||||
/* Notify observers about this log message. */
|
||||
$this->_announce(array('priority' => $priority, 'message' => $message));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
127
egw-pear/Log/error_log.php
Normal file
127
egw-pear/Log/error_log.php
Normal file
@ -0,0 +1,127 @@
|
||||
<?php
|
||||
/**
|
||||
* $Header: /repository/pear/Log/Log/error_log.php,v 1.8 2006/06/29 07:09:21 jon Exp $
|
||||
*
|
||||
* @version $Revision: 1.8 $
|
||||
* @package Log
|
||||
*/
|
||||
|
||||
/**
|
||||
* The Log_error_log class is a concrete implementation of the Log abstract
|
||||
* class that logs messages using PHP's error_log() function.
|
||||
*
|
||||
* @author Jon Parise <jon@php.net>
|
||||
* @since Log 1.7.0
|
||||
* @package Log
|
||||
*
|
||||
* @example error_log.php Using the error_log handler.
|
||||
*/
|
||||
class Log_error_log extends Log
|
||||
{
|
||||
/**
|
||||
* The error_log() log type.
|
||||
* @var integer
|
||||
* @access private
|
||||
*/
|
||||
var $_type = PEAR_LOG_TYPE_SYSTEM;
|
||||
|
||||
/**
|
||||
* The type-specific destination value.
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $_destination = '';
|
||||
|
||||
/**
|
||||
* Additional headers to pass to the mail() function when the
|
||||
* PEAR_LOG_TYPE_MAIL type is used.
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $_extra_headers = '';
|
||||
|
||||
/**
|
||||
* Constructs a new Log_error_log object.
|
||||
*
|
||||
* @param string $name Ignored.
|
||||
* @param string $ident The identity string.
|
||||
* @param array $conf The configuration array.
|
||||
* @param int $level Log messages up to and including this level.
|
||||
* @access public
|
||||
*/
|
||||
function Log_error_log($name, $ident = '', $conf = array(),
|
||||
$level = PEAR_LOG_DEBUG)
|
||||
{
|
||||
$this->_id = md5(microtime());
|
||||
$this->_type = $name;
|
||||
$this->_ident = $ident;
|
||||
$this->_mask = Log::UPTO($level);
|
||||
|
||||
if (!empty($conf['destination'])) {
|
||||
$this->_destination = $conf['destination'];
|
||||
}
|
||||
if (!empty($conf['extra_headers'])) {
|
||||
$this->_extra_headers = $conf['extra_headers'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens the handler.
|
||||
*
|
||||
* @access public
|
||||
* @since Log 1.9.6
|
||||
*/
|
||||
function open()
|
||||
{
|
||||
$this->_opened = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the handler.
|
||||
*
|
||||
* @access public
|
||||
* @since Log 1.9.6
|
||||
*/
|
||||
function close()
|
||||
{
|
||||
$this->_opened = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs $message using PHP's error_log() function. The message is also
|
||||
* passed along to any Log_observer instances that are observing this Log.
|
||||
*
|
||||
* @param mixed $message String or object containing the message to log.
|
||||
* @param string $priority The priority of the message. Valid
|
||||
* values are: PEAR_LOG_EMERG, PEAR_LOG_ALERT,
|
||||
* PEAR_LOG_CRIT, PEAR_LOG_ERR, PEAR_LOG_WARNING,
|
||||
* PEAR_LOG_NOTICE, PEAR_LOG_INFO, and PEAR_LOG_DEBUG.
|
||||
* @return boolean True on success or false on failure.
|
||||
* @access public
|
||||
*/
|
||||
function log($message, $priority = null)
|
||||
{
|
||||
/* If a priority hasn't been specified, use the default value. */
|
||||
if ($priority === null) {
|
||||
$priority = $this->_priority;
|
||||
}
|
||||
|
||||
/* Abort early if the priority is above the maximum logging level. */
|
||||
if (!$this->_isMasked($priority)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Extract the string representation of the message. */
|
||||
$message = $this->_extractMessage($message);
|
||||
|
||||
$success = error_log($this->_ident . ': ' . $message, $this->_type,
|
||||
$this->_destination, $this->_extra_headers);
|
||||
|
||||
$this->_announce(array('priority' => $priority, 'message' => $message));
|
||||
|
||||
return $success;
|
||||
}
|
||||
|
||||
}
|
312
egw-pear/Log/file.php
Normal file
312
egw-pear/Log/file.php
Normal file
@ -0,0 +1,312 @@
|
||||
<?php
|
||||
/**
|
||||
* $Header: /repository/pear/Log/Log/file.php,v 1.45 2006/01/11 07:56:37 jon Exp $
|
||||
*
|
||||
* @version $Revision: 1.45 $
|
||||
* @package Log
|
||||
*/
|
||||
|
||||
/**
|
||||
* The Log_file class is a concrete implementation of the Log abstract
|
||||
* class that logs messages to a text file.
|
||||
*
|
||||
* @author Jon Parise <jon@php.net>
|
||||
* @author Roman Neuhauser <neuhauser@bellavista.cz>
|
||||
* @since Log 1.0
|
||||
* @package Log
|
||||
*
|
||||
* @example file.php Using the file handler.
|
||||
*/
|
||||
class Log_file extends Log
|
||||
{
|
||||
/**
|
||||
* String containing the name of the log file.
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $_filename = 'php.log';
|
||||
|
||||
/**
|
||||
* Handle to the log file.
|
||||
* @var resource
|
||||
* @access private
|
||||
*/
|
||||
var $_fp = false;
|
||||
|
||||
/**
|
||||
* Should new log entries be append to an existing log file, or should the
|
||||
* a new log file overwrite an existing one?
|
||||
* @var boolean
|
||||
* @access private
|
||||
*/
|
||||
var $_append = true;
|
||||
|
||||
/**
|
||||
* Should advisory file locking (i.e., flock()) be used?
|
||||
* @var boolean
|
||||
* @access private
|
||||
*/
|
||||
var $_locking = false;
|
||||
|
||||
/**
|
||||
* Integer (in octal) containing the log file's permissions mode.
|
||||
* @var integer
|
||||
* @access private
|
||||
*/
|
||||
var $_mode = 0644;
|
||||
|
||||
/**
|
||||
* Integer (in octal) specifying the file permission mode that will be
|
||||
* used when creating directories that do not already exist.
|
||||
* @var integer
|
||||
* @access private
|
||||
*/
|
||||
var $_dirmode = 0755;
|
||||
|
||||
/**
|
||||
* String containing the format of a log line.
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $_lineFormat = '%1$s %2$s [%3$s] %4$s';
|
||||
|
||||
/**
|
||||
* String containing the timestamp format. It will be passed directly to
|
||||
* strftime(). Note that the timestamp string will generated using the
|
||||
* current locale.
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $_timeFormat = '%b %d %H:%M:%S';
|
||||
|
||||
/**
|
||||
* String containing the end-on-line character sequence.
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $_eol = "\n";
|
||||
|
||||
/**
|
||||
* Constructs a new Log_file object.
|
||||
*
|
||||
* @param string $name Ignored.
|
||||
* @param string $ident The identity string.
|
||||
* @param array $conf The configuration array.
|
||||
* @param int $level Log messages up to and including this level.
|
||||
* @access public
|
||||
*/
|
||||
function Log_file($name, $ident = '', $conf = array(),
|
||||
$level = PEAR_LOG_DEBUG)
|
||||
{
|
||||
$this->_id = md5(microtime());
|
||||
$this->_filename = $name;
|
||||
$this->_ident = $ident;
|
||||
$this->_mask = Log::UPTO($level);
|
||||
|
||||
if (isset($conf['append'])) {
|
||||
$this->_append = $conf['append'];
|
||||
}
|
||||
|
||||
if (isset($conf['locking'])) {
|
||||
$this->_locking = $conf['locking'];
|
||||
}
|
||||
|
||||
if (!empty($conf['mode'])) {
|
||||
if (is_string($conf['mode'])) {
|
||||
$this->_mode = octdec($conf['mode']);
|
||||
} else {
|
||||
$this->_mode = $conf['mode'];
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($conf['dirmode'])) {
|
||||
if (is_string($conf['dirmode'])) {
|
||||
$this->_dirmode = octdec($conf['dirmode']);
|
||||
} else {
|
||||
$this->_dirmode = $conf['dirmode'];
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($conf['lineFormat'])) {
|
||||
$this->_lineFormat = str_replace(array_keys($this->_formatMap),
|
||||
array_values($this->_formatMap),
|
||||
$conf['lineFormat']);
|
||||
}
|
||||
|
||||
if (!empty($conf['timeFormat'])) {
|
||||
$this->_timeFormat = $conf['timeFormat'];
|
||||
}
|
||||
|
||||
if (!empty($conf['eol'])) {
|
||||
$this->_eol = $conf['eol'];
|
||||
} else {
|
||||
$this->_eol = (strstr(PHP_OS, 'WIN')) ? "\r\n" : "\n";
|
||||
}
|
||||
|
||||
register_shutdown_function(array(&$this, '_Log_file'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
function _Log_file()
|
||||
{
|
||||
if ($this->_opened) {
|
||||
$this->close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the given directory path. If the parent directories don't
|
||||
* already exist, they will be created, too.
|
||||
*
|
||||
* This implementation is inspired by Python's os.makedirs function.
|
||||
*
|
||||
* @param string $path The full directory path to create.
|
||||
* @param integer $mode The permissions mode with which the
|
||||
* directories will be created.
|
||||
*
|
||||
* @return True if the full path is successfully created or already
|
||||
* exists.
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
function _mkpath($path, $mode = 0700)
|
||||
{
|
||||
/* Separate the last pathname component from the rest of the path. */
|
||||
$head = dirname($path);
|
||||
$tail = basename($path);
|
||||
|
||||
/* Make sure we've split the path into two complete components. */
|
||||
if (empty($tail)) {
|
||||
$head = dirname($path);
|
||||
$tail = basename($path);
|
||||
}
|
||||
|
||||
/* Recurse up the path if our current segment does not exist. */
|
||||
if (!empty($head) && !empty($tail) && !is_dir($head)) {
|
||||
$this->_mkpath($head, $mode);
|
||||
}
|
||||
|
||||
/* Create this segment of the path. */
|
||||
return @mkdir($head, $mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens the log file for output. If the specified log file does not
|
||||
* already exist, it will be created. By default, new log entries are
|
||||
* appended to the end of the log file.
|
||||
*
|
||||
* This is implicitly called by log(), if necessary.
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function open()
|
||||
{
|
||||
if (!$this->_opened) {
|
||||
/* If the log file's directory doesn't exist, create it. */
|
||||
if (!is_dir(dirname($this->_filename))) {
|
||||
$this->_mkpath($this->_filename, $this->_dirmode);
|
||||
}
|
||||
|
||||
/* Determine whether the log file needs to be created. */
|
||||
$creating = !file_exists($this->_filename);
|
||||
|
||||
/* Obtain a handle to the log file. */
|
||||
$this->_fp = fopen($this->_filename, ($this->_append) ? 'a' : 'w');
|
||||
|
||||
/* We consider the file "opened" if we have a valid file pointer. */
|
||||
$this->_opened = ($this->_fp !== false);
|
||||
|
||||
/* Attempt to set the file's permissions if we just created it. */
|
||||
if ($creating && $this->_opened) {
|
||||
chmod($this->_filename, $this->_mode);
|
||||
}
|
||||
}
|
||||
|
||||
return $this->_opened;
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the log file if it is open.
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function close()
|
||||
{
|
||||
/* If the log file is open, close it. */
|
||||
if ($this->_opened && fclose($this->_fp)) {
|
||||
$this->_opened = false;
|
||||
}
|
||||
|
||||
return ($this->_opened === false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Flushes all pending data to the file handle.
|
||||
*
|
||||
* @access public
|
||||
* @since Log 1.8.2
|
||||
*/
|
||||
function flush()
|
||||
{
|
||||
return fflush($this->_fp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs $message to the output window. The message is also passed along
|
||||
* to any Log_observer instances that are observing this Log.
|
||||
*
|
||||
* @param mixed $message String or object containing the message to log.
|
||||
* @param string $priority The priority of the message. Valid
|
||||
* values are: PEAR_LOG_EMERG, PEAR_LOG_ALERT,
|
||||
* PEAR_LOG_CRIT, PEAR_LOG_ERR, PEAR_LOG_WARNING,
|
||||
* PEAR_LOG_NOTICE, PEAR_LOG_INFO, and PEAR_LOG_DEBUG.
|
||||
* @return boolean True on success or false on failure.
|
||||
* @access public
|
||||
*/
|
||||
function log($message, $priority = null)
|
||||
{
|
||||
/* If a priority hasn't been specified, use the default value. */
|
||||
if ($priority === null) {
|
||||
$priority = $this->_priority;
|
||||
}
|
||||
|
||||
/* Abort early if the priority is above the maximum logging level. */
|
||||
if (!$this->_isMasked($priority)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* If the log file isn't already open, open it now. */
|
||||
if (!$this->_opened && !$this->open()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Extract the string representation of the message. */
|
||||
$message = $this->_extractMessage($message);
|
||||
|
||||
/* Build the string containing the complete log line. */
|
||||
$line = $this->_format($this->_lineFormat,
|
||||
strftime($this->_timeFormat),
|
||||
$priority, $message) . $this->_eol;
|
||||
|
||||
/* If locking is enabled, acquire an exclusive lock on the file. */
|
||||
if ($this->_locking) {
|
||||
flock($this->_fp, LOCK_EX);
|
||||
}
|
||||
|
||||
/* Write the log line to the log file. */
|
||||
$success = (fwrite($this->_fp, $line) !== false);
|
||||
|
||||
/* Unlock the file now that we're finished writing to it. */
|
||||
if ($this->_locking) {
|
||||
flock($this->_fp, LOCK_UN);
|
||||
}
|
||||
|
||||
/* Notify observers about this log message. */
|
||||
$this->_announce(array('priority' => $priority, 'message' => $message));
|
||||
|
||||
return $success;
|
||||
}
|
||||
|
||||
}
|
246
egw-pear/Log/mail.php
Normal file
246
egw-pear/Log/mail.php
Normal file
@ -0,0 +1,246 @@
|
||||
<?php
|
||||
/**
|
||||
* $Header: /repository/pear/Log/Log/mail.php,v 1.24 2006/01/30 05:37:18 jon Exp $
|
||||
*
|
||||
* @version $Revision: 1.24 $
|
||||
* @package Log
|
||||
*/
|
||||
|
||||
/**
|
||||
* The Log_mail class is a concrete implementation of the Log:: abstract class
|
||||
* which sends log messages to a mailbox.
|
||||
* The mail is actually sent when you close() the logger, or when the destructor
|
||||
* is called (when the script is terminated).
|
||||
*
|
||||
* PLEASE NOTE that you must create a Log_mail object using =&, like this :
|
||||
* $logger =& Log::factory("mail", "recipient@example.com", ...)
|
||||
*
|
||||
* This is a PEAR requirement for destructors to work properly.
|
||||
* See http://pear.php.net/manual/en/class.pear.php
|
||||
*
|
||||
* @author Ronnie Garcia <ronnie@mk2.net>
|
||||
* @author Jon Parise <jon@php.net>
|
||||
* @since Log 1.3
|
||||
* @package Log
|
||||
*
|
||||
* @example mail.php Using the mail handler.
|
||||
*/
|
||||
class Log_mail extends Log
|
||||
{
|
||||
/**
|
||||
* String holding the recipient's email address.
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $_recipient = '';
|
||||
|
||||
/**
|
||||
* String holding the sender's email address.
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $_from = '';
|
||||
|
||||
/**
|
||||
* String holding the email's subject.
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $_subject = '[Log_mail] Log message';
|
||||
|
||||
/**
|
||||
* String holding an optional preamble for the log messages.
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $_preamble = '';
|
||||
|
||||
/**
|
||||
* String containing the format of a log line.
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $_lineFormat = '%1$s %2$s [%3$s] %4$s';
|
||||
|
||||
/**
|
||||
* String containing the timestamp format. It will be passed directly to
|
||||
* strftime(). Note that the timestamp string will generated using the
|
||||
* current locale.
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $_timeFormat = '%b %d %H:%M:%S';
|
||||
|
||||
/**
|
||||
* String holding the mail message body.
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $_message = '';
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a new Log_mail object.
|
||||
*
|
||||
* Here is how you can customize the mail driver with the conf[] hash :
|
||||
* $conf['from'] : the mail's "From" header line,
|
||||
* $conf['subject'] : the mail's "Subject" line.
|
||||
*
|
||||
* @param string $name The filename of the logfile.
|
||||
* @param string $ident The identity string.
|
||||
* @param array $conf The configuration array.
|
||||
* @param int $level Log messages up to and including this level.
|
||||
* @access public
|
||||
*/
|
||||
function Log_mail($name, $ident = '', $conf = array(),
|
||||
$level = PEAR_LOG_DEBUG)
|
||||
{
|
||||
$this->_id = md5(microtime());
|
||||
$this->_recipient = $name;
|
||||
$this->_ident = $ident;
|
||||
$this->_mask = Log::UPTO($level);
|
||||
|
||||
if (!empty($conf['from'])) {
|
||||
$this->_from = $conf['from'];
|
||||
} else {
|
||||
$this->_from = ini_get('sendmail_from');
|
||||
}
|
||||
|
||||
if (!empty($conf['subject'])) {
|
||||
$this->_subject = $conf['subject'];
|
||||
}
|
||||
|
||||
if (!empty($conf['preamble'])) {
|
||||
$this->_preamble = $conf['preamble'];
|
||||
}
|
||||
|
||||
if (!empty($conf['lineFormat'])) {
|
||||
$this->_lineFormat = str_replace(array_keys($this->_formatMap),
|
||||
array_values($this->_formatMap),
|
||||
$conf['lineFormat']);
|
||||
}
|
||||
|
||||
if (!empty($conf['timeFormat'])) {
|
||||
$this->_timeFormat = $conf['timeFormat'];
|
||||
}
|
||||
|
||||
/* register the destructor */
|
||||
register_shutdown_function(array(&$this, '_Log_mail'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Destructor. Calls close().
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
function _Log_mail()
|
||||
{
|
||||
$this->close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts a new mail message.
|
||||
* This is implicitly called by log(), if necessary.
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function open()
|
||||
{
|
||||
if (!$this->_opened) {
|
||||
if (!empty($this->_preamble)) {
|
||||
$this->_message = $this->_preamble . "\r\n\r\n";
|
||||
}
|
||||
$this->_opened = true;
|
||||
}
|
||||
|
||||
return $this->_opened;
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the message, if it is open, and sends the mail.
|
||||
* This is implicitly called by the destructor, if necessary.
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function close()
|
||||
{
|
||||
if ($this->_opened) {
|
||||
if (!empty($this->_message)) {
|
||||
$headers = "From: $this->_from\r\n";
|
||||
$headers .= "User-Agent: Log_mail";
|
||||
|
||||
if (mail($this->_recipient, $this->_subject, $this->_message,
|
||||
$headers) == false) {
|
||||
error_log("Log_mail: Failure executing mail()", 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Clear the message string now that the email has been sent. */
|
||||
$this->_message = '';
|
||||
}
|
||||
$this->_opened = false;
|
||||
}
|
||||
|
||||
return ($this->_opened === false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Flushes the log output by forcing the email message to be sent now.
|
||||
* Events that are logged after flush() is called will be appended to a
|
||||
* new email message.
|
||||
*
|
||||
* @access public
|
||||
* @since Log 1.8.2
|
||||
*/
|
||||
function flush()
|
||||
{
|
||||
/*
|
||||
* It's sufficient to simply call close() to flush the output.
|
||||
* The next call to log() will cause the handler to be reopened.
|
||||
*/
|
||||
return $this->close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes $message to the currently open mail message.
|
||||
* Calls open(), if necessary.
|
||||
*
|
||||
* @param mixed $message String or object containing the message to log.
|
||||
* @param string $priority The priority of the message. Valid
|
||||
* values are: PEAR_LOG_EMERG, PEAR_LOG_ALERT,
|
||||
* PEAR_LOG_CRIT, PEAR_LOG_ERR, PEAR_LOG_WARNING,
|
||||
* PEAR_LOG_NOTICE, PEAR_LOG_INFO, and PEAR_LOG_DEBUG.
|
||||
* @return boolean True on success or false on failure.
|
||||
* @access public
|
||||
*/
|
||||
function log($message, $priority = null)
|
||||
{
|
||||
/* If a priority hasn't been specified, use the default value. */
|
||||
if ($priority === null) {
|
||||
$priority = $this->_priority;
|
||||
}
|
||||
|
||||
/* Abort early if the priority is above the maximum logging level. */
|
||||
if (!$this->_isMasked($priority)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* If the message isn't open and can't be opened, return failure. */
|
||||
if (!$this->_opened && !$this->open()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Extract the string representation of the message. */
|
||||
$message = $this->_extractMessage($message);
|
||||
|
||||
/* Build the string containing the complete log line. */
|
||||
$this->_message .= $this->_format($this->_lineFormat,
|
||||
strftime($this->_timeFormat),
|
||||
$priority, $message) . "\r\n";
|
||||
|
||||
/* Notify observers about this log message. */
|
||||
$this->_announce(array('priority' => $priority, 'message' => $message));
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
170
egw-pear/Log/mcal.php
Normal file
170
egw-pear/Log/mcal.php
Normal file
@ -0,0 +1,170 @@
|
||||
<?php
|
||||
/**
|
||||
* $Header: /repository/pear/Log/Log/mcal.php,v 1.18 2005/02/26 14:48:58 chagenbu Exp $
|
||||
* $Horde: horde/lib/Log/mcal.php,v 1.2 2000/06/28 21:36:13 jon Exp $
|
||||
*
|
||||
* @version $Revision: 1.18 $
|
||||
* @package Log
|
||||
*/
|
||||
|
||||
/**
|
||||
* The Log_mcal class is a concrete implementation of the Log::
|
||||
* abstract class which sends messages to a local or remote calendar
|
||||
* store accessed through MCAL.
|
||||
*
|
||||
* @author Chuck Hagenbuch <chuck@horde.org>
|
||||
* @since Horde 1.3
|
||||
* @since Log 1.0
|
||||
* @package Log
|
||||
*/
|
||||
class Log_mcal extends Log
|
||||
{
|
||||
/**
|
||||
* holding the calendar specification to connect to.
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $_calendar = '{localhost/mstore}';
|
||||
|
||||
/**
|
||||
* holding the username to use.
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $_username = '';
|
||||
|
||||
/**
|
||||
* holding the password to use.
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $_password = '';
|
||||
|
||||
/**
|
||||
* holding the options to pass to the calendar stream.
|
||||
* @var integer
|
||||
* @access private
|
||||
*/
|
||||
var $_options = 0;
|
||||
|
||||
/**
|
||||
* ResourceID of the MCAL stream.
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $_stream = '';
|
||||
|
||||
/**
|
||||
* Integer holding the log facility to use.
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $_name = LOG_SYSLOG;
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a new Log_mcal object.
|
||||
*
|
||||
* @param string $name The category to use for our events.
|
||||
* @param string $ident The identity string.
|
||||
* @param array $conf The configuration array.
|
||||
* @param int $level Log messages up to and including this level.
|
||||
* @access public
|
||||
*/
|
||||
function Log_mcal($name, $ident = '', $conf = array(),
|
||||
$level = PEAR_LOG_DEBUG)
|
||||
{
|
||||
$this->_id = md5(microtime());
|
||||
$this->_name = $name;
|
||||
$this->_ident = $ident;
|
||||
$this->_mask = Log::UPTO($level);
|
||||
$this->_calendar = $conf['calendar'];
|
||||
$this->_username = $conf['username'];
|
||||
$this->_password = $conf['password'];
|
||||
$this->_options = $conf['options'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens a calendar stream, if it has not already been
|
||||
* opened. This is implicitly called by log(), if necessary.
|
||||
* @access public
|
||||
*/
|
||||
function open()
|
||||
{
|
||||
if (!$this->_opened) {
|
||||
$this->_stream = mcal_open($this->_calendar, $this->_username,
|
||||
$this->_password, $this->_options);
|
||||
$this->_opened = true;
|
||||
}
|
||||
|
||||
return $this->_opened;
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the calendar stream, if it is open.
|
||||
* @access public
|
||||
*/
|
||||
function close()
|
||||
{
|
||||
if ($this->_opened) {
|
||||
mcal_close($this->_stream);
|
||||
$this->_opened = false;
|
||||
}
|
||||
|
||||
return ($this->_opened === false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs $message and associated information to the currently open
|
||||
* calendar stream. Calls open() if necessary. Also passes the
|
||||
* message along to any Log_observer instances that are observing
|
||||
* this Log.
|
||||
*
|
||||
* @param mixed $message String or object containing the message to log.
|
||||
* @param string $priority The priority of the message. Valid
|
||||
* values are: PEAR_LOG_EMERG, PEAR_LOG_ALERT,
|
||||
* PEAR_LOG_CRIT, PEAR_LOG_ERR, PEAR_LOG_WARNING,
|
||||
* PEAR_LOG_NOTICE, PEAR_LOG_INFO, and PEAR_LOG_DEBUG.
|
||||
* @return boolean True on success or false on failure.
|
||||
* @access public
|
||||
*/
|
||||
function log($message, $priority = null)
|
||||
{
|
||||
/* If a priority hasn't been specified, use the default value. */
|
||||
if ($priority === null) {
|
||||
$priority = $this->_priority;
|
||||
}
|
||||
|
||||
/* Abort early if the priority is above the maximum logging level. */
|
||||
if (!$this->_isMasked($priority)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* If the connection isn't open and can't be opened, return failure. */
|
||||
if (!$this->_opened && !$this->open()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Extract the string representation of the message. */
|
||||
$message = $this->_extractMessage($message);
|
||||
|
||||
$date_str = date('Y:n:j:G:i:s');
|
||||
$dates = explode(':', $date_str);
|
||||
|
||||
mcal_event_init($this->_stream);
|
||||
mcal_event_set_title($this->_stream, $this->_ident);
|
||||
mcal_event_set_category($this->_stream, $this->_name);
|
||||
mcal_event_set_description($this->_stream, $message);
|
||||
mcal_event_add_attribute($this->_stream, 'priority', $priority);
|
||||
mcal_event_set_start($this->_stream, $dates[0], $dates[1], $dates[2],
|
||||
$dates[3], $dates[4], $dates[5]);
|
||||
mcal_event_set_end($this->_stream, $dates[0], $dates[1], $dates[2],
|
||||
$dates[3], $dates[4], $dates[5]);
|
||||
mcal_append_event($this->_stream);
|
||||
|
||||
$this->_announce(array('priority' => $priority, 'message' => $message));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
358
egw-pear/Log/mdb2.php
Normal file
358
egw-pear/Log/mdb2.php
Normal file
@ -0,0 +1,358 @@
|
||||
<?php
|
||||
/**
|
||||
* $Header: /repository/pear/Log/Log/mdb2.php,v 1.5 2006/01/08 03:35:44 jon Exp $
|
||||
*
|
||||
* @version $Revision: 1.5 $
|
||||
* @package Log
|
||||
*/
|
||||
|
||||
/** PEAR's MDB2 package */
|
||||
require_once 'MDB2.php';
|
||||
MDB2::loadFile('Date');
|
||||
|
||||
/**
|
||||
* The Log_mdb2 class is a concrete implementation of the Log:: abstract class
|
||||
* which sends messages to an SQL server. Each entry occupies a separate row
|
||||
* in the database.
|
||||
*
|
||||
* This implementation uses PEAR's MDB2 database abstraction layer.
|
||||
*
|
||||
* CREATE TABLE log_table (
|
||||
* id INT NOT NULL,
|
||||
* logtime TIMESTAMP NOT NULL,
|
||||
* ident CHAR(16) NOT NULL,
|
||||
* priority INT NOT NULL,
|
||||
* message VARCHAR(200),
|
||||
* PRIMARY KEY (id)
|
||||
* );
|
||||
*
|
||||
* @author Lukas Smith <smith@backendmedia.com>
|
||||
* @author Jon Parise <jon@php.net>
|
||||
* @since Log 1.9.0
|
||||
* @package Log
|
||||
*/
|
||||
class Log_mdb2 extends Log
|
||||
{
|
||||
/**
|
||||
* Variable containing the DSN information.
|
||||
* @var mixed
|
||||
* @access private
|
||||
*/
|
||||
var $_dsn = '';
|
||||
|
||||
/**
|
||||
* Array containing our set of DB configuration options.
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $_options = array('persistent' => true);
|
||||
|
||||
/**
|
||||
* Object holding the database handle.
|
||||
* @var object
|
||||
* @access private
|
||||
*/
|
||||
var $_db = null;
|
||||
|
||||
/**
|
||||
* Resource holding the prepared statement handle.
|
||||
* @var resource
|
||||
* @access private
|
||||
*/
|
||||
var $_statement = null;
|
||||
|
||||
/**
|
||||
* Flag indicating that we're using an existing database connection.
|
||||
* @var boolean
|
||||
* @access private
|
||||
*/
|
||||
var $_existingConnection = false;
|
||||
|
||||
/**
|
||||
* String holding the database table to use.
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $_table = 'log_table';
|
||||
|
||||
/**
|
||||
* String holding the name of the ID sequence.
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $_sequence = 'log_id';
|
||||
|
||||
/**
|
||||
* Maximum length of the $ident string. This corresponds to the size of
|
||||
* the 'ident' column in the SQL table.
|
||||
* @var integer
|
||||
* @access private
|
||||
*/
|
||||
var $_identLimit = 16;
|
||||
|
||||
/**
|
||||
* Set of field types used in the database table.
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $_types = array(
|
||||
'id' => 'integer',
|
||||
'logtime' => 'timestamp',
|
||||
'ident' => 'text',
|
||||
'priority' => 'text',
|
||||
'message' => 'clob'
|
||||
);
|
||||
|
||||
/**
|
||||
* Constructs a new sql logging object.
|
||||
*
|
||||
* @param string $name The target SQL table.
|
||||
* @param string $ident The identification field.
|
||||
* @param array $conf The connection configuration array.
|
||||
* @param int $level Log messages up to and including this level.
|
||||
* @access public
|
||||
*/
|
||||
function Log_mdb2($name, $ident = '', $conf = array(),
|
||||
$level = PEAR_LOG_DEBUG)
|
||||
{
|
||||
$this->_id = md5(microtime());
|
||||
$this->_table = $name;
|
||||
$this->_mask = Log::UPTO($level);
|
||||
|
||||
/* If an options array was provided, use it. */
|
||||
if (isset($conf['options']) && is_array($conf['options'])) {
|
||||
$this->_options = $conf['options'];
|
||||
}
|
||||
|
||||
/* If a specific sequence name was provided, use it. */
|
||||
if (!empty($conf['sequence'])) {
|
||||
$this->_sequence = $conf['sequence'];
|
||||
}
|
||||
|
||||
/* If a specific sequence name was provided, use it. */
|
||||
if (isset($conf['identLimit'])) {
|
||||
$this->_identLimit = $conf['identLimit'];
|
||||
}
|
||||
|
||||
/* Now that the ident limit is confirmed, set the ident string. */
|
||||
$this->setIdent($ident);
|
||||
|
||||
/* If an existing database connection was provided, use it. */
|
||||
if (isset($conf['db'])) {
|
||||
$this->_db = &$conf['db'];
|
||||
$this->_existingConnection = true;
|
||||
$this->_opened = true;
|
||||
} elseif (isset($conf['singleton'])) {
|
||||
$this->_db = &MDB2::singleton($conf['singleton'], $this->_options);
|
||||
$this->_existingConnection = true;
|
||||
$this->_opened = true;
|
||||
} else {
|
||||
$this->_dsn = $conf['dsn'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens a connection to the database, if it has not already
|
||||
* been opened. This is implicitly called by log(), if necessary.
|
||||
*
|
||||
* @return boolean True on success, false on failure.
|
||||
* @access public
|
||||
*/
|
||||
function open()
|
||||
{
|
||||
if (!$this->_opened) {
|
||||
/* Use the DSN and options to create a database connection. */
|
||||
$this->_db = &MDB2::connect($this->_dsn, $this->_options);
|
||||
if (PEAR::isError($this->_db)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Create a prepared statement for repeated use in log(). */
|
||||
if (!$this->_prepareStatement()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* We now consider out connection open. */
|
||||
$this->_opened = true;
|
||||
}
|
||||
|
||||
return $this->_opened;
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the connection to the database if it is still open and we were
|
||||
* the ones that opened it. It is the caller's responsible to close an
|
||||
* existing connection that was passed to us via $conf['db'].
|
||||
*
|
||||
* @return boolean True on success, false on failure.
|
||||
* @access public
|
||||
*/
|
||||
function close()
|
||||
{
|
||||
/* If we have a statement object, free it. */
|
||||
if (is_object($this->_statement)) {
|
||||
$this->_statement->free();
|
||||
$this->_statement = null;
|
||||
}
|
||||
|
||||
/* If we opened the database connection, disconnect it. */
|
||||
if ($this->_opened && !$this->_existingConnection) {
|
||||
$this->_opened = false;
|
||||
return $this->_db->disconnect();
|
||||
}
|
||||
|
||||
return ($this->_opened === false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets this Log instance's identification string. Note that this
|
||||
* SQL-specific implementation will limit the length of the $ident string
|
||||
* to sixteen (16) characters.
|
||||
*
|
||||
* @param string $ident The new identification string.
|
||||
*
|
||||
* @access public
|
||||
* @since Log 1.8.5
|
||||
*/
|
||||
function setIdent($ident)
|
||||
{
|
||||
$this->_ident = substr($ident, 0, $this->_identLimit);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts $message to the currently open database. Calls open(),
|
||||
* if necessary. Also passes the message along to any Log_observer
|
||||
* instances that are observing this Log.
|
||||
*
|
||||
* @param mixed $message String or object containing the message to log.
|
||||
* @param string $priority The priority of the message. Valid
|
||||
* values are: PEAR_LOG_EMERG, PEAR_LOG_ALERT,
|
||||
* PEAR_LOG_CRIT, PEAR_LOG_ERR, PEAR_LOG_WARNING,
|
||||
* PEAR_LOG_NOTICE, PEAR_LOG_INFO, and PEAR_LOG_DEBUG.
|
||||
* @return boolean True on success or false on failure.
|
||||
* @access public
|
||||
*/
|
||||
function log($message, $priority = null)
|
||||
{
|
||||
/* If a priority hasn't been specified, use the default value. */
|
||||
if ($priority === null) {
|
||||
$priority = $this->_priority;
|
||||
}
|
||||
|
||||
/* Abort early if the priority is above the maximum logging level. */
|
||||
if (!$this->_isMasked($priority)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* If the connection isn't open and can't be opened, return failure. */
|
||||
if (!$this->_opened && !$this->open()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* If we don't already have a statement object, create one. */
|
||||
if (!is_object($this->_statement) && !$this->_prepareStatement()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Extract the string representation of the message. */
|
||||
$message = $this->_extractMessage($message);
|
||||
|
||||
/* Build our set of values for this log entry. */
|
||||
$values = array(
|
||||
'id' => $this->_db->nextId($this->_sequence),
|
||||
'logtime' => MDB2_Date::mdbNow(),
|
||||
'ident' => $this->_ident,
|
||||
'priority' => $priority,
|
||||
'message' => $message
|
||||
);
|
||||
|
||||
/* Execute the SQL query for this log entry insertion. */
|
||||
$this->_db->expectError(MDB2_ERROR_NOSUCHTABLE);
|
||||
$result = &$this->_statement->execute($values);
|
||||
$this->_db->popExpect();
|
||||
|
||||
/* Attempt to handle any errors. */
|
||||
if (PEAR::isError($result)) {
|
||||
/* We can only handle MDB2_ERROR_NOSUCHTABLE errors. */
|
||||
if ($result->getCode() != MDB2_ERROR_NOSUCHTABLE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Attempt to create the target table. */
|
||||
if (!$this->_createTable()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Recreate our prepared statement resource. */
|
||||
$this->_statement->free();
|
||||
if (!$this->_prepareStatement()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Attempt to re-execute the insertion query. */
|
||||
$result = $this->_statement->execute($values);
|
||||
if (PEAR::isError($result)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
$this->_announce(array('priority' => $priority, 'message' => $message));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the log table in the database.
|
||||
*
|
||||
* @return boolean True on success or false on failure.
|
||||
* @access private
|
||||
*/
|
||||
function _createTable()
|
||||
{
|
||||
$this->_db->loadModule('Manager', null, true);
|
||||
$result = $this->_db->manager->createTable(
|
||||
$this->_table,
|
||||
array(
|
||||
'id' => array('type' => $this->_types['id']),
|
||||
'logtime' => array('type' => $this->_types['logtime']),
|
||||
'ident' => array('type' => $this->_types['ident']),
|
||||
'priority' => array('type' => $this->_types['priority']),
|
||||
'message' => array('type' => $this->_types['message'])
|
||||
)
|
||||
);
|
||||
if (PEAR::isError($result)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$result = $this->_db->manager->createIndex(
|
||||
$this->_table,
|
||||
'unique_id',
|
||||
array('fields' => array('id' => true), 'unique' => true)
|
||||
);
|
||||
if (PEAR::isError($result)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare the SQL insertion statement.
|
||||
*
|
||||
* @return boolean True if the statement was successfully created.
|
||||
*
|
||||
* @access private
|
||||
* @since Log 1.9.0
|
||||
*/
|
||||
function _prepareStatement()
|
||||
{
|
||||
$this->_statement = &$this->_db->prepare(
|
||||
'INSERT INTO ' . $this->_table .
|
||||
' (id, logtime, ident, priority, message)' .
|
||||
' VALUES(:id, :logtime, :ident, :priority, :message)',
|
||||
$this->_types, MDB2_PREPARE_MANIP);
|
||||
|
||||
/* Return success if we didn't generate an error. */
|
||||
return (PEAR::isError($this->_statement) === false);
|
||||
}
|
||||
}
|
91
egw-pear/Log/null.php
Normal file
91
egw-pear/Log/null.php
Normal file
@ -0,0 +1,91 @@
|
||||
<?php
|
||||
/**
|
||||
* $Header: /repository/pear/Log/Log/null.php,v 1.5 2006/06/29 07:09:21 jon Exp $
|
||||
*
|
||||
* @version $Revision: 1.5 $
|
||||
* @package Log
|
||||
*/
|
||||
|
||||
/**
|
||||
* The Log_null class is a concrete implementation of the Log:: abstract
|
||||
* class. It simply consumes log events.
|
||||
*
|
||||
* @author Jon Parise <jon@php.net>
|
||||
* @since Log 1.8.2
|
||||
* @package Log
|
||||
*
|
||||
* @example null.php Using the null handler.
|
||||
*/
|
||||
class Log_null extends Log
|
||||
{
|
||||
/**
|
||||
* Constructs a new Log_null object.
|
||||
*
|
||||
* @param string $name Ignored.
|
||||
* @param string $ident The identity string.
|
||||
* @param array $conf The configuration array.
|
||||
* @param int $level Log messages up to and including this level.
|
||||
* @access public
|
||||
*/
|
||||
function Log_null($name, $ident = '', $conf = array(),
|
||||
$level = PEAR_LOG_DEBUG)
|
||||
{
|
||||
$this->_id = md5(microtime());
|
||||
$this->_ident = $ident;
|
||||
$this->_mask = Log::UPTO($level);
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens the handler.
|
||||
*
|
||||
* @access public
|
||||
* @since Log 1.9.6
|
||||
*/
|
||||
function open()
|
||||
{
|
||||
$this->_opened = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the handler.
|
||||
*
|
||||
* @access public
|
||||
* @since Log 1.9.6
|
||||
*/
|
||||
function close()
|
||||
{
|
||||
$this->_opened = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simply consumes the log event. The message will still be passed
|
||||
* along to any Log_observer instances that are observing this Log.
|
||||
*
|
||||
* @param mixed $message String or object containing the message to log.
|
||||
* @param string $priority The priority of the message. Valid
|
||||
* values are: PEAR_LOG_EMERG, PEAR_LOG_ALERT,
|
||||
* PEAR_LOG_CRIT, PEAR_LOG_ERR, PEAR_LOG_WARNING,
|
||||
* PEAR_LOG_NOTICE, PEAR_LOG_INFO, and PEAR_LOG_DEBUG.
|
||||
* @return boolean True on success or false on failure.
|
||||
* @access public
|
||||
*/
|
||||
function log($message, $priority = null)
|
||||
{
|
||||
/* If a priority hasn't been specified, use the default value. */
|
||||
if ($priority === null) {
|
||||
$priority = $this->_priority;
|
||||
}
|
||||
|
||||
/* Abort early if the priority is above the maximum logging level. */
|
||||
if (!$this->_isMasked($priority)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->_announce(array('priority' => $priority, 'message' => $message));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
129
egw-pear/Log/observer.php
Normal file
129
egw-pear/Log/observer.php
Normal file
@ -0,0 +1,129 @@
|
||||
<?php
|
||||
/**
|
||||
* $Header: /repository/pear/Log/Log/observer.php,v 1.18 2006/04/25 06:02:23 jon Exp $
|
||||
* $Horde: horde/lib/Log/observer.php,v 1.5 2000/06/28 21:36:13 jon Exp $
|
||||
*
|
||||
* @version $Revision: 1.18 $
|
||||
* @package Log
|
||||
*/
|
||||
|
||||
/**
|
||||
* The Log_observer:: class implements the Observer end of a Subject-Observer
|
||||
* pattern for watching log activity and taking actions on exceptional events.
|
||||
*
|
||||
* @author Chuck Hagenbuch <chuck@horde.org>
|
||||
* @since Horde 1.3
|
||||
* @since Log 1.0
|
||||
* @package Log
|
||||
*
|
||||
* @example observer_mail.php An example Log_observer implementation.
|
||||
*/
|
||||
class Log_observer
|
||||
{
|
||||
/**
|
||||
* Instance-specific unique identification number.
|
||||
*
|
||||
* @var integer
|
||||
* @access private
|
||||
*/
|
||||
var $_id = 0;
|
||||
|
||||
/**
|
||||
* The minimum priority level of message that we want to hear about.
|
||||
* PEAR_LOG_EMERG is the highest priority, so we will only hear messages
|
||||
* with an integer priority value less than or equal to ours. It defaults
|
||||
* to PEAR_LOG_INFO, which listens to everything except PEAR_LOG_DEBUG.
|
||||
*
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $_priority = PEAR_LOG_INFO;
|
||||
|
||||
/**
|
||||
* Creates a new basic Log_observer instance.
|
||||
*
|
||||
* @param integer $priority The highest priority at which to receive
|
||||
* log event notifications.
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function Log_observer($priority = PEAR_LOG_INFO)
|
||||
{
|
||||
$this->_id = md5(microtime());
|
||||
$this->_priority = $priority;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to return a new concrete Log_observer instance of the requested
|
||||
* type.
|
||||
*
|
||||
* @param string $type The type of concreate Log_observer subclass
|
||||
* to return.
|
||||
* @param integer $priority The highest priority at which to receive
|
||||
* log event notifications.
|
||||
* @param array $conf Optional associative array of additional
|
||||
* configuration values.
|
||||
*
|
||||
* @return object The newly created concrete Log_observer
|
||||
* instance, or null on an error.
|
||||
*/
|
||||
function &factory($type, $priority = PEAR_LOG_INFO, $conf = array())
|
||||
{
|
||||
$type = strtolower($type);
|
||||
$class = 'Log_observer_' . $type;
|
||||
|
||||
/*
|
||||
* If the desired class already exists (because the caller has supplied
|
||||
* it from some custom location), simply instantiate and return a new
|
||||
* instance.
|
||||
*/
|
||||
if (class_exists($class)) {
|
||||
$object = &new $class($priority, $conf);
|
||||
return $object;
|
||||
}
|
||||
|
||||
/* Support both the new-style and old-style file naming conventions. */
|
||||
$newstyle = true;
|
||||
$classfile = dirname(__FILE__) . '/observer_' . $type . '.php';
|
||||
|
||||
if (!file_exists($classfile)) {
|
||||
$classfile = 'Log/' . $type . '.php';
|
||||
$newstyle = false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Attempt to include our version of the named class, but don't treat
|
||||
* a failure as fatal. The caller may have already included their own
|
||||
* version of the named class.
|
||||
*/
|
||||
@include_once $classfile;
|
||||
|
||||
/* If the class exists, return a new instance of it. */
|
||||
if (class_exists($class)) {
|
||||
/* Support both new-style and old-style construction. */
|
||||
if ($newstyle) {
|
||||
$object = &new $class($priority, $conf);
|
||||
} else {
|
||||
$object = &new $class($priority);
|
||||
}
|
||||
return $object;
|
||||
}
|
||||
|
||||
$null = null;
|
||||
return $null;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a stub method to make sure that Log_Observer classes do
|
||||
* something when they are notified of a message. The default behavior
|
||||
* is to just print the message, which is obviously not desireable in
|
||||
* practically any situation - which is why you need to override this
|
||||
* method. :)
|
||||
*
|
||||
* @param array $event A hash describing the log event.
|
||||
*/
|
||||
function notify($event)
|
||||
{
|
||||
print_r($event);
|
||||
}
|
||||
}
|
294
egw-pear/Log/sql.php
Normal file
294
egw-pear/Log/sql.php
Normal file
@ -0,0 +1,294 @@
|
||||
<?php
|
||||
/**
|
||||
* $Header: /repository/pear/Log/Log/sql.php,v 1.40 2006/01/03 04:12:45 jon Exp $
|
||||
* $Horde: horde/lib/Log/sql.php,v 1.12 2000/08/16 20:27:34 chuck Exp $
|
||||
*
|
||||
* @version $Revision: 1.40 $
|
||||
* @package Log
|
||||
*/
|
||||
|
||||
/*
|
||||
* We require the PEAR DB class. This is generally defined in the DB.php file,
|
||||
* but it's possible that the caller may have provided the DB class, or a
|
||||
* compatible wrapper (such as the one shipped with MDB2), so we first check
|
||||
* for an existing 'DB' class before including 'DB.php'.
|
||||
*/
|
||||
if (!class_exists('DB')) {
|
||||
require_once 'DB.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* The Log_sql class is a concrete implementation of the Log::
|
||||
* abstract class which sends messages to an SQL server. Each entry
|
||||
* occupies a separate row in the database.
|
||||
*
|
||||
* This implementation uses PHP's PEAR database abstraction layer.
|
||||
*
|
||||
* CREATE TABLE log_table (
|
||||
* id INT NOT NULL,
|
||||
* logtime TIMESTAMP NOT NULL,
|
||||
* ident CHAR(16) NOT NULL,
|
||||
* priority INT NOT NULL,
|
||||
* message VARCHAR(200),
|
||||
* PRIMARY KEY (id)
|
||||
* );
|
||||
*
|
||||
* @author Jon Parise <jon@php.net>
|
||||
* @since Horde 1.3
|
||||
* @since Log 1.0
|
||||
* @package Log
|
||||
*
|
||||
* @example sql.php Using the SQL handler.
|
||||
*/
|
||||
class Log_sql extends Log
|
||||
{
|
||||
/**
|
||||
* Variable containing the DSN information.
|
||||
* @var mixed
|
||||
* @access private
|
||||
*/
|
||||
var $_dsn = '';
|
||||
|
||||
/**
|
||||
* String containing the SQL insertion statement.
|
||||
*
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $_sql = '';
|
||||
|
||||
/**
|
||||
* Array containing our set of DB configuration options.
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $_options = array('persistent' => true);
|
||||
|
||||
/**
|
||||
* Object holding the database handle.
|
||||
* @var object
|
||||
* @access private
|
||||
*/
|
||||
var $_db = null;
|
||||
|
||||
/**
|
||||
* Resource holding the prepared statement handle.
|
||||
* @var resource
|
||||
* @access private
|
||||
*/
|
||||
var $_statement = null;
|
||||
|
||||
/**
|
||||
* Flag indicating that we're using an existing database connection.
|
||||
* @var boolean
|
||||
* @access private
|
||||
*/
|
||||
var $_existingConnection = false;
|
||||
|
||||
/**
|
||||
* String holding the database table to use.
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $_table = 'log_table';
|
||||
|
||||
/**
|
||||
* String holding the name of the ID sequence.
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $_sequence = 'log_id';
|
||||
|
||||
/**
|
||||
* Maximum length of the $ident string. This corresponds to the size of
|
||||
* the 'ident' column in the SQL table.
|
||||
* @var integer
|
||||
* @access private
|
||||
*/
|
||||
var $_identLimit = 16;
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a new sql logging object.
|
||||
*
|
||||
* @param string $name The target SQL table.
|
||||
* @param string $ident The identification field.
|
||||
* @param array $conf The connection configuration array.
|
||||
* @param int $level Log messages up to and including this level.
|
||||
* @access public
|
||||
*/
|
||||
function Log_sql($name, $ident = '', $conf = array(),
|
||||
$level = PEAR_LOG_DEBUG)
|
||||
{
|
||||
$this->_id = md5(microtime());
|
||||
$this->_table = $name;
|
||||
$this->_mask = Log::UPTO($level);
|
||||
|
||||
/* Now that we have a table name, assign our SQL statement. */
|
||||
if (!empty($this->_sql)) {
|
||||
$this->_sql = $conf['sql'];
|
||||
} else {
|
||||
$this->_sql = 'INSERT INTO ' . $this->_table .
|
||||
' (id, logtime, ident, priority, message)' .
|
||||
' VALUES(?, CURRENT_TIMESTAMP, ?, ?, ?)';
|
||||
}
|
||||
|
||||
/* If an options array was provided, use it. */
|
||||
if (isset($conf['options']) && is_array($conf['options'])) {
|
||||
$this->_options = $conf['options'];
|
||||
}
|
||||
|
||||
/* If a specific sequence name was provided, use it. */
|
||||
if (!empty($conf['sequence'])) {
|
||||
$this->_sequence = $conf['sequence'];
|
||||
}
|
||||
|
||||
/* If a specific sequence name was provided, use it. */
|
||||
if (isset($conf['identLimit'])) {
|
||||
$this->_identLimit = $conf['identLimit'];
|
||||
}
|
||||
|
||||
/* Now that the ident limit is confirmed, set the ident string. */
|
||||
$this->setIdent($ident);
|
||||
|
||||
/* If an existing database connection was provided, use it. */
|
||||
if (isset($conf['db'])) {
|
||||
$this->_db = &$conf['db'];
|
||||
$this->_existingConnection = true;
|
||||
$this->_opened = true;
|
||||
} else {
|
||||
$this->_dsn = $conf['dsn'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens a connection to the database, if it has not already
|
||||
* been opened. This is implicitly called by log(), if necessary.
|
||||
*
|
||||
* @return boolean True on success, false on failure.
|
||||
* @access public
|
||||
*/
|
||||
function open()
|
||||
{
|
||||
if (!$this->_opened) {
|
||||
/* Use the DSN and options to create a database connection. */
|
||||
$this->_db = &DB::connect($this->_dsn, $this->_options);
|
||||
if (DB::isError($this->_db)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Create a prepared statement for repeated use in log(). */
|
||||
if (!$this->_prepareStatement()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* We now consider out connection open. */
|
||||
$this->_opened = true;
|
||||
}
|
||||
|
||||
return $this->_opened;
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the connection to the database if it is still open and we were
|
||||
* the ones that opened it. It is the caller's responsible to close an
|
||||
* existing connection that was passed to us via $conf['db'].
|
||||
*
|
||||
* @return boolean True on success, false on failure.
|
||||
* @access public
|
||||
*/
|
||||
function close()
|
||||
{
|
||||
if ($this->_opened && !$this->_existingConnection) {
|
||||
$this->_opened = false;
|
||||
$this->_db->freePrepared($this->_statement);
|
||||
return $this->_db->disconnect();
|
||||
}
|
||||
|
||||
return ($this->_opened === false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets this Log instance's identification string. Note that this
|
||||
* SQL-specific implementation will limit the length of the $ident string
|
||||
* to sixteen (16) characters.
|
||||
*
|
||||
* @param string $ident The new identification string.
|
||||
*
|
||||
* @access public
|
||||
* @since Log 1.8.5
|
||||
*/
|
||||
function setIdent($ident)
|
||||
{
|
||||
$this->_ident = substr($ident, 0, $this->_identLimit);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts $message to the currently open database. Calls open(),
|
||||
* if necessary. Also passes the message along to any Log_observer
|
||||
* instances that are observing this Log.
|
||||
*
|
||||
* @param mixed $message String or object containing the message to log.
|
||||
* @param string $priority The priority of the message. Valid
|
||||
* values are: PEAR_LOG_EMERG, PEAR_LOG_ALERT,
|
||||
* PEAR_LOG_CRIT, PEAR_LOG_ERR, PEAR_LOG_WARNING,
|
||||
* PEAR_LOG_NOTICE, PEAR_LOG_INFO, and PEAR_LOG_DEBUG.
|
||||
* @return boolean True on success or false on failure.
|
||||
* @access public
|
||||
*/
|
||||
function log($message, $priority = null)
|
||||
{
|
||||
/* If a priority hasn't been specified, use the default value. */
|
||||
if ($priority === null) {
|
||||
$priority = $this->_priority;
|
||||
}
|
||||
|
||||
/* Abort early if the priority is above the maximum logging level. */
|
||||
if (!$this->_isMasked($priority)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* If the connection isn't open and can't be opened, return failure. */
|
||||
if (!$this->_opened && !$this->open()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* If we don't already have our statement object yet, create it. */
|
||||
if (!is_object($this->_statement) && !$this->_prepareStatement()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Extract the string representation of the message. */
|
||||
$message = $this->_extractMessage($message);
|
||||
|
||||
/* Build our set of values for this log entry. */
|
||||
$id = $this->_db->nextId($this->_sequence);
|
||||
$values = array($id, $this->_ident, $priority, $message);
|
||||
|
||||
/* Execute the SQL query for this log entry insertion. */
|
||||
$result =& $this->_db->execute($this->_statement, $values);
|
||||
if (DB::isError($result)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->_announce(array('priority' => $priority, 'message' => $message));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare the SQL insertion statement.
|
||||
*
|
||||
* @return boolean True if the statement was successfully created.
|
||||
*
|
||||
* @access private
|
||||
* @since Log 1.9.1
|
||||
*/
|
||||
function _prepareStatement()
|
||||
{
|
||||
$this->_statement = $this->_db->prepare($this->_sql);
|
||||
|
||||
/* Return success if we didn't generate an error. */
|
||||
return (DB::isError($this->_statement) === false);
|
||||
}
|
||||
}
|
225
egw-pear/Log/sqlite.php
Normal file
225
egw-pear/Log/sqlite.php
Normal file
@ -0,0 +1,225 @@
|
||||
<?php
|
||||
/**
|
||||
* $Header: /repository/pear/Log/Log/sqlite.php,v 1.5 2005/12/05 05:38:31 jon Exp $
|
||||
*
|
||||
* @version $Revision: 1.5 $
|
||||
* @package Log
|
||||
*/
|
||||
|
||||
/**
|
||||
* The Log_sqlite class is a concrete implementation of the Log::
|
||||
* abstract class which sends messages to an Sqlite database.
|
||||
* Each entry occupies a separate row in the database.
|
||||
*
|
||||
* This implementation uses PHP native Sqlite functions.
|
||||
*
|
||||
* CREATE TABLE log_table (
|
||||
* id INTEGER PRIMARY KEY NOT NULL,
|
||||
* logtime NOT NULL,
|
||||
* ident CHAR(16) NOT NULL,
|
||||
* priority INT NOT NULL,
|
||||
* message
|
||||
* );
|
||||
*
|
||||
* @author Bertrand Mansion <bmansion@mamasam.com>
|
||||
* @author Jon Parise <jon@php.net>
|
||||
* @since Log 1.8.3
|
||||
* @package Log
|
||||
*
|
||||
* @example sqlite.php Using the Sqlite handler.
|
||||
*/
|
||||
class Log_sqlite extends Log
|
||||
{
|
||||
/**
|
||||
* Array containing the connection defaults
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $_options = array('mode' => 0666,
|
||||
'persistent' => false);
|
||||
|
||||
/**
|
||||
* Object holding the database handle.
|
||||
* @var object
|
||||
* @access private
|
||||
*/
|
||||
var $_db = null;
|
||||
|
||||
/**
|
||||
* Flag indicating that we're using an existing database connection.
|
||||
* @var boolean
|
||||
* @access private
|
||||
*/
|
||||
var $_existingConnection = false;
|
||||
|
||||
/**
|
||||
* String holding the database table to use.
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $_table = 'log_table';
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a new sql logging object.
|
||||
*
|
||||
* @param string $name The target SQL table.
|
||||
* @param string $ident The identification field.
|
||||
* @param mixed $conf Can be an array of configuration options used
|
||||
* to open a new database connection
|
||||
* or an already opened sqlite connection.
|
||||
* @param int $level Log messages up to and including this level.
|
||||
* @access public
|
||||
*/
|
||||
function Log_sqlite($name, $ident = '', &$conf, $level = PEAR_LOG_DEBUG)
|
||||
{
|
||||
$this->_id = md5(microtime());
|
||||
$this->_table = $name;
|
||||
$this->_ident = $ident;
|
||||
$this->_mask = Log::UPTO($level);
|
||||
|
||||
if (is_array($conf)) {
|
||||
foreach ($conf as $k => $opt) {
|
||||
$this->_options[$k] = $opt;
|
||||
}
|
||||
} else {
|
||||
// If an existing database connection was provided, use it.
|
||||
$this->_db =& $conf;
|
||||
$this->_existingConnection = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens a connection to the database, if it has not already
|
||||
* been opened. This is implicitly called by log(), if necessary.
|
||||
*
|
||||
* @return boolean True on success, false on failure.
|
||||
* @access public
|
||||
*/
|
||||
function open()
|
||||
{
|
||||
if (is_resource($this->_db)) {
|
||||
$this->_opened = true;
|
||||
return $this->_createTable();
|
||||
} else {
|
||||
/* Set the connection function based on the 'persistent' option. */
|
||||
if (empty($this->_options['persistent'])) {
|
||||
$connectFunction = 'sqlite_open';
|
||||
} else {
|
||||
$connectFunction = 'sqlite_popen';
|
||||
}
|
||||
|
||||
/* Attempt to connect to the database. */
|
||||
if ($this->_db = $connectFunction($this->_options['filename'],
|
||||
(int)$this->_options['mode'],
|
||||
$error)) {
|
||||
$this->_opened = true;
|
||||
return $this->_createTable();
|
||||
}
|
||||
}
|
||||
|
||||
return $this->_opened;
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the connection to the database if it is still open and we were
|
||||
* the ones that opened it. It is the caller's responsible to close an
|
||||
* existing connection that was passed to us via $conf['db'].
|
||||
*
|
||||
* @return boolean True on success, false on failure.
|
||||
* @access public
|
||||
*/
|
||||
function close()
|
||||
{
|
||||
/* We never close existing connections. */
|
||||
if ($this->_existingConnection) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($this->_opened) {
|
||||
$this->_opened = false;
|
||||
sqlite_close($this->_db);
|
||||
}
|
||||
|
||||
return ($this->_opened === false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts $message to the currently open database. Calls open(),
|
||||
* if necessary. Also passes the message along to any Log_observer
|
||||
* instances that are observing this Log.
|
||||
*
|
||||
* @param mixed $message String or object containing the message to log.
|
||||
* @param string $priority The priority of the message. Valid
|
||||
* values are: PEAR_LOG_EMERG, PEAR_LOG_ALERT,
|
||||
* PEAR_LOG_CRIT, PEAR_LOG_ERR, PEAR_LOG_WARNING,
|
||||
* PEAR_LOG_NOTICE, PEAR_LOG_INFO, and PEAR_LOG_DEBUG.
|
||||
* @return boolean True on success or false on failure.
|
||||
* @access public
|
||||
*/
|
||||
function log($message, $priority = null)
|
||||
{
|
||||
/* If a priority hasn't been specified, use the default value. */
|
||||
if ($priority === null) {
|
||||
$priority = $this->_priority;
|
||||
}
|
||||
|
||||
/* Abort early if the priority is above the maximum logging level. */
|
||||
if (!$this->_isMasked($priority)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* If the connection isn't open and can't be opened, return failure. */
|
||||
if (!$this->_opened && !$this->open()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Extract the string representation of the message.
|
||||
$message = $this->_extractMessage($message);
|
||||
|
||||
// Build the SQL query for this log entry insertion.
|
||||
$q = sprintf('INSERT INTO [%s] (logtime, ident, priority, message) ' .
|
||||
"VALUES ('%s', '%s', %d, '%s')",
|
||||
$this->_table,
|
||||
strftime('%Y-%m-%d %H:%M:%S', time()),
|
||||
sqlite_escape_string($this->_ident),
|
||||
$priority,
|
||||
sqlite_escape_string($message));
|
||||
if (!($res = @sqlite_unbuffered_query($this->_db, $q))) {
|
||||
return false;
|
||||
}
|
||||
$this->_announce(array('priority' => $priority, 'message' => $message));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the log table exists and creates it if necessary.
|
||||
*
|
||||
* @return boolean True on success or false on failure.
|
||||
* @access private
|
||||
*/
|
||||
function _createTable()
|
||||
{
|
||||
$q = "SELECT name FROM sqlite_master WHERE name='" . $this->_table .
|
||||
"' AND type='table'";
|
||||
|
||||
$res = sqlite_query($this->_db, $q);
|
||||
|
||||
if (sqlite_num_rows($res) == 0) {
|
||||
$q = 'CREATE TABLE [' . $this->_table . '] (' .
|
||||
'id INTEGER PRIMARY KEY NOT NULL, ' .
|
||||
'logtime NOT NULL, ' .
|
||||
'ident CHAR(16) NOT NULL, ' .
|
||||
'priority INT NOT NULL, ' .
|
||||
'message)';
|
||||
|
||||
if (!($res = sqlite_unbuffered_query($this->_db, $q))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
160
egw-pear/Log/syslog.php
Normal file
160
egw-pear/Log/syslog.php
Normal file
@ -0,0 +1,160 @@
|
||||
<?php
|
||||
/**
|
||||
* $Header: /repository/pear/Log/Log/syslog.php,v 1.23 2005/02/26 14:48:59 chagenbu Exp $
|
||||
* $Horde: horde/lib/Log/syslog.php,v 1.6 2000/06/28 21:36:13 jon Exp $
|
||||
*
|
||||
* @version $Revision: 1.23 $
|
||||
* @package Log
|
||||
*/
|
||||
|
||||
/**
|
||||
* The Log_syslog class is a concrete implementation of the Log::
|
||||
* abstract class which sends messages to syslog on UNIX-like machines
|
||||
* (PHP emulates this with the Event Log on Windows machines).
|
||||
*
|
||||
* @author Chuck Hagenbuch <chuck@horde.org>
|
||||
* @since Horde 1.3
|
||||
* @since Log 1.0
|
||||
* @package Log
|
||||
*
|
||||
* @example syslog.php Using the syslog handler.
|
||||
*/
|
||||
class Log_syslog extends Log
|
||||
{
|
||||
/**
|
||||
* Integer holding the log facility to use.
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $_name = LOG_SYSLOG;
|
||||
|
||||
/**
|
||||
* Constructs a new syslog object.
|
||||
*
|
||||
* @param string $name The syslog facility.
|
||||
* @param string $ident The identity string.
|
||||
* @param array $conf The configuration array.
|
||||
* @param int $level Log messages up to and including this level.
|
||||
* @access public
|
||||
*/
|
||||
function Log_syslog($name, $ident = '', $conf = array(),
|
||||
$level = PEAR_LOG_DEBUG)
|
||||
{
|
||||
/* Ensure we have a valid integer value for $name. */
|
||||
if (empty($name) || !is_int($name)) {
|
||||
$name = LOG_SYSLOG;
|
||||
}
|
||||
|
||||
$this->_id = md5(microtime());
|
||||
$this->_name = $name;
|
||||
$this->_ident = $ident;
|
||||
$this->_mask = Log::UPTO($level);
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens a connection to the system logger, if it has not already
|
||||
* been opened. This is implicitly called by log(), if necessary.
|
||||
* @access public
|
||||
*/
|
||||
function open()
|
||||
{
|
||||
if (!$this->_opened) {
|
||||
openlog($this->_ident, LOG_PID, $this->_name);
|
||||
$this->_opened = true;
|
||||
}
|
||||
|
||||
return $this->_opened;
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the connection to the system logger, if it is open.
|
||||
* @access public
|
||||
*/
|
||||
function close()
|
||||
{
|
||||
if ($this->_opened) {
|
||||
closelog();
|
||||
$this->_opened = false;
|
||||
}
|
||||
|
||||
return ($this->_opened === false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends $message to the currently open syslog connection. Calls
|
||||
* open() if necessary. Also passes the message along to any Log_observer
|
||||
* instances that are observing this Log.
|
||||
*
|
||||
* @param mixed $message String or object containing the message to log.
|
||||
* @param int $priority (optional) The priority of the message. Valid
|
||||
* values are: PEAR_LOG_EMERG, PEAR_LOG_ALERT,
|
||||
* PEAR_LOG_CRIT, PEAR_LOG_ERR, PEAR_LOG_WARNING,
|
||||
* PEAR_LOG_NOTICE, PEAR_LOG_INFO, and PEAR_LOG_DEBUG.
|
||||
* @return boolean True on success or false on failure.
|
||||
* @access public
|
||||
*/
|
||||
function log($message, $priority = null)
|
||||
{
|
||||
/* If a priority hasn't been specified, use the default value. */
|
||||
if ($priority === null) {
|
||||
$priority = $this->_priority;
|
||||
}
|
||||
|
||||
/* Abort early if the priority is above the maximum logging level. */
|
||||
if (!$this->_isMasked($priority)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* If the connection isn't open and can't be opened, return failure. */
|
||||
if (!$this->_opened && !$this->open()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Extract the string representation of the message. */
|
||||
$message = $this->_extractMessage($message);
|
||||
|
||||
if (!syslog($this->_toSyslog($priority), $message)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->_announce(array('priority' => $priority, 'message' => $message));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a PEAR_LOG_* constant into a syslog LOG_* constant.
|
||||
*
|
||||
* This function exists because, under Windows, not all of the LOG_*
|
||||
* constants have unique values. Instead, the PEAR_LOG_* were introduced
|
||||
* for global use, with the conversion to the LOG_* constants kept local to
|
||||
* to the syslog driver.
|
||||
*
|
||||
* @param int $priority PEAR_LOG_* value to convert to LOG_* value.
|
||||
*
|
||||
* @return The LOG_* representation of $priority.
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
function _toSyslog($priority)
|
||||
{
|
||||
static $priorities = array(
|
||||
PEAR_LOG_EMERG => LOG_EMERG,
|
||||
PEAR_LOG_ALERT => LOG_ALERT,
|
||||
PEAR_LOG_CRIT => LOG_CRIT,
|
||||
PEAR_LOG_ERR => LOG_ERR,
|
||||
PEAR_LOG_WARNING => LOG_WARNING,
|
||||
PEAR_LOG_NOTICE => LOG_NOTICE,
|
||||
PEAR_LOG_INFO => LOG_INFO,
|
||||
PEAR_LOG_DEBUG => LOG_DEBUG
|
||||
);
|
||||
|
||||
/* If we're passed an unknown priority, default to LOG_INFO. */
|
||||
if (!is_int($priority) || !in_array($priority, $priorities)) {
|
||||
return LOG_INFO;
|
||||
}
|
||||
|
||||
return $priorities[$priority];
|
||||
}
|
||||
|
||||
}
|
269
egw-pear/Log/win.php
Normal file
269
egw-pear/Log/win.php
Normal file
@ -0,0 +1,269 @@
|
||||
<?php
|
||||
/**
|
||||
* $Header: /repository/pear/Log/Log/win.php,v 1.20 2006/07/26 05:21:47 jon Exp $
|
||||
*
|
||||
* @version $Revision: 1.20 $
|
||||
* @package Log
|
||||
*/
|
||||
|
||||
/**
|
||||
* The Log_win class is a concrete implementation of the Log abstract
|
||||
* class that logs messages to a separate browser window.
|
||||
*
|
||||
* The concept for this log handler is based on part by Craig Davis' article
|
||||
* entitled "JavaScript Power PHP Debugging:
|
||||
*
|
||||
* http://www.zend.com/zend/tut/tutorial-DebugLib.php
|
||||
*
|
||||
* @author Jon Parise <jon@php.net>
|
||||
* @since Log 1.7.0
|
||||
* @package Log
|
||||
*
|
||||
* @example win.php Using the window handler.
|
||||
*/
|
||||
class Log_win extends Log
|
||||
{
|
||||
/**
|
||||
* The name of the output window.
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $_name = 'LogWindow';
|
||||
|
||||
/**
|
||||
* The title of the output window.
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $_title = 'Log Output Window';
|
||||
|
||||
/**
|
||||
* Mapping of log priorities to styles.
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $_styles = array(
|
||||
PEAR_LOG_EMERG => 'color: red;',
|
||||
PEAR_LOG_ALERT => 'color: orange;',
|
||||
PEAR_LOG_CRIT => 'color: yellow;',
|
||||
PEAR_LOG_ERR => 'color: green;',
|
||||
PEAR_LOG_WARNING => 'color: blue;',
|
||||
PEAR_LOG_NOTICE => 'color: indigo;',
|
||||
PEAR_LOG_INFO => 'color: violet;',
|
||||
PEAR_LOG_DEBUG => 'color: black;'
|
||||
);
|
||||
|
||||
/**
|
||||
* String buffer that holds line that are pending output.
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $_buffer = array();
|
||||
|
||||
/**
|
||||
* Constructs a new Log_win object.
|
||||
*
|
||||
* @param string $name Ignored.
|
||||
* @param string $ident The identity string.
|
||||
* @param array $conf The configuration array.
|
||||
* @param int $level Log messages up to and including this level.
|
||||
* @access public
|
||||
*/
|
||||
function Log_win($name, $ident = '', $conf = array(),
|
||||
$level = PEAR_LOG_DEBUG)
|
||||
{
|
||||
$this->_id = md5(microtime());
|
||||
$this->_name = $name;
|
||||
$this->_ident = $ident;
|
||||
$this->_mask = Log::UPTO($level);
|
||||
|
||||
if (isset($conf['title'])) {
|
||||
$this->_title = $conf['title'];
|
||||
}
|
||||
if (isset($conf['styles']) && is_array($conf['styles'])) {
|
||||
$this->_styles = $conf['styles'];
|
||||
}
|
||||
if (isset($conf['colors']) && is_array($conf['colors'])) {
|
||||
foreach ($conf['colors'] as $level => $color) {
|
||||
$this->_styles[$level] .= "color: $color;";
|
||||
}
|
||||
}
|
||||
|
||||
register_shutdown_function(array(&$this, '_Log_win'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
function _Log_win()
|
||||
{
|
||||
if ($this->_opened || (count($this->_buffer) > 0)) {
|
||||
$this->close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The first time open() is called, it will open a new browser window and
|
||||
* prepare it for output.
|
||||
*
|
||||
* This is implicitly called by log(), if necessary.
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function open()
|
||||
{
|
||||
if (!$this->_opened) {
|
||||
$win = $this->_name;
|
||||
$styles = $this->_styles;
|
||||
|
||||
if (!empty($this->_ident)) {
|
||||
$identHeader = "$win.document.writeln('<th>Ident</th>')";
|
||||
} else {
|
||||
$identHeader = '';
|
||||
}
|
||||
|
||||
echo <<< EOT
|
||||
<script language="JavaScript">
|
||||
$win = window.open('', '{$this->_name}', 'toolbar=no,scrollbars,width=600,height=400');
|
||||
$win.document.writeln('<html>');
|
||||
$win.document.writeln('<head>');
|
||||
$win.document.writeln('<title>{$this->_title}</title>');
|
||||
$win.document.writeln('<style type="text/css">');
|
||||
$win.document.writeln('body { font-family: monospace; font-size: 8pt; }');
|
||||
$win.document.writeln('td,th { font-size: 8pt; }');
|
||||
$win.document.writeln('td,th { border-bottom: #999999 solid 1px; }');
|
||||
$win.document.writeln('td,th { border-right: #999999 solid 1px; }');
|
||||
$win.document.writeln('tr { text-align: left; vertical-align: top; }');
|
||||
$win.document.writeln('td.l0 { $styles[0] }');
|
||||
$win.document.writeln('td.l1 { $styles[1] }');
|
||||
$win.document.writeln('td.l2 { $styles[2] }');
|
||||
$win.document.writeln('td.l3 { $styles[3] }');
|
||||
$win.document.writeln('td.l4 { $styles[4] }');
|
||||
$win.document.writeln('td.l5 { $styles[5] }');
|
||||
$win.document.writeln('td.l6 { $styles[6] }');
|
||||
$win.document.writeln('td.l7 { $styles[7] }');
|
||||
$win.document.writeln('</style>');
|
||||
$win.document.writeln('</head>');
|
||||
$win.document.writeln('<body>');
|
||||
$win.document.writeln('<table border="0" cellpadding="2" cellspacing="0">');
|
||||
$win.document.writeln('<tr><th>Time</th>');
|
||||
$identHeader
|
||||
$win.document.writeln('<th>Priority</th><th width="100%">Message</th></tr>');
|
||||
</script>
|
||||
EOT;
|
||||
$this->_opened = true;
|
||||
}
|
||||
|
||||
return $this->_opened;
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the output stream if it is open. If there are still pending
|
||||
* lines in the output buffer, the output window will be opened so that
|
||||
* the buffer can be drained.
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function close()
|
||||
{
|
||||
/*
|
||||
* If there are still lines waiting to be written, open the output
|
||||
* window so that we can drain the buffer.
|
||||
*/
|
||||
if (!$this->_opened && (count($this->_buffer) > 0)) {
|
||||
$this->open();
|
||||
}
|
||||
|
||||
if ($this->_opened) {
|
||||
$this->_writeln('</table>');
|
||||
$this->_writeln('</body></html>');
|
||||
$this->_opened = false;
|
||||
}
|
||||
|
||||
return ($this->_opened === false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a single line of text to the output window.
|
||||
*
|
||||
* @param string $line The line of text to write.
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
function _writeln($line)
|
||||
{
|
||||
/* Add this line to our output buffer. */
|
||||
$this->_buffer[] = $line;
|
||||
|
||||
/* Buffer the output until this page's headers have been sent. */
|
||||
if (!headers_sent()) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* If we haven't already opened the output window, do so now. */
|
||||
if (!$this->_opened && !$this->open()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Drain the buffer to the output window. */
|
||||
$win = $this->_name;
|
||||
foreach ($this->_buffer as $line) {
|
||||
echo "<script language='JavaScript'>\n";
|
||||
echo "$win.document.writeln('" . addslashes($line) . "');\n";
|
||||
echo "self.focus();\n";
|
||||
echo "</script>\n";
|
||||
}
|
||||
|
||||
/* Now that the buffer has been drained, clear it. */
|
||||
$this->_buffer = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs $message to the output window. The message is also passed along
|
||||
* to any Log_observer instances that are observing this Log.
|
||||
*
|
||||
* @param mixed $message String or object containing the message to log.
|
||||
* @param string $priority The priority of the message. Valid
|
||||
* values are: PEAR_LOG_EMERG, PEAR_LOG_ALERT,
|
||||
* PEAR_LOG_CRIT, PEAR_LOG_ERR, PEAR_LOG_WARNING,
|
||||
* PEAR_LOG_NOTICE, PEAR_LOG_INFO, and PEAR_LOG_DEBUG.
|
||||
* @return boolean True on success or false on failure.
|
||||
* @access public
|
||||
*/
|
||||
function log($message, $priority = null)
|
||||
{
|
||||
/* If a priority hasn't been specified, use the default value. */
|
||||
if ($priority === null) {
|
||||
$priority = $this->_priority;
|
||||
}
|
||||
|
||||
/* Abort early if the priority is above the maximum logging level. */
|
||||
if (!$this->_isMasked($priority)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Extract the string representation of the message. */
|
||||
$message = $this->_extractMessage($message);
|
||||
$message = preg_replace('/\r\n|\n|\r/', '<br />', $message);
|
||||
|
||||
list($usec, $sec) = explode(' ', microtime());
|
||||
|
||||
/* Build the output line that contains the log entry row. */
|
||||
$line = '<tr>';
|
||||
$line .= sprintf('<td>%s.%s</td>',
|
||||
strftime('%H:%M:%S', $sec), substr($usec, 2, 2));
|
||||
if (!empty($this->_ident)) {
|
||||
$line .= '<td>' . $this->_ident . '</td>';
|
||||
}
|
||||
$line .= '<td>' . ucfirst($this->priorityToString($priority)) . '</td>';
|
||||
$line .= sprintf('<td class="l%d">%s</td>', $priority, $message);
|
||||
$line .= '</tr>';
|
||||
|
||||
$this->_writeln($line);
|
||||
|
||||
$this->_announce(array('priority' => $priority, 'message' => $message));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
2713
egw-pear/Net/IMAP.php
Normal file
2713
egw-pear/Net/IMAP.php
Normal file
File diff suppressed because it is too large
Load Diff
3325
egw-pear/Net/IMAPProtocol.php
Normal file
3325
egw-pear/Net/IMAPProtocol.php
Normal file
File diff suppressed because it is too large
Load Diff
1145
egw-pear/Net/Sieve.php
Normal file
1145
egw-pear/Net/Sieve.php
Normal file
File diff suppressed because it is too large
Load Diff
556
egw-pear/Net/Socket.php
Normal file
556
egw-pear/Net/Socket.php
Normal file
@ -0,0 +1,556 @@
|
||||
<?php
|
||||
//
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP Version 4 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1997-2003 The PHP Group |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | This source file is subject to version 2.0 of the PHP license, |
|
||||
// | that is bundled with this package in the file LICENSE, and is |
|
||||
// | available at through the world-wide-web at |
|
||||
// | http://www.php.net/license/2_02.txt. |
|
||||
// | If you did not receive a copy of the PHP license and are unable to |
|
||||
// | obtain it through the world-wide-web, please send a note to |
|
||||
// | license@php.net so we can mail you a copy immediately. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Authors: Stig Bakken <ssb@php.net> |
|
||||
// | Chuck Hagenbuch <chuck@horde.org> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id: Socket.php,v 1.28 2006/12/13 21:32:03 cweiske Exp $
|
||||
|
||||
require_once 'PEAR.php';
|
||||
|
||||
define('NET_SOCKET_READ', 1);
|
||||
define('NET_SOCKET_WRITE', 2);
|
||||
define('NET_SOCKET_ERROR', 4);
|
||||
|
||||
/**
|
||||
* Generalized Socket class.
|
||||
*
|
||||
* @version 1.1
|
||||
* @author Stig Bakken <ssb@php.net>
|
||||
* @author Chuck Hagenbuch <chuck@horde.org>
|
||||
*/
|
||||
class Net_Socket extends PEAR {
|
||||
|
||||
/**
|
||||
* Socket file pointer.
|
||||
* @var resource $fp
|
||||
*/
|
||||
var $fp = null;
|
||||
|
||||
/**
|
||||
* Whether the socket is blocking. Defaults to true.
|
||||
* @var boolean $blocking
|
||||
*/
|
||||
var $blocking = true;
|
||||
|
||||
/**
|
||||
* Whether the socket is persistent. Defaults to false.
|
||||
* @var boolean $persistent
|
||||
*/
|
||||
var $persistent = false;
|
||||
|
||||
/**
|
||||
* The IP address to connect to.
|
||||
* @var string $addr
|
||||
*/
|
||||
var $addr = '';
|
||||
|
||||
/**
|
||||
* The port number to connect to.
|
||||
* @var integer $port
|
||||
*/
|
||||
var $port = 0;
|
||||
|
||||
/**
|
||||
* Number of seconds to wait on socket connections before assuming
|
||||
* there's no more data. Defaults to no timeout.
|
||||
* @var integer $timeout
|
||||
*/
|
||||
var $timeout = false;
|
||||
|
||||
/**
|
||||
* Number of bytes to read at a time in readLine() and
|
||||
* readAll(). Defaults to 2048.
|
||||
* @var integer $lineLength
|
||||
*/
|
||||
var $lineLength = 2048;
|
||||
|
||||
/**
|
||||
* Connect to the specified port. If called when the socket is
|
||||
* already connected, it disconnects and connects again.
|
||||
*
|
||||
* @param string $addr IP address or host name.
|
||||
* @param integer $port TCP port number.
|
||||
* @param boolean $persistent (optional) Whether the connection is
|
||||
* persistent (kept open between requests
|
||||
* by the web server).
|
||||
* @param integer $timeout (optional) How long to wait for data.
|
||||
* @param array $options See options for stream_context_create.
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @return boolean | PEAR_Error True on success or a PEAR_Error on failure.
|
||||
*/
|
||||
function connect($addr, $port = 0, $persistent = null, $timeout = null, $options = null)
|
||||
{
|
||||
if (is_resource($this->fp)) {
|
||||
@fclose($this->fp);
|
||||
$this->fp = null;
|
||||
}
|
||||
|
||||
if (!$addr) {
|
||||
return $this->raiseError('$addr cannot be empty');
|
||||
} elseif (strspn($addr, '.0123456789') == strlen($addr) ||
|
||||
strstr($addr, '/') !== false) {
|
||||
$this->addr = $addr;
|
||||
} else {
|
||||
$this->addr = @gethostbyname($addr);
|
||||
}
|
||||
|
||||
$this->port = $port % 65536;
|
||||
|
||||
if ($persistent !== null) {
|
||||
$this->persistent = $persistent;
|
||||
}
|
||||
|
||||
if ($timeout !== null) {
|
||||
$this->timeout = $timeout;
|
||||
}
|
||||
|
||||
$errno = 0;
|
||||
$errstr = '';
|
||||
if ($options && function_exists('stream_socket_client')) {
|
||||
if ($this->timeout) {
|
||||
$timeout = $this->timeout;
|
||||
} else {
|
||||
$timeout = 0;
|
||||
}
|
||||
|
||||
$context = stream_context_create($options);
|
||||
$flags = ($this->persistent === true ? STREAM_CLIENT_CONNECT | STREAM_CLIENT_PERSISTENT : STREAM_CLIENT_CONNECT);
|
||||
$fp = @stream_socket_client($this->addr.':'.$this->port, $errno, $errstr, $timeout, $flags, $context);
|
||||
} else {
|
||||
$openfunc = $this->persistent ? 'pfsockopen' : 'fsockopen';
|
||||
if ($this->timeout) {
|
||||
$fp = @$openfunc($this->addr, $this->port, $errno, $errstr, $this->timeout);
|
||||
} else {
|
||||
$fp = @$openfunc($this->addr, $this->port, $errno, $errstr);
|
||||
}
|
||||
}
|
||||
|
||||
if (!$fp) {
|
||||
return $this->raiseError($errstr, $errno);
|
||||
}
|
||||
|
||||
$this->fp = $fp;
|
||||
|
||||
return $this->setBlocking($this->blocking);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disconnects from the peer, closes the socket.
|
||||
*
|
||||
* @access public
|
||||
* @return mixed true on success or an error object otherwise
|
||||
*/
|
||||
function disconnect()
|
||||
{
|
||||
if (!is_resource($this->fp)) {
|
||||
return $this->raiseError('not connected');
|
||||
}
|
||||
|
||||
@fclose($this->fp);
|
||||
$this->fp = null;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find out if the socket is in blocking mode.
|
||||
*
|
||||
* @access public
|
||||
* @return boolean The current blocking mode.
|
||||
*/
|
||||
function isBlocking()
|
||||
{
|
||||
return $this->blocking;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether the socket connection should be blocking or
|
||||
* not. A read call to a non-blocking socket will return immediately
|
||||
* if there is no data available, whereas it will block until there
|
||||
* is data for blocking sockets.
|
||||
*
|
||||
* @param boolean $mode True for blocking sockets, false for nonblocking.
|
||||
* @access public
|
||||
* @return mixed true on success or an error object otherwise
|
||||
*/
|
||||
function setBlocking($mode)
|
||||
{
|
||||
if (!is_resource($this->fp)) {
|
||||
return $this->raiseError('not connected');
|
||||
}
|
||||
|
||||
$this->blocking = $mode;
|
||||
socket_set_blocking($this->fp, $this->blocking);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the timeout value on socket descriptor,
|
||||
* expressed in the sum of seconds and microseconds
|
||||
*
|
||||
* @param integer $seconds Seconds.
|
||||
* @param integer $microseconds Microseconds.
|
||||
* @access public
|
||||
* @return mixed true on success or an error object otherwise
|
||||
*/
|
||||
function setTimeout($seconds, $microseconds)
|
||||
{
|
||||
if (!is_resource($this->fp)) {
|
||||
return $this->raiseError('not connected');
|
||||
}
|
||||
|
||||
return socket_set_timeout($this->fp, $seconds, $microseconds);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the file buffering size on the stream.
|
||||
* See php's stream_set_write_buffer for more information.
|
||||
*
|
||||
* @param integer $size Write buffer size.
|
||||
* @access public
|
||||
* @return mixed on success or an PEAR_Error object otherwise
|
||||
*/
|
||||
function setWriteBuffer($size)
|
||||
{
|
||||
if (!is_resource($this->fp)) {
|
||||
return $this->raiseError('not connected');
|
||||
}
|
||||
|
||||
$returned = stream_set_write_buffer($this->fp, $code);
|
||||
if ($returned == 0) {
|
||||
return true;
|
||||
}
|
||||
return $this->raiseError('Cannot set write buffer.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns information about an existing socket resource.
|
||||
* Currently returns four entries in the result array:
|
||||
*
|
||||
* <p>
|
||||
* timed_out (bool) - The socket timed out waiting for data<br>
|
||||
* blocked (bool) - The socket was blocked<br>
|
||||
* eof (bool) - Indicates EOF event<br>
|
||||
* unread_bytes (int) - Number of bytes left in the socket buffer<br>
|
||||
* </p>
|
||||
*
|
||||
* @access public
|
||||
* @return mixed Array containing information about existing socket resource or an error object otherwise
|
||||
*/
|
||||
function getStatus()
|
||||
{
|
||||
if (!is_resource($this->fp)) {
|
||||
return $this->raiseError('not connected');
|
||||
}
|
||||
|
||||
return socket_get_status($this->fp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a specified line of data
|
||||
*
|
||||
* @access public
|
||||
* @return $size bytes of data from the socket, or a PEAR_Error if
|
||||
* not connected.
|
||||
*/
|
||||
function gets($size)
|
||||
{
|
||||
if (!is_resource($this->fp)) {
|
||||
return $this->raiseError('not connected');
|
||||
}
|
||||
|
||||
return @fgets($this->fp, $size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a specified amount of data. This is guaranteed to return,
|
||||
* and has the added benefit of getting everything in one fread()
|
||||
* chunk; if you know the size of the data you're getting
|
||||
* beforehand, this is definitely the way to go.
|
||||
*
|
||||
* @param integer $size The number of bytes to read from the socket.
|
||||
* @access public
|
||||
* @return $size bytes of data from the socket, or a PEAR_Error if
|
||||
* not connected.
|
||||
*/
|
||||
function read($size)
|
||||
{
|
||||
if (!is_resource($this->fp)) {
|
||||
return $this->raiseError('not connected');
|
||||
}
|
||||
|
||||
return @fread($this->fp, $size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a specified amount of data.
|
||||
*
|
||||
* @param string $data Data to write.
|
||||
* @param integer $blocksize Amount of data to write at once.
|
||||
* NULL means all at once.
|
||||
*
|
||||
* @access public
|
||||
* @return mixed true on success or an error object otherwise
|
||||
*/
|
||||
function write($data, $blocksize = null)
|
||||
{
|
||||
if (!is_resource($this->fp)) {
|
||||
return $this->raiseError('not connected');
|
||||
}
|
||||
|
||||
if (is_null($blocksize) && !OS_WINDOWS) {
|
||||
return fwrite($this->fp, $data);
|
||||
} else {
|
||||
if (is_null($blocksize)) {
|
||||
$blocksize = 1024;
|
||||
}
|
||||
|
||||
$pos = 0;
|
||||
$size = strlen($data);
|
||||
while ($pos < $size) {
|
||||
$written = @fwrite($this->fp, substr($data, $pos, $blocksize));
|
||||
if ($written === false) {
|
||||
return false;
|
||||
}
|
||||
$pos += $written;
|
||||
}
|
||||
|
||||
return $pos;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a line of data to the socket, followed by a trailing "\r\n".
|
||||
*
|
||||
* @access public
|
||||
* @return mixed fputs result, or an error
|
||||
*/
|
||||
function writeLine($data)
|
||||
{
|
||||
if (!is_resource($this->fp)) {
|
||||
return $this->raiseError('not connected');
|
||||
}
|
||||
|
||||
return fwrite($this->fp, $data . "\r\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests for end-of-file on a socket descriptor.
|
||||
*
|
||||
* Also returns true if the socket is disconnected.
|
||||
*
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
function eof()
|
||||
{
|
||||
return (!is_resource($this->fp) || feof($this->fp));
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a byte of data
|
||||
*
|
||||
* @access public
|
||||
* @return 1 byte of data from the socket, or a PEAR_Error if
|
||||
* not connected.
|
||||
*/
|
||||
function readByte()
|
||||
{
|
||||
if (!is_resource($this->fp)) {
|
||||
return $this->raiseError('not connected');
|
||||
}
|
||||
|
||||
return ord(@fread($this->fp, 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a word of data
|
||||
*
|
||||
* @access public
|
||||
* @return 1 word of data from the socket, or a PEAR_Error if
|
||||
* not connected.
|
||||
*/
|
||||
function readWord()
|
||||
{
|
||||
if (!is_resource($this->fp)) {
|
||||
return $this->raiseError('not connected');
|
||||
}
|
||||
|
||||
$buf = @fread($this->fp, 2);
|
||||
return (ord($buf[0]) + (ord($buf[1]) << 8));
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads an int of data
|
||||
*
|
||||
* @access public
|
||||
* @return integer 1 int of data from the socket, or a PEAR_Error if
|
||||
* not connected.
|
||||
*/
|
||||
function readInt()
|
||||
{
|
||||
if (!is_resource($this->fp)) {
|
||||
return $this->raiseError('not connected');
|
||||
}
|
||||
|
||||
$buf = @fread($this->fp, 4);
|
||||
return (ord($buf[0]) + (ord($buf[1]) << 8) +
|
||||
(ord($buf[2]) << 16) + (ord($buf[3]) << 24));
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a zero-terminated string of data
|
||||
*
|
||||
* @access public
|
||||
* @return string, or a PEAR_Error if
|
||||
* not connected.
|
||||
*/
|
||||
function readString()
|
||||
{
|
||||
if (!is_resource($this->fp)) {
|
||||
return $this->raiseError('not connected');
|
||||
}
|
||||
|
||||
$string = '';
|
||||
while (($char = @fread($this->fp, 1)) != "\x00") {
|
||||
$string .= $char;
|
||||
}
|
||||
return $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads an IP Address and returns it in a dot formated string
|
||||
*
|
||||
* @access public
|
||||
* @return Dot formated string, or a PEAR_Error if
|
||||
* not connected.
|
||||
*/
|
||||
function readIPAddress()
|
||||
{
|
||||
if (!is_resource($this->fp)) {
|
||||
return $this->raiseError('not connected');
|
||||
}
|
||||
|
||||
$buf = @fread($this->fp, 4);
|
||||
return sprintf("%s.%s.%s.%s", ord($buf[0]), ord($buf[1]),
|
||||
ord($buf[2]), ord($buf[3]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Read until either the end of the socket or a newline, whichever
|
||||
* comes first. Strips the trailing newline from the returned data.
|
||||
*
|
||||
* @access public
|
||||
* @return All available data up to a newline, without that
|
||||
* newline, or until the end of the socket, or a PEAR_Error if
|
||||
* not connected.
|
||||
*/
|
||||
function readLine()
|
||||
{
|
||||
if (!is_resource($this->fp)) {
|
||||
return $this->raiseError('not connected');
|
||||
}
|
||||
|
||||
ob_start();
|
||||
$line = '';
|
||||
$timeout = time() + $this->timeout;
|
||||
while (!feof($this->fp) && (!$this->timeout || time() < $timeout)) {
|
||||
$line .= fgets($this->fp, $this->lineLength);
|
||||
if (substr($line, -1) == "\n") {
|
||||
ob_end_clean();
|
||||
return rtrim($line, "\r\n");
|
||||
}
|
||||
}
|
||||
ob_end_clean();
|
||||
return $line;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read until the socket closes, or until there is no more data in
|
||||
* the inner PHP buffer. If the inner buffer is empty, in blocking
|
||||
* mode we wait for at least 1 byte of data. Therefore, in
|
||||
* blocking mode, if there is no data at all to be read, this
|
||||
* function will never exit (unless the socket is closed on the
|
||||
* remote end).
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @return string All data until the socket closes, or a PEAR_Error if
|
||||
* not connected.
|
||||
*/
|
||||
function readAll()
|
||||
{
|
||||
if (!is_resource($this->fp)) {
|
||||
return $this->raiseError('not connected');
|
||||
}
|
||||
|
||||
$data = '';
|
||||
while (!feof($this->fp)) {
|
||||
$data .= @fread($this->fp, $this->lineLength);
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the equivalent of the select() system call on the socket
|
||||
* with a timeout specified by tv_sec and tv_usec.
|
||||
*
|
||||
* @param integer $state Which of read/write/error to check for.
|
||||
* @param integer $tv_sec Number of seconds for timeout.
|
||||
* @param integer $tv_usec Number of microseconds for timeout.
|
||||
*
|
||||
* @access public
|
||||
* @return False if select fails, integer describing which of read/write/error
|
||||
* are ready, or PEAR_Error if not connected.
|
||||
*/
|
||||
function select($state, $tv_sec, $tv_usec = 0)
|
||||
{
|
||||
if (!is_resource($this->fp)) {
|
||||
return $this->raiseError('not connected');
|
||||
}
|
||||
|
||||
$read = null;
|
||||
$write = null;
|
||||
$except = null;
|
||||
if ($state & NET_SOCKET_READ) {
|
||||
$read[] = $this->fp;
|
||||
}
|
||||
if ($state & NET_SOCKET_WRITE) {
|
||||
$write[] = $this->fp;
|
||||
}
|
||||
if ($state & NET_SOCKET_ERROR) {
|
||||
$except[] = $this->fp;
|
||||
}
|
||||
if (false === ($sr = stream_select($read, $write, $except, $tv_sec, $tv_usec))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$result = 0;
|
||||
if (count($read)) {
|
||||
$result |= NET_SOCKET_READ;
|
||||
}
|
||||
if (count($write)) {
|
||||
$result |= NET_SOCKET_WRITE;
|
||||
}
|
||||
if (count($except)) {
|
||||
$result |= NET_SOCKET_ERROR;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
}
|
58
egw-pear/setup/setup.inc.php
Normal file
58
egw-pear/setup/setup.inc.php
Normal file
@ -0,0 +1,58 @@
|
||||
<?php
|
||||
/**************************************************************************\
|
||||
* eGroupWare - egw-pear *
|
||||
* http://www.egroupware.org *
|
||||
* Author: lkneschke@egroupware.org *
|
||||
* -------------------------------------------- *
|
||||
* 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 *
|
||||
\**************************************************************************/
|
||||
/* $Id: setup.inc.php 21904 2006-06-20 23:07:03Z ralfbecker $ */
|
||||
|
||||
$setup_info['egw-pear']['name'] = 'egw-pear';
|
||||
$setup_info['egw-pear']['title'] = 'egw-pear';
|
||||
$setup_info['egw-pear']['version'] = '1.4.000';
|
||||
$setup_info['egw-pear']['app_order'] = 99;
|
||||
$setup_info['egw-pear']['enable'] = 2;
|
||||
|
||||
$setup_info['egw-pear']['author'] = 'Lars Kneschke';
|
||||
$setup_info['egw-pear']['license'] = 'LGPL';
|
||||
$setup_info['egw-pear']['description'] =
|
||||
'A place for PEAR modules modified for eGroupWare.';
|
||||
|
||||
$setup_info['egw-pear']['note'] =
|
||||
'This application is a place for PEAR modules used by eGroupWare, which are NOT YET available from pear,
|
||||
because we patched them somehow and the PEAR modules are not released upstream.
|
||||
This application is under the LGPL license because the GPL is not compatible with the PHP license.
|
||||
If the modules are available from PEAR they do NOT belong here anymore.';
|
||||
|
||||
$setup_info['egw-pear']['maintainer'] = array(
|
||||
'name' => 'Lars Kneschke',
|
||||
'email' => 'l.kneschke@metaways.de'
|
||||
);
|
||||
|
||||
// installation checks for egw-pear
|
||||
$setup_info['egw-pear']['check_install'] = array(
|
||||
// we need pear itself to be installed
|
||||
'' => array(
|
||||
'func' => 'pear_check',
|
||||
'from' => 'FeLaMiMail',
|
||||
),
|
||||
// Net_Socket is required from Net_IMAP & Net_Sieve
|
||||
'Net_Socket' => array(
|
||||
'func' => 'pear_check',
|
||||
'from' => 'FeLaMiMail',
|
||||
),
|
||||
);
|
||||
?>
|
Loading…
Reference in New Issue
Block a user