Example #1
0
 /**
  * Find a related recordset.
  * @param Garp_Model $model The model that spawned this data
  * @param Garp_Db_Row $row The row object
  * @param Garp_Util_Configuration $options Various relation options
  * @return String The name of the method.
  */
 protected function _getRelatedRowset(Garp_Model $model, Garp_Db_Table_Row $row, Garp_Util_Configuration $options)
 {
     /**
      * An optional passed SELECT object will be passed by reference after every query.
      * This results in an error when 'clone' is not used, because correlation names will be
      * used twice (since they were set during the first iteration). Using 'clone' makes sure
      * a brand new SELECT object is used every time that hasn't been soiled by a possible
      * previous query.
      */
     $conditions = is_null($options['conditions']) ? null : clone $options['conditions'];
     $otherModel = $options['modelClass'];
     if (!$otherModel instanceof Zend_Db_Table_Abstract) {
         $otherModel = new $otherModel();
     }
     /**
      * Do not cache related queries. The "outside" query should be the only
      * query that's cached.
      */
     $originalCacheQueriesFlag = $otherModel->getCacheQueries();
     $otherModel->setCacheQueries(false);
     $modelName = get_class($otherModel);
     $relatedRowset = null;
     // many to many
     if (!empty($options['bindingModel'])) {
         $relatedRowset = $row->findManyToManyRowset($otherModel, $options['bindingModel'], $options['rule2'], $options['rule'], $conditions);
     } else {
         /**
          * 'mode' is used to clear ambiguity with homophilic relationships. For example,
          * a Model_Doc can have have child Docs and one parent Doc. The conditionals below can never tell
          * which method to call (findParentRow or findDependentRowset) from the referenceMap.
          * Therefore, we can help the decision-making by passing "mode". This can either be
          * "parent" or "dependent", which will then force a call to findParentRow and findDependentRowset,
          * respectively.
          */
         if (is_null($options['mode'])) {
             // belongs to
             try {
                 $model->getReference($modelName, $options['rule']);
                 $relatedRowset = $row->findParentRow($otherModel, $options['rule'], $conditions);
             } catch (Exception $e) {
                 if (!Garp_Content_Relation_Manager::isInvalidReferenceException($e)) {
                     throw $e;
                 }
                 try {
                     // one to many - one to one
                     // The following line triggers an exception if no reference is available
                     $otherModel->getReference(get_class($model), $options['rule']);
                     $relatedRowset = $row->findDependentRowset($otherModel, $options['rule'], $conditions);
                 } catch (Exception $e) {
                     if (!Garp_Content_Relation_Manager::isInvalidReferenceException($e)) {
                         throw $e;
                     }
                     $bindingModel = $model->getBindingModel($modelName);
                     $relatedRowset = $row->findManyToManyRowset($otherModel, $bindingModel, $options['rule2'], $options['rule'], $conditions);
                 }
             }
         } else {
             switch ($options['mode']) {
                 case 'parent':
                     $relatedRowset = $row->findParentRow($otherModel, $options['rule'], $conditions);
                     break;
                 case 'dependent':
                     $relatedRowset = $row->findDependentRowset($otherModel, $options['rule'], $conditions);
                     break;
                 default:
                     throw new Garp_Model_Exception('Invalid value for "mode" given. Must be either "parent" or ' . '"dependent", but "' . $options['mode'] . '" was given.');
                     break;
             }
         }
     }
     // Reset the cacheQueries value. It's a static property,
     // so leaving it FALSE will affect all future fetch() calls to this
     // model. Not good.
     $otherModel->setCacheQueries($originalCacheQueriesFlag);
     return $relatedRowset;
 }