/**
* Method to list the contents of a directory on the FTP server
*
* @param string $path Path to the local file to be stored on the FTP server
* @param string $type Return type [raw|all|folders|files]
*
* @return mixed If $type is raw: string Directory listing, otherwise array of string with file-names
*
* @since 1.5
*/
public function listDetails($path = null, $type = 'all')
{
$dir_list = array();
$data = null;
$regs = null;
// @todo: Deal with recurse -- nightmare
// For now we will just set it to false
$recurse = false;
// If native FTP support is enabled let's use it...
if (FTP_NATIVE) {
// Turn passive mode on
if (@ftp_pasv($this->_conn, true) === false) {
Log::add(Text::sprintf('JLIB_CLIENT_ERROR_FTP_PASSIVE', __METHOD__), Log::WARNING, 'jerror');
return false;
}
if (($contents = @ftp_rawlist($this->_conn, $path)) === false) {
Log::add(Text::sprintf('JLIB_CLIENT_ERROR_FTP_BAD_RESPONSE', __METHOD__), Log::WARNING, 'jerror');
return false;
}
} else {
// Non Native mode
// Start passive mode
if (!$this->_passive()) {
Log::add(Text::sprintf('JLIB_CLIENT_ERROR_FTP_PASSIVE', __METHOD__), Log::WARNING, 'jerror');
return false;
}
// If a path exists, prepend a space
if ($path != null) {
$path = ' ' . $path;
}
// Request the file listing
if (!$this->_putCmd($recurse == true ? 'LIST -R' : 'LIST' . $path, array(150, 125))) {
Log::add(Text::sprintf('JLIB_CLIENT_ERROR_FTP_NOT_EXPECTED_RESPONSE_150_125', __METHOD__, $this->_response, $path), Log::WARNING, 'jerror');
@fclose($this->_dataconn);
return false;
}
// Read in the file listing.
while (!feof($this->_dataconn)) {
$data .= fread($this->_dataconn, 4096);
}
fclose($this->_dataconn);
// Everything go okay?
if (!$this->_verifyResponse(226)) {
Log::add(Text::sprintf('JLIB_CLIENT_ERROR_FTP_TRANSFER_FAILED', __METHOD__, $this->_response, $path), Log::WARNING, 'jerror');
return false;
}
$contents = explode(CRLF, $data);
}
// If only raw output is requested we are done
if ($type === 'raw') {
return $data;
}
// If we received the listing of an empty directory, we are done as well
if (empty($contents[0])) {
return $dir_list;
}
// If the server returned the number of results in the first response, let's dump it
if (strtolower(substr($contents[0], 0, 6)) === 'total ') {
array_shift($contents);
if (!isset($contents[0]) || empty($contents[0])) {
return $dir_list;
}
}
// Regular expressions for the directory listing parsing.
$regexps = array('UNIX' => '#([-dl][rwxstST-]+).* ([0-9]*) ([a-zA-Z0-9]+).* ([a-zA-Z0-9]+).* ([0-9]*)' . ' ([a-zA-Z]+[0-9: ]*[0-9])[ ]+(([0-9]{1,2}:[0-9]{2})|[0-9]{4}) (.+)#', 'MAC' => '#([-dl][rwxstST-]+).* ?([0-9 ]*)?([a-zA-Z0-9]+).* ([a-zA-Z0-9]+).* ([0-9]*)' . ' ([a-zA-Z]+[0-9: ]*[0-9])[ ]+(([0-9]{2}:[0-9]{2})|[0-9]{4}) (.+)#', 'WIN' => '#([0-9]{2})-([0-9]{2})-([0-9]{2}) +([0-9]{2}):([0-9]{2})(AM|PM) +([0-9]+|<DIR>) +(.+)#');
// Find out the format of the directory listing by matching one of the regexps
$osType = null;
foreach ($regexps as $k => $v) {
if (@preg_match($v, $contents[0])) {
$osType = $k;
$regexp = $v;
break;
}
}
if (!$osType) {
Log::add(Text::sprintf('JLIB_CLIENT_ERROR_FTP_UNRECOGNISED_FOLDER_LISTING_FORMATJLIB_CLIENT_ERROR_JFTP_LISTDETAILS_UNRECOGNISED', __METHOD__), Log::WARNING, 'jerror');
return false;
}
// Here is where it is going to get dirty....
if ($osType === 'UNIX' || $osType === 'MAC') {
foreach ($contents as $file) {
$tmp_array = null;
if (@preg_match($regexp, $file, $regs)) {
$fType = (int) strpos('-dl', $regs[1][0]);
// $tmp_array['line'] = $regs[0];
$tmp_array['type'] = $fType;
$tmp_array['rights'] = $regs[1];
// $tmp_array['number'] = $regs[2];
$tmp_array['user'] = $regs[3];
$tmp_array['group'] = $regs[4];
$tmp_array['size'] = $regs[5];
$tmp_array['date'] = @date('m-d', strtotime($regs[6]));
$tmp_array['time'] = $regs[7];
$tmp_array['name'] = $regs[9];
}
// If we just want files, do not add a folder
if ($type === 'files' && $tmp_array['type'] == 1) {
continue;
}
// If we just want folders, do not add a file
if ($type === 'folders' && $tmp_array['type'] == 0) {
continue;
}
if (\is_array($tmp_array) && $tmp_array['name'] != '.' && $tmp_array['name'] != '..') {
$dir_list[] = $tmp_array;
}
}
} else {
foreach ($contents as $file) {
$tmp_array = null;
if (@preg_match($regexp, $file, $regs)) {
$fType = (int) ($regs[7] === '<DIR>');
$timestamp = strtotime("{$regs[3]}-{$regs[1]}-{$regs[2]} {$regs[4]}:{$regs[5]}{$regs[6]}");
// $tmp_array['line'] = $regs[0];
$tmp_array['type'] = $fType;
$tmp_array['rights'] = '';
// $tmp_array['number'] = 0;
$tmp_array['user'] = '';
$tmp_array['group'] = '';
$tmp_array['size'] = (int) $regs[7];
$tmp_array['date'] = date('m-d', $timestamp);
$tmp_array['time'] = date('H:i', $timestamp);
$tmp_array['name'] = $regs[8];
}
// If we just want files, do not add a folder
if ($type === 'files' && $tmp_array['type'] == 1) {
continue;
}
// If we just want folders, do not add a file
if ($type === 'folders' && $tmp_array['type'] == 0) {
continue;
}
if (\is_array($tmp_array) && $tmp_array['name'] != '.' && $tmp_array['name'] != '..') {
$dir_list[] = $tmp_array;
}
}
}
return $dir_list;
}