This isn't tested, so take it with a grain of salt, but I think it should work :
class Mage_Catalog_Block_Product_List_Random extends Mage_Catalog_Block_Product_List
{
protected function _getProductCollection()
{
if (is_null($this->_productCollection)) {
$categoryID = $this->getCategoryId();
if($categoryID)
{
// Get array of subcategory ids
$subCatArray = array();
$catModel = Mage::getModel('catalog/category');
$children = $catModel->getChildrenCategories($categoryID);
foreach ($children as $subcat) {
$id = $subcat->getId();
array_push($subCatArray, $id);
}
// Use the array to filter the collection
$collection = Mage::getModel('catalog/product')
->getCollection()
->joinField(
'category_id', 'catalog/category_product', 'category_id',
'product_id = entity_id', null, 'left'
)
->addAttributeToSelect('*')
->addAttributeToFilter('category_id', array(
array('in' => $subCatArray),
));
//Add Distinct to Select in case you have products in more than one of the child categories.
$collection->getSelect()->distinct();
} else {
$collection = Mage::getResourceModel('catalog/product_collection');
}
Mage::getModel('catalog/layer')->prepareProductCollection($collection);
$collection->getSelect()->order('rand()');
$collection->addStoreFilter();
$numProducts = $this->getNumProducts() ? $this->getNumProducts() : 3;
$collection->setPage(1, $numProducts)->load();
$this->_productCollection = $collection;
}
return $this->_productCollection;
}
}
I'm not sure about the timing on calling $collection->getSelect()->distinct();
- if your products aren't assigned to multiple categories that bit is unnecessary.