Exemplo n.º 1
0
 /**
  * Conflicts checker/solver.
  * When $amSolvedValues is null, it will only check for dependancies problems and throw exceptions.
  * When $amSolvedValues is not null, it must be an array of misc values, at the same indexes than $aoComponents.
  * If a solution is found, $amSolvedValues will be reorganized in the correct order.
  */
 private function doCheckOrSolveDependancies($aoComponents, $amSolvedValues = null, $nDepth = 0)
 {
     self::debug("solveDependancies() for " . $this->getSourceComponent()->getComponentName());
     // search for source/target indices...
     $nSourceComponentIndice = null;
     $nTargetComponentIndice = null;
     foreach ($aoComponents as $i => $oComponent) {
         if ($nSourceComponentIndice === null && $this->sourceComponentMatches($oComponent)) {
             $nSourceComponentIndice = $i;
         } else {
             if ($nTargetComponentIndice === null && $this->targetComponentMatches($oComponent)) {
                 $nTargetComponentIndice = $i;
             }
         }
         if ($nSourceComponentIndice !== null && $nTargetComponentIndice !== null) {
             break;
         }
     }
     if ($nSourceComponentIndice === null) {
         throw new AnwUnexpectedException("Source component not found");
         //should never happend
     }
     // begin dependancies resolution
     if ($nTargetComponentIndice !== null) {
         //the conflicting component has been found...
         if ($this->mSolution == self::SOLUTION_NONE) {
             // there is no solution
             self::debug("conflict between " . $this->getSourceComponent()->getComponentName() . " and " . $this->getTargetComponentName() . " : no solution");
             throw new AnwDependancyException(AnwComponent::g_editcontent("dependancy_conflict", array('component1' => $this->getSourceComponent()->getComponentName(), 'component2' => $this->getTargetComponentName())));
         } else {
             // there is a solution, we will try to apply it...
             $bSolvedValuesWereChanged = false;
             if ($this->mSolution == self::SOLUTION_LOAD_BEFORE && $nSourceComponentIndice < $nTargetComponentIndice || $this->mSolution == self::SOLUTION_LOAD_AFTER && $nSourceComponentIndice > $nTargetComponentIndice) {
                 // already solved
                 self::debug("conflict between " . $this->getSourceComponent()->getComponentName() . " and " . $this->getTargetComponentName() . " : already solved");
             } else {
                 self::debug("conflict between " . $this->getSourceComponent()->getComponentName() . " and " . $this->getTargetComponentName() . " : solvable");
                 if ($amSolvedValues !== null) {
                     // conflict can be solved by permuting the two components (must permute it in $aoComponents AND $amSolvedValues)
                     list($aoComponents, $amSolvedValues) = AnwUtils::permuteMultipleArrays(array($aoComponents, $amSolvedValues), $nSourceComponentIndice, $nTargetComponentIndice);
                     $bSolvedValuesWereChanged = true;
                 } else {
                     throw new AnwDependancyException(AnwComponent::g_editcontent("dependancy_conflict_unsolved", array('component1' => $this->getSourceComponent()->getComponentName(), 'component2' => $this->getTargetComponentName())));
                 }
             }
             if ($amSolvedValues !== null && $bSolvedValuesWereChanged) {
                 // we have to check again the whole values, to be sure that we didn't break a dependancy while reorganizing $amSolvedValues
                 $nDepth++;
                 if ($nDepth > 3) {
                     // we may be in an infinite dependancies problem... give up!
                     self::debug("amSolvedValues have changed, but nDepth exceeded");
                     throw new AnwDependancyException(AnwComponent::g_editcontent("dependancy_conflict_exceed", array('component1' => $this->getSourceComponent()->getComponentName(), 'component2' => $this->getTargetComponentName())));
                 } else {
                     self::debug("amSolvedValues have changed, checking again whole values");
                     $aoComponents = $this->doCheckOrSolveDependancies($aoComponents, $amSolvedValues, $nDepth);
                     //recursive call
                 }
             }
         }
     } else {
         //no dependancy problem
         self::debug("conflict between " . $this->getSourceComponent()->getComponentName() . " and " . $this->getTargetComponentName() . " : no dependancy problem");
     }
     return $amSolvedValues;
 }