[BUG] VmMediaHandler::$theme_url is never assigned, breaking the "no image"

Started by sirius, July 08, 2026, 10:07:41 AM

Previous topic - Next topic

sirius

VmMediaHandler::$theme_url is never assigned, breaking the "no image" placeholder URL (front and admin)

Environment
  • VirtueMart 4.6.8
  • Joomla 5.4.6
  • PHP 8.1 / 8.5

Summary
The static property VmMediaHandler::$theme_url is declared as null and is never assigned anywhere in the codebase (I checked both the site and administrator sides, including the legacy VmMedia class). Because of that, every "no image" placeholder built from it resolves to a broken URL that is missing the components/com_virtuemart/ segment.

Where it happens
In administrator/components/com_virtuemart/helpers/mediahandler.php:

// line 45
static $theme_url = null;

// line 591, inside setNoImageSet()
$this->file_url_folder = self::$theme_url.'assets/images/vmgeneral/';

// line 736, inside getIcon()
$tC = self::$theme_url.'assets/images/vmgeneral/filetype_'.$this->file_extension.'.png';

// line 751, inside getIcon()
$file_url = self::$theme_url.'assets/images/vmgeneral/'.VmConfig::get('no_image_found');

Since $theme_url is always null, the concatenation collapses to just assets/images/vmgeneral/..., with the components/com_virtuemart/ prefix missing entirely.

Then in displayIt() (same file, around line 785):

if( substr( $this->file_url, 0, 2) == "//"  or substr( $this->file_url, 0, 4) == "http" ) {
} else if($absUrl){
$root = JURI::root(false);
} else {
$root = JURI::root(true).'/';
}
...
$imageArgs['src'] = $root.$file_url;

On a shop installed at the domain root, JURI::root(true) returns an empty string, so $root becomes just /. The final src ends up as:

/assets/images/vmgeneral/noimage_new.gif
instead of the correct:

/components/com_virtuemart/assets/images/vmgeneral/noimage_new.gif
The correct path is confirmed elsewhere in core, for example in administrator/components/com_virtuemart/models/config.php (around line 222), which hardcodes:

$dirs[] = VMPATH_ROOT.'/components/com_virtuemart/assets/images/vmgeneral';
Steps to reproduce
  • Create or open a manufacturer with no logo assigned.
  • Go to Manufacturer > Edit > Images tab.
  • Inspect the placeholder image: src="/assets/images/vmgeneral/noimage_new.gif", which 404s.

The same broken prefix affects any entity that falls back to setNoImageSet() or the getIcon() fallback (vendor, product, category, etc.) whenever no image/file is set, on both front and back end.

Suggested fix
Assign VmMediaHandler::$theme_url to 'components/com_virtuemart/' (the same segment already hardcoded in config.php) at class init, or replace the direct use of self::$theme_url in setNoImageSet() and getIcon() with a call that returns that path directly, since the property is currently dead weight that is only ever read, never written.

Happy to test a patch on a staging VM 4.6.8 / Joomla 5.4.6 install if useful.
J5.4.7 | PHP 8.4.10 + Redis + APC + Opcode
Litespeed | MariaDB 10.6.22
VM Prod : 4.6.8 11258 | VM Test : 4.9.3 11254