示例#1
0
 /**
  * Updates the value of the inverse var
  * @param epFieldMap $fm The field map toward the inverse var
  * @param epObject &$o The opposite object
  * @param string $actoin The update action to take: INVERSE_ADD|REMOVE
  * @param bool $one_way Whether inverse update is one way only
  * @return bool
  */
 protected function _updateInverse($fm, &$o, $action = epObject::INVERSE_ADD, $one_way = true)
 {
     // check if object is epObject
     if (!$o || !$o instanceof epObject) {
         return false;
     }
     // no action if an object is updating (to prevent endless loop)
     if ($o->epIsUpdating($action)) {
         return true;
     }
     // get inverse var
     if (!($ivar = $fm->getInverse())) {
         return true;
     }
     // set inverse updating flag
     if ($one_way) {
         $this->epSetUpdating(true, $action);
     }
     $o->epSetUpdating(true, $action);
     // a single-valued field
     if (!$o->epIsMany($ivar)) {
         switch ($action) {
             case epObject::INVERSE_ADD:
                 $o[$ivar] = $this;
                 break;
             case epObject::INVERSE_REMOVE:
                 $o[$ivar] = null;
                 break;
         }
     } else {
         switch ($action) {
             case epObject::INVERSE_ADD:
                 $o[$ivar][] = $this;
                 break;
             case epObject::INVERSE_REMOVE:
                 $o[$ivar]->remove($this);
                 break;
         }
     }
     // reset inverse updating flag
     $o->epSetUpdating(false, $action);
     if ($one_way) {
         $this->epSetUpdating(false, $action);
     }
     return true;
 }
示例#2
0
 /**
  * Validate related class and inverse on a field map 
  * @param epFieldMap $fm the field map to be checked 
  * @param string $class the name of the class that the field belongs to
  * @return array (errors)
  */
 protected function _validateRelationshipField(&$fm, $class)
 {
     // array to hold error messages
     $errors = array();
     //
     // 1. check the opposite class for the field
     //
     // string for class and field
     $class_field = '[' . $class . '::' . $fm->getName() . ']';
     // does the relation field have the related class defined?
     if (!($rclass = $fm->getClass())) {
         // shouldn't happend
         $errors[] = $class_field . ' does not have opposite class specified';
         return $errors;
     }
     // does the related class exist?
     if (!isset($this->class_maps[$rclass])) {
         // alert if not
         $errors[] = 'Class [' . $rclass . '] for ' . $class_field . ' does not exist';
         return $errors;
     }
     //
     // 2. check inverse of the field
     //
     // does this field have an inverse?
     if (!($inverse = $fm->getInverse())) {
         return $errors;
     }
     // get the related class map
     $rcm = $this->class_maps[$rclass];
     // get all fields point to the current class in the related class
     $rfields = $rcm->getFieldsOfClass($class);
     // 2.a. default inverse (that is, set to true)
     if (true === $inverse) {
         // the related class must have only one relationship var to the current class
         if (!$rfields) {
             $errors[] = 'No inverse found for ' . $class_field;
         } else {
             if (count($rfields) > 1) {
                 $errors[] = 'Ambiguilty in the inverse of ' . $class_field;
             } else {
                 $rfms = array_values($rfields);
                 $fm->setInverse($rfms[0]->getName());
                 $rfms[0]->setInverse($fm->getName());
             }
         }
         return $errors;
     }
     // 2.b. inverse is specified
     // check if inverse exists
     if (!isset($rfields[$fm->getClass() . ':' . $inverse]) || !$rfields[$fm->getClass() . ':' . $inverse]) {
         $errors[] = 'Inverse of ' . $class_field . ' (' . $fm->getClass() . '::' . $inverse . ') does not exist';
         return $errors;
     }
     // get the field map for the inverse
     $rfm = $rfields[$fm->getClass() . ':' . $inverse];
     // set up the inverse on the other side -only if- inverse on the other side
     // is -not- already set or set to default
     if (!($rinverse = $rfm->getInverse()) || $rinverse === true) {
         $rfm->setInverse($fm->getName());
         return $errors;
     }
     // if specified, check duality
     if ($class != $rfm->getClass() || $rinverse != $fm->getName()) {
         $errors[] = 'Inverse of [' . $rcm->getName() . '::' . $fm->getName() . '] is not specified as ' . $class_field;
     }
     return $errors;
 }
示例#3
0
 /**
  * Update the value of the inverse var
  * @param epObject $o the opposite object
  * @param string $actoin UPDATE_INVERSE_ADD or UPDATE_INVERSE_REMOVE
  * @return boolean
  */
 protected function _updateInverse(&$o, $action = self::UPDATE_INVERSE_ADD)
 {
     // check if object is epObject
     if (!$o || !$this->fm || !$o instanceof epObject) {
         return false;
     }
     // get inverse var
     if (!($ivar = $this->fm->getInverse())) {
         return true;
     }
     // no action if an object is updating (to prevent endless loop)
     if ($o->epIsUpdating()) {
         return true;
     }
     // set inverse updating flag
     $o->epSetUpdating(true);
     // a single-valued field
     if (!$o->epIsMany($ivar)) {
         switch ($action) {
             case self::UPDATE_INVERSE_ADD:
                 $o[$ivar] = $this->o;
                 break;
             case self::UPDATE_INVERSE_REMOVE:
                 $o[$ivar] = null;
                 break;
         }
     } else {
         switch ($action) {
             case self::UPDATE_INVERSE_ADD:
                 $o[$ivar][] = $this->o;
                 break;
             case self::UPDATE_INVERSE_REMOVE:
                 $o[$ivar]->remove($this->o);
                 break;
         }
     }
     // reset inverse updating flag
     $o->epSetUpdating(false);
     return true;
 }