/**
* check dependencies of an item.
*
* @param Item $item
* @param string $epId
*/
protected function _checkDependencies(Item $item)
{
if (isset($this->circularDependencyTracker[$item->getName()])) {
throw new ItemException('Circular dependency! Cannot process the item ' . $item->getName(), $item, 1);
}
$this->circularDependencyTracker[$item->getName()] = true;
$missingItems = array();
foreach ($item->getDependencies() as $depItemName => $depItemVersion) {
$depItem = null;
if (isset($this->items[$depItemName])) {
$depItem = $this->items[$depItemName];
} else {
$missingItems[] = $depItemName;
continue;
}
if ($depItem->getAction() == self::ACTION_REMOVE) {
throw new ItemException('Item ' . $depItemName . ', needed by item ' . $item->getName() . ', should be removed at the same time', $item, 3, $depItem);
}
if (isset($this->checkedItems[$depItemName])) {
continue;
}
if ($depItem->getAction() == self::ACTION_NONE) {
$version = $depItem->getCurrentVersion();
if (!VersionComparator::compareVersionRange($version, $depItemVersion)) {
throw new ItemException("Version of item '" . $depItemName . "' does not match required version by item " . $item->getName(), $item, 2, $depItem);
}
if (!$depItem->isInstalled()) {
$depItem->setAction(self::ACTION_INSTALL);
$this->_checkDependencies($depItem);
$this->chain[] = $depItem;
}
} elseif ($depItem->getAction() == self::ACTION_INSTALL) {
$version = $depItem->getCurrentVersion();
if (!VersionComparator::compareVersionRange($version, $depItemVersion)) {
throw new ItemException("Version of item '" . $depItemName . "' does not match required version by item " . $item->getName(), $item, 2, $depItem);
}
$this->_checkDependencies($depItem);
$this->chain[] = $depItem;
} elseif ($depItem->getAction() == self::ACTION_UPGRADE) {
$version = $depItem->getNextVersion();
if (!VersionComparator::compareVersionRange($version, $depItemVersion)) {
throw new ItemException("Version of item '" . $depItemName . "' does not match required version by item " . $item->getName(), $item, 2, $depItem);
}
$this->_checkDependencies($depItem);
$this->chain[] = $depItem;
}
}
$this->checkedItems[$item->getName()] = true;
unset($this->circularDependencyTracker[$item->getName()]);
if ($missingItems) {
throw new ItemException('For item ' . $item->getName() . ', some items are missing :' . implode(',', $missingItems), $item, 6, $missingItems);
}
}