Exemplo n.º 1
0
Arquivo: IO.php Projeto: promoso/HVAC
 /**
  * Adds an existing record to a relationship.
  * @param $record a Dataface_RelatedRecord object to be added.
  */
 function addExistingRelatedRecord(&$record, $secure = false)
 {
     if ($secure && !$record->_record->checkPermission('add existing related record', array('relationship' => $record->_relationshipName))) {
         // Use security to check to see if we are allowed to delete this
         // record.
         //print_r( $record->_record->getPermissions(array('relationship'=>$record->_relationshipName)));exit;
         //echo $record->_record->_table->getDelegate()->getRoles($record->_record);
         //print_r($record->_record->vals());exit;
         return Dataface_Error::permissionDenied(df_translate('scripts.Dataface.IO.addExistingRelatedRecord.PERMISSION_DENIED', 'Could not add record "' . $record->getTitle() . '" to relationship "' . $record->_relationshipName . '" of record "' . $record->_record->getTitle() . '" because you have insufficient permissions.', array('title' => $record->getTitle(), 'relationship' => $record->_relationshipName, 'parent' => $record->_record->getTitle())));
     }
     $builder = new Dataface_QueryBuilder($this->_table->tablename);
     //We are often missing the values from the domain table so we will load them
     //here
     $domainRec = $record->toRecord($record->_relationship->getDomainTable());
     $domainRec2 = df_get_record_by_id($domainRec->getId());
     //$record->setValues(array_merge($domainRec2->vals(), $record->vals()));
     foreach ($domainRec2->vals() as $dreckey => $drecval) {
         if (!$record->val($dreckey)) {
             $record->setValue($dreckey, $drecval);
         }
     }
     // fire the "before" events
     if ($this->fireTriggers) {
         $res = $this->fireBeforeAddRelatedRecord($record);
         if (PEAR::isError($res)) {
             return $res;
         }
         $res = $this->fireBeforeAddExistingRelatedRecord($record);
         if (PEAR::isError($res)) {
             return $res;
         }
     }
     // It makes sense for us to fire beforeSave, afterSave, beforeInsert, and afterInsert
     // events here for the records that are being inserted.  To do this we will need to extract
     // Dataface_Record objects for all of the tables that will have records inserted.  In this
     // case we are not updated any records because relationships are created by adding a record
     // to the join table.  This means that we are also NOT adding a record to the domain table.
     // i.e., we should only fire these events for the join table.
     $drecords =& $record->toRecords();
     // $drecords is an array of Dataface_Record objects
     if (count($drecords) > 1) {
         // If there is only one record then it is for the domain table - which we don't actually
         // change.
         foreach (array_keys($drecords) as $recordIndex) {
             $currentRecord =& $drecords[$recordIndex];
             if (isset($this->insertids[$currentRecord->_table->tablename])) {
                 $idfield =& $currentRecord->_table->getAutoIncrementField();
                 if ($idfield) {
                     $currentRecord->setValue($idfield, $this->insertids[$currentRecord->_table->tablename]);
                 }
                 unset($idfield);
             }
             unset($currentRecord);
             if ($drecords[$recordIndex]->_table->tablename === $record->_relationship->getDomainTable()) {
                 continue;
             }
             // We don't do anything for the domain table because it is not being updated.
             $rio = new Dataface_IO($drecords[$recordIndex]->_table->tablename);
             $drec_snapshot = $drecords[$recordIndex]->strvals();
             $res = $rio->fireBeforeSave($drecords[$recordIndex]);
             if (PEAR::isError($res)) {
                 return $res;
             }
             $res = $rio->fireBeforeInsert($drecords[$recordIndex]);
             if (PEAR::isError($res)) {
                 return $res;
             }
             $drec_post_snapshot = $drecords[$recordIndex]->strvals();
             foreach ($drec_post_snapshot as $ss_key => $ss_val) {
                 if ($drec_snapshot[$ss_key] != $ss_val) {
                     $drecords[$recordIndex]->setValue($ss_key, $ss_val);
                 }
             }
             unset($drec_post_snapshot);
             unset($drec_snapshot);
             unset($rio);
         }
     }
     if (count($drecords) > 1) {
         $sql = $builder->addExistingRelatedRecord($record);
         if (PEAR::isError($sql)) {
             return $sql;
         }
         // Actually add the related record
         $res = $this->performSQL($sql);
         if (PEAR::isError($res)) {
             return $res;
         }
         // If there is only one record then it is for the domain table - which we don't actually
         // change.
         foreach (array_keys($drecords) as $recordIndex) {
             if ($drecords[$recordIndex]->_table->tablename === $record->_relationship->getDomainTable()) {
                 continue;
             }
             // We don't do anything for the domain table because it is not being updated.
             $rio = new Dataface_IO($drecords[$recordIndex]->_table->tablename);
             $res = $rio->fireAfterInsert($drecords[$recordIndex]);
             if (PEAR::isError($res)) {
                 return $res;
             }
             $res = $rio->fireAfterSave($drecords[$recordIndex]);
             if (PEAR::isError($res)) {
                 return $res;
             }
             unset($rio);
         }
     } else {
         // This is a one to many relationship.  We will handle this case
         // only when the foreign key is currently null.  Otherwise we return
         // and error.
         $fkeys = $record->_relationship->getForeignKeyValues();
         $fkeyvals = $record->getForeignKeyValues();
         //print_r($fkeyvals);exit;
         if (isset($fkeys[$domainRec2->_table->tablename])) {
             $drecid = $domainRec2->getId();
             unset($domainRec2);
             $domainRec2 = df_get_record_by_id($drecid);
             if (!$domainRec2) {
                 return PEAR::raiseError("Tried to get record with id {$drecid} but it doesn't exist");
             } else {
                 if (PEAR::isError($domainRec2)) {
                     return $domainRec2;
                 }
             }
             foreach (array_keys($fkeys[$domainRec2->_table->tablename]) as $fkey) {
                 //echo $fkey;
                 if ($domainRec2->val($fkey)) {
                     return PEAR::raiseError("Could not add existing related record '" . $domainRec2->getTitle() . "' because it can only belong to a single relationship and it already belongs to one.");
                 } else {
                     $domainRec2->setValue($fkey, $fkeyvals[$domainRec2->_table->tablename][$fkey]);
                 }
             }
             //echo "About to save record";exit;
             $res = $domainRec2->save($secure);
             if (PEAR::raiseError($res)) {
                 return $res;
             }
         } else {
             return PEAR::raiseError("Failed to add existing record because the domain table doesn't have any foreign keys in it.");
         }
     }
     // Fire the "after" events
     if ($this->fireTriggers) {
         $res2 = $this->fireAfterAddExistingRelatedRecord($record);
         if (PEAR::isError($res2)) {
             return $res2;
         }
         $res2 = $this->fireAfterAddRelatedRecord($record);
         if (PEAR::isError($res2)) {
             return $res2;
         }
     }
     return $res;
 }