/**
* upload a file to the box (via POST) [all files are uploaded to the 'firmwarecfg' cgi-program]
* the main cURL wrapper handles the command
*
* @access public
* @param array $formfields an associative array with the POST fields to pass
* @param array $filefileds an associative array with the file data (key: content) and type (key: type)
* @return string the raw HTML code returned by the Fritz!Box
*/
public function doPostFile($formfields = array(), $filefileds = array())
{
$ch = curl_init();
// add the sid, if it is already set
if ($this->sid != '0000000000000000') {
// 'sid' MUST be the first POST variable!!! (otherwise it will not work!!)
// therfore we use array_merge to ensuere the foreach outputs 'sid' fist
$formfields = array_merge(array('sid' => $this->getSID()), $formfields);
//$formfields['sid'] = $this->sid;
}
curl_setopt($ch, CURLOPT_URL, $this->config->getItem('fritzbox_url') . '/cgi-bin/firmwarecfg');
curl_setopt($ch, CURLOPT_POST, 1);
// remote config?
if ($this->config->getItem('enable_remote_config')) {
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
// support for pre FRITZ!OS 5.50 remote config
if (!$this->config->getItem('use_lua_login_method')) {
curl_setopt($ch, CURLOPT_USERPWD, $this->config->getItem('remote_config_user') . ':' . $this->config->getItem('remote_config_password'));
}
}
// enable for debugging:
//curl_setopt($ch, CURLOPT_VERBOSE, TRUE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
// if filefileds not specified ('@/path/to/file.xml;type=text/xml' works fine)
if (empty($filefileds)) {
curl_setopt($ch, CURLOPT_POSTFIELDS, $formfields); // http_build_query
} // post calculated raw data
else {
$header = $this->_create_custom_file_post_header($formfields, $filefileds);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: multipart/form-data; boundary=' . $header['delimiter'], 'Content-Length: ' . strlen($header['data']))
);
curl_setopt($ch, CURLOPT_POSTFIELDS, $header['data']);
}
$output = curl_exec($ch);
// curl error
if (curl_errno($ch)) {
$this->error(curl_error($ch) . " (" . curl_errno($ch) . ")");
}
// finger out an error message, if given
preg_match('@<p class="ErrorMsg">(.*?)</p>@is', $output, $matches);
if (isset($matches[1])) {
$this->error(str_replace(' ', ' ', $matches[1]));
}
curl_close($ch);
return $output;
}
private function _create_custom_file_post_header($postFields, $fileFields)
{
// form field separator
$delimiter = '-------------' . uniqid();
/*
// file upload fields: name => array(type=>'mime/type',content=>'raw data')
$fileFields = array(
'file1' => array(
'type' => 'text/xml',
'content' => '...your raw file content goes here...',
'filename' = 'filename.xml'
),
);
// all other fields (not file upload): name => value
$postFields = array(
'otherformfield' => 'content of otherformfield is this text',
);
*/
$data = '';
// populate normal fields first (simpler)
foreach ($postFields as $name => $content) {
$data .= "--" . $delimiter . "\r\n";
$data .= 'Content-Disposition: form-data; name="' . urlencode($name) . '"';
$data .= "\r\n\r\n";
$data .= $content;
$data .= "\r\n";
}
// populate file fields
foreach ($fileFields as $name => $file) {
$data .= "--" . $delimiter . "\r\n";
// "filename" attribute is not essential; server-side scripts may use it
$data .= 'Content-Disposition: form-data; name="' . urlencode($name) . '";' .
' filename="' . $file['filename'] . '"' . "\r\n";
//$data .= 'Content-Transfer-Encoding: binary'."\r\n";
// this is, again, informative only; good practice to include though
$data .= 'Content-Type: ' . $file['type'] . "\r\n";
// this endline must be here to indicate end of headers
$data .= "\r\n";
// the file itself (note: there's no encoding of any kind)
$data .= $file['content'] . "\r\n";
}
// last delimiter
$data .= "--" . $delimiter . "--\r\n";
return array('delimiter' => $delimiter, 'data' => $data);
}