Files
2024-10-25 14:16:28 +02:00

806 lines
27 KiB
PHP

<?php
/**
* File from http://PrestaShow.pl
*
* DISCLAIMER
* Do not edit or add to this file if you wish to upgrade this module to newer
* versions in the future.
*
* @authors PrestaShow.pl <kontakt@prestashow.pl>
* @copyright 2015 PrestaShow.pl
* @license http://PrestaShow.pl/license
*/
class PShow_File
{
/**
* Update file from URL
* (convert to XML if CSV downloaded)
*
* @param string $filepath
* @param string $url
* @return boolean
*/
public static function updateFileFromURL($filepath, $url)
{
if (empty($filepath)) {
return false;
}
$filename = pathinfo($filepath, PATHINFO_FILENAME);
if (empty($url) || filter_var($url, FILTER_VALIDATE_URL) === false) {
PShow_Log::add($filename . '.log', "url is empty or invalid " . $url);
return false;
}
PShow_Log::add($filename . '.log', sprintf("downloading file from %s to %s", $url, $filepath));
$config = PShow_Config::getFileConfig($filename);
$login = (isset($config['file']) && isset($config['file']['login'])) ? $config['file']['login'] : null;
$password = (isset($config['file']) && isset($config['file']['password'])) ? $config['file']['password'] : null;
if (!isset($config['file']) || !isset($config['file']['auth_req']) || !$config['file']['auth_req']) {
$login = $password = null;
}
PShow_File::download($url, $filepath, $login, $password);
if (file_exists(_IMPORT_CONFIG_PATH_ . $filename . '/csv_delimiter')) {
// this method is deprecated
$delimiter = file_get_contents(_IMPORT_CONFIG_PATH_ . $filename . '/csv_delimiter');
if (empty($delimiter)) {
PShow_Log::add($filename . '.log', "delimiter not found");
return false;
}
$headers_in_the_file = 1;
if (file_exists(_IMPORT_CONFIG_PATH_ . $filename . '/headers_in_the_file')) {
$headers_in_the_file = (int) file_get_contents(_IMPORT_CONFIG_PATH_ . $filename . '/headers_in_the_file');
}
PShow_Log::add($filename . '.log', "converting csv to xml document");
PShow_Csv::convertToXml($filepath, $delimiter, true, $headers_in_the_file);
$new_config = array(
'file' => array(
'format' => 'csv',
'csv' => array(
'headers_in_the_file' => $headers_in_the_file,
'separator' => $delimiter,
),
)
);
PShow_Config::saveFileConfig($filename, $new_config);
@unlink(_IMPORT_CONFIG_PATH_ . $filename . '/csv_delimiter');
@unlink(_IMPORT_CONFIG_PATH_ . $filename . '/headers_in_the_file');
} elseif (isset($config['file']) && isset($config['file']['format']) && $config['file']['format'] == 'csv') {
$delimiter = $config['file']['csv']['separator'];
if (empty($delimiter)) {
PShow_Log::add($filename . '.log', "delimiter not found");
return false;
}
$headers_in_the_file = $config['file']['csv']['headers_in_the_file'];
PShow_Log::add($filename . '.log', "converting csv to xml document");
PShow_Csv::convertToXml($filepath, $delimiter, true, $headers_in_the_file, (isset($config['file']['encoding']) ? $config['file']['encoding'] : 'UTF-8'));
}
PShow_File::minifyXmlFile($filepath);
return true;
}
/**
* Re-encode file with UTF8
*
* @param string $dest_filepath
*/
public static function re_encode_utf8_file($dest_filepath)
{
$source_filepath = $dest_filepath . '.encoding';
rename($dest_filepath, $source_filepath);
$r = fopen($source_filepath, 'r');
$w = fopen($dest_filepath, 'w');
while ($str = fread($r, 255)) {
fwrite($w, utf8_encode(utf8_decode($str)));
}
fclose($r);
fclose($w);
@unlink($source_filepath);
}
/**
* Find free filename in upload directory
*
* @param string $name_
* @param int $append
* @return string
*/
public static function findFreeNameToUpload($name_, $append = 0)
{
$name = $name_;
if ($append) {
$name .= '_' . $append;
}
if (count(glob(_MODULE_UPLOAD_PATH_ . '*-' . $name . '.*'))) {
return self::findFreeNameToUpload($name_, ++$append);
}
return $name;
}
public static function unlink($filepath)
{
if (!file_exists($filepath)) {
return false;
}
return unlink($filepath);
}
/**
*
* @param string $path
*/
public static function minifyXmlFile($path)
{
if (strtolower(pathinfo($path, PATHINFO_EXTENSION)) == "xml") {
$content = file_get_contents($path);
$newcontent = preg_replace('~ xmlns:([^=]+)="([^"]+)"~', "", $content);
$newcontent = preg_replace('~ xmlns="([^"]+)"~', "", $newcontent);
$newcontent = preg_replace('~ xsi:([^=]+)="([^"]+)"~', "", $newcontent);
$newcontent = preg_replace('~ xsi="([^"]+)"~', "", $newcontent);
$newcontent = preg_replace('~iaiext:~', "", $newcontent);
file_put_contents($path, $newcontent);
}
}
/**
*
* @param string $url
* @return boolean|array
*/
public static function isImage(&$url)
{
$url = str_replace('\n', '', $url);
$url = preg_replace('~(.*)(http|ftp)~', '$2', $url);
$url = chop($url);
$url = str_replace(' ', '%20', $url);
if (strpos($url, 'ftp://') !== false) {
return array('url' => $url);
}
$headers = self::get_headers($url);
if (!$headers) {
return false;
}
if (stripos($headers['Content-Type'], 'image') === false) {
return false;
}
return $headers;
}
public static function getLogFile($filepath)
{
return PShow_Log::getLogFile($filepath);
}
public static function _getHeaders($url)
{
if (function_exists('curl_init')) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_NOBODY, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_VERBOSE, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_exec($ch);
$responseCode = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
$contentType = curl_getinfo($ch, CURLINFO_CONTENT_TYPE);
curl_close($ch);
if ($responseCode != null) {
return array(
$responseCode,
'Content-Type: ' . $contentType
);
}
} else {
PShow_Log::addImportLog('curl extension not available');
}
return get_headers($url);
}
public static function get_headers($url)
{
$headers = self::_getHeaders($url);
while (stripos($headers[0], "301") !== false) {
foreach ($headers as $h) {
if (stripos($h, 'Location: ') !== false) {
$url = str_replace('Location: ', null, $h);
break;
}
}
$headers = self::_getHeaders($url);
}
if (!$headers || stripos($headers[0], "200") === false) {
$url = urldecode($url);
$headers = self::_getHeaders($url);
}
if (!$headers || stripos($headers[0], "200") === false) {
$url = urlencode($url);
$headers = self::_getHeaders($url);
}
if (!$headers || stripos($headers[0], "200") === false) {
return false;
}
$content_type = null;
foreach ($headers as $h) {
if (stripos($h, 'Content-Type: ') !== false) {
$content_type = str_replace('Content-Type: ', null, $h);
break;
}
}
if (stripos($content_type, 'image') === false && in_array($content_type, array('png', 'jpg', 'jpeg', 'gif'))) {
$content_type = "image/" . $content_type;
}
return array(
'url' => $url,
'Content-Type' => $content_type
);
}
public static function file_get_contents($path)
{
$contents = Tools::file_get_contents($path, false, null, (60 * 10));
if (!$contents && filter_var($path, FILTER_VALIDATE_URL)) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $path);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$contents = curl_exec($ch);
curl_close($ch);
}
return $contents;
}
/**
* download()
*
* @param $url address to file
* @param $save_as download file to...
*/
public static function download($url, $save_as, $login = null, $password = null)
{
$opts = array(
"ssl" => array(
"verify_peer" => false,
"verify_peer_name" => false,
),
'http' => array(
'method' => 'GET',
'timeout' => 60 * 10
)
);
if (!empty($login) && !empty($password)) {
$url = str_replace('https://', sprintf('https://%s:%s@', $login, $password), $url);
$url = str_replace('http://', sprintf('http://%s:%s@', $login, $password), $url);
$url = str_replace('ftp://', sprintf('ftp://%s:%s@', $login, $password), $url);
}
$file = @fopen($url, "rb", false, stream_context_create($opts));
//stream_set_timeout($file, 300);
if ($file) {
$newf = fopen($save_as, "wb");
if ($newf) {
while (!feof($file)) {
fwrite($newf, fread($file, 1024 * 8), 1024 * 8);
}
fclose($newf);
}
fclose($file);
} else {
$data = self::file_get_contents($url);
file_put_contents($save_as, $data);
}
}
/**
* getFileFromURL()
*
* @param $url address to file
* @return bool downloaded or not
*/
public static function getFileFromURL($url, $auth_req, $login, $password)
{
$ext = strtolower(Tools::getValue('fileext'));
$filename = Tools::getValue('saveas');
$filename = str_replace(' ', '_', $filename);
$time = time();
$freeFilename = self::findFreeNameToUpload($filename);
$info_file = _MODULE_UPLOAD_PATH_ . $time . '-' . $freeFilename . '.txt';
$data_file = _MODULE_UPLOAD_PATH_ . $time . '-' . $freeFilename . '.' . $ext;
$encoding = Tools::getValue('file_encoding');
PShow_Config::saveFileConfig($time . '-' . $freeFilename, array(
'file' => array(
'auth_req' => (int) $auth_req,
'login' => $login,
'password' => $password,
'format' => 'xml',
'encoding' => $encoding,
),
));
file_put_contents($info_file, $url);
if (!file_exists($info_file)) {
return false;
}
self::download($url, $data_file, $login, $password);
@chmod($data_file, 0664);
if (!file_exists($data_file)) {
unlink($info_file);
return false;
}
$delimiter = Tools::getValue('csvdelim');
$headers_in_the_file = (int) Tools::getValue('headers_in_the_file');
self::minifyXmlFile($data_file);
if ($ext == 'csv' && $delimiter) {
// create xml file
PShow_Csv::convertToXml($data_file, $delimiter, true, $headers_in_the_file, $encoding, ($encoding ? $encoding : 'UTF-8'));
$conf_dir = _IMPORT_CONFIG_PATH_ . pathinfo($data_file, PATHINFO_FILENAME);
if (!is_dir($conf_dir)) {
mkdir($conf_dir, 0777);
}
PShow_Config::saveFileConfig($time . '-' . $freeFilename, array(
'file' => array(
'csv' => array(
'separator' => $delimiter,
'headers_in_the_file' => $headers_in_the_file,
),
'format' => 'csv',
),
));
}
Cache::getInstance()->delete('pshowimporter_files_list');
return true;
}
/**
* getFileFromLocalDisk()
*
* @return string
*/
public static function getFileFromLocalDisk()
{
$filename_ = Tools::getValue('saveas');
$filename_ = str_replace(' ', '_', $filename_);
$dirname = self::findFreeNameToUpload($filename_);
$filename = $dirname . '.' . strtolower(pathinfo($_FILES['file']['name'], PATHINFO_EXTENSION));
$upload_path = time() . '-' . $filename;
PShow_Config::saveFileConfig($dirname, array(
'file' => array(
'auth_req' => 0,
'format' => 'xml',
),
));
$return = null;
if (!preg_match('/.*\.(' . str_replace(',', '|', _IMPORT_FILE_EXTENSIONS_) . ')$/i', $_FILES['file']['name'])) {
$return = 'The extension of your file should be .csv or .xml';
} elseif (!@move_uploaded_file($_FILES['file']['tmp_name'], _MODULE_UPLOAD_PATH_ . $upload_path)) {
$return = 'An error occurred while uploading / copying the file.';
} else {
@chmod(_MODULE_UPLOAD_PATH_ . $upload_path, 0664);
$_FILES['file']['filename'] = $upload_path;
$return = 'File successfully uploaded.';
self::minifyXmlFile(_MODULE_UPLOAD_PATH_ . $upload_path);
$delimiter = Tools::getValue('csvdelim');
$headers_in_the_file = (int) Tools::getValue('headers_in_the_file');
$encoding = Tools::getValue('file_encoding');
PShow_Config::saveFileConfig($dirname, array(
'file' => array(
'csv' => array(
'separator' => $delimiter,
'headers_in_the_file' => $headers_in_the_file,
),
'format' => 'csv',
'encoding' => $encoding,
),
));
if ($delimiter) {
// create xml file
PShow_Csv::convertToXml(_MODULE_UPLOAD_PATH_ . $upload_path, $delimiter, true, $headers_in_the_file, ($encoding ? $encoding : 'UTF-8'));
$conf_dir = _IMPORT_CONFIG_PATH_ . pathinfo($upload_path, PATHINFO_FILENAME);
if (!is_dir($conf_dir)) {
mkdir($conf_dir, 0777);
}
}
Cache::getInstance()->delete('pshowimporter_files_list');
}
return $return;
}
/**
* getFilesList()
*
* @return array list of the files
*/
public static function getFilesList()
{
if (_PS_CACHE_ENABLED_ && Cache::getInstance()->exists('pshowimporter_files_list')) {
return Cache::getInstance()->get('pshowimporter_files_list');
}
$files = glob(_MODULE_UPLOAD_PATH_ . '*.*');
$data = array();
$i = 0;
foreach ($files as $path) {
if (!in_array(pathinfo($path, PATHINFO_EXTENSION), explode(',', _IMPORT_FILE_EXTENSIONS_))) {
continue;
}
$data[$i] = pathinfo($path);
$data[$i]['path'] = $path;
// chmods
$data[$i]['chmod'] = "<span class='label label-default'>" . substr(sprintf('%o', fileperms($path)), -4) . "</span>";
$data[$i]['writable'] = is_writable($path);
$data[$i]['readable'] = is_readable($path);
if ($data[$i]['writable'] && $data[$i]['readable']) {
$data[$i]['chmod'] = "<span class='label label-success'>OK</span>";
} else {
$data[$i]['chmod'] = "<a class='label label-danger' onclick=\"alert('Change file permissions using FTP.');\">Error</a>";
}
$data[$i]['writable'] = $data[$i]['writable'] ? 'OK' : 'No access!';
$data[$i]['readable'] = $data[$i]['readable'] ? 'OK' : 'No access!';
// source
$txt_file = $data[$i]['dirname'] . '/' . $data[$i]['filename'] . '.txt';
if (file_exists($txt_file)) {
$data[$i]['from_url'] = self::file_get_contents($txt_file);
} else {
$data[$i]['from_url'] = false;
}
// time
$filename_data = explode('-', $data[$i]['filename']);
$data[$i]['time'] = $filename_data[0];
$lastimport_file = _IMPORT_CONFIG_PATH_ . $data[$i]['filename'] . '/lastimport';
if (file_exists($lastimport_file)) {
$data[$i]['lastimport'] = filemtime($lastimport_file);
} else {
$data[$i]['lastimport'] = false;
}
$config = PShow_Config::getFileConfig($data[$i]['filename']);
$data[$i]['rowsCount'] = (array_key_exists('primary', $config) && array_key_exists('rowsCount', $config['primary'])) ? $config['primary']['rowsCount'] : '-';
$data[$i]['configured'] = array_key_exists('primary', $config);
$data[$i]['matched'] = array_key_exists('matched', $config);
$data[$i]['match_cats'] = ($data[$i]['configured'] && $data[$i]['matched']);
$data[$i]['filename'] = str_replace($data[$i]['time'] . '-', '', $data[$i]['filename']);
$filesizetypes = array('B', 'KB', 'MB', 'GB', 'TB');
$data[$i]['filesizetype'] = 'B';
// required memory
$data[$i]['reqMoreMemory'] = (bool) (intval(filesize($path)) * 2.2 > intval(ini_get('memory_limit')) * 1000 * 1000);
if ($data[$i]['reqMoreMemory']) {
$data[$i]['reqMoreMemory'] = (string) ($data[$i]['filesize'] * 2) . $data[$i]['filesizetype'];
}
$data[$i]['filesize'] = round(filesize($path), 2);
while ($data[$i]['filesize'] > 1000) {
$data[$i]['filesize'] = round($data[$i]['filesize'] / 1000, 2);
$act = array_search($data[$i]['filesizetype'], $filesizetypes);
$data[$i]['filesizetype'] = $filesizetypes[($act + 1)];
}
// get display filename
$data[$i]['data'] = array(
'displayFileName' => array_key_exists('displayFileName', $config) ? $config['displayFileName'] : $data[$i]['filename']
);
$mime_encoding = "utf-8";
$disabled = ini_get("disable_functions");
if (stripos($disabled, 'exec') === false) {
@exec("file --mime-encoding " . escapeshellarg($path), $mime_encoding);
if (is_array($mime_encoding)) {
$mime_encoding = reset($mime_encoding);
$mime_encoding = substr($mime_encoding, (stripos($mime_encoding, ': ')) + 2);
}
}
// file encoding
$data[$i]['correct_encoding'] = ($mime_encoding == "utf-8" || $mime_encoding == "us-ascii") ? true : $mime_encoding;
if ($data[$i]['correct_encoding'] === true) {
$data[$i]['encoding'] = "<span class='label label-success'>OK</span>";
} else {
$data[$i]['encoding'] = "<a class='label label-danger' onclick=\"alert('This file has incorrect encoding (" . $mime_encoding . "). Change file encoding to UTF-8');\">ERROR</a>";
}
$data[$i]['id'] = $i + 1;
$data[$i]['reconfigRequired'] = false;
$data[$i]['wrong_xml_format'] = false;
$data[$i]['log_dir'] = _IMPORT_LOG_PATH_ . $data[$i]['time'] . '-' . $data[$i]['filename'];
++$i;
}
if (_PS_CACHE_ENABLED_) {
Cache::getInstance()->set('pshowimporter_files_list', $data);
}
return $data;
}
/**
* sortFiles()
*
* @param array list of the files
* @param string sort type
* @param string sorting order
* @return array sorted list of the files
*/
public static function sortFiles($files, $sort_by, $order)
{
$files_count = count($files);
for ($y = 0; $y < $files_count; ++$y) {
for ($x = 0; $x < ($files_count - 1); ++$x) {
$tmp = array();
switch ($sort_by) {
case 'time':
if ($files[$x]['time'] > $files[$x + 1]['time'] && $order == 'desc') {
$tmp = $files[$x];
$files[$x] = $files[$x + 1];
$files[$x + 1] = $tmp;
}
if ($files[$x]['time'] < $files[$x + 1]['time'] && $order == 'asc') {
$tmp = $files[$x];
$files[$x] = $files[$x + 1];
$files[$x + 1] = $tmp;
}
break;
case 'filesize':
if ($files[$x]['filesize'] < $files[$x + 1]['filesize'] && $order == 'desc') {
$tmp = $files[$x];
$files[$x] = $files[$x + 1];
$files[$x + 1] = $tmp;
}
if ($files[$x]['filesize'] > $files[$x + 1]['filesize'] && $order == 'asc') {
$tmp = $files[$x];
$files[$x] = $files[$x + 1];
$files[$x + 1] = $tmp;
}
break;
}
}
}
return $files;
}
/**
* Import image as attribute texture
*
* @param string $url
* @param integer $id_attribute
*/
public static function importAttributeTexture($url, $id_attribute)
{
$images_path = _PS_COL_IMG_DIR_ . $id_attribute;
PShow_Log::addImportLog("import attribute texture from: " . $url);
$img = self::file_get_contents($url);
file_put_contents($images_path . '.temp', $img);
list($width, $height, $type) = self::getimagesize($images_path . '.temp');
unlink($images_path . '.temp');
if ($type === null) {
PShow_Log::addImportLog("attribute texture not imported because type not found for url: " . $url);
return false;
}
$_ext = (($type == IMAGETYPE_JPEG) ? '.jpg' : '.png');
$ext = '.jpg';
if ($type == IMAGETYPE_JPEG) {
file_put_contents($images_path . $ext, $img);
} else {
file_put_contents($images_path . $_ext, $img);
$input_file = $images_path . $_ext;
$output_file = $images_path . $ext;
$input = imagecreatefrompng($input_file);
list($width, $height) = getimagesize($input_file);
$output = imagecreatetruecolor($width, $height);
$white = imagecolorallocate($output, 255, 255, 255);
imagefilledrectangle($output, 0, 0, $width, $height, $white);
imagecopy($output, $input, 0, 0, 0, 0, $width, $height);
imagejpeg($output, $output_file);
unlink($images_path . $_ext);
}
PShow_Log::addImportLog("attribute texture imported to: " . $images_path . $ext);
}
private static $imagesize = array();
public static function getimagesize($url)
{
$md5 = md5($url);
if (!array_key_exists($md5, self::$imagesize) || self::$imagesize[$md5] === null) {
self::$imagesize[$md5] = getimagesize($url);
}
return self::$imagesize[$md5];
}
/**
*
* @param string $url
* @param string $images_path
* @param integer $quality
* @param boolean $generate_thumbnails
* @param string $log_path
*/
public static function import_image($url, $images_path, $quality, $generate_thumbnails, $log_path = null)
{
$img = self::file_get_contents($url);
file_put_contents($images_path . '.temp', $img);
list($width, $height, $type) = self::getimagesize($images_path . '.temp');
unlink($images_path . '.temp');
if ($type === null) {
if ($log_path !== null) {
PShow_Log::addImportLog("Image type not found for url: " . $url);
}
$type = IMAGETYPE_JPEG;
}
$_ext = (($type == IMAGETYPE_JPEG) ? '.jpg' : '.png');
$ext = '.jpg';
if ($type == IMAGETYPE_JPEG) {
file_put_contents($images_path . $ext, $img);
} else {
file_put_contents($images_path . $_ext, $img);
$input_file = $images_path . $_ext;
$output_file = $images_path . $ext;
$input = imagecreatefrompng($input_file);
list($width, $height) = getimagesize($input_file);
$output = imagecreatetruecolor($width, $height);
$white = imagecolorallocate($output, 255, 255, 255);
imagefilledrectangle($output, 0, 0, $width, $height, $white);
imagecopy($output, $input, 0, 0, 0, 0, $width, $height);
imagejpeg($output, $output_file);
unlink($images_path . $_ext);
}
$tmpZero = 0;
$tmpNull = null;
if ($generate_thumbnails) {
PShow_Log::addImportLog("generate thumbnails for image: " . $url);
$images_types = ImageType::getImagesTypes('products');
$quality = ($quality < 3 ? 3 : ($quality > 10 ? 10 : $quality));
foreach ($images_types as $image_type) {
$result = ImageManager::resize(
$images_path . $ext, $images_path . '-' . $image_type['name'] . $ext, (int) $image_type['width'], (int) $image_type['height'], false, $tmpZero, $tmpNull, $tmpNull, $quality
);
if (!$result) {
PShow_Log::addImportLog("unable to create thumbnail: " . $image_type['name']);
} else {
$expl = explode('/img/', $images_path . '-' . $image_type['name'] . $ext);
PShow_Log::addImportLog("created thumbnail " . $image_type['name'] . " in " . __PS_BASE_URI__ . 'img/' . $expl[1]);
}
}
}
}
}