OXID eShop CE  4.9.6
 All Classes Files Functions Variables Pages
oxutilsfile.php
Go to the documentation of this file.
1 <?php
2 
6 class oxUtilsFile extends oxSuperCfg
7 {
8 
14  const PROMO_PICTURE_DIR = 'promo';
15 
21  protected $_iMaxPicImgCount = 12;
22 
28  protected $_iMaxZoomImgCount = 12;
29 
35  protected $_aTypeToPath = array('TC' => 'master/category/thumb',
36  'CICO' => 'master/category/icon',
37  'PICO' => 'master/category/promo_icon',
38  'MICO' => 'master/manufacturer/icon',
39  'VICO' => 'master/vendor/icon',
40  'PROMO' => self::PROMO_PICTURE_DIR,
41  'ICO' => 'master/product/icon',
42  'TH' => 'master/product/thumb',
43  'M1' => 'master/product/1',
44  'M2' => 'master/product/2',
45  'M3' => 'master/product/3',
46  'M4' => 'master/product/4',
47  'M5' => 'master/product/5',
48  'M6' => 'master/product/6',
49  'M7' => 'master/product/7',
50  'M8' => 'master/product/8',
51  'M9' => 'master/product/9',
52  'M10' => 'master/product/10',
53  'M11' => 'master/product/11',
54  'M12' => 'master/product/12',
55  //
56  'P1' => '1',
57  'P2' => '2',
58  'P3' => '3',
59  'P4' => '4',
60  'P5' => '5',
61  'P6' => '6',
62  'P7' => '7',
63  'P8' => '8',
64  'P9' => '9',
65  'P10' => '10',
66  'P11' => '11',
67  'P12' => '12',
68  'Z1' => 'z1',
69  'Z2' => 'z2',
70  'Z3' => 'z3',
71  'Z4' => 'z4',
72  'Z5' => 'z5',
73  'Z6' => 'z6',
74  'Z7' => 'z7',
75  'Z8' => 'z8',
76  'Z9' => 'z9',
77  'Z10' => 'z10',
78  'Z11' => 'z11',
79  'Z12' => 'z12',
80  //
81  'WP' => 'master/wrapping',
82  'FL' => 'media',
83  );
84 
90  protected $_aBadFiles = array('php', 'php3', 'php4', 'php5', 'phps', 'php6', 'jsp', 'cgi', 'cmf', 'exe');
91 
97  protected $_aAllowedFiles = array('gif', 'jpg', 'jpeg', 'png', 'pdf');
98 
104  protected $_iNewFilesCounter = 0;
105 
111  public function __construct()
112  {
113  $myConfig = $this->getConfig();
114 
115  if ($iPicCount = $myConfig->getConfigParam('iPicCount')) {
116  $this->_iMaxPicImgCount = $iPicCount;
117  }
118 
119  $this->_iMaxZoomImgCount = $this->_iMaxPicImgCount;
120  }
121 
127  public function getNewFilesCounter()
128  {
130  }
131 
137  protected function _setNewFilesCounter($iNewFilesCounter)
138  {
139  $this->_iNewFilesCounter = (int) $iNewFilesCounter;
140  }
141 
149  public function normalizeDir($sDir)
150  {
151  if (isset($sDir) && $sDir != "" && substr($sDir, -1) !== '/') {
152  $sDir .= "/";
153  }
154 
155  return $sDir;
156  }
157 
164  public function copyDir($sSourceDir, $sTargetDir)
165  {
166  $oStr = getStr();
167  $handle = opendir($sSourceDir);
168  while (false !== ($file = readdir($handle))) {
169  if ($file != '.' && $file != '..') {
170  if (is_dir($sSourceDir . '/' . $file)) {
171 
172  // recursive
173  $sNewSourceDir = $sSourceDir . '/' . $file;
174  $sNewTargetDir = $sTargetDir . '/' . $file;
175  if (strcasecmp($file, 'CVS') && strcasecmp($file, '.svn')) {
176  @mkdir($sNewTargetDir, 0777);
177  $this->copyDir($sNewSourceDir, $sNewTargetDir);
178  }
179  } else {
180  $sSourceFile = $sSourceDir . '/' . $file;
181  $sTargetFile = $sTargetDir . '/' . $file;
182 
183  //do not copy files within dyn_images
184  if (!$oStr->strstr($sSourceDir, 'dyn_images') || $file == 'nopic.jpg' || $file == 'nopic_ico.jpg') {
185  @copy($sSourceFile, $sTargetFile);
186  }
187  }
188  }
189  }
190  closedir($handle);
191  }
192 
200  public function deleteDir($sSourceDir)
201  {
202  if (is_dir($sSourceDir)) {
203  if ($oDir = dir($sSourceDir)) {
204 
205  while (false !== $sFile = $oDir->read()) {
206  if ($sFile == '.' || $sFile == '..') {
207  continue;
208  }
209 
210  if (!$this->deleteDir($oDir->path . DIRECTORY_SEPARATOR . $sFile)) {
211  $oDir->close();
212 
213  return false;
214  }
215  }
216 
217  $oDir->close();
218 
219  return rmdir($sSourceDir);
220  }
221  } elseif (file_exists($sSourceDir)) {
222  return unlink($sSourceDir);
223  }
224  }
225 
233  public function readRemoteFileAsString($sPath)
234  {
235  $sRet = '';
236  $hFile = @fopen($sPath, 'r');
237  if ($hFile) {
238  socket_set_timeout($hFile, 2);
239  while (!feof($hFile)) {
240  $sLine = fgets($hFile, 4096);
241  $sRet .= $sLine;
242  }
243  fclose($hFile);
244  }
245 
246  return $sRet;
247  }
248 
260  protected function _prepareImageName($sValue, $sType, $blDemo, $sImagePath, $blUnique = true)
261  {
262  if ($sValue) {
263  // add type to name
264  $aFilename = explode(".", $sValue);
265 
266  $sFileType = trim($aFilename[count($aFilename) - 1]);
267 
268  if (isset($sFileType)) {
269 
270  $oStr = getStr();
271 
272  // unallowed files ?
273  if (in_array($sFileType, $this->_aBadFiles) || ($blDemo && !in_array($sFileType, $this->_aAllowedFiles))) {
274  oxRegistry::getUtils()->showMessageAndExit("We don't play this game, go away");
275  }
276 
277  // removing file type
278  if (count($aFilename) > 0) {
279  unset($aFilename[count($aFilename) - 1]);
280  }
281 
282  $sFName = '';
283  if (isset($aFilename[0])) {
284  $sFName = $oStr->preg_replace('/[^a-zA-Z0-9()_\.-]/', '', implode('.', $aFilename));
285  }
286 
287  $sValue = $this->_getUniqueFileName($sImagePath, "{$sFName}", $sFileType, "", $blUnique);
288  }
289  }
290 
291  return $sValue;
292  }
293 
301  protected function _getImagePath($sType)
302  {
303  $sFolder = array_key_exists($sType, $this->_aTypeToPath) ? $this->_aTypeToPath[$sType] : '0';
304  $sPath = $this->normalizeDir($this->getConfig()->getPictureDir(false)) . "{$sFolder}/";
305 
306  return $sPath;
307  }
308 
319  protected function _getImageSize($sImgType, $iImgNum, $sImgConf)
320  {
321  $myConfig = $this->getConfig();
322  $sSize = false;
323 
324  switch ($sImgConf) {
325  case 'aDetailImageSizes':
326  $aDetailImageSizes = $myConfig->getConfigParam($sImgConf);
327  $sSize = $myConfig->getConfigParam('sDetailImageSize');
328  if (isset($aDetailImageSizes['oxpic' . $iImgNum])) {
329  $sSize = $aDetailImageSizes['oxpic' . $iImgNum];
330  }
331  break;
332  default:
333  $sSize = $myConfig->getConfigParam($sImgConf);
334  break;
335  }
336  if ($sSize) {
337  return explode('*', $sSize);
338  }
339  }
340 
349  protected function _copyFile($sSource, $sTarget)
350  {
351  $blDone = false;
352 
353  if ($sSource === $sTarget) {
354  $blDone = true;
355  } else {
356  $blDone = copy($sSource, $sTarget);
357  }
358 
359  if ($blDone) {
360  $blDone = @chmod($sTarget, 0644);
361  }
362 
363  return $blDone;
364  }
365 
374  protected function _moveImage($sSource, $sTarget)
375  {
376  $blDone = false;
377  if (!is_dir(dirname($sTarget))) {
378  mkdir(dirname($sTarget), 0744, true);
379  }
380  if ($sSource === $sTarget) {
381  $blDone = true;
382  } else {
383  $blDone = move_uploaded_file($sSource, $sTarget);
384  }
385 
386  if ($blDone) {
387  $blDone = @chmod($sTarget, 0644);
388  }
389 
390  return $blDone;
391  }
392 
404  public function processFiles($oObject = null, $aFiles = array(), $blUseMasterImage = false, $blUnique = true)
405  {
406  $aFiles = $aFiles ? $aFiles : $_FILES;
407  if (isset($aFiles['myfile']['name'])) {
408 
409  $oConfig = $this->getConfig();
410  $oStr = getStr();
411 
412  // A. protection for demoshops - strictly defining allowed file extensions
413  $blDemo = (bool) $oConfig->isDemoShop();
414 
415  // folder where images will be processed
416  $sTmpFolder = $oConfig->getConfigParam("sCompileDir");
417 
418  $iNewFilesCounter = 0;
419  $aSource = $aFiles['myfile']['tmp_name'];
420  $aError = $aFiles['myfile']['error'];
421  $sErrorsDescription = '';
422 
423  $oEx = oxNew("oxExceptionToDisplay");
424  // process all files
425  while (list($sKey, $sValue) = each($aFiles['myfile']['name'])) {
426 
427  $sSource = $aSource[$sKey];
428  $iError = $aError[$sKey];
429  $aFiletype = explode("@", $sKey);
430  $sKey = $aFiletype[1];
431  $sType = $aFiletype[0];
432 
433  $sValue = strtolower($sValue);
434  $sImagePath = $this->_getImagePath($sType);
435 
436  // Should translate error to user if file was uploaded
437  if (UPLOAD_ERR_OK !== $iError && UPLOAD_ERR_NO_FILE !== $iError) {
438  $sErrorsDescription = $this->translateError($iError);
439  $oEx->setMessage($sErrorsDescription);
440  oxRegistry::get("oxUtilsView")->addErrorToDisplay($oEx, false);
441  }
442 
443  // checking file type and building final file name
444  if ($sSource && ($sValue = $this->_prepareImageName($sValue, $sType, $blDemo, $sImagePath, $blUnique))) {
445  // moving to tmp folder for processing as safe mode or spec. open_basedir setup
446  // usually does not allow file modification in php's temp folder
447  $sProcessPath = $sTmpFolder . basename($sSource);
448 
449  if ($sProcessPath) {
450 
451  if ($blUseMasterImage) {
452  //using master image as source, so only copying it to
453  $blMoved = $this->_copyFile($sSource, $sImagePath . $sValue);
454  } else {
455  $blMoved = $this->_moveImage($sSource, $sImagePath . $sValue);
456  }
457 
458  if ($blMoved) {
459  // New image successfully add.
460  $iNewFilesCounter++;
461  // assign the name
462  if ($oObject && isset($oObject->$sKey)) {
463  $oObject->{$sKey}->setValue($sValue);
464  }
465  }
466  }
467  }
468  }
469 
470  $this->_setNewFilesCounter($iNewFilesCounter);
471  }
472 
473  return $oObject;
474  }
475 
484  public function checkFile($sFile)
485  {
486  $aCheckCache = oxRegistry::getSession()->getVariable("checkcache");
487 
488  if (isset($aCheckCache[$sFile])) {
489  return $aCheckCache[$sFile];
490  }
491 
492  $blRet = false;
493 
494  if (is_readable($sFile)) {
495  $blRet = true;
496  } else {
497  // try again via socket
498  $blRet = $this->urlValidate($sFile);
499  }
500 
501  $aCheckCache[$sFile] = $blRet;
502  oxRegistry::getSession()->setVariable("checkcache", $aCheckCache);
503 
504  return $blRet;
505  }
506 
514  public function urlValidate($sLink)
515  {
516  $aUrlParts = @parse_url($sLink);
517  $sHost = (isset($aUrlParts["host"]) && $aUrlParts["host"]) ? $aUrlParts["host"] : null;
518 
519  $blValid = false;
520  if ($sHost) {
521  $sDocumentPath = (isset($aUrlParts["path"]) && $aUrlParts["path"]) ? $aUrlParts["path"] : '/';
522  $sDocumentPath .= (isset($aUrlParts["query"]) && $aUrlParts["query"]) ? '?' . $aUrlParts["query"] : '';
523 
524  $sPort = (isset($aUrlParts["port"]) && $aUrlParts["port"]) ? $aUrlParts["port"] : '80';
525 
526  // Now (HTTP-)GET $documentpath at $sHost";
527  if (($oConn = @fsockopen($sHost, $sPort, $iErrNo, $sErrStr, 30))) {
528  fwrite($oConn, "HEAD {$sDocumentPath} HTTP/1.0\r\nHost: {$sHost}\r\n\r\n");
529  $sResponse = fgets($oConn, 22);
530  fclose($oConn);
531 
532  if (preg_match("/200 OK/", $sResponse)) {
533  $blValid = true;
534  }
535  }
536  }
537 
538  return $blValid;
539  }
540 
551  public function processFile($sFileName, $sUploadPath)
552  {
553  $aFileInfo = $_FILES[$sFileName];
554 
555  $sBasePath = $this->getConfig()->getConfigParam('sShopDir');
556 
557  //checking params
558  if (!isset($aFileInfo['name']) || !isset($aFileInfo['tmp_name'])) {
559  throw oxNew("oxException", 'EXCEPTION_NOFILE');
560  }
561 
562  //wrong chars in file name?
563  if (!getStr()->preg_match('/^[\-_a-z0-9\.]+$/i', $aFileInfo['name'])) {
564  throw oxNew("oxException", 'EXCEPTION_FILENAMEINVALIDCHARS');
565  }
566 
567  // error uploading file ?
568  if (isset($aFileInfo['error']) && $aFileInfo['error']) {
569  throw oxNew("oxException", 'EXCEPTION_FILEUPLOADERROR_' . ((int) $aFileInfo['error']));
570  }
571 
572  $aPathInfo = pathinfo($aFileInfo['name']);
573 
574  $sExt = $aPathInfo['extension'];
575  $sFileName = $aPathInfo['filename'];
576 
577  $aAllowedUploadTypes = (array) $this->getConfig()->getConfigParam('aAllowedUploadTypes');
578  $aAllowedUploadTypes = array_map("strtolower", $aAllowedUploadTypes);
579 
580  if (!in_array(strtolower($sExt), $aAllowedUploadTypes)) {
581  throw oxNew("oxException", 'EXCEPTION_NOTALLOWEDTYPE');
582  }
583 
584  $sFileName = $this->_getUniqueFileName($sBasePath . $sUploadPath, $sFileName, $sExt);
585 
586  if ($this->_moveImage($aFileInfo['tmp_name'], $sBasePath . $sUploadPath . "/" . $sFileName)) {
587  return $sFileName;
588  } else {
589  return false;
590  }
591  }
592 
605  protected function _getUniqueFileName($sFilePath, $sFileName, $sFileExt, $sSufix = "", $blUnique = true)
606  {
607  $sFilePath = $this->normalizeDir($sFilePath);
608  $iFileCounter = 0;
609  $sTempFileName = $sFileName;
610  $oStr = getStr();
611 
612  //file exists ?
613  while ($blUnique && file_exists($sFilePath . "/" . $sFileName . $sSufix . "." . $sFileExt)) {
614  $iFileCounter++;
615 
616  //removing "(any digit)" from file name end
617  $sTempFileName = $oStr->preg_replace("/\(" . $iFileCounter . "\)/", "", $sTempFileName);
618 
619  $sFileName = $sTempFileName . "($iFileCounter)";
620  }
621 
622  return $sFileName . $sSufix . "." . $sFileExt;
623  }
624 
633  public function getImageDirByType($sType, $blGenerated = false)
634  {
635  $sFolder = array_key_exists($sType, $this->_aTypeToPath) ? $this->_aTypeToPath[$sType] : '0';
636  $sDir = $this->normalizeDir($sFolder);
637 
638  if ($blGenerated === true) {
639  $sDir = str_replace('master/', 'generated/', $sDir);
640  }
641 
642  return $sDir;
643  }
644 
652  public function translateError($iError)
653  {
654  $message = '';
655  // Translate only if translation exist
656  if ($iError > 0 && $iError < 9 && 5 !== $iError) {
657  $message = 'EXCEPTION_FILEUPLOADERROR_' . ((int) $iError);
658  }
659 
660  return $message;
661  }
662 }