summaryrefslogtreecommitdiff
path: root/inc/io.php
diff options
context:
space:
mode:
authorGuy Brand <gb@unistra.fr>2015-08-10 10:03:27 +0200
committerGuy Brand <gb@unistra.fr>2015-08-10 10:03:27 +0200
commit53a57d16b9c741bb44099fd93bf79efa06796341 (patch)
tree24a90a50afe9325926c8ebaa2ed90f9fa093e5b9 /inc/io.php
parentcf6e6645c31a9f185cef3fb9452fb188882ede47 (diff)
parenta060d9973e7c1d5051f2cc426937881826e4972e (diff)
downloadrpg-53a57d16b9c741bb44099fd93bf79efa06796341.tar.gz
rpg-53a57d16b9c741bb44099fd93bf79efa06796341.tar.bz2
Merge branch master into stable
Diffstat (limited to 'inc/io.php')
-rw-r--r--inc/io.php273
1 files changed, 202 insertions, 71 deletions
diff --git a/inc/io.php b/inc/io.php
index 27a34b045..704c5b1a6 100644
--- a/inc/io.php
+++ b/inc/io.php
@@ -20,6 +20,7 @@ if(!defined('DOKU_INC')) die('meh.');
* @param string $id - a pageid, the namespace of that id will be tried to deleted
* @param string $basedir - the config name of the type to delete (datadir or mediadir usally)
* @return bool - true if at least one namespace was deleted
+ *
* @author Andreas Gohr <andi@splitbrain.org>
* @author Ben Coburn <btcoburn@silicodon.net>
*/
@@ -60,6 +61,11 @@ function io_sweepNS($id,$basedir='datadir'){
* $data[3] rev: The page revision, false for current wiki pages.
*
* @author Ben Coburn <btcoburn@silicodon.net>
+ *
+ * @param string $file filename
+ * @param string $id page id
+ * @param bool|int $rev revision timestamp
+ * @return string
*/
function io_readWikiPage($file, $id, $rev=false) {
if (empty($rev)) { $rev = false; }
@@ -69,7 +75,11 @@ function io_readWikiPage($file, $id, $rev=false) {
/**
* Callback adapter for io_readFile().
+ *
* @author Ben Coburn <btcoburn@silicodon.net>
+ *
+ * @param array $data event data
+ * @return string
*/
function _io_readWikiPage_action($data) {
if (is_array($data) && is_array($data[0]) && count($data[0])===2) {
@@ -88,19 +98,25 @@ function _io_readWikiPage_action($data) {
* be sure to set $clean to false!
*
* @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $file filename
+ * @param bool $clean
+ * @return string|bool the file contents or false on error
*/
function io_readFile($file,$clean=true){
$ret = '';
- if(@file_exists($file)){
+ if(file_exists($file)){
if(substr($file,-3) == '.gz'){
- $ret = join('',gzfile($file));
+ $ret = gzfile($file);
+ if(is_array($ret)) $ret = join('', $ret);
}else if(substr($file,-4) == '.bz2'){
$ret = bzfile($file);
}else{
$ret = file_get_contents($file);
}
}
- if($clean){
+ if($ret === null) return false;
+ if($ret !== false && $clean){
return cleanText($ret);
}else{
return $ret;
@@ -108,21 +124,44 @@ function io_readFile($file,$clean=true){
}
/**
* Returns the content of a .bz2 compressed file as string
+ *
* @author marcel senf <marcel@rucksackreinigung.de>
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $file filename
+ * @param bool $array return array of lines
+ * @return string|array|bool content or false on error
*/
-
-function bzfile($file){
+function bzfile($file, $array=false) {
$bz = bzopen($file,"r");
+ if($bz === false) return false;
+
+ if($array) $lines = array();
$str = '';
- while (!feof($bz)){
+ while (!feof($bz)) {
//8192 seems to be the maximum buffersize?
- $str = $str . bzread($bz,8192);
+ $buffer = bzread($bz,8192);
+ if(($buffer === false) || (bzerrno($bz) !== 0)) {
+ return false;
+ }
+ $str = $str . $buffer;
+ if($array) {
+ $pos = strpos($str, "\n");
+ while($pos !== false) {
+ $lines[] = substr($str, 0, $pos+1);
+ $str = substr($str, $pos+1);
+ $pos = strpos($str, "\n");
+ }
+ }
}
bzclose($bz);
+ if($array) {
+ if($str !== '') $lines[] = $str;
+ return $lines;
+ }
return $str;
}
-
/**
* Used to write out a DokuWiki page to file, and send IO_WIKIPAGE_WRITE events.
*
@@ -138,6 +177,12 @@ function bzfile($file){
* $data[3] rev: The page revision, false for current wiki pages.
*
* @author Ben Coburn <btcoburn@silicodon.net>
+ *
+ * @param string $file filename
+ * @param string $content
+ * @param string $id page id
+ * @param int|bool $rev timestamp of revision
+ * @return bool
*/
function io_writeWikiPage($file, $content, $id, $rev=false) {
if (empty($rev)) { $rev = false; }
@@ -149,6 +194,9 @@ function io_writeWikiPage($file, $content, $id, $rev=false) {
/**
* Callback adapter for io_saveFile().
* @author Ben Coburn <btcoburn@silicodon.net>
+ *
+ * @param array $data event data
+ * @return bool
*/
function _io_writeWikiPage_action($data) {
if (is_array($data) && is_array($data[0]) && count($data[0])===3) {
@@ -159,113 +207,147 @@ function _io_writeWikiPage_action($data) {
}
/**
- * Saves $content to $file.
- *
- * If the third parameter is set to true the given content
- * will be appended.
- *
- * Uses gzip if extension is .gz
- * and bz2 if extension is .bz2
+ * Internal function to save contents to a file.
*
* @author Andreas Gohr <andi@splitbrain.org>
- * @return bool true on success
+ *
+ * @param string $file filename path to file
+ * @param string $content
+ * @param bool $append
+ * @return bool true on success, otherwise false
*/
-function io_saveFile($file,$content,$append=false){
+function _io_saveFile($file, $content, $append) {
global $conf;
$mode = ($append) ? 'ab' : 'wb';
+ $fileexists = file_exists($file);
- $fileexists = @file_exists($file);
- io_makeFileDir($file);
- io_lock($file);
if(substr($file,-3) == '.gz'){
$fh = @gzopen($file,$mode.'9');
- if(!$fh){
- msg("Writing $file failed",-1);
- io_unlock($file);
- return false;
- }
+ if(!$fh) return false;
gzwrite($fh, $content);
gzclose($fh);
}else if(substr($file,-4) == '.bz2'){
- $fh = @bzopen($file,$mode{0});
- if(!$fh){
- msg("Writing $file failed", -1);
- io_unlock($file);
- return false;
+ if($append) {
+ $bzcontent = bzfile($file);
+ if($bzcontent === false) return false;
+ $content = $bzcontent.$content;
}
+ $fh = @bzopen($file,'w');
+ if(!$fh) return false;
bzwrite($fh, $content);
bzclose($fh);
}else{
$fh = @fopen($file,$mode);
- if(!$fh){
- msg("Writing $file failed",-1);
- io_unlock($file);
- return false;
- }
+ if(!$fh) return false;
fwrite($fh, $content);
fclose($fh);
}
if(!$fileexists and !empty($conf['fperm'])) chmod($file, $conf['fperm']);
- io_unlock($file);
return true;
}
/**
- * Delete exact linematch for $badline from $file.
+ * Saves $content to $file.
*
- * Be sure to include the trailing newline in $badline
+ * If the third parameter is set to true the given content
+ * will be appended.
*
* Uses gzip if extension is .gz
+ * and bz2 if extension is .bz2
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $file filename path to file
+ * @param string $content
+ * @param bool $append
+ * @return bool true on success, otherwise false
+ */
+function io_saveFile($file, $content, $append=false) {
+ io_makeFileDir($file);
+ io_lock($file);
+ if(!_io_saveFile($file, $content, $append)) {
+ msg("Writing $file failed",-1);
+ io_unlock($file);
+ return false;
+ }
+ io_unlock($file);
+ return true;
+}
+
+/**
+ * Replace one or more occurrences of a line in a file.
+ *
+ * The default, when $maxlines is 0 is to delete all matching lines then append a single line.
+ * A regex that matches any part of the line will remove the entire line in this mode.
+ * Captures in $newline are not available.
*
- * 2005-10-14 : added regex option -- Christopher Smith <chris@jalakai.co.uk>
+ * Otherwise each line is matched and replaced individually, up to the first $maxlines lines
+ * or all lines if $maxlines is -1. If $regex is true then captures can be used in $newline.
+ *
+ * Be sure to include the trailing newline in $oldline when replacing entire lines.
+ *
+ * Uses gzip if extension is .gz
+ * and bz2 if extension is .bz2
*
* @author Steven Danz <steven-danz@kc.rr.com>
+ * @author Christopher Smith <chris@jalakai.co.uk>
+ * @author Patrick Brown <ptbrown@whoopdedo.org>
+ *
+ * @param string $file filename
+ * @param string $oldline exact linematch to remove
+ * @param string $newline new line to insert
+ * @param bool $regex use regexp?
+ * @param int $maxlines number of occurrences of the line to replace
* @return bool true on success
*/
-function io_deleteFromFile($file,$badline,$regex=false){
- if (!@file_exists($file)) return true;
+function io_replaceInFile($file, $oldline, $newline, $regex=false, $maxlines=0) {
+ if ((string)$oldline === '') {
+ trigger_error('$oldline parameter cannot be empty in io_replaceInFile()', E_USER_WARNING);
+ return false;
+ }
+
+ if (!file_exists($file)) return true;
io_lock($file);
// load into array
if(substr($file,-3) == '.gz'){
$lines = gzfile($file);
+ }else if(substr($file,-4) == '.bz2'){
+ $lines = bzfile($file, true);
}else{
$lines = file($file);
}
- // remove all matching lines
- if ($regex) {
- $lines = preg_grep($badline,$lines,PREG_GREP_INVERT);
- } else {
- $pos = array_search($badline,$lines); //return null or false if not found
- while(is_int($pos)){
- unset($lines[$pos]);
- $pos = array_search($badline,$lines);
+ // make non-regexes into regexes
+ $pattern = $regex ? $oldline : '/^'.preg_quote($oldline,'/').'$/';
+ $replace = $regex ? $newline : addcslashes($newline, '\$');
+
+ // remove matching lines
+ if ($maxlines > 0) {
+ $count = 0;
+ $matched = 0;
+ while (($count < $maxlines) && (list($i,$line) = each($lines))) {
+ // $matched will be set to 0|1 depending on whether pattern is matched and line replaced
+ $lines[$i] = preg_replace($pattern, $replace, $line, -1, $matched);
+ if ($matched) $count++;
+ }
+ } else if ($maxlines == 0) {
+ $lines = preg_grep($pattern, $lines, PREG_GREP_INVERT);
+
+ if ((string)$newline !== ''){
+ $lines[] = $newline;
}
+ } else {
+ $lines = preg_replace($pattern, $replace, $lines);
}
if(count($lines)){
- $content = join('',$lines);
- if(substr($file,-3) == '.gz'){
- $fh = @gzopen($file,'wb9');
- if(!$fh){
- msg("Removing content from $file failed",-1);
- io_unlock($file);
- return false;
- }
- gzwrite($fh, $content);
- gzclose($fh);
- }else{
- $fh = @fopen($file,'wb');
- if(!$fh){
- msg("Removing content from $file failed",-1);
- io_unlock($file);
- return false;
- }
- fwrite($fh, $content);
- fclose($fh);
+ if(!_io_saveFile($file, join('',$lines), false)) {
+ msg("Removing content from $file failed",-1);
+ io_unlock($file);
+ return false;
}
}else{
@unlink($file);
@@ -276,6 +358,22 @@ function io_deleteFromFile($file,$badline,$regex=false){
}
/**
+ * Delete lines that match $badline from $file.
+ *
+ * Be sure to include the trailing newline in $badline
+ *
+ * @author Patrick Brown <ptbrown@whoopdedo.org>
+ *
+ * @param string $file filename
+ * @param string $badline exact linematch to remove
+ * @param bool $regex use regexp?
+ * @return bool true on success
+ */
+function io_deleteFromFile($file,$badline,$regex=false){
+ return io_replaceInFile($file,$badline,null,$regex,0);
+}
+
+/**
* Tries to lock a file
*
* Locking is only done for io_savefile and uses directories
@@ -285,6 +383,8 @@ function io_deleteFromFile($file,$badline,$regex=false){
* the lock is assumed to be stale and the function goes on
*
* @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $file filename
*/
function io_lock($file){
global $conf;
@@ -311,6 +411,8 @@ function io_lock($file){
* Unlocks a file
*
* @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $file filename
*/
function io_unlock($file){
global $conf;
@@ -331,6 +433,9 @@ function io_unlock($file){
* $data[1] ns_type: 'pages' or 'media' namespace tree.
*
* @author Ben Coburn <btcoburn@silicodon.net>
+ *
+ * @param string $id page id
+ * @param string $ns_type 'pages' or 'media'
*/
function io_createNamespace($id, $ns_type='pages') {
// verify ns_type
@@ -344,7 +449,7 @@ function io_createNamespace($id, $ns_type='pages') {
$ns_stack = explode(':', $id);
$ns = $id;
$tmp = dirname( $file = call_user_func($types[$ns_type], $ns) );
- while (!@is_dir($tmp) && !(@file_exists($tmp) && !is_dir($tmp))) {
+ while (!@is_dir($tmp) && !(file_exists($tmp) && !is_dir($tmp))) {
array_pop($ns_stack);
$ns = implode(':', $ns_stack);
if (strlen($ns)==0) { break; }
@@ -365,6 +470,8 @@ function io_createNamespace($id, $ns_type='pages') {
* Create the directory needed for the given file
*
* @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $file file name
*/
function io_makeFileDir($file){
$dir = dirname($file);
@@ -379,11 +486,14 @@ function io_makeFileDir($file){
* @link http://www.php.net/manual/en/function.mkdir.php
* @author <saint@corenova.com>
* @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $target filename
+ * @return bool|int|string
*/
function io_mkdir_p($target){
global $conf;
if (@is_dir($target)||empty($target)) return 1; // best case check first
- if (@file_exists($target) && !is_dir($target)) return 0;
+ if (file_exists($target) && !is_dir($target)) return 0;
//recursion
if (io_mkdir_p(substr($target,0,strrpos($target,'/')))){
if($conf['safemodehack']){
@@ -454,6 +564,9 @@ function io_rmdir($path, $removefiles = false) {
* This is used when the safemode workaround is enabled
*
* @author <andi@splitbrain.org>
+ *
+ * @param string $dir name of the new directory
+ * @return false|string
*/
function io_mkdir_ftp($dir){
global $conf;
@@ -488,6 +601,8 @@ function io_mkdir_ftp($dir){
* its path.
*
* @author Michael Klier <chi@chimeric.de>
+ *
+ * @return false|string path to new directory or false
*/
function io_mktmpdir() {
global $conf;
@@ -516,6 +631,13 @@ function io_mktmpdir() {
*
* @author Andreas Gohr <andi@splitbrain.org>
* @author Chris Smith <chris@jalakai.co.uk>
+ *
+ * @param string $url url to download
+ * @param string $file path to file or directory where to save
+ * @param bool $useAttachment if true: try to use name of download, uses otherwise $defaultName, false: uses $file as path to file
+ * @param string $defaultName fallback for if using $useAttachment
+ * @param int $maxSize maximum file size
+ * @return bool|string if failed false, otherwise true or the name of the file in the given dir
*/
function io_download($url,$file,$useAttachment=false,$defaultName='',$maxSize=2097152){
global $conf;
@@ -548,7 +670,7 @@ function io_download($url,$file,$useAttachment=false,$defaultName='',$maxSize=20
$file = $file.$name;
}
- $fileexists = @file_exists($file);
+ $fileexists = file_exists($file);
$fp = @fopen($file,"w");
if(!$fp) return false;
fwrite($fp,$data);
@@ -563,6 +685,10 @@ function io_download($url,$file,$useAttachment=false,$defaultName='',$maxSize=20
*
* rename() can not overwrite existing files on Windows
* this function will use copy/unlink instead
+ *
+ * @param string $from
+ * @param string $to
+ * @return bool succes or fail
*/
function io_rename($from,$to){
global $conf;
@@ -582,6 +708,11 @@ function io_rename($from,$to){
* Returns the exit code from the process.
*
* @author Tom N Harris <tnharris@whoopdedo.org>
+ *
+ * @param string $cmd
+ * @param string $input input pipe
+ * @param string $output output pipe
+ * @return int exit code from process
*/
function io_exec($cmd, $input, &$output){
$descspec = array(