summaryrefslogtreecommitdiffstats
path: root/wp-admin/includes
diff options
context:
space:
mode:
authordonncha <donncha@7be80a69-a1ef-0310-a953-fb0f7c49ff36>2008-03-19 12:35:25 +0000
committerdonncha <donncha@7be80a69-a1ef-0310-a953-fb0f7c49ff36>2008-03-19 12:35:25 +0000
commit50b00028bd207f461d6ed02f7868eccb5c6b8fe1 (patch)
tree003311f94f815dddbc39f91ba25b959f6ef18524 /wp-admin/includes
parent63f0f49bde74f02cdfc79140a7f101173f33322b (diff)
downloadwordpress-mu-50b00028bd207f461d6ed02f7868eccb5c6b8fe1.tar.gz
wordpress-mu-50b00028bd207f461d6ed02f7868eccb5c6b8fe1.tar.xz
wordpress-mu-50b00028bd207f461d6ed02f7868eccb5c6b8fe1.zip
Add and delete WP 2.5 files. *DON'T SVN UPDATE!*
git-svn-id: http://svn.automattic.com/wordpress-mu/trunk@1214 7be80a69-a1ef-0310-a953-fb0f7c49ff36
Diffstat (limited to 'wp-admin/includes')
-rw-r--r--wp-admin/includes/class-ftp-pure.php175
-rw-r--r--wp-admin/includes/class-ftp-sockets.php236
-rw-r--r--wp-admin/includes/class-ftp.php842
-rw-r--r--wp-admin/includes/class-pclzip.php5748
-rw-r--r--wp-admin/includes/class-wp-filesystem-direct.php336
-rw-r--r--wp-admin/includes/class-wp-filesystem-ftpext.php480
-rw-r--r--wp-admin/includes/class-wp-filesystem-ftpsockets.php426
-rw-r--r--wp-admin/includes/dashboard.php538
-rw-r--r--wp-admin/includes/export.php255
-rw-r--r--wp-admin/includes/media.php1225
-rw-r--r--wp-admin/includes/widgets.php269
11 files changed, 10530 insertions, 0 deletions
diff --git a/wp-admin/includes/class-ftp-pure.php b/wp-admin/includes/class-ftp-pure.php
new file mode 100644
index 0000000..5ef92bf
--- /dev/null
+++ b/wp-admin/includes/class-ftp-pure.php
@@ -0,0 +1,175 @@
+<?php
+/**
+ * PemFTP - A Ftp implementation in pure PHP
+ *
+ * @package PemFTP
+ * @since 2.5
+ *
+ * @version 1.0
+ * @copyright Alexey Dotsenko
+ * @author Alexey Dotsenko
+ * @link http://www.phpclasses.org/browse/package/1743.html Site
+ * @license LGPL License http://www.opensource.org/licenses/lgpl-license.html
+ */
+class ftp extends ftp_base {
+
+ function ftp($verb=FALSE, $le=FALSE) {
+ $this->__construct($verb, $le);
+ }
+
+ function __construct($verb=FALSE, $le=FALSE) {
+ parent::__construct(false, $verb, $le);
+ }
+
+// <!-- --------------------------------------------------------------------------------------- -->
+// <!-- Private functions -->
+// <!-- --------------------------------------------------------------------------------------- -->
+
+ function _settimeout($sock) {
+ if(!@stream_set_timeout($sock, $this->_timeout)) {
+ $this->PushError('_settimeout','socket set send timeout');
+ $this->_quit();
+ return FALSE;
+ }
+ return TRUE;
+ }
+
+ function _connect($host, $port) {
+ $this->SendMSG("Creating socket");
+ $sock = @fsockopen($host, $port, $errno, $errstr, $this->_timeout);
+ if (!$sock) {
+ $this->PushError('_connect','socket connect failed', $errstr." (".$errno.")");
+ return FALSE;
+ }
+ $this->_connected=true;
+ return $sock;
+ }
+
+ function _readmsg($fnction="_readmsg"){
+ if(!$this->_connected) {
+ $this->PushError($fnction, 'Connect first');
+ return FALSE;
+ }
+ $result=true;
+ $this->_message="";
+ $this->_code=0;
+ $go=true;
+ do {
+ $tmp=@fgets($this->_ftp_control_sock, 512);
+ if($tmp===false) {
+ $go=$result=false;
+ $this->PushError($fnction,'Read failed');
+ } else {
+ $this->_message.=$tmp;
+ if(preg_match("/^([0-9]{3})(-(.*[".CRLF."]{1,2})+\\1)? [^".CRLF."]+[".CRLF."]{1,2}$/", $this->_message, $regs)) $go=false;
+ }
+ } while($go);
+ if($this->LocalEcho) echo "GET < ".rtrim($this->_message, CRLF).CRLF;
+ $this->_code=(int)$regs[1];
+ return $result;
+ }
+
+ function _exec($cmd, $fnction="_exec") {
+ if(!$this->_ready) {
+ $this->PushError($fnction,'Connect first');
+ return FALSE;
+ }
+ if($this->LocalEcho) echo "PUT > ",$cmd,CRLF;
+ $status=@fputs($this->_ftp_control_sock, $cmd.CRLF);
+ if($status===false) {
+ $this->PushError($fnction,'socket write failed');
+ return FALSE;
+ }
+ $this->_lastaction=time();
+ if(!$this->_readmsg($fnction)) return FALSE;
+ return TRUE;
+ }
+
+ function _data_prepare($mode=FTP_ASCII) {
+ if(!$this->_settype($mode)) return FALSE;
+ if($this->_passive) {
+ if(!$this->_exec("PASV", "pasv")) {
+ $this->_data_close();
+ return FALSE;
+ }
+ if(!$this->_checkCode()) {
+ $this->_data_close();
+ return FALSE;
+ }
+ $ip_port = explode(",", ereg_replace("^.+ \\(?([0-9]{1,3},[0-9]{1,3},[0-9]{1,3},[0-9]{1,3},[0-9]+,[0-9]+)\\)?.*".CRLF."$", "\\1", $this->_message));
+ $this->_datahost=$ip_port[0].".".$ip_port[1].".".$ip_port[2].".".$ip_port[3];
+ $this->_dataport=(((int)$ip_port[4])<<8) + ((int)$ip_port[5]);
+ $this->SendMSG("Connecting to ".$this->_datahost.":".$this->_dataport);
+ $this->_ftp_data_sock=@fsockopen($this->_datahost, $this->_dataport, $errno, $errstr, $this->_timeout);
+ if(!$this->_ftp_data_sock) {
+ $this->PushError("_data_prepare","fsockopen fails", $errstr." (".$errno.")");
+ $this->_data_close();
+ return FALSE;
+ }
+ else $this->_ftp_data_sock;
+ } else {
+ $this->SendMSG("Only passive connections available!");
+ return FALSE;
+ }
+ return TRUE;
+ }
+
+ function _data_read($mode=FTP_ASCII, $fp=NULL) {
+ if(is_resource($fp)) $out=0;
+ else $out="";
+ if(!$this->_passive) {
+ $this->SendMSG("Only passive connections available!");
+ return FALSE;
+ }
+ while (!feof($this->_ftp_data_sock)) {
+ $block=fread($this->_ftp_data_sock, $this->_ftp_buff_size);
+ if($mode!=FTP_BINARY) $block=preg_replace("/\r\n|\r|\n/", $this->_eol_code[$this->OS_local], $block);
+ if(is_resource($fp)) $out+=fwrite($fp, $block, strlen($block));
+ else $out.=$block;
+ }
+ return $out;
+ }
+
+ function _data_write($mode=FTP_ASCII, $fp=NULL) {
+ if(is_resource($fp)) $out=0;
+ else $out="";
+ if(!$this->_passive) {
+ $this->SendMSG("Only passive connections available!");
+ return FALSE;
+ }
+ if(is_resource($fp)) {
+ while(!feof($fp)) {
+ $block=fread($fp, $this->_ftp_buff_size);
+ if(!$this->_data_write_block($mode, $block)) return false;
+ }
+ } elseif(!$this->_data_write_block($mode, $fp)) return false;
+ return TRUE;
+ }
+
+ function _data_write_block($mode, $block) {
+ if($mode!=FTP_BINARY) $block=preg_replace("/\r\n|\r|\n/", $this->_eol_code[$this->OS_remote], $block);
+ do {
+ if(($t=@fwrite($this->_ftp_data_sock, $block))===FALSE) {
+ $this->PushError("_data_write","Can't write to socket");
+ return FALSE;
+ }
+ $block=substr($block, $t);
+ } while(!empty($block));
+ return true;
+ }
+
+ function _data_close() {
+ @fclose($this->_ftp_data_sock);
+ $this->SendMSG("Disconnected data from remote host");
+ return TRUE;
+ }
+
+ function _quit($force=FALSE) {
+ if($this->_connected or $force) {
+ @fclose($this->_ftp_control_sock);
+ $this->_connected=false;
+ $this->SendMSG("Socket closed");
+ }
+ }
+}
+?>
diff --git a/wp-admin/includes/class-ftp-sockets.php b/wp-admin/includes/class-ftp-sockets.php
new file mode 100644
index 0000000..99b4050
--- /dev/null
+++ b/wp-admin/includes/class-ftp-sockets.php
@@ -0,0 +1,236 @@
+<?php
+/**
+ * PemFTP - A Ftp implementation in pure PHP
+ *
+ * @package PemFTP
+ * @since 2.5
+ *
+ * @version 1.0
+ * @copyright Alexey Dotsenko
+ * @author Alexey Dotsenko
+ * @link http://www.phpclasses.org/browse/package/1743.html Site
+ * @license LGPL License http://www.opensource.org/licenses/lgpl-license.html
+ */
+class ftp extends ftp_base {
+
+ function ftp($verb=FALSE, $le=FALSE) {
+ $this->__construct($verb, $le);
+ }
+
+ function __construct($verb=FALSE, $le=FALSE) {
+ parent::__construct(true, $verb, $le);
+ }
+
+// <!-- --------------------------------------------------------------------------------------- -->
+// <!-- Private functions -->
+// <!-- --------------------------------------------------------------------------------------- -->
+
+ function _settimeout($sock) {
+ if(!@socket_set_option($sock, SOL_SOCKET, SO_RCVTIMEO, array("sec"=>$this->_timeout, "usec"=>0))) {
+ $this->PushError('_connect','socket set receive timeout',socket_strerror(socket_last_error($sock)));
+ @socket_close($sock);
+ return FALSE;
+ }
+ if(!@socket_set_option($sock, SOL_SOCKET , SO_SNDTIMEO, array("sec"=>$this->_timeout, "usec"=>0))) {
+ $this->PushError('_connect','socket set send timeout',socket_strerror(socket_last_error($sock)));
+ @socket_close($sock);
+ return FALSE;
+ }
+ return true;
+ }
+
+ function _connect($host, $port) {
+ $this->SendMSG("Creating socket");
+ if(!($sock = @socket_create(AF_INET, SOCK_STREAM, SOL_TCP))) {
+ $this->PushError('_connect','socket create failed',socket_strerror(socket_last_error($sock)));
+ return FALSE;
+ }
+ if(!$this->_settimeout($sock)) return FALSE;
+ $this->SendMSG("Connecting to \"".$host.":".$port."\"");
+ if (!($res = @socket_connect($sock, $host, $port))) {
+ $this->PushError('_connect','socket connect failed',socket_strerror(socket_last_error($sock)));
+ @socket_close($sock);
+ return FALSE;
+ }
+ $this->_connected=true;
+ return $sock;
+ }
+
+ function _readmsg($fnction="_readmsg"){
+ if(!$this->_connected) {
+ $this->PushError($fnction,'Connect first');
+ return FALSE;
+ }
+ $result=true;
+ $this->_message="";
+ $this->_code=0;
+ $go=true;
+ do {
+ $tmp=@socket_read($this->_ftp_control_sock, 4096, PHP_BINARY_READ);
+ if($tmp===false) {
+ $go=$result=false;
+ $this->PushError($fnction,'Read failed', socket_strerror(socket_last_error($this->_ftp_control_sock)));
+ } else {
+ $this->_message.=$tmp;
+ $go = !preg_match("/^([0-9]{3})(-.+\\1)? [^".CRLF."]+".CRLF."$/Us", $this->_message, $regs);
+ }
+ } while($go);
+ if($this->LocalEcho) echo "GET < ".rtrim($this->_message, CRLF).CRLF;
+ $this->_code=(int)$regs[1];
+ return $result;
+ }
+
+ function _exec($cmd, $fnction="_exec") {
+ if(!$this->_ready) {
+ $this->PushError($fnction,'Connect first');
+ return FALSE;
+ }
+ if($this->LocalEcho) echo "PUT > ",$cmd,CRLF;
+ $status=@socket_write($this->_ftp_control_sock, $cmd.CRLF);
+ if($status===false) {
+ $this->PushError($fnction,'socket write failed', socket_strerror(socket_last_error($this->stream)));
+ return FALSE;
+ }
+ $this->_lastaction=time();
+ if(!$this->_readmsg($fnction)) return FALSE;
+ return TRUE;
+ }
+
+ function _data_prepare($mode=FTP_ASCII) {
+ if(!$this->_settype($mode)) return FALSE;
+ $this->SendMSG("Creating data socket");
+ $this->_ftp_data_sock = @socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
+ if ($this->_ftp_data_sock < 0) {
+ $this->PushError('_data_prepare','socket create failed',socket_strerror(socket_last_error($this->_ftp_data_sock)));
+ return FALSE;
+ }
+ if(!$this->_settimeout($this->_ftp_data_sock)) {
+ $this->_data_close();
+ return FALSE;
+ }
+ if($this->_passive) {
+ if(!$this->_exec("PASV", "pasv")) {
+ $this->_data_close();
+ return FALSE;
+ }
+ if(!$this->_checkCode()) {
+ $this->_data_close();
+ return FALSE;
+ }
+ $ip_port = explode(",", ereg_replace("^.+ \\(?([0-9]{1,3},[0-9]{1,3},[0-9]{1,3},[0-9]{1,3},[0-9]+,[0-9]+)\\)?.*".CRLF."$", "\\1", $this->_message));
+ $this->_datahost=$ip_port[0].".".$ip_port[1].".".$ip_port[2].".".$ip_port[3];
+ $this->_dataport=(((int)$ip_port[4])<<8) + ((int)$ip_port[5]);
+ $this->SendMSG("Connecting to ".$this->_datahost.":".$this->_dataport);
+ if(!@socket_connect($this->_ftp_data_sock, $this->_datahost, $this->_dataport)) {
+ $this->PushError("_data_prepare","socket_connect", socket_strerror(socket_last_error($this->_ftp_data_sock)));
+ $this->_data_close();
+ return FALSE;
+ }
+ else $this->_ftp_temp_sock=$this->_ftp_data_sock;
+ } else {
+ if(!@socket_getsockname($this->_ftp_control_sock, $addr, $port)) {
+ $this->PushError("_data_prepare","can't get control socket information", socket_strerror(socket_last_error($this->_ftp_control_sock)));
+ $this->_data_close();
+ return FALSE;
+ }
+ if(!@socket_bind($this->_ftp_data_sock,$addr)){
+ $this->PushError("_data_prepare","can't bind data socket", socket_strerror(socket_last_error($this->_ftp_data_sock)));
+ $this->_data_close();
+ return FALSE;
+ }
+ if(!@socket_listen($this->_ftp_data_sock)) {
+ $this->PushError("_data_prepare","can't listen data socket", socket_strerror(socket_last_error($this->_ftp_data_sock)));
+ $this->_data_close();
+ return FALSE;
+ }
+ if(!@socket_getsockname($this->_ftp_data_sock, $this->_datahost, $this->_dataport)) {
+ $this->PushError("_data_prepare","can't get data socket information", socket_strerror(socket_last_error($this->_ftp_data_sock)));
+ $this->_data_close();
+ return FALSE;
+ }
+ if(!$this->_exec('PORT '.str_replace('.',',',$this->_datahost.'.'.($this->_dataport>>8).'.'.($this->_dataport&0x00FF)), "_port")) {
+ $this->_data_close();
+ return FALSE;
+ }
+ if(!$this->_checkCode()) {
+ $this->_data_close();
+ return FALSE;
+ }
+ }
+ return TRUE;
+ }
+
+ function _data_read($mode=FTP_ASCII, $fp=NULL) {
+ $NewLine=$this->_eol_code[$this->OS_local];
+ if(is_resource($fp)) $out=0;
+ else $out="";
+ if(!$this->_passive) {
+ $this->SendMSG("Connecting to ".$this->_datahost.":".$this->_dataport);
+ $this->_ftp_temp_sock=socket_accept($this->_ftp_data_sock);
+ if($this->_ftp_temp_sock===FALSE) {
+ $this->PushError("_data_read","socket_accept", socket_strerror(socket_last_error($this->_ftp_temp_sock)));
+ $this->_data_close();
+ return FALSE;
+ }
+ }
+
+ while(($block=@socket_read($this->_ftp_temp_sock, $this->_ftp_buff_size, PHP_BINARY_READ))!==false) {
+ if($block==="") break;
+ if($mode!=FTP_BINARY) $block=preg_replace("/\r\n|\r|\n/", $this->_eol_code[$this->OS_local], $block);
+ if(is_resource($fp)) $out+=fwrite($fp, $block, strlen($block));
+ else $out.=$block;
+ }
+ return $out;
+ }
+
+ function _data_write($mode=FTP_ASCII, $fp=NULL) {
+ $NewLine=$this->_eol_code[$this->OS_local];
+ if(is_resource($fp)) $out=0;
+ else $out="";
+ if(!$this->_passive) {
+ $this->SendMSG("Connecting to ".$this->_datahost.":".$this->_dataport);
+ $this->_ftp_temp_sock=socket_accept($this->_ftp_data_sock);
+ if($this->_ftp_temp_sock===FALSE) {
+ $this->PushError("_data_write","socket_accept", socket_strerror(socket_last_error($this->_ftp_temp_sock)));
+ $this->_data_close();
+ return false;
+ }
+ }
+ if(is_resource($fp)) {
+ while(!feof($fp)) {
+ $block=fread($fp, $this->_ftp_buff_size);
+ if(!$this->_data_write_block($mode, $block)) return false;
+ }
+ } elseif(!$this->_data_write_block($mode, $fp)) return false;
+ return true;
+ }
+
+ function _data_write_block($mode, $block) {
+ if($mode!=FTP_BINARY) $block=preg_replace("/\r\n|\r|\n/", $this->_eol_code[$this->OS_remote], $block);
+ do {
+ if(($t=@socket_write($this->_ftp_temp_sock, $block))===FALSE) {
+ $this->PushError("_data_write","socket_write", socket_strerror(socket_last_error($this->_ftp_temp_sock)));
+ $this->_data_close();
+ return FALSE;
+ }
+ $block=substr($block, $t);
+ } while(!empty($block));
+ return true;
+ }
+
+ function _data_close() {
+ @socket_close($this->_ftp_temp_sock);
+ @socket_close($this->_ftp_data_sock);
+ $this->SendMSG("Disconnected data from remote host");
+ return TRUE;
+ }
+
+ function _quit() {
+ if($this->_connected) {
+ @socket_close($this->_ftp_control_sock);
+ $this->_connected=false;
+ $this->SendMSG("Socket closed");
+ }
+ }
+}
+?>
diff --git a/wp-admin/includes/class-ftp.php b/wp-admin/includes/class-ftp.php
new file mode 100644
index 0000000..bc2720a
--- /dev/null
+++ b/wp-admin/includes/class-ftp.php
@@ -0,0 +1,842 @@
+<?php
+/**
+ * PemFTP - A Ftp implementation in pure PHP
+ *
+ * @package PemFTP
+ * @since 2.5
+ *
+ * @version 1.0
+ * @copyright Alexey Dotsenko
+ * @author Alexey Dotsenko
+ * @link http://www.phpclasses.org/browse/package/1743.html Site
+ * @license LGPL License http://www.opensource.org/licenses/lgpl-license.html
+ */
+if(!defined('CRLF')) define('CRLF',"\r\n");
+if(!defined("FTP_AUTOASCII")) define("FTP_AUTOASCII", -1);
+if(!defined("FTP_BINARY")) define("FTP_BINARY", 1);
+if(!defined("FTP_ASCII")) define("FTP_ASCII", 0);
+if(!defined('FTP_FORCE')) define('FTP_FORCE', TRUE);
+define('FTP_OS_Unix','u');
+define('FTP_OS_Windows','w');
+define('FTP_OS_Mac','m');
+
+class ftp_base {
+ /* Public variables */
+ var $LocalEcho;
+ var $Verbose;
+ var $OS_local;
+ var $OS_remote;
+
+ /* Private variables */
+ var $_lastaction;
+ var $_errors;
+ var $_type;
+ var $_umask;
+ var $_timeout;
+ var $_passive;
+ var $_host;
+ var $_fullhost;
+ var $_port;
+ var $_datahost;
+ var $_dataport;
+ var $_ftp_control_sock;
+ var $_ftp_data_sock;
+ var $_ftp_temp_sock;
+ var $_ftp_buff_size;
+ var $_login;
+ var $_password;
+ var $_connected;
+ var $_ready;
+ var $_code;
+ var $_message;
+ var $_can_restore;
+ var $_port_available;
+ var $_curtype;
+ var $_features;
+
+ var $_error_array;
+ var $AuthorizedTransferMode;
+ var $OS_FullName;
+ var $_eol_code;
+ var $AutoAsciiExt;
+
+ /* Constructor */
+ function ftp_base($port_mode=FALSE) {
+ $this->__construct($port_mode);
+ }
+
+ function __construct($port_mode=FALSE, $verb=FALSE, $le=FALSE) {
+ $this->LocalEcho=$le;
+ $this->Verbose=$verb;
+ $this->_lastaction=NULL;
+ $this->_error_array=array();
+ $this->_eol_code=array(FTP_OS_Unix=>"\n", FTP_OS_Mac=>"\r", FTP_OS_Windows=>"\r\n");
+ $this->AuthorizedTransferMode=array(FTP_AUTOASCII, FTP_ASCII, FTP_BINARY);
+ $this->OS_FullName=array(FTP_OS_Unix => 'UNIX', FTP_OS_Windows => 'WINDOWS', FTP_OS_Mac => 'MACOS');
+ $this->AutoAsciiExt=array("ASP","BAT","C","CPP","CSS","CSV","JS","H","HTM","HTML","SHTML","INI","LOG","PHP3","PHTML","PL","PERL","SH","SQL","TXT");
+ $this->_port_available=($port_mode==TRUE);
+ $this->SendMSG("Staring FTP client class".($this->_port_available?"":" without PORT mode support"));
+ $this->_connected=FALSE;
+ $this->_ready=FALSE;
+ $this->_can_restore=FALSE;
+ $this->_code=0;
+ $this->_message="";
+ $this->_ftp_buff_size=4096;
+ $this->_curtype=NULL;
+ $this->SetUmask(0022);
+ $this->SetType(FTP_AUTOASCII);
+ $this->SetTimeout(30);
+ $this->Passive(!$this->_port_available);
+ $this->_login="anonymous";
+ $this->_password="anon@ftp.com";
+ $this->_features=array();
+ $this->OS_local=FTP_OS_Unix;
+ $this->OS_remote=FTP_OS_Unix;
+ $this->features=array();
+ if(strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') $this->OS_local=FTP_OS_Windows;
+ elseif(strtoupper(substr(PHP_OS, 0, 3)) === 'MAC') $this->OS_local=FTP_OS_Mac;
+ }
+
+// <!-- --------------------------------------------------------------------------------------- -->
+// <!-- Public functions -->
+// <!-- --------------------------------------------------------------------------------------- -->
+
+ function parselisting($line) {
+ $is_windows = ($this->OS_remote == FTP_OS_Windows);
+ if ($is_windows && preg_match("/([0-9]{2})-([0-9]{2})-([0-9]{2}) +([0-9]{2}):([0-9]{2})(AM|PM) +([0-9]+|<DIR>) +(.+)/",$line,$lucifer)) {
+ $b = array();
+ if ($lucifer[3]<70) { $lucifer[3]+=2000; } else { $lucifer[3]+=1900; } // 4digit year fix
+ $b['isdir'] = ($lucifer[7]=="<DIR>");
+ if ( $b['isdir'] )
+ $b['type'] = 'd';
+ else
+ $b['type'] = 'f';
+ $b['size'] = $lucifer[7];
+ $b['month'] = $lucifer[1];
+ $b['day'] = $lucifer[2];
+ $b['year'] = $lucifer[3];
+ $b['hour'] = $lucifer[4];
+ $b['minute'] = $lucifer[5];
+ $b['time'] = @mktime($lucifer[4]+(strcasecmp($lucifer[6],"PM")==0?12:0),$lucifer[5],0,$lucifer[1],$lucifer[2],$lucifer[3]);
+ $b['am/pm'] = $lucifer[6];
+ $b['name'] = $lucifer[8];
+ } else if (!$is_windows && $lucifer=preg_split("/[ ]/",$line,9,PREG_SPLIT_NO_EMPTY)) {
+ //echo $line."\n";
+ $lcount=count($lucifer);
+ if ($lcount<8) return '';
+ $b = array();
+ $b['isdir'] = $lucifer[0]{0} === "d";
+ $b['islink'] = $lucifer[0]{0} === "l";
+ if ( $b['isdir'] )
+ $b['type'] = 'd';
+ elseif ( $b['islink'] )
+ $b['type'] = 'l';
+ else
+ $b['type'] = 'f';
+ $b['perms'] = $lucifer[0];
+ $b['number'] = $lucifer[1];
+ $b['owner'] = $lucifer[2];
+ $b['group'] = $lucifer[3];
+ $b['size'] = $lucifer[4];
+ if ($lcount==8) {
+ sscanf($lucifer[5],"%d-%d-%d",$b['year'],$b['month'],$b['day']);
+ sscanf($lucifer[6],"%d:%d",$b['hour'],$b['minute']);
+ $b['time'] = @mktime($b['hour'],$b['minute'],0,$b['month'],$b['day'],$b['year']);
+ $b['name'] = $lucifer[7];
+ } else {
+ $b['month'] = $lucifer[5];
+ $b['day'] = $lucifer[6];
+ if (preg_match("/([0-9]{2}):([0-9]{2})/",$lucifer[7],$l2)) {
+ $b['year'] = date("Y");
+ $b['hour'] = $l2[1];
+ $b['minute'] = $l2[2];
+ } else {
+ $b['year'] = $lucifer[7];
+ $b['hour'] = 0;
+ $b['minute'] = 0;
+ }
+ $b['time'] = strtotime(sprintf("%d %s %d %02d:%02d",$b['day'],$b['month'],$b['year'],$b['hour'],$b['minute']));
+ $b['name'] = $lucifer[8];
+ }
+ }
+
+ return $b;
+ }
+
+ function SendMSG($message = "", $crlf=true) {
+ if ($this->Verbose) {
+ echo $message.($crlf?CRLF:"");
+ flush();
+ }
+ return TRUE;
+ }
+
+ function SetType($mode=FTP_AUTOASCII) {
+ if(!in_array($mode, $this->AuthorizedTransferMode)) {
+ $this->SendMSG("Wrong type");
+ return FALSE;
+ }
+ $this->_type=$mode;
+ $this->SendMSG("Transfer type: ".($this->_type==FTP_BINARY?"binary":($this->_type==FTP_ASCII?"ASCII":"auto ASCII") ) );
+ return TRUE;
+ }
+
+ function _settype($mode=FTP_ASCII) {
+ if($this->_ready) {
+ if($mode==FTP_BINARY) {
+ if($this->_curtype!=FTP_BINARY) {
+ if(!$this->_exec("TYPE I", "SetType")) return FALSE;
+ $this->_curtype=FTP_BINARY;
+ }
+ } elseif($this->_curtype!=FTP_ASCII) {
+ if(!$this->_exec("TYPE A", "SetType")) return FALSE;
+ $this->_curtype=FTP_ASCII;
+ }
+ } else return FALSE;
+ return TRUE;
+ }
+
+ function Passive($pasv=NULL) {
+ if(is_null($pasv)) $this->_passive=!$this->_passive;
+ else $this->_passive=$pasv;
+ if(!$this->_port_available and !$this->_passive) {
+ $this->SendMSG("Only passive connections available!");
+ $this->_passive=TRUE;
+ return FALSE;
+ }
+ $this->SendMSG("Passive mode ".($this->_passive?"on":"off"));
+ return TRUE;
+ }
+
+ function SetServer($host, $port=21, $reconnect=true) {
+ if(!is_long($port)) {
+ $this->verbose=true;
+ $this->SendMSG("Incorrect port syntax");
+ return FALSE;
+ } else {
+ $ip=@gethostbyname($host);
+ $dns=@gethostbyaddr($host);
+ if(!$ip) $ip=$host;
+ if(!$dns) $dns=$host;
+ if(ip2long($ip) === -1) {
+ $this->SendMSG("Wrong host name/address \"".$host."\"");
+ return FALSE;
+ }
+ $this->_host=$ip;
+ $this->_fullhost=$dns;
+ $this->_port=$port;
+ $this->_dataport=$port-1;
+ }
+ $this->SendMSG("Host \"".$this->_fullhost."(".$this->_host."):".$this->_port."\"");
+ if($reconnect){
+ if($this->_connected) {
+ $this->SendMSG("Reconnecting");
+ if(!$this->quit(FTP_FORCE)) return FALSE;
+ if(!$this->connect()) return FALSE;
+ }
+ }
+ return TRUE;
+ }
+
+ function SetUmask($umask=0022) {
+ $this->_umask=$umask;
+ umask($this->_umask);
+ $this->SendMSG("UMASK 0".decoct($this->_umask));
+ return TRUE;
+ }
+
+ function SetTimeout($timeout=30) {
+ $this->_timeout=$timeout;
+ $this->SendMSG("Timeout ".$this->_timeout);
+ if($this->_connected)
+ if(!$this->_settimeout($this->_ftp_control_sock)) return FALSE;
+ return TRUE;
+ }
+
+ function connect($server=NULL) {
+ if(!empty($server)) {
+ if(!$this->SetServer($server)) return false;
+ }
+ if($this->_ready) return true;
+ $this->SendMsg('Local OS : '.$this->OS_FullName[$this->OS_local]);
+ if(!($this->_ftp_control_sock = $this->_connect($this->_host, $this->_port))) {
+ $this->SendMSG("Error : Cannot connect to remote host \"".$this->_fullhost." :".$this->_port."\"");
+ return FALSE;
+ }
+ $this->SendMSG("Connected to remote host \"".$this->_fullhost.":".$this->_port."\". Waiting for greeting.");
+ do {
+ if(!$this->_readmsg()) return FALSE;
+ if(!$this->_checkCode()) return FALSE;
+ $this->_lastaction=time();
+ } while($this->_code<200);
+ $this->_ready=true;
+ $syst=$this->systype();
+ if(!$syst) $this->SendMSG("Can't detect remote OS");
+ else {
+ if(preg_match("/win|dos|novell/i", $syst[0])) $this->OS_remote=FTP_OS_Windows;
+ elseif(preg_match("/os/i", $syst[0])) $this->OS_remote=FTP_OS_Mac;
+ elseif(preg_match("/(li|u)nix/i", $syst[0])) $this->OS_remote=FTP_OS_Unix;
+ else $this->OS_remote=FTP_OS_Mac;
+ $this->SendMSG("Remote OS: ".$this->OS_FullName[$this->OS_remote]);
+ }
+ if(!$this->features()) $this->SendMSG("Can't get features list. All supported - disabled");
+ else $this->SendMSG("Supported features: ".implode(", ", array_keys($this->_features)));
+ return TRUE;
+ }
+
+ function quit($force=false) {
+ if($this->_ready) {
+ if(!$this->_exec("QUIT") and !$force) return FALSE;
+ if(!$this->_checkCode() and !$force) return FALSE;
+ $this->_ready=false;
+ $this->SendMSG("Session finished");
+ }
+ $this->_quit();
+ return TRUE;
+ }
+
+ function login($user=NULL, $pass=NULL) {
+ if(!is_null($user)) $this->_login=$user;
+ else $this->_login="anonymous";
+ if(!is_null($pass)) $this->_password=$pass;
+ else $this->_password="anon@anon.com";
+ if(!$this->_exec("USER ".$this->_login, "login")) return FALSE;
+ if(!$this->_checkCode()) return FALSE;
+ if($this->_code!=230) {
+ if(!$this->_exec((($this->_code==331)?"PASS ":"ACCT ").$this->_password, "login")) return FALSE;
+ if(!$this->_checkCode()) return FALSE;
+ }
+ $this->SendMSG("Authentication succeeded");
+ if(empty($this->_features)) {
+ if(!$this->features()) $this->SendMSG("Can't get features list. All supported - disabled");
+ else $this->SendMSG("Supported features: ".implode(", ", array_keys($this->_features)));
+ }
+ return TRUE;
+ }
+
+ function pwd() {
+ if(!$this->_exec("PWD", "pwd")) return FALSE;
+ if(!$this->_checkCode()) return FALSE;
+ return ereg_replace("^[0-9]{3} \"(.+)\" .+".CRLF, "\\1", $this->_message);
+ }
+
+ function cdup() {
+ if(!$this->_exec("CDUP", "cdup")) return FALSE;
+ if(!$this->_checkCode()) return FALSE;
+ return true;
+ }
+
+ function chdir($pathname) {
+ if(!$this->_exec("CWD ".$pathname, "chdir")) return FALSE;
+ if(!$this->_checkCode()) return FALSE;
+ return TRUE;
+ }
+
+ function rmdir($pathname) {
+ if(!$this->_exec("RMD ".$pathname, "rmdir")) return FALSE;
+ if(!$this->_checkCode()) return FALSE;
+ return TRUE;
+ }
+
+ function mkdir($pathname) {
+ if(!$this->_exec("MKD ".$pathname, "mkdir")) return FALSE;
+ if(!$this->_checkCode()) return FALSE;
+ return TRUE;
+ }
+
+ function rename($from, $to) {
+ if(!$this->_exec("RNFR ".$from, "rename")) return FALSE;
+ if(!$this->_checkCode()) return FALSE;
+ if($this->_code==350) {
+ if(!$this->_exec("RNTO ".$to, "rename")) return FALSE;
+ if(!$this->_checkCode()) return FALSE;
+ } else return FALSE;
+ return TRUE;
+ }
+
+ function filesize($pathname) {
+ if(!isset($this->_features["SIZE"])) {
+ $this->PushError("filesize", "not supported by server");
+ return FALSE;
+ }
+ if(!$this->_exec("SIZE ".$pathname, "filesize")) return FALSE;
+ if(!$this->_checkCode()) return FALSE;
+ return ereg_replace("^[0-9]{3} ([0-9]+)".CRLF, "\\1", $this->_message);
+ }
+
+ function abort() {
+ if(!$this->_exec("ABOR", "abort")) return FALSE;
+ if(!$this->_checkCode()) {
+ if($this->_code!=426) return FALSE;
+ if(!$this->_readmsg("abort")) return FALSE;
+ if(!$this->_checkCode()) return FALSE;
+ }
+ return true;
+ }
+
+ function mdtm($pathname) {
+ if(!isset($this->_features["MDTM"])) {
+ $this->PushError("mdtm", "not supported by server");
+ return FALSE;
+ }
+ if(!$this->_exec("MDTM ".$pathname, "mdtm")) return FALSE;
+ if(!$this->_checkCode()) return FALSE;
+ $mdtm = ereg_replace("^[0-9]{3} ([0-9]+)".CRLF, "\\1", $this->_message);
+ $date = sscanf($mdtm, "%4d%2d%2d%2d%2d%2d");
+ $timestamp = mktime($date[3], $date[4], $date[5], $date[1], $date[2], $date[0]);
+ return $timestamp;
+ }
+
+ function systype() {
+ if(!$this->_exec("SYST", "systype")) return FALSE;
+ if(!$this->_checkCode()) return FALSE;
+ $DATA = explode(" ", $this->_message);
+ return array($DATA[1], $DATA[3]);
+ }
+
+ function delete($pathname) {
+ if(!$this->_exec("DELE ".$pathname, "delete")) return FALSE;
+ if(!$this->_checkCode()) return FALSE;
+ return TRUE;
+ }
+
+ function site($command, $fnction="site") {
+ if(!$this->_exec("SITE ".$command, $fnction)) return FALSE;
+ if(!$this->_checkCode()) return FALSE;
+ return TRUE;
+ }
+
+ function chmod($pathname, $mode) {
+ if(!$this->site( sprintf('CHMOD %o %s', $mode, $pathname), "chmod")) return FALSE;
+ return TRUE;
+ }
+
+ function restore($from) {
+ if(!isset($this->_features["REST"])) {
+ $this->PushError("restore", "not supported by server");
+ return FALSE;
+ }
+ if($this->_curtype!=FTP_BINARY) {
+ $this->PushError("restore", "can't restore in ASCII mode");
+ return FALSE;
+ }
+ if(!$this->_exec("REST ".$from, "resore")) return FALSE;
+ if(!$this->_checkCode()) return FALSE;
+ return TRUE;
+ }
+
+ function features() {
+ if(!$this->_exec("FEAT", "features")) return FALSE;
+ if(!$this->_checkCode()) return FALSE;
+ $f=preg_split("/[".CRLF."]+/", preg_replace("/[0-9]{3}[ -].*[".CRLF."]+/", "", $this->_message), -1, PREG_SPLIT_NO_EMPTY);
+ $this->_features=array();
+ foreach($f as $k=>$v) {
+ $v=explode(" ", trim($v));
+ $this->_features[array_shift($v)]=$v;;
+ }
+ return true;
+ }
+
+ function rawlist($pathname="", $arg="") {
+ return $this->_list(($arg?" ".$arg:"").($pathname?" ".$pathname:""), "LIST", "rawlist");
+ }
+
+ function nlist($pathname="") {
+ return $this->_list(($arg?" ".$arg:"").($pathname?" ".$pathname:""), "NLST", "nlist");
+ }
+
+ function is_exists($pathname) {
+ return $this->file_exists($pathname);
+ }
+
+ function file_exists($pathname) {
+ $exists=true;
+ if(!$this->_exec("RNFR ".$pathname, "rename")) $exists=FALSE;
+ else {
+ if(!$this->_checkCode()) $exists=FALSE;
+ $this->abort();
+ }
+ if($exists) $this->SendMSG("Remote file ".$pathname." exists");
+ else $this->SendMSG("Remote file ".$pathname." does not exist");
+ return $exists;
+ }
+
+ function fget($fp, $remotefile,$rest=0) {
+ if($this->_can_restore and $rest!=0) fseek($fp, $rest);
+ $pi=pathinfo($remotefile);
+ if($this->_type==FTP_ASCII or ($this->_type==FTP_AUTOASCII and in_array(strtoupper($pi["extension"]), $this->AutoAsciiExt))) $mode=FTP_ASCII;
+ else $mode=FTP_BINARY;
+ if(!$this->_data_prepare($mode)) {
+ return FALSE;
+ }
+ if($this->_can_restore and $rest!=0) $this->restore($rest);
+ if(!$this->_exec("RETR ".$remotefile, "get")) {
+ $this->_data_close();
+ return FALSE;
+ }
+ if(!$this->_checkCode()) {
+ $this->_data_close();
+ return FALSE;
+ }
+ $out=$this->_data_read($mode, $fp);
+ $this->_data_close();
+ if(!$this->_readmsg()) return FALSE;
+ if(!$this->_checkCode()) return FALSE;
+ return $out;
+ }
+
+ function get($remotefile, $localfile=NULL, $rest=0) {
+ if(is_null($localfile)) $localfile=$remotefile;
+ if (@file_exists($localfile)) $this->SendMSG("Warning : local file will be overwritten");
+ $fp = @fopen($localfile, "w");
+ if (!$fp) {
+ $this->PushError("get","can't open local file", "Cannot create \"".$localfile."\"");
+ return FALSE;
+ }
+ if($this->_can_restore and $rest!=0) fseek($fp, $rest);
+ $pi=pathinfo($remotefile);
+ if($this->_type==FTP_ASCII or ($this->_type==FTP_AUTOASCII and in_array(strtoupper($pi["extension"]), $this->AutoAsciiExt))) $mode=FTP_ASCII;
+ else $mode=FTP_BINARY;
+ if(!$this->_data_prepare($mode)) {
+ fclose($fp);
+ return FALSE;
+ }
+ if($this->_can_restore and $rest!=0) $this->restore($rest);
+ if(!$this->_exec("RETR ".$remotefile, "get")) {
+ $this->_data_close();
+ fclose($fp);
+ return FALSE;
+ }
+ if(!$this->_checkCode()) {
+ $this->_data_close();
+ fclose($fp);
+ return FALSE;
+ }
+ $out=$this->_data_read($mode, $fp);
+ fclose($fp);
+ $this->_data_close();
+ if(!$this->_readmsg()) return FALSE;
+ if(!$this->_checkCode()) return FALSE;
+ return $out;
+ }
+
+ function fput($remotefile, $fp) {
+ if($this->_can_restore and $rest!=0) fseek($fp, $rest);
+ $pi=pathinfo($remotefile);
+ if($this->_type==FTP_ASCII or ($this->_type==FTP_AUTOASCII and in_array(strtoupper($pi["extension"]), $this->AutoAsciiExt))) $mode=FTP_ASCII;
+ else $mode=FTP_BINARY;
+ if(!$this->_data_prepare($mode)) {
+ return FALSE;
+ }
+ if($this->_can_restore and $rest!=0) $this->restore($rest);
+ if(!$this->_exec("STOR ".$remotefile, "put")) {
+ $this->_data_close();
+ return FALSE;
+ }
+ if(!$this->_checkCode()) {
+ $this->_data_close();
+ return FALSE;
+ }
+ $ret=$this->_data_write($mode, $fp);
+ $this->_data_close();
+ if(!$this->_readmsg()) return FALSE;
+ if(!$this->_checkCode()) return FALSE;
+ return $ret;
+ }
+
+ function put($localfile, $remotefile=NULL, $rest=0) {
+ if(is_null($remotefile)) $remotefile=$localfile;
+ if (!file_exists($localfile)) {
+ $this->PushError("put","can't open local file", "No such file or directory \"".$localfile."\"");
+ return FALSE;
+ }
+ $fp = @fopen($localfile, "r");
+
+ if (!$fp) {
+ $this->PushError("put","can't open local file", "Cannot read file \"".$localfile."\"");
+ return FALSE;
+ }
+ if($this->_can_restore and $rest!=0) fseek($fp, $rest);
+ $pi=pathinfo($localfile);
+ if($this->_type==FTP_ASCII or ($this->_type==FTP_AUTOASCII and in_array(strtoupper($pi["extension"]), $this->AutoAsciiExt))) $mode=FTP_ASCII;
+ else $mode=FTP_BINARY;
+ if(!$this->_data_prepare($mode)) {
+ fclose($fp);
+ return FALSE;
+ }
+ if($this->_can_restore and $rest!=0) $this->restore($rest);
+ if(!$this->_exec("STOR ".$remotefile, "put")) {
+ $this->_data_close();
+ fclose($fp);
+ return FALSE;
+ }
+ if(!$this->_checkCode()) {
+ $this->_data_close();
+ fclose($fp);
+ return FALSE;
+ }
+ $ret=$this->_data_write($mode, $fp);
+ fclose($fp);
+ $this->_data_close();
+ if(!$this->_readmsg()) return FALSE;
+ if(!$this->_checkCode()) return FALSE;
+ return $ret;
+ }
+
+ function mput($local=".", $remote=NULL, $continious=false) {
+ $local=realpath($local);
+ if(!@file_exists($local)) {
+ $this->PushError("mput","can't open local folder", "Cannot stat folder \"".$local."\"");
+ return FALSE;
+ }
+ if(!is_dir($local)) return $this->put($local, $remote);
+ if(empty($remote)) $remote=".";
+ elseif(!$this->file_exists($remote) and !$this->mkdir($remote)) return FALSE;
+ if($handle = opendir($local)) {
+ $list=array();
+ while (false !== ($file = readdir($handle))) {
+ if ($file != "." && $file != "..") $list[]=$file;
+ }
+ closedir($handle);
+ } else {
+ $this->PushError("mput","can't open local folder", "Cannot read folder \"".$local."\"");
+ return FALSE;
+ }
+ if(empty($list)) return TRUE;
+ $ret=true;
+ foreach($list as $el) {
+ if(is_dir($local."/".$el)) $t=$this->mput($local."/".$el, $remote."/".$el);
+ else $t=$this->put($local."/".$el, $remote."/".$el);
+ if(!$t) {
+ $ret=FALSE;
+ if(!$continious) break;
+ }
+ }
+ return $ret;
+
+ }
+
+ function mget($remote, $local=".", $continious=false) {
+ $list=$this->rawlist($remote, "-lA");
+ if($list===false) {
+ $this->PushError("mget","can't read remote folder list", "Can't read remote folder \"".$remote."\" contents");
+ return FALSE;
+ }
+ if(empty($list)) return true;
+ if(!@file_exists($local)) {
+ if(!@mkdir($local)) {
+ $this->PushError("mget","can't create local folder", "Cannot create folder \"".$local."\"");
+ return FALSE;
+ }
+ }
+ foreach($list as $k=>$v) {
+ $list[$k]=$this->parselisting($v);
+ if($list[$k]["name"]=="." or $list[$k]["name"]=="..") unset($list[$k]);
+ }
+ $ret=true;
+ foreach($list as $el) {
+ if($el["type"]=="d") {
+ if(!$this->mget($remote."/".$el["name"], $local."/".$el["name"], $continious)) {
+ $this->PushError("mget", "can't copy folder", "Can't copy remote folder \"".$remote."/".$el["name"]."\" to local \"".$local."/".$el["name"]."\"");
+ $ret=false;
+ if(!$continious) break;
+ }
+ } else {
+ if(!$this->get($remote."/".$el["name"], $local."/".$el["name"])) {
+ $this->PushError("mget", "can't copy file", "Can't copy remote file \"".$remote."/".$el["name"]."\" to local \"".$local."/".$el["name"]."\"");
+ $ret=false;
+ if(!$continious) break;
+ }
+ }
+ @chmod($local."/".$el["name"], $el["perms"]);
+ $t=strtotime($el["date"]);
+ if($t!==-1 and $t!==false) @touch($local."/".$el["name"], $t);
+ }
+ return $ret;
+ }
+
+ function mdel($remote, $continious=false) {
+ $list=$this->rawlist($remote, "-la");
+ if($list===false) {
+ $this->PushError("mdel","can't read remote folder list", "Can't read remote folder \"".$remote."\" contents");
+ return false;
+ }
+
+ foreach($list as $k=>$v) {
+ $list[$k]=$this->parselisting($v);
+ if($list[$k]["name"]=="." or $list[$k]["name"]=="..") unset($list[$k]);
+ }
+ $ret=true;
+
+ foreach($list as $el) {
+ if ( empty($el) )
+ continue;
+
+ if($el["type"]=="d") {
+ if(!$this->mdel($remote."/".$el["name"], $continious)) {
+ $ret=false;
+ if(!$continious) break;
+ }
+ } else {
+ if (!$this->delete($remote."/".$el["name"])) {
+ $this->PushError("mdel", "can't delete file", "Can't delete remote file \"".$remote."/".$el["name"]."\"");
+ $ret=false;
+ if(!$continious) break;
+ }
+ }
+ }
+
+ if(!$this->rmdir($remote)) {
+ $this->PushError("mdel", "can't delete folder", "Can't delete remote folder \"".$remote."/".$el["name"]."\"");
+ $ret=false;
+ }
+ return $ret;
+ }
+
+ function mmkdir($dir, $mode = 0777) {
+ if(empty($dir)) return FALSE;
+ if($this->is_exists($dir) or $dir == "/" ) return TRUE;
+ if(!$this->mmkdir(dirname($dir), $mode)) return false;
+ $r=$this->mkdir($dir, $mode);
+ $this->chmod($dir,$mode);
+ return $r;
+ }
+
+ function glob($pattern, $handle=NULL) {
+ $path=$output=null;
+ if(PHP_OS=='WIN32') $slash='\\';
+ else $slash='/';
+ $lastpos=strrpos($pattern,$slash);
+ if(!($lastpos===false)) {
+ $path=substr($pattern,0,-$lastpos-1);
+ $pattern=substr($pattern,$lastpos);
+ } else $path=getcwd();
+ if(is_array($handle) and !empty($handle)) {
+ while($dir=each($handle)) {
+ if($this->glob_pattern_match($pattern,$dir))
+ $output[]=$dir;
+ }
+ } else {
+ $handle=@opendir($path);
+ if($handle===false) return false;
+ while($dir=readdir($handle)) {
+ if($this->glob_pattern_match($pattern,$dir))
+ $output[]=$dir;
+ }
+ closedir($handle);
+ }
+ if(is_array($output)) return $output;
+ return false;
+ }
+
+ function glob_pattern_match($pattern,$string) {
+ $out=null;
+ $chunks=explode(';',$pattern);
+ foreach($chunks as $pattern) {
+ $escape=array('$','^','.','{','}','(',')','[',']','|');
+ while(strpos($pattern,'**')!==false)
+ $pattern=str_replace('**','*',$pattern);
+ foreach($escape as $probe)
+ $pattern=str_replace($probe,"\\$probe",$pattern);
+ $pattern=str_replace('?*','*',
+ str_replace('*?','*',
+ str_replace('*',".*",
+ str_replace('?','.{1,1}',$pattern))));
+ $out[]=$pattern;
+ }
+ if(count($out)==1) return($this->glob_regexp("^$out[0]$",$string));
+ else {
+ foreach($out as $tester)
+ if($this->my_regexp("^$tester$",$string)) return true;
+ }
+ return false;
+ }
+
+ function glob_regexp($pattern,$probe) {
+ $sensitive=(PHP_OS!='WIN32');
+ return ($sensitive?
+ ereg($pattern,$probe):
+ eregi($pattern,$probe)
+ );
+ }
+
+ function dirlist($remote) {
+ $list=$this->rawlist($remote, "-la");
+ if($list===false) {
+ $this->PushError("dirlist","can't read remote folder list", "Can't read remote folder \"".$remote."\" contents");
+ return false;
+ }
+
+ $dirlist = array();
+ foreach($list as $k=>$v) {
+ $entry=$this->parselisting($v);
+ if ( empty($entry) )
+ continue;
+
+ if($entry["name"]=="." or $entry["name"]=="..")
+ continue;
+
+ $dirlist[$entry['name']] = $entry;
+ }
+
+ return $dirlist;
+ }
+// <!-- --------------------------------------------------------------------------------------- -->
+// <!-- Private functions -->
+// <!-- --------------------------------------------------------------------------------------- -->
+ function _checkCode() {
+ return ($this->_code<400 and $this->_code>0);
+ }
+
+ function _list($arg="", $cmd="LIST", $fnction="_list") {
+ if(!$this->_data_prepare()) return false;
+ if(!$this->_exec($cmd.$arg, $fnction)) {
+ $this->_data_close();
+ return FALSE;
+ }
+ if(!$this->_checkCode()) {
+ $this->_data_close();
+ return FALSE;
+ }
+ $out="";
+ if($this->_code<200) {
+ $out=$this->_data_read();
+ $this->_data_close();
+ if(!$this->_readmsg()) return FALSE;
+ if(!$this->_checkCode()) return FALSE;
+ if($out === FALSE ) return FALSE;
+ $out=preg_split("/[".CRLF."]+/", $out, -1, PREG_SPLIT_NO_EMPTY);
+// $this->SendMSG(implode($this->_eol_code[$this->OS_local], $out));
+ }
+ return $out;
+ }
+
+// <!-- --------------------------------------------------------------------------------------- -->
+// <!-- Partie : gestion des erreurs -->
+// <!-- --------------------------------------------------------------------------------------- -->
+// Gnre une erreur pour traitement externe la classe
+ function PushError($fctname,$msg,$desc=false){
+ $error=array();
+ $error['time']=time();
+ $error['fctname']=$fctname;
+ $error['msg']=$msg;
+ $error['desc']=$desc;
+ if($desc) $tmp=' ('.$desc.')'; else $tmp='';
+ $this->SendMSG($fctname.': '.$msg.$tmp);
+ return(array_push($this->_error_array,$error));
+ }
+
+// Rcupre une erreur externe
+ function PopError(){
+ if(count($this->_error_array)) return(array_pop($this->_error_array));
+ else return(false);
+ }
+}
+
+$mod_sockets=TRUE;
+if (!extension_loaded('sockets')) {
+ $prefix = (PHP_SHLIB_SUFFIX == 'dll') ? 'php_' : '';
+ if(!@dl($prefix . 'sockets.' . PHP_SHLIB_SUFFIX)) $mod_sockets=FALSE;
+}
+require_once "class-ftp-".($mod_sockets?"sockets":"pure").".php";
+?>
diff --git a/wp-admin/includes/class-pclzip.php b/wp-admin/includes/class-pclzip.php
new file mode 100644
index 0000000..d387f00
--- /dev/null
+++ b/wp-admin/includes/class-pclzip.php
@@ -0,0 +1,5748 @@
+<?php
+// --------------------------------------------------------------------------------
+// PhpConcept Library - Zip Module 2.5
+// --------------------------------------------------------------------------------
+// License GNU/LGPL - Vincent Blavet - March 2006
+// http://www.phpconcept.net
+// --------------------------------------------------------------------------------
+//
+// Presentation :
+// PclZip is a PHP library that manage ZIP archives.
+// So far tests show that archives generated by PclZip are readable by
+// WinZip application and other tools.
+//
+// Description :
+// See readme.txt and http://www.phpconcept.net
+//
+// Warning :
+// This library and the associated files are non commercial, non professional
+// work.
+// It should not have unexpected results. However if any damage is caused by
+// this software the author can not be responsible.
+// The use of this software is at the risk of the user.
+//
+// --------------------------------------------------------------------------------
+// $Id: pclzip.lib.php,v 1.44 2006/03/08 21:23:59 vblavet Exp $
+// --------------------------------------------------------------------------------
+
+ // ----- Constants
+ define( 'PCLZIP_READ_BLOCK_SIZE', 2048 );
+
+ // ----- File list separator
+ // In version 1.x of PclZip, the separator for file list is a space
+ // (which is not a very smart choice, specifically for windows paths !).
+ // A better separator should be a comma (,). This constant gives you the
+ // abilty to change that.
+ // However notice that changing this value, may have impact on existing
+ // scripts, using space separated filenames.
+ // Recommanded values for compatibility with older versions :
+ //define( 'PCLZIP_SEPARATOR', ' ' );
+ // Recommanded values for smart separation of filenames.
+ define( 'PCLZIP_SEPARATOR', ',' );
+
+ // ----- Error configuration
+ // 0 : PclZip Class integrated error handling
+ // 1 : PclError external library error handling. By enabling this
+ // you must ensure that you have included PclError library.
+ // [2,...] : reserved for futur use
+ define( 'PCLZIP_ERROR_EXTERNAL', 0 );
+
+ // ----- Optional static temporary directory
+ // By default temporary files are generated in the script current
+ // path.
+ // If defined :
+ // - MUST BE terminated by a '/'.
+ // - MUST be a valid, already created directory
+ // Samples :
+ // define( 'PCLZIP_TEMPORARY_DIR', '/temp/' );
+ // define( 'PCLZIP_TEMPORARY_DIR', 'C:/Temp/' );
+ define( 'PCLZIP_TEMPORARY_DIR', '' );
+
+// --------------------------------------------------------------------------------
+// ***** UNDER THIS LINE NOTHING NEEDS TO BE MODIFIED *****
+// --------------------------------------------------------------------------------
+
+ // ----- Global variables
+ $g_pclzip_version = "2.5";
+
+ // ----- Error codes
+ // -1 : Unable to open file in binary write mode
+ // -2 : Unable to open file in binary read mode
+ // -3 : Invalid parameters
+ // -4 : File does not exist
+ // -5 : Filename is too long (max. 255)
+ // -6 : Not a valid zip file
+ // -7 : Invalid extracted file size
+ // -8 : Unable to create directory
+ // -9 : Invalid archive extension
+ // -10 : Invalid archive format
+ // -11 : Unable to delete file (unlink)
+ // -12 : Unable to rename file (rename)
+ // -13 : Invalid header checksum
+ // -14 : Invalid archive size
+ define( 'PCLZIP_ERR_USER_ABORTED', 2 );
+ define( 'PCLZIP_ERR_NO_ERROR', 0 );
+ define( 'PCLZIP_ERR_WRITE_OPEN_FAIL', -1 );
+ define( 'PCLZIP_ERR_READ_OPEN_FAIL', -2 );
+ define( 'PCLZIP_ERR_INVALID_PARAMETER', -3 );
+ define( 'PCLZIP_ERR_MISSING_FILE', -4 );
+ define( 'PCLZIP_ERR_FILENAME_TOO_LONG', -5 );
+ define( 'PCLZIP_ERR_INVALID_ZIP', -6 );
+ define( 'PCLZIP_ERR_BAD_EXTRACTED_FILE', -7 );
+ define( 'PCLZIP_ERR_DIR_CREATE_FAIL', -8 );
+ define( 'PCLZIP_ERR_BAD_EXTENSION', -9 );
+ define( 'PCLZIP_ERR_BAD_FORMAT', -10 );
+ define( 'PCLZIP_ERR_DELETE_FILE_FAIL', -11 );
+ define( 'PCLZIP_ERR_RENAME_FILE_FAIL', -12 );
+ define( 'PCLZIP_ERR_BAD_CHECKSUM', -13 );
+ define( 'PCLZIP_ERR_INVALID_ARCHIVE_ZIP', -14 );
+ define( 'PCLZIP_ERR_MISSING_OPTION_VALUE', -15 );
+ define( 'PCLZIP_ERR_INVALID_OPTION_VALUE', -16 );
+ define( 'PCLZIP_ERR_ALREADY_A_DIRECTORY', -17 );
+ define( 'PCLZIP_ERR_UNSUPPORTED_COMPRESSION', -18 );
+ define( 'PCLZIP_ERR_UNSUPPORTED_ENCRYPTION', -19 );
+ define( 'PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE', -20 );
+ define( 'PCLZIP_ERR_DIRECTORY_RESTRICTION', -21 );
+
+ // ----- Options values
+ define( 'PCLZIP_OPT_PATH', 77001 );
+ define( 'PCLZIP_OPT_ADD_PATH', 77002 );
+ define( 'PCLZIP_OPT_REMOVE_PATH', 77003 );
+ define( 'PCLZIP_OPT_REMOVE_ALL_PATH', 77004 );
+ define( 'PCLZIP_OPT_SET_CHMOD', 77005 );
+ define( 'PCLZIP_OPT_EXTRACT_AS_STRING', 77006 );
+ define( 'PCLZIP_OPT_NO_COMPRESSION', 77007 );
+ define( 'PCLZIP_OPT_BY_NAME', 77008 );
+ define( 'PCLZIP_OPT_BY_INDEX', 77009 );
+ define( 'PCLZIP_OPT_BY_EREG', 77010 );
+ define( 'PCLZIP_OPT_BY_PREG', 77011 );
+ define( 'PCLZIP_OPT_COMMENT', 77012 );
+ define( 'PCLZIP_OPT_ADD_COMMENT', 77013 );
+ define( 'PCLZIP_OPT_PREPEND_COMMENT', 77014 );
+ define( 'PCLZIP_OPT_EXTRACT_IN_OUTPUT', 77015 );
+ define( 'PCLZIP_OPT_REPLACE_NEWER', 77016 );
+ define( 'PCLZIP_OPT_STOP_ON_ERROR', 77017 );
+ // Having big trouble with crypt. Need to multiply 2 long int
+ // which is not correctly supported by PHP ...
+ //define( 'PCLZIP_OPT_CRYPT', 77018 );
+ define( 'PCLZIP_OPT_EXTRACT_DIR_RESTRICTION', 77019 );
+
+ // ----- File description attributes
+ define( 'PCLZIP_ATT_FILE_NAME', 79001 );
+ define( 'PCLZIP_ATT_FILE_NEW_SHORT_NAME', 79002 );
+ define( 'PCLZIP_ATT_FILE_NEW_FULL_NAME', 79003 );
+
+ // ----- Call backs values
+ define( 'PCLZIP_CB_PRE_EXTRACT', 78001 );
+ define( 'PCLZIP_CB_POST_EXTRACT', 78002 );
+ define( 'PCLZIP_CB_PRE_ADD', 78003 );
+ define( 'PCLZIP_CB_POST_ADD', 78004 );
+ /* For futur use
+ define( 'PCLZIP_CB_PRE_LIST', 78005 );
+ define( 'PCLZIP_CB_POST_LIST', 78006 );
+ define( 'PCLZIP_CB_PRE_DELETE', 78007 );
+ define( 'PCLZIP_CB_POST_DELETE', 78008 );
+ */
+
+ // --------------------------------------------------------------------------------
+ // Class : PclZip
+ // Description :
+ // PclZip is the class that represent a Zip archive.
+ // The public methods allow the manipulation of the archive.
+ // Attributes :
+ // Attributes must not be accessed directly.
+ // Methods :
+ // PclZip() : Object creator
+ // create() : Creates the Zip archive
+ // listContent() : List the content of the Zip archive
+ // extract() : Extract the content of the archive
+ // properties() : List the properties of the archive
+ // --------------------------------------------------------------------------------
+ class PclZip
+ {
+ // ----- Filename of the zip file
+ var $zipname = '';
+
+ // ----- File descriptor of the zip file
+ var $zip_fd = 0;
+
+ // ----- Internal error handling
+ var $error_code = 1;
+ var $error_string = '';
+
+ // ----- Current status of the magic_quotes_runtime
+ // This value store the php configuration for magic_quotes
+ // The class can then disable the magic_quotes and reset it after
+ var $magic_quotes_status;
+
+ // --------------------------------------------------------------------------------
+ // Function : PclZip()
+ // Description :
+ // Creates a PclZip object and set the name of the associated Zip archive
+ // filename.
+ // Note that no real action is taken, if the archive does not exist it is not
+ // created. Use create() for that.
+ // --------------------------------------------------------------------------------
+ function PclZip($p_zipname)
+ {
+ //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, 'PclZip::PclZip', "zipname=$p_zipname");
+
+ // ----- Tests the zlib
+ if (!function_exists('gzopen'))
+ {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 1, "zlib extension seems to be missing");
+ die('Abort '.basename(__FILE__).' : Missing zlib extensions');
+ }
+
+ // ----- Set the attributes
+ $this->zipname = $p_zipname;
+ $this->zip_fd = 0;
+ $this->magic_quotes_status = -1;
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 1);
+ return;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function :
+ // create($p_filelist, $p_add_dir="", $p_remove_dir="")
+ // create($p_filelist, $p_option, $p_option_value, ...)
+ // Description :
+ // This method supports two different synopsis. The first one is historical.
+ // This method creates a Zip Archive. The Zip file is created in the
+ // filesystem. The files and directories indicated in $p_filelist
+ // are added in the archive. See the parameters description for the
+ // supported format of $p_filelist.
+ // When a directory is in the list, the directory and its content is added
+ // in the archive.
+ // In this synopsis, the function takes an optional variable list of
+ // options. See bellow the supported options.
+ // Parameters :
+ // $p_filelist : An array containing file or directory names, or
+ // a string containing one filename or one directory name, or
+ // a string containing a list of filenames and/or directory
+ // names separated by spaces.
+ // $p_add_dir : A path to add before the real path of the archived file,
+ // in order to have it memorized in the archive.
+ // $p_remove_dir : A path to remove from the real path of the file to archive,
+ // in order to have a shorter path memorized in the archive.
+ // When $p_add_dir and $p_remove_dir are set, $p_remove_dir
+ // is removed first, before $p_add_dir is added.
+ // Options :
+ // PCLZIP_OPT_ADD_PATH :
+ // PCLZIP_OPT_REMOVE_PATH :
+ // PCLZIP_OPT_REMOVE_ALL_PATH :
+ // PCLZIP_OPT_COMMENT :
+ // PCLZIP_CB_PRE_ADD :
+ // PCLZIP_CB_POST_ADD :
+ // Return Values :
+ // 0 on failure,
+ // The list of the added files, with a status of the add action.
+ // (see PclZip::listContent() for list entry format)
+ // --------------------------------------------------------------------------------
+ function create($p_filelist)
+ {
+ //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, 'PclZip::create', "filelist='$p_filelist', ...");
+ $v_result=1;
+
+ // ----- Reset the error handler
+ $this->privErrorReset();
+
+ // ----- Set default values
+ $v_options = array();
+ $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE;
+
+ // ----- Look for variable options arguments
+ $v_size = func_num_args();
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "$v_size arguments passed to the method");
+
+ // ----- Look for arguments
+ if ($v_size > 1) {
+ // ----- Get the arguments
+ $v_arg_list = func_get_args();
+
+ // ----- Remove from the options list the first argument
+ array_shift($v_arg_list);
+ $v_size--;
+
+ // ----- Look for first arg
+ if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Variable list of options detected");
+
+ // ----- Parse the options
+ $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
+ array (PCLZIP_OPT_REMOVE_PATH => 'optional',
+ PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
+ PCLZIP_OPT_ADD_PATH => 'optional',
+ PCLZIP_CB_PRE_ADD => 'optional',
+ PCLZIP_CB_POST_ADD => 'optional',
+ PCLZIP_OPT_NO_COMPRESSION => 'optional',
+ PCLZIP_OPT_COMMENT => 'optional'
+ //, PCLZIP_OPT_CRYPT => 'optional'
+ ));
+ if ($v_result != 1) {
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
+ return 0;
+ }
+ }
+
+ // ----- Look for 2 args
+ // Here we need to support the first historic synopsis of the
+ // method.
+ else {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Static synopsis");
+
+ // ----- Get the first argument
+ $v_options[PCLZIP_OPT_ADD_PATH] = $v_arg_list[0];
+
+ // ----- Look for the optional second argument
+ if ($v_size == 2) {
+ $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1];
+ }
+ else if ($v_size > 2) {
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER,
+ "Invalid number / type of arguments");
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
+ return 0;
+ }
+ }
+ }
+
+ // ----- Init
+ $v_string_list = array();
+ $v_att_list = array();
+ $v_filedescr_list = array();
+ $p_result_list = array();
+
+ // ----- Look if the $p_filelist is really an array
+ if (is_array($p_filelist)) {
+
+ // ----- Look if the first element is also an array
+ // This will mean that this is a file description entry
+ if (isset($p_filelist[0]) && is_array($p_filelist[0])) {
+ $v_att_list = $p_filelist;
+ }
+
+ // ----- The list is a list of string names
+ else {
+ $v_string_list = $p_filelist;
+ }
+ }
+
+ // ----- Look if the $p_filelist is a string
+ else if (is_string($p_filelist)) {
+ // ----- Create a list from the string
+ $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist);
+ }
+
+ // ----- Invalid variable type for $p_filelist
+ else {
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_filelist");
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
+ return 0;
+ }
+
+ // ----- Reformat the string list
+ if (sizeof($v_string_list) != 0) {
+ foreach ($v_string_list as $v_string) {
+ if ($v_string != '') {
+ $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string;
+ }
+ else {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Ignore an empty filename");
+ }
+ }
+ }
+
+ // ----- For each file in the list check the attributes
+ $v_supported_attributes
+ = array ( PCLZIP_ATT_FILE_NAME => 'mandatory'
+ ,PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional'
+ ,PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional'
+ );
+ foreach ($v_att_list as $v_entry) {
+ $v_result = $this->privFileDescrParseAtt($v_entry,
+ $v_filedescr_list[],
+ $v_options,
+ $v_supported_attributes);
+ if ($v_result != 1) {
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
+ return 0;
+ }
+ }
+
+ // ----- Expand the filelist (expand directories)
+ $v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options);
+ if ($v_result != 1) {
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
+ return 0;
+ }
+
+ // ----- Call the create fct
+ $v_result = $this->privCreate($v_filedescr_list, $p_result_list, $v_options);
+ if ($v_result != 1) {
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
+ return 0;
+ }
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $p_result_list);
+ return $p_result_list;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function :
+ // add($p_filelist, $p_add_dir="", $p_remove_dir="")
+ // add($p_filelist, $p_option, $p_option_value, ...)
+ // Description :
+ // This method supports two synopsis. The first one is historical.
+ // This methods add the list of files in an existing archive.
+ // If a file with the same name already exists, it is added at the end of the
+ // archive, the first one is still present.
+ // If the archive does not exist, it is created.
+ // Parameters :
+ // $p_filelist : An array containing file or directory names, or
+ // a string containing one filename or one directory name, or
+ // a string containing a list of filenames and/or directory
+ // names separated by spaces.
+ // $p_add_dir : A path to add before the real path of the archived file,
+ // in order to have it memorized in the archive.
+ // $p_remove_dir : A path to remove from the real path of the file to archive,
+ // in order to have a shorter path memorized in the archive.
+ // When $p_add_dir and $p_remove_dir are set, $p_remove_dir
+ // is removed first, before $p_add_dir is added.
+ // Options :
+ // PCLZIP_OPT_ADD_PATH :
+ // PCLZIP_OPT_REMOVE_PATH :
+ // PCLZIP_OPT_REMOVE_ALL_PATH :
+ // PCLZIP_OPT_COMMENT :
+ // PCLZIP_OPT_ADD_COMMENT :
+ // PCLZIP_OPT_PREPEND_COMMENT :
+ // PCLZIP_CB_PRE_ADD :
+ // PCLZIP_CB_POST_ADD :
+ // Return Values :
+ // 0 on failure,
+ // The list of the added files, with a status of the add action.
+ // (see PclZip::listContent() for list entry format)
+ // --------------------------------------------------------------------------------
+ function add($p_filelist)
+ {
+ //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, 'PclZip::add', "filelist='$p_filelist', ...");
+ $v_result=1;
+
+ // ----- Reset the error handler
+ $this->privErrorReset();
+
+ // ----- Set default values
+ $v_options = array();
+ $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE;
+
+ // ----- Look for variable options arguments
+ $v_size = func_num_args();
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "$v_size arguments passed to the method");
+
+ // ----- Look for arguments
+ if ($v_size > 1) {
+ // ----- Get the arguments
+ $v_arg_list = func_get_args();
+
+ // ----- Remove form the options list the first argument
+ array_shift($v_arg_list);
+ $v_size--;
+
+ // ----- Look for first arg
+ if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Variable list of options detected");
+
+ // ----- Parse the options
+ $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
+ array (PCLZIP_OPT_REMOVE_PATH => 'optional',
+ PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
+ PCLZIP_OPT_ADD_PATH => 'optional',
+ PCLZIP_CB_PRE_ADD => 'optional',
+ PCLZIP_CB_POST_ADD => 'optional',
+ PCLZIP_OPT_NO_COMPRESSION => 'optional',
+ PCLZIP_OPT_COMMENT => 'optional',
+ PCLZIP_OPT_ADD_COMMENT => 'optional',
+ PCLZIP_OPT_PREPEND_COMMENT => 'optional'
+ //, PCLZIP_OPT_CRYPT => 'optional'
+ ));
+ if ($v_result != 1) {
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
+ return 0;
+ }
+ }
+
+ // ----- Look for 2 args
+ // Here we need to support the first historic synopsis of the
+ // method.
+ else {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Static synopsis");
+
+ // ----- Get the first argument
+ $v_options[PCLZIP_OPT_ADD_PATH] = $v_add_path = $v_arg_list[0];
+
+ // ----- Look for the optional second argument
+ if ($v_size == 2) {
+ $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1];
+ }
+ else if ($v_size > 2) {
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
+ return 0;
+ }
+ }
+ }
+
+ // ----- Init
+ $v_string_list = array();
+ $v_att_list = array();
+ $v_filedescr_list = array();
+ $p_result_list = array();
+
+ // ----- Look if the $p_filelist is really an array
+ if (is_array($p_filelist)) {
+
+ // ----- Look if the first element is also an array
+ // This will mean that this is a file description entry
+ if (isset($p_filelist[0]) && is_array($p_filelist[0])) {
+ $v_att_list = $p_filelist;
+ }
+
+ // ----- The list is a list of string names
+ else {
+ $v_string_list = $p_filelist;
+ }
+ }
+
+ // ----- Look if the $p_filelist is a string
+ else if (is_string($p_filelist)) {
+ // ----- Create a list from the string
+ $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist);
+ }
+
+ // ----- Invalid variable type for $p_filelist
+ else {
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type '".gettype($p_filelist)."' for p_filelist");
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
+ return 0;
+ }
+
+ // ----- Reformat the string list
+ if (sizeof($v_string_list) != 0) {
+ foreach ($v_string_list as $v_string) {
+ $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string;
+ }
+ }
+
+ // ----- For each file in the list check the attributes
+ $v_supported_attributes
+ = array ( PCLZIP_ATT_FILE_NAME => 'mandatory'
+ ,PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional'
+ ,PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional'
+ );
+ foreach ($v_att_list as $v_entry) {
+ $v_result = $this->privFileDescrParseAtt($v_entry,
+ $v_filedescr_list[],
+ $v_options,
+ $v_supported_attributes);
+ if ($v_result != 1) {
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
+ return 0;
+ }
+ }
+
+ // ----- Expand the filelist (expand directories)
+ $v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options);
+ if ($v_result != 1) {
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
+ return 0;
+ }
+
+ // ----- Call the create fct
+ $v_result = $this->privAdd($v_filedescr_list, $p_result_list, $v_options);
+ if ($v_result != 1) {
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
+ return 0;
+ }
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $p_result_list);
+ return $p_result_list;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : listContent()
+ // Description :
+ // This public method, gives the list of the files and directories, with their
+ // properties.
+ // The properties of each entries in the list are (used also in other functions) :
+ // filename : Name of the file. For a create or add action it is the filename
+ // given by the user. For an extract function it is the filename
+ // of the extracted file.
+ // stored_filename : Name of the file / directory stored in the archive.
+ // size : Size of the stored file.
+ // compressed_size : Size of the file's data compressed in the archive
+ // (without the headers overhead)
+ // mtime : Last known modification date of the file (UNIX timestamp)
+ // comment : Comment associated with the file
+ // folder : true | false
+ // index : index of the file in the archive
+ // status : status of the action (depending of the action) :
+ // Values are :
+ // ok : OK !
+ // filtered : the file / dir is not extracted (filtered by user)
+ // already_a_directory : the file can not be extracted because a
+ // directory with the same name already exists
+ // write_protected : the file can not be extracted because a file
+ // with the same name already exists and is
+ // write protected
+ // newer_exist : the file was not extracted because a newer file exists
+ // path_creation_fail : the file is not extracted because the folder
+ // does not exists and can not be created
+ // write_error : the file was not extracted because there was a
+ // error while writing the file
+ // read_error : the file was not extracted because there was a error
+ // while reading the file
+ // invalid_header : the file was not extracted because of an archive
+ // format error (bad file header)
+ // Note that each time a method can continue operating when there
+ // is an action error on a file, the error is only logged in the file status.
+ // Return Values :
+ // 0 on an unrecoverable failure,
+ // The list of the files in the archive.
+ // --------------------------------------------------------------------------------
+ function listContent()
+ {
+ //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, 'PclZip::listContent', "");
+ $v_result=1;
+
+ // ----- Reset the error handler
+ $this->privErrorReset();
+
+ // ----- Check archive
+ if (!$this->privCheckFormat()) {
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
+ return(0);
+ }
+
+ // ----- Call the extracting fct
+ $p_list = array();
+ if (($v_result = $this->privList($p_list)) != 1)
+ {
+ unset($p_list);
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0, PclZip::errorInfo());
+ return(0);
+ }
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $p_list);
+ return $p_list;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function :
+ // extract($p_path="./", $p_remove_path="")
+ // extract([$p_option, $p_option_value, ...])
+ // Description :
+ // This method supports two synopsis. The first one is historical.
+ // This method extract all the files / directories from the archive to the
+ // folder indicated in $p_path.
+ // If you want to ignore the 'root' part of path of the memorized files
+ // you can indicate this in the optional $p_remove_path parameter.
+ // By default, if a newer file with the same name already exists, the
+ // file is not extracted.
+ //
+ // If both PCLZIP_OPT_PATH and PCLZIP_OPT_ADD_PATH aoptions
+ // are used, the path indicated in PCLZIP_OPT_ADD_PATH is append
+ // at the end of the path value of PCLZIP_OPT_PATH.
+ // Parameters :
+ // $p_path : Path where the files and directories are to be extracted
+ // $p_remove_path : First part ('root' part) of the memorized path
+ // (if any similar) to remove while extracting.
+ // Options :
+ // PCLZIP_OPT_PATH :
+ // PCLZIP_OPT_ADD_PATH :
+ // PCLZIP_OPT_REMOVE_PATH :
+ // PCLZIP_OPT_REMOVE_ALL_PATH :
+ // PCLZIP_CB_PRE_EXTRACT :
+ // PCLZIP_CB_POST_EXTRACT :
+ // Return Values :
+ // 0 or a negative value on failure,
+ // The list of the extracted files, with a status of the action.
+ // (see PclZip::listContent() for list entry format)
+ // --------------------------------------------------------------------------------
+ function extract()
+ {
+ //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::extract", "");
+ $v_result=1;
+
+ // ----- Reset the error handler
+ $this->privErrorReset();
+
+ // ----- Check archive
+ if (!$this->privCheckFormat()) {
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
+ return(0);
+ }
+
+ // ----- Set default values
+ $v_options = array();
+// $v_path = "./";
+ $v_path = '';
+ $v_remove_path = "";
+ $v_remove_all_path = false;
+
+ // ----- Look for variable options arguments
+ $v_size = func_num_args();
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "$v_size arguments passed to the method");
+
+ // ----- Default values for option
+ $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE;
+
+ // ----- Look for arguments
+ if ($v_size > 0) {
+ // ----- Get the arguments
+ $v_arg_list = func_get_args();
+
+ // ----- Look for first arg
+ if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Variable list of options");
+
+ // ----- Parse the options
+ $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
+ array (PCLZIP_OPT_PATH => 'optional',
+ PCLZIP_OPT_REMOVE_PATH => 'optional',
+ PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
+ PCLZIP_OPT_ADD_PATH => 'optional',
+ PCLZIP_CB_PRE_EXTRACT => 'optional',
+ PCLZIP_CB_POST_EXTRACT => 'optional',
+ PCLZIP_OPT_SET_CHMOD => 'optional',
+ PCLZIP_OPT_BY_NAME => 'optional',
+ PCLZIP_OPT_BY_EREG => 'optional',
+ PCLZIP_OPT_BY_PREG => 'optional',
+ PCLZIP_OPT_BY_INDEX => 'optional',
+ PCLZIP_OPT_EXTRACT_AS_STRING => 'optional',
+ PCLZIP_OPT_EXTRACT_IN_OUTPUT => 'optional',
+ PCLZIP_OPT_REPLACE_NEWER => 'optional'
+ ,PCLZIP_OPT_STOP_ON_ERROR => 'optional'
+ ,PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional'
+ ));
+ if ($v_result != 1) {
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
+ return 0;
+ }
+
+ // ----- Set the arguments
+ if (isset($v_options[PCLZIP_OPT_PATH])) {
+ $v_path = $v_options[PCLZIP_OPT_PATH];
+ }
+ if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) {
+ $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH];
+ }
+ if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {
+ $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH];
+ }
+ if (isset($v_options[PCLZIP_OPT_ADD_PATH])) {
+ // ----- Check for '/' in last path char
+ if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) {
+ $v_path .= '/';
+ }
+ $v_path .= $v_options[PCLZIP_OPT_ADD_PATH];
+ }
+ }
+
+ // ----- Look for 2 args
+ // Here we need to support the first historic synopsis of the
+ // method.
+ else {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Static synopsis");
+
+ // ----- Get the first argument
+ $v_path = $v_arg_list[0];
+
+ // ----- Look for the optional second argument
+ if ($v_size == 2) {
+ $v_remove_path = $v_arg_list[1];
+ }
+ else if ($v_size > 2) {
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0, PclZip::errorInfo());
+ return 0;
+ }
+ }
+ }
+
+ // ----- Trace
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "path='$v_path', remove_path='$v_remove_path', remove_all_path='".($v_remove_path?'true':'false')."'");
+
+ // ----- Call the extracting fct
+ $p_list = array();
+ $v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path,
+ $v_remove_all_path, $v_options);
+ if ($v_result < 1) {
+ unset($p_list);
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0, PclZip::errorInfo());
+ return(0);
+ }
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $p_list);
+ return $p_list;
+ }
+ // --------------------------------------------------------------------------------
+
+
+ // --------------------------------------------------------------------------------
+ // Function :
+ // extractByIndex($p_index, $p_path="./", $p_remove_path="")
+ // extractByIndex($p_index, [$p_option, $p_option_value, ...])
+ // Description :
+ // This method supports two synopsis. The first one is historical.
+ // This method is doing a partial extract of the archive.
+ // The extracted files or folders are identified by their index in the
+ // archive (from 0 to n).
+ // Note that if the index identify a folder, only the folder entry is
+ // extracted, not all the files included in the archive.
+ // Parameters :
+ // $p_index : A single index (integer) or a string of indexes of files to
+ // extract. The form of the string is "0,4-6,8-12" with only numbers
+ // and '-' for range or ',' to separate ranges. No spaces or ';'
+ // are allowed.
+ // $p_path : Path where the files and directories are to be extracted
+ // $p_remove_path : First part ('root' part) of the memorized path
+ // (if any similar) to remove while extracting.
+ // Options :
+ // PCLZIP_OPT_PATH :
+ // PCLZIP_OPT_ADD_PATH :
+ // PCLZIP_OPT_REMOVE_PATH :
+ // PCLZIP_OPT_REMOVE_ALL_PATH :
+ // PCLZIP_OPT_EXTRACT_AS_STRING : The files are extracted as strings and
+ // not as files.
+ // The resulting content is in a new field 'content' in the file
+ // structure.
+ // This option must be used alone (any other options are ignored).
+ // PCLZIP_CB_PRE_EXTRACT :
+ // PCLZIP_CB_POST_EXTRACT :
+ // Return Values :
+ // 0 on failure,
+ // The list of the extracted files, with a status of the action.
+ // (see PclZip::listContent() for list entry format)
+ // --------------------------------------------------------------------------------
+ //function extractByIndex($p_index, options...)
+ function extractByIndex($p_index)
+ {
+ //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::extractByIndex", "index='$p_index', ...");
+ $v_result=1;
+
+ // ----- Reset the error handler
+ $this->privErrorReset();
+
+ // ----- Check archive
+ if (!$this->privCheckFormat()) {
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
+ return(0);
+ }
+
+ // ----- Set default values
+ $v_options = array();
+// $v_path = "./";
+ $v_path = '';
+ $v_remove_path = "";
+ $v_remove_all_path = false;
+
+ // ----- Look for variable options arguments
+ $v_size = func_num_args();
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "$v_size arguments passed to the method");
+
+ // ----- Default values for option
+ $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE;
+
+ // ----- Look for arguments
+ if ($v_size > 1) {
+ // ----- Get the arguments
+ $v_arg_list = func_get_args();
+
+ // ----- Remove form the options list the first argument
+ array_shift($v_arg_list);
+ $v_size--;
+
+ // ----- Look for first arg
+ if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Variable list of options");
+
+ // ----- Parse the options
+ $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
+ array (PCLZIP_OPT_PATH => 'optional',
+ PCLZIP_OPT_REMOVE_PATH => 'optional',
+ PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
+ PCLZIP_OPT_EXTRACT_AS_STRING => 'optional',
+ PCLZIP_OPT_ADD_PATH => 'optional',
+ PCLZIP_CB_PRE_EXTRACT => 'optional',
+ PCLZIP_CB_POST_EXTRACT => 'optional',
+ PCLZIP_OPT_SET_CHMOD => 'optional',
+ PCLZIP_OPT_REPLACE_NEWER => 'optional'
+ ,PCLZIP_OPT_STOP_ON_ERROR => 'optional'
+ ,PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional'
+ ));
+ if ($v_result != 1) {
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
+ return 0;
+ }
+
+ // ----- Set the arguments
+ if (isset($v_options[PCLZIP_OPT_PATH])) {
+ $v_path = $v_options[PCLZIP_OPT_PATH];
+ }
+ if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) {
+ $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH];
+ }
+ if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {
+ $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH];
+ }
+ if (isset($v_options[PCLZIP_OPT_ADD_PATH])) {
+ // ----- Check for '/' in last path char
+ if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) {
+ $v_path .= '/';
+ }
+ $v_path .= $v_options[PCLZIP_OPT_ADD_PATH];
+ }
+ if (!isset($v_options[PCLZIP_OPT_EXTRACT_AS_STRING])) {
+ $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE;
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Option PCLZIP_OPT_EXTRACT_AS_STRING not set.");
+ }
+ else {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Option PCLZIP_OPT_EXTRACT_AS_STRING set.");
+ }
+ }
+
+ // ----- Look for 2 args
+ // Here we need to support the first historic synopsis of the
+ // method.
+ else {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Static synopsis");
+
+ // ----- Get the first argument
+ $v_path = $v_arg_list[0];
+
+ // ----- Look for the optional second argument
+ if ($v_size == 2) {
+ $v_remove_path = $v_arg_list[1];
+ }
+ else if ($v_size > 2) {
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
+ return 0;
+ }
+ }
+ }
+
+ // ----- Trace
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "index='$p_index', path='$v_path', remove_path='$v_remove_path', remove_all_path='".($v_remove_path?'true':'false')."'");
+
+ // ----- Trick
+ // Here I want to reuse extractByRule(), so I need to parse the $p_index
+ // with privParseOptions()
+ $v_arg_trick = array (PCLZIP_OPT_BY_INDEX, $p_index);
+ $v_options_trick = array();
+ $v_result = $this->privParseOptions($v_arg_trick, sizeof($v_arg_trick), $v_options_trick,
+ array (PCLZIP_OPT_BY_INDEX => 'optional' ));
+ if ($v_result != 1) {
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
+ return 0;
+ }
+ $v_options[PCLZIP_OPT_BY_INDEX] = $v_options_trick[PCLZIP_OPT_BY_INDEX];
+
+ // ----- Call the extracting fct
+ if (($v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path, $v_remove_all_path, $v_options)) < 1) {
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0, PclZip::errorInfo());
+ return(0);
+ }
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $p_list);
+ return $p_list;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function :
+ // delete([$p_option, $p_option_value, ...])
+ // Description :
+ // This method removes files from the archive.
+ // If no parameters are given, then all the archive is emptied.
+ // Parameters :
+ // None or optional arguments.
+ // Options :
+ // PCLZIP_OPT_BY_INDEX :
+ // PCLZIP_OPT_BY_NAME :
+ // PCLZIP_OPT_BY_EREG :
+ // PCLZIP_OPT_BY_PREG :
+ // Return Values :
+ // 0 on failure,
+ // The list of the files which are still present in the archive.
+ // (see PclZip::listContent() for list entry format)
+ // --------------------------------------------------------------------------------
+ function delete()
+ {
+ //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::delete", "");
+ $v_result=1;
+
+ // ----- Reset the error handler
+ $this->privErrorReset();
+
+ // ----- Check archive
+ if (!$this->privCheckFormat()) {
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
+ return(0);
+ }
+
+ // ----- Set default values
+ $v_options = array();
+
+ // ----- Look for variable options arguments
+ $v_size = func_num_args();
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "$v_size arguments passed to the method");
+
+ // ----- Look for arguments
+ if ($v_size > 0) {
+ // ----- Get the arguments
+ $v_arg_list = func_get_args();
+
+ // ----- Parse the options
+ $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
+ array (PCLZIP_OPT_BY_NAME => 'optional',
+ PCLZIP_OPT_BY_EREG => 'optional',
+ PCLZIP_OPT_BY_PREG => 'optional',
+ PCLZIP_OPT_BY_INDEX => 'optional' ));
+ if ($v_result != 1) {
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
+ return 0;
+ }
+ }
+
+ // ----- Magic quotes trick
+ $this->privDisableMagicQuotes();
+
+ // ----- Call the delete fct
+ $v_list = array();
+ if (($v_result = $this->privDeleteByRule($v_list, $v_options)) != 1) {
+ $this->privSwapBackMagicQuotes();
+ unset($v_list);
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0, PclZip::errorInfo());
+ return(0);
+ }
+
+ // ----- Magic quotes trick
+ $this->privSwapBackMagicQuotes();
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_list);
+ return $v_list;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : deleteByIndex()
+ // Description :
+ // ***** Deprecated *****
+ // delete(PCLZIP_OPT_BY_INDEX, $p_index) should be prefered.
+ // --------------------------------------------------------------------------------
+ function deleteByIndex($p_index)
+ {
+ //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::deleteByIndex", "index='$p_index'");
+
+ $p_list = $this->delete(PCLZIP_OPT_BY_INDEX, $p_index);
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $p_list);
+ return $p_list;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : properties()
+ // Description :
+ // This method gives the properties of the archive.
+ // The properties are :
+ // nb : Number of files in the archive
+ // comment : Comment associated with the archive file
+ // status : not_exist, ok
+ // Parameters :
+ // None
+ // Return Values :
+ // 0 on failure,
+ // An array with the archive properties.
+ // --------------------------------------------------------------------------------
+ function properties()
+ {
+ //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::properties", "");
+
+ // ----- Reset the error handler
+ $this->privErrorReset();
+
+ // ----- Magic quotes trick
+ $this->privDisableMagicQuotes();
+
+ // ----- Check archive
+ if (!$this->privCheckFormat()) {
+ $this->privSwapBackMagicQuotes();
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
+ return(0);
+ }
+
+ // ----- Default properties
+ $v_prop = array();
+ $v_prop['comment'] = '';
+ $v_prop['nb'] = 0;
+ $v_prop['status'] = 'not_exist';
+
+ // ----- Look if file exists
+ if (@is_file($this->zipname))
+ {
+ // ----- Open the zip file
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode");
+ if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0)
+ {
+ $this->privSwapBackMagicQuotes();
+
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in binary read mode');
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), 0);
+ return 0;
+ }
+
+ // ----- Read the central directory informations
+ $v_central_dir = array();
+ if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
+ {
+ $this->privSwapBackMagicQuotes();
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
+ return 0;
+ }
+
+ // ----- Close the zip file
+ $this->privCloseFd();
+
+ // ----- Set the user attributes
+ $v_prop['comment'] = $v_central_dir['comment'];
+ $v_prop['nb'] = $v_central_dir['entries'];
+ $v_prop['status'] = 'ok';
+ }
+
+ // ----- Magic quotes trick
+ $this->privSwapBackMagicQuotes();
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_prop);
+ return $v_prop;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : duplicate()
+ // Description :
+ // This method creates an archive by copying the content of an other one. If
+ // the archive already exist, it is replaced by the new one without any warning.
+ // Parameters :
+ // $p_archive : The filename of a valid archive, or
+ // a valid PclZip object.
+ // Return Values :
+ // 1 on success.
+ // 0 or a negative value on error (error code).
+ // --------------------------------------------------------------------------------
+ function duplicate($p_archive)
+ {
+ //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::duplicate", "");
+ $v_result = 1;
+
+ // ----- Reset the error handler
+ $this->privErrorReset();
+
+ // ----- Look if the $p_archive is a PclZip object
+ if ((is_object($p_archive)) && (get_class($p_archive) == 'pclzip'))
+ {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "The parameter is valid PclZip object '".$p_archive->zipname."'");
+
+ // ----- Duplicate the archive
+ $v_result = $this->privDuplicate($p_archive->zipname);
+ }
+
+ // ----- Look if the $p_archive is a string (so a filename)
+ else if (is_string($p_archive))
+ {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "The parameter is a filename '$p_archive'");
+
+ // ----- Check that $p_archive is a valid zip file
+ // TBC : Should also check the archive format
+ if (!is_file($p_archive)) {
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "No file with filename '".$p_archive."'");
+ $v_result = PCLZIP_ERR_MISSING_FILE;
+ }
+ else {
+ // ----- Duplicate the archive
+ $v_result = $this->privDuplicate($p_archive);
+ }
+ }
+
+ // ----- Invalid variable
+ else
+ {
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add");
+ $v_result = PCLZIP_ERR_INVALID_PARAMETER;
+ }
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : merge()
+ // Description :
+ // This method merge the $p_archive_to_add archive at the end of the current
+ // one ($this).
+ // If the archive ($this) does not exist, the merge becomes a duplicate.
+ // If the $p_archive_to_add archive does not exist, the merge is a success.
+ // Parameters :
+ // $p_archive_to_add : It can be directly the filename of a valid zip archive,
+ // or a PclZip object archive.
+ // Return Values :
+ // 1 on success,
+ // 0 or negative values on error (see below).
+ // --------------------------------------------------------------------------------
+ function merge($p_archive_to_add)
+ {
+ //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::merge", "");
+ $v_result = 1;
+
+ // ----- Reset the error handler
+ $this->privErrorReset();
+
+ // ----- Check archive
+ if (!$this->privCheckFormat()) {
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
+ return(0);
+ }
+
+ // ----- Look if the $p_archive_to_add is a PclZip object
+ if ((is_object($p_archive_to_add)) && (get_class($p_archive_to_add) == 'pclzip'))
+ {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The parameter is valid PclZip object");
+
+ // ----- Merge the archive
+ $v_result = $this->privMerge($p_archive_to_add);
+ }
+
+ // ----- Look if the $p_archive_to_add is a string (so a filename)
+ else if (is_string($p_archive_to_add))
+ {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The parameter is a filename");
+
+ // ----- Create a temporary archive
+ $v_object_archive = new PclZip($p_archive_to_add);
+
+ // ----- Merge the archive
+ $v_result = $this->privMerge($v_object_archive);
+ }
+
+ // ----- Invalid variable
+ else
+ {
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add");
+ $v_result = PCLZIP_ERR_INVALID_PARAMETER;
+ }
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+ // --------------------------------------------------------------------------------
+
+
+
+ // --------------------------------------------------------------------------------
+ // Function : errorCode()
+ // Description :
+ // Parameters :
+ // --------------------------------------------------------------------------------
+ function errorCode()
+ {
+ if (PCLZIP_ERROR_EXTERNAL == 1) {
+ return(PclErrorCode());
+ }
+ else {
+ return($this->error_code);
+ }
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : errorName()
+ // Description :
+ // Parameters :
+ // --------------------------------------------------------------------------------
+ function errorName($p_with_code=false)
+ {
+ $v_name = array ( PCLZIP_ERR_NO_ERROR => 'PCLZIP_ERR_NO_ERROR',
+ PCLZIP_ERR_WRITE_OPEN_FAIL => 'PCLZIP_ERR_WRITE_OPEN_FAIL',
+ PCLZIP_ERR_READ_OPEN_FAIL => 'PCLZIP_ERR_READ_OPEN_FAIL',
+ PCLZIP_ERR_INVALID_PARAMETER => 'PCLZIP_ERR_INVALID_PARAMETER',
+ PCLZIP_ERR_MISSING_FILE => 'PCLZIP_ERR_MISSING_FILE',
+ PCLZIP_ERR_FILENAME_TOO_LONG => 'PCLZIP_ERR_FILENAME_TOO_LONG',
+ PCLZIP_ERR_INVALID_ZIP => 'PCLZIP_ERR_INVALID_ZIP',
+ PCLZIP_ERR_BAD_EXTRACTED_FILE => 'PCLZIP_ERR_BAD_EXTRACTED_FILE',
+ PCLZIP_ERR_DIR_CREATE_FAIL => 'PCLZIP_ERR_DIR_CREATE_FAIL',
+ PCLZIP_ERR_BAD_EXTENSION => 'PCLZIP_ERR_BAD_EXTENSION',
+ PCLZIP_ERR_BAD_FORMAT => 'PCLZIP_ERR_BAD_FORMAT',
+ PCLZIP_ERR_DELETE_FILE_FAIL => 'PCLZIP_ERR_DELETE_FILE_FAIL',
+ PCLZIP_ERR_RENAME_FILE_FAIL => 'PCLZIP_ERR_RENAME_FILE_FAIL',
+ PCLZIP_ERR_BAD_CHECKSUM => 'PCLZIP_ERR_BAD_CHECKSUM',
+ PCLZIP_ERR_INVALID_ARCHIVE_ZIP => 'PCLZIP_ERR_INVALID_ARCHIVE_ZIP',
+ PCLZIP_ERR_MISSING_OPTION_VALUE => 'PCLZIP_ERR_MISSING_OPTION_VALUE',
+ PCLZIP_ERR_INVALID_OPTION_VALUE => 'PCLZIP_ERR_INVALID_OPTION_VALUE',
+ PCLZIP_ERR_UNSUPPORTED_COMPRESSION => 'PCLZIP_ERR_UNSUPPORTED_COMPRESSION',
+ PCLZIP_ERR_UNSUPPORTED_ENCRYPTION => 'PCLZIP_ERR_UNSUPPORTED_ENCRYPTION'
+ ,PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE => 'PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE'
+ ,PCLZIP_ERR_DIRECTORY_RESTRICTION => 'PCLZIP_ERR_DIRECTORY_RESTRICTION'
+ );
+
+ if (isset($v_name[$this->error_code])) {
+ $v_value = $v_name[$this->error_code];
+ }
+ else {
+ $v_value = 'NoName';
+ }
+
+ if ($p_with_code) {
+ return($v_value.' ('.$this->error_code.')');
+ }
+ else {
+ return($v_value);
+ }
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : errorInfo()
+ // Description :
+ // Parameters :
+ // --------------------------------------------------------------------------------
+ function errorInfo($p_full=false)
+ {
+ if (PCLZIP_ERROR_EXTERNAL == 1) {
+ return(PclErrorString());
+ }
+ else {
+ if ($p_full) {
+ return($this->errorName(true)." : ".$this->error_string);
+ }
+ else {
+ return($this->error_string." [code ".$this->error_code."]");
+ }
+ }
+ }
+ // --------------------------------------------------------------------------------
+
+
+// --------------------------------------------------------------------------------
+// ***** UNDER THIS LINE ARE DEFINED PRIVATE INTERNAL FUNCTIONS *****
+// ***** *****
+// ***** THESES FUNCTIONS MUST NOT BE USED DIRECTLY *****
+// --------------------------------------------------------------------------------
+
+
+
+ // --------------------------------------------------------------------------------
+ // Function : privCheckFormat()
+ // Description :
+ // This method check that the archive exists and is a valid zip archive.
+ // Several level of check exists. (futur)
+ // Parameters :
+ // $p_level : Level of check. Default 0.
+ // 0 : Check the first bytes (magic codes) (default value))
+ // 1 : 0 + Check the central directory (futur)
+ // 2 : 1 + Check each file header (futur)
+ // Return Values :
+ // true on success,
+ // false on error, the error code is set.
+ // --------------------------------------------------------------------------------
+ function privCheckFormat($p_level=0)
+ {
+ //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privCheckFormat", "");
+ $v_result = true;
+
+ // ----- Reset the file system cache
+ clearstatcache();
+
+ // ----- Reset the error handler
+ $this->privErrorReset();
+
+ // ----- Look if the file exits
+ if (!is_file($this->zipname)) {
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "Missing archive file '".$this->zipname."'");
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, false, PclZip::errorInfo());
+ return(false);
+ }
+
+ // ----- Check that the file is readeable
+ if (!is_readable($this->zipname)) {
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to read archive '".$this->zipname."'");
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, false, PclZip::errorInfo());
+ return(false);
+ }
+
+ // ----- Check the magic code
+ // TBC
+
+ // ----- Check the central header
+ // TBC
+
+ // ----- Check each file header
+ // TBC
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : privParseOptions()
+ // Description :
+ // This internal methods reads the variable list of arguments ($p_options_list,
+ // $p_size) and generate an array with the options and values ($v_result_list).
+ // $v_requested_options contains the options that can be present and those that
+ // must be present.
+ // $v_requested_options is an array, with the option value as key, and 'optional',
+ // or 'mandatory' as value.
+ // Parameters :
+ // See above.
+ // Return Values :
+ // 1 on success.
+ // 0 on failure.
+ // --------------------------------------------------------------------------------
+ function privParseOptions(&$p_options_list, $p_size, &$v_result_list, $v_requested_options=false)
+ {
+ //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privParseOptions", "");
+ $v_result=1;
+
+ // ----- Read the options
+ $i=0;
+ while ($i<$p_size) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Looking for table index $i, option = '".PclZipUtilOptionText($p_options_list[$i])."(".$p_options_list[$i].")'");
+
+ // ----- Check if the option is supported
+ if (!isset($v_requested_options[$p_options_list[$i]])) {
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid optional parameter '".$p_options_list[$i]."' for this method");
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
+ return PclZip::errorCode();
+ }
+
+ // ----- Look for next option
+ switch ($p_options_list[$i]) {
+ // ----- Look for options that request a path value
+ case PCLZIP_OPT_PATH :
+ case PCLZIP_OPT_REMOVE_PATH :
+ case PCLZIP_OPT_ADD_PATH :
+ // ----- Check the number of parameters
+ if (($i+1) >= $p_size) {
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
+ return PclZip::errorCode();
+ }
+
+ // ----- Get the value
+ $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], false);
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($p_options_list[$i])." = '".$v_result_list[$p_options_list[$i]]."'");
+ $i++;
+ break;
+
+ case PCLZIP_OPT_EXTRACT_DIR_RESTRICTION :
+ // ----- Check the number of parameters
+ if (($i+1) >= $p_size) {
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
+ return PclZip::errorCode();
+ }
+
+ // ----- Get the value
+ if ( is_string($p_options_list[$i+1])
+ && ($p_options_list[$i+1] != '')) {
+ $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], false);
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($p_options_list[$i])." = '".$v_result_list[$p_options_list[$i]]."'");
+ $i++;
+ }
+ else {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($p_options_list[$i])." set with an empty value is ignored.");
+ }
+ break;
+
+ // ----- Look for options that request an array of string for value
+ case PCLZIP_OPT_BY_NAME :
+ // ----- Check the number of parameters
+ if (($i+1) >= $p_size) {
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
+ return PclZip::errorCode();
+ }
+
+ // ----- Get the value
+ if (is_string($p_options_list[$i+1])) {
+ $v_result_list[$p_options_list[$i]][0] = $p_options_list[$i+1];
+ }
+ else if (is_array($p_options_list[$i+1])) {
+ $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
+ }
+ else {
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
+ return PclZip::errorCode();
+ }
+ ////--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($p_options_list[$i])." = '".$v_result_list[$p_options_list[$i]]."'");
+ $i++;
+ break;
+
+ // ----- Look for options that request an EREG or PREG expression
+ case PCLZIP_OPT_BY_EREG :
+ case PCLZIP_OPT_BY_PREG :
+ //case PCLZIP_OPT_CRYPT :
+ // ----- Check the number of parameters
+ if (($i+1) >= $p_size) {
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
+ return PclZip::errorCode();
+ }
+
+ // ----- Get the value
+ if (is_string($p_options_list[$i+1])) {
+ $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
+ }
+ else {
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
+ return PclZip::errorCode();
+ }
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($p_options_list[$i])." = '".$v_result_list[$p_options_list[$i]]."'");
+ $i++;
+ break;
+
+ // ----- Look for options that takes a string
+ case PCLZIP_OPT_COMMENT :
+ case PCLZIP_OPT_ADD_COMMENT :
+ case PCLZIP_OPT_PREPEND_COMMENT :
+ // ----- Check the number of parameters
+ if (($i+1) >= $p_size) {
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE,
+ "Missing parameter value for option '"
+ .PclZipUtilOptionText($p_options_list[$i])
+ ."'");
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
+ return PclZip::errorCode();
+ }
+
+ // ----- Get the value
+ if (is_string($p_options_list[$i+1])) {
+ $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
+ }
+ else {
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE,
+ "Wrong parameter value for option '"
+ .PclZipUtilOptionText($p_options_list[$i])
+ ."'");
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
+ return PclZip::errorCode();
+ }
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($p_options_list[$i])." = '".$v_result_list[$p_options_list[$i]]."'");
+ $i++;
+ break;
+
+ // ----- Look for options that request an array of index
+ case PCLZIP_OPT_BY_INDEX :
+ // ----- Check the number of parameters
+ if (($i+1) >= $p_size) {
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
+ return PclZip::errorCode();
+ }
+
+ // ----- Get the value
+ $v_work_list = array();
+ if (is_string($p_options_list[$i+1])) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Index value is a string '".$p_options_list[$i+1]."'");
+
+ // ----- Remove spaces
+ $p_options_list[$i+1] = strtr($p_options_list[$i+1], ' ', '');
+
+ // ----- Parse items
+ $v_work_list = explode(",", $p_options_list[$i+1]);
+ }
+ else if (is_integer($p_options_list[$i+1])) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Index value is an integer '".$p_options_list[$i+1]."'");
+ $v_work_list[0] = $p_options_list[$i+1].'-'.$p_options_list[$i+1];
+ }
+ else if (is_array($p_options_list[$i+1])) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Index value is an array");
+ $v_work_list = $p_options_list[$i+1];
+ }
+ else {
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Value must be integer, string or array for option '".PclZipUtilOptionText($p_options_list[$i])."'");
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
+ return PclZip::errorCode();
+ }
+
+ // ----- Reduce the index list
+ // each index item in the list must be a couple with a start and
+ // an end value : [0,3], [5-5], [8-10], ...
+ // ----- Check the format of each item
+ $v_sort_flag=false;
+ $v_sort_value=0;
+ for ($j=0; $j<sizeof($v_work_list); $j++) {
+ // ----- Explode the item
+ $v_item_list = explode("-", $v_work_list[$j]);
+ $v_size_item_list = sizeof($v_item_list);
+
+ // ----- TBC : Here we might check that each item is a
+ // real integer ...
+
+ // ----- Look for single value
+ if ($v_size_item_list == 1) {
+ // ----- Set the option value
+ $v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0];
+ $v_result_list[$p_options_list[$i]][$j]['end'] = $v_item_list[0];
+ }
+ elseif ($v_size_item_list == 2) {
+ // ----- Set the option value
+ $v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0];
+ $v_result_list[$p_options_list[$i]][$j]['end'] = $v_item_list[1];
+ }
+ else {
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Too many values in index range for option '".PclZipUtilOptionText($p_options_list[$i])."'");
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
+ return PclZip::errorCode();
+ }
+
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extracted index item = [".$v_result_list[$p_options_list[$i]][$j]['start'].",".$v_result_list[$p_options_list[$i]][$j]['end']."]");
+
+ // ----- Look for list sort
+ if ($v_result_list[$p_options_list[$i]][$j]['start'] < $v_sort_value) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The list should be sorted ...");
+ $v_sort_flag=true;
+
+ // ----- TBC : An automatic sort should be writen ...
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Invalid order of index range for option '".PclZipUtilOptionText($p_options_list[$i])."'");
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
+ return PclZip::errorCode();
+ }
+ $v_sort_value = $v_result_list[$p_options_list[$i]][$j]['start'];
+ }
+
+ // ----- Sort the items
+ if ($v_sort_flag) {
+ // TBC : To Be Completed
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "List sorting is not yet write ...");
+ }
+
+ // ----- Next option
+ $i++;
+ break;
+
+ // ----- Look for options that request no value
+ case PCLZIP_OPT_REMOVE_ALL_PATH :
+ case PCLZIP_OPT_EXTRACT_AS_STRING :
+ case PCLZIP_OPT_NO_COMPRESSION :
+ case PCLZIP_OPT_EXTRACT_IN_OUTPUT :
+ case PCLZIP_OPT_REPLACE_NEWER :
+ case PCLZIP_OPT_STOP_ON_ERROR :
+ $v_result_list[$p_options_list[$i]] = true;
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($p_options_list[$i])." = '".$v_result_list[$p_options_list[$i]]."'");
+ break;
+
+ // ----- Look for options that request an octal value
+ case PCLZIP_OPT_SET_CHMOD :
+ // ----- Check the number of parameters
+ if (($i+1) >= $p_size) {
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
+ return PclZip::errorCode();
+ }
+
+ // ----- Get the value
+ $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($p_options_list[$i])." = '".$v_result_list[$p_options_list[$i]]."'");
+ $i++;
+ break;
+
+ // ----- Look for options that request a call-back
+ case PCLZIP_CB_PRE_EXTRACT :
+ case PCLZIP_CB_POST_EXTRACT :
+ case PCLZIP_CB_PRE_ADD :
+ case PCLZIP_CB_POST_ADD :
+ /* for futur use
+ case PCLZIP_CB_PRE_DELETE :
+ case PCLZIP_CB_POST_DELETE :
+ case PCLZIP_CB_PRE_LIST :
+ case PCLZIP_CB_POST_LIST :
+ */
+ // ----- Check the number of parameters
+ if (($i+1) >= $p_size) {
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
+ return PclZip::errorCode();
+ }
+
+ // ----- Get the value
+ $v_function_name = $p_options_list[$i+1];
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "call-back ".PclZipUtilOptionText($p_options_list[$i])." = '".$v_function_name."'");
+
+ // ----- Check that the value is a valid existing function
+ if (!function_exists($v_function_name)) {
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Function '".$v_function_name."()' is not an existing function for option '".PclZipUtilOptionText($p_options_list[$i])."'");
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
+ return PclZip::errorCode();
+ }
+
+ // ----- Set the attribute
+ $v_result_list[$p_options_list[$i]] = $v_function_name;
+ $i++;
+ break;
+
+ default :
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER,
+ "Unknown parameter '"
+ .$p_options_list[$i]."'");
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
+ return PclZip::errorCode();
+ }
+
+ // ----- Next options
+ $i++;
+ }
+
+ // ----- Look for mandatory options
+ if ($v_requested_options !== false) {
+ for ($key=reset($v_requested_options); $key=key($v_requested_options); $key=next($v_requested_options)) {
+ // ----- Look for mandatory option
+ if ($v_requested_options[$key] == 'mandatory') {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Detect a mandatory option : ".PclZipUtilOptionText($key)."(".$key.")");
+ // ----- Look if present
+ if (!isset($v_result_list[$key])) {
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing mandatory parameter ".PclZipUtilOptionText($key)."(".$key.")");
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
+ return PclZip::errorCode();
+ }
+ }
+ }
+ }
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : privFileDescrParseAtt()
+ // Description :
+ // Parameters :
+ // Return Values :
+ // 1 on success.
+ // 0 on failure.
+ // --------------------------------------------------------------------------------
+ function privFileDescrParseAtt(&$p_file_list, &$p_filedescr, $v_options, $v_requested_options=false)
+ {
+ //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privFileDescrParseAtt", "");
+ $v_result=1;
+
+ // ----- For each file in the list check the attributes
+ foreach ($p_file_list as $v_key => $v_value) {
+
+ // ----- Check if the option is supported
+ if (!isset($v_requested_options[$v_key])) {
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file attribute '".$v_key."' for this file");
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
+ return PclZip::errorCode();
+ }
+
+ // ----- Look for attribute
+ switch ($v_key) {
+ case PCLZIP_ATT_FILE_NAME :
+ if (!is_string($v_value)) {
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'");
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
+ return PclZip::errorCode();
+ }
+
+ $p_filedescr['filename'] = PclZipUtilPathReduction($v_value);
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($v_key)." = '".$v_value."'");
+
+ if ($p_filedescr['filename'] == '') {
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty filename for attribute '".PclZipUtilOptionText($v_key)."'");
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
+ return PclZip::errorCode();
+ }
+
+ break;
+
+ case PCLZIP_ATT_FILE_NEW_SHORT_NAME :
+ if (!is_string($v_value)) {
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'");
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
+ return PclZip::errorCode();
+ }
+
+ $p_filedescr['new_short_name'] = PclZipUtilPathReduction($v_value);
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($v_key)." = '".$v_value."'");
+
+ if ($p_filedescr['new_short_name'] == '') {
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty short filename for attribute '".PclZipUtilOptionText($v_key)."'");
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
+ return PclZip::errorCode();
+ }
+ break;
+
+ case PCLZIP_ATT_FILE_NEW_FULL_NAME :
+ if (!is_string($v_value)) {
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'");
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
+ return PclZip::errorCode();
+ }
+
+ $p_filedescr['new_full_name'] = PclZipUtilPathReduction($v_value);
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($v_key)." = '".$v_value."'");
+
+ if ($p_filedescr['new_full_name'] == '') {
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty full filename for attribute '".PclZipUtilOptionText($v_key)."'");
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
+ return PclZip::errorCode();
+ }
+ break;
+
+ default :
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER,
+ "Unknown parameter '".$v_key."'");
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
+ return PclZip::errorCode();
+ }
+
+ // ----- Look for mandatory options
+ if ($v_requested_options !== false) {
+ for ($key=reset($v_requested_options); $key=key($v_requested_options); $key=next($v_requested_options)) {
+ // ----- Look for mandatory option
+ if ($v_requested_options[$key] == 'mandatory') {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Detect a mandatory option : ".PclZipUtilOptionText($key)."(".$key.")");
+ // ----- Look if present
+ if (!isset($p_file_list[$key])) {
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing mandatory parameter ".PclZipUtilOptionText($key)."(".$key.")");
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
+ return PclZip::errorCode();
+ }
+ }
+ }
+ }
+
+ // end foreach
+ }
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : privFileDescrExpand()
+ // Description :
+ // Parameters :
+ // Return Values :
+ // 1 on success.
+ // 0 on failure.
+ // --------------------------------------------------------------------------------
+ function privFileDescrExpand(&$p_filedescr_list, &$p_options)
+ {
+ //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privFileDescrExpand", "");
+ $v_result=1;
+
+ // ----- Create a result list
+ $v_result_list = array();
+
+ // ----- Look each entry
+ for ($i=0; $i<sizeof($p_filedescr_list); $i++) {
+ // ----- Get filedescr
+ $v_descr = $p_filedescr_list[$i];
+
+ // ----- Reduce the filename
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Filedescr before reduction :'".$v_descr['filename']."'");
+ $v_descr['filename'] = PclZipUtilTranslateWinPath($v_descr['filename']);
+ $v_descr['filename'] = PclZipUtilPathReduction($v_descr['filename']);
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Filedescr after reduction :'".$v_descr['filename']."'");
+
+ // ----- Get type of descr
+ if (!file_exists($v_descr['filename'])) {
+ // ----- Error log
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "File '".$v_descr['filename']."' does not exists");
+ PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "File '".$v_descr['filename']."' does not exists");
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
+ return PclZip::errorCode();
+ }
+ if (@is_file($v_descr['filename'])) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "This is a file");
+ $v_descr['type'] = 'file';
+ }
+ else if (@is_dir($v_descr['filename'])) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "This is a folder");
+ $v_descr['type'] = 'folder';
+ }
+ else if (@is_link($v_descr['filename'])) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Unsupported file type : link");
+ // skip
+ continue;
+ }
+ else {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Unsupported file type : unknown type");
+ // skip
+ continue;
+ }
+
+ // ----- Calculate the stored filename
+ $this->privCalculateStoredFilename($v_descr, $p_options);
+
+ // ----- Add the descriptor in result list
+ $v_result_list[sizeof($v_result_list)] = $v_descr;
+
+ // ----- Look for folder
+ if ($v_descr['type'] == 'folder') {
+ // ----- List of items in folder
+ $v_dirlist_descr = array();
+ $v_dirlist_nb = 0;
+ if ($v_folder_handler = @opendir($v_descr['filename'])) {
+ while (($v_item_handler = @readdir($v_folder_handler)) !== false) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Looking for '".$v_item_handler."' in the directory");
+
+ // ----- Skip '.' and '..'
+ if (($v_item_handler == '.') || ($v_item_handler == '..')) {
+ continue;
+ }
+
+ // ----- Compose the full filename
+ $v_dirlist_descr[$v_dirlist_nb]['filename'] = $v_descr['filename'].'/'.$v_item_handler;
+
+ // ----- Look for different stored filename
+ // Because the name of the folder was changed, the name of the
+ // files/sub-folders also change
+ if ($v_descr['stored_filename'] != $v_descr['filename']) {
+ $v_dirlist_descr[$v_dirlist_nb]['new_full_name'] = $v_descr['stored_filename'].'/'.$v_item_handler;
+ }
+
+ $v_dirlist_nb++;
+ }
+ }
+ else {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Unable to open dir '".$v_descr['filename']."' in read mode. Skipped.");
+ // TBC : unable to open folder in read mode
+ }
+
+ // ----- Expand each element of the list
+ if ($v_dirlist_nb != 0) {
+ // ----- Expand
+ if (($v_result = $this->privFileDescrExpand($v_dirlist_descr, $p_options)) != 1) {
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+
+ // ----- Concat the resulting list
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Merging result list (size '".sizeof($v_result_list)."') with dirlist (size '".sizeof($v_dirlist_descr)."')");
+ $v_result_list = array_merge($v_result_list, $v_dirlist_descr);
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "merged result list is size '".sizeof($v_result_list)."'");
+ }
+ else {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Nothing in this folder to expand.");
+ }
+
+ // ----- Free local array
+ unset($v_dirlist_descr);
+ }
+ }
+
+ // ----- Get the result list
+ $p_filedescr_list = $v_result_list;
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : privCreate()
+ // Description :
+ // Parameters :
+ // Return Values :
+ // --------------------------------------------------------------------------------
+ function privCreate($p_filedescr_list, &$p_result_list, &$p_options)
+ {
+ //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privCreate", "list");
+ $v_result=1;
+ $v_list_detail = array();
+
+ // ----- Magic quotes trick
+ $this->privDisableMagicQuotes();
+
+ // ----- Open the file in write mode
+ if (($v_result = $this->privOpenFd('wb')) != 1)
+ {
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+
+ // ----- Add the list of files
+ $v_result = $this->privAddList($p_filedescr_list, $p_result_list, $p_options);
+
+ // ----- Close
+ $this->privCloseFd();
+
+ // ----- Magic quotes trick
+ $this->privSwapBackMagicQuotes();
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : privAdd()
+ // Description :
+ // Parameters :
+ // Return Values :
+ // --------------------------------------------------------------------------------
+ function privAdd($p_filedescr_list, &$p_result_list, &$p_options)
+ {
+ //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privAdd", "list");
+ $v_result=1;
+ $v_list_detail = array();
+
+ // ----- Look if the archive exists or is empty
+ if ((!is_file($this->zipname)) || (filesize($this->zipname) == 0))
+ {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Archive does not exist, or is empty, create it.");
+
+ // ----- Do a create
+ $v_result = $this->privCreate($p_filedescr_list, $p_result_list, $p_options);
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+ // ----- Magic quotes trick
+ $this->privDisableMagicQuotes();
+
+ // ----- Open the zip file
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode");
+ if (($v_result=$this->privOpenFd('rb')) != 1)
+ {
+ // ----- Magic quotes trick
+ $this->privSwapBackMagicQuotes();
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+
+ // ----- Read the central directory informations
+ $v_central_dir = array();
+ if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
+ {
+ $this->privCloseFd();
+ $this->privSwapBackMagicQuotes();
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+
+ // ----- Go to beginning of File
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position in file : ".ftell($this->zip_fd)."'");
+ @rewind($this->zip_fd);
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position in file : ".ftell($this->zip_fd)."'");
+
+ // ----- Creates a temporay file
+ $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp';
+
+ // ----- Open the temporary file in write mode
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode");
+ if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0)
+ {
+ $this->privCloseFd();
+ $this->privSwapBackMagicQuotes();
+
+ PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_zip_temp_name.'\' in binary write mode');
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
+ return PclZip::errorCode();
+ }
+
+ // ----- Copy the files from the archive to the temporary file
+ // TBC : Here I should better append the file and go back to erase the central dir
+ $v_size = $v_central_dir['offset'];
+ while ($v_size != 0)
+ {
+ $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Read $v_read_size bytes");
+ $v_buffer = fread($this->zip_fd, $v_read_size);
+ @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
+ $v_size -= $v_read_size;
+ }
+
+ // ----- Swap the file descriptor
+ // Here is a trick : I swap the temporary fd with the zip fd, in order to use
+ // the following methods on the temporary fil and not the real archive
+ $v_swap = $this->zip_fd;
+ $this->zip_fd = $v_zip_temp_fd;
+ $v_zip_temp_fd = $v_swap;
+
+ // ----- Add the files
+ $v_header_list = array();
+ if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1)
+ {
+ fclose($v_zip_temp_fd);
+ $this->privCloseFd();
+ @unlink($v_zip_temp_name);
+ $this->privSwapBackMagicQuotes();
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+
+ // ----- Store the offset of the central dir
+ $v_offset = @ftell($this->zip_fd);
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "New offset of central dir : $v_offset");
+
+ // ----- Copy the block of file headers from the old archive
+ $v_size = $v_central_dir['size'];
+ while ($v_size != 0)
+ {
+ $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Read $v_read_size bytes");
+ $v_buffer = @fread($v_zip_temp_fd, $v_read_size);
+ @fwrite($this->zip_fd, $v_buffer, $v_read_size);
+ $v_size -= $v_read_size;
+ }
+
+ // ----- Create the Central Dir files header
+ for ($i=0, $v_count=0; $i<sizeof($v_header_list); $i++)
+ {
+ // ----- Create the file header
+ if ($v_header_list[$i]['status'] == 'ok') {
+ if (($v_result = $this->privWriteCentralFileHeader($v_header_list[$i])) != 1) {
+ fclose($v_zip_temp_fd);
+ $this->privCloseFd();
+ @unlink($v_zip_temp_name);
+ $this->privSwapBackMagicQuotes();
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+ $v_count++;
+ }
+
+ // ----- Transform the header to a 'usable' info
+ $this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]);
+ }
+
+ // ----- Zip file comment
+ $v_comment = $v_central_dir['comment'];
+ if (isset($p_options[PCLZIP_OPT_COMMENT])) {
+ $v_comment = $p_options[PCLZIP_OPT_COMMENT];
+ }
+ if (isset($p_options[PCLZIP_OPT_ADD_COMMENT])) {
+ $v_comment = $v_comment.$p_options[PCLZIP_OPT_ADD_COMMENT];
+ }
+ if (isset($p_options[PCLZIP_OPT_PREPEND_COMMENT])) {
+ $v_comment = $p_options[PCLZIP_OPT_PREPEND_COMMENT].$v_comment;
+ }
+
+ // ----- Calculate the size of the central header
+ $v_size = @ftell($this->zip_fd)-$v_offset;
+
+ // ----- Create the central dir footer
+ if (($v_result = $this->privWriteCentralHeader($v_count+$v_central_dir['entries'], $v_size, $v_offset, $v_comment)) != 1)
+ {
+ // ----- Reset the file list
+ unset($v_header_list);
+ $this->privSwapBackMagicQuotes();
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+
+ // ----- Swap back the file descriptor
+ $v_swap = $this->zip_fd;
+ $this->zip_fd = $v_zip_temp_fd;
+ $v_zip_temp_fd = $v_swap;
+
+ // ----- Close
+ $this->privCloseFd();
+
+ // ----- Close the temporary file
+ @fclose($v_zip_temp_fd);
+
+ // ----- Magic quotes trick
+ $this->privSwapBackMagicQuotes();
+
+ // ----- Delete the zip file
+ // TBC : I should test the result ...
+ @unlink($this->zipname);
+
+ // ----- Rename the temporary file
+ // TBC : I should test the result ...
+ //@rename($v_zip_temp_name, $this->zipname);
+ PclZipUtilRename($v_zip_temp_name, $this->zipname);
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : privOpenFd()
+ // Description :
+ // Parameters :
+ // --------------------------------------------------------------------------------
+ function privOpenFd($p_mode)
+ {
+ //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privOpenFd", 'mode='.$p_mode);
+ $v_result=1;
+
+ // ----- Look if already open
+ if ($this->zip_fd != 0)
+ {
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Zip file \''.$this->zipname.'\' already open');
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
+ return PclZip::errorCode();
+ }
+
+ // ----- Open the zip file
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Open file in '.$p_mode.' mode');
+ if (($this->zip_fd = @fopen($this->zipname, $p_mode)) == 0)
+ {
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in '.$p_mode.' mode');
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
+ return PclZip::errorCode();
+ }
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : privCloseFd()
+ // Description :
+ // Parameters :
+ // --------------------------------------------------------------------------------
+ function privCloseFd()
+ {
+ //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privCloseFd", "");
+ $v_result=1;
+
+ if ($this->zip_fd != 0)
+ @fclose($this->zip_fd);
+ $this->zip_fd = 0;
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : privAddList()
+ // Description :
+ // $p_add_dir and $p_remove_dir will give the ability to memorize a path which is
+ // different from the real path of the file. This is usefull if you want to have PclTar
+ // running in any directory, and memorize relative path from an other directory.
+ // Parameters :
+ // $p_list : An array containing the file or directory names to add in the tar
+ // $p_result_list : list of added files with their properties (specially the status field)
+ // $p_add_dir : Path to add in the filename path archived
+ // $p_remove_dir : Path to remove in the filename path archived
+ // Return Values :
+ // --------------------------------------------------------------------------------
+// function privAddList($p_list, &$p_result_list, $p_add_dir, $p_remove_dir, $p_remove_all_dir, &$p_options)
+ function privAddList($p_filedescr_list, &$p_result_list, &$p_options)
+ {
+ //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privAddList", "list");
+ $v_result=1;
+
+ // ----- Add the files
+ $v_header_list = array();
+ if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1)
+ {
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+
+ // ----- Store the offset of the central dir
+ $v_offset = @ftell($this->zip_fd);
+
+ // ----- Create the Central Dir files header
+ for ($i=0,$v_count=0; $i<sizeof($v_header_list); $i++)
+ {
+ // ----- Create the file header
+ if ($v_header_list[$i]['status'] == 'ok') {
+ if (($v_result = $this->privWriteCentralFileHeader($v_header_list[$i])) != 1) {
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+ $v_count++;
+ }
+
+ // ----- Transform the header to a 'usable' info
+ $this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]);
+ }
+
+ // ----- Zip file comment
+ $v_comment = '';
+ if (isset($p_options[PCLZIP_OPT_COMMENT])) {
+ $v_comment = $p_options[PCLZIP_OPT_COMMENT];
+ }
+
+ // ----- Calculate the size of the central header
+ $v_size = @ftell($this->zip_fd)-$v_offset;
+
+ // ----- Create the central dir footer
+ if (($v_result = $this->privWriteCentralHeader($v_count, $v_size, $v_offset, $v_comment)) != 1)
+ {
+ // ----- Reset the file list
+ unset($v_header_list);
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : privAddFileList()
+ // Description :
+ // Parameters :
+ // $p_filedescr_list : An array containing the file description
+ // or directory names to add in the zip
+ // $p_result_list : list of added files with their properties (specially the status field)
+ // Return Values :
+ // --------------------------------------------------------------------------------
+ function privAddFileList($p_filedescr_list, &$p_result_list, &$p_options)
+ {
+ //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privAddFileList", "filedescr_list");
+ $v_result=1;
+ $v_header = array();
+
+ // ----- Recuperate the current number of elt in list
+ $v_nb = sizeof($p_result_list);
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Before add, list have ".$v_nb." elements");
+
+ // ----- Loop on the files
+ for ($j=0; ($j<sizeof($p_filedescr_list)) && ($v_result==1); $j++) {
+ // ----- Format the filename
+ $p_filedescr_list[$j]['filename']
+ = PclZipUtilTranslateWinPath($p_filedescr_list[$j]['filename'], false);
+
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Looking for file '".$p_filedescr_list[$j]['filename']."'");
+
+ // ----- Skip empty file names
+ // TBC : Can this be possible ? not checked in DescrParseAtt ?
+ if ($p_filedescr_list[$j]['filename'] == "") {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Skip empty filename");
+ continue;
+ }
+
+ // ----- Check the filename
+ if (!file_exists($p_filedescr_list[$j]['filename'])) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "File '".$p_filedescr_list[$j]['filename']."' does not exists");
+ PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "File '".$p_filedescr_list[$j]['filename']."' does not exists");
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
+ return PclZip::errorCode();
+ }
+
+ // ----- Look if it is a file or a dir with no all path remove option
+ if ( (is_file($p_filedescr_list[$j]['filename']))
+ || ( is_dir($p_filedescr_list[$j]['filename'])
+ && ( !isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH])
+ || !$p_options[PCLZIP_OPT_REMOVE_ALL_PATH]))) {
+
+ // ----- Add the file
+ $v_result = $this->privAddFile($p_filedescr_list[$j], $v_header,
+ $p_options);
+ if ($v_result != 1) {
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+
+ // ----- Store the file infos
+ $p_result_list[$v_nb++] = $v_header;
+ }
+ }
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "After add, list have ".$v_nb." elements");
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : privAddFile()
+ // Description :
+ // Parameters :
+ // Return Values :
+ // --------------------------------------------------------------------------------
+ function privAddFile($p_filedescr, &$p_header, &$p_options)
+ {
+ //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privAddFile", "filename='".$p_filedescr['filename']."'");
+ $v_result=1;
+
+ // ----- Working variable
+ $p_filename = $p_filedescr['filename'];
+
+ // TBC : Already done in the fileAtt check ... ?
+ if ($p_filename == "") {
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file list parameter (invalid or empty list)");
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
+ return PclZip::errorCode();
+ }
+
+ // ----- Look for a stored different filename
+ if (isset($p_filedescr['stored_filename'])) {
+ $v_stored_filename = $p_filedescr['stored_filename'];
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, 'Stored filename is NOT the same "'.$v_stored_filename.'"');
+ }
+ else {
+ $v_stored_filename = $p_filedescr['stored_filename'];
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, 'Stored filename is the same');
+ }
+
+ // ----- Set the file properties
+ clearstatcache();
+ $p_header['version'] = 20;
+ $p_header['version_extracted'] = 10;
+ $p_header['flag'] = 0;
+ $p_header['compression'] = 0;
+ $p_header['mtime'] = filemtime($p_filename);
+ $p_header['crc'] = 0;
+ $p_header['compressed_size'] = 0;
+ $p_header['size'] = filesize($p_filename);
+ $p_header['filename_len'] = strlen($p_filename);
+ $p_header['extra_len'] = 0;
+ $p_header['comment_len'] = 0;
+ $p_header['disk'] = 0;
+ $p_header['internal'] = 0;
+// $p_header['external'] = (is_file($p_filename)?0xFE49FFE0:0x41FF0010);
+ $p_header['external'] = (is_file($p_filename)?0x00000000:0x00000010);
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Header external extension '".sprintf("0x%X",$p_header['external'])."'");
+ $p_header['offset'] = 0;
+ $p_header['filename'] = $p_filename;
+ $p_header['stored_filename'] = $v_stored_filename;
+ $p_header['extra'] = '';
+ $p_header['comment'] = '';
+ $p_header['status'] = 'ok';
+ $p_header['index'] = -1;
+
+ // ----- Look for pre-add callback
+ if (isset($p_options[PCLZIP_CB_PRE_ADD])) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "A pre-callback '".$p_options[PCLZIP_CB_PRE_ADD]."()') is defined for the extraction");
+
+ // ----- Generate a local information
+ $v_local_header = array();
+ $this->privConvertHeader2FileInfo($p_header, $v_local_header);
+
+ // ----- Call the callback
+ // Here I do not use call_user_func() because I need to send a reference to the
+ // header.
+ eval('$v_result = '.$p_options[PCLZIP_CB_PRE_ADD].'(PCLZIP_CB_PRE_ADD, $v_local_header);');
+ if ($v_result == 0) {
+ // ----- Change the file status
+ $p_header['status'] = "skipped";
+ $v_result = 1;
+ }
+
+ // ----- Update the informations
+ // Only some fields can be modified
+ if ($p_header['stored_filename'] != $v_local_header['stored_filename']) {
+ $p_header['stored_filename'] = PclZipUtilPathReduction($v_local_header['stored_filename']);
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "New stored filename is '".$p_header['stored_filename']."'");
+ }
+ }
+
+ // ----- Look for empty stored filename
+ if ($p_header['stored_filename'] == "") {
+ $p_header['status'] = "filtered";
+ }
+
+ // ----- Check the path length
+ if (strlen($p_header['stored_filename']) > 0xFF) {
+ $p_header['status'] = 'filename_too_long';
+ }
+
+ // ----- Look if no error, or file not skipped
+ if ($p_header['status'] == 'ok') {
+
+ // ----- Look for a file
+ if (is_file($p_filename))
+ {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "'".$p_filename."' is a file");
+ // ----- Open the source file
+ if (($v_file = @fopen($p_filename, "rb")) == 0) {
+ PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to open file '$p_filename' in binary read mode");
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
+ return PclZip::errorCode();
+ }
+
+ if ($p_options[PCLZIP_OPT_NO_COMPRESSION]) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "File will not be compressed");
+ // ----- Read the file content
+ $v_content_compressed = @fread($v_file, $p_header['size']);
+
+ // ----- Calculate the CRC
+ $p_header['crc'] = @crc32($v_content_compressed);
+
+ // ----- Set header parameters
+ $p_header['compressed_size'] = $p_header['size'];
+ $p_header['compression'] = 0;
+ }
+ else {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "File will be compressed");
+ // ----- Read the file content
+ $v_content = @fread($v_file, $p_header['size']);
+
+ // ----- Calculate the CRC
+ $p_header['crc'] = @crc32($v_content);
+
+ // ----- Compress the file
+ $v_content_compressed = @gzdeflate($v_content);
+
+ // ----- Set header parameters
+ $p_header['compressed_size'] = strlen($v_content_compressed);
+ $p_header['compression'] = 8;
+ }
+
+ // ----- Look for encryption
+ /*
+ if ((isset($p_options[PCLZIP_OPT_CRYPT]))
+ && ($p_options[PCLZIP_OPT_CRYPT] != "")) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "File need to be crypted ....");
+
+ // Should be a random header
+ $v_header = 'xxxxxxxxxxxx';
+ $v_content_compressed = PclZipUtilZipEncrypt($v_content_compressed,
+ $p_header['compressed_size'],
+ $v_header,
+ $p_header['crc'],
+ "test");
+
+ $p_header['compressed_size'] += 12;
+ $p_header['flag'] = 1;
+
+ // ----- Add the header to the data
+ $v_content_compressed = $v_header.$v_content_compressed;
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Size after header : ".strlen($v_content_compressed)."");
+ }
+ */
+
+ // ----- Call the header generation
+ if (($v_result = $this->privWriteFileHeader($p_header)) != 1) {
+ @fclose($v_file);
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+
+ // ----- Write the compressed (or not) content
+ @fwrite($this->zip_fd,
+ $v_content_compressed, $p_header['compressed_size']);
+
+ // ----- Close the file
+ @fclose($v_file);
+ }
+
+ // ----- Look for a directory
+ else {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "'".$p_filename."' is a folder");
+ // ----- Look for directory last '/'
+ if (@substr($p_header['stored_filename'], -1) != '/') {
+ $p_header['stored_filename'] .= '/';
+ }
+
+ // ----- Set the file properties
+ $p_header['size'] = 0;
+ //$p_header['external'] = 0x41FF0010; // Value for a folder : to be checked
+ $p_header['external'] = 0x00000010; // Value for a folder : to be checked
+
+ // ----- Call the header generation
+ if (($v_result = $this->privWriteFileHeader($p_header)) != 1)
+ {
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+ }
+ }
+
+ // ----- Look for post-add callback
+ if (isset($p_options[PCLZIP_CB_POST_ADD])) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "A post-callback '".$p_options[PCLZIP_CB_POST_ADD]."()') is defined for the extraction");
+
+ // ----- Generate a local information
+ $v_local_header = array();
+ $this->privConvertHeader2FileInfo($p_header, $v_local_header);
+
+ // ----- Call the callback
+ // Here I do not use call_user_func() because I need to send a reference to the
+ // header.
+ eval('$v_result = '.$p_options[PCLZIP_CB_POST_ADD].'(PCLZIP_CB_POST_ADD, $v_local_header);');
+ if ($v_result == 0) {
+ // ----- Ignored
+ $v_result = 1;
+ }
+
+ // ----- Update the informations
+ // Nothing can be modified
+ }
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : privCalculateStoredFilename()
+ // Description :
+ // Based on file descriptor properties and global options, this method
+ // calculate the filename that will be stored in the archive.
+ // Parameters :
+ // Return Values :
+ // --------------------------------------------------------------------------------
+ function privCalculateStoredFilename(&$p_filedescr, &$p_options)
+ {
+ //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privCalculateStoredFilename", "filename='".$p_filedescr['filename']."'");
+ $v_result=1;
+
+ // ----- Working variables
+ $p_filename = $p_filedescr['filename'];
+ if (isset($p_options[PCLZIP_OPT_ADD_PATH])) {
+ $p_add_dir = $p_options[PCLZIP_OPT_ADD_PATH];
+ }
+ else {
+ $p_add_dir = '';
+ }
+ if (isset($p_options[PCLZIP_OPT_REMOVE_PATH])) {
+ $p_remove_dir = $p_options[PCLZIP_OPT_REMOVE_PATH];
+ }
+ else {
+ $p_remove_dir = '';
+ }
+ if (isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {
+ $p_remove_all_dir = $p_options[PCLZIP_OPT_REMOVE_ALL_PATH];
+ }
+ else {
+ $p_remove_all_dir = 0;
+ }
+
+ // ----- Look for full name change
+ if (isset($p_filedescr['new_full_name'])) {
+ $v_stored_filename = $p_filedescr['new_full_name'];
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Changing full name of '".$p_filename."' for '".$v_stored_filename."'");
+ }
+
+ // ----- Look for path and/or short name change
+ else {
+
+ // ----- Look for short name change
+ if (isset($p_filedescr['new_short_name'])) {
+ $v_path_info = pathinfo($p_filename);
+ $v_dir = '';
+ if ($v_path_info['dirname'] != '') {
+ $v_dir = $v_path_info['dirname'].'/';
+ }
+ $v_stored_filename = $v_dir.$p_filedescr['new_short_name'];
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Changing short name of '".$p_filename."' for '".$v_stored_filename."'");
+ }
+ else {
+ // ----- Calculate the stored filename
+ $v_stored_filename = $p_filename;
+ }
+
+ // ----- Look for all path to remove
+ if ($p_remove_all_dir) {
+ $v_stored_filename = basename($p_filename);
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Remove all path selected change '".$p_filename."' for '".$v_stored_filename."'");
+ }
+ // ----- Look for partial path remove
+ else if ($p_remove_dir != "") {
+ if (substr($p_remove_dir, -1) != '/')
+ $p_remove_dir .= "/";
+
+ if ( (substr($p_filename, 0, 2) == "./")
+ || (substr($p_remove_dir, 0, 2) == "./")) {
+
+ if ( (substr($p_filename, 0, 2) == "./")
+ && (substr($p_remove_dir, 0, 2) != "./")) {
+ $p_remove_dir = "./".$p_remove_dir;
+ }
+ if ( (substr($p_filename, 0, 2) != "./")
+ && (substr($p_remove_dir, 0, 2) == "./")) {
+ $p_remove_dir = substr($p_remove_dir, 2);
+ }
+ }
+
+ $v_compare = PclZipUtilPathInclusion($p_remove_dir,
+ $v_stored_filename);
+ if ($v_compare > 0) {
+ if ($v_compare == 2) {
+ $v_stored_filename = "";
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Path to remove is the current folder");
+ }
+ else {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Remove path '$p_remove_dir' in file '$v_stored_filename'");
+ $v_stored_filename = substr($v_stored_filename,
+ strlen($p_remove_dir));
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Result is '$v_stored_filename'");
+ }
+ }
+ }
+ // ----- Look for path to add
+ if ($p_add_dir != "") {
+ if (substr($p_add_dir, -1) == "/")
+ $v_stored_filename = $p_add_dir.$v_stored_filename;
+ else
+ $v_stored_filename = $p_add_dir."/".$v_stored_filename;
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Add path '$p_add_dir' in file '$p_filename' = '$v_stored_filename'");
+ }
+ }
+
+ // ----- Filename (reduce the path of stored name)
+ $v_stored_filename = PclZipUtilPathReduction($v_stored_filename);
+ $p_filedescr['stored_filename'] = $v_stored_filename;
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Stored filename will be '".$p_filedescr['stored_filename']."', strlen ".strlen($p_filedescr['stored_filename']));
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : privWriteFileHeader()
+ // Description :
+ // Parameters :
+ // Return Values :
+ // --------------------------------------------------------------------------------
+ function privWriteFileHeader(&$p_header)
+ {
+ //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privWriteFileHeader", 'file="'.$p_header['filename'].'", stored as "'.$p_header['stored_filename'].'"');
+ $v_result=1;
+
+ // ----- Store the offset position of the file
+ $p_header['offset'] = ftell($this->zip_fd);
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, 'File offset of the header :'.$p_header['offset']);
+
+ // ----- Transform UNIX mtime to DOS format mdate/mtime
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Date : \''.date("d/m/y H:i:s", $p_header['mtime']).'\'');
+ $v_date = getdate($p_header['mtime']);
+ $v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2;
+ $v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday'];
+
+ // ----- Packed data
+ $v_binary_data = pack("VvvvvvVVVvv", 0x04034b50,
+ $p_header['version_extracted'], $p_header['flag'],
+ $p_header['compression'], $v_mtime, $v_mdate,
+ $p_header['crc'], $p_header['compressed_size'],
+ $p_header['size'],
+ strlen($p_header['stored_filename']),
+ $p_header['extra_len']);
+
+ // ----- Write the first 148 bytes of the header in the archive
+ fputs($this->zip_fd, $v_binary_data, 30);
+
+ // ----- Write the variable fields
+ if (strlen($p_header['stored_filename']) != 0)
+ {
+ fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename']));
+ }
+ if ($p_header['extra_len'] != 0)
+ {
+ fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']);
+ }
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : privWriteCentralFileHeader()
+ // Description :
+ // Parameters :
+ // Return Values :
+ // --------------------------------------------------------------------------------
+ function privWriteCentralFileHeader(&$p_header)
+ {
+ //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privWriteCentralFileHeader", 'file="'.$p_header['filename'].'", stored as "'.$p_header['stored_filename'].'"');
+ $v_result=1;
+
+ // TBC
+ //for(reset($p_header); $key = key($p_header); next($p_header)) {
+ // //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "header[$key] = ".$p_header[$key]);
+ //}
+
+ // ----- Transform UNIX mtime to DOS format mdate/mtime
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Date : \''.date("d/m/y H:i:s", $p_header['mtime']).'\'');
+ $v_date = getdate($p_header['mtime']);
+ $v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2;
+ $v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday'];
+
+ // ----- Packed data
+ $v_binary_data = pack("VvvvvvvVVVvvvvvVV", 0x02014b50,
+ $p_header['version'], $p_header['version_extracted'],
+ $p_header['flag'], $p_header['compression'],
+ $v_mtime, $v_mdate, $p_header['crc'],
+ $p_header['compressed_size'], $p_header['size'],
+ strlen($p_header['stored_filename']),
+ $p_header['extra_len'], $p_header['comment_len'],
+ $p_header['disk'], $p_header['internal'],
+ $p_header['external'], $p_header['offset']);
+
+ // ----- Write the 42 bytes of the header in the zip file
+ fputs($this->zip_fd, $v_binary_data, 46);
+
+ // ----- Write the variable fields
+ if (strlen($p_header['stored_filename']) != 0)
+ {
+ fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename']));
+ }
+ if ($p_header['extra_len'] != 0)
+ {
+ fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']);
+ }
+ if ($p_header['comment_len'] != 0)
+ {
+ fputs($this->zip_fd, $p_header['comment'], $p_header['comment_len']);
+ }
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : privWriteCentralHeader()
+ // Description :
+ // Parameters :
+ // Return Values :
+ // --------------------------------------------------------------------------------
+ function privWriteCentralHeader($p_nb_entries, $p_size, $p_offset, $p_comment)
+ {
+ //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privWriteCentralHeader", 'nb_entries='.$p_nb_entries.', size='.$p_size.', offset='.$p_offset.', comment="'.$p_comment.'"');
+ $v_result=1;
+
+ // ----- Packed data
+ $v_binary_data = pack("VvvvvVVv", 0x06054b50, 0, 0, $p_nb_entries,
+ $p_nb_entries, $p_size,
+ $p_offset, strlen($p_comment));
+
+ // ----- Write the 22 bytes of the header in the zip file
+ fputs($this->zip_fd, $v_binary_data, 22);
+
+ // ----- Write the variable fields
+ if (strlen($p_comment) != 0)
+ {
+ fputs($this->zip_fd, $p_comment, strlen($p_comment));
+ }
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : privList()
+ // Description :
+ // Parameters :
+ // Return Values :
+ // --------------------------------------------------------------------------------
+ function privList(&$p_list)
+ {
+ //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privList", "list");
+ $v_result=1;
+
+ // ----- Magic quotes trick
+ $this->privDisableMagicQuotes();
+
+ // ----- Open the zip file
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode");
+ if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0)
+ {
+ // ----- Magic quotes trick
+ $this->privSwapBackMagicQuotes();
+
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in binary read mode');
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
+ return PclZip::errorCode();
+ }
+
+ // ----- Read the central directory informations
+ $v_central_dir = array();
+ if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
+ {
+ $this->privSwapBackMagicQuotes();
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+
+ // ----- Go to beginning of Central Dir
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Offset : ".$v_central_dir['offset']."'");
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Position in file : ".ftell($this->zip_fd)."'");
+ @rewind($this->zip_fd);
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Position in file : ".ftell($this->zip_fd)."'");
+ if (@fseek($this->zip_fd, $v_central_dir['offset']))
+ {
+ $this->privSwapBackMagicQuotes();
+
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
+ return PclZip::errorCode();
+ }
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Position in file : ".ftell($this->zip_fd)."'");
+
+ // ----- Read each entry
+ for ($i=0; $i<$v_central_dir['entries']; $i++)
+ {
+ // ----- Read the file header
+ if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1)
+ {
+ $this->privSwapBackMagicQuotes();
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+ $v_header['index'] = $i;
+
+ // ----- Get the only interesting attributes
+ $this->privConvertHeader2FileInfo($v_header, $p_list[$i]);
+ unset($v_header);
+ }
+
+ // ----- Close the zip file
+ $this->privCloseFd();
+
+ // ----- Magic quotes trick
+ $this->privSwapBackMagicQuotes();
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : privConvertHeader2FileInfo()
+ // Description :
+ // This function takes the file informations from the central directory
+ // entries and extract the interesting parameters that will be given back.
+ // The resulting file infos are set in the array $p_info
+ // $p_info['filename'] : Filename with full path. Given by user (add),
+ // extracted in the filesystem (extract).
+ // $p_info['stored_filename'] : Stored filename in the archive.
+ // $p_info['size'] = Size of the file.
+ // $p_info['compressed_size'] = Compressed size of the file.
+ // $p_info['mtime'] = Last modification date of the file.
+ // $p_info['comment'] = Comment associated with the file.
+ // $p_info['folder'] = true/false : indicates if the entry is a folder or not.
+ // $p_info['status'] = status of the action on the file.
+ // Parameters :
+ // Return Values :
+ // --------------------------------------------------------------------------------
+ function privConvertHeader2FileInfo($p_header, &$p_info)
+ {
+ //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privConvertHeader2FileInfo", "Filename='".$p_header['filename']."'");
+ $v_result=1;
+
+ // ----- Get the interesting attributes
+ $p_info['filename'] = $p_header['filename'];
+ $p_info['stored_filename'] = $p_header['stored_filename'];
+ $p_info['size'] = $p_header['size'];
+ $p_info['compressed_size'] = $p_header['compressed_size'];
+ $p_info['mtime'] = $p_header['mtime'];
+ $p_info['comment'] = $p_header['comment'];
+ $p_info['folder'] = (($p_header['external']&0x00000010)==0x00000010);
+ $p_info['index'] = $p_header['index'];
+ $p_info['status'] = $p_header['status'];
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : privExtractByRule()
+ // Description :
+ // Extract a file or directory depending of rules (by index, by name, ...)
+ // Parameters :
+ // $p_file_list : An array where will be placed the properties of each
+ // extracted file
+ // $p_path : Path to add while writing the extracted files
+ // $p_remove_path : Path to remove (from the file memorized path) while writing the
+ // extracted files. If the path does not match the file path,
+ // the file is extracted with its memorized path.
+ // $p_remove_path does not apply to 'list' mode.
+ // $p_path and $p_remove_path are commulative.
+ // Return Values :
+ // 1 on success,0 or less on error (see error code list)
+ // --------------------------------------------------------------------------------
+ function privExtractByRule(&$p_file_list, $p_path, $p_remove_path, $p_remove_all_path, &$p_options)
+ {
+ //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privExtractByRule", "path='$p_path', remove_path='$p_remove_path', remove_all_path='".($p_remove_all_path?'true':'false')."'");
+ $v_result=1;
+
+ // ----- Magic quotes trick
+ $this->privDisableMagicQuotes();
+
+ // ----- Check the path
+ if ( ($p_path == "")
+ || ( (substr($p_path, 0, 1) != "/")
+ && (substr($p_path, 0, 3) != "../")
+ && (substr($p_path,1,2)!=":/")))
+ $p_path = "./".$p_path;
+
+ // ----- Reduce the path last (and duplicated) '/'
+ if (($p_path != "./") && ($p_path != "/"))
+ {
+ // ----- Look for the path end '/'
+ while (substr($p_path, -1) == "/")
+ {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Destination path [$p_path] ends by '/'");
+ $p_path = substr($p_path, 0, strlen($p_path)-1);
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Modified to [$p_path]");
+ }
+ }
+
+ // ----- Look for path to remove format (should end by /)
+ if (($p_remove_path != "") && (substr($p_remove_path, -1) != '/'))
+ {
+ $p_remove_path .= '/';
+ }
+ $p_remove_path_size = strlen($p_remove_path);
+
+ // ----- Open the zip file
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode");
+ if (($v_result = $this->privOpenFd('rb')) != 1)
+ {
+ $this->privSwapBackMagicQuotes();
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+
+ // ----- Read the central directory informations
+ $v_central_dir = array();
+ if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
+ {
+ // ----- Close the zip file
+ $this->privCloseFd();
+ $this->privSwapBackMagicQuotes();
+
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+
+ // ----- Start at beginning of Central Dir
+ $v_pos_entry = $v_central_dir['offset'];
+
+ // ----- Read each entry
+ $j_start = 0;
+ for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++)
+ {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Read next file header entry : '$i'");
+
+ // ----- Read next Central dir entry
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Position before rewind : ".ftell($this->zip_fd)."'");
+ @rewind($this->zip_fd);
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Position after rewind : ".ftell($this->zip_fd)."'");
+ if (@fseek($this->zip_fd, $v_pos_entry))
+ {
+ // ----- Close the zip file
+ $this->privCloseFd();
+ $this->privSwapBackMagicQuotes();
+
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
+ return PclZip::errorCode();
+ }
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Position after fseek : ".ftell($this->zip_fd)."'");
+
+ // ----- Read the file header
+ $v_header = array();
+ if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1)
+ {
+ // ----- Close the zip file
+ $this->privCloseFd();
+ $this->privSwapBackMagicQuotes();
+
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+
+ // ----- Store the index
+ $v_header['index'] = $i;
+
+ // ----- Store the file position
+ $v_pos_entry = ftell($this->zip_fd);
+
+ // ----- Look for the specific extract rules
+ $v_extract = false;
+
+ // ----- Look for extract by name rule
+ if ( (isset($p_options[PCLZIP_OPT_BY_NAME]))
+ && ($p_options[PCLZIP_OPT_BY_NAME] != 0)) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract with rule 'ByName'");
+
+ // ----- Look if the filename is in the list
+ for ($j=0; ($j<sizeof($p_options[PCLZIP_OPT_BY_NAME])) && (!$v_extract); $j++) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Compare with file '".$p_options[PCLZIP_OPT_BY_NAME][$j]."'");
+
+ // ----- Look for a directory
+ if (substr($p_options[PCLZIP_OPT_BY_NAME][$j], -1) == "/") {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The searched item is a directory");
+
+ // ----- Look if the directory is in the filename path
+ if ( (strlen($v_header['stored_filename']) > strlen($p_options[PCLZIP_OPT_BY_NAME][$j]))
+ && (substr($v_header['stored_filename'], 0, strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) == $p_options[PCLZIP_OPT_BY_NAME][$j])) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The directory is in the file path");
+ $v_extract = true;
+ }
+ }
+ // ----- Look for a filename
+ elseif ($v_header['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The file is the right one.");
+ $v_extract = true;
+ }
+ }
+ }
+
+ // ----- Look for extract by ereg rule
+ else if ( (isset($p_options[PCLZIP_OPT_BY_EREG]))
+ && ($p_options[PCLZIP_OPT_BY_EREG] != "")) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract by ereg '".$p_options[PCLZIP_OPT_BY_EREG]."'");
+
+ if (ereg($p_options[PCLZIP_OPT_BY_EREG], $v_header['stored_filename'])) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Filename match the regular expression");
+ $v_extract = true;
+ }
+ }
+
+ // ----- Look for extract by preg rule
+ else if ( (isset($p_options[PCLZIP_OPT_BY_PREG]))
+ && ($p_options[PCLZIP_OPT_BY_PREG] != "")) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract with rule 'ByEreg'");
+
+ if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header['stored_filename'])) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Filename match the regular expression");
+ $v_extract = true;
+ }
+ }
+
+ // ----- Look for extract by index rule
+ else if ( (isset($p_options[PCLZIP_OPT_BY_INDEX]))
+ && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract with rule 'ByIndex'");
+
+ // ----- Look if the index is in the list
+ for ($j=$j_start; ($j<sizeof($p_options[PCLZIP_OPT_BY_INDEX])) && (!$v_extract); $j++) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Look if index '$i' is in [".$p_options[PCLZIP_OPT_BY_INDEX][$j]['start'].",".$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']."]");
+
+ if (($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i<=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Found as part of an index range");
+ $v_extract = true;
+ }
+ if ($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Do not look this index range for next loop");
+ $j_start = $j+1;
+ }
+
+ if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start']>$i) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Index range is greater than index, stop loop");
+ break;
+ }
+ }
+ }
+
+ // ----- Look for no rule, which means extract all the archive
+ else {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract with no rule (extract all)");
+ $v_extract = true;
+ }
+
+ // ----- Check compression method
+ if ( ($v_extract)
+ && ( ($v_header['compression'] != 8)
+ && ($v_header['compression'] != 0))) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Unsupported compression method (".$v_header['compression'].")");
+ $v_header['status'] = 'unsupported_compression';
+
+ // ----- Look for PCLZIP_OPT_STOP_ON_ERROR
+ if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
+ && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "PCLZIP_OPT_STOP_ON_ERROR is selected, extraction will be stopped");
+
+ $this->privSwapBackMagicQuotes();
+
+ PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_COMPRESSION,
+ "Filename '".$v_header['stored_filename']."' is "
+ ."compressed by an unsupported compression "
+ ."method (".$v_header['compression'].") ");
+
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
+ return PclZip::errorCode();
+ }
+ }
+
+ // ----- Check encrypted files
+ if (($v_extract) && (($v_header['flag'] & 1) == 1)) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Unsupported file encryption");
+ $v_header['status'] = 'unsupported_encryption';
+
+ // ----- Look for PCLZIP_OPT_STOP_ON_ERROR
+ if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
+ && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "PCLZIP_OPT_STOP_ON_ERROR is selected, extraction will be stopped");
+
+ $this->privSwapBackMagicQuotes();
+
+ PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_ENCRYPTION,
+ "Unsupported encryption for "
+ ." filename '".$v_header['stored_filename']
+ ."'");
+
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
+ return PclZip::errorCode();
+ }
+ }
+
+ // ----- Look for real extraction
+ if (($v_extract) && ($v_header['status'] != 'ok')) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "No need for extract");
+ $v_result = $this->privConvertHeader2FileInfo($v_header,
+ $p_file_list[$v_nb_extracted++]);
+ if ($v_result != 1) {
+ $this->privCloseFd();
+ $this->privSwapBackMagicQuotes();
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+
+ $v_extract = false;
+ }
+
+ // ----- Look for real extraction
+ if ($v_extract)
+ {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extracting file '".$v_header['filename']."', index '$i'");
+
+ // ----- Go to the file position
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position before rewind : ".ftell($this->zip_fd)."'");
+ @rewind($this->zip_fd);
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position after rewind : ".ftell($this->zip_fd)."'");
+ if (@fseek($this->zip_fd, $v_header['offset']))
+ {
+ // ----- Close the zip file
+ $this->privCloseFd();
+
+ $this->privSwapBackMagicQuotes();
+
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
+ return PclZip::errorCode();
+ }
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position after fseek : ".ftell($this->zip_fd)."'");
+
+ // ----- Look for extraction as string
+ if ($p_options[PCLZIP_OPT_EXTRACT_AS_STRING]) {
+
+ // ----- Extracting the file
+ $v_result1 = $this->privExtractFileAsString($v_header, $v_string);
+ if ($v_result1 < 1) {
+ $this->privCloseFd();
+ $this->privSwapBackMagicQuotes();
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result1);
+ return $v_result1;
+ }
+
+ // ----- Get the only interesting attributes
+ if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted])) != 1)
+ {
+ // ----- Close the zip file
+ $this->privCloseFd();
+ $this->privSwapBackMagicQuotes();
+
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+
+ // ----- Set the file content
+ $p_file_list[$v_nb_extracted]['content'] = $v_string;
+
+ // ----- Next extracted file
+ $v_nb_extracted++;
+
+ // ----- Look for user callback abort
+ if ($v_result1 == 2) {
+ break;
+ }
+ }
+ // ----- Look for extraction in standard output
+ elseif ( (isset($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT]))
+ && ($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT])) {
+ // ----- Extracting the file in standard output
+ $v_result1 = $this->privExtractFileInOutput($v_header, $p_options);
+ if ($v_result1 < 1) {
+ $this->privCloseFd();
+ $this->privSwapBackMagicQuotes();
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result1);
+ return $v_result1;
+ }
+
+ // ----- Get the only interesting attributes
+ if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1) {
+ $this->privCloseFd();
+ $this->privSwapBackMagicQuotes();
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+
+ // ----- Look for user callback abort
+ if ($v_result1 == 2) {
+ break;
+ }
+ }
+ // ----- Look for normal extraction
+ else {
+ // ----- Extracting the file
+ $v_result1 = $this->privExtractFile($v_header,
+ $p_path, $p_remove_path,
+ $p_remove_all_path,
+ $p_options);
+ if ($v_result1 < 1) {
+ $this->privCloseFd();
+ $this->privSwapBackMagicQuotes();
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result1);
+ return $v_result1;
+ }
+
+ // ----- Get the only interesting attributes
+ if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1)
+ {
+ // ----- Close the zip file
+ $this->privCloseFd();
+ $this->privSwapBackMagicQuotes();
+
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+
+ // ----- Look for user callback abort
+ if ($v_result1 == 2) {
+ break;
+ }
+ }
+ }
+ }
+
+ // ----- Close the zip file
+ $this->privCloseFd();
+ $this->privSwapBackMagicQuotes();
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : privExtractFile()
+ // Description :
+ // Parameters :
+ // Return Values :
+ //
+ // 1 : ... ?
+ // PCLZIP_ERR_USER_ABORTED(2) : User ask for extraction stop in callback
+ // --------------------------------------------------------------------------------
+ function privExtractFile(&$p_entry, $p_path, $p_remove_path, $p_remove_all_path, &$p_options)
+ {
+ //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, 'PclZip::privExtractFile', "path='$p_path', remove_path='$p_remove_path', remove_all_path='".($p_remove_all_path?'true':'false')."'");
+ $v_result=1;
+
+ // ----- Read the file header
+ if (($v_result = $this->privReadFileHeader($v_header)) != 1)
+ {
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Found file '".$v_header['filename']."', size '".$v_header['size']."'");
+
+ // ----- Check that the file header is coherent with $p_entry info
+ if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) {
+ // TBC
+ }
+
+ // ----- Look for all path to remove
+ if ($p_remove_all_path == true) {
+ // ----- Look for folder entry that not need to be extracted
+ if (($p_entry['external']&0x00000010)==0x00000010) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "The entry is a folder : need to be filtered");
+
+ $p_entry['status'] = "filtered";
+
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "All path is removed");
+ // ----- Get the basename of the path
+ $p_entry['filename'] = basename($p_entry['filename']);
+ }
+
+ // ----- Look for path to remove
+ else if ($p_remove_path != "")
+ {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Look for some path to remove");
+ if (PclZipUtilPathInclusion($p_remove_path, $p_entry['filename']) == 2)
+ {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "The folder is the same as the removed path '".$p_entry['filename']."'");
+
+ // ----- Change the file status
+ $p_entry['status'] = "filtered";
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+
+ $p_remove_path_size = strlen($p_remove_path);
+ if (substr($p_entry['filename'], 0, $p_remove_path_size) == $p_remove_path)
+ {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Found path '$p_remove_path' to remove in file '".$p_entry['filename']."'");
+
+ // ----- Remove the path
+ $p_entry['filename'] = substr($p_entry['filename'], $p_remove_path_size);
+
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Resulting file is '".$p_entry['filename']."'");
+ }
+ }
+
+ // ----- Add the path
+ if ($p_path != '') {
+ $p_entry['filename'] = $p_path."/".$p_entry['filename'];
+ }
+
+ // ----- Check a base_dir_restriction
+ if (isset($p_options[PCLZIP_OPT_EXTRACT_DIR_RESTRICTION])) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Check the extract directory restriction");
+ $v_inclusion
+ = PclZipUtilPathInclusion($p_options[PCLZIP_OPT_EXTRACT_DIR_RESTRICTION],
+ $p_entry['filename']);
+ if ($v_inclusion == 0) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "PCLZIP_OPT_EXTRACT_DIR_RESTRICTION is selected, file is outside restriction");
+
+ PclZip::privErrorLog(PCLZIP_ERR_DIRECTORY_RESTRICTION,
+ "Filename '".$p_entry['filename']."' is "
+ ."outside PCLZIP_OPT_EXTRACT_DIR_RESTRICTION");
+
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
+ return PclZip::errorCode();
+ }
+ }
+
+ // ----- Look for pre-extract callback
+ if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "A pre-callback '".$p_options[PCLZIP_CB_PRE_EXTRACT]."()') is defined for the extraction");
+
+ // ----- Generate a local information
+ $v_local_header = array();
+ $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
+
+ // ----- Call the callback
+ // Here I do not use call_user_func() because I need to send a reference to the
+ // header.
+ eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);');
+ if ($v_result == 0) {
+ // ----- Change the file status
+ $p_entry['status'] = "skipped";
+ $v_result = 1;
+ }
+
+ // ----- Look for abort result
+ if ($v_result == 2) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "User callback abort the extraction");
+ // ----- This status is internal and will be changed in 'skipped'
+ $p_entry['status'] = "aborted";
+ $v_result = PCLZIP_ERR_USER_ABORTED;
+ }
+
+ // ----- Update the informations
+ // Only some fields can be modified
+ $p_entry['filename'] = $v_local_header['filename'];
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "New filename is '".$p_entry['filename']."'");
+ }
+
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extracting file (with path) '".$p_entry['filename']."', size '$v_header[size]'");
+
+ // ----- Look if extraction should be done
+ if ($p_entry['status'] == 'ok') {
+
+ // ----- Look for specific actions while the file exist
+ if (file_exists($p_entry['filename']))
+ {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "File '".$p_entry['filename']."' already exists");
+
+ // ----- Look if file is a directory
+ if (is_dir($p_entry['filename']))
+ {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Existing file '".$p_entry['filename']."' is a directory");
+
+ // ----- Change the file status
+ $p_entry['status'] = "already_a_directory";
+
+ // ----- Look for PCLZIP_OPT_STOP_ON_ERROR
+ // For historical reason first PclZip implementation does not stop
+ // when this kind of error occurs.
+ if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
+ && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "PCLZIP_OPT_STOP_ON_ERROR is selected, extraction will be stopped");
+
+ PclZip::privErrorLog(PCLZIP_ERR_ALREADY_A_DIRECTORY,
+ "Filename '".$p_entry['filename']."' is "
+ ."already used by an existing directory");
+
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
+ return PclZip::errorCode();
+ }
+ }
+ // ----- Look if file is write protected
+ else if (!is_writeable($p_entry['filename']))
+ {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Existing file '".$p_entry['filename']."' is write protected");
+
+ // ----- Change the file status
+ $p_entry['status'] = "write_protected";
+
+ // ----- Look for PCLZIP_OPT_STOP_ON_ERROR
+ // For historical reason first PclZip implementation does not stop
+ // when this kind of error occurs.
+ if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
+ && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "PCLZIP_OPT_STOP_ON_ERROR is selected, extraction will be stopped");
+
+ PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL,
+ "Filename '".$p_entry['filename']."' exists "
+ ."and is write protected");
+
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
+ return PclZip::errorCode();
+ }
+ }
+
+ // ----- Look if the extracted file is older
+ else if (filemtime($p_entry['filename']) > $p_entry['mtime'])
+ {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Existing file '".$p_entry['filename']."' is newer (".date("l dS of F Y h:i:s A", filemtime($p_entry['filename'])).") than the extracted file (".date("l dS of F Y h:i:s A", $p_entry['mtime']).")");
+ // ----- Change the file status
+ if ( (isset($p_options[PCLZIP_OPT_REPLACE_NEWER]))
+ && ($p_options[PCLZIP_OPT_REPLACE_NEWER]===true)) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "PCLZIP_OPT_REPLACE_NEWER is selected, file will be replaced");
+ }
+ else {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "File will not be replaced");
+ $p_entry['status'] = "newer_exist";
+
+ // ----- Look for PCLZIP_OPT_STOP_ON_ERROR
+ // For historical reason first PclZip implementation does not stop
+ // when this kind of error occurs.
+ if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
+ && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "PCLZIP_OPT_STOP_ON_ERROR is selected, extraction will be stopped");
+
+ PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL,
+ "Newer version of '".$p_entry['filename']."' exists "
+ ."and option PCLZIP_OPT_REPLACE_NEWER is not selected");
+
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
+ return PclZip::errorCode();
+ }
+ }
+ }
+ else {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Existing file '".$p_entry['filename']."' is older than the extrated one - will be replaced by the extracted one (".date("l dS of F Y h:i:s A", filemtime($p_entry['filename'])).") than the extracted file (".date("l dS of F Y h:i:s A", $p_entry['mtime']).")");
+ }
+ }
+
+ // ----- Check the directory availability and create it if necessary
+ else {
+ if ((($p_entry['external']&0x00000010)==0x00000010) || (substr($p_entry['filename'], -1) == '/'))
+ $v_dir_to_check = $p_entry['filename'];
+ else if (!strstr($p_entry['filename'], "/"))
+ $v_dir_to_check = "";
+ else
+ $v_dir_to_check = dirname($p_entry['filename']);
+
+ if (($v_result = $this->privDirCheck($v_dir_to_check, (($p_entry['external']&0x00000010)==0x00000010))) != 1) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Unable to create path for '".$p_entry['filename']."'");
+
+ // ----- Change the file status
+ $p_entry['status'] = "path_creation_fail";
+
+ // ----- Return
+ ////--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ //return $v_result;
+ $v_result = 1;
+ }
+ }
+ }
+
+ // ----- Look if extraction should be done
+ if ($p_entry['status'] == 'ok') {
+
+ // ----- Do the extraction (if not a folder)
+ if (!(($p_entry['external']&0x00000010)==0x00000010))
+ {
+ // ----- Look for not compressed file
+ if ($p_entry['compression'] == 0) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extracting an un-compressed file");
+
+ // ----- Opening destination file
+ if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0)
+ {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Error while opening '".$p_entry['filename']."' in write binary mode");
+
+ // ----- Change the file status
+ $p_entry['status'] = "write_error";
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Read '".$p_entry['size']."' bytes");
+
+ // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks
+ $v_size = $p_entry['compressed_size'];
+ while ($v_size != 0)
+ {
+ $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Read $v_read_size bytes");
+ $v_buffer = @fread($this->zip_fd, $v_read_size);
+ /* Try to speed up the code
+ $v_binary_data = pack('a'.$v_read_size, $v_buffer);
+ @fwrite($v_dest_file, $v_binary_data, $v_read_size);
+ */
+ @fwrite($v_dest_file, $v_buffer, $v_read_size);
+ $v_size -= $v_read_size;
+ }
+
+ // ----- Closing the destination file
+ fclose($v_dest_file);
+
+ // ----- Change the file mtime
+ touch($p_entry['filename'], $p_entry['mtime']);
+
+
+ }
+ else {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extracting a compressed file (Compression method ".$p_entry['compression'].")");
+ // ----- TBC
+ // Need to be finished
+ if (($p_entry['flag'] & 1) == 1) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "File is encrypted");
+ /*
+ // ----- Read the encryption header
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Read 12 encryption header bytes");
+ $v_encryption_header = @fread($this->zip_fd, 12);
+
+ // ----- Read the encrypted & compressed file in a buffer
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Read '".($p_entry['compressed_size']-12)."' compressed & encrypted bytes");
+ $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']-12);
+
+ // ----- Decrypt the buffer
+ $this->privDecrypt($v_encryption_header, $v_buffer,
+ $p_entry['compressed_size']-12, $p_entry['crc']);
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Buffer is '".$v_buffer."'");
+ */
+ }
+ else {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Read '".$p_entry['compressed_size']."' compressed bytes");
+ // ----- Read the compressed file in a buffer (one shot)
+ $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']);
+ }
+
+ // ----- Decompress the file
+ $v_file_content = @gzinflate($v_buffer);
+ unset($v_buffer);
+ if ($v_file_content === FALSE) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Unable to inflate compressed file");
+
+ // ----- Change the file status
+ // TBC
+ $p_entry['status'] = "error";
+
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+
+ // ----- Opening destination file
+ if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Error while opening '".$p_entry['filename']."' in write binary mode");
+
+ // ----- Change the file status
+ $p_entry['status'] = "write_error";
+
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+
+ // ----- Write the uncompressed data
+ @fwrite($v_dest_file, $v_file_content, $p_entry['size']);
+ unset($v_file_content);
+
+ // ----- Closing the destination file
+ @fclose($v_dest_file);
+
+ // ----- Change the file mtime
+ @touch($p_entry['filename'], $p_entry['mtime']);
+ }
+
+ // ----- Look for chmod option
+ if (isset($p_options[PCLZIP_OPT_SET_CHMOD])) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "chmod option activated '".$p_options[PCLZIP_OPT_SET_CHMOD]."'");
+
+ // ----- Change the mode of the file
+ @chmod($p_entry['filename'], $p_options[PCLZIP_OPT_SET_CHMOD]);
+ }
+
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extraction done");
+ }
+ }
+
+ // ----- Change abort status
+ if ($p_entry['status'] == "aborted") {
+ $p_entry['status'] = "skipped";
+ }
+
+ // ----- Look for post-extract callback
+ elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "A post-callback '".$p_options[PCLZIP_CB_POST_EXTRACT]."()') is defined for the extraction");
+
+ // ----- Generate a local information
+ $v_local_header = array();
+ $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
+
+ // ----- Call the callback
+ // Here I do not use call_user_func() because I need to send a reference to the
+ // header.
+ eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);');
+
+ // ----- Look for abort result
+ if ($v_result == 2) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "User callback abort the extraction");
+ $v_result = PCLZIP_ERR_USER_ABORTED;
+ }
+ }
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : privExtractFileInOutput()
+ // Description :
+ // Parameters :
+ // Return Values :
+ // --------------------------------------------------------------------------------
+ function privExtractFileInOutput(&$p_entry, &$p_options)
+ {
+ //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, 'PclZip::privExtractFileInOutput', "");
+ $v_result=1;
+
+ // ----- Read the file header
+ if (($v_result = $this->privReadFileHeader($v_header)) != 1) {
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Found file '".$v_header['filename']."', size '".$v_header['size']."'");
+
+ // ----- Check that the file header is coherent with $p_entry info
+ if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) {
+ // TBC
+ }
+
+ // ----- Look for pre-extract callback
+ if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "A pre-callback '".$p_options[PCLZIP_CB_PRE_EXTRACT]."()') is defined for the extraction");
+
+ // ----- Generate a local information
+ $v_local_header = array();
+ $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
+
+ // ----- Call the callback
+ // Here I do not use call_user_func() because I need to send a reference to the
+ // header.
+ eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);');
+ if ($v_result == 0) {
+ // ----- Change the file status
+ $p_entry['status'] = "skipped";
+ $v_result = 1;
+ }
+
+ // ----- Look for abort result
+ if ($v_result == 2) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "User callback abort the extraction");
+ // ----- This status is internal and will be changed in 'skipped'
+ $p_entry['status'] = "aborted";
+ $v_result = PCLZIP_ERR_USER_ABORTED;
+ }
+
+ // ----- Update the informations
+ // Only some fields can be modified
+ $p_entry['filename'] = $v_local_header['filename'];
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "New filename is '".$p_entry['filename']."'");
+ }
+
+ // ----- Trace
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extracting file (with path) '".$p_entry['filename']."', size '$v_header[size]'");
+
+ // ----- Look if extraction should be done
+ if ($p_entry['status'] == 'ok') {
+
+ // ----- Do the extraction (if not a folder)
+ if (!(($p_entry['external']&0x00000010)==0x00000010)) {
+ // ----- Look for not compressed file
+ if ($p_entry['compressed_size'] == $p_entry['size']) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extracting an un-compressed file");
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Reading '".$p_entry['size']."' bytes");
+
+ // ----- Read the file in a buffer (one shot)
+ $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']);
+
+ // ----- Send the file to the output
+ echo $v_buffer;
+ unset($v_buffer);
+ }
+ else {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extracting a compressed file");
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Reading '".$p_entry['size']."' bytes");
+
+ // ----- Read the compressed file in a buffer (one shot)
+ $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']);
+
+ // ----- Decompress the file
+ $v_file_content = gzinflate($v_buffer);
+ unset($v_buffer);
+
+ // ----- Send the file to the output
+ echo $v_file_content;
+ unset($v_file_content);
+ }
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extraction done");
+ }
+ }
+
+ // ----- Change abort status
+ if ($p_entry['status'] == "aborted") {
+ $p_entry['status'] = "skipped";
+ }
+
+ // ----- Look for post-extract callback
+ elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "A post-callback '".$p_options[PCLZIP_CB_POST_EXTRACT]."()') is defined for the extraction");
+
+ // ----- Generate a local information
+ $v_local_header = array();
+ $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
+
+ // ----- Call the callback
+ // Here I do not use call_user_func() because I need to send a reference to the
+ // header.
+ eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);');
+
+ // ----- Look for abort result
+ if ($v_result == 2) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "User callback abort the extraction");
+ $v_result = PCLZIP_ERR_USER_ABORTED;
+ }
+ }
+
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : privExtractFileAsString()
+ // Description :
+ // Parameters :
+ // Return Values :
+ // --------------------------------------------------------------------------------
+ function privExtractFileAsString(&$p_entry, &$p_string)
+ {
+ //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, 'PclZip::privExtractFileAsString', "p_entry['filename']='".$p_entry['filename']."'");
+ $v_result=1;
+
+ // ----- Read the file header
+ $v_header = array();
+ if (($v_result = $this->privReadFileHeader($v_header)) != 1)
+ {
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Found file '".$v_header['filename']."', size '".$v_header['size']."'");
+
+ // ----- Check that the file header is coherent with $p_entry info
+ if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) {
+ // TBC
+ }
+
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extracting file in string (with path) '".$p_entry['filename']."', size '$v_header[size]'");
+
+ // ----- Do the extraction (if not a folder)
+ if (!(($p_entry['external']&0x00000010)==0x00000010))
+ {
+ // ----- Look for not compressed file
+// if ($p_entry['compressed_size'] == $p_entry['size'])
+ if ($p_entry['compression'] == 0) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extracting an un-compressed file");
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Reading '".$p_entry['size']."' bytes");
+
+ // ----- Reading the file
+ $p_string = @fread($this->zip_fd, $p_entry['compressed_size']);
+ }
+ else {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extracting a compressed file (compression method '".$p_entry['compression']."')");
+
+ // ----- Reading the file
+ $v_data = @fread($this->zip_fd, $p_entry['compressed_size']);
+
+ // ----- Decompress the file
+ if (($p_string = @gzinflate($v_data)) === FALSE) {
+ // TBC
+ }
+ }
+
+ // ----- Trace
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extraction done");
+ }
+ else {
+ // TBC : error : can not extract a folder in a string
+ }
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : privReadFileHeader()
+ // Description :
+ // Parameters :
+ // Return Values :
+ // --------------------------------------------------------------------------------
+ function privReadFileHeader(&$p_header)
+ {
+ //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privReadFileHeader", "");
+ $v_result=1;
+
+ // ----- Read the 4 bytes signature
+ $v_binary_data = @fread($this->zip_fd, 4);
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Binary data is : '".sprintf("%08x", $v_binary_data)."'");
+ $v_data = unpack('Vid', $v_binary_data);
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Binary signature is : '".sprintf("0x%08x", $v_data['id'])."'");
+
+ // ----- Check signature
+ if ($v_data['id'] != 0x04034b50)
+ {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Invalid File header");
+
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure');
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
+ return PclZip::errorCode();
+ }
+
+ // ----- Read the first 42 bytes of the header
+ $v_binary_data = fread($this->zip_fd, 26);
+
+ // ----- Look for invalid block size
+ if (strlen($v_binary_data) != 26)
+ {
+ $p_header['filename'] = "";
+ $p_header['status'] = "invalid_header";
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Invalid block size : ".strlen($v_binary_data));
+
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid block size : ".strlen($v_binary_data));
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
+ return PclZip::errorCode();
+ }
+
+ // ----- Extract the values
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Header : '".$v_binary_data."'");
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Header (Hex) : '".bin2hex($v_binary_data)."'");
+ $v_data = unpack('vversion/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len', $v_binary_data);
+
+ // ----- Get filename
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "File name length : ".$v_data['filename_len']);
+ $p_header['filename'] = fread($this->zip_fd, $v_data['filename_len']);
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Filename : \''.$p_header['filename'].'\'');
+
+ // ----- Get extra_fields
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extra field length : ".$v_data['extra_len']);
+ if ($v_data['extra_len'] != 0) {
+ $p_header['extra'] = fread($this->zip_fd, $v_data['extra_len']);
+ }
+ else {
+ $p_header['extra'] = '';
+ }
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Extra field : \''.bin2hex($p_header['extra']).'\'');
+
+ // ----- Extract properties
+ $p_header['version_extracted'] = $v_data['version'];
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Version need to extract : ('.$p_header['version_extracted'].') \''.($p_header['version_extracted']/10).'.'.($p_header['version_extracted']%10).'\'');
+ $p_header['compression'] = $v_data['compression'];
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Compression method : \''.$p_header['compression'].'\'');
+ $p_header['size'] = $v_data['size'];
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Size : \''.$p_header['size'].'\'');
+ $p_header['compressed_size'] = $v_data['compressed_size'];
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Compressed Size : \''.$p_header['compressed_size'].'\'');
+ $p_header['crc'] = $v_data['crc'];
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'CRC : \''.sprintf("0x%X", $p_header['crc']).'\'');
+ $p_header['flag'] = $v_data['flag'];
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Flag : \''.$p_header['flag'].'\'');
+ $p_header['filename_len'] = $v_data['filename_len'];
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Filename_len : \''.$p_header['filename_len'].'\'');
+
+ // ----- Recuperate date in UNIX format
+ $p_header['mdate'] = $v_data['mdate'];
+ $p_header['mtime'] = $v_data['mtime'];
+ if ($p_header['mdate'] && $p_header['mtime'])
+ {
+ // ----- Extract time
+ $v_hour = ($p_header['mtime'] & 0xF800) >> 11;
+ $v_minute = ($p_header['mtime'] & 0x07E0) >> 5;
+ $v_seconde = ($p_header['mtime'] & 0x001F)*2;
+
+ // ----- Extract date
+ $v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980;
+ $v_month = ($p_header['mdate'] & 0x01E0) >> 5;
+ $v_day = $p_header['mdate'] & 0x001F;
+
+ // ----- Get UNIX date format
+ $p_header['mtime'] = mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year);
+
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Date : \''.date("d/m/y H:i:s", $p_header['mtime']).'\'');
+ }
+ else
+ {
+ $p_header['mtime'] = time();
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Date is actual : \''.date("d/m/y H:i:s", $p_header['mtime']).'\'');
+ }
+
+ // TBC
+ //for(reset($v_data); $key = key($v_data); next($v_data)) {
+ // //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Attribut[$key] = ".$v_data[$key]);
+ //}
+
+ // ----- Set the stored filename
+ $p_header['stored_filename'] = $p_header['filename'];
+
+ // ----- Set the status field
+ $p_header['status'] = "ok";
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : privReadCentralFileHeader()
+ // Description :
+ // Parameters :
+ // Return Values :
+ // --------------------------------------------------------------------------------
+ function privReadCentralFileHeader(&$p_header)
+ {
+ //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privReadCentralFileHeader", "");
+ $v_result=1;
+
+ // ----- Read the 4 bytes signature
+ $v_binary_data = @fread($this->zip_fd, 4);
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Binary data is : '".sprintf("%08x", $v_binary_data)."'");
+ $v_data = unpack('Vid', $v_binary_data);
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Binary signature is : '".sprintf("0x%08x", $v_data['id'])."'");
+
+ // ----- Check signature
+ if ($v_data['id'] != 0x02014b50)
+ {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Invalid Central Dir File signature");
+
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure');
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
+ return PclZip::errorCode();
+ }
+
+ // ----- Read the first 42 bytes of the header
+ $v_binary_data = fread($this->zip_fd, 42);
+
+ // ----- Look for invalid block size
+ if (strlen($v_binary_data) != 42)
+ {
+ $p_header['filename'] = "";
+ $p_header['status'] = "invalid_header";
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Invalid block size : ".strlen($v_binary_data));
+
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid block size : ".strlen($v_binary_data));
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
+ return PclZip::errorCode();
+ }
+
+ // ----- Extract the values
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Header : '".$v_binary_data."'");
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Header (Hex) : '".bin2hex($v_binary_data)."'");
+ $p_header = unpack('vversion/vversion_extracted/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len/vcomment_len/vdisk/vinternal/Vexternal/Voffset', $v_binary_data);
+
+ // ----- Get filename
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "File name length : ".$p_header['filename_len']);
+ if ($p_header['filename_len'] != 0)
+ $p_header['filename'] = fread($this->zip_fd, $p_header['filename_len']);
+ else
+ $p_header['filename'] = '';
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Filename : \''.$p_header['filename'].'\'');
+
+ // ----- Get extra
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Extra length : ".$p_header['extra_len']);
+ if ($p_header['extra_len'] != 0)
+ $p_header['extra'] = fread($this->zip_fd, $p_header['extra_len']);
+ else
+ $p_header['extra'] = '';
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Extra : \''.$p_header['extra'].'\'');
+
+ // ----- Get comment
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Comment length : ".$p_header['comment_len']);
+ if ($p_header['comment_len'] != 0)
+ $p_header['comment'] = fread($this->zip_fd, $p_header['comment_len']);
+ else
+ $p_header['comment'] = '';
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Comment : \''.$p_header['comment'].'\'');
+
+ // ----- Extract properties
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Version : \''.($p_header['version']/10).'.'.($p_header['version']%10).'\'');
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Version need to extract : \''.($p_header['version_extracted']/10).'.'.($p_header['version_extracted']%10).'\'');
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Size : \''.$p_header['size'].'\'');
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Compressed Size : \''.$p_header['compressed_size'].'\'');
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'CRC : \''.sprintf("0x%X", $p_header['crc']).'\'');
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Flag : \''.$p_header['flag'].'\'');
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Offset : \''.$p_header['offset'].'\'');
+
+ // ----- Recuperate date in UNIX format
+ if ($p_header['mdate'] && $p_header['mtime'])
+ {
+ // ----- Extract time
+ $v_hour = ($p_header['mtime'] & 0xF800) >> 11;
+ $v_minute = ($p_header['mtime'] & 0x07E0) >> 5;
+ $v_seconde = ($p_header['mtime'] & 0x001F)*2;
+
+ // ----- Extract date
+ $v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980;
+ $v_month = ($p_header['mdate'] & 0x01E0) >> 5;
+ $v_day = $p_header['mdate'] & 0x001F;
+
+ // ----- Get UNIX date format
+ $p_header['mtime'] = mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year);
+
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Date : \''.date("d/m/y H:i:s", $p_header['mtime']).'\'');
+ }
+ else
+ {
+ $p_header['mtime'] = time();
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Date is actual : \''.date("d/m/y H:i:s", $p_header['mtime']).'\'');
+ }
+
+ // ----- Set the stored filename
+ $p_header['stored_filename'] = $p_header['filename'];
+
+ // ----- Set default status to ok
+ $p_header['status'] = 'ok';
+
+ // ----- Look if it is a directory
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Internal (Hex) : '".sprintf("Ox%04X", $p_header['internal'])."'");
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "External (Hex) : '".sprintf("Ox%04X", $p_header['external'])."' (".(($p_header['external']&0x00000010)==0x00000010?'is a folder':'is a file').')');
+ if (substr($p_header['filename'], -1) == '/') {
+ //$p_header['external'] = 0x41FF0010;
+ $p_header['external'] = 0x00000010;
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Force folder external : \''.sprintf("Ox%04X", $p_header['external']).'\'');
+ }
+
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Header of filename : \''.$p_header['filename'].'\'');
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : privCheckFileHeaders()
+ // Description :
+ // Parameters :
+ // Return Values :
+ // 1 on success,
+ // 0 on error;
+ // --------------------------------------------------------------------------------
+ function privCheckFileHeaders(&$p_local_header, &$p_central_header)
+ {
+ //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privCheckFileHeaders", "");
+ $v_result=1;
+
+ // ----- Check the static values
+ // TBC
+ if ($p_local_header['filename'] != $p_central_header['filename']) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Bad check "filename" : TBC To Be Completed');
+ }
+ if ($p_local_header['version_extracted'] != $p_central_header['version_extracted']) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Bad check "version_extracted" : TBC To Be Completed');
+ }
+ if ($p_local_header['flag'] != $p_central_header['flag']) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Bad check "flag" : TBC To Be Completed');
+ }
+ if ($p_local_header['compression'] != $p_central_header['compression']) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Bad check "compression" : TBC To Be Completed');
+ }
+ if ($p_local_header['mtime'] != $p_central_header['mtime']) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Bad check "mtime" : TBC To Be Completed');
+ }
+ if ($p_local_header['filename_len'] != $p_central_header['filename_len']) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Bad check "filename_len" : TBC To Be Completed');
+ }
+
+ // ----- Look for flag bit 3
+ if (($p_local_header['flag'] & 8) == 8) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Purpose bit flag bit 3 set !');
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'File size, compression size and crc found in central header');
+ $p_local_header['size'] = $p_central_header['size'];
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Size : \''.$p_local_header['size'].'\'');
+ $p_local_header['compressed_size'] = $p_central_header['compressed_size'];
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Compressed Size : \''.$p_local_header['compressed_size'].'\'');
+ $p_local_header['crc'] = $p_central_header['crc'];
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'CRC : \''.sprintf("0x%X", $p_local_header['crc']).'\'');
+ }
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : privReadEndCentralDir()
+ // Description :
+ // Parameters :
+ // Return Values :
+ // --------------------------------------------------------------------------------
+ function privReadEndCentralDir(&$p_central_dir)
+ {
+ //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privReadEndCentralDir", "");
+ $v_result=1;
+
+ // ----- Go to the end of the zip file
+ $v_size = filesize($this->zipname);
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Size of the file :$v_size");
+ @fseek($this->zip_fd, $v_size);
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Position at end of zip file : \''.ftell($this->zip_fd).'\'');
+ if (@ftell($this->zip_fd) != $v_size)
+ {
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to go to the end of the archive \''.$this->zipname.'\'');
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
+ return PclZip::errorCode();
+ }
+
+ // ----- First try : look if this is an archive with no commentaries (most of the time)
+ // in this case the end of central dir is at 22 bytes of the file end
+ $v_found = 0;
+ if ($v_size > 26) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Look for central dir with no comment');
+ @fseek($this->zip_fd, $v_size-22);
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Position after min central position : \''.ftell($this->zip_fd).'\'');
+ if (($v_pos = @ftell($this->zip_fd)) != ($v_size-22))
+ {
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \''.$this->zipname.'\'');
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
+ return PclZip::errorCode();
+ }
+
+ // ----- Read for bytes
+ $v_binary_data = @fread($this->zip_fd, 4);
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Binary data is : '".sprintf("%08x", $v_binary_data)."'");
+ $v_data = @unpack('Vid', $v_binary_data);
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Binary signature is : '".sprintf("0x%08x", $v_data['id'])."'");
+
+ // ----- Check signature
+ if ($v_data['id'] == 0x06054b50) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Found central dir at the default position.");
+ $v_found = 1;
+ }
+
+ $v_pos = ftell($this->zip_fd);
+ }
+
+ // ----- Go back to the maximum possible size of the Central Dir End Record
+ if (!$v_found) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Start extended search of end central dir');
+ $v_maximum_size = 65557; // 0xFFFF + 22;
+ if ($v_maximum_size > $v_size)
+ $v_maximum_size = $v_size;
+ @fseek($this->zip_fd, $v_size-$v_maximum_size);
+ if (@ftell($this->zip_fd) != ($v_size-$v_maximum_size))
+ {
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \''.$this->zipname.'\'');
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
+ return PclZip::errorCode();
+ }
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Position after max central position : \''.ftell($this->zip_fd).'\'');
+
+ // ----- Read byte per byte in order to find the signature
+ $v_pos = ftell($this->zip_fd);
+ $v_bytes = 0x00000000;
+ while ($v_pos < $v_size)
+ {
+ // ----- Read a byte
+ $v_byte = @fread($this->zip_fd, 1);
+
+ // ----- Add the byte
+ $v_bytes = ($v_bytes << 8) | Ord($v_byte);
+
+ // ----- Compare the bytes
+ if ($v_bytes == 0x504b0506)
+ {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Found End Central Dir signature at position : \''.ftell($this->zip_fd).'\'');
+ $v_pos++;
+ break;
+ }
+
+ $v_pos++;
+ }
+
+ // ----- Look if not found end of central dir
+ if ($v_pos == $v_size)
+ {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Unable to find End of Central Dir Record signature");
+
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Unable to find End of Central Dir Record signature");
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
+ return PclZip::errorCode();
+ }
+ }
+
+ // ----- Read the first 18 bytes of the header
+ $v_binary_data = fread($this->zip_fd, 18);
+
+ // ----- Look for invalid block size
+ if (strlen($v_binary_data) != 18)
+ {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Invalid End of Central Dir Record size : ".strlen($v_binary_data));
+
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid End of Central Dir Record size : ".strlen($v_binary_data));
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
+ return PclZip::errorCode();
+ }
+
+ // ----- Extract the values
+ ////--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Central Dir Record : '".$v_binary_data."'");
+ ////--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Central Dir Record (Hex) : '".bin2hex($v_binary_data)."'");
+ $v_data = unpack('vdisk/vdisk_start/vdisk_entries/ventries/Vsize/Voffset/vcomment_size', $v_binary_data);
+
+ // ----- Check the global size
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Comment length : ".$v_data['comment_size']);
+ if (($v_pos + $v_data['comment_size'] + 18) != $v_size) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "The central dir is not at the end of the archive. Some trailing bytes exists after the archive.");
+
+ // ----- Removed in release 2.2 see readme file
+ // The check of the file size is a little too strict.
+ // Some bugs where found when a zip is encrypted/decrypted with 'crypt'.
+ // While decrypted, zip has training 0 bytes
+ if (0) {
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT,
+ 'The central dir is not at the end of the archive.'
+ .' Some trailing bytes exists after the archive.');
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
+ return PclZip::errorCode();
+ }
+ }
+
+ // ----- Get comment
+ if ($v_data['comment_size'] != 0)
+ $p_central_dir['comment'] = fread($this->zip_fd, $v_data['comment_size']);
+ else
+ $p_central_dir['comment'] = '';
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Comment : \''.$p_central_dir['comment'].'\'');
+
+ $p_central_dir['entries'] = $v_data['entries'];
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Nb of entries : \''.$p_central_dir['entries'].'\'');
+ $p_central_dir['disk_entries'] = $v_data['disk_entries'];
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Nb of entries for this disk : \''.$p_central_dir['disk_entries'].'\'');
+ $p_central_dir['offset'] = $v_data['offset'];
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Offset of Central Dir : \''.$p_central_dir['offset'].'\'');
+ $p_central_dir['size'] = $v_data['size'];
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Size of Central Dir : \''.$p_central_dir['size'].'\'');
+ $p_central_dir['disk'] = $v_data['disk'];
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Disk number : \''.$p_central_dir['disk'].'\'');
+ $p_central_dir['disk_start'] = $v_data['disk_start'];
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Start disk number : \''.$p_central_dir['disk_start'].'\'');
+
+ // TBC
+ //for(reset($p_central_dir); $key = key($p_central_dir); next($p_central_dir)) {
+ // //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "central_dir[$key] = ".$p_central_dir[$key]);
+ //}
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : privDeleteByRule()
+ // Description :
+ // Parameters :
+ // Return Values :
+ // --------------------------------------------------------------------------------
+ function privDeleteByRule(&$p_result_list, &$p_options)
+ {
+ //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privDeleteByRule", "");
+ $v_result=1;
+ $v_list_detail = array();
+
+ // ----- Open the zip file
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode");
+ if (($v_result=$this->privOpenFd('rb')) != 1)
+ {
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+
+ // ----- Read the central directory informations
+ $v_central_dir = array();
+ if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
+ {
+ $this->privCloseFd();
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+
+ // ----- Go to beginning of File
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position in file : ".ftell($this->zip_fd)."'");
+ @rewind($this->zip_fd);
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position in file : ".ftell($this->zip_fd)."'");
+
+ // ----- Scan all the files
+ // ----- Start at beginning of Central Dir
+ $v_pos_entry = $v_central_dir['offset'];
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position before rewind : ".ftell($this->zip_fd)."'");
+ @rewind($this->zip_fd);
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position after rewind : ".ftell($this->zip_fd)."'");
+ if (@fseek($this->zip_fd, $v_pos_entry))
+ {
+ // ----- Close the zip file
+ $this->privCloseFd();
+
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
+ return PclZip::errorCode();
+ }
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position after fseek : ".ftell($this->zip_fd)."'");
+
+ // ----- Read each entry
+ $v_header_list = array();
+ $j_start = 0;
+ for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++)
+ {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Read next file header entry (index '$i')");
+
+ // ----- Read the file header
+ $v_header_list[$v_nb_extracted] = array();
+ if (($v_result = $this->privReadCentralFileHeader($v_header_list[$v_nb_extracted])) != 1)
+ {
+ // ----- Close the zip file
+ $this->privCloseFd();
+
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Filename (index '$i') : '".$v_header_list[$v_nb_extracted]['stored_filename']."'");
+
+ // ----- Store the index
+ $v_header_list[$v_nb_extracted]['index'] = $i;
+
+ // ----- Look for the specific extract rules
+ $v_found = false;
+
+ // ----- Look for extract by name rule
+ if ( (isset($p_options[PCLZIP_OPT_BY_NAME]))
+ && ($p_options[PCLZIP_OPT_BY_NAME] != 0)) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract with rule 'ByName'");
+
+ // ----- Look if the filename is in the list
+ for ($j=0; ($j<sizeof($p_options[PCLZIP_OPT_BY_NAME])) && (!$v_found); $j++) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Compare with file '".$p_options[PCLZIP_OPT_BY_NAME][$j]."'");
+
+ // ----- Look for a directory
+ if (substr($p_options[PCLZIP_OPT_BY_NAME][$j], -1) == "/") {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The searched item is a directory");
+
+ // ----- Look if the directory is in the filename path
+ if ( (strlen($v_header_list[$v_nb_extracted]['stored_filename']) > strlen($p_options[PCLZIP_OPT_BY_NAME][$j]))
+ && (substr($v_header_list[$v_nb_extracted]['stored_filename'], 0, strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) == $p_options[PCLZIP_OPT_BY_NAME][$j])) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The directory is in the file path");
+ $v_found = true;
+ }
+ elseif ( (($v_header_list[$v_nb_extracted]['external']&0x00000010)==0x00000010) /* Indicates a folder */
+ && ($v_header_list[$v_nb_extracted]['stored_filename'].'/' == $p_options[PCLZIP_OPT_BY_NAME][$j])) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The entry is the searched directory");
+ $v_found = true;
+ }
+ }
+ // ----- Look for a filename
+ elseif ($v_header_list[$v_nb_extracted]['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The file is the right one.");
+ $v_found = true;
+ }
+ }
+ }
+
+ // ----- Look for extract by ereg rule
+ else if ( (isset($p_options[PCLZIP_OPT_BY_EREG]))
+ && ($p_options[PCLZIP_OPT_BY_EREG] != "")) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract by ereg '".$p_options[PCLZIP_OPT_BY_EREG]."'");
+
+ if (ereg($p_options[PCLZIP_OPT_BY_EREG], $v_header_list[$v_nb_extracted]['stored_filename'])) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Filename match the regular expression");
+ $v_found = true;
+ }
+ }
+
+ // ----- Look for extract by preg rule
+ else if ( (isset($p_options[PCLZIP_OPT_BY_PREG]))
+ && ($p_options[PCLZIP_OPT_BY_PREG] != "")) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract with rule 'ByEreg'");
+
+ if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header_list[$v_nb_extracted]['stored_filename'])) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Filename match the regular expression");
+ $v_found = true;
+ }
+ }
+
+ // ----- Look for extract by index rule
+ else if ( (isset($p_options[PCLZIP_OPT_BY_INDEX]))
+ && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract with rule 'ByIndex'");
+
+ // ----- Look if the index is in the list
+ for ($j=$j_start; ($j<sizeof($p_options[PCLZIP_OPT_BY_INDEX])) && (!$v_found); $j++) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Look if index '$i' is in [".$p_options[PCLZIP_OPT_BY_INDEX][$j]['start'].",".$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']."]");
+
+ if (($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i<=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Found as part of an index range");
+ $v_found = true;
+ }
+ if ($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Do not look this index range for next loop");
+ $j_start = $j+1;
+ }
+
+ if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start']>$i) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Index range is greater than index, stop loop");
+ break;
+ }
+ }
+ }
+ else {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "No argument mean remove all file");
+ $v_found = true;
+ }
+
+ // ----- Look for deletion
+ if ($v_found)
+ {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "File '".$v_header_list[$v_nb_extracted]['stored_filename']."', index '$i' need to be deleted");
+ unset($v_header_list[$v_nb_extracted]);
+ }
+ else
+ {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "File '".$v_header_list[$v_nb_extracted]['stored_filename']."', index '$i' will not be deleted");
+ $v_nb_extracted++;
+ }
+ }
+
+ // ----- Look if something need to be deleted
+ if ($v_nb_extracted > 0) {
+
+ // ----- Creates a temporay file
+ $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp';
+
+ // ----- Creates a temporary zip archive
+ $v_temp_zip = new PclZip($v_zip_temp_name);
+
+ // ----- Open the temporary zip file in write mode
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary write mode");
+ if (($v_result = $v_temp_zip->privOpenFd('wb')) != 1) {
+ $this->privCloseFd();
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+
+ // ----- Look which file need to be kept
+ for ($i=0; $i<sizeof($v_header_list); $i++) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Keep entry index '$i' : '".$v_header_list[$i]['filename']."'");
+
+ // ----- Calculate the position of the header
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Offset='". $v_header_list[$i]['offset']."'");
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position before rewind : ".ftell($this->zip_fd)."'");
+ @rewind($this->zip_fd);
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position after rewind : ".ftell($this->zip_fd)."'");
+ if (@fseek($this->zip_fd, $v_header_list[$i]['offset'])) {
+ // ----- Close the zip file
+ $this->privCloseFd();
+ $v_temp_zip->privCloseFd();
+ @unlink($v_zip_temp_name);
+
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
+ return PclZip::errorCode();
+ }
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position after fseek : ".ftell($this->zip_fd)."'");
+
+ // ----- Read the file header
+ $v_local_header = array();
+ if (($v_result = $this->privReadFileHeader($v_local_header)) != 1) {
+ // ----- Close the zip file
+ $this->privCloseFd();
+ $v_temp_zip->privCloseFd();
+ @unlink($v_zip_temp_name);
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+
+ // ----- Check that local file header is same as central file header
+ if ($this->privCheckFileHeaders($v_local_header,
+ $v_header_list[$i]) != 1) {
+ // TBC
+ }
+ unset($v_local_header);
+
+ // ----- Write the file header
+ if (($v_result = $v_temp_zip->privWriteFileHeader($v_header_list[$i])) != 1) {
+ // ----- Close the zip file
+ $this->privCloseFd();
+ $v_temp_zip->privCloseFd();
+ @unlink($v_zip_temp_name);
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Offset for this file is '".$v_header_list[$i]['offset']."'");
+
+ // ----- Read/write the data block
+ if (($v_result = PclZipUtilCopyBlock($this->zip_fd, $v_temp_zip->zip_fd, $v_header_list[$i]['compressed_size'])) != 1) {
+ // ----- Close the zip file
+ $this->privCloseFd();
+ $v_temp_zip->privCloseFd();
+ @unlink($v_zip_temp_name);
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+ }
+
+ // ----- Store the offset of the central dir
+ $v_offset = @ftell($v_temp_zip->zip_fd);
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "New offset of central dir : $v_offset");
+
+ // ----- Re-Create the Central Dir files header
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Creates the new central directory");
+ for ($i=0; $i<sizeof($v_header_list); $i++) {
+ // ----- Create the file header
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Offset of file : ".$v_header_list[$i]['offset']);
+ if (($v_result = $v_temp_zip->privWriteCentralFileHeader($v_header_list[$i])) != 1) {
+ $v_temp_zip->privCloseFd();
+ $this->privCloseFd();
+ @unlink($v_zip_temp_name);
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+
+ // ----- Transform the header to a 'usable' info
+ $v_temp_zip->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]);
+ }
+
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Creates the central directory footer");
+
+ // ----- Zip file comment
+ $v_comment = '';
+ if (isset($p_options[PCLZIP_OPT_COMMENT])) {
+ $v_comment = $p_options[PCLZIP_OPT_COMMENT];
+ }
+
+ // ----- Calculate the size of the central header
+ $v_size = @ftell($v_temp_zip->zip_fd)-$v_offset;
+
+ // ----- Create the central dir footer
+ if (($v_result = $v_temp_zip->privWriteCentralHeader(sizeof($v_header_list), $v_size, $v_offset, $v_comment)) != 1) {
+ // ----- Reset the file list
+ unset($v_header_list);
+ $v_temp_zip->privCloseFd();
+ $this->privCloseFd();
+ @unlink($v_zip_temp_name);
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+
+ // ----- Close
+ $v_temp_zip->privCloseFd();
+ $this->privCloseFd();
+
+ // ----- Delete the zip file
+ // TBC : I should test the result ...
+ @unlink($this->zipname);
+
+ // ----- Rename the temporary file
+ // TBC : I should test the result ...
+ //@rename($v_zip_temp_name, $this->zipname);
+ PclZipUtilRename($v_zip_temp_name, $this->zipname);
+
+ // ----- Destroy the temporary archive
+ unset($v_temp_zip);
+ }
+
+ // ----- Remove every files : reset the file
+ else if ($v_central_dir['entries'] != 0) {
+ $this->privCloseFd();
+
+ if (($v_result = $this->privOpenFd('wb')) != 1) {
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+
+ if (($v_result = $this->privWriteCentralHeader(0, 0, 0, '')) != 1) {
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+
+ $this->privCloseFd();
+ }
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : privDirCheck()
+ // Description :
+ // Check if a directory exists, if not it creates it and all the parents directory
+ // which may be useful.
+ // Parameters :
+ // $p_dir : Directory path to check.
+ // Return Values :
+ // 1 : OK
+ // -1 : Unable to create directory
+ // --------------------------------------------------------------------------------
+ function privDirCheck($p_dir, $p_is_dir=false)
+ {
+ $v_result = 1;
+
+ //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privDirCheck", "entry='$p_dir', is_dir='".($p_is_dir?"true":"false")."'");
+
+ // ----- Remove the final '/'
+ if (($p_is_dir) && (substr($p_dir, -1)=='/'))
+ {
+ $p_dir = substr($p_dir, 0, strlen($p_dir)-1);
+ }
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Looking for entry '$p_dir'");
+
+ // ----- Check the directory availability
+ if ((is_dir($p_dir)) || ($p_dir == ""))
+ {
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, "'$p_dir' is a directory");
+ return 1;
+ }
+
+ // ----- Extract parent directory
+ $p_parent_dir = dirname($p_dir);
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Parent directory is '$p_parent_dir'");
+
+ // ----- Just a check
+ if ($p_parent_dir != $p_dir)
+ {
+ // ----- Look for parent directory
+ if ($p_parent_dir != "")
+ {
+ if (($v_result = $this->privDirCheck($p_parent_dir)) != 1)
+ {
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+ }
+ }
+
+ // ----- Create the directory
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Create directory '$p_dir'");
+ if (!@mkdir($p_dir, 0777))
+ {
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_DIR_CREATE_FAIL, "Unable to create directory '$p_dir'");
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
+ return PclZip::errorCode();
+ }
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result, "Directory '$p_dir' created");
+ return $v_result;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : privMerge()
+ // Description :
+ // If $p_archive_to_add does not exist, the function exit with a success result.
+ // Parameters :
+ // Return Values :
+ // --------------------------------------------------------------------------------
+ function privMerge(&$p_archive_to_add)
+ {
+ //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privMerge", "archive='".$p_archive_to_add->zipname."'");
+ $v_result=1;
+
+ // ----- Look if the archive_to_add exists
+ if (!is_file($p_archive_to_add->zipname))
+ {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Archive to add does not exist. End of merge.");
+
+ // ----- Nothing to merge, so merge is a success
+ $v_result = 1;
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+
+ // ----- Look if the archive exists
+ if (!is_file($this->zipname))
+ {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Archive does not exist, duplicate the archive_to_add.");
+
+ // ----- Do a duplicate
+ $v_result = $this->privDuplicate($p_archive_to_add->zipname);
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+
+ // ----- Open the zip file
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode");
+ if (($v_result=$this->privOpenFd('rb')) != 1)
+ {
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+
+ // ----- Read the central directory informations
+ $v_central_dir = array();
+ if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
+ {
+ $this->privCloseFd();
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+
+ // ----- Go to beginning of File
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position in zip : ".ftell($this->zip_fd)."'");
+ @rewind($this->zip_fd);
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position in zip : ".ftell($this->zip_fd)."'");
+
+ // ----- Open the archive_to_add file
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open archive_to_add in binary read mode");
+ if (($v_result=$p_archive_to_add->privOpenFd('rb')) != 1)
+ {
+ $this->privCloseFd();
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+
+ // ----- Read the central directory informations
+ $v_central_dir_to_add = array();
+ if (($v_result = $p_archive_to_add->privReadEndCentralDir($v_central_dir_to_add)) != 1)
+ {
+ $this->privCloseFd();
+ $p_archive_to_add->privCloseFd();
+
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+
+ // ----- Go to beginning of File
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position in archive_to_add : ".ftell($p_archive_to_add->zip_fd)."'");
+ @rewind($p_archive_to_add->zip_fd);
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position in archive_to_add : ".ftell($p_archive_to_add->zip_fd)."'");
+
+ // ----- Creates a temporay file
+ $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp';
+
+ // ----- Open the temporary file in write mode
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode");
+ if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0)
+ {
+ $this->privCloseFd();
+ $p_archive_to_add->privCloseFd();
+
+ PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_zip_temp_name.'\' in binary write mode');
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
+ return PclZip::errorCode();
+ }
+
+ // ----- Copy the files from the archive to the temporary file
+ // TBC : Here I should better append the file and go back to erase the central dir
+ $v_size = $v_central_dir['offset'];
+ while ($v_size != 0)
+ {
+ $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Read $v_read_size bytes");
+ $v_buffer = fread($this->zip_fd, $v_read_size);
+ @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
+ $v_size -= $v_read_size;
+ }
+
+ // ----- Copy the files from the archive_to_add into the temporary file
+ $v_size = $v_central_dir_to_add['offset'];
+ while ($v_size != 0)
+ {
+ $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Read $v_read_size bytes");
+ $v_buffer = fread($p_archive_to_add->zip_fd, $v_read_size);
+ @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
+ $v_size -= $v_read_size;
+ }
+
+ // ----- Store the offset of the central dir
+ $v_offset = @ftell($v_zip_temp_fd);
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "New offset of central dir : $v_offset");
+
+ // ----- Copy the block of file headers from the old archive
+ $v_size = $v_central_dir['size'];
+ while ($v_size != 0)
+ {
+ $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Read $v_read_size bytes");
+ $v_buffer = @fread($this->zip_fd, $v_read_size);
+ @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
+ $v_size -= $v_read_size;
+ }
+
+ // ----- Copy the block of file headers from the archive_to_add
+ $v_size = $v_central_dir_to_add['size'];
+ while ($v_size != 0)
+ {
+ $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Read $v_read_size bytes");
+ $v_buffer = @fread($p_archive_to_add->zip_fd, $v_read_size);
+ @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
+ $v_size -= $v_read_size;
+ }
+
+ // ----- Merge the file comments
+ $v_comment = $v_central_dir['comment'].' '.$v_central_dir_to_add['comment'];
+
+ // ----- Calculate the size of the (new) central header
+ $v_size = @ftell($v_zip_temp_fd)-$v_offset;
+
+ // ----- Swap the file descriptor
+ // Here is a trick : I swap the temporary fd with the zip fd, in order to use
+ // the following methods on the temporary fil and not the real archive fd
+ $v_swap = $this->zip_fd;
+ $this->zip_fd = $v_zip_temp_fd;
+ $v_zip_temp_fd = $v_swap;
+
+ // ----- Create the central dir footer
+ if (($v_result = $this->privWriteCentralHeader($v_central_dir['entries']+$v_central_dir_to_add['entries'], $v_size, $v_offset, $v_comment)) != 1)
+ {
+ $this->privCloseFd();
+ $p_archive_to_add->privCloseFd();
+ @fclose($v_zip_temp_fd);
+ $this->zip_fd = null;
+
+ // ----- Reset the file list
+ unset($v_header_list);
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+
+ // ----- Swap back the file descriptor
+ $v_swap = $this->zip_fd;
+ $this->zip_fd = $v_zip_temp_fd;
+ $v_zip_temp_fd = $v_swap;
+
+ // ----- Close
+ $this->privCloseFd();
+ $p_archive_to_add->privCloseFd();
+
+ // ----- Close the temporary file
+ @fclose($v_zip_temp_fd);
+
+ // ----- Delete the zip file
+ // TBC : I should test the result ...
+ @unlink($this->zipname);
+
+ // ----- Rename the temporary file
+ // TBC : I should test the result ...
+ //@rename($v_zip_temp_name, $this->zipname);
+ PclZipUtilRename($v_zip_temp_name, $this->zipname);
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : privDuplicate()
+ // Description :
+ // Parameters :
+ // Return Values :
+ // --------------------------------------------------------------------------------
+ function privDuplicate($p_archive_filename)
+ {
+ //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privDuplicate", "archive_filename='$p_archive_filename'");
+ $v_result=1;
+
+ // ----- Look if the $p_archive_filename exists
+ if (!is_file($p_archive_filename))
+ {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Archive to duplicate does not exist. End of duplicate.");
+
+ // ----- Nothing to duplicate, so duplicate is a success.
+ $v_result = 1;
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+
+ // ----- Open the zip file
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode");
+ if (($v_result=$this->privOpenFd('wb')) != 1)
+ {
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+
+ // ----- Open the temporary file in write mode
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode");
+ if (($v_zip_temp_fd = @fopen($p_archive_filename, 'rb')) == 0)
+ {
+ $this->privCloseFd();
+
+ PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive file \''.$p_archive_filename.'\' in binary write mode');
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
+ return PclZip::errorCode();
+ }
+
+ // ----- Copy the files from the archive to the temporary file
+ // TBC : Here I should better append the file and go back to erase the central dir
+ $v_size = filesize($p_archive_filename);
+ while ($v_size != 0)
+ {
+ $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Read $v_read_size bytes");
+ $v_buffer = fread($v_zip_temp_fd, $v_read_size);
+ @fwrite($this->zip_fd, $v_buffer, $v_read_size);
+ $v_size -= $v_read_size;
+ }
+
+ // ----- Close
+ $this->privCloseFd();
+
+ // ----- Close the temporary file
+ @fclose($v_zip_temp_fd);
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : privErrorLog()
+ // Description :
+ // Parameters :
+ // --------------------------------------------------------------------------------
+ function privErrorLog($p_error_code=0, $p_error_string='')
+ {
+ if (PCLZIP_ERROR_EXTERNAL == 1) {
+ PclError($p_error_code, $p_error_string);
+ }
+ else {
+ $this->error_code = $p_error_code;
+ $this->error_string = $p_error_string;
+ }
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : privErrorReset()
+ // Description :
+ // Parameters :
+ // --------------------------------------------------------------------------------
+ function privErrorReset()
+ {
+ if (PCLZIP_ERROR_EXTERNAL == 1) {
+ PclErrorReset();
+ }
+ else {
+ $this->error_code = 0;
+ $this->error_string = '';
+ }
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : privDecrypt()
+ // Description :
+ // Parameters :
+ // Return Values :
+ // --------------------------------------------------------------------------------
+ function privDecrypt($p_encryption_header, &$p_buffer, $p_size, $p_crc)
+ {
+ //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, 'PclZip::privDecrypt', "size=".$p_size."");
+ $v_result=1;
+
+ // ----- To Be Modified ;-)
+ $v_pwd = "test";
+
+ $p_buffer = PclZipUtilZipDecrypt($p_buffer, $p_size, $p_encryption_header,
+ $p_crc, $v_pwd);
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : privDisableMagicQuotes()
+ // Description :
+ // Parameters :
+ // Return Values :
+ // --------------------------------------------------------------------------------
+ function privDisableMagicQuotes()
+ {
+ //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, 'PclZip::privDisableMagicQuotes', "");
+ $v_result=1;
+
+ // ----- Look if function exists
+ if ( (!function_exists("get_magic_quotes_runtime"))
+ || (!function_exists("set_magic_quotes_runtime"))) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Functions *et_magic_quotes_runtime are not supported");
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+
+ // ----- Look if already done
+ if ($this->magic_quotes_status != -1) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "magic_quote already disabled");
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+
+ // ----- Get and memorize the magic_quote value
+ $this->magic_quotes_status = @get_magic_quotes_runtime();
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Current magic_quotes_runtime status is '".($this->magic_quotes_status==0?'disable':'enable')."'");
+
+ // ----- Disable magic_quotes
+ if ($this->magic_quotes_status == 1) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Disable magic_quotes");
+ @set_magic_quotes_runtime(0);
+ }
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : privSwapBackMagicQuotes()
+ // Description :
+ // Parameters :
+ // Return Values :
+ // --------------------------------------------------------------------------------
+ function privSwapBackMagicQuotes()
+ {
+ //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, 'PclZip::privSwapBackMagicQuotes', "");
+ $v_result=1;
+
+ // ----- Look if function exists
+ if ( (!function_exists("get_magic_quotes_runtime"))
+ || (!function_exists("set_magic_quotes_runtime"))) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Functions *et_magic_quotes_runtime are not supported");
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+
+ // ----- Look if something to do
+ if ($this->magic_quotes_status != -1) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "magic_quote not modified");
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+
+ // ----- Swap back magic_quotes
+ if ($this->magic_quotes_status == 1) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Enable back magic_quotes");
+ @set_magic_quotes_runtime($this->magic_quotes_status);
+ }
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+ // --------------------------------------------------------------------------------
+
+ }
+ // End of class
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : PclZipUtilPathReduction()
+ // Description :
+ // Parameters :
+ // Return Values :
+ // --------------------------------------------------------------------------------
+ function PclZipUtilPathReduction($p_dir)
+ {
+ //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZipUtilPathReduction", "dir='$p_dir'");
+ $v_result = "";
+
+ // ----- Look for not empty path
+ if ($p_dir != "") {
+ // ----- Explode path by directory names
+ $v_list = explode("/", $p_dir);
+
+ // ----- Study directories from last to first
+ $v_skip = 0;
+ for ($i=sizeof($v_list)-1; $i>=0; $i--) {
+ // ----- Look for current path
+ if ($v_list[$i] == ".") {
+ // ----- Ignore this directory
+ // Should be the first $i=0, but no check is done
+ }
+ else if ($v_list[$i] == "..") {
+ $v_skip++;
+ }
+ else if ($v_list[$i] == "") {
+ // ----- First '/' i.e. root slash
+ if ($i == 0) {
+ $v_result = "/".$v_result;
+ if ($v_skip > 0) {
+ // ----- It is an invalid path, so the path is not modified
+ // TBC
+ $v_result = $p_dir;
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Invalid path is unchanged");
+ $v_skip = 0;
+ }
+ }
+ // ----- Last '/' i.e. indicates a directory
+ else if ($i == (sizeof($v_list)-1)) {
+ $v_result = $v_list[$i];
+ }
+ // ----- Double '/' inside the path
+ else {
+ // ----- Ignore only the double '//' in path,
+ // but not the first and last '/'
+ }
+ }
+ else {
+ // ----- Look for item to skip
+ if ($v_skip > 0) {
+ $v_skip--;
+ }
+ else {
+ $v_result = $v_list[$i].($i!=(sizeof($v_list)-1)?"/".$v_result:"");
+ }
+ }
+ }
+
+ // ----- Look for skip
+ if ($v_skip > 0) {
+ while ($v_skip > 0) {
+ $v_result = '../'.$v_result;
+ $v_skip--;
+ }
+ }
+ }
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : PclZipUtilPathInclusion()
+ // Description :
+ // This function indicates if the path $p_path is under the $p_dir tree. Or,
+ // said in an other way, if the file or sub-dir $p_path is inside the dir
+ // $p_dir.
+ // The function indicates also if the path is exactly the same as the dir.
+ // This function supports path with duplicated '/' like '//', but does not
+ // support '.' or '..' statements.
+ // Parameters :
+ // Return Values :
+ // 0 if $p_path is not inside directory $p_dir
+ // 1 if $p_path is inside directory $p_dir
+ // 2 if $p_path is exactly the same as $p_dir
+ // --------------------------------------------------------------------------------
+ function PclZipUtilPathInclusion($p_dir, $p_path)
+ {
+ //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZipUtilPathInclusion", "dir='$p_dir', path='$p_path'");
+ $v_result = 1;
+
+ // ----- Look for path beginning by ./
+ if ( ($p_dir == '.')
+ || ((strlen($p_dir) >=2) && (substr($p_dir, 0, 2) == './'))) {
+ $p_dir = PclZipUtilTranslateWinPath(getcwd(), FALSE).'/'.substr($p_dir, 1);
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Replacing ./ by full path in p_dir '".$p_dir."'");
+ }
+ if ( ($p_path == '.')
+ || ((strlen($p_path) >=2) && (substr($p_path, 0, 2) == './'))) {
+ $p_path = PclZipUtilTranslateWinPath(getcwd(), FALSE).'/'.substr($p_path, 1);
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Replacing ./ by full path in p_path '".$p_path."'");
+ }
+
+ // ----- Explode dir and path by directory separator
+ $v_list_dir = explode("/", $p_dir);
+ $v_list_dir_size = sizeof($v_list_dir);
+ $v_list_path = explode("/", $p_path);
+ $v_list_path_size = sizeof($v_list_path);
+
+ // ----- Study directories paths
+ $i = 0;
+ $j = 0;
+ while (($i < $v_list_dir_size) && ($j < $v_list_path_size) && ($v_result)) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Working on dir($i)='".$v_list_dir[$i]."' and path($j)='".$v_list_path[$j]."'");
+
+ // ----- Look for empty dir (path reduction)
+ if ($v_list_dir[$i] == '') {
+ $i++;
+ continue;
+ }
+ if ($v_list_path[$j] == '') {
+ $j++;
+ continue;
+ }
+
+ // ----- Compare the items
+ if (($v_list_dir[$i] != $v_list_path[$j]) && ($v_list_dir[$i] != '') && ( $v_list_path[$j] != '')) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Items ($i,$j) are different");
+ $v_result = 0;
+ }
+
+ // ----- Next items
+ $i++;
+ $j++;
+ }
+
+ // ----- Look if everything seems to be the same
+ if ($v_result) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Look for tie break");
+ // ----- Skip all the empty items
+ while (($j < $v_list_path_size) && ($v_list_path[$j] == '')) $j++;
+ while (($i < $v_list_dir_size) && ($v_list_dir[$i] == '')) $i++;
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Looking on dir($i)='".($i < $v_list_dir_size?$v_list_dir[$i]:'')."' and path($j)='".($j < $v_list_path_size?$v_list_path[$j]:'')."'");
+
+ if (($i >= $v_list_dir_size) && ($j >= $v_list_path_size)) {
+ // ----- There are exactly the same
+ $v_result = 2;
+ }
+ else if ($i < $v_list_dir_size) {
+ // ----- The path is shorter than the dir
+ $v_result = 0;
+ }
+ }
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : PclZipUtilCopyBlock()
+ // Description :
+ // Parameters :
+ // $p_mode : read/write compression mode
+ // 0 : src & dest normal
+ // 1 : src gzip, dest normal
+ // 2 : src normal, dest gzip
+ // 3 : src & dest gzip
+ // Return Values :
+ // --------------------------------------------------------------------------------
+ function PclZipUtilCopyBlock($p_src, $p_dest, $p_size, $p_mode=0)
+ {
+ //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZipUtilCopyBlock", "size=$p_size, mode=$p_mode");
+ $v_result = 1;
+
+ if ($p_mode==0)
+ {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Src offset before read :".(@ftell($p_src)));
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Dest offset before write :".(@ftell($p_dest)));
+ while ($p_size != 0)
+ {
+ $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Read $v_read_size bytes");
+ $v_buffer = @fread($p_src, $v_read_size);
+ @fwrite($p_dest, $v_buffer, $v_read_size);
+ $p_size -= $v_read_size;
+ }
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Src offset after read :".(@ftell($p_src)));
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Dest offset after write :".(@ftell($p_dest)));
+ }
+ else if ($p_mode==1)
+ {
+ while ($p_size != 0)
+ {
+ $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Read $v_read_size bytes");
+ $v_buffer = @gzread($p_src, $v_read_size);
+ @fwrite($p_dest, $v_buffer, $v_read_size);
+ $p_size -= $v_read_size;
+ }
+ }
+ else if ($p_mode==2)
+ {
+ while ($p_size != 0)
+ {
+ $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Read $v_read_size bytes");
+ $v_buffer = @fread($p_src, $v_read_size);
+ @gzwrite($p_dest, $v_buffer, $v_read_size);
+ $p_size -= $v_read_size;
+ }
+ }
+ else if ($p_mode==3)
+ {
+ while ($p_size != 0)
+ {
+ $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Read $v_read_size bytes");
+ $v_buffer = @gzread($p_src, $v_read_size);
+ @gzwrite($p_dest, $v_buffer, $v_read_size);
+ $p_size -= $v_read_size;
+ }
+ }
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : PclZipUtilRename()
+ // Description :
+ // This function tries to do a simple rename() function. If it fails, it
+ // tries to copy the $p_src file in a new $p_dest file and then unlink the
+ // first one.
+ // Parameters :
+ // $p_src : Old filename
+ // $p_dest : New filename
+ // Return Values :
+ // 1 on success, 0 on failure.
+ // --------------------------------------------------------------------------------
+ function PclZipUtilRename($p_src, $p_dest)
+ {
+ //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZipUtilRename", "source=$p_src, destination=$p_dest");
+ $v_result = 1;
+
+ // ----- Try to rename the files
+ if (!@rename($p_src, $p_dest)) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Fail to rename file, try copy+unlink");
+
+ // ----- Try to copy & unlink the src
+ if (!@copy($p_src, $p_dest)) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Fail to copy file");
+ $v_result = 0;
+ }
+ else if (!@unlink($p_src)) {
+ //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Fail to unlink old filename");
+ $v_result = 0;
+ }
+ }
+
+ // ----- Return
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : PclZipUtilOptionText()
+ // Description :
+ // Translate option value in text. Mainly for debug purpose.
+ // Parameters :
+ // $p_option : the option value.
+ // Return Values :
+ // The option text value.
+ // --------------------------------------------------------------------------------
+ function PclZipUtilOptionText($p_option)
+ {
+ //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZipUtilOptionText", "option='".$p_option."'");
+
+ $v_list = get_defined_constants();
+ for (reset($v_list); $v_key = key($v_list); next($v_list)) {
+ $v_prefix = substr($v_key, 0, 10);
+ if (( ($v_prefix == 'PCLZIP_OPT')
+ || ($v_prefix == 'PCLZIP_CB_')
+ || ($v_prefix == 'PCLZIP_ATT'))
+ && ($v_list[$v_key] == $p_option)) {
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_key);
+ return $v_key;
+ }
+ }
+
+ $v_result = 'Unknown';
+
+ //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+ return $v_result;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : PclZipUtilTranslateWinPath()
+ // Description :
+ // Translate windows path by replacing '\' by '/' and optionally removing
+ // drive letter.
+ // Parameters :
+ // $p_path : path to translate.
+ // $p_remove_disk_letter : true | false
+ // Return Values :
+ // The path translated.
+ // --------------------------------------------------------------------------------
+ function PclZipUtilTranslateWinPath($p_path, $p_remove_disk_letter=true)
+ {
+ if (stristr(php_uname(), 'windows')) {
+ // ----- Look for potential disk letter
+ if (($p_remove_disk_letter) && (($v_position = strpos($p_path, ':')) != false)) {
+ $p_path = substr($p_path, $v_position+1);
+ }
+ // ----- Change potential windows directory separator
+ if ((strpos($p_path, '\\') > 0) || (substr($p_path, 0,1) == '\\')) {
+ $p_path = strtr($p_path, '\\', '/');
+ }
+ }
+ return $p_path;
+ }
+ // --------------------------------------------------------------------------------
+
+
+?>
diff --git a/wp-admin/includes/class-wp-filesystem-direct.php b/wp-admin/includes/class-wp-filesystem-direct.php
new file mode 100644
index 0000000..d698b20
--- /dev/null
+++ b/wp-admin/includes/class-wp-filesystem-direct.php
@@ -0,0 +1,336 @@
+<?php
+
+class WP_Filesystem_Direct{
+ var $permission = null;
+ var $errors = array();
+ function WP_Filesystem_Direct($arg){
+ $this->errors = new WP_Error();
+ $this->permission = umask();
+ }
+ function connect(){
+ return;
+ }
+ function setDefaultPermissions($perm){
+ $this->permission = $perm;
+ }
+ function find_base_dir($base = '.', $echo = false){
+ return str_replace('\\','/',ABSPATH);
+ }
+ function get_base_dir($base = '.', $echo = false){
+ return find_base_dir($base, $echo);
+ }
+ function get_contents($file){
+ return @file_get_contents($file);
+ }
+ function get_contents_array($file){
+ return @file($file);
+ }
+ function put_contents($file,$contents,$mode=false,$type=''){
+ $fp=@fopen($file,'w'.$type);
+ if (!$fp)
+ return false;
+ @fwrite($fp,$contents);
+ @fclose($fp);
+ $this->chmod($file,$mode);
+ return true;
+ }
+ function cwd(){
+ return @getcwd();
+ }
+ function chgrp($file,$group,$recursive=false){
+ if( ! $this->exists($file) )
+ return false;
+ if( ! $recursive )
+ return @chgrp($file,$group);
+ if( ! $this->is_dir($file) )
+ return @chgrp($file,$group);
+ //Is a directory, and we want recursive
+ $filelist = $this->dirlist($file);
+ foreach($filelist as $filename){
+ $this->chgrp($file.'/'.$filename,$group,$recursive);
+ }
+ return true;
+ }
+ function chmod($file,$mode=false,$recursive=false){
+ if( ! $mode )
+ $mode = $this->permission;
+ if( ! $this->exists($file) )
+ return false;
+ if( ! $recursive )
+ return @chmod($file,$mode);
+ if( ! $this->is_dir($file) )
+ return @chmod($file,$mode);
+ //Is a directory, and we want recursive
+ $filelist = $this->dirlist($file);
+ foreach($filelist as $filename){
+ $this->chmod($file.'/'.$filename,$mode,$recursive);
+ }
+ return true;
+ }
+ function chown($file,$owner,$recursive=false){
+ if( ! $this->exists($file) )
+ return false;
+ if( ! $recursive )
+ return @chown($file,$owner);
+ if( ! $this->is_dir($file) )
+ return @chown($file,$owner);
+ //Is a directory, and we want recursive
+ $filelist = $this->dirlist($file);
+ foreach($filelist as $filename){
+ $this->chown($file.'/'.$filename,$owner,$recursive);
+ }
+ return true;
+ }
+ function owner($file){
+ $owneruid=@fileowner($file);
+ if( ! $owneruid )
+ return false;
+ if( !function_exists('posix_getpwuid') )
+ return $owneruid;
+ $ownerarray=posix_getpwuid($owneruid);
+ return $ownerarray['name'];
+ }
+ function getchmod($file){
+ return @fileperms($file);
+ }
+ function gethchmod($file){
+ //From the PHP.net page for ...?
+ $perms = $this->getchmod($file);
+ if (($perms & 0xC000) == 0xC000) {
+ // Socket
+ $info = 's';
+ } elseif (($perms & 0xA000) == 0xA000) {
+ // Symbolic Link
+ $info = 'l';
+ } elseif (($perms & 0x8000) == 0x8000) {
+ // Regular
+ $info = '-';
+ } elseif (($perms & 0x6000) == 0x6000) {
+ // Block special
+ $info = 'b';
+ } elseif (($perms & 0x4000) == 0x4000) {
+ // Directory
+ $info = 'd';
+ } elseif (($perms & 0x2000) == 0x2000) {
+ // Character special
+ $info = 'c';
+ } elseif (($perms & 0x1000) == 0x1000) {
+ // FIFO pipe
+ $info = 'p';
+ } else {
+ // Unknown
+ $info = 'u';
+ }
+
+ // Owner
+ $info .= (($perms & 0x0100) ? 'r' : '-');
+ $info .= (($perms & 0x0080) ? 'w' : '-');
+ $info .= (($perms & 0x0040) ?
+ (($perms & 0x0800) ? 's' : 'x' ) :
+ (($perms & 0x0800) ? 'S' : '-'));
+
+ // Group
+ $info .= (($perms & 0x0020) ? 'r' : '-');
+ $info .= (($perms & 0x0010) ? 'w' : '-');
+ $info .= (($perms & 0x0008) ?
+ (($perms & 0x0400) ? 's' : 'x' ) :
+ (($perms & 0x0400) ? 'S' : '-'));
+
+ // World
+ $info .= (($perms & 0x0004) ? 'r' : '-');
+ $info .= (($perms & 0x0002) ? 'w' : '-');
+ $info .= (($perms & 0x0001) ?
+ (($perms & 0x0200) ? 't' : 'x' ) :
+ (($perms & 0x0200) ? 'T' : '-'));
+ return $info;
+ }
+ function getnumchmodfromh($mode) {
+ $realmode = "";
+ $legal = array("","w","r","x","-");
+ $attarray = preg_split("//",$mode);
+ for($i=0;$i<count($attarray);$i++){
+ if($key = array_search($attarray[$i],$legal)){
+ $realmode .= $legal[$key];
+ }
+ }
+ $mode = str_pad($realmode,9,'-');
+ $trans = array('-'=>'0','r'=>'4','w'=>'2','x'=>'1');
+ $mode = strtr($mode,$trans);
+ $newmode = '';
+ $newmode .= $mode[0]+$mode[1]+$mode[2];
+ $newmode .= $mode[3]+$mode[4]+$mode[5];
+ $newmode .= $mode[6]+$mode[7]+$mode[8];
+ return $newmode;
+ }
+ function group($file){
+ $gid=@filegroup($file);
+ if( ! $gid )
+ return false;
+ if( !function_exists('posix_getgrgid') )
+ return $gid;
+ $grouparray=posix_getgrgid($gid);
+ return $grouparray['name'];
+ }
+
+ function copy($source,$destination,$overwrite=false){
+ if( $overwrite && $this->exists($destination) )
+ return false;
+ return copy($source,$destination);
+ }
+
+ function move($source,$destination,$overwrite=false){
+ //Possible to use rename()
+ if( $this->copy($source,$destination,$overwrite) && $this->exists($destination) ){
+ $this->delete($source);
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ function delete($file,$recursive=false){
+ $file = str_replace('\\','/',$file); //for win32, occasional problems deleteing files otherwise
+
+ if( $this->is_file($file) )
+ return @unlink($file);
+
+ if( !$recursive && $this->is_dir($file) )
+ return @rmdir($file);
+
+ $filelist = $this->dirlist($file);
+ if( ! $filelist )
+ return true; //No files exist, Say we've deleted them
+
+ $retval = true;
+ foreach($filelist as $filename=>$fileinfo){
+ if( ! $this->delete($file.'/'.$filename,$recursive) )
+ $retval = false;
+ }
+ if( ! @rmdir($file) )
+ return false;
+ return $retval;
+ }
+
+ function exists($file){
+ return @file_exists($file);
+ }
+
+ function is_file($file){
+ return @is_file($file);
+ }
+
+ function is_dir($path){
+ return @is_dir($path);
+ }
+
+ function is_readable($file){
+ return @is_readable($file);
+ }
+
+ function is_writable($file){
+ return @is_writable($file);
+ }
+
+ function atime($file){
+ return @fileatime($file);
+ }
+
+ function mtime($file){
+ return @filemtime($file);
+ }
+ function size($file){
+ return @filesize($file);
+ }
+
+ function touch($file,$time=0,$atime=0){
+ if($time==0)
+ $time = time();
+ if($atime==0)
+ $atime = time();
+ return @touch($file,$time,$atime);
+ }
+
+ function mkdir($path,$chmod=false,$chown=false,$chgrp=false){
+ if( ! $chmod)
+ $chmod = $this->permission;
+
+ if( !@mkdir($path,$chmod) )
+ return false;
+ if( $chown )
+ $this->chown($path,$chown);
+ if( $chgrp )
+ $this->chgrp($path,$chgrp);
+ return true;
+ }
+
+ function rmdir($path,$recursive=false){
+ if( ! $recursive )
+ return @rmdir($path);
+ //recursive:
+ $filelist = $this->dirlist($path);
+ foreach($filelist as $filename=>$det){
+ if ( '/' == substr($filename,-1,1) )
+ $this->rmdir($path.'/'.$filename,$recursive);
+ @rmdir($filename);
+ }
+ return @rmdir($path);
+ }
+
+ function dirlist($path,$incdot=false,$recursive=false){
+ if( $this->is_file($path) ){
+ $limitFile = basename($path);
+ $path = dirname($path);
+ } else {
+ $limitFile = false;
+ }
+ if( ! $this->is_dir($path) )
+ return false;
+
+ $ret = array();
+ $dir = dir($path);
+ while (false !== ($entry = $dir->read())) {
+ $struc = array();
+ $struc['name'] = $entry;
+
+ if( '.' == $struc['name'][0] && !$incdot)
+ continue;
+ if( $limitFile && $struc['name'] != $limitFile)
+ continue;
+
+ $struc['perms'] = $this->gethchmod($path.'/'.$entry);
+ $struc['permsn'] = $this->getnumchmodfromh($struc['perms']);
+ $struc['number'] = false;
+ $struc['owner'] = $this->owner($path.'/'.$entry);
+ $struc['group'] = $this->group($path.'/'.$entry);
+ $struc['size'] = $this->size($path.'/'.$entry);
+ $struc['lastmodunix']= $this->mtime($path.'/'.$entry);
+ $struc['lastmod'] = date('M j',$struc['lastmodunix']);
+ $struc['time'] = date('h:i:s',$struc['lastmodunix']);
+ $struc['type'] = $this->is_dir($path.'/'.$entry) ? 'd' : 'f';
+ if ('d' == $struc['type'] ){
+ $struc['files'] = array();
+
+ if( $incdot ){
+ //We're including the doted starts
+ if( '.' != $struc['name'] && '..' != $struc['name'] ){ //Ok, It isnt a special folder
+ if ($recursive)
+ $struc['files'] = $this->dirlist($path.'/'.$struc['name'],$incdot,$recursive);
+ }
+ } else { //No dots
+ if ($recursive)
+ $struc['files'] = $this->dirlist($path.'/'.$struc['name'],$incdot,$recursive);
+ }
+ }
+ //File
+ $ret[$struc['name']] = $struc;
+ }
+ $dir->close();
+ unset($dir);
+ return $ret;
+ }
+
+ function __destruct(){
+ return;
+ }
+}
+?>
diff --git a/wp-admin/includes/class-wp-filesystem-ftpext.php b/wp-admin/includes/class-wp-filesystem-ftpext.php
new file mode 100644
index 0000000..a8a3585
--- /dev/null
+++ b/wp-admin/includes/class-wp-filesystem-ftpext.php
@@ -0,0 +1,480 @@
+<?php
+class WP_Filesystem_FTPext{
+ var $link;
+ var $timeout = 5;
+ var $errors = array();
+ var $options = array();
+
+ var $wp_base = '';
+ var $permission = null;
+
+ var $filetypes = array(
+ 'php'=>FTP_ASCII,
+ 'css'=>FTP_ASCII,
+ 'txt'=>FTP_ASCII,
+ 'js'=>FTP_ASCII,
+ 'html'=>FTP_ASCII,
+ 'htm'=>FTP_ASCII,
+ 'xml'=>FTP_ASCII,
+
+ 'jpg'=>FTP_BINARY,
+ 'png'=>FTP_BINARY,
+ 'gif'=>FTP_BINARY,
+ 'bmp'=>FTP_BINARY
+ );
+
+ function WP_Filesystem_FTPext($opt='') {
+ $this->errors = new WP_Error();
+
+ //Check if possible to use ftp functions.
+ if ( ! extension_loaded('ftp') ) {
+ $this->errors->add('no_ftp_ext', __('The ftp PHP extension is not available'));
+ return false;
+ }
+
+ // Set defaults:
+ if ( empty($opt['port']) )
+ $this->options['port'] = 21;
+ else
+ $this->options['port'] = $opt['port'];
+
+ if ( empty($opt['hostname']) )
+ $this->errors->add('empty_hostname', __('FTP hostname is required'));
+ else
+ $this->options['hostname'] = $opt['hostname'];
+
+ if ( isset($opt['base']) && ! empty($opt['base']) )
+ $this->wp_base = $opt['base'];
+
+ // Check if the options provided are OK.
+ if ( empty ($opt['username']) )
+ $this->errors->add('empty_username', __('FTP username is required'));
+ else
+ $this->options['username'] = $opt['username'];
+
+ if ( empty ($opt['password']) )
+ $this->errors->add('empty_password', __('FTP password is required'));
+ else
+ $this->options['password'] = $opt['password'];
+
+ $this->options['ssl'] = ( !empty($opt['ssl']) );
+ }
+
+ function connect(){
+ if ( $this->options['ssl'] && function_exists('ftp_ssl_connect') ) {
+ $this->link = @ftp_ssl_connect($this->options['hostname'], $this->options['port'],$this->timeout);
+ } else {
+ $this->link = @ftp_connect($this->options['hostname'], $this->options['port'],$this->timeout);
+ }
+
+ if ( ! $this->link ) {
+ $this->errors->add('connect', sprintf(__('Failed to connect to FTP Server %1$s:%2$s'), $this->options['hostname'], $this->options['port']));
+ return false;
+ }
+
+ if ( ! @ftp_login($this->link,$this->options['username'], $this->options['password']) ) {
+ $this->errors->add('auth', sprintf(__('Username/Password incorrect for %s'), $this->options['username']));
+ return false;
+ }
+
+ return true;
+ }
+
+ function setDefaultPermissions($perm){
+ $this->permission = $perm;
+ }
+
+ function find_base_dir($base = '.',$echo = false){
+ $abspath = str_replace('\\','/',ABSPATH); //windows: Straighten up the paths..
+ if( strpos($abspath, ':') ){ //Windows, Strip out the driveletter
+ if( preg_match("|.{1}\:(.+)|i", $abspath, $mat) )
+ $abspath = $mat[1];
+ }
+
+ if( empty( $base ) || '.' == $base ) $base = $this->cwd();
+ if( empty( $base ) ) $base = '/';
+ if( '/' != substr($base, -1) ) $base .= '/';
+
+ if($echo) echo __('Changing to ') . $base .'<br>';
+ if( false === $this->chdir($base) )
+ return false;
+
+ if( $this->exists($base . 'wp-settings.php') ){
+ if($echo) echo __('Found ') . $base . 'wp-settings.php<br>';
+ $this->wp_base = $base;
+ return $this->wp_base;
+ }
+
+ if( strpos($abspath, $base) > 0)
+ $arrPath = split('/',substr($abspath,strpos($abspath, $base)));
+ else
+ $arrPath = split('/',$abspath);
+
+ for($i = 0; $i <= count($arrPath); $i++)
+ if( $arrPath[ $i ] == '' ) unset( $arrPath[ $i ] );
+
+ foreach($arrPath as $key=>$folder){
+ if( $this->is_dir($base . $folder) ){
+ if($echo) echo __('Found ') . $folder . ' ' . __('Changing to') . ' ' . $base . $folder . '/<br>';
+ return $this->find_base_dir($base . $folder . '/',$echo);
+ }
+ }
+
+ if( $base == '/' )
+ return false;
+ //If we get this far, somethings gone wrong, change to / and restart the process.
+ return $this->find_base_dir('/',$echo);
+ }
+ function get_base_dir($base = '.', $echo=false){
+ if( empty($this->wp_base) )
+ $this->wp_base = $this->find_base_dir($base,$echo);
+ return $this->wp_base;
+ }
+ function get_contents($file,$type='',$resumepos=0){
+ if( empty($type) ){
+ $extension = substr(strrchr($file, "."), 1);
+ $type = isset($this->filetypes[ $extension ]) ? $this->filetypes[ $extension ] : FTP_ASCII;
+ }
+ $temp = tmpfile();
+ if( ! @ftp_fget($this->link,$temp,$file,$type,$resumepos) )
+ return false;
+ fseek($temp, 0); //Skip back to the start of the file being written to
+ $contents = '';
+ while (!feof($temp)) {
+ $contents .= fread($temp, 8192);
+ }
+ fclose($temp);
+ return $contents;
+ }
+ function get_contents_array($file){
+ return explode("\n",$this->get_contents($file));
+ }
+ function put_contents($file,$contents,$type=''){
+ if( empty($type) ){
+ $extension = substr(strrchr($filename, "."), 1);
+ $type = isset($this->filetypes[ $extension ]) ? $this->filetypes[ $extension ] : FTP_ASCII;
+ }
+ $temp = tmpfile();
+ fwrite($temp,$contents);
+ fseek($temp, 0); //Skip back to the start of the file being written to
+ $ret = @ftp_fput($this->link,$file,$temp,$type);
+ fclose($temp);
+ return $ret;
+ }
+ function cwd(){
+ return ftp_pwd($this->link);
+ }
+ function chdir($dir){
+ return @ftp_chdir($dir);
+ }
+ function chgrp($file,$group,$recursive=false){
+ return false;
+ }
+ function chmod($file,$mode=false,$recursive=false){
+ if( ! $mode )
+ $mode = $this->permission;
+ if( ! $mode )
+ return false;
+ if ( ! $this->exists($file) )
+ return false;
+ if ( ! $recursive || ! $this->is_dir($file) ){
+ if (!function_exists('ftp_chmod'))
+ return @ftp_site($this->link, sprintf('CHMOD %o %s', $mode, $file));
+ return @ftp_chmod($this->link,$mode,$file);
+ }
+ //Is a directory, and we want recursive
+ $filelist = $this->dirlist($file);
+ foreach($filelist as $filename){
+ $this->chmod($file.'/'.$filename,$mode,$recursive);
+ }
+ return true;
+ }
+ function chown($file,$owner,$recursive=false){
+ return false;
+ }
+ function owner($file){
+ $dir = $this->dirlist($file);
+ return $dir[$file]['owner'];
+ }
+ function getchmod($file){
+ $dir = $this->dirlist($file);
+ return $dir[$file]['permsn'];
+ }
+ function gethchmod($file){
+ //From the PHP.net page for ...?
+ $perms = $this->getchmod($file);
+ if (($perms & 0xC000) == 0xC000) {
+ // Socket
+ $info = 's';
+ } elseif (($perms & 0xA000) == 0xA000) {
+ // Symbolic Link
+ $info = 'l';
+ } elseif (($perms & 0x8000) == 0x8000) {
+ // Regular
+ $info = '-';
+ } elseif (($perms & 0x6000) == 0x6000) {
+ // Block special
+ $info = 'b';
+ } elseif (($perms & 0x4000) == 0x4000) {
+ // Directory
+ $info = 'd';
+ } elseif (($perms & 0x2000) == 0x2000) {
+ // Character special
+ $info = 'c';
+ } elseif (($perms & 0x1000) == 0x1000) {
+ // FIFO pipe
+ $info = 'p';
+ } else {
+ // Unknown
+ $info = 'u';
+ }
+
+ // Owner
+ $info .= (($perms & 0x0100) ? 'r' : '-');
+ $info .= (($perms & 0x0080) ? 'w' : '-');
+ $info .= (($perms & 0x0040) ?
+ (($perms & 0x0800) ? 's' : 'x' ) :
+ (($perms & 0x0800) ? 'S' : '-'));
+
+ // Group
+ $info .= (($perms & 0x0020) ? 'r' : '-');
+ $info .= (($perms & 0x0010) ? 'w' : '-');
+ $info .= (($perms & 0x0008) ?
+ (($perms & 0x0400) ? 's' : 'x' ) :
+ (($perms & 0x0400) ? 'S' : '-'));
+
+ // World
+ $info .= (($perms & 0x0004) ? 'r' : '-');
+ $info .= (($perms & 0x0002) ? 'w' : '-');
+ $info .= (($perms & 0x0001) ?
+ (($perms & 0x0200) ? 't' : 'x' ) :
+ (($perms & 0x0200) ? 'T' : '-'));
+ return $info;
+ }
+ function getnumchmodfromh($mode) {
+ $realmode = "";
+ $legal = array("","w","r","x","-");
+ $attarray = preg_split("//",$mode);
+ for($i=0;$i<count($attarray);$i++){
+ if($key = array_search($attarray[$i],$legal)){
+ $realmode .= $legal[$key];
+ }
+ }
+ $mode = str_pad($realmode,9,'-');
+ $trans = array('-'=>'0','r'=>'4','w'=>'2','x'=>'1');
+ $mode = strtr($mode,$trans);
+ $newmode = '';
+ $newmode .= $mode[0]+$mode[1]+$mode[2];
+ $newmode .= $mode[3]+$mode[4]+$mode[5];
+ $newmode .= $mode[6]+$mode[7]+$mode[8];
+ return $newmode;
+ }
+ function group($file){
+ $dir = $this->dirlist($file);
+ return $dir[$file]['group'];
+ }
+ function copy($source,$destination,$overwrite=false){
+ if( ! $overwrite && $this->exists($destination) )
+ return false;
+ $content = $this->get_contents($source);
+ if( false === $content)
+ return false;
+ return $this->put_contents($destination,$content);
+ }
+ function move($source,$destination,$overwrite=false){
+ return ftp_rename($this->link,$source,$destination);
+ }
+
+ function delete($file,$recursive=false) {
+ if ( $this->is_file($file) )
+ return @ftp_delete($this->link,$file);
+ if ( !$recursive )
+ return @ftp_rmdir($this->link,$file);
+ $filelist = $this->dirlist($file);
+ foreach ((array) $filelist as $filename => $fileinfo) {
+ $this->delete($file.'/'.$filename,$recursive);
+ }
+ return @ftp_rmdir($this->link,$file);
+ }
+
+ function exists($file){
+ $list = ftp_rawlist($this->link,$file,false);
+ if( ! $list )
+ return false;
+ return count($list) == 1 ? true : false;
+ }
+ function is_file($file){
+ return $this->is_dir($file) ? false : true;
+ }
+ function is_dir($path){
+ $cwd = $this->cwd();
+ @ftp_chdir($this->link, $path);
+ if ( $this->cwd() != $cwd ) {
+ @ftp_chdir($this->link, $cwd);
+ return true;
+ }
+ return false;
+ }
+ function is_readable($file){
+ //Get dir list, Check if the file is writable by the current user??
+ return true;
+ }
+ function is_writable($file){
+ //Get dir list, Check if the file is writable by the current user??
+ return true;
+ }
+ function atime($file){
+ return false;
+ }
+ function mtime($file){
+ return ftp_mdtm($this->link, $file);
+ }
+ function size($file){
+ return ftp_size($this->link, $file);
+ }
+ function touch($file,$time=0,$atime=0){
+ return false;
+ }
+ function mkdir($path,$chmod=false,$chown=false,$chgrp=false){
+ if( !@ftp_mkdir($this->link, $path) )
+ return false;
+ if( $chmod )
+ $this->chmod($path, $chmod);
+ if( $chown )
+ $this->chown($path, $chown);
+ if( $chgrp )
+ $this->chgrp($path, $chgrp);
+ return true;
+ }
+ function rmdir($path,$recursive=false){
+ if( ! $recursive )
+ return @ftp_rmdir($this->link, $path);
+
+ //TODO: Recursive Directory delete, Have to delete files from the folder first.
+ //$dir = $this->dirlist($path);
+ //foreach($dir as $file)
+
+ }
+
+ function parselisting($line) {
+ $is_windows = ($this->OS_remote == FTP_OS_Windows);
+ if ($is_windows && preg_match("/([0-9]{2})-([0-9]{2})-([0-9]{2}) +([0-9]{2}):([0-9]{2})(AM|PM) +([0-9]+|<DIR>) +(.+)/",$line,$lucifer)) {
+ $b = array();
+ if ($lucifer[3]<70) { $lucifer[3]+=2000; } else { $lucifer[3]+=1900; } // 4digit year fix
+ $b['isdir'] = ($lucifer[7]=="<DIR>");
+ if ( $b['isdir'] )
+ $b['type'] = 'd';
+ else
+ $b['type'] = 'f';
+ $b['size'] = $lucifer[7];
+ $b['month'] = $lucifer[1];
+ $b['day'] = $lucifer[2];
+ $b['year'] = $lucifer[3];
+ $b['hour'] = $lucifer[4];
+ $b['minute'] = $lucifer[5];
+ $b['time'] = @mktime($lucifer[4]+(strcasecmp($lucifer[6],"PM")==0?12:0),$lucifer[5],0,$lucifer[1],$lucifer[2],$lucifer[3]);
+ $b['am/pm'] = $lucifer[6];
+ $b['name'] = $lucifer[8];
+ } else if (!$is_windows && $lucifer=preg_split("/[ ]/",$line,9,PREG_SPLIT_NO_EMPTY)) {
+ //echo $line."\n";
+ $lcount=count($lucifer);
+ if ($lcount<8) return '';
+ $b = array();
+ $b['isdir'] = $lucifer[0]{0} === "d";
+ $b['islink'] = $lucifer[0]{0} === "l";
+ if ( $b['isdir'] )
+ $b['type'] = 'd';
+ elseif ( $b['islink'] )
+ $b['type'] = 'l';
+ else
+ $b['type'] = 'f';
+ $b['perms'] = $lucifer[0];
+ $b['number'] = $lucifer[1];
+ $b['owner'] = $lucifer[2];
+ $b['group'] = $lucifer[3];
+ $b['size'] = $lucifer[4];
+ if ($lcount==8) {
+ sscanf($lucifer[5],"%d-%d-%d",$b['year'],$b['month'],$b['day']);
+ sscanf($lucifer[6],"%d:%d",$b['hour'],$b['minute']);
+ $b['time'] = @mktime($b['hour'],$b['minute'],0,$b['month'],$b['day'],$b['year']);
+ $b['name'] = $lucifer[7];
+ } else {
+ $b['month'] = $lucifer[5];
+ $b['day'] = $lucifer[6];
+ if (preg_match("/([0-9]{2}):([0-9]{2})/",$lucifer[7],$l2)) {
+ $b['year'] = date("Y");
+ $b['hour'] = $l2[1];
+ $b['minute'] = $l2[2];
+ } else {
+ $b['year'] = $lucifer[7];
+ $b['hour'] = 0;
+ $b['minute'] = 0;
+ }
+ $b['time'] = strtotime(sprintf("%d %s %d %02d:%02d",$b['day'],$b['month'],$b['year'],$b['hour'],$b['minute']));
+ $b['name'] = $lucifer[8];
+ }
+ }
+
+ return $b;
+ }
+
+ function dirlist($path='.',$incdot=false,$recursive=false){
+ if( $this->is_file($path) ){
+ $limitFile = basename($path);
+ $path = dirname($path) . '/';
+ } else {
+ $limitFile = false;
+ }
+ //if( ! $this->is_dir($path) )
+ // return false;
+ $list = ftp_rawlist($this->link , '-a ' . $path, false);
+ if ( $list === false )
+ return false;
+
+ $dirlist = array();
+ foreach ( $list as $k => $v ) {
+ $entry = $this->parselisting($v);
+ if ( empty($entry) )
+ continue;
+
+ if ( $entry["name"]=="." or $entry["name"]==".." )
+ continue;
+
+ $dirlist[$entry['name']] = $entry;
+ }
+
+ if ( ! $dirlist )
+ return false;
+ if ( empty($dirlist) )
+ return array();
+
+ $ret = array();
+ foreach ( $dirlist as $struc ) {
+
+ if ( 'd' == $struc['type'] ) {
+ $struc['files'] = array();
+
+ if ( $incdot ){
+ //We're including the doted starts
+ if( '.' != $struc['name'] && '..' != $struc['name'] ){ //Ok, It isnt a special folder
+ if ($recursive)
+ $struc['files'] = $this->dirlist($path.'/'.$struc['name'],$incdot,$recursive);
+ }
+ } else { //No dots
+ if ($recursive)
+ $struc['files'] = $this->dirlist($path.'/'.$struc['name'],$incdot,$recursive);
+ }
+ }
+ //File
+ $ret[$struc['name']] = $struc;
+ }
+ return $ret;
+ }
+
+ function __destruct(){
+ if( $this->link )
+ ftp_close($this->link);
+ }
+}
+
+?>
diff --git a/wp-admin/includes/class-wp-filesystem-ftpsockets.php b/wp-admin/includes/class-wp-filesystem-ftpsockets.php
new file mode 100644
index 0000000..15ab390
--- /dev/null
+++ b/wp-admin/includes/class-wp-filesystem-ftpsockets.php
@@ -0,0 +1,426 @@
+<?php
+class WP_Filesystem_ftpsockets{
+ var $ftp = false;
+ var $timeout = 5;
+ var $errors;
+ var $options = array();
+
+ var $wp_base = '';
+ var $permission = null;
+
+ var $filetypes = array(
+ 'php'=>FTP_ASCII,
+ 'css'=>FTP_ASCII,
+ 'txt'=>FTP_ASCII,
+ 'js'=>FTP_ASCII,
+ 'html'=>FTP_ASCII,
+ 'htm'=>FTP_ASCII,
+ 'xml'=>FTP_ASCII,
+
+ 'jpg'=>FTP_BINARY,
+ 'png'=>FTP_BINARY,
+ 'gif'=>FTP_BINARY,
+ 'bmp'=>FTP_BINARY
+ );
+
+ function WP_Filesystem_ftpsockets($opt='') {
+ $this->errors = new WP_Error();
+
+ //Check if possible to use ftp functions.
+ if( ! @include_once ABSPATH . 'wp-admin/includes/class-ftp.php' )
+ return false;
+ $this->ftp = new ftp();
+
+ //Set defaults:
+ if ( empty($opt['port']) )
+ $this->options['port'] = 21;
+ else
+ $this->options['port'] = $opt['port'];
+
+ if ( empty($opt['hostname']) )
+ $this->errors->add('empty_hostname', __('FTP hostname is required'));
+ else
+ $this->options['hostname'] = $opt['hostname'];
+
+ if ( isset($opt['base']) && ! empty($opt['base']) )
+ $this->wp_base = $opt['base'];
+
+ // Check if the options provided are OK.
+ if ( empty ($opt['username']) )
+ $this->errors->add('empty_username', __('FTP username is required'));
+ else
+ $this->options['username'] = $opt['username'];
+
+ if ( empty ($opt['password']) )
+ $this->errors->add('empty_password', __('FTP password is required'));
+ else
+ $this->options['password'] = $opt['password'];
+ }
+
+ function connect() {
+ if ( ! $this->ftp )
+ return false;
+
+ //$this->ftp->Verbose = true;
+
+ if ( ! $this->ftp->SetServer($this->options['hostname'], $this->options['port']) ) {
+ $this->errors->add('connect', sprintf(__('Failed to connect to FTP Server %1$s:%2$s'), $this->options['hostname'], $this->options['port']));
+ return false;
+ }
+ if ( ! $this->ftp->connect() ) {
+ $this->errors->add('connect', sprintf(__('Failed to connect to FTP Server %1$s:%2$s'), $this->options['hostname'], $this->options['port']));
+ return false;
+ }
+
+ if ( ! $this->ftp->login($this->options['username'], $this->options['password']) ) {
+ $this->errors->add('auth', sprintf(__('Username/Password incorrect for %s'), $this->options['username']));
+ return false;
+ }
+
+ $this->ftp->SetType(FTP_AUTOASCII);
+ $this->ftp->Passive(true);
+ return true;
+ }
+
+ function setDefaultPermissions($perm) {
+ $this->permission = $perm;
+ }
+
+ function find_base_dir($base = '.',$echo = false) {
+ $abspath = str_replace('\\','/',ABSPATH); //windows: Straighten up the paths..
+ if( strpos($abspath, ':') ){ //Windows, Strip out the driveletter
+ if( preg_match("|.{1}\:(.+)|i", $abspath, $mat) )
+ $abspath = $mat[1];
+ }
+
+ if( empty( $base ) || '.' == $base ) $base = $this->cwd();
+ if( empty( $base ) ) $base = '/';
+ if( '/' != substr($base, -1) ) $base .= '/';
+
+ if($echo) echo __('Changing to ') . $base .'<br>';
+ if( false === $this->chdir($base) )
+ return false;
+
+ if( $this->exists($base . 'wp-settings.php') ){
+ if($echo) echo __('Found ') . $base . 'wp-settings.php<br>';
+ $this->wp_base = $base;
+ return $this->wp_base;
+ }
+
+ if( strpos($abspath, $base) > 0)
+ $arrPath = split('/',substr($abspath,strpos($abspath, $base)));
+ else
+ $arrPath = split('/',$abspath);
+
+ for($i = 0; $i <= count($arrPath); $i++)
+ if( $arrPath[ $i ] == '' ) unset( $arrPath[ $i ] );
+
+ foreach($arrPath as $key=>$folder){
+ if( $this->is_dir($base . $folder) ){
+ if($echo) echo __('Found ') . $folder . ' ' . __('Changing to') . ' ' . $base . $folder . '/<br>';
+ return $this->find_base_dir($base . $folder . '/',$echo);
+ }
+ }
+
+ if( $base == '/' )
+ return false;
+ //If we get this far, somethings gone wrong, change to / and restart the process.
+ return $this->find_base_dir('/',$echo);
+ }
+
+ function get_base_dir($base = '.', $echo = false){
+ if( empty($this->wp_base) )
+ $this->wp_base = $this->find_base_dir($base, $echo);
+ return $this->wp_base;
+ }
+
+ function get_contents($file,$type='',$resumepos=0){
+ if( ! $this->exists($file) )
+ return false;
+
+ if( empty($type) ){
+ $extension = substr(strrchr($file, "."), 1);
+ $type = isset($this->filetypes[ $extension ]) ? $this->filetypes[ $extension ] : FTP_AUTOASCII;
+ }
+ $this->ftp->SetType($type);
+ $temp = tmpfile();
+ if ( ! $this->ftp->fget($temp, $file) ) {
+ fclose($temp);
+ return ''; //Blank document, File does exist, Its just blank.
+ }
+ fseek($temp, 0); //Skip back to the start of the file being written to
+ $contents = '';
+ while ( !feof($temp) )
+ $contents .= fread($temp, 8192);
+ fclose($temp);
+ return $contents;
+ }
+
+ function get_contents_array($file){
+ return explode("\n",$this->get_contents($file));
+ }
+
+ function put_contents($file,$contents,$type=''){
+ if( empty($type) ){
+ $extension = substr(strrchr($file, "."), 1);
+ $type = isset($this->filetypes[ $extension ]) ? $this->filetypes[ $extension ] : FTP_ASCII;
+ }
+ $this->ftp->SetType($type);
+
+ $temp = tmpfile();
+ fwrite($temp,$contents);
+ fseek($temp, 0); //Skip back to the start of the file being written to
+ $ret = $this->ftp->fput($file, $temp);
+ fclose($temp);
+ return $ret;
+ }
+
+ function cwd(){
+ return $this->ftp->pwd();
+ }
+
+ function chdir($file){
+ return $this->ftp->chdir($file);
+ }
+
+ function chgrp($file,$group,$recursive=false){
+ return false;
+ }
+
+ function chmod($file,$mode=false,$recursive=false){
+ if( ! $mode )
+ $mode = $this->permission;
+ if( ! $mode )
+ return false;
+ //if( ! $this->exists($file) )
+ // return false;
+ if( ! $recursive || ! $this->is_dir($file) ){
+ return $this->ftp->chmod($file,$mode);
+ }
+ //Is a directory, and we want recursive
+ $filelist = $this->dirlist($file);
+ foreach($filelist as $filename){
+ $this->chmod($file.'/'.$filename,$mode,$recursive);
+ }
+ return true;
+ }
+
+ function chown($file,$owner,$recursive=false){
+ return false;
+ }
+
+ function owner($file){
+ $dir = $this->dirlist($file);
+ return $dir[$file]['owner'];
+ }
+
+ function getchmod($file){
+ $dir = $this->dirlist($file);
+ return $dir[$file]['permsn'];
+ }
+
+ function gethchmod($file){
+ //From the PHP.net page for ...?
+ $perms = $this->getchmod($file);
+ if (($perms & 0xC000) == 0xC000) {
+ // Socket
+ $info = 's';
+ } elseif (($perms & 0xA000) == 0xA000) {
+ // Symbolic Link
+ $info = 'l';
+ } elseif (($perms & 0x8000) == 0x8000) {
+ // Regular
+ $info = '-';
+ } elseif (($perms & 0x6000) == 0x6000) {
+ // Block special
+ $info = 'b';
+ } elseif (($perms & 0x4000) == 0x4000) {
+ // Directory
+ $info = 'd';
+ } elseif (($perms & 0x2000) == 0x2000) {
+ // Character special
+ $info = 'c';
+ } elseif (($perms & 0x1000) == 0x1000) {
+ // FIFO pipe
+ $info = 'p';
+ } else {
+ // Unknown
+ $info = 'u';
+ }
+
+ // Owner
+ $info .= (($perms & 0x0100) ? 'r' : '-');
+ $info .= (($perms & 0x0080) ? 'w' : '-');
+ $info .= (($perms & 0x0040) ?
+ (($perms & 0x0800) ? 's' : 'x' ) :
+ (($perms & 0x0800) ? 'S' : '-'));
+
+ // Group
+ $info .= (($perms & 0x0020) ? 'r' : '-');
+ $info .= (($perms & 0x0010) ? 'w' : '-');
+ $info .= (($perms & 0x0008) ?
+ (($perms & 0x0400) ? 's' : 'x' ) :
+ (($perms & 0x0400) ? 'S' : '-'));
+
+ // World
+ $info .= (($perms & 0x0004) ? 'r' : '-');
+ $info .= (($perms & 0x0002) ? 'w' : '-');
+ $info .= (($perms & 0x0001) ?
+ (($perms & 0x0200) ? 't' : 'x' ) :
+ (($perms & 0x0200) ? 'T' : '-'));
+ return $info;
+ }
+
+ function getnumchmodfromh($mode) {
+ $realmode = "";
+ $legal = array("","w","r","x","-");
+ $attarray = preg_split("//",$mode);
+ for($i=0;$i<count($attarray);$i++){
+ if($key = array_search($attarray[$i],$legal)){
+ $realmode .= $legal[$key];
+ }
+ }
+ $mode = str_pad($realmode,9,'-');
+ $trans = array('-'=>'0','r'=>'4','w'=>'2','x'=>'1');
+ $mode = strtr($mode,$trans);
+ $newmode = '';
+ $newmode .= $mode[0]+$mode[1]+$mode[2];
+ $newmode .= $mode[3]+$mode[4]+$mode[5];
+ $newmode .= $mode[6]+$mode[7]+$mode[8];
+ return $newmode;
+ }
+
+ function group($file){
+ $dir = $this->dirlist($file);
+ return $dir[$file]['group'];
+ }
+
+ function copy($source,$destination,$overwrite=false){
+ if( ! $overwrite && $this->exists($destination) )
+ return false;
+
+ $content = $this->get_contents($source);
+ if ( false === $content )
+ return false;
+
+ return $this->put_contents($destination,$content);
+ }
+
+ function move($source,$destination,$overwrite=false){
+ return $this->ftp->rename($source,$destination);
+ }
+
+ function delete($file,$recursive=false) {
+ if ( $this->is_file($file) )
+ return $this->ftp->delete($file);
+ if ( !$recursive )
+ return $this->ftp->rmdir($file);
+
+ return $this->ftp->mdel($file);
+ }
+
+ function exists($file){
+ return $this->ftp->is_exists($file);
+ }
+
+ function is_file($file){
+ return $this->is_dir($file) ? false : true;
+ }
+
+ function is_dir($path){
+ $cwd = $this->cwd();
+ if ( $this->chdir($path) ) {
+ $this->chdir($cwd);
+ return true;
+ }
+ return false;
+ }
+
+ function is_readable($file){
+ //Get dir list, Check if the file is writable by the current user??
+ return true;
+ }
+
+ function is_writable($file){
+ //Get dir list, Check if the file is writable by the current user??
+ return true;
+ }
+
+ function atime($file){
+ return false;
+ }
+
+ function mtime($file){
+ return $this->ftp->mdtm($file);
+ }
+
+ function size($file){
+ return $this->ftp->filesize($file);
+ }
+
+ function touch($file,$time=0,$atime=0){
+ return false;
+ }
+
+ function mkdir($path,$chmod=false,$chown=false,$chgrp=false){
+ if( ! $this->ftp->mkdir($path) )
+ return false;
+ if( $chmod )
+ $this->chmod($path, $chmod);
+ if( $chown )
+ $this->chown($path, $chown);
+ if( $chgrp )
+ $this->chgrp($path, $chgrp);
+ return true;
+ }
+
+ function rmdir($path,$recursive=false){
+ if( ! $recursive )
+ return $this->ftp->rmdir($path);
+
+ return $this->ftp->mdel($path);
+ }
+
+ function dirlist($path='.',$incdot=false,$recursive=false){
+ if( $this->is_file($path) ){
+ $limitFile = basename($path);
+ $path = dirname($path) . '/';
+ } else {
+ $limitFile = false;
+ }
+ //if( ! $this->is_dir($path) )
+ // return false;
+ $list = $this->ftp->dirlist($path);
+ if( ! $list )
+ return false;
+ if( empty($list) )
+ return array();
+
+ $ret = array();
+ foreach ( $list as $struc ) {
+
+ if ( 'd' == $struc['type'] ) {
+ $struc['files'] = array();
+
+ if ( $incdot ){
+ //We're including the doted starts
+ if( '.' != $struc['name'] && '..' != $struc['name'] ){ //Ok, It isnt a special folder
+ if ($recursive)
+ $struc['files'] = $this->dirlist($path.'/'.$struc['name'],$incdot,$recursive);
+ }
+ } else { //No dots
+ if ($recursive)
+ $struc['files'] = $this->dirlist($path.'/'.$struc['name'],$incdot,$recursive);
+ }
+ }
+ //File
+ $ret[$struc['name']] = $struc;
+ }
+ return $ret;
+ }
+
+ function __destruct(){
+ $this->ftp->quit();
+ }
+}
+?>
diff --git a/wp-admin/includes/dashboard.php b/wp-admin/includes/dashboard.php
new file mode 100644
index 0000000..c675c4d
--- /dev/null
+++ b/wp-admin/includes/dashboard.php
@@ -0,0 +1,538 @@
+<?php
+
+// Registers dashboard widgets, handles POST data, sets up filters
+function wp_dashboard_setup() {
+ global $wpdb, $wp_dashboard_sidebars;
+ $update = false;
+ if ( !$widget_options = get_option( 'dashboard_widget_options' ) )
+ $widget_options = array();
+
+
+ /* Register WP Dashboard Dynamic Sidebar */
+ register_sidebar( array(
+ 'name' => 'WordPress Dashboard',
+ 'id' => 'wp_dashboard',
+ 'before_widget' => "\t<div class='dashboard-widget-holder %2\$s' id='%1\$s'>\n\n\t\t<div class='dashboard-widget'>\n\n",
+ 'after_widget' => "\t\t</div>\n\n\t</div>\n\n",
+ 'before_title' => "\t\t\t<h3 class='dashboard-widget-title'>",
+ 'after_title' => "</h3>\n\n"
+ ) );
+
+
+ /* Register Widgets and Controls */
+
+ // Recent Comments Widget
+ if ( current_user_can( 'moderate_comments' ) && $mod_comments = $wpdb->get_var("SELECT COUNT(*) FROM $wpdb->comments WHERE comment_approved = '0'") ) {
+ $notice = sprintf( __ngettext( '%d comment awaiting moderation', '%d comments awaiting moderation', $mod_comments ), $mod_comments );
+ $notice = "<a href='moderation.php'>$notice</a>";
+ } else {
+ $notice = '';
+ }
+ wp_register_sidebar_widget( 'dashboard_recent_comments', __( 'Recent Comments' ), 'wp_dashboard_recent_comments',
+ array( 'all_link' => 'edit-comments.php', 'notice' => $notice, 'width' => 'half' )
+ );
+
+ // Incoming Links Widget
+ if ( !isset( $widget_options['dashboard_incoming_links'] ) ) {
+ $update = true;
+ $widget_options['dashboard_incoming_links'] = array(
+ 'link' => apply_filters( 'dashboard_incoming_links_link', 'http://blogsearch.google.com/blogsearch?hl=en&scoring=d&partner=wordpress&q=link:' . trailingslashit( get_option('home') ) ),
+ 'url' => apply_filters( 'dashboard_incoming_links_feed', 'http://blogsearch.google.com/blogsearch_feeds?hl=en&scoring=d&ie=utf-8&num=10&output=rss&partner=wordpress&q=link:' . trailingslashit( get_option('home') ) ),
+ 'items' => 5,
+ 'show_date' => 0
+ );
+ }
+ wp_register_sidebar_widget( 'dashboard_incoming_links', __( 'Incoming Links' ), 'wp_dashboard_empty',
+ array( 'all_link' => $widget_options['dashboard_incoming_links']['link'], 'feed_link' => $widget_options['dashboard_incoming_links']['url'], 'width' => 'half' ),
+ 'wp_dashboard_cached_rss_widget', 'wp_dashboard_incoming_links_output'
+ );
+ wp_register_widget_control( 'dashboard_incoming_links', __( 'Incoming Links' ), 'wp_dashboard_rss_control', array(),
+ array( 'widget_id' => 'dashboard_incoming_links', 'form_inputs' => array( 'title' => false, 'show_summary' => false, 'show_author' => false ) )
+ );
+
+
+ // WP Plugins Widget
+ wp_register_sidebar_widget( 'dashboard_plugins', __( 'Plugins' ), 'wp_dashboard_empty',
+ array( 'all_link' => 'http://wordpress.org/extend/plugins/', 'feed_link' => 'http://wordpress.org/extend/plugins/rss/topics/', 'width' => 'half' ),
+ 'wp_dashboard_cached_rss_widget', 'wp_dashboard_plugins_output',
+ array( 'http://wordpress.org/extend/plugins/rss/browse/popular/', 'http://wordpress.org/extend/plugins/rss/browse/new/', 'http://wordpress.org/extend/plugins/rss/browse/updated/' )
+ );
+
+ // Primary feed (Dev Blog) Widget
+ if ( !isset( $widget_options['dashboard_primary'] ) ) {
+ $update = true;
+ $widget_options['dashboard_primary'] = array(
+ 'link' => apply_filters( 'dashboard_primary_link', 'http://wordpress.org/development/' ),
+ 'url' => apply_filters( 'dashboard_primary_feed', 'http://wordpress.org/development/feed/' ),
+ 'title' => apply_filters( 'dashboard_primary_title', __( 'WordPress Development Blog' ) ),
+ 'items' => 2,
+ 'show_summary' => 1,
+ 'show_author' => 0,
+ 'show_date' => 1
+ );
+ }
+ wp_register_sidebar_widget( 'dashboard_primary', $widget_options['dashboard_primary']['title'], 'wp_dashboard_empty',
+ array( 'all_link' => $widget_options['dashboard_primary']['link'], 'feed_link' => $widget_options['dashboard_primary']['url'], 'width' => 'half', 'class' => 'widget_rss' ),
+ 'wp_dashboard_cached_rss_widget', 'wp_dashboard_rss_output'
+ );
+ wp_register_widget_control( 'dashboard_primary', __( 'Primary Feed' ), 'wp_dashboard_rss_control', array(),
+ array( 'widget_id' => 'dashboard_primary' )
+ );
+
+
+ // Secondary Feed (Planet) Widget
+ if ( !isset( $widget_options['dashboard_secondary'] ) ) {
+ $update = true;
+ $widget_options['dashboard_secondary'] = array(
+ 'link' => apply_filters( 'dashboard_secondary_link', 'http://planet.wordpress.org/' ),
+ 'url' => apply_filters( 'dashboard_secondary_feed', 'http://planet.wordpress.org/feed/' ),
+ 'title' => apply_filters( 'dashboard_secondary_title', __( 'Other WordPress News' ) ),
+ 'items' => 15
+ );
+ }
+ wp_register_sidebar_widget( 'dashboard_secondary', $widget_options['dashboard_secondary']['title'], 'wp_dashboard_empty',
+ array( 'all_link' => $widget_options['dashboard_secondary']['link'], 'feed_link' => $widget_options['dashboard_secondary']['url'], 'width' => 'full' ),
+ 'wp_dashboard_cached_rss_widget', 'wp_dashboard_secondary_output'
+ );
+ wp_register_widget_control( 'dashboard_secondary', __( 'Secondary Feed' ), 'wp_dashboard_rss_control', array(),
+ array( 'widget_id' => 'dashboard_secondary', 'form_inputs' => array( 'show_summary' => false, 'show_author' => false, 'show_date' => false ) )
+ );
+
+
+ /* Dashboard Widget Template
+ wp_register_sidebar_widget( $widget_id (unique slug) , $widget_title, $output_callback,
+ array(
+ 'all_link' => full url for "See All" link,
+ 'feed_link' => full url for "RSS" link,
+ 'width' => 'fourth', 'third', 'half', 'full' (defaults to 'half'),
+ 'height' => 'single', 'double' (defaults to 'single'),
+ ),
+ $wp_dashboard_empty_callback (only needed if using 'wp_dashboard_empty' as your $output_callback),
+ $arg, $arg, $arg... (further args passed to callbacks)
+ );
+
+ // optional: if you want users to be able to edit the settings of your widget, you need to register a widget_control
+ wp_register_widget_control( $widget_id, $widget_control_title, $control_output_callback,
+ array(), // leave an empty array here: oddity in widget code
+ array(
+ 'widget_id' => $widget_id, // Yes - again. This is required: oddity in widget code
+ 'arg' => an arg to pass to the $control_output_callback,
+ 'another' => another arg to pass to the $control_output_callback,
+ ...
+ )
+ );
+ */
+
+ // Hook to register new widgets
+ do_action( 'wp_dashboard_setup' );
+
+ // Hard code the sidebar's widgets and order
+ $dashboard_widgets = array();
+ $dashboard_widgets[] = 'dashboard_recent_comments';
+ $dashboard_widgets[] = 'dashboard_incoming_links';
+ $dashboard_widgets[] = 'dashboard_primary';
+ if ( current_user_can( 'activate_plugins' ) )
+ $dashboard_widgets[] = 'dashboard_plugins';
+ $dashboard_widgets[] = 'dashboard_secondary';
+
+ // Filter widget order
+ $dashboard_widgets = apply_filters( 'wp_dashboard_widgets', $dashboard_widgets );
+
+ $wp_dashboard_sidebars = array( 'wp_dashboard' => $dashboard_widgets, 'array_version' => 3.5 );
+
+ add_filter( 'dynamic_sidebar_params', 'wp_dashboard_dynamic_sidebar_params' );
+
+ if ( 'POST' == $_SERVER['REQUEST_METHOD'] && isset($_POST['widget_id']) ) {
+ ob_start(); // hack - but the same hack wp-admin/widgets.php uses
+ wp_dashbaord_trigger_widget_control( $_POST['widget_id'] );
+ ob_end_clean();
+ wp_redirect( remove_query_arg( 'edit' ) );
+ exit;
+ }
+
+ if ( $update )
+ update_option( 'dashboard_widget_options', $widget_options );
+}
+
+// Echoes out the dashboard
+function wp_dashboard() {
+ echo "<div id='dashboard-widgets'>\n\n";
+
+ // We're already filtering dynamic_sidebar_params obove
+ add_filter( 'option_sidebars_widgets', 'wp_dashboard_sidebars_widgets' ); // here there be hackery
+ dynamic_sidebar( 'wp_dashboard' );
+ remove_filter( 'option_sidebars_widgets', 'wp_dashboard_sidebars_widgets' );
+
+ echo "<br class='clear' />\n</div>\n\n\n";
+}
+
+// Makes sidebar_widgets option reflect the dashboard settings
+function wp_dashboard_sidebars_widgets() { // hackery
+ return $GLOBALS['wp_dashboard_sidebars'];
+}
+
+// Modifies sidbar params on the fly to set up ids, class names, titles for each widget (called once per widget)
+// Switches widget to edit mode if $_GET['edit']
+function wp_dashboard_dynamic_sidebar_params( $params ) {
+ global $wp_registered_widgets, $wp_registered_widget_controls;
+
+ $sidebar_defaults = array('widget_id' => 0, 'before_widget' => '', 'after_widget' => '', 'before_title' => '', 'after_title' => '');
+ extract( $sidebar_defaults, EXTR_PREFIX_ALL, 'sidebar' );
+ extract( $params[0], EXTR_PREFIX_ALL, 'sidebar' );
+
+ if ( !isset($wp_registered_widgets[$sidebar_widget_id]) || !is_array($wp_registered_widgets[$sidebar_widget_id]) ) {
+ return $params;
+ }
+ $widget_defaults = array('id' => '', 'width' => '', 'height' => '', 'class' => '', 'feed_link' => '', 'all_link' => '', 'notice' => false, 'error' => false);
+ extract( $widget_defaults, EXTR_PREFIX_ALL, 'widget' );
+ extract( $wp_registered_widgets[$sidebar_widget_id], EXTR_PREFIX_ALL, 'widget' );
+
+ $the_classes = array();
+ if ( in_array($widget_width, array( 'third', 'fourth', 'full' ) ) )
+ $the_classes[] = $widget_width;
+
+ if ( 'double' == $widget_height )
+ $the_classes[] = 'double';
+
+ if ( $widget_class )
+ $the_classes[] = $widget_class;
+
+ // Add classes to the widget holder
+ if ( $the_classes )
+ $sidebar_before_widget = str_replace( "<div class='dashboard-widget-holder ", "<div class='dashboard-widget-holder " . join( ' ', $the_classes ) . ' ', $sidebar_before_widget );
+
+ $links = array();
+ if ( $widget_all_link )
+ $links[] = '<a href="' . clean_url( $widget_all_link ) . '">' . __( 'See&nbsp;All' ) . '</a>';
+
+ $content_class = 'dashboard-widget-content';
+ if ( current_user_can( 'edit_dashboard' ) && isset($wp_registered_widget_controls[$widget_id]) && is_callable($wp_registered_widget_controls[$widget_id]['callback']) ) {
+ // Switch this widget to edit mode
+ if ( isset($_GET['edit']) && $_GET['edit'] == $widget_id ) {
+ $content_class .= ' dashboard-widget-control';
+ $wp_registered_widgets[$widget_id]['callback'] = 'wp_dashboard_empty';
+ $sidebar_widget_name = $wp_registered_widget_controls[$widget_id]['name'];
+ $params[1] = 'wp_dashbaord_trigger_widget_control';
+ $sidebar_before_widget .= '<form action="' . remove_query_arg( 'edit' ) . '" method="post">';
+ $sidebar_after_widget = "<div class='dashboard-widget-submit'><input type='hidden' name='sidebar' value='wp_dashboard' /><input type='hidden' name='widget_id' value='$widget_id' /><input type='submit' value='" . __( 'Save' ) . "' /></div></form>$sidebar_after_widget";
+ $links[] = '<a href="' . remove_query_arg( 'edit' ) . '">' . __( 'Cancel' ) . '</a>';
+ } else {
+ $links[] = '<a href="' . add_query_arg( 'edit', $widget_id ) . "#$widget_id" . '">' . __( 'Edit' ) . '</a>';
+ }
+ }
+
+ if ( $widget_feed_link )
+ $links[] = '<img class="rss-icon" src="' . get_option( 'siteurl' ) . '/' . WPINC . '/images/rss.png" alt="' . __( 'rss icon' ) . '" /> <a href="' . clean_url( $widget_feed_link ) . '">' . __( 'RSS' ) . '</a>';
+
+ $links = apply_filters( "wp_dashboard_widget_links_$widget_id", $links );
+
+ // Add links to widget's title bar
+ if ( $links ) {
+ $sidebar_before_title .= '<span>';
+ $sidebar_after_title = '</span><small>' . join( '&nbsp;|&nbsp;', $links ) . "</small><br class='clear' />$sidebar_after_title";
+ }
+
+ // Could have put this in widget-content. Doesn't really matter
+ if ( $widget_notice )
+ $sidebar_after_title .= "\t\t\t<div class='dashboard-widget-notice'>$widget_notice</div>\n\n";
+
+ if ( $widget_error )
+ $sidebar_after_title .= "\t\t\t<div class='dashboard-widget-error'>$widget_error</div>\n\n";
+
+ $sidebar_after_title .= "\t\t\t<div class='$content_class'>\n\n";
+
+ $sidebar_after_widget .= "\t\t\t</div>\n\n";
+
+ foreach( array_keys( $params[0] ) as $key )
+ $$key = ${'sidebar_' . $key};
+
+ $params[0] = compact( array_keys( $params[0] ) );
+
+ return $params;
+}
+
+
+/* Dashboard Widgets */
+
+function wp_dashboard_recent_comments( $sidebar_args ) {
+ global $comment;
+ extract( $sidebar_args, EXTR_SKIP );
+
+ echo $before_widget;
+
+ echo $before_title;
+ echo $widget_name;
+ echo $after_title;
+
+ $lambda = create_function( '', 'return 5;' );
+ add_filter( 'option_posts_per_rss', $lambda ); // hack - comments query doesn't accept per_page parameter
+ $comments_query = new WP_Query('feed=rss2&withcomments=1');
+ remove_filter( 'option_posts_per_rss', $lambda );
+
+ $is_first = true;
+
+ if ( $comments_query->have_comments() ) {
+ while ( $comments_query->have_comments() ) { $comments_query->the_comment();
+
+ $comment_post_url = get_permalink( $comment->comment_post_ID );
+ $comment_post_title = get_the_title( $comment->comment_post_ID );
+ $comment_post_link = "<a href='$comment_post_url'>$comment_post_title</a>";
+ $comment_link = '<a class="comment-link" href="' . get_comment_link() . '">#</a>';
+ $comment_meta = sprintf( __( 'From <strong>%1$s</strong> on %2$s %3$s' ), get_comment_author(), $comment_post_link, $comment_link );
+
+ if ( $is_first ) : $is_first = false;
+?>
+ <blockquote><p>&#8220;<?php comment_excerpt(); ?>&#8221;</p></blockquote>
+ <p class='comment-meta'><?php echo $comment_meta; ?></p>
+
+ <ul id="dashboard-comments-list">
+<?php
+ else :
+?>
+
+ <li class='comment-meta'><?php echo $comment_meta; ?></li>
+<?php
+ endif;
+ }
+?>
+
+ </ul>
+
+<?php
+
+ }
+
+ echo $after_widget;
+}
+
+// $sidebar_args are handled by wp_dashboard_empty()
+function wp_dashboard_incoming_links_output() {
+ $widgets = get_option( 'dashboard_widget_options' );
+ @extract( @$widgets['dashboard_incoming_links'], EXTR_SKIP );
+ $rss = @fetch_rss( $url );
+ if ( isset($rss->items) && 1 < count($rss->items) ) {// Technorati returns a 1-item feed when it has no results
+
+ echo "<ul>\n";
+
+ $rss->items = array_slice($rss->items, 0, $items);
+ foreach ( $rss->items as $item ) {
+ $publisher = '';
+ $site_link = '';
+ $link = '';
+ $content = '';
+ $date = '';
+ $link = clean_url( strip_tags( $item['link'] ) );
+
+ if ( isset( $item['author_uri'] ) )
+ $site_link = clean_url( strip_tags( $item['author_uri'] ) );
+
+ if ( !$publisher = wp_specialchars( strip_tags( isset($item['dc']['publisher']) ? $item['dc']['publisher'] : $item['author_name'] ) ) )
+ $publisher = __( 'Somebody' );
+ if ( $site_link )
+ $publisher = "<a href='$site_link'>$publisher</a>";
+ else
+ $publisher = "<strong>$publisher</strong>";
+
+ if ( isset($item['description']) )
+ $content = $item['description'];
+ elseif ( isset($item['summary']) )
+ $content = $item['summary'];
+ elseif ( isset($item['atom_content']) )
+ $content = $item['atom_content'];
+ else
+ $content = __( 'something' );
+ $content = wp_html_excerpt($content, 50) . ' ...';
+ if ( $link )
+ $text = _c( '%1$s linked here <a href="%2$s">saying</a>, "%3$s"|feed_display' );
+ else
+ $text = _c( '%1$s linked here saying, "%3$s"|feed_display' );
+
+ if ( $show_date ) {
+ if ( $show_author || $show_summary )
+ $text .= _c( ' on %4$s|feed_display' );
+ $date = wp_specialchars( strip_tags( isset($item['pubdate']) ? $item['pubdate'] : $item['published'] ) );
+ $date = strtotime( $date );
+ $date = gmdate( get_option( 'date_format' ), $date );
+ }
+
+ echo "\t<li>" . sprintf( _c( "$text|feed_display" ), $publisher, $link, $content, $date ) . "</li>\n";
+ }
+
+ echo "</ul>\n";
+
+ } else {
+ echo '<p>' . __('This dashboard widget queries <a href="http://blogsearch.google.com/">Google Blog Search</a> so that when another blog links to your site it will show up here. They have found no incoming links found&hellip; yet. It&#8217;s okay &#8212; there is no rush.') . "</p>\n";
+ }
+}
+
+// $sidebar_args are handled by wp_dashboard_empty()
+function wp_dashboard_rss_output( $widget_id ) {
+ $widgets = get_option( 'dashboard_widget_options' );
+ wp_widget_rss_output( $widgets[$widget_id] );
+}
+
+// $sidebar_args are handled by wp_dashboard_empty()
+function wp_dashboard_secondary_output() {
+ $widgets = get_option( 'dashboard_widget_options' );
+ @extract( @$widgets['dashboard_secondary'], EXTR_SKIP );
+ $rss = @fetch_rss( $url );
+ if ( !isset($rss->items) || 0 == count($rss->items) )
+ return false;
+
+ echo "<ul id='planetnews'>\n";
+
+ $rss->items = array_slice($rss->items, 0, $items);
+ foreach ($rss->items as $item ) {
+ $title = wp_specialchars($item['title']);
+ $author = preg_replace( '|(.+?):.+|s', '$1', $item['title'] );
+ $post = preg_replace( '|.+?:(.+)|s', '$1', $item['title'] );
+ $link = clean_url($item['link']);
+
+ echo "\t<li><a href='$link'><span class='post'>$post</span><span class='hidden'> - </span><cite>$author</cite></a></li>\n";
+ }
+
+ echo "</ul>\n<br class='clear' />\n";
+}
+
+// $sidebar_args are handled by wp_dashboard_empty()
+function wp_dashboard_plugins_output() {
+ $popular = @fetch_rss( 'http://wordpress.org/extend/plugins/rss/browse/popular/' );
+ $new = @fetch_rss( 'http://wordpress.org/extend/plugins/rss/browse/new/' );
+ $updated = @fetch_rss( 'http://wordpress.org/extend/plugins/rss/browse/updated/' );
+
+ foreach ( array( 'popular' => __('Most Popular'), 'new' => __('Newest Plugins'), 'updated' => __('Recently Updated') ) as $feed => $label ) {
+ if ( !isset($$feed->items) || 0 == count($$feed->items) )
+ continue;
+
+ $$feed->items = array_slice($$feed->items, 0, 5);
+ $item_key = array_rand($$feed->items);
+
+ // Eliminate some common badly formed plugin descriptions
+ while ( ( null !== $item_key = array_rand($$feed->items) ) && false !== strpos( $$feed->items[$item_key]['description'], 'Plugin Name:' ) )
+ unset($$feed->items[$item_key]);
+
+ if ( !isset($$feed->items[$item_key]) )
+ continue;
+
+ $item = $$feed->items[$item_key];
+
+ // current bbPress feed item titles are: user on "topic title"
+ if ( preg_match( '/"(.*)"/s', $item['title'], $matches ) )
+ $title = $matches[1];
+ else // but let's make it forward compatible if things change
+ $title = $item['title'];
+ $title = wp_specialchars( $title );
+
+ $description = wp_specialchars( strip_tags(html_entity_decode($item['description'], ENT_QUOTES)) );
+
+ list($link, $frag) = explode( '#', $item['link'] );
+
+ $link = clean_url($link);
+ $dlink = rtrim($link, '/') . '/download/';
+
+ echo "<h4>$label</h4>\n";
+ echo "<h5><a href='$link'>$title</a></h5>&nbsp;<span>(<a href='$dlink'>" . __( 'Download' ) . "</a>)</span>\n";
+ echo "<p>$description</p>\n";
+ }
+}
+
+// Checks to see if all of the feed url in $check_urls are cached.
+// If $check_urls is empty, look for the rss feed url found in the dashboard widget optios of $widget_id.
+// If cached, call $callback, a function that echoes out output for this widget.
+// If not cache, echo a "Loading..." stub which is later replaced by AJAX call (see top of /wp-admin/index.php)
+function wp_dashboard_cached_rss_widget( $widget_id, $callback, $check_urls = array() ) {
+ $loading = '<p class="widget-loading">' . __( 'Loading&#8230;' ) . '</p>';
+
+ if ( empty($check_urls) ) {
+ $widgets = get_option( 'dashboard_widget_options' );
+ if ( empty($widgets[$widget_id]['url']) ) {
+ echo $loading;
+ return false;
+ }
+ $check_urls = array( $widgets[$widget_id]['url'] );
+ }
+
+
+ require_once( ABSPATH . WPINC . '/rss.php' );
+ init(); // initialize rss constants
+
+ $cache = new RSSCache( MAGPIE_CACHE_DIR, MAGPIE_CACHE_AGE );
+
+ foreach ( $check_urls as $check_url ) {
+ $status = $cache->check_cache( $check_url );
+ if ( 'HIT' !== $status ) {
+ echo $loading;
+ return false;
+ }
+ }
+
+ if ( $callback && is_callable( $callback ) ) {
+ $args = array_slice( func_get_args(), 2 );
+ array_unshift( $args, $widget_id );
+ call_user_func_array( $callback, $args );
+ }
+
+ return true;
+}
+
+// Empty widget used for JS/AJAX created output.
+// Callback inserts content between before_widget and after_widget. Used when widget is in edit mode. Can also be used for custom widgets.
+function wp_dashboard_empty( $sidebar_args, $callback = false ) {
+ extract( $sidebar_args, EXTR_SKIP );
+
+ echo $before_widget;
+
+ echo $before_title;
+ echo $widget_name;
+ echo $after_title;
+
+ // When in edit mode, the callback passed to this function is the widget_control callback
+ if ( $callback && is_callable( $callback ) ) {
+ $args = array_slice( func_get_args(), 2 );
+ array_unshift( $args, $widget_id );
+ call_user_func_array( $callback, $args );
+ }
+
+ echo $after_widget;
+}
+
+/* Dashboard Widgets Controls. Ssee also wp_dashboard_empty() */
+
+// Calls widget_control callback
+function wp_dashbaord_trigger_widget_control( $widget_control_id = false ) {
+ global $wp_registered_widget_controls;
+ if ( is_scalar($widget_control_id) && $widget_control_id && isset($wp_registered_widget_controls[$widget_control_id]) && is_callable($wp_registered_widget_controls[$widget_control_id]['callback']) )
+ call_user_func_array( $wp_registered_widget_controls[$widget_control_id]['callback'], $wp_registered_widget_controls[$widget_control_id]['params'] );
+}
+
+// Sets up $args to be used as input to wp_widget_rss_form(), handles POST data from RSS-type widgets
+function wp_dashboard_rss_control( $args ) {
+ extract( $args );
+ if ( !$widget_id )
+ return false;
+
+ if ( !$widget_options = get_option( 'dashboard_widget_options' ) )
+ $widget_options = array();
+
+ if ( !isset($widget_options[$widget_id]) )
+ $widget_options[$widget_id] = array();
+
+ $number = 1; // Hack to use wp_widget_rss_form()
+ $widget_options[$widget_id]['number'] = $number;
+
+ if ( 'POST' == $_SERVER['REQUEST_METHOD'] && isset($_POST['widget-rss'][$number]) ) {
+ $_POST['widget-rss'][$number] = stripslashes_deep( $_POST['widget-rss'][$number] );
+ $widget_options[$widget_id] = wp_widget_rss_process( $_POST['widget-rss'][$number] );
+ // title is optional. If black, fill it if possible
+ if ( !$widget_options[$widget_id]['title'] && isset($_POST['widget-rss'][$number]['title']) ) {
+ require_once(ABSPATH . WPINC . '/rss.php');
+ $rss = fetch_rss($widget_options[$widget_id]['url']);
+ $widget_options[$widget_id]['title'] = htmlentities(strip_tags($rss->channel['title']));
+ }
+ update_option( 'dashboard_widget_options', $widget_options );
+ }
+
+ wp_widget_rss_form( $widget_options[$widget_id], $form_inputs );
+}
+
+?>
diff --git a/wp-admin/includes/export.php b/wp-admin/includes/export.php
new file mode 100644
index 0000000..a712177
--- /dev/null
+++ b/wp-admin/includes/export.php
@@ -0,0 +1,255 @@
+<?php
+
+// version number for the export format. bump this when something changes that might affect compatibility.
+define('WXR_VERSION', '1.0');
+
+function export_wp($author='') {
+global $wpdb, $post_ids, $post;
+
+do_action('export_wp');
+
+$filename = 'wordpress.' . date('Y-m-d') . '.xml';
+
+header('Content-Description: File Transfer');
+header("Content-Disposition: attachment; filename=$filename");
+header('Content-Type: text/xml; charset=' . get_option('blog_charset'), true);
+
+$where = '';
+if ( $author and $author != 'all' ) {
+ $author_id = (int) $author;
+ $where = " WHERE post_author = '$author_id' ";
+}
+
+// grab a snapshot of post IDs, just in case it changes during the export
+$post_ids = $wpdb->get_col("SELECT ID FROM $wpdb->posts $where ORDER BY post_date_gmt ASC");
+
+$categories = (array) get_categories('get=all');
+$tags = (array) get_tags('get=all');
+
+function wxr_missing_parents($categories) {
+ if ( !is_array($categories) || empty($categories) )
+ return array();
+
+ foreach ( $categories as $category )
+ $parents[$category->term_id] = $category->parent;
+
+ $parents = array_unique(array_diff($parents, array_keys($parents)));
+
+ if ( $zero = array_search('0', $parents) )
+ unset($parents[$zero]);
+
+ return $parents;
+}
+
+while ( $parents = wxr_missing_parents($categories) ) {
+ $found_parents = get_categories("include=" . join(', ', $parents));
+ if ( is_array($found_parents) && count($found_parents) )
+ $categories = array_merge($categories, $found_parents);
+ else
+ break;
+}
+
+// Put them in order to be inserted with no child going before its parent
+$pass = 0;
+$passes = 1000 + count($categories);
+while ( ( $cat = array_shift($categories) ) && ++$pass < $passes ) {
+ if ( $cat->parent == 0 || isset($cats[$cat->parent]) ) {
+ $cats[$cat->term_id] = $cat;
+ } else {
+ $categories[] = $cat;
+ }
+}
+unset($categories);
+
+function wxr_cdata($str) {
+ if ( seems_utf8($str) == false )
+ $str = utf8_encode($str);
+
+ // $str = ent2ncr(wp_specialchars($str));
+
+ $str = "<![CDATA[$str" . ( ( substr($str, -1) == ']' ) ? ' ' : '') . "]]>";
+
+ return $str;
+}
+
+function wxr_site_url() {
+ global $current_site;
+
+ // mu: the base url
+ if ( isset($current_site->domain) ) {
+ return 'http://'.$current_site->domain.$current_site->path;
+ }
+ // wp: the blog url
+ else {
+ return get_bloginfo_rss('url');
+ }
+}
+
+function wxr_cat_name($c) {
+ if ( empty($c->name) )
+ return;
+
+ echo '<wp:cat_name>' . wxr_cdata($c->name) . '</wp:cat_name>';
+}
+
+function wxr_category_description($c) {
+ if ( empty($c->description) )
+ return;
+
+ echo '<wp:category_description>' . wxr_cdata($c->description) . '</wp:category_description>';
+}
+
+function wxr_tag_name($t) {
+ if ( empty($t->name) )
+ return;
+
+ echo '<wp:tag_name>' . wxr_cdata($t->name) . '</wp:tag_name>';
+}
+
+function wxr_tag_description($t) {
+ if ( empty($t->description) )
+ return;
+
+ echo '<wp:tag_description>' . wxr_cdata($t->description) . '</wp:tag_description>';
+}
+
+function wxr_post_taxonomy() {
+ $categories = get_the_category();
+ $tags = get_the_tags();
+ $the_list = '';
+ $filter = 'rss';
+
+ if ( !empty($categories) ) foreach ( (array) $categories as $category ) {
+ $cat_name = sanitize_term_field('name', $category->name, $category->term_id, 'category', $filter);
+ // for backwards compatibility
+ $the_list .= "\n\t\t<category><![CDATA[$cat_name]]></category>\n";
+ // forwards compatibility: use a unique identifier for each cat to avoid clashes
+ // http://trac.wordpress.org/ticket/5447
+ $the_list .= "\n\t\t<category domain=\"category\" nicename=\"{$category->slug}\"><![CDATA[$cat_name]]></category>\n";
+ }
+
+ if ( !empty($tags) ) foreach ( (array) $tags as $tag ) {
+ $tag_name = sanitize_term_field('name', $tag->name, $tag->term_id, 'post_tag', $filter);
+ $the_list .= "\n\t\t<category domain=\"tag\"><![CDATA[$tag_name]]></category>\n";
+ // forwards compatibility as above
+ $the_list .= "\n\t\t<category domain=\"tag\" nicename=\"{$tag->slug}\"><![CDATA[$tag_name]]></category>\n";
+ }
+
+ echo $the_list;
+}
+
+echo '<?xml version="1.0" encoding="' . get_bloginfo('charset') . '"?' . ">\n";
+
+?>
+<!-- This is a WordPress eXtended RSS file generated by WordPress as an export of your blog. -->
+<!-- It contains information about your blog's posts, comments, and categories. -->
+<!-- You may use this file to transfer that content from one site to another. -->
+<!-- This file is not intended to serve as a complete backup of your blog. -->
+
+<!-- To import this information into a WordPress blog follow these steps. -->
+<!-- 1. Log into that blog as an administrator. -->
+<!-- 2. Go to Manage: Import in the blog's admin panels. -->
+<!-- 3. Choose "WordPress" from the list. -->
+<!-- 4. Upload this file using the form provided on that page. -->
+<!-- 5. You will first be asked to map the authors in this export file to users -->
+<!-- on the blog. For each author, you may choose to map to an -->
+<!-- existing user on the blog or to create a new user -->
+<!-- 6. WordPress will then import each of the posts, comments, and categories -->
+<!-- contained in this file into your blog -->
+
+<?php the_generator('export');?>
+<rss version="2.0"
+ xmlns:content="http://purl.org/rss/1.0/modules/content/"
+ xmlns:wfw="http://wellformedweb.org/CommentAPI/"
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:wp="http://wordpress.org/export/<?php echo WXR_VERSION; ?>/"
+>
+
+<channel>
+ <title><?php bloginfo_rss('name'); ?></title>
+ <link><?php bloginfo_rss('url') ?></link>
+ <description><?php bloginfo_rss("description") ?></description>
+ <pubDate><?php echo mysql2date('D, d M Y H:i:s +0000', get_lastpostmodified('GMT'), false); ?></pubDate>
+ <generator>http://wordpress.org/?v=<?php bloginfo_rss('version'); ?></generator>
+ <language><?php echo get_option('rss_language'); ?></language>
+ <wp:wxr_version><?php echo WXR_VERSION; ?></wp:wxr_version>
+ <wp:base_site_url><?php echo wxr_site_url(); ?></wp:base_site_url>
+ <wp:base_blog_url><?php bloginfo_rss('url'); ?></wp:base_blog_url>
+<?php if ( $cats ) : foreach ( $cats as $c ) : ?>
+ <wp:category><wp:category_nicename><?php echo $c->slug; ?></wp:category_nicename><wp:category_parent><?php echo $c->parent ? $cats[$c->parent]->name : ''; ?></wp:category_parent><?php wxr_cat_name($c); ?><?php wxr_category_description($c); ?></wp:category>
+<?php endforeach; endif; ?>
+<?php if ( $tags ) : foreach ( $tags as $t ) : ?>
+ <wp:tag><wp:tag_slug><?php echo $t->slug; ?></wp:tag_slug><?php wxr_tag_name($t); ?><?php wxr_tag_description($t); ?></wp:tag>
+<?php endforeach; endif; ?>
+ <?php do_action('rss2_head'); ?>
+ <?php if ($post_ids) {
+ global $wp_query;
+ $wp_query->in_the_loop = true; // Fake being in the loop.
+ // fetch 20 posts at a time rather than loading the entire table into memory
+ while ( $next_posts = array_splice($post_ids, 0, 20) ) {
+ $where = "WHERE ID IN (".join(',', $next_posts).")";
+ $posts = $wpdb->get_results("SELECT * FROM $wpdb->posts $where ORDER BY post_date_gmt ASC");
+ foreach ($posts as $post) {
+ setup_postdata($post); ?>
+<item>
+<title><?php echo apply_filters('the_title_rss', $post->post_title); ?></title>
+<link><?php the_permalink_rss() ?></link>
+<pubDate><?php echo mysql2date('D, d M Y H:i:s +0000', get_post_time('Y-m-d H:i:s', true), false); ?></pubDate>
+<dc:creator><?php the_author() ?></dc:creator>
+<?php wxr_post_taxonomy() ?>
+
+<guid isPermaLink="false"><?php the_guid(); ?></guid>
+<description></description>
+<content:encoded><![CDATA[<?php echo apply_filters('the_content_export', $post->post_content); ?>]]></content:encoded>
+<wp:post_id><?php echo $post->ID; ?></wp:post_id>
+<wp:post_date><?php echo $post->post_date; ?></wp:post_date>
+<wp:post_date_gmt><?php echo $post->post_date_gmt; ?></wp:post_date_gmt>
+<wp:comment_status><?php echo $post->comment_status; ?></wp:comment_status>
+<wp:ping_status><?php echo $post->ping_status; ?></wp:ping_status>
+<wp:post_name><?php echo $post->post_name; ?></wp:post_name>
+<wp:status><?php echo $post->post_status; ?></wp:status>
+<wp:post_parent><?php echo $post->post_parent; ?></wp:post_parent>
+<wp:menu_order><?php echo $post->menu_order; ?></wp:menu_order>
+<wp:post_type><?php echo $post->post_type; ?></wp:post_type>
+<wp:post_password><?php echo $post->post_password; ?></wp:post_password>
+<?php
+if ($post->post_type == 'attachment') { ?>
+<wp:attachment_url><?php echo wp_get_attachment_url($post->ID); ?></wp:attachment_url>
+<?php } ?>
+<?php
+$postmeta = $wpdb->get_results("SELECT * FROM $wpdb->postmeta WHERE post_id = $post->ID");
+if ( $postmeta ) {
+?>
+<?php foreach( $postmeta as $meta ) { ?>
+<wp:postmeta>
+<wp:meta_key><?php echo $meta->meta_key; ?></wp:meta_key>
+<wp:meta_value><?Php echo $meta->meta_value; ?></wp:meta_value>
+</wp:postmeta>
+<?php } ?>
+<?php } ?>
+<?php
+$comments = $wpdb->get_results("SELECT * FROM $wpdb->comments WHERE comment_post_ID = $post->ID");
+if ( $comments ) { foreach ( $comments as $c ) { ?>
+<wp:comment>
+<wp:comment_id><?php echo $c->comment_ID; ?></wp:comment_id>
+<wp:comment_author><?php echo wxr_cdata($c->comment_author); ?></wp:comment_author>
+<wp:comment_author_email><?php echo $c->comment_author_email; ?></wp:comment_author_email>
+<wp:comment_author_url><?php echo $c->comment_author_url; ?></wp:comment_author_url>
+<wp:comment_author_IP><?php echo $c->comment_author_IP; ?></wp:comment_author_IP>
+<wp:comment_date><?php echo $c->comment_date; ?></wp:comment_date>
+<wp:comment_date_gmt><?php echo $c->comment_date_gmt; ?></wp:comment_date_gmt>
+<wp:comment_content><?php echo $c->comment_content; ?></wp:comment_content>
+<wp:comment_approved><?php echo $c->comment_approved; ?></wp:comment_approved>
+<wp:comment_type><?php echo $c->comment_type; ?></wp:comment_type>
+<wp:comment_parent><?php echo $c->comment_parent; ?></wp:comment_parent>
+<wp:comment_user_id><?php echo $c->user_id; ?></wp:comment_user_id>
+</wp:comment>
+<?php } } ?>
+ </item>
+<?php } } } ?>
+</channel>
+</rss>
+<?php
+}
+
+?> \ No newline at end of file
diff --git a/wp-admin/includes/media.php b/wp-admin/includes/media.php
new file mode 100644
index 0000000..b43c2da
--- /dev/null
+++ b/wp-admin/includes/media.php
@@ -0,0 +1,1225 @@
+<?php
+
+function media_upload_tabs() {
+ $_default_tabs = array(
+ 'type' => __('Choose File'), // handler action suffix => tab text
+ 'gallery' => __('Gallery'),
+ 'library' => __('Media Library'),
+ );
+
+ return apply_filters('media_upload_tabs', $_default_tabs);
+}
+
+function update_gallery_tab($tabs) {
+ global $wpdb;
+ if ( !isset($_REQUEST['post_id']) ) {
+ unset($tabs['gallery']);
+ return $tabs;
+ }
+ if ( intval($_REQUEST['post_id']) )
+ $attachments = intval($wpdb->get_var($wpdb->prepare("SELECT count(*) FROM $wpdb->posts WHERE post_type = 'attachment' AND post_parent = %d", $_REQUEST['post_id'])));
+
+ $tabs['gallery'] = sprintf(__('Gallery (%s)'), "<span id='attachments-count'>$attachments</span>");
+
+ return $tabs;
+}
+add_filter('media_upload_tabs', 'update_gallery_tab');
+
+function the_media_upload_tabs() {
+ $tabs = media_upload_tabs();
+
+ if ( !empty($tabs) ) {
+ echo "<ul id='sidemenu'>\n";
+ if ( isset($_GET['tab']) && array_key_exists($_GET['tab'], $tabs) )
+ $current = $_GET['tab'];
+ else {
+ $keys = array_keys($tabs);
+ $current = array_shift($keys);
+ }
+ foreach ( $tabs as $callback => $text ) {
+ $class = '';
+ if ( $current == $callback )
+ $class = " class='current'";
+ $href = add_query_arg(array('tab'=>$callback, 's'=>false, 'paged'=>false, 'post_mime_type'=>false, 'm'=>false));
+ $link = "<a href='$href'$class>$text</a>";
+ echo "\t<li id='tab-$callback'>$link</li>\n";
+ }
+ echo "</ul>\n";
+ }
+}
+
+function get_image_send_to_editor($id, $alt, $title, $align, $url='', $rel = false, $size='medium') {
+
+ $html = get_image_tag($id, $alt, $title, $align, $rel, $size);
+
+ $rel = $rel ? ' rel="attachment wp-att-'.attribute_escape($id).'"' : '';
+
+ if ( $url )
+ $html = "<a href='".attribute_escape($url)."'$rel>$html</a>";
+
+ $html = apply_filters( 'image_send_to_editor', $html, $id, $alt, $title, $align, $url );
+
+ return $html;
+}
+
+function media_send_to_editor($html) {
+ ?>
+<script type="text/javascript">
+<!--
+top.send_to_editor('<?php echo addslashes($html); ?>');
+top.tb_remove();
+-->
+</script>
+ <?php
+ exit;
+}
+
+// this handles the file upload POST itself, creating the attachment post
+function media_handle_upload($file_id, $post_id, $post_data = array()) {
+ $overrides = array('test_form'=>false);
+ $file = wp_handle_upload($_FILES[$file_id], $overrides);
+
+ if ( isset($file['error']) )
+ return new wp_error( 'upload_error', $file['error'] );
+
+ $url = $file['url'];
+ $type = $file['type'];
+ $file = $file['file'];
+ $title = preg_replace('/\.[^.]+$/', '', basename($file));
+ $content = '';
+
+ // use image exif/iptc data for title and caption defaults if possible
+ if ( $image_meta = @wp_read_image_metadata($file) ) {
+ if ( trim($image_meta['title']) )
+ $title = $image_meta['title'];
+ if ( trim($image_meta['caption']) )
+ $content = $image_meta['caption'];
+ }
+
+ // Construct the attachment array
+ $attachment = array_merge( array(
+ 'post_mime_type' => $type,
+ 'guid' => $url,
+ 'post_parent' => $post_id,
+ 'post_title' => $title,
+ 'post_content' => $content,
+ ), $post_data );
+
+ // Save the data
+ $id = wp_insert_attachment($attachment, $file, $post_parent);
+ if ( !is_wp_error($id) ) {
+ wp_update_attachment_metadata( $id, wp_generate_attachment_metadata( $id, $file ) );
+ }
+
+ return $id;
+
+}
+
+
+// wrap iframe content (produced by $content_func) in a doctype, html head/body etc
+// any additional function args will be passed to content_func
+function wp_iframe($content_func /* ... */) {
+?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" <?php do_action('admin_xml_ns'); ?> <?php language_attributes(); ?>>
+<head>
+<meta http-equiv="Content-Type" content="<?php bloginfo('html_type'); ?>; charset=<?php echo get_option('blog_charset'); ?>" />
+<title><?php bloginfo('name') ?> &rsaquo; <?php _e('Uploads'); ?> &#8212; WordPress</title>
+<?php
+wp_admin_css( 'css/global' );
+wp_admin_css();
+wp_admin_css( 'css/colors' );
+?>
+<script type="text/javascript">
+//<![CDATA[
+function addLoadEvent(func) {if ( typeof wpOnload!='function'){wpOnload=func;}else{ var oldonload=wpOnload;wpOnload=function(){oldonload();func();}}}
+//]]>
+</script>
+<?php
+do_action('admin_print_scripts');
+do_action('admin_head');
+if ( is_string($content_func) )
+ do_action( "admin_head_{$content_func}" );
+?>
+</head>
+<body<?php if ( isset($GLOBALS['body_id']) ) echo ' id="' . $GLOBALS['body_id'] . '"'; ?>>
+<?php
+ $args = func_get_args();
+ $args = array_slice($args, 1);
+ call_user_func_array($content_func, $args);
+?>
+</body>
+</html>
+<?php
+}
+
+function media_buttons() {
+ global $post_ID, $temp_ID;
+ $uploading_iframe_ID = (int) (0 == $post_ID ? $temp_ID : $post_ID);
+ $context = apply_filters('media_buttons_context', __('Add media: %s'));
+ $media_upload_iframe_src = "media-upload.php?post_id=$uploading_iframe_ID";
+ $media_title = __('Add Media');
+ $image_upload_iframe_src = apply_filters('image_upload_iframe_src', "$media_upload_iframe_src&amp;type=image");
+ $image_title = __('Add an Image');
+ $video_upload_iframe_src = apply_filters('video_upload_iframe_src', "$media_upload_iframe_src&amp;type=video");
+ $video_title = __('Add Video');
+ $audio_upload_iframe_src = apply_filters('audio_upload_iframe_src', "$media_upload_iframe_src&amp;type=audio");
+ $audio_title = __('Add Audio');
+ $out = <<<EOF
+
+ <a href="{$image_upload_iframe_src}&amp;TB_iframe=true&amp;height=500&amp;width=640" class="thickbox" title='$image_title'><img src='images/media-button-image.gif' alt='$image_title' /></a>
+ <a href="{$video_upload_iframe_src}&amp;TB_iframe=true&amp;height=500&amp;width=640" class="thickbox" title='$video_title'><img src='images/media-button-video.gif' alt='$video_title' /></a>
+ <a href="{$audio_upload_iframe_src}&amp;TB_iframe=true&amp;height=500&amp;width=640" class="thickbox" title='$audio_title'><img src='images/media-button-music.gif' alt='$audio_title' /></a>
+ <a href="{$media_upload_iframe_src}&amp;TB_iframe=true&amp;height=500&amp;width=640" class="thickbox" title='$media_title'><img src='images/media-button-other.gif' alt='$media_title' /></a>
+
+EOF;
+ printf($context, $out);
+}
+add_action( 'media_buttons', 'media_buttons' );
+
+function media_buttons_head() {
+$siteurl = get_option('siteurl');
+echo "<style type='text/css' media='all'>
+ @import '{$siteurl}/wp-includes/js/thickbox/thickbox.css?1';
+ div#TB_title {
+ background-color: #222222;
+ color: #cfcfcf;
+ }
+ div#TB_title a, div#TB_title a:visited {
+ color: #cfcfcf;
+ }
+</style>\n";
+}
+
+add_action( 'admin_print_scripts', 'media_buttons_head' );
+
+function media_admin_css() {
+ wp_admin_css('css/media');
+}
+
+add_action('media_upload_media', 'media_upload_handler');
+
+function media_upload_form_handler() {
+ check_admin_referer('media-form');
+
+ // Insert media button was clicked
+ if ( !empty($_FILES) ) {
+ // Upload File button was clicked
+
+ $id = media_handle_upload('async-upload', $_REQUEST['post_id']);
+
+ if ( is_wp_error($id) ) {
+ $errors['upload_error'] = $id;
+ $id = false;
+ }
+ }
+
+ if ( !empty($_POST['attachments']) ) foreach ( $_POST['attachments'] as $attachment_id => $attachment ) {
+ $post = $_post = get_post($attachment_id, ARRAY_A);
+ if ( isset($attachment['post_content']) )
+ $post['post_content'] = $attachment['post_content'];
+ if ( isset($attachment['post_title']) )
+ $post['post_title'] = $attachment['post_title'];
+ if ( isset($attachment['post_excerpt']) )
+ $post['post_excerpt'] = $attachment['post_excerpt'];
+
+ $post = apply_filters('attachment_fields_to_save', $post, $attachment);
+
+ if ( isset($post['errors']) ) {
+ $errors[$attachment_id] = $post['errors'];
+ unset($post['errors']);
+ }
+
+ if ( $post != $_post )
+ wp_update_post($post);
+
+ foreach ( get_attachment_taxonomies($post) as $t )
+ if ( isset($attachment[$t]) )
+ wp_set_object_terms($attachment_id, array_map('trim', preg_split('/,+/', $attachment[$t])), $t, false);
+ }
+
+ if ( isset($_POST['insert-gallery']) )
+ return media_send_to_editor('[gallery]');
+
+ if ( isset($_POST['send']) ) {
+ $keys = array_keys($_POST['send']);
+ $send_id = (int) array_shift($keys);
+ $attachment = $_POST['attachments'][$send_id];
+ $html = $attachment['post_title'];
+ if ( !empty($attachment['url']) )
+ $html = "<a href='{$attachment['url']}'>$html</a>";
+ $html = apply_filters('media_send_to_editor', $html, $send_id, $attachment);
+ return media_send_to_editor($html);
+ }
+
+ return $errors;
+}
+
+function media_upload_image() {
+ if ( !empty($_FILES) ) {
+ // Upload File button was clicked
+ $id = media_handle_upload('async-upload', $_REQUEST['post_id']);
+ unset($_FILES);
+ if ( is_wp_error($id) ) {
+ $errors['upload_error'] = $id;
+ $id = false;
+ }
+ }
+
+ if ( !empty($_POST['insertonlybutton']) ) {
+ $src = $_POST['insertonly']['src'];
+ if ( !strpos($src, '://') )
+ $src = "http://$src";
+ $alt = attribute_escape($_POST['insertonly']['alt']);
+ if ( isset($_POST['insertonly']['align']) ) {
+ $align = attribute_escape($_POST['insertonly']['align']);
+ $class = " class='align$align'";
+ }
+ $html = "<img src='$src' alt='$alt'$class />";
+ return media_send_to_editor($html);
+ }
+
+ if ( !empty($_POST) ) {
+ $return = media_upload_form_handler();
+
+ if ( is_string($return) )
+ return $return;
+ if ( is_array($return) )
+ $errors = $return;
+ }
+
+ return wp_iframe( 'media_upload_type_form', 'image', $errors, $id );
+}
+
+function media_upload_audio() {
+ if ( !empty($_FILES) ) {
+ // Upload File button was clicked
+ $id = media_handle_upload('async-upload', $_REQUEST['post_id']);
+ unset($_FILES);
+ if ( is_wp_error($id) ) {
+ $errors['upload_error'] = $id;
+ $id = false;
+ }
+ }
+
+ if ( !empty($_POST['insertonlybutton']) ) {
+ $href = $_POST['insertonly']['href'];
+ if ( !strpos($href, '://') )
+ $href = "http://$href";
+ $title = attribute_escape($_POST['insertonly']['title']);
+ $html = "<a href='$href' >$title</a>";
+ return media_send_to_editor($html);
+ }
+
+ if ( !empty($_POST) ) {
+ $return = media_upload_form_handler();
+
+ if ( is_string($return) )
+ return $return;
+ if ( is_array($return) )
+ $errors = $return;
+ }
+
+ return wp_iframe( 'media_upload_type_form', 'audio', $errors, $id );
+}
+
+function media_upload_video() {
+ if ( !empty($_FILES) ) {
+ // Upload File button was clicked
+ $id = media_handle_upload('async-upload', $_REQUEST['post_id']);
+ unset($_FILES);
+ if ( is_wp_error($id) ) {
+ $errors['upload_error'] = $id;
+ $id = false;
+ }
+ }
+
+ if ( !empty($_POST['insertonlybutton']) ) {
+ $href = $_POST['insertonly']['href'];
+ if ( !strpos($href, '://') )
+ $href = "http://$href";
+ $title = attribute_escape($_POST['insertonly']['title']);
+ $html = "<a href='$href' >$title</a>";
+ return media_send_to_editor($html);
+ }
+
+ if ( !empty($_POST) ) {
+ $return = media_upload_form_handler();
+
+ if ( is_string($return) )
+ return $return;
+ if ( is_array($return) )
+ $errors = $return;
+ }
+
+ return wp_iframe( 'media_upload_type_form', 'video', $errors, $id );
+}
+
+function media_upload_file() {
+ if ( !empty($_FILES) ) {
+ // Upload File button was clicked
+ $id = media_handle_upload('async-upload', $_REQUEST['post_id']);
+ unset($_FILES);
+ if ( is_wp_error($id) ) {
+ $errors['upload_error'] = $id;
+ $id = false;
+ }
+ }
+
+ if ( !empty($_POST['insertonlybutton']) ) {
+ $href = $_POST['insertonly']['href'];
+ if ( !strpos($href, '://') )
+ $href = "http://$href";
+ $title = attribute_escape($_POST['insertonly']['title']);
+ $html = "<a href='$href' >$title</a>";
+ return media_send_to_editor($html);
+ }
+
+ if ( !empty($_POST) ) {
+ $return = media_upload_form_handler();
+
+ if ( is_string($return) )
+ return $return;
+ if ( is_array($return) )
+ $errors = $return;
+ }
+
+ return wp_iframe( 'media_upload_type_form', 'file', $errors, $id );
+}
+
+function media_upload_gallery() {
+ if ( !empty($_POST) ) {
+ $return = media_upload_form_handler();
+
+ if ( is_string($return) )
+ return $return;
+ if ( is_array($return) )
+ $errors = $return;
+ }
+
+ return wp_iframe( 'media_upload_gallery_form', $errors );
+}
+
+function media_upload_library() {
+ if ( !empty($_POST) ) {
+ $return = media_upload_form_handler();
+
+ if ( is_string($return) )
+ return $return;
+ if ( is_array($return) )
+ $errors = $return;
+ }
+
+ return wp_iframe( 'media_upload_library_form', $errors );
+}
+
+function get_attachment_taxonomies($attachment) {
+ if ( is_int( $attachment ) )
+ $attachment = get_post($attachment);
+ else if ( is_array($attachment) )
+ $attachment = (object) $attachment;
+
+ if ( ! is_object($attachment) )
+ return array();
+
+ $filename = basename($attachment->guid);
+
+ $objects = array('attachment');
+
+ if ( false !== strpos($filename, '.') )
+ $objects[] = 'attachment:' . substr($filename, strrpos($filename, '.') + 1);
+ if ( !empty($attachment->post_mime_type) ) {
+ $objects[] = 'attachment:' . $attachment->post_mime_type;
+ if ( false !== strpos($attachment->post_mime_type, '/') )
+ foreach ( explode('/', $attachment->post_mime_type) as $token )
+ if ( !empty($token) )
+ $objects[] = "attachment:$token";
+ }
+
+ $taxonomies = array();
+ foreach ( $objects as $object )
+ if ( $taxes = get_object_taxonomies($object) )
+ $taxonomies = array_merge($taxonomies, $taxes);
+
+ return array_unique($taxonomies);
+}
+
+function image_attachment_fields_to_edit($form_fields, $post) {
+ if ( substr($post->post_mime_type, 0, 5) == 'image' ) {
+ $form_fields['post_title']['required'] = true;
+ $form_fields['post_excerpt']['label'] = __('Description');
+ $form_fields['post_excerpt']['helps'][] = __('Alternate text, e.g. "The Mona Lisa"');
+
+ $form_fields['post_content']['label'] = __('Long Description');
+
+ $thumb = wp_get_attachment_thumb_url($post->ID);
+
+ $form_fields['align'] = array(
+ 'label' => __('Alignment'),
+ 'input' => 'html',
+ 'html' => "
+ <input type='radio' name='attachments[$post->ID][align]' id='image-align-none-$post->ID' value='none' />
+ <label for='image-align-none-$post->ID' class='align image-align-none-label'>" . __('None') . "</label>
+ <input type='radio' name='attachments[$post->ID][align]' id='image-align-left-$post->ID' value='left' />
+ <label for='image-align-left-$post->ID' class='align image-align-left-label'>" . __('Left') . "</label>
+ <input type='radio' name='attachments[$post->ID][align]' id='image-align-center-$post->ID' value='center' />
+ <label for='image-align-center-$post->ID' class='align image-align-center-label'>" . __('Center') . "</label>
+ <input type='radio' name='attachments[$post->ID][align]' id='image-align-right-$post->ID' value='right' />
+ <label for='image-align-right-$post->ID' class='align image-align-right-label'>" . __('Right') . "</label>\n",
+ );
+ $form_fields['image-size'] = array(
+ 'label' => __('Size'),
+ 'input' => 'html',
+ 'html' => "
+ " . ( $thumb ? "<input type='radio' name='attachments[$post->ID][image-size]' id='image-size-thumb-$post->ID' value='thumbnail' />
+ <label for='image-size-thumb-$post->ID'>" . __('Thumbnail') . "</label>
+ " : '' ) . "<input type='radio' name='attachments[$post->ID][image-size]' id='image-size-medium-$post->ID' value='medium' checked='checked' />
+ <label for='image-size-medium-$post->ID'>" . __('Medium') . "</label>
+ <input type='radio' name='attachments[$post->ID][image-size]' id='image-size-full-$post->ID' value='full' />
+ <label for='image-size-full-$post->ID'>" . __('Full size') . "</label>",
+ );
+ }
+ return $form_fields;
+}
+
+add_filter('attachment_fields_to_edit', 'image_attachment_fields_to_edit', 10, 2);
+
+function media_single_attachment_fields_to_edit( $form_fields, $post ) {
+ unset($form_fields['url'], $form_fields['align'], $form_fields['image-size']);
+ return $form_fields;
+}
+
+function image_attachment_fields_to_save($post, $attachment) {
+ if ( substr($post['post_mime_type'], 0, 5) == 'image' ) {
+ if ( strlen(trim($post['post_title'])) == 0 ) {
+ $post['post_title'] = preg_replace('/\.\w+$/', '', basename($post['guid']));
+ $post['errors']['post_title']['errors'][] = __('Empty Title filled from filename.');
+ }
+ }
+
+ return $post;
+}
+
+add_filter('attachment_fields_to_save', 'image_attachment_fields_to_save', 10, 2);
+
+function image_media_send_to_editor($html, $attachment_id, $attachment) {
+ $post =& get_post($attachment_id);
+ if ( substr($post->post_mime_type, 0, 5) == 'image' ) {
+ $url = $attachment['url'];
+
+ if ( isset($attachment['align']) )
+ $align = $attachment['align'];
+ else
+ $align = 'none';
+
+ if ( !empty($attachment['image-size']) )
+ $size = $attachment['image-size'];
+ else
+ $size = 'medium';
+
+ return get_image_send_to_editor($attachment_id, $attachment['post_excerpt'], $attachment['post_title'], $align, $url, $rel, $size);
+ }
+
+ return $html;
+}
+
+add_filter('media_send_to_editor', 'image_media_send_to_editor', 10, 3);
+
+function get_attachment_fields_to_edit($post, $errors = null) {
+ if ( is_int($post) )
+ $post =& get_post($post);
+ if ( is_array($post) )
+ $post = (object) $post;
+
+ $edit_post = sanitize_post($post, 'edit');
+ $file = wp_get_attachment_url($post->ID);
+ $link = get_attachment_link($post->ID);
+
+ $form_fields = array(
+ 'post_title' => array(
+ 'label' => __('Title'),
+ 'value' => $edit_post->post_title,
+ ),
+ 'post_excerpt' => array(
+ 'label' => __('Description'),
+ 'value' => $edit_post->post_excerpt,
+ ),
+ 'post_content' => array(
+ 'label' => __('Long description'),
+ 'value' => $edit_post->post_content,
+ 'input' => 'textarea',
+ ),
+ 'url' => array(
+ 'label' => __('Link URL'),
+ 'input' => 'html',
+ 'html' => "
+ <input type='text' name='attachments[$post->ID][url]' value='" . attribute_escape($file) . "' /><br />
+ <button type='button' class='button url-$post->ID' value=''>" . __('None') . "</button>
+ <button type='button' class='button url-$post->ID' value='" . attribute_escape($file) . "'>" . __('File URL') . "</button>
+ <button type='button' class='button url-$post->ID' value='" . attribute_escape($link) . "'>" . __('Post URL') . "</button>
+ <script type='text/javascript'>
+ jQuery('button.url-$post->ID').bind('click', function(){jQuery(this).siblings('input').val(this.value);});
+ </script>\n",
+ 'helps' => __('Enter a link URL or click above for presets.'),
+ ),
+ );
+
+ foreach ( get_attachment_taxonomies($post) as $taxonomy ) {
+ $t = (array) get_taxonomy($taxonomy);
+ if ( empty($t['label']) )
+ $t['label'] = $taxonomy;
+ if ( empty($t['args']) )
+ $t['args'] = array();
+
+ $terms = get_object_term_cache($post->ID, $taxonomy);
+ if ( empty($terms) )
+ $terms = wp_get_object_terms($post->ID, $taxonomy, $t['args']);
+
+ $values = array();
+
+ foreach ( $terms as $term )
+ $values[] = $term->name;
+ $t['value'] = join(', ', $values);
+
+ $form_fields[$taxonomy] = $t;
+ }
+
+ // Merge default fields with their errors, so any key passed with the error (e.g. 'error', 'helps', 'value') will replace the default
+ // The recursive merge is easily traversed with array casting: foreach( (array) $things as $thing )
+ $form_fields = array_merge_recursive($form_fields, (array) $errors);
+
+ $form_fields = apply_filters('attachment_fields_to_edit', $form_fields, $post);
+
+ return $form_fields;
+}
+
+function get_media_items( $post_id, $errors ) {
+ if ( $post_id && $post = get_post($post_id) ) {
+ if ( $post->post_type == 'attachment' )
+ $attachments = array($post->ID => $post);
+ else
+ $attachments = get_children("post_parent=$post_id&post_type=attachment&orderby=menu_order ASC, ID&order=DESC");
+ } else {
+ if ( is_array($GLOBALS['wp_the_query']->posts) )
+ foreach ( $GLOBALS['wp_the_query']->posts as $attachment )
+ $attachments[$attachment->ID] = $attachment;
+ }
+
+ if ( empty($attachments) )
+ return '';
+
+ foreach ( $attachments as $id => $attachment )
+ if ( $item = get_media_item( $id, array( 'errors' => isset($errors[$id]) ? $errors[$id] : null) ) )
+ $output .= "\n<div id='media-item-$id' class='media-item child-of-$attachment->post_parent preloaded'><div id='media-upload-error-$id'></div><div class='filename'></div><div class='progress'><div class='bar'></div></div>$item<div class='progress clickmask'></div>\n</div>";
+
+ return $output;
+}
+
+function get_media_item( $attachment_id, $args = null ) {
+ $default_args = array( 'errors' => null, 'send' => true, 'delete' => true, 'toggle' => true );
+ $args = wp_parse_args( $args, $default_args );
+ extract( $args, EXTR_SKIP );
+
+ global $post_mime_types;
+ if ( ( $attachment_id = intval($attachment_id) ) && $thumb_url = get_attachment_icon_src( $attachment_id ) )
+ $thumb_url = $thumb_url[0];
+ else
+ return false;
+
+ $title_label = __('Title');
+ $description_label = __('Description');
+ $tags_label = __('Tags');
+
+ $toggle_on = __('Show');
+ $toggle_off = __('Hide');
+
+ $post = get_post($attachment_id);
+
+ $filename = basename($post->guid);
+ $title = attribute_escape($post->post_title);
+ $description = attribute_escape($post->post_content);
+ if ( $_tags = get_the_tags($attachment_id) ) {
+ foreach ( $_tags as $tag )
+ $tags[] = $tag->name;
+ $tags = attribute_escape(join(', ', $tags));
+ }
+
+ if ( isset($post_mime_types) ) {
+ $keys = array_keys(wp_match_mime_types(array_keys($post_mime_types), $post->post_mime_type));
+ $type = array_shift($keys);
+ $type = "<input type='hidden' id='type-of-$attachment_id' value='$type' />";
+ }
+
+ $form_fields = get_attachment_fields_to_edit($post, $errors);
+
+ if ( $toggle ) {
+ $class = empty($errors) ? 'startclosed' : 'startopen';
+ $toggle_links = "
+ <a class='toggle describe-toggle-on' href='#'>$toggle_on</a>
+ <a class='toggle describe-toggle-off' href='#'>$toggle_off</a>";
+ } else {
+ $class = 'form-table';
+ $toggle_links = '';
+ }
+
+ $item = "
+ $type
+ $toggle_links
+ <div class='filename new'>$filename</div>
+ <table class='slidetoggle describe $class'>
+ <tbody class='media-item-info'>
+ <tr>
+ <td class='A1B1' rowspan='4'><img class='thumbnail' src='$thumb_url' alt='' /></td>
+ <td>$filename</td>
+ </tr>
+ <td>$post->post_mime_type</td></tr>
+ <tr><td>" . mysql2date($post->post_date, get_option('time_format')) . "</td></tr>
+ <tr><td>" . apply_filters('media_meta', '', $post) . "</tr></td>
+ </tbody>
+ <tbody>\n";
+
+ $defaults = array(
+ 'input' => 'text',
+ 'required' => false,
+ 'value' => '',
+ 'extra_rows' => array(),
+ );
+
+ $delete_href = wp_nonce_url("post.php?action=delete-post&amp;post=$attachment_id", 'delete-post_' . $attachment_id);
+ if ( $send )
+ $send = "<button type='submit' class='button' value='1' name='send[$attachment_id]'>" . __('Insert into Post') . '</button>';
+ if ( $delete )
+ $delete = "<a href='$delete_href' id='del[$attachment_id]' disabled='disabled' class='delete'>" . __('Delete') . "</button>";
+ if ( ( $send || $delete ) && !isset($form_fields['buttons']) )
+ $form_fields['buttons'] = array('tr' => "\t\t<tr class='submit'><td></td><td class='savesend'>$send $delete</td></tr>\n");
+
+ $hidden_fields = array();
+
+ foreach ( $form_fields as $id => $field ) {
+ if ( $id{0} == '_' )
+ continue;
+
+ if ( !empty($field['tr']) ) {
+ $item .= $field['tr'];
+ continue;
+ }
+
+ $field = array_merge($defaults, $field);
+ $name = "attachments[$attachment_id][$id]";
+
+ if ( $field['input'] == 'hidden' ) {
+ $hidden_fields[$name] = $field['value'];
+ continue;
+ }
+
+ $required = $field['required'] ? '<abbr title="required" class="required">*</abbr>' : '';
+ $class = $id;
+ $class .= $field['required'] ? ' form-required' : '';
+
+ $item .= "\t\t<tr class='$class'>\n\t\t\t<th valign='top' scope='row' class='label'><label for='$name'><span class='alignleft'>{$field['label']}</span><span class='alignright'>$required</span><br class='clear' /></label></th>\n\t\t\t<td class='field'>";
+ if ( !empty($field[$field['input']]) )
+ $item .= $field[$field['input']];
+ elseif ( $field['input'] == 'textarea' ) {
+ $item .= "<textarea type='text' id='$name' name='$name'>" . wp_specialchars($field['value'], 1) . "</textarea>";
+ } else {
+ $item .= "<input type='text' id='$name' name='$name' value='" . wp_specialchars($field['value'], 1) . "' />";
+ }
+ if ( !empty($field['helps']) )
+ $item .= "<p class='help'>" . join( "</p>\n<p class='help'>", array_unique((array) $field['helps']) ) . '</p>';
+ $item .= "</td>\n\t\t</tr>\n";
+
+ $extra_rows = array();
+
+ if ( !empty($field['errors']) )
+ foreach ( array_unique((array) $field['errors']) as $error )
+ $extra_rows['error'][] = $error;
+
+ if ( !empty($field['extra_rows']) )
+ foreach ( $field['extra_rows'] as $class => $rows )
+ foreach ( (array) $rows as $html )
+ $extra_rows[$class][] = $html;
+
+ foreach ( $extra_rows as $class => $rows )
+ foreach ( $rows as $html )
+ $item .= "\t\t<tr><td></td><td class='$class'>$html</td></tr>\n";
+ }
+
+ if ( !empty($form_fields['_final']) )
+ $item .= "\t\t<tr class='final'><td colspan='2'>{$form_fields['_final']}</td></tr>\n";
+ $item .= "\t</table>\n";
+
+ foreach ( $hidden_fields as $name => $value )
+ $item .= "\t<input type='hidden' name='$name' id='$name' value='" . wp_specialchars($value, 1) . "' />\n";
+
+ return $item;
+}
+
+function media_upload_header() {
+ ?>
+ <script type="text/javascript">post_id = <?php echo intval($_REQUEST['post_id']); ?>;</script>
+ <div id="media-upload-header">
+ <?php the_media_upload_tabs(); ?>
+ </div>
+ <?php
+}
+
+function media_upload_form( $errors = null ) {
+ global $type, $tab;
+
+ $flash_action_url = get_option('siteurl') . "/wp-admin/async-upload.php";
+
+ $post_id = intval($_REQUEST['post_id']);
+
+?>
+<input type='hidden' name='post_id' value='<?php echo $post_id; ?>' />
+<div id="media-upload-error">
+<?php if (isset($errors['upload_error']) && is_wp_error($errors['upload_error'])) { ?>
+ <?php echo $errors['upload_error']->get_error_message(); ?>
+<?php } ?>
+</div>
+<script type="text/javascript">
+<!--
+jQuery(function($){
+ swfu = new SWFUpload({
+ upload_url : "<?php echo attribute_escape( $flash_action_url ); ?>",
+ flash_url : "<?php echo get_option('siteurl').'/wp-includes/js/swfupload/swfupload_f9.swf'; ?>",
+ file_post_name: "async-upload",
+ file_types: "*.*",
+ post_params : {
+ "post_id" : "<?php echo $post_id; ?>",
+ "auth_cookie" : "<?php echo $_COOKIE[AUTH_COOKIE]; ?>",
+ "type" : "<?php echo $type; ?>",
+ "tab" : "<?php echo $tab; ?>"
+ },
+ file_size_limit : "<?php echo wp_max_upload_size(); ?>b",
+ swfupload_element_id : "flash-upload-ui", // id of the element displayed when swfupload is available
+ degraded_element_id : "html-upload-ui", // when swfupload is unavailable
+ swfupload_loaded_handler : uploadLoaded,
+ file_dialog_start_handler : fileDialogStart,
+ file_queued_handler : fileQueued,
+ upload_start_handler : uploadStart,
+ upload_progress_handler : uploadProgress,
+ upload_error_handler : uploadError,
+ upload_success_handler : uploadSuccess,
+ upload_complete_handler : uploadComplete,
+ file_queue_error_handler : fileQueueError,
+ file_dialog_complete_handler : fileDialogComplete,
+
+ debug: false,
+ });
+ $("#flash-browse-button").bind( "click", function(){swfu.selectFiles();});
+});
+//-->
+</script>
+
+
+<div id="flash-upload-ui">
+ <p><input id="flash-browse-button" type="button" value="<?php _e('Choose files to upload'); ?>" class="button" /></p>
+ <p><?php _e('After a file has been uploaded, you can add titles and descriptions.'); ?></p>
+</div>
+
+<div id="html-upload-ui">
+ <p>
+ <input type="file" name="async-upload" id="async-upload" /> <input type="submit" class="button" value="<?php echo attribute_escape(__('Upload')); ?>" /> <a href="#" onClick="return top.tb_remove();"><?php _e('Cancel'); ?></a>
+ </p>
+ <input type="hidden" name="post_id" id="post_id" value="<?php echo $post_id; ?>" />
+ <br style="clear:both" />
+</div>
+<?php
+}
+
+function media_upload_type_form($type = 'file', $errors = null, $id = null) {
+ media_upload_header();
+
+ $post_id = intval($_REQUEST['post_id']);
+
+ $form_action_url = get_option('siteurl') . "/wp-admin/media-upload.php?type=$type&tab=type&post_id=$post_id";
+
+ $callback = "type_form_$type";
+?>
+
+<form enctype="multipart/form-data" method="post" action="<?php echo attribute_escape($form_action_url); ?>" class="media-upload-form type-form" id="<?php echo $type; ?>-form">
+<input type="hidden" name="post_id" id="post_id" value="<?php echo $post_id; ?>" />
+<?php wp_nonce_field('media-form'); ?>
+<h3><?php _e('From Computer'); ?></h3>
+<?php media_upload_form( $errors ); ?>
+
+<script type="text/javascript">
+<!--
+jQuery(function($){
+ var preloaded = $(".media-item.preloaded");
+ if ( preloaded.length > 0 ) {
+ preloaded.each(function(){prepareMediaItem({id:this.id.replace(/[^0-9]/g, '')},'');});
+ }
+ updateMediaForm();
+});
+-->
+</script>
+<?php if ( $id && !is_wp_error($id) ) : ?>
+<div id="media-items">
+<?php echo get_media_items( $id, $errors ); ?>
+</div>
+<input type="submit" class="button savebutton" name="save" value="<?php _e('Save all changes'); ?>" />
+
+<?php elseif ( is_callable($callback) ) : ?>
+
+<div class="media-blank">
+<p style="text-align:center"><?php _e('&mdash; OR &mdash;'); ?></p>
+<h3><?php _e('From URL'); ?></h3>
+</div>
+
+<div id="media-items">
+<div class="media-item media-blank">
+<?php echo call_user_func($callback); ?>
+</div>
+</div>
+<input type="submit" class="button savebutton" name="save" value="<?php _e('Save all changes'); ?>" />
+<?php
+ endif;
+}
+
+function media_upload_gallery_form($errors) {
+ media_upload_header();
+
+ $post_id = intval($_REQUEST['post_id']);
+
+ $form_action_url = get_option('siteurl') . "/wp-admin/media-upload.php?type={$GLOBALS['type']}&tab=gallery&post_id=$post_id";
+
+?>
+
+<script type="text/javascript">
+<!--
+jQuery(function($){
+ var preloaded = $(".media-item.preloaded");
+ if ( preloaded.length > 0 ) {
+ preloaded.each(function(){prepareMediaItem({id:this.id.replace(/[^0-9]/g, '')},'');});
+ updateMediaForm();
+ }
+});
+-->
+</script>
+
+<form enctype="multipart/form-data" method="post" action="<?php echo attribute_escape($form_action_url); ?>" class="media-upload-form" id="gallery-form">
+<?php wp_nonce_field('media-form'); ?>
+<?php //media_upload_form( $errors ); ?>
+
+<div id="media-items">
+<?php echo get_media_items($post_id, $errors); ?>
+</div>
+<input type="submit" class="button savebutton" name="save" value="<?php _e('Save all changes'); ?>" />
+<input type="submit" class="button insert-gallery" name="insert-gallery" value="<?php _e('Insert gallery into post'); ?>" />
+<input type="hidden" name="post_id" id="post_id" value="<?php echo $post_id; ?>" />
+<input type="hidden" name="type" value="<?php echo $GLOBALS['type']; ?>" />
+<input type="hidden" name="tab" value="<?php echo $GLOBALS['tab']; ?>" />
+</form>
+<?php
+}
+
+function media_upload_library_form($errors) {
+ global $wpdb, $wp_query, $wp_locale, $type, $tab, $post_mime_types;
+
+ media_upload_header();
+
+ $post_id = intval($_REQUEST['post_id']);
+
+ $form_action_url = get_option('siteurl') . "/wp-admin/media-upload.php?type={$GLOBALS['type']}&tab=library&post_id=$post_id";
+
+ $_GET['paged'] = intval($_GET['paged']);
+ if ( $_GET['paged'] < 1 )
+ $_GET['paged'] = 1;
+ $start = ( $_GET['paged'] - 1 ) * 10;
+ if ( $start < 1 )
+ $start = 0;
+ add_filter( 'post_limits', $limit_filter = create_function( '$a', "return 'LIMIT $start, 10';" ) );
+
+ list($post_mime_types, $avail_post_mime_types) = wp_edit_attachments_query();
+
+?>
+
+<form id="filter" action="" method="get">
+<input type="hidden" name="type" value="<?php echo $type; ?>" />
+<input type="hidden" name="tab" value="<?php echo $tab; ?>" />
+<input type="hidden" name="post_id" value="<?php echo $post_id; ?>" />
+<input type="hidden" name="post_mime_type" value="<?php echo wp_specialchars($_GET['post_mime_type'], true); ?>" />
+
+<div id="search-filter">
+ <input type="text" id="post-search-input" name="s" value="<?php the_search_query(); ?>" />
+ <input type="submit" value="<?php _e( 'Search Media' ); ?>" class="button" />
+</div>
+
+<p>
+<ul class="subsubsub">
+<?php
+$type_links = array();
+$_num_posts = (array) wp_count_attachments();
+$matches = wp_match_mime_types(array_keys($post_mime_types), array_keys($_num_posts));
+foreach ( $matches as $_type => $reals )
+ foreach ( $reals as $real )
+ $num_posts[$_type] += $_num_posts[$real];
+$class = empty($_GET['post_mime_type']) ? ' class="current"' : '';
+$type_links[] = "<li><a href='" . remove_query_arg(array('post_mime_type', 'paged', 'm')) . "'$class>".__('All Types')."</a>";
+foreach ( $post_mime_types as $mime_type => $label ) {
+ $class = '';
+
+ if ( !wp_match_mime_types($mime_type, $avail_post_mime_types) )
+ continue;
+
+ if ( wp_match_mime_types($mime_type, $_GET['post_mime_type']) )
+ $class = ' class="current"';
+
+ $type_links[] = "<li><a href='" . add_query_arg(array('post_mime_type'=>$mime_type, 'paged'=>false)) . "'$class>" . sprintf($label[2], "<span id='$mime_type-counter'>{$num_posts[$mime_type]}</span>") . '</a>';
+}
+echo implode(' | </li>', $type_links) . '</li>';
+unset($type_links);
+?>
+</ul>
+</p>
+
+<div class="tablenav">
+
+<?php
+$page_links = paginate_links( array(
+ 'base' => add_query_arg( 'paged', '%#%' ),
+ 'format' => '',
+ 'total' => ceil($wp_query->found_posts / 10),
+ 'current' => $_GET['paged']
+));
+
+if ( $page_links )
+ echo "<div class='tablenav-pages'>$page_links</div>";
+?>
+
+<div style="float: left">
+<?php
+
+$arc_query = "SELECT DISTINCT YEAR(post_date) AS yyear, MONTH(post_date) AS mmonth FROM $wpdb->posts WHERE post_type = 'attachment' ORDER BY post_date DESC";
+
+$arc_result = $wpdb->get_results( $arc_query );
+
+$month_count = count($arc_result);
+
+if ( $month_count && !( 1 == $month_count && 0 == $arc_result[0]->mmonth ) ) { ?>
+<select name='m'>
+<option<?php selected( @$_GET['m'], 0 ); ?> value='0'><?php _e('Show all dates'); ?></option>
+<?php
+foreach ($arc_result as $arc_row) {
+ if ( $arc_row->yyear == 0 )
+ continue;
+ $arc_row->mmonth = zeroise( $arc_row->mmonth, 2 );
+
+ if ( $arc_row->yyear . $arc_row->mmonth == $_GET['m'] )
+ $default = ' selected="selected"';
+ else
+ $default = '';
+
+ echo "<option$default value='$arc_row->yyear$arc_row->mmonth'>";
+ echo $wp_locale->get_month($arc_row->mmonth) . " $arc_row->yyear";
+ echo "</option>\n";
+}
+?>
+</select>
+<?php } ?>
+
+<input type="submit" id="post-query-submit" value="<?php _e('Filter &#187;'); ?>" class="button-secondary" />
+
+</div>
+
+<br style="clear:both;" />
+</div>
+</form>
+
+<form enctype="multipart/form-data" method="post" action="<?php echo attribute_escape($form_action_url); ?>" class="media-upload-form" id="library-form">
+
+<?php wp_nonce_field('media-form'); ?>
+<?php //media_upload_form( $errors ); ?>
+
+<script type="text/javascript">
+<!--
+jQuery(function($){
+ var preloaded = $(".media-item.preloaded");
+ if ( preloaded.length > 0 ) {
+ preloaded.each(function(){prepareMediaItem({id:this.id.replace(/[^0-9]/g, '')},'');});
+ updateMediaForm();
+ }
+});
+-->
+</script>
+
+<div id="media-items">
+<?php echo get_media_items(null, $errors); ?>
+</div>
+<input type="submit" class="button savebutton" name="save" value="<?php _e('Save all changes'); ?>" />
+<input type="hidden" name="post_id" id="post_id" value="<?php echo $post_id; ?>" />
+</form>
+<?php
+}
+
+function type_form_image() {
+ return '
+ <table class="describe"><tbody>
+ <tr>
+ <th valign="top" scope="row" class="label">
+ <span class="alignleft"><label for="insertonly[src]">' . __('Image URL') . '</label></span>
+ <span class="alignright"><abbr title="required" class="required">*</abbr></span>
+ </th>
+ <td class="field"><input id="insertonly[src]" name="insertonly[src]" value="" type="text"></td>
+ </tr>
+ <tr>
+ <th valign="top" scope="row" class="label">
+ <span class="alignleft"><label for="insertonly[alt]">' . __('Description') . '</label></span>
+ <span class="alignright"><abbr title="required">*</abbr></span>
+ </th>
+ <td class="field"><input id="insertonly[alt]" name="insertonly[alt]" value="" type="text"></td>
+ </tr>
+ <tr><td></td><td class="help">' . __('Alternate text, e.g. "The Mona Lisa"') . '</td></tr>
+ <tr class="align">
+ <th valign="top" scope="row" class="label"><label for="insertonly[align]">' . __('Alignment') . '</label></th>
+ <td class="field">
+ <input name="insertonly[align]" id="image-align-none-0" value="none" type="radio">
+ <label for="image-align-none-0" class="align image-align-none-label">' . __('None') . '</label>
+ <input name="insertonly[align]" id="image-align-left-0" value="left" type="radio">
+ <label for="image-align-left-0" class="align image-align-left-label">' . __('Left') . '</label>
+ <input name="insertonly[align]" id="image-align-center-0" value="center" type="radio">
+ <label for="image-align-center-0" class="align image-align-center-label">' . __('Center') . '</label>
+ <input name="insertonly[align]" id="image-align-right-0" value="right" type="radio">
+ <label for="image-align-right-0" class="align image-align-right-label">' . __('Right') . '</label>
+ </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>
+ <input type="submit" class="button" name="insertonlybutton" value="' . attribute_escape(__('Insert into Post')) . '" />
+ </td>
+ </tr>
+ </tbody></table>
+';
+}
+
+function type_form_audio() {
+ return '
+ <table class="describe"><tbody>
+ <tr>
+ <th valign="top" scope="row" class="label">
+ <span class="alignleft"><label for="insertonly[href]">' . __('Audio File URL') . '</label></span>
+ <span class="alignright"><abbr title="required" class="required">*</abbr></span>
+ </th>
+ <td class="field"><input id="insertonly[href]" name="insertonly[href]" value="" type="text"></td>
+ </tr>
+ <tr>
+ <th valign="top" scope="row" class="label">
+ <span class="alignleft"><label for="insertonly[title]">' . __('Title') . '</label></span>
+ <span class="alignright"><abbr title="required" class="required">*</abbr></span>
+ </th>
+ <td class="field"><input id="insertonly[title]" name="insertonly[title]" value="" type="text"></td>
+ </tr>
+ <tr><td></td><td class="help">' . __('Link text, e.g. "Still Alive by Jonathan Coulton"') . '</td></tr>
+ <tr>
+ <td></td>
+ <td>
+ <input type="submit" class="button" name="insertonlybutton" value="' . attribute_escape(__('Insert into Post')) . '" />
+ </td>
+ </tr>
+ </tbody></table>
+';
+}
+
+function type_form_video() {
+ return '
+ <table class="describe"><tbody>
+ <tr>
+ <th valign="top" scope="row" class="label">
+ <span class="alignleft"><label for="insertonly[href]">' . __('Video URL') . '</label></span>
+ <span class="alignright"><abbr title="required" class="required">*</abbr></span>
+ </th>
+ <td class="field"><input id="insertonly[href]" name="insertonly[href]" value="" type="text"></td>
+ </tr>
+ <tr>
+ <th valign="top" scope="row" class="label">
+ <span class="alignleft"><label for="insertonly[title]">' . __('Title') . '</label></span>
+ <span class="alignright"><abbr title="required" class="required">*</abbr></span>
+ </th>
+ <td class="field"><input id="insertonly[title]" name="insertonly[title]" value="" type="text"></td>
+ </tr>
+ <tr><td></td><td class="help">' . __('Link text, e.g. "Lucy on YouTube"') . '</td></tr>
+ <tr>
+ <td></td>
+ <td>
+ <input type="submit" class="button" name="insertonlybutton" value="' . attribute_escape(__('Insert into Post')) . '" />
+ </td>
+ </tr>
+ </tbody></table>
+';
+}
+
+function type_form_file() {
+ return '
+ <table class="describe"><tbody>
+ <tr>
+ <th valign="top" scope="row" class="label">
+ <span class="alignleft"><label for="insertonly[href]">' . __('URL') . '</label></span>
+ <span class="alignright"><abbr title="required" class="required">*</abbr></span>
+ </th>
+ <td class="field"><input id="insertonly[href]" name="insertonly[href]" value="" type="text"></td>
+ </tr>
+ <tr>
+ <th valign="top" scope="row" class="label">
+ <span class="alignleft"><label for="insertonly[title]">' . __('Title') . '</label></span>
+ <span class="alignright"><abbr title="required" class="required">*</abbr></span>
+ </th>
+ <td class="field"><input id="insertonly[title]" name="insertonly[title]" value="" type="text"></td>
+ </tr>
+ <tr><td></td><td class="help">' . __('Link text, e.g. "Ransom Demands (PDF)"') . '</td></tr>
+ <tr>
+ <td></td>
+ <td>
+ <input type="submit" class="button" name="insertonlybutton" value="' . attribute_escape(__('Insert into Post')) . '" />
+ </td>
+ </tr>
+ </tbody></table>
+';
+}
+
+add_filter('async_upload_image', 'get_media_item', 10, 2);
+add_filter('async_upload_audio', 'get_media_item', 10, 2);
+add_filter('async_upload_video', 'get_media_item', 10, 2);
+add_filter('async_upload_file', 'get_media_item', 10, 2);
+
+add_action('media_upload_image', 'media_upload_image');
+add_action('media_upload_audio', 'media_upload_audio');
+add_action('media_upload_video', 'media_upload_video');
+add_action('media_upload_file', 'media_upload_file');
+add_action('admin_head_media_upload_type_form', 'media_admin_css');
+
+add_filter('media_upload_gallery', 'media_upload_gallery');
+add_action('admin_head_media_upload_gallery_form', 'media_admin_css');
+
+add_filter('media_upload_library', 'media_upload_library');
+add_action('admin_head_media_upload_library_form', 'media_admin_css');
+
+
+// Any 'attachment' taxonomy will be included in the description input form for the multi uploader
+// Example:
+/*
+register_taxonomy(
+ 'image_people',
+ 'attachment:image',
+ array(
+ 'label' => __('People'),
+ 'template' => __('People: %l'),
+ 'helps' => __('Left to right, top to bottom.'),
+ 'sort' => true,
+ 'args' => array(
+ 'orderby' => 'term_order'
+ )
+ )
+);
+*/
+/*
+register_taxonomy('movie_director', 'attachment:video', array('label'=>__('Directors'), 'template'=>__('Directed by %l.')));
+register_taxonomy('movie_producer', 'attachment:video', array('label'=>__('Producers'), 'template'=>__('Produced by %l.')));
+register_taxonomy('movie_screenwriter', 'attachment:video', array('label'=>__('Screenwriter'), 'template'=>__('Screenplay by %l.')));
+register_taxonomy('movie_actor', 'attachment:video', array('label'=>__('Cast'), 'template'=>array(__('Cast: %l.')));
+register_taxonomy('movie_crew', 'attachment:video', array('label'=>__('Crew'), 'template'=>array(__('Crew: %l.')));
+*/
+
+?>
diff --git a/wp-admin/includes/widgets.php b/wp-admin/includes/widgets.php
new file mode 100644
index 0000000..4523b24
--- /dev/null
+++ b/wp-admin/includes/widgets.php
@@ -0,0 +1,269 @@
+<?php
+
+// $_search is unsanitized
+function wp_list_widgets( $show = 'all', $_search = false ) {
+ global $wp_registered_widgets, $sidebars_widgets;
+ if ( $_search ) {
+ // sanitize
+ $search = preg_replace( '/[^\w\s]/', '', $_search );
+ // array of terms
+ $search_terms = preg_split( '/[\s]/', $search, -1, PREG_SPLIT_NO_EMPTY );
+ } else {
+ $search_terms = array();
+ }
+
+ if ( !in_array( $show, array( 'all', 'unused', 'used' ) ) )
+ $show = 'all';
+?>
+
+ <ul id='widget-list'>
+ <?php
+ $no_widgets_shown = true;
+ $already_shown = array();
+ foreach ( $wp_registered_widgets as $name => $widget ) :
+ if ( in_array( $widget['callback'], $already_shown ) ) // We already showed this multi-widget
+ continue;
+
+ if ( $search_terms ) {
+ $hit = false;
+ // Simple case-insensitive search. Boolean OR.
+ $search_text = preg_replace( '/[^\w]/', '', $widget['name'] );
+ if ( isset($widget['description']) )
+ $search_text .= preg_replace( '/[^\w]/', '', $widget['description'] );
+
+ foreach ( $search_terms as $search_term ) {
+ if ( stristr( $search_text, $search_term ) ) {
+ $hit = true;
+ break;
+ }
+ }
+ if ( !$hit )
+ continue;
+ }
+
+ $sidebar = is_active_widget( $widget['callback'], $widget['id'] );
+
+ if ( ( 'unused' == $show && $sidebar ) || ( 'used' == $show && !$sidebar ) )
+ continue;
+
+ ob_start();
+ $args = wp_list_widget_controls_dynamic_sidebar( array( 0 => array( 'widget_id' => $widget['id'], 'widget_name' => $widget['name'], '_display' => 'template' ) ) );
+ $sidebar_args = call_user_func_array( 'wp_widget_control', $args );
+ $widget_control_template = ob_get_contents();
+ ob_end_clean();
+
+ $is_multi = false !== strpos( $widget_control_template, '%i%' );
+ if ( !$sidebar || $is_multi ) {
+ if ( $is_multi )
+ $already_shown[] = $widget['callback']; // it's a multi-widget. We only need to show it in the list once.
+ $action = 'add';
+ $add_url = wp_nonce_url( add_query_arg( array(
+ 'sidebar' => $sidebar,
+ 'add' => $widget['id'],
+ 'key' => false,
+ 'edit' => false
+ ) ), "add-widget_$widget[id]" );
+ } else {
+ $action = 'edit';
+ $edit_url = clean_url( add_query_arg( array(
+ 'sidebar' => $sidebar,
+ 'edit' => $widget['id'],
+ 'key' => array_search( $widget['id'], $sidebars_widgets[$sidebar] ),
+ ) ) );
+
+ $widget_control_template = '<textarea rows="1" cols="1">' . htmlspecialchars( $widget_control_template ) . '</textarea>';
+ }
+
+ $widget_control_template = $sidebar_args['before_widget'] . $widget_control_template . $sidebar_args['after_widget'];
+
+ $no_widgets_shown = false;
+
+ ?>
+
+ <li id="widget-list-item-<?php echo attribute_escape( $widget['id'] ); ?>" class="widget-list-item">
+ <h4 class="widget-title widget-draggable">
+
+ <?php echo wp_specialchars( $widget['name'] ); ?>
+
+ <?php if ( 'add' == $action ) : ?>
+
+ <a class="widget-action widget-control-add" href="<?php echo $add_url; ?>"><?php _e( 'Add' ); ?></a>
+
+ <?php elseif ( 'edit' == $action ) :
+ // We echo a hidden edit link for the sake of the JS. Edit links are shown (needlessly?) after a widget is added.
+ ?>
+
+ <a class="widget-action widget-control-edit" href="<?php echo $edit_url; ?>" style="display: none;"><?php _e( 'Edit' ); ?></a>
+
+ <?php endif; ?>
+
+ </h4>
+
+
+ <ul id="widget-control-info-<?php echo $widget['id']; ?>" class="widget-control-info">
+
+ <?php echo $widget_control_template; ?>
+
+ </ul>
+
+ <?php if ( 'add' == $action ) : ?>
+ <?php endif; ?>
+
+ <div class="widget-description">
+ <?php echo ( $widget_description = wp_widget_description( $widget['id'] ) ) ? $widget_description : '&nbsp;'; ?>
+ </div>
+
+ <br class="clear" />
+
+ </li>
+
+ <?php endforeach; if ( $no_widgets_shown ) : ?>
+
+ <li><?php _e( 'No matching widgets' ); ?></li>
+
+ <?php endif; ?>
+
+ </ul>
+<?php
+}
+
+
+
+function wp_list_widget_controls( $sidebar ) {
+ add_filter( 'dynamic_sidebar_params', 'wp_list_widget_controls_dynamic_sidebar' );
+?>
+
+ <ul class="widget-control-list">
+
+ <?php if ( !dynamic_sidebar( $sidebar ) ) echo "<li />"; ?>
+
+ </ul>
+
+<?php
+}
+
+
+function wp_list_widget_controls_dynamic_sidebar( $params ) {
+ global $wp_registered_widgets;
+ static $i = 0;
+ $i++;
+
+ $widget_id = $params[0]['widget_id'];
+
+ $params[0]['before_widget'] = "<li id='widget-list-control-item-$i-$widget_id' class='widget-list-control-item widget-sortable'>\n";
+ $params[0]['after_widget'] = "</li>";
+ $params[0]['before_title'] = "%BEG_OF_TITLE%";
+ $params[0]['after_title'] = "%END_OF_TITLE%";
+ if ( is_callable( $wp_registered_widgets[$widget_id]['callback'] ) ) {
+ $wp_registered_widgets[$widget_id]['_callback'] = $wp_registered_widgets[$widget_id]['callback'];
+ $wp_registered_widgets[$widget_id]['callback'] = 'wp_widget_control';
+ }
+ return $params;
+}
+
+/*
+ * Meta widget used to display the control form for a widget. Called from dynamic_sidebar()
+ */
+function wp_widget_control( $sidebar_args ) {
+ global $wp_registered_widgets, $wp_registered_widget_controls, $sidebars_widgets, $edit_widget;
+ $widget_id = $sidebar_args['widget_id'];
+ $sidebar_id = isset($sidebar_args['id']) ? $sidebar_args['id'] : false;
+
+ $control = $wp_registered_widget_controls[$widget_id];
+ $widget = $wp_registered_widgets[$widget_id];
+
+ $key = $sidebar_id ? array_search( $widget_id, $sidebars_widgets[$sidebar_id] ) : 'no-key'; // position of widget in sidebar
+
+ $edit = $edit_widget > 0 && $key && $edit_widget == $key; // (bool) are we currently editing this widget
+
+ $id_format = $widget['id'];
+ // We aren't showing a widget control, we're outputing a template for a mult-widget control
+ if ( 'template' == $sidebar_args['_display'] && isset($control['params'][0]['number']) ) {
+ // number == -1 implies a template where id numbers are replaced by a generic '%i%'
+ $control['params'][0]['number'] = -1;
+ // if given, id_base means widget id's should be constructed like {$id_base}-{$id_number}
+ if ( isset($control['id_base']) )
+ $id_format = $control['id_base'] . '-%i%';
+ }
+
+ $widget_title = '';
+ // We grab the normal widget output to find the widget's title
+ if ( is_callable( $widget['_callback'] ) ) {
+ ob_start();
+ $args = func_get_args();
+ call_user_func_array( $widget['_callback'], $args );
+ $widget_title = ob_get_clean();
+ $widget_title = wp_widget_control_ob_filter( $widget_title );
+ }
+ $wp_registered_widgets[$widget_id]['callback'] = $wp_registered_widgets[$widget_id]['_callback'];
+ unset($wp_registered_widgets[$widget_id]['_callback']);
+
+ if ( $widget_title )
+ $widget_title = sprintf( _c('%1$s: %2$s|widget_admin_title' ), $sidebar_args['widget_name'], $widget_title );
+ else
+ $widget_title = wp_specialchars( strip_tags( $sidebar_args['widget_name'] ) );
+
+
+ if ( empty($sidebar_args['_display']) || 'template' != $sidebar_args['_display'] )
+ echo $sidebar_args['before_widget'];
+?>
+ <h4 class="widget-title"><?php echo $widget_title ?>
+
+ <?php if ( $edit ) : ?>
+
+ <a class="widget-action widget-control-edit" href="<?php echo remove_query_arg( array( 'edit', 'key' ) ); ?>"><?php _e('Cancel'); ?></a>
+
+ <?php else : ?>
+
+ <a class="widget-action widget-control-edit" href="<?php echo clean_url( add_query_arg( array( 'edit' => $id_format, 'key' => $key ) ) ); ?>"><?php _e('Edit'); ?></a>
+
+ <?php endif; ?>
+
+ </h4>
+
+ <div class="widget-control"<?php if ( $edit ) echo ' style="display: block;"'; ?>>
+
+ <?php
+ if ( $control )
+ call_user_func_array( $control['callback'], $control['params'] );
+ else
+ echo '<p>' . __('There are no options for this widget.') . '</p>';
+ ?>
+
+ <input type="hidden" name="widget-id[]" value="<?php echo $id_format; ?>" />
+ <input type="hidden" class="widget-width" value="<?php echo $control['width']; ?>" />
+
+ <div class="widget-control-actions">
+
+ <?php if ( $control ) : ?>
+
+ <a class="widget-action widget-control-save wp-no-js-hidden edit alignleft" href="#save:<?php echo $id_format; ?>"><?php _e('Change'); ?></a>
+
+ <?php endif; ?>
+
+ <a class="widget-action widget-control-remove delete alignright" href="<?php echo clean_url( add_query_arg( array( 'remove' => $id_format, 'key' => $key ), wp_nonce_url( null, "remove-widget_$widget[id]" ) ) ); ?>"><?php _e('Remove'); ?></a>
+ <br class="clear" />
+ </div>
+ </div>
+<?php
+ if ( empty($sidebar_args['_display']) || 'template' != $sidebar_args['_display'] )
+ echo $sidebar_args['after_widget'];
+ return $sidebar_args;
+}
+
+function wp_widget_control_ob_filter( $string ) {
+ if ( false === $beg = strpos( $string, '%BEG_OF_TITLE%' ) )
+ return '';
+ if ( false === $end = strpos( $string, '%END_OF_TITLE%' ) )
+ return '';
+ $string = substr( $string, $beg + 14 , $end - $beg - 14);
+ return wp_specialchars( strip_tags( $string ) );
+}
+
+function widget_css() {
+ wp_admin_css( 'css/widgets' );
+}
+
+add_action( 'admin_head', 'widget_css' );
+
+?>