Esempio n. 1
0
 function saveTransients(Dataface_Record $record, $keys = null, $tablename = null, $secure = false)
 {
     $app = Dataface_Application::getInstance();
     // Now we take care of the transient relationship fields.
     // Transient relationship fields aren't actually stored in the record
     // itself, they are stored as related records.
     foreach ($record->_table->transientFields() as $tfield) {
         if (!isset($tfield['relationship'])) {
             continue;
         }
         if (!$record->valueChanged($tfield['name'])) {
             continue;
         }
         $trelationship =& $record->_table->getRelationship($tfield['relationship']);
         if (!$trelationship or PEAR::isError($trelationship)) {
             // We couldn't find the specified relationship.
             //$record->vetoSecurity = $oldVeto;
             return $trelationship;
         }
         $orderCol = $trelationship->getOrderColumn();
         if (PEAR::isError($orderCol)) {
             $orderCol = null;
         }
         $tval = $record->getValue($tfield['name']);
         if ($tfield['widget']['type'] == 'grid') {
             $tval_existing = array();
             $tval_new = array();
             $tval_new_existing = array();
             $torder = 0;
             foreach ($tval as $trow) {
                 if (!is_array($trow)) {
                     continue;
                 }
                 $trow['__order__'] = $torder++;
                 if (isset($trow['__id__']) and preg_match('/^new:/', $trow['__id__'])) {
                     $tval_new_existing[] = $trow;
                 } else {
                     if (isset($trow['__id__']) and $trow['__id__'] != 'new') {
                         $tval_existing[$trow['__id__']] = $trow;
                     } else {
                         if (isset($trow['__id__']) and $trow['__id__'] == 'new') {
                             $tval_new[] = $trow;
                         }
                     }
                 }
             }
             // The transient field was loaded so we can go about saving the
             // changes/
             $trecords =& $record->getRelatedRecordObjects($tfield['relationship'], 'all');
             if (!is_array($trecords) or PEAR::isError($trecords)) {
                 error_log('Failed to get related records for record ' . $record->getId() . ' in its relationship ' . $tfield['relationship']);
                 unset($tval);
                 unset($orderCol);
                 unset($tval_new);
                 unset($torder);
                 unset($trelationship);
                 unset($tval_existing);
                 continue;
             }
             // Update the existing records in the relationship.
             // We use the __id__ parameter in each row for this.
             //echo "About to save related records";
             foreach ($trecords as $trec) {
                 $tid = $trec->getId();
                 if (isset($tval_existing[$tid])) {
                     $tmp = new Dataface_RelatedRecord($trec->_record, $tfield['relationship'], $trec->getValues());
                     $tmp->setValues($tval_existing[$tid]);
                     $changed = false;
                     foreach ($tval_existing[$tid] as $k1 => $v1) {
                         if ($tmp->isDirty($k1)) {
                             $changed = true;
                             break;
                         }
                     }
                     if ($changed) {
                         $trec->setValues($tval_existing[$tid]);
                         if ($orderCol) {
                             $trec->setValue($orderCol, $tval_existing[$tid]['__order__']);
                         }
                         //echo "Saving ";print_r($trec->vals());
                         $res_t = $trec->save($this->lang, $secure);
                         if (PEAR::isError($res_t)) {
                             return $res_t;
                             error_log('Failed to save related record ' . $trec->getId() . ' while saving transient field ' . $tfield['name'] . ' in record ' . $record->getId() . '. The error returned was : ' . $res_t->getMessage());
                         }
                     } else {
                         if ($orderCol and $record->checkPermission('reorder_related_records', array('relationship' => $tfield['relationship']))) {
                             $trec->setValue($orderCol, $tval_existing[$tid]['__order__']);
                             $res_t = $trec->save($this->lang, false);
                             // we don't need this to be secure
                             if (PEAR::isError($res_t)) {
                                 return $res_t;
                                 error_log('Failed to save related record ' . $trec->getId() . ' while saving transient field ' . $tfield['name'] . ' in record ' . $record->getId() . '. The error returned was : ' . $res_t->getMessage());
                             }
                         }
                     }
                     unset($tmp);
                 } else {
                 }
                 unset($trec);
                 unset($tid);
                 unset($res_t);
             }
             // Now add new records  (specified by __id__ field being 'new'
             foreach ($tval_new as $tval_to_add) {
                 $temp_rrecord = new Dataface_RelatedRecord($record, $tfield['relationship'], array());
                 $temp_rrecord->setValues($tval_to_add);
                 if ($orderCol) {
                     $temp_rrecord->setValue($orderCol, $tval_to_add['__order__']);
                 }
                 $res_t = $this->addRelatedRecord($temp_rrecord, $secure);
                 if (PEAR::isError($res_t)) {
                     error_log('Failed to save related record ' . $temp_rrecord->getId() . ' while saving transient field ' . $tfield['name'] . ' in record ' . $record->getId() . '. The error returned was : ' . $res_t->getMessage());
                 }
                 unset($temp_rrecord);
                 unset($res_t);
             }
             // Now add new existing records  (specified by __id__ field being 'new:<recordid>'
             foreach ($tval_new_existing as $tval_to_add) {
                 $tid = preg_replace('/^new:/', '', $tval_to_add['__id__']);
                 $temp_record = df_get_record_by_id($tid);
                 if (PEAR::isError($temp_record)) {
                     return $temp_record;
                 }
                 if (!$temp_record) {
                     return PEAR::raiseError("Failed to load existing record with ID {$tid}.");
                 }
                 $temp_rrecord = new Dataface_RelatedRecord($record, $tfield['relationship'], $temp_record->vals());
                 $temp_rrecord->setValues($tval_to_add);
                 if ($orderCol) {
                     $temp_rrecord->setValue($orderCol, $tval_to_add['__order__']);
                 }
                 $res_t = $this->addExistingRelatedRecord($temp_rrecord, $secure);
                 if (PEAR::isError($res_t)) {
                     error_log('Failed to save related record ' . $temp_rrecord->getId() . ' while saving transient field ' . $tfield['name'] . ' in record ' . $record->getId() . '. The error returned was : ' . $res_t->getMessage());
                 }
                 unset($temp_rrecord);
                 unset($res_t);
             }
             // Now we delete the records that were deleted
             // we use the __deleted__ field.
             if (isset($tval['__deleted__']) and is_array($tval['__deleted__']) and $trelationship->supportsRemove()) {
                 $tdelete_record = ($trelationship->isOneToMany() and !$trelationship->supportsAddExisting());
                 // If it supports add existing, then we shouldn't delete the entire record.  Just remove it
                 // from the relationship.
                 foreach ($tval['__deleted__'] as $del_id) {
                     if ($del_id == 'new') {
                         continue;
                     }
                     $drec = Dataface_IO::getByID($del_id);
                     if (PEAR::isError($drec) or !$drec) {
                         unset($drec);
                         continue;
                     }
                     $mres = $this->removeRelatedRecord($drec, $tdelete_record, $secure);
                     if (PEAR::isError($mres)) {
                         throw new Exception($mres->getMessage());
                     }
                     unset($drec);
                 }
             }
             unset($trecords);
         } else {
             if ($tfield['widget']['type'] == 'checkbox') {
                 // Load existing records in the relationship
                 $texisting =& $record->getRelatedRecordObjects($tfield['relationship'], 'all');
                 if (!is_array($texisting) or PEAR::isError($texisting)) {
                     error_log('Failed to get related records for record ' . $record->getId() . ' in its relationship ' . $tfield['relationship']);
                     unset($tval);
                     unset($orderCol);
                     unset($tval_new);
                     unset($torder);
                     unset($trelationship);
                     unset($tval_existing);
                     continue;
                 }
                 $texistingIds = array();
                 foreach ($texisting as $terec) {
                     $texistingIds[] = $terec->getId();
                 }
                 // Load currently checked records
                 $tchecked = array();
                 $tcheckedRecords = array();
                 $tcheckedIds = array();
                 $tcheckedId2ValsMap = array();
                 foreach ($tval as $trkey => $trval) {
                     // $trval is in the form key1=val1&size=key2=val2
                     parse_str($trval, $trquery);
                     $trRecord = new Dataface_RelatedRecord($record, $tfield['relationship'], $trquery);
                     $trRecords[] =& $trRecord;
                     $tcheckedIds[] = $tid = $trRecord->getId();
                     $checkedId2ValsMap[$tid] = $trquery;
                     unset($trRecord);
                     unset($trquery);
                 }
                 // Now we have existing ids in $texistingIds
                 // and checked ids in $tcheckedIds
                 // See which records we need to have removed
                 $tremoves = array_diff($texistingIds, $tcheckedIds);
                 $tadds = array_diff($tcheckedIds, $texistingIds);
                 foreach ($tremoves as $tid) {
                     $trec = df_get_record_by_id($tid);
                     $res = $this->removeRelatedRecord($trec, false, $secure);
                     if (PEAR::isError($res)) {
                         return $res;
                     }
                     unset($trec);
                 }
                 foreach ($tadds as $tid) {
                     $trecvals = $checkedId2ValsMap[$tid];
                     $trec = new Dataface_RelatedRecord($record, $tfield['relationship'], $trecvals);
                     $res = $this->addExistingRelatedRecord($trec, $secure);
                     if (PEAR::isError($res)) {
                         return $res;
                     }
                     unset($trec, $trecvals);
                 }
                 unset($tadds);
                 unset($tremoves);
                 unset($tcheckedIds, $tcheckedId2ValsMap);
                 unset($tcheckedRecords);
                 unset($tchecked);
                 unset($texistingIds);
                 unset($texisting);
             }
         }
         unset($tval);
         unset($trelationship);
     }
 }