Writing a local file from an external FTP server - Issue with Varien_Io_File
-
12-12-2019 - |
Question
I have a script that pulls a file from an external server, and tries to save it locally (to then be processed). I'm using Varien_Io_Ftp() to facilitate this, however, upon saving the file locally, it throws the following exception, despite creating the file that is required which upsets me.
Warning: chdir(): Invalid argument (errno 22) in C:\wamp\www\xxxxx\shop\lib\Varien\Io\File.php on line 547
This line in Varien_Io_File is the only one in the vacinity that doesn't have error suppression added to it. Is this a bug, or should I be setting _iwd somewhere within my call?
Hopefully some code to explain the call below:
$importDir = Mage::getBaseDir() . DS . 'var' . DS . 'import' . DS . 'stock' . DS;
$localFile = $importDir . "StockUpdate_" . date("Y-m-d-H-i-s") . ".csv";
$file = new Varien_Io_File();
$file->mkdir($importDir);
$pickupFile = new Varien_Io_Ftp();
try {
$pickupFile->open(
array(
'host' => $host,
'user' => $username,
'password' => $password,
'timeout' => '10'
)
);
$pickupFile->cd($remoteDir);
$_fileToImportRemoteTmp = $pickupFile->read($remoteFile);
$pickupFile->close();
if (!$file->write($localFile, $_fileToImportRemoteTmp)) {
die("cannot write local file :/");
}
$file->close();
} catch (Exception $e) {
var_dump($e);
}
The exception I being thrown with this line:
if (!$file->write($localFile, $_fileToImportRemoteTmp)) {
Solution 2
For anyone looking at this in the future, RS has provided an example that works, but I wanted to jump in and give a little explanation about WHY his solution works.
The exception being thrown at lib\Varien\Io\File.php on line 547 is due to the reference to $this->_iwd
not being supressed (and inherently, the fact that it isn't set). I'm assuming this isn't a bug, despite the fact tht you can clearly call the function directly. I'm guessing that the intention is that you call the ->open()
function prior to making any action upon a file.
The open()
function sets a reference to _iwd
(if you pass a path
into it to begin with). i.e.
$file->open(array('path' => $importDir));
Grabbing a reference to Varien_Io_File, and making a direct call to cd
, whilst possible, doesn't follow the correct flow, therefore when you write
, the original reference to _iwd
isn't in place.
It's worth pointing out that you need to call:
$file->mkdir($importDir);
prior to calling open()
.
Additionally, RS noted that http://inchoo.net/magento/magento-code-library/ has an example, however, the inital code doesn't mention the limitation above and actually calls ->write()
directly too.
OTHER TIPS
Try
$importDir = Mage::getBaseDir() . DS . 'var' . DS . 'import' . DS . 'stock' . DS;
$localFile = $importDir . "StockUpdate_" . date("Y-m-d-H-i-s") . ".csv";
$file = new Varien_Io_File();
$file->open(array('path' => $importDir));
$file->mkdir($importDir);
$pickupFile = new Varien_Io_Ftp();
try {
$pickupFile->open(
array(
'host' => $host,
'user' => $username,
'password' => $password,
'timeout' => '10'
)
);
$pickupFile->cd($remoteDir);
$_fileToImportRemoteTmp = $pickupFile->read($remoteFile);
$pickupFile->close();
if (!$file->write($localFile, $_fileToImportRemoteTmp)) {
die("cannot write local file :/");
}
$file->close();
} catch (Exception $e) {
var_dump($e);
}
Try
$pickupFile = new Varien_Io_Ftp();
$localDir = "/path/to/local/dir";
$remoteFile = "/path/to/remote/dir/text.csv"
mkdir($localDir, 0700, true);
$localFile = $localDir . '/local.csv'
try {
$pickupFile->open(
array(
'host' => $host,
'user' => $username,
'password' => $password,
'timeout' => '10'
)
);
$pickupFile->read($remoteFile, $localFile);
} catch (Exception $e) {
var_dump($e);
}
See Varien_Io_Ftp
Also for security you way want to use Varien_Io_Sftp