virtuemart_media_id = $id; if(!isset(self::$theme_url)){ self::$theme_url = VmConfig::get('vm_themeurl',0); if(empty(self::$theme_url)){ self::$theme_url = 'components/com_virtuemart/'; } } $this->setRealImageSize = VmConfig::get('setRealImageSize',1); } /** * The type of the media determines the used path for storing them * * @author Max Milbers * @param string $type type of the media, allowed values product, category, shop, vendor, manufacturer, forSale */ public function getMediaUrlByView($type){ //the problem is here, that we use for autocreatoin the name of the model, here products //But for storing we use the product to build automatically the table out of it (product_medias) $choosed = false; if($type == 'product' || $type == 'products'){ $relUrl = VmConfig::get('media_product_path'); $choosed = true; } else if($type == 'category' || $type == 'categories'){ $relUrl = VmConfig::get('media_category_path'); $choosed = true; } else if($type == 'shop'){ $relUrl = VmConfig::get('media_path'); $choosed = true; } else if($type == 'vendor' || $type == 'vendors'){ $relUrl = VmConfig::get('media_vendor_path'); $choosed = true; } else if($type == 'manufacturer' || $type == 'manufacturers'){ $relUrl = VmConfig::get('media_manufacturer_path'); $choosed = true; } else if($type == 'forSale' || $type== 'file_is_forSale'){ $relUrl = shopFunctions::checkSafePath(); if($relUrl){ $choosed = true; $this->file_is_forSale=1; } } if($choosed && empty($relUrl)){ $link =JURI::root() . 'administrator/index.php?option=com_virtuemart&view=config'; vmInfo('COM_VIRTUEMART_MEDIA_NO_PATH_TYPE',$type,$link ); //Todo add general media_path to config //$relUrl = VmConfig::get('media_path'); $relUrl = self::getStoriesFb('typeless').'/'; $this->setRole=true; // } else if(!$choosed and empty($relUrl) and $this->file_is_forSale==0){ } else if(!$choosed and empty($relUrl) ){ if(empty($this->file_type) and !empty($this->file_url)){ vmAdminInfo('COM_VIRTUEMART_MEDIA_CHOOSE_TYPE',$this->file_title ); // vmError('Ignore this message, when it appears while the media synchronisation process, else report to http://forum.virtuemart.net/index.php?board=127.0 : cant create media of unknown type, a programmers error, used type ',$type); } $relUrl = self::getStoriesFb('typeless').'/'; $this->setRole=true; } else if(!$choosed and $this->file_is_forSale==1){ $relUrl = ''; $this->setRole=false; } return $relUrl; } static function getStoriesFb($suffix = ''){ if(!isset(self::$url[$suffix])){ self::$url[$suffix] = 'images/virtuemart/'. $suffix ; if(JFolder::exists(VMPATH_ROOT .'/'.self::$url[$suffix])) { return self::$url[$suffix]; } else { $urlOld = 'images/stories/virtuemart/'. $suffix; if(JFolder::exists(VMPATH_ROOT .'/'.$urlOld)){ self::$url[$suffix] = $urlOld; return $urlOld; } } if(JFolder::create(VMPATH_ROOT .'/'.self::$url[$suffix])) { return self::$url[$suffix]; } else { self::$url[$suffix] = false; return false; } } else { return self::$url[$suffix]; } } /** * This function determines the type of a media and creates it. * When you want to write a child class of the mediahandler, you need to manipulate this function. * We may use later here a hook for plugins or simular * * @author Max Milbers * @param object $table * @param string $type vendor,product,category,... * @param string $file_mimetype such as image/jpeg */ static public function createMedia($table,$type='',$file_mimetype=''){ $isImage = self::isImage($table->file_url); if($isImage){ $media = new VmImage(); } else { $media = new VmMediaHandler(); } $attribsImage = $table->getProperties(); foreach($attribsImage as $k=>$v){ $media->{$k} = $v; } if(empty($type)){ $type = $media->file_type; } else { $media->file_type = $type; } $media->setFileInfo($type); return $media; } /** * This prepares the object for storing the data. This means it does the action * and returns the data for storing in the table * * @author Max Milbers * @param object $table * @param array $data * @param string $type */ static public function prepareStoreMedia($table,$data,$type){ $media = VmMediaHandler::createMedia($table,$type); $data = $media->processAttributes($data); $data = $media->processAction($data); if($data===false) return false; $attribsImage = get_object_vars($media); foreach($attribsImage as $k=>$v){ $data[$k] = $v; } return $data; } /** * Sets the file information and paths/urls and so on. * * @author Max Milbers * @param unknown_type $filename * @param unknown_type $url * @param unknown_type $path */ function setFileInfo($type=0){ $this->file_url_folder = ''; $this->file_path_folder = ''; $this->file_url_folder_thumb = ''; if( substr( $this->file_url, 0, 2) == "//" ) { $rdspos = strrpos($this->file_url,'/'); if($rdspos!==false){ $this->file_name = substr($this->file_url,$rdspos+1); $rdspos = strrpos($this->file_name,'.'); if($rdspos!==false){ $this->file_extension = strtolower(JFile::getExt($this->file_name)); $this->file_name = substr($this->file_name, 0,$rdspos); } }else { vmdebug('$name',$this->file_url); } //vmdebug('Remote image URL, created file_name',$this->file_name,$this->file_extension); } if($this->file_is_forSale==0 and $type!='forSale'){ $this->file_url_folder = $this->getMediaUrlByView($type); $this->file_url_folder_thumb = $this->file_url_folder.'resized/'; $this->file_path_folder = str_replace('/',DS,$this->file_url_folder); } else { $safePath = shopFunctions::checkSafePathBase(); if(!$safePath){ return FALSE; } $this->file_path_folder = $safePath; $this->file_url_folder = $this->file_path_folder;//str_replace(DS,'/',$this->file_path_folder); $this->file_url_folder_thumb = VmConfig::get('forSale_path_thumb'); } //Clean from possible injection while(strpos($this->file_path_folder,'..')!==false){ $this->file_path_folder = str_replace('..', '', $this->file_path_folder); }; $this->file_path_folder = preg_replace('#[/\\\\]+#', DS, $this->file_path_folder); if(empty($this->file_url)){ $this->file_url = $this->file_url_folder; $this->file_name = ''; $this->file_extension = ''; } else { if( substr( $this->file_url, 0, 2) == "//" ) { $name = ''; // so that the !empty($name ..) case is not executed } else if($this->file_is_forSale==1){ $rdspos = strrpos($this->file_url,DS); if($rdspos!==false){ $name = substr($this->file_url,$rdspos+1); }else { vmdebug('$name',$this->file_url,$rdspos); } } else { //This construction is only valid for the images, it is for own structuring using folders $name = str_replace($this->file_url_folder,'',$this->file_url); } if(!empty($name) && $name !=='/'){ $this->file_name = JFile::stripExt($name); //$this->file_extension = strtolower(JFile::getExt($name)); $this->file_extension = strtolower(JFile::getExt($name)); //Ensure using right directory $file_url = $this->getMediaUrlByView($type).$name; if($this->file_is_forSale==1){ if(JFile::exists($file_url)){ $this->file_url = $file_url; } else { // vmdebug('MediaHandler, file does not exist in safepath '.$file_url); } } else { $pathToTest = VMPATH_ROOT.DS.str_replace('/',DS,$file_url); if(JFile::exists($pathToTest)){ $this->file_url = $file_url; } else { // vmdebug('MediaHandler, file does not exist in '.$pathToTest); } } } } //if($this->file_is_downloadable) $this->media_role = 'file_is_downloadable'; if($this->file_is_forSale) $this->media_role = 'file_is_forSale'; if(empty($this->media_role)) $this->media_role = 'file_is_displayable'; $this->determineFoldersToTest(); //Do we need this? /*if(!empty($this->file_url) && empty($this->file_url_thumb)){ $this->displayMediaThumb('',true,'',false); }*/ } public function getUrl(){ return $this->file_url_folder.$this->file_name.'.'.$this->file_extension; } public function getThumbUrl(){ return $this->file_url_folder_thumb.$this->file_name.'.'.$this->file_extension; } public function getFullPath(){ $rel_path = str_replace('/',DS,$this->file_url_folder); return VMPATH_ROOT.DS.$rel_path.$this->file_name.'.'.$this->file_extension; } public function getThumbPath(){ $rel_path = str_replace('/',DS,$this->file_url_folder); return VMPATH_ROOT.DS.$rel_path.$this->file_name_thumb.'.'.$this->file_extension; } /** * Tests if a function is an image by mime or extension * * @author Max Milbers * @param string $file_mimetype * @param string $file_extension */ static private function isImage($file_url){ $file_extension = strtolower(JFile::getExt($file_url)); if($file_extension == 'jpg' || $file_extension == 'jpeg' || $file_extension == 'png' || $file_extension == 'gif' || $file_extension == 'webp'){ $isImage = TRUE; } else { $isImage = FALSE; vmTrace('is no image '.$file_url); } return $isImage; } private $_foldersToTest = array(); /** * This functions adds the folders to test for each media, you can add more folders to test with * addFoldersToTest * @author Max Milbers */ public function determineFoldersToTest(){ if(VmAccess::manager('core')){ $r = ini_get('upload_tmp_dir') ? ini_get('upload_tmp_dir') : sys_get_temp_dir(); $this->addFoldersToTest($r); } $file_path = str_replace('/',DS,$this->file_url_folder); if($this->file_is_forSale){ $this->addFoldersToTest($file_path); } else { $this->addFoldersToTest(VMPATH_ROOT.DS.$file_path); } $file_path_thumb = str_replace('/',DS,$this->file_url_folder_thumb); $this->addFoldersToTest(VMPATH_ROOT.DS.$file_path_thumb); } /** * Add complete paths here to test/display if their are writable * * @author Max Milbers * @param absolutepPath $folders */ public function addFoldersToTest($folders){ if(!is_array($folders)) $folders = (array) $folders; $this->_foldersToTest = array_merge($this->_foldersToTest, $folders); } /** * Displays for paths if they are writeable * You set the folders to test with the function addFoldersToTest * @author Max Milbers */ public function displayFoldersWriteAble(){ $style = 'text-align:left;margin-left:20px;'; $result = '
'; foreach( $this->_foldersToTest as $dir ) { $result .= $dir . ' :: '; $result .= is_writable( $dir ) ? ''.vmText::_('COM_VIRTUEMART_WRITABLE').'' : ''.vmText::_('COM_VIRTUEMART_UNWRITABLE').''; $result .= '
'; } $result .= '
'; return $result; } /** * Shows the supported file types for the server * * @author enyo 06-Nov-2003 03:32 http://www.php.net/manual/en/function.imagetypes.php * @author Max Milbers * @return multitype:string */ function displaySupportedImageTypes() { $aSupportedTypes = array(); $aPossibleImageTypeBits = array(); if(defined('IMG_GIF')) { $aPossibleImageTypeBits[IMG_GIF] = 'GIF'; } if(defined('IMG_JPG')) { $aPossibleImageTypeBits[IMG_JPG] = 'JPG'; } if(defined('IMG_PNG')) { $aPossibleImageTypeBits[IMG_PNG] = 'PNG'; } if(defined('IMG_WBMP')) { $aPossibleImageTypeBits[IMG_WBMP] = 'WBMP'; } if(defined('IMG_WEBP')) { $aPossibleImageTypeBits[IMG_WEBP] = 'WEBP'; } foreach ($aPossibleImageTypeBits as $iImageTypeBits => $sImageTypeString) { if(function_exists('imagetypes')){ if (imagetypes() & $iImageTypeBits) { $aSupportedTypes[] = $sImageTypeString; } } } $supportedTypes = ''; if(function_exists('mime_content_type')){ $supportedTypes .= vmText::_('COM_VIRTUEMART_FILES_FORM_MIME_CONTENT_TYPE_SUPPORTED').'
'; } else { $supportedTypes .= vmText::_('COM_VIRTUEMART_FILES_FORM_MIME_CONTENT_TYPE_NOT_SUPPORTED').'
'; } $supportedTypes .= vmText::_('COM_VIRTUEMART_FILES_FORM_IMAGETYPES_SUPPORTED'). implode(', ', $aSupportedTypes); return $supportedTypes; } function imageArgsToArray($imageArgs){ /*if(empty($imageArgs)){ $imageArgs = array('class' => $this->file_class); } else {*/ if(!is_array($imageArgs)) { $parts = explode('=', $imageArgs); //vmdebug('filterImageArgs my image $parts ',$imageArgs,$parts); $imageArgs = array(); $first = true; $keyV = ''; $count = count($parts); $i = 0; foreach ($parts as $part) { if ($first) { $newKey = $keyV = trim($part); $first = false; } else { $tmpParts = explode(' ',$part); if(is_array($tmpParts)){ if($i<($count-1)){ $newKey = array_pop($tmpParts); $value = trim(implode(' ',$tmpParts)); $imageArgs[$keyV] = trim($value,'"'); $keyV = $newKey; } else { $value = trim(implode(' ',$tmpParts)); $imageArgs[$newKey] = trim($value,'"'); } } } $i++; } //vmdebug('filterImageArgs my image args filtered',$imageArgs); } //vmdebug('my image args u',$imageArgs); //$imageArgs = str_replace(array('class','"','=',"'"),'',$imageArgs); //} if(!empty($this->file_class)){ if(!isset($imageArgs['class'])){ $imageArgs['class'] = ''; } $imageArgs['class'] .= ' '.$this->file_class; //vmdebug('filterImageArgs $this->file_class added',$imageArgs); } return $imageArgs; } /** * Just for overwriting purpose for childs. Take a look on VmImage to see an example * * @author Max Milbers */ function displayMediaFull($imageArgs=array('id'=>'vm_display_image'), $lightbox=false, $effect ="class='modal'",$description = true){ return $this->displayMediaThumb($imageArgs ,$lightbox,$effect,true,$description); } function setNoImageSet(){ /*if($this->file_is_downloadable){ $file_name = VmConfig::get('downloadable','zip.png'); } else {*/ $file_name = VmConfig::get('no_image_set','noimage_new.gif'); //} //vmTrace('SetNoImageSet'); $this->file_name = JFile::stripExt($file_name); $this->file_url_folder = self::$theme_url.'assets/images/vmgeneral/'; $this->file_url = $this->file_url_folder.$file_name; $this->file_path_folder = VMPATH_ROOT.'/'.str_replace('/',DS, $this->file_url_folder); $this->file_url_folder_thumb = self::getStoriesFb('typeless').'/'; //$this->file_meta = vmText::_('COM_VIRTUEMART_NO_IMAGE_SET').' '.$this->file_description; $this->file_extension = strtolower(JFile::getExt($file_name)); $this->noImageSet = true; } /** * This function displays the image, when the image is not already a resized one, * it tries to get first the resized one, or create a resized one or fallback in case * * @author Max Milbers * * @param string $imageArgs Attributes to be included in the tag. * @param boolean $lightbox alternative display method * @param string $effect alternative lightbox display * @param boolean $withDesc display the image media description */ function displayMediaThumb($imageArgs=array(),$lightbox=true,$effect="rel='group'",$return = true,$withDescr = false,$absUrl = false, $width=0,$height=0){ $imageArgs = $this->imageArgsToArray($imageArgs); $typelessUrl = ''; if(empty($this->file_name) or empty($this->file_url)){ vmdebug('displayMediaThumb empty file name or url '.$this->virtuemart_media_id,$this->file_name,$this->file_url); $typelessUrl = static::getStoriesFb('typeless').'/'; $this->setNoImageSet(); } if( substr( $this->file_url, 0, 2) == "//" ) { $toChk = $this->file_url; try { $resObj = VmConnector::getHttp(array(), array('curl', 'stream'))->get($toChk); //vmdebug('Object per URL',$resObj); if($resObj->code!=200){ vmdebug('URL does not exists',$toChk,$resObj); vmError(vmText::sprintf('COM_VIRTUEMART_FILE_NOT_FOUND',$toChk)); }; } catch (RuntimeException $e) { vmError(vmText::sprintf('COM_VIRTUEMART_FILE_NOT_FOUND',$toChk)); } } else { if($this->file_is_forSale){ $toChk = $this->file_url; } else { $toChk = VMPATH_ROOT.'/'.$this->file_url; } if(empty($typelessUrl) and !JFile::exists($toChk)){ vmdebug('Media file does not exists',$toChk); vmError(vmText::sprintf('COM_VIRTUEMART_FILE_NOT_FOUND',$toChk)); } } if ($this->setRealImageSize) { if(empty($width) and !empty($imageArgs['width'])){ $width = $imageArgs['width']; } if(empty($height) and !empty($imageArgs['height'])){ $height = $imageArgs['height']; } } $file_url_thumb = $this -> getFileUrlThumb($width, $height); $media_path = VMPATH_ROOT.DS.str_replace('/',DS,$file_url_thumb); if(empty($this->file_meta)){ if(!empty($this->file_description)){ $file_alt = $this->file_description; } else if(!empty($this->file_name)) { $file_alt = $this->file_name; } else { $file_alt = vmText::_('COM_VIRTUEMART_NO_IMAGE_SET'); } } else { $file_alt = $this->file_meta; } if ((empty($file_url_thumb) || !file_exists($media_path)) && is_a($this,'VmImage')) { $file_url_thumb = $this->createThumb($width,$height); if(!empty($file_url_thumb)){ $media_path = VMPATH_ROOT.DS.str_replace('/',DS,$file_url_thumb); } else { $media_path = ''; } } //$this->file_url_thumb = $file_url_thumb; if ($this->setRealImageSize and (empty($width) or empty($height))) { if (file_exists($file_url_thumb)) { // Spiros //vmStartTimer('thumbs'); //vmSetStartTime('thumbs1'); $sizeAttr = getimagesize($file_url_thumb); $imageArgs['width'] = $sizeAttr[0]; $imageArgs['height'] = $sizeAttr[1]; //vmTime('Thumping','thumbs'); //vmTime('Thumping1','thumbs1'); } } else { $imageArgs['width'] = $width; $imageArgs['height'] = $height; } if($withDescr) $withDescr = $this->file_description; if (empty($file_url_thumb) || !file_exists($media_path)) { return $this->getIcon($imageArgs,$lightbox,$return,$withDescr,$absUrl); } if($return) return $this->displayIt($file_url_thumb, $file_alt, $imageArgs,$lightbox,$effect,$withDescr,$absUrl); } function getFileUrlThumb($width = 0,$height = 0){ if(!empty($this->file_url_thumb)){ $file_url_thumb = $this->file_url_thumb; } else if(is_a($this,'VmImage')) { $file_url_thumb = $this->createThumbFileUrl($width,$height); } else { vmdebug('No image '.$this->file_name); $file_url_thumb = ''; } return $file_url_thumb; } /** * This function should return later also an icon, if there isnt any automatic thumbnail creation possible * like pdf, zip, ... * * @author Max Milbers * @param string $imageArgs * @param boolean $lightbox */ function getIcon($imageArgs,$lightbox,$return=false,$withDescr=false,$absUrl = false){ $file_url = false; $file_alt = false; static $exists = array(); $tC = self::$theme_url.'assets/images/vmgeneral/filetype_'.$this->file_extension.'.png'; if(!empty($this->file_extension)){ $file_alt = $this->file_description; if(!isset($exists[$this->file_extension])){ $exists[$this->file_extension] = file_exists($tC); } if($exists[$this->file_extension]){ $file_url = $tC; } } if(!$file_url){ $file_url = self::$theme_url.'assets/images/vmgeneral/'.VmConfig::get('no_image_found'); $file_alt = vmText::_('COM_VIRTUEMART_NO_IMAGE_FOUND').' '.$this->file_description; } if($return){ /*if($this->file_is_downloadable){ return $this->displayIt($file_url, $file_alt, '',true,'',$withDescr,$absUrl); } else {*/ return $this->displayIt($file_url, $file_alt, $imageArgs,$lightbox,'',$withDescr,$absUrl); //} } } /** * This function is just for options how to display an image... * we may add here plugins for displaying images * * @author Max Milbers * @param string $file_url relative Url * @param string $file_alt media description * @param string $imageArgs attributes for displaying the images * @param boolean $lightbox use lightbox */ function displayIt($file_url, $file_alt, $imageArgs, $lightbox, $effect ="class='modal'",$withDesc=false,$absUrl = false){ if ($withDesc) $desc=''.$withDesc.''; else $desc=''; $root=''; if( substr( $this->file_url, 0, 2) == "//" ) { $root = '';//JURI::root(true).'/';; } else if($absUrl){ $root = JURI::root(false); } else { $root = JURI::root(true).'/'; } if(!isset(VmConfig::$lazyLoad)){ if(VmConfig::get('lazyLoad',false)){ VmConfig::$lazyLoad = true;//'loading="lazy"'; } else { VmConfig::$lazyLoad = false; } } $imageArgs = $this->imageArgsToArray($imageArgs); if(VmConfig::$lazyLoad) { $imageArgs['loading'] = 'lazy'; } if(!isset($imageArgs['src'])) { $imageArgs['src'] = $root.$file_url; } else if($imageArgs['src']) { $imageArgs[$imageArgs['src']] = $root.$file_url; unset($imageArgs['src']); unset($imageArgs['loading']); } if(empty($imageArgs['alt']) and !empty($file_alt)){ $imageArgs['alt'] = $file_alt; } if ($this->setRealImageSize and (empty($imageArgs['width']) or empty($imageArgs['height']))) { // Spiros //vmStartTimer('thumbs2'); if (file_exists($this->file_url)){ $sizeAttr = getimagesize($this->file_url); if(isset($sizeAttr[0])){ $imageArgs['width'] = $sizeAttr[0]; } if(isset($sizeAttr[1])){ $imageArgs['height'] = $sizeAttr[1]; } } //vmTime('Thumping2','thumbs2'); } $args = ''; if(!empty($imageArgs)){ foreach($imageArgs as $k=>$v){ if(!empty($k) and !empty($v)){ $args .= ' '.$k.'="'.$v.'" '; } else if($k===0){ $args .= ' '.$v.' '; } } } $image = ''; if($lightbox){ if ($file_alt ) $file_alt = 'title="'.$file_alt.'"'; if ($this->file_url and pathinfo($this->file_url, PATHINFO_EXTENSION) and (substr( $this->file_url, 0, 4) != "http" or substr( $this->file_url, 0, 2) == "//")) { if($this->file_is_forSale ){ $href = $this->file_url ; } else { $href = JURI::root() .$this->file_url ; } } else { $href = $root.$file_url ; } /*if ($this->file_is_downloadable) { $lightboxImage = ''.$image.$desc.''; } else {*/ $lightboxImage = ''.$image.''; $lightboxImage = $lightboxImage.$desc; //} return $lightboxImage; } else { return $image . $desc; } } /** * Handles the upload process of a media, sets the mime_type, when success * * @author Max Milbers * @param string $urlfolder relative url of the folder where to store the media * @return name of the uploaded file */ function uploadFile($urlfolder,$overwrite = false){ $r = vmUploader::uploadFile($urlfolder,$this,$overwrite); return $r; } /** * Deletes a file * * @param string $url relative Url, gets adjusted to path */ function deleteFile($url, $absPathGiv = 0){ if(!vmAccess::manager('media.delete')){ vmWarn('Insufficient permissions to delete the media'); return false; } if(empty($url)){ vmTrace('deleteFile empty url was given'); return false; } $file_path = str_replace('/',DS,$url); if($absPathGiv){ //vmdebug('deleteFile absolut Path given',$file_path); } else { $file_path = VMPATH_ROOT.DS.$file_path; //vmdebug('deleteFile relative Path given',$file_path); } if(is_dir($file_path)){ vmTrace('deleteFile path given '.$file_path); return false; } $app = JFactory::getApplication(); $msg_path = ''; if(vmAccess::manager('core')){ $msg_path = $file_path; } if($res = JFile::delete( $file_path )){ $app->enqueueMessage(vmText::sprintf('COM_VIRTUEMART_FILE_DELETE_OK',$msg_path)); return true; } else { $app->enqueueMessage(vmText::sprintf('COM_VIRTUEMART_FILE_DELETE_ERR',$res.' '.$msg_path)); } return false; } function deleteThumbs(){ $oldFileUrlThumb = $this->getFileUrlThumb(); if(empty($oldFileUrlThumb)) return true; $filename = $this->file_name; if($this->file_is_forSale!=1){ $dir = VMPATH_ROOT.DS.$this->file_url_folder.'resized'; if($p = strpos($this->file_name,'/')){ $dir .= DS.substr($this->file_name,0,$p); $filename = substr($this->file_name,$p+1); } } else { $dir = VmConfig::get('forSale_path_thumb', false); $dir = VMPATH_ROOT.DS.rtrim($dir,'/'); } if(!is_dir($dir)){ $m = 'deleteThumbs: Attention directoy is not accessible (does not exists or wrong rights) '; vmError($m.$dir,$m); //continue; } if ($handle = opendir($dir)) { while (false !== ($file = readdir($handle))) { if(!empty($file) and strpos($file,'.')!==0 and $file != 'index.html' and !is_dir($dir.DS.$file)){ $hits = array(); $regex = "/".$filename.'_\d{1,4}x\d{1,4}.\S{1,3}'."/"; $res = preg_match($regex, $file, $hits); foreach($hits as $name){ $this->deleteFile($dir.DS.$name,true); } } } } $this->deleteFile($oldFileUrlThumb, false); } /** * Processes the choosed Action while storing the data, gets extend by the used child, use for the action clear commands. * Useable commands in all medias upload, upload_delete, delete, and all of them with _thumb on it also. * * @author Max Milbers * @param arraybyform $data */ function processAction($data){ if(empty($data['media_action'])) return $data; if( $data['media_action'] == 'upload' ){ $this->virtuemart_media_id=0; $this->file_url=''; $this->file_url_thumb=''; $file_name = $this->uploadFile($this->file_url_folder); if ($file_name===false) return false; $this->file_name = $file_name; $this->file_url = $this->file_url_folder.$this->file_name; } else if( $data['media_action'] == 'replace' ){ //always delete the thumb $this->deleteThumbs(); $oldFileUrl = $this->file_url; $file_name = $this->uploadFile($this->file_url_folder,true); if ($file_name===false) return false; $this->file_name = $file_name; $this->file_url = $this->file_url_folder.$this->file_name; if($this->file_url!=$oldFileUrl && !empty($this->file_name)){ $this->deleteFile($oldFileUrl,$this->file_is_forSale); } } else if( $data['media_action'] == 'replace_thumb' ){ //always delete the thumb $this->deleteThumbs(); $oldFileUrlThumb = $this->getFileUrlThumb(); $oldFileUrl = $this->file_url_folder_thumb; $file_name = $this->uploadFile($this->file_url_folder_thumb,true); if ($file_name===false) return false; $this->file_name = $file_name; $this->file_url_thumb = $this->file_url_folder_thumb.$this->file_name; if($this->file_url_thumb!=$oldFileUrl&& !empty($this->file_name)){ $this->deleteFile($oldFileUrlThumb); } } else if( $data['media_action'] == 'delete' ){ //TODO this is complex, we must assure that the media entry gets also deleted. $mediaM = VmModel::getModel('media'); $mediaM->removeFiles($this->virtuemart_media_id); //unset($data['active_media_id']); } if(empty($this->file_title) && !empty($file_name)) $this->file_title = $file_name; return $data; } /** * For processing the Attributes of the media while the storing process * * @author Max Milbers * @param unknown_type $data */ function processAttributes($data){ $this->file_is_product_image = 0; $this->file_is_downloadable = 0; if(empty($data['media_roles'])) return $data; /*if($data['media_roles'] == 'file_is_downloadable'){ $this->file_is_downloadable = 1; $this->file_is_forSale = 0; } else */if($data['media_roles'] == 'file_is_forSale'){ $this->file_is_downloadable = 0; $this->file_is_forSale = 1; $this->file_url_folder = VmConfig::get('forSale_path'); $this->file_url_folder_thumb = VmConfig::get('forSale_path_thumb'); $this->setRole = false; } if($this->setRole and $data['media_roles'] != 'file_is_forSale'){ $this->file_url_folder = $this->getMediaUrlByView($data['media_attributes']); //media_roles $this->file_url_folder_thumb = $this->file_url_folder.'resized/'; $typelessUrl = static::getStoriesFb('typeless').'/'.$this->file_name; vmdebug('the Urls',$data['media_roles'],$typelessUrl,$this->file_url_folder.$this->file_name); if(!file_exists($this->file_url_folder.$this->file_name) and file_exists($typelessUrl)){ vmdebug('Execute move'); JFile::move($typelessUrl, $this->file_url_folder.$this->file_name); } } if(!empty($data['active_languages'])) { $active_languages = implode(",", $data['active_languages']); $this->file_lang = $active_languages; } return $data; } public $_actions = array(); /** * This method can be used to add extra actions to the media * * @author Max Milbers * @param string $optionName this is the value in the form * @param string $langkey the langkey used */ function addMediaAction($optionName,$langkey){ $this->_actions[$optionName] = $langkey ; } /** * Adds the media action which are needed in the form for all media, * you can use this function in your child calling parent. Look in VmImage for an exampel * @author Max Milbers */ function addMediaActionByType(){ $this->addMediaAction(0,'COM_VIRTUEMART_NONE'); $view = vRequest::getCmd('view'); if($view!='media' or empty($this->virtuemart_media_id) /*or $this->noImageSet*/){ $this->addMediaAction('upload','COM_VIRTUEMART_FORM_MEDIA_UPLOAD'); } if(!empty($this->virtuemart_media_id) or (!empty($this->file_name) and !$this->noImageSet)){ $this->addMediaAction('replace','COM_VIRTUEMART_FORM_MEDIA_UPLOAD_REPLACE'); $this->addMediaAction('replace_thumb','COM_VIRTUEMART_FORM_MEDIA_UPLOAD_REPLACE_THUMB'); } } public $_mLocation = array(); /** * This method can be used to add extra attributes to the media * * @author Max Milbers * @param string $optionName this is the value in the form * @param string $langkey the langkey used */ public function addMediaAttributes($optionName,$langkey=''){ $this->_mLocation[$optionName] = $langkey ; } /** * Adds the attributes which are needed in the form for all media, * you can use this function in your child calling parent. Look in VmImage for an exampel * @author Max Milbers */ public function addMediaAttributesByType(){ if($this->setRole){ // $this->addMediaAttributes('file_is_product_image','COM_VIRTUEMART_FORM_MEDIA_SET_PRODUCT'); $this->addMediaAttributes('product','COM_VIRTUEMART_FORM_MEDIA_SET_PRODUCT'); // => file_is_displayable =>location $this->addMediaAttributes('category','COM_VIRTUEMART_FORM_MEDIA_SET_CATEGORY'); $this->addMediaAttributes('manufacturer','COM_VIRTUEMART_FORM_MEDIA_SET_MANUFACTURER'); $this->addMediaAttributes('vendor','COM_VIRTUEMART_FORM_MEDIA_SET_VENDOR'); $this->_mRoles['file_is_displayable'] = 'COM_VIRTUEMART_FORM_MEDIA_DISPLAYABLE' ; //$this->_mRoles['file_is_downloadable'] = 'COM_VIRTUEMART_FORM_MEDIA_DOWNLOADABLE' ; $this->_mRoles['file_is_forSale'] = 'COM_VIRTUEMART_FORM_MEDIA_SET_FORSALE' ; } else { if($this->file_is_forSale==1){ $this->_mRoles['file_is_forSale'] = 'COM_VIRTUEMART_FORM_MEDIA_SET_FORSALE' ; } else { $this->_mRoles['file_is_displayable'] = 'COM_VIRTUEMART_FORM_MEDIA_DISPLAYABLE' ; //$this->_mRoles['file_is_downloadable'] = 'COM_VIRTUEMART_FORM_MEDIA_DOWNLOADABLE' ; } } } private $_hidden = array(); /** * Use this to adjust the hidden fields of the displayFileHandler to your form * * @author Max Milbers * @param string $name for exampel view * @param string $value for exampel media */ public function addHidden($name, $value=''){ $this->_hidden[$name] = $value; } /** * Adds the hidden fields which are needed for the form in every case * @author Max Milbers */ public function addHiddenByType(){ $this->addHidden('media[active_media_id]',$this->virtuemart_media_id); $this->addHidden('option','com_virtuemart'); // $this->addHidden('file_mimetype',$this->file_mimetype); } /** * Displays file handler and file selector * * @author Max Milbers * @param array $fileIds */ public function displayFilesHandler($fileIds,$type,$vendorId = 0){ vmLanguage::loadJLang('com_virtuemart_media'); $html = $this->displayFileSelection($fileIds,$type); $html .= $this->displayFileHandler($vendorId); /*$db = JFactory::getDBO(); $db->setQuery('SELECT FOUND_ROWS()'); $imagetotal = $db->loadResult();*/ //vmJsApi::jQuery(array('easing-1.3.pack','mousewheel-3.0.4.pack','fancybox-1.3.4.pack'),'','fancybox'); //$j = "jQuery(document).ready(function(){ jQuery('#ImagesContainer').vm2admin('media','".$type."','0') }); " ; $j = 'if (typeof Virtuemart === "undefined") var Virtuemart = {}; Virtuemart.medialink = "'. vmURI::createUrlWithPrefix('index.php?option=com_virtuemart&view=media&format=json&mediatype='.$type) .'";'; $j .= "jQuery(document).ready(function(){ jQuery('#ImagesContainer').vmmedia('media','".$type."','0') }); " ; vmJsApi::addJScript('mediahandler.vars',$j); vmJsApi::mediaHandler(); return $html; } /** * Displays a possibility to select already uploaded media * the getImagesList must be adjusted to have more search functions * @author Max Milbers * @param array $fileIds */ public function displayFileSelection($fileIds,$type = 0){ $html=''; $html .= '
' ; $html .= ''.vmText::_('COM_VIRTUEMART_IMAGES').''; $html .= ''.vmText::_('COM_VIRTUEMART_SEARCH_MEDIA') . ''; $html .= ' 16 16 '; $html .='
'; $html .= '
'; if(!empty($fileIds)) { $model = VmModel::getModel('Media'); $medias = $model->createMediaByIds($fileIds, $type); foreach($medias as $k=>$id){ $html .= $this->displayImage($id,$k ); } } $html .= '
'; return $html.'
'; } function displayImage($image ,$key) { if (isset($image->file_url)) { //$image->file_root = JURI::root(true).'/'; //$image->msg = 'OK'; $file_url_thumb = $image->getFileUrlThumb(); $media_path = VMPATH_ROOT.DS.str_replace('/',DS,$image->file_url_thumb); if ((empty($image->file_url_thumb) || !file_exists($media_path)) && is_a($image,'VmImage')) { $file_url_thumb = $image->createThumb(); } return '
' . $image->file_title . '
'; } else { $fileTitle = empty($image->file_title)? 'no title':$image->file_title; return '
'.vmText::_('COM_VIRTUEMART_NO_IMAGE_SET').'
'.$fileTitle.'
'; } } static function displayImages($types ='',$page=0,$max=16 ) { $Images = array(); $list = VmMediaHandler::getImagesList($types,$page,$max); if (empty($list['images'])){ $Images[0]['label'] = vmText::_('COM_VIRTUEMART_NO_MEDIA_FILES'); $Images[0 ]['value'] = ''; return $Images; } foreach ($list['images'] as $key =>$image) { $htmlImages =''; $image->file_url_thumb = $image->getFileUrlThumb(); $media_path = VMPATH_ROOT.DS.str_replace('/',DS,$image->file_url_thumb); if ((empty($image->file_url_thumb) || !file_exists($media_path)) && is_a($image,'VmImage')) { $file_url_thumb = $image->createThumb(); } // quorvia modified to give text in the images and allow jquery 1.13.2 to function May 2023 if ($image->file_url_thumb > "0" ) { $htmlImages .= '
'; $htmlImages .= '
'.$image->file_title.'
'; $htmlImages .= ' '.JHtml::image($image->file_url_thumb,$image->file_title, ' title="'.$image->file_title.'" class="vm_thumb" ').''; } else { $htmlImages .= '
'.vmText::_('COM_VIRTUEMART_NO_IMAGE_SET').'
'.$image->file_title ; } $Images[$key ]['label'] = $htmlImages.'
'; $Images[$key ]['value'] = $image->file_title.' :: '.$image->virtuemart_media_id; } //$list['htmlImages'] = $htmlImages; return $Images; } /** * Retrieve a list of layouts from the default and chosen templates directory. * * We may use here the getFiles function of the media model or write something simular * @author Max Milbers * @param name of the view * @return object List of flypage objects */ static function getImagesList($type = '',$limit=0, $max=16) { $db = JFactory::getDBO(); $list = array(); $vendorId = vmAccess::isSuperVendor(); $q='SELECT SQL_CALC_FOUND_ROWS `virtuemart_media_id` FROM `#__virtuemart_medias` WHERE `published`=1 AND (`virtuemart_vendor_id`= "'.(int)$vendorId.'" OR `shared` = "1")'; if(!empty($type)){ $q .= ' AND `file_type` = "'.$type.'" '; } $search = trim(vRequest::getString('term', false)); if (!empty($search)){ $search = '"%' . $db->escape( $search, true ) . '%"' ; $q .= ' AND (`file_title` LIKE '.$search.' OR `file_description` LIKE '.$search.' OR `file_meta` LIKE '.$search.') '; } $q .= ' LIMIT '.(int)$limit.', '.(int)$max; $db->setQuery($q); if ($virtuemart_media_ids = $db->loadColumn()) { $model = VmModel::getModel('Media'); $db->setQuery('SELECT FOUND_ROWS()'); $list['total'] = $db->loadResult(); $list['images'] = $model->createMediaByIds($virtuemart_media_ids, $type); } else { $list['total'] = 0; $list['images'] = array(); } return $list; } /** * This displays a media handler. It displays the full and the thumb (icon) of the media. * It also gives a possibility to upload/change/thumbnail media * * @param string $imageArgs html atttributes, Just for displaying the fullsized image */ public function displayFileHandler($vendorId = 0){ vmLanguage::loadJLang('com_virtuemart_media'); $this->addHiddenByType(); $html = '
' ; $html .= ''.vmText::_('COM_VIRTUEMART_IMAGE_INFORMATION').''; $html .= '
'; $imageArgs = array('id'=>'vm_display_image'); $html .= $this->displayMediaFull($imageArgs,false,'',false).'
'; //This makes problems, when there is already a form, and there would be form in a form. breaks js in some browsers // $html .= '
'; $html .= ' '; if ($this->published || $this->virtuemart_media_id === 0){ $checked = 1; } else { $checked = 0; } $html .= ''; // The following was removed bacause the check box (publish/unpublish) was not functioning... // $this->media_published = $this->published; $html .= ''; $imgWidth = VmConfig::get('img_width',''); if(!empty($imgWidth)){ $imgWidth = 'width:'.VmConfig::get('img_width',90).'px;'; } else { $imgWidth = 'max-width:500px;width:auto;'; } $imgHeight = VmConfig::get('img_height',''); if(!empty($imgHeight)){ $imgHeight = 'height:'.VmConfig::get('img_height',90).'px;'; } else { $imgHeight = ''; } $minWidth = intval(VmConfig::get('img_width',90))+10; $html .= ''; $html .= ''; if(!vmAccess::manager('media')){ $readonly = 'readonly'; } else { $readonly = ''; } if($this->noImageSet) $this->file_url = ''; $html .= $this->displayRow('COM_VIRTUEMART_FILES_FORM_FILE_TITLE','file_title'); $html .= $this->displayRow('COM_VIRTUEMART_FILES_FORM_FILE_DESCRIPTION','file_description'); $html .= $this->displayRow('COM_VIRTUEMART_FILES_FORM_FILE_META','file_meta'); $html .= $this->displayRow('COM_VIRTUEMART_FILES_FORM_FILE_CLASS','file_class'); $html .= $this->displayRow('COM_VIRTUEMART_FILES_FORM_FILE_URL','file_url',$readonly); //remove the file_url_thumb in case it is standard $file_url_thumb = $this->getFileUrlThumb(); if(empty($this->file_url_thumb) and is_a($this,'VmImage')) { $file_url_thumb = vmText::sprintf('COM_VIRTUEMART_DEFAULT_URL',$file_url_thumb); $html .= ''; } else { $html .= $this->displayRow('COM_VIRTUEMART_FILES_FORM_FILE_URL_THUMB','file_url_thumb',$readonly,$file_url_thumb); } $this->addMediaAttributesByType(); $html .= ''; // $html .= ''; } else { $mediaattribtemp = $this->media_attributes; if(empty($this->media_attributes)){ $mediaattribtemp = 'product'; } $html .= ''; } // select language for image $active_languages = VmConfig::get('active_languages',array(VmConfig::$jDefLangTag)); if (count($active_languages)>1) { $selectedImageLangue = explode(",", $this->file_lang); $configM = VmModel::getModel('config'); $languages = $configM->getActiveLanguages($selectedImageLangue,'media[active_languages][]'); $html .= ''; } if(VmConfig::get('multix','none')!='none'){ if(empty($this->virtuemart_vendor_id) and $vendorId === 0){ $vendorId = vmAccess::isSuperVendor(); } else if(empty($vendorId)) { $vendorId = $this->virtuemart_vendor_id; } $vendorList = ShopFunctions::renderVendorList($vendorId, 'media[virtuemart_vendor_id]'); $html .= VmHTML::row('raw','COM_VIRTUEMART_VENDOR', $vendorList ); } $html .= '
'; $html .= VmHtml::checkbox('media[media_published]', $checked,1,0,'class="inputbox"','media[media_published]') ; // $html .=''; $thumbArgs = array('class'=>'vm_thumb_image','style'=>'overflow: auto;'.$imgWidth.$imgHeight); $html .= $this->displayMediaThumb($thumbArgs); //JHTML::image($this->file_url_thumb, 'thumbnail', 'id="vm_thumb_image" style="overflow: auto; float: right;"'); // $html .= $this->displayMediaThumb('',false,'id="vm_thumb_image" style="overflow: auto; float: right;"'); $html .= '
'.vmText::_('COM_VIRTUEMART_FILES_FORM_FILE_URL_THUMB').' '.vmText::sprintf('COM_VIRTUEMART_DEFAULT_URL','').'
'.vmText::_('COM_VIRTUEMART_FILES_FORM_ROLE').'
'.JHtml::_('select.radiolist', $this->getOptions($this->_mRoles), 'media[media_roles]', '', 'value', 'text', $this->media_role).'
'.VmHTML::checkbox('file_is_forSale', $this->file_is_forSale); // $html .= VmHTML::checkbox('file_is_downloadable', $this->file_is_downloadable); if(!empty($this->file_type)){ $html .= '
'.vmText::_('COM_VIRTUEMART_FILES_FORM_LOCATION').'
'.vmText::_('COM_VIRTUEMART_FORM_MEDIA_SET_'.strtoupper($this->file_type)).'
'.vmText::_('COM_VIRTUEMART_FILES_FORM_LOCATION').'
'.JHtml::_('select.radiolist', $this->getOptions($this->_mLocation), 'media[media_attributes]', '', 'value', 'text', $mediaattribtemp).'
' . vmText::_ ('COM_VIRTUEMART_FILES_FORM_LANGUAGE') . '
'.$languages.'
'; $html .='
'; $this->addMediaActionByType(); $html .= '
' ; $html .= ''.vmText::_('COM_VIRTUEMART_FILE_UPLOAD').''; $html .= vmText::_('COM_VIRTUEMART_IMAGE_ACTION'). JHtml::_('select.radiolist', $this->getOptions($this->_actions), 'media[media_action]', '', 'value', 'text', 0).'

'; $html .= vmText::_('COM_VIRTUEMART_FILE_UPLOAD').'
'; $html .= '
'.$this->displaySupportedImageTypes(); $html .='
'; $html .= $this->displayFoldersWriteAble(); $html .= $this->displayHidden(); // $html .= ''; return $html; } /** * child classes can add their own options and you can get them with this function * * @param array $optionsarray Allowed values are $this->_actions and $this->_attributes */ public function getOptions($optionsarray){ $options=array(); foreach($optionsarray as $optionName=>$langkey){ $options[] = JHtml::_('select.option', $optionName, vmText::_( $langkey ) ); } return $options; } /** * Just for creating simpel rows * * @author Max Milbers * @param string $descr * @param string $name */ private function displayRow($descr, $name,$readonly='',$value = null){ $v = (isset($value))? $value: $this->{$name}; $html = ' '.vmText::_($descr).' '; return $html; } /** * renders the hiddenfields added in the layout before (used to make the displayFileHandle reusable) * @author Max Milbers */ public function displayHidden(){ //vmdebug('displayHidden',$this->_hidden); $html=''; foreach($this->_hidden as $k=>$v){ $html .= ''; } return $html; } }