Page Menu
Home
Code
Search
Configure Global Search
Log In
Files
F880987
util.inc.php
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
11 KB
Subscribers
None
util.inc.php
View Options
<?php
/**
* util.inc.php
* Static utility functions
*
* Copyright Gottfried Haider, Danja Vasiliev 2010.
* This source code is licensed under the GNU General Public License.
* See the file COPYING for more details.
*/
/**
* convert an associative array to a javascript block
*
* @param array $container container array
* @return string
*/
function
array_to_js
(
$container
)
{
$ret
=
'<script type="text/javascript">'
.
nl
();
// sort container by keys
ksort
(
$container
);
$exists
=
array
();
foreach
(
$container
as
$key
=>
$val
)
{
// make sure the keys exist
$objs
=
expl
(
'.'
,
$key
);
for
(
$i
=
0
;
$i
<
count
(
$objs
)-
1
;
$i
++)
{
$obj
=
implode
(
'.'
,
array_slice
(
$objs
,
0
,
$i
+
1
));
if
(!
in_array
(
$obj
,
$exists
))
{
if
(
$i
==
0
)
{
$ret
.=
tab
().
'var '
.
$obj
.
' = '
.
$obj
.
' || {};'
.
nl
();
}
else
{
$ret
.=
tab
().
$obj
.
' = '
.
$obj
.
' || {};'
.
nl
();
}
$exists
[]
=
$obj
;
}
}
$ret
.=
tab
().
''
.
$key
.
' = '
.
json_encode
(
$val
).
';'
.
nl
();
}
$ret
.=
'</script>'
.
nl
();
return
$ret
;
}
/**
* make an array off associative array unique in a certain key-value
*
* @param array &$a reference to array
* @param mixed $key key whose value we compare
*/
function
array_unique_element
(&
$a
,
$key
)
{
// for each row
for
(
$cur
=
0
;
$cur
<
count
(
$a
);
$cur
++)
{
// look in every row further down
for
(
$i
=
$cur
+
1
;
$i
<
count
(
$a
);
$i
++)
{
// to see if the value of a key in the array is the same as in the
// current row
if
(
$a
[
$i
][
$key
]
==
$a
[
$cur
][
$key
])
{
// delete the row further down
array_splice
(
$a
,
$i
,
1
);
$i
--;
}
}
}
}
/**
* check if a directory already contains a file (based on its content)
*
* @param string $dir directory to check
* @param string $fn file to look for
* @param string $orig_fn first check this filename (optional)
* @return (basename) filename of identical file in $dir or false if
* there is none
*/
function
dir_has_same_file
(
$dir
,
$fn
,
$orig_fn
=
''
)
{
// strip any slash at the end of $dir
if
(
substr
(
$dir
,
-
1
)
==
'/'
)
{
$dir
=
substr
(
$dir
,
0
,
-
1
);
}
if
(
empty
(
$orig_fn
))
{
$orig_fn
=
basename
(
$fn
);
}
else
{
$orig_fn
=
basename
(
$orig_fn
);
}
if
((
$dir_fns
=
@
scandir
(
$dir
))
===
false
)
{
return
false
;
}
// optimization: check $orig_fn first
if
((
$i
=
array_search
(
$orig_fn
,
$dir_fns
))
!==
false
)
{
$a
=
array_splice
(
$dir_fns
,
$i
,
1
);
array_unshift
(
$dir_fns
,
$a
[
0
]);
}
foreach
(
$dir_fns
as
$f
)
{
if
(
$f
==
'.'
||
$f
==
'..'
)
{
continue
;
}
if
(!
file_is_different
(
$fn
,
$dir
.
'/'
.
$f
))
{
return
$f
;
}
}
return
false
;
}
/**
* check if two directories are different
*
* @param string $a filename
* @param string $b filename
* @return bool
*/
function
dir_is_different
(
$a
,
$b
)
{
if
(
substr
(
$a
,
-
1
)
==
'/'
)
{
$a
=
substr
(
$a
,
0
,
-
1
);
}
if
(
substr
(
$b
,
-
1
)
==
'/'
)
{
$b
=
substr
(
$b
,
0
,
-
1
);
}
$a_fns
=
@
scandir
(
$a
);
$b_fns
=
@
scandir
(
$b
);
if
(
$a_fns
!==
$b_fns
)
{
return
true
;
}
foreach
(
$a_fns
as
$fn
)
{
if
(
$fn
==
'.'
||
$fn
==
'..'
)
{
continue
;
}
if
(
is_dir
(
$a
.
'/'
.
$fn
)
||
is_dir
(
$b
.
'/'
.
$fn
))
{
if
(
dir_is_different
(
$a
.
'/'
.
$fn
,
$b
.
'/'
.
$fn
))
{
return
true
;
}
}
else
{
if
(
file_is_different
(
$a
.
'/'
.
$fn
,
$b
.
'/'
.
$fn
))
{
return
true
;
}
}
}
return
false
;
}
/**
* split a string by string
*
* like php's explode() but handles empty strings better.
* @param string $delimiter boundary string
* @param string $string input string
* @return array
*/
function
expl
(
$delimiter
,
$string
)
{
$ret
=
explode
(
$delimiter
,
$string
);
if
(
count
(
$ret
)
==
1
&&
empty
(
$ret
[
0
]))
{
return
array
();
}
else
{
return
$ret
;
}
}
/**
* explode a string splitting it by whitespace characters
*
* @param string $s input string
* @param bool $honor_quot don't split inside quotation marks
* @return array of strings
*/
function
expl_whitesp
(
$s
,
$honor_quot
=
false
)
{
// same characters as trim() uses
$whitesp
=
array
(
' '
,
"
\t
"
,
"
\n
"
,
"
\r
"
,
"
\0
"
,
"
\x
0B"
);
$quot
=
array
(
'"'
,
"'"
);
$ret
=
array
();
$prev
=
-
1
;
$cur_quot
=
false
;
for
(
$i
=
0
;
$i
<
strlen
(
$s
);
$i
++)
{
if
(
$honor_quot
&&
in_array
(
$s
[
$i
],
$quot
))
{
if
(
$cur_quot
===
false
)
{
// begin of quote
$cur_quot
=
$s
[
$i
];
}
elseif
(
$cur_quot
==
$s
[
$i
]
&&
(
$i
<
1
||
$s
[
$i
-
1
]
!=
"
\\
"
))
{
// end of quote
$cur_quot
=
false
;
}
}
if
(
$cur_quot
!==
false
)
{
// do nothing while on a quote
continue
;
}
if
(
in_array
(
$s
[
$i
],
$whitesp
))
{
if
(
$prev
+
1
==
$i
)
{
$prev
++;
}
else
{
$ret
[]
=
substr
(
$s
,
$prev
+
1
,
$i
-
$prev
-
1
);
$prev
=
$i
;
}
}
}
if
(
$prev
+
2
<
$i
)
{
$ret
[]
=
substr
(
$s
,
$prev
+
1
);
}
return
$ret
;
}
/**
* check if two files are different
*
* @param string $a filename
* @param string $b filename
* @return bool
*/
function
file_is_different
(
$a
,
$b
)
{
if
(@
filesize
(
$a
)
!==
@
filesize
(
$b
))
{
return
true
;
}
if
(@
md5_file
(
$a
)
!==
@
md5_file
(
$b
))
{
return
true
;
}
else
{
return
false
;
}
}
/**
* get the extension of a file
*
* @param string $s filename
* @return string
*/
function
filext
(
$s
)
{
$a
=
expl
(
'.'
,
$s
);
if
(
1
<
count
(
$a
))
{
return
(
array_pop
(
$a
));
}
else
{
return
''
;
}
}
/**
* return a error 400 message to the client
*
* this function doesn't return.
*/
function
http_400
()
{
// TODO (listed): we need hotglue theming here
// TODO (later): turn this into http_error()
header
(
$_SERVER
[
'SERVER_PROTOCOL'
].
' 400 Bad Request'
);
echo
'Bad Request'
;
die
();
}
/**
* return a error 404 message to the client
*
* this function doesn't return.
*/
function
http_404
()
{
// TODO (listed): we need hotglue theming here
// TODO (later): turn this into http_error()
header
(
$_SERVER
[
'SERVER_PROTOCOL'
].
' 404 Not Found'
);
echo
'Not Found'
;
die
();
}
/**
* return a error 500 message to the client
*
* this function doesn't return.
*/
function
http_500
()
{
// TODO (listed): we need hotglue theming here
// TODO (later): turn this into http_error()
header
(
$_SERVER
[
'SERVER_PROTOCOL'
].
' 500 Internal Server Error'
);
echo
'Internal Server Error'
;
die
();
}
/**
* check if the user is http digest authenticated
*
* @param array $users array of possible users (usernames as keys,
* password as values)
* @param string $realm realm (e.g. name of the site)
* @retval 0 authenticated
* @retval -1 user did not request authentication
* @retval -2 parts of the response are missing
* @retval -3 unknown username
* @retval -4 invalid password
*/
function
http_digest_check
(
$users
,
$realm
=
''
)
{
// code based on the php documentation
if
(
empty
(
$_SERVER
[
'PHP_AUTH_DIGEST'
]))
{
return
-
1
;
}
else
{
$auth
=
$_SERVER
[
'PHP_AUTH_DIGEST'
];
}
// taken from one of the comments
$data
=
array
();
preg_match
(
"/username=
\"
([^
\"
]+)
\"
/i"
,
$auth
,
$match
);
if
(
isset
(
$match
[
1
]))
{
$data
[
'username'
]
=
$match
[
1
];
}
else
{
return
-
2
;
}
preg_match
(
'/nonce=
\"
([^
\"
]+)
\"
/i'
,
$auth
,
$match
);
if
(
isset
(
$match
[
1
]))
{
$data
[
'nonce'
]
=
$match
[
1
];
}
else
{
return
-
2
;
}
preg_match
(
'/nc=([0-9a-f]+)/i'
,
$auth
,
$match
);
if
(
isset
(
$match
[
1
]))
{
$data
[
'nc'
]
=
$match
[
1
];
}
else
{
return
-
2
;
}
preg_match
(
'/cnonce=
\"
([^
\"
]+)
\"
/i'
,
$auth
,
$match
);
if
(
isset
(
$match
[
1
]))
{
$data
[
'cnonce'
]
=
$match
[
1
];
}
else
{
return
-
2
;
}
// fixed for Safari
// qop comes as qop="auth"
preg_match
(
'/qop=
\"
?([^,
\"
]+)/i'
,
$auth
,
$match
);
if
(
isset
(
$match
[
1
]))
{
$data
[
'qop'
]
=
$match
[
1
];
}
else
{
return
-
2
;
}
preg_match
(
'/uri=
\"
([^
\"
]+)
\"
/i'
,
$auth
,
$match
);
if
(
isset
(
$match
[
1
]))
{
$data
[
'uri'
]
=
$match
[
1
];
}
else
{
return
-
2
;
}
preg_match
(
'/response=
\"
([^
\"
]+)
\"
/i'
,
$auth
,
$match
);
if
(
isset
(
$match
[
1
]))
{
$data
[
'response'
]
=
$match
[
1
];
}
else
{
return
-
2
;
}
// check username
if
(!
array_key_exists
(
$data
[
'username'
],
$users
))
{
return
-
3
;
}
// generate the valid response
$a1
=
md5
(
$data
[
'username'
].
':'
.
str_replace
(
"
\"
"
,
''
,
$realm
).
':'
.
$users
[
$data
[
'username'
]]);
$a2
=
md5
(
$_SERVER
[
'REQUEST_METHOD'
].
':'
.
$data
[
'uri'
]);
$valid_response
=
md5
(
$a1
.
':'
.
$data
[
'nonce'
].
':'
.
$data
[
'nc'
].
':'
.
$data
[
'cnonce'
].
':'
.
$data
[
'qop'
].
':'
.
$a2
);
if
(
$data
[
'response'
]
!=
$valid_response
)
{
return
-
4
;
}
else
{
return
0
;
}
}
/**
* prompt the user for http digest authentication
*
* make sure the script stops execution after calling this function.
* @param string $realm realm (e.g. name of the site)
*/
function
http_digest_prompt
(
$realm
=
''
)
{
// code based on the php documentation
header
(
$_SERVER
[
'SERVER_PROTOCOL'
].
' 401 Unauthorized'
);
header
(
'WWW-Authenticate: Digest realm="'
.
str_replace
(
"
\"
"
,
''
,
$realm
).
'",qop="auth",nonce="'
.
uniqid
().
'",opaque="'
.
md5
(
str_replace
(
"
\"
"
,
''
,
$realm
)).
'"'
);
}
/**
* check if a string is a url
*
* @param string $s
* @return bool
*/
function
is_url
(
$s
)
{
if
(
strpos
(
$s
,
'://'
))
{
return
true
;
}
else
{
return
false
;
}
}
/**
* return a number of newline characters
*
* @param int $count count (one is default)
* @return string
*/
function
nl
(
$count
=
1
)
{
$s
=
''
;
while
(
0
<
$count
--)
{
$s
.=
"
\n
"
;
}
return
$s
;
}
/**
* pad a string to have at least $num characters
*
* @param string $s string to operate on
* @param int $num number of characters desired
* @param string $chr character to pad the string with
* @return string
*/
function
pad
(
$s
,
$num
,
$chr
=
' '
)
{
for
(
$i
=
strlen
(
$s
);
$i
<
$num
;
$i
++)
{
$s
.=
$chr
;
}
return
$s
;
}
/**
* return a string with double quotation marks wrapped around
*
* @param string $s string
* @return string
*/
function
quot
(
$s
)
{
return
'"'
.
$s
.
'"'
;
}
/**
* serve a file to the client
*
* this function only returns on errors.
* @param string $fn filename
* @param bool $dl download file
* @param string $mime mime type
*/
function
serve_file
(
$fn
,
$dl
,
$mime
)
{
if
((
$size
=
@
filesize
(
$fn
))
===
false
)
{
return
false
;
}
if
(
empty
(
$mime
))
{
// fall back to octet-stream
$mime
=
'application/octet-stream'
;
}
// TODO (later): optionally set the mime type based on the file extension only
// see http://www.php.net/manual/en/function.readfile.php#52722
// TODO (later): handle byte range
// TODO (later): handle if-modified-since etc
// TODO (later): also check apache_request_headers()
if
(
$dl
)
{
// these are taken from the php documentation (on readfile())
header
(
'Content-Description: File Transfer'
);
header
(
'Content-Type: application/octet-stream'
);
header
(
'Content-Disposition: attachment; filename='
.
basename
(
$fn
));
header
(
'Content-Transfer-Encoding: binary'
);
}
else
{
header
(
'Content-Type: '
.
$mime
);
}
header
(
'Content-Length: '
.
$size
);
flush
();
@
readfile
(
$fn
);
die
();
}
/**
* return a number of tab characters
*
* @param int $count count (one is default)
* @return string
*/
function
tab
(
$count
=
1
)
{
$s
=
''
;
while
(
0
<
$count
--)
{
$s
.=
"
\t
"
;
}
return
$s
;
}
/**
* find a unique filename for copying a file to destination directory
*
* @param string $dir destination directory
* @param string $orig_fn original filename
* @return string (basename) proposed filename
*/
function
unique_filename
(
$dir
,
$orig_fn
)
{
// strip any slash at the end of $dir
if
(
substr
(
$dir
,
-
1
)
==
'/'
)
{
$dir
=
substr
(
$dir
,
0
,
-
1
);
}
$fn
=
basename
(
$orig_fn
);
$num
=
1
;
// is_link() is there to catch dangling symlinks
while
(
is_file
(
$dir
.
'/'
.
$fn
)
||
is_dir
(
$dir
.
'/'
.
$fn
)
||
is_link
(
$dir
.
'/'
.
$fn
))
{
// find first dot and prepend _$num there
// TODO (later): we could handle the case where $orig_fn is already
// something like foo_2.bar
$fn
=
basename
(
$orig_fn
);
if
((
$p
=
strpos
(
$fn
,
'.'
))
!==
false
)
{
$fn
=
substr
(
$fn
,
0
,
$p
).
'_'
.(++
$num
).
substr
(
$fn
,
$p
);
}
else
{
$fn
.=
'_'
.(++
$num
);
}
}
return
$fn
;
}
/**
* print human-readable information about a variable in inline format
*
* @param mixed $var variable
* @return string
*/
function
var_dump_inl
(
$var
)
{
// print_r returns true/false as '1'/''
// fix this at least for the value of $var itself
if
(
is_bool
(
$var
)
&&
$var
)
{
return
'true'
;
}
elseif
(
is_bool
(
$var
))
{
return
'false'
;
}
$ret
=
print_r
(
$var
,
true
);
// remove control characters
$ret
=
str_replace
(
"
\n
"
,
' '
,
$ret
);
$ret
=
str_replace
(
"
\r
"
,
' '
,
$ret
);
$ret
=
str_replace
(
"
\t
"
,
' '
,
$ret
);
// remove double spaces
do
{
$ret
=
str_replace
(
' '
,
' '
,
$ret
,
$cnt
);
}
while
(
0
<
$cnt
);
return
trim
(
$ret
);
}
?>
File Metadata
Details
Attached
Mime Type
text/x-php
Expires
Apr 2 2025, 03:09 (4 w, 3 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
22095
Default Alt Text
util.inc.php (11 KB)
Attached To
rZED Zed
Event Timeline
Log In to Comment