Ejemplo n.º 1
0
Archivo: IO.php Proyecto: promoso/HVAC
 /**
  * 
  * Imports data into the supplied record's relationship.  This makes use of this table's delegate
  * file to handle the importing.
  *
  * @param 	$record 			A Dataface_Record object whose relationship is to have records added to it.
  * @type Dataface_Record | null
  *
  * @param 	$data 				Either raw data that is to be imported, or the name of an Import table from which
  * 							data is to be imported.
  * @type Raw | string
  * 
  * @param	$importFilter		The name of the import filter that should be used.
  * @type string
  * 
  * @param	$relationshipName	The name of the relationship where these records should be added.
  * @type string
  * 
  * @param $commit				A boolean value indicating whether this import should be committed to the 
  *								database.  If this is false, then the records will not actually be imported.  They
  *								will merely be stored in an import table.  This must be explicitly set to true
  *								for the import to succeed.
  * @type boolean
  *
  * @param defaultValues			Array of default values of the form [Abs fieldname] -> [field value], where 'Abs fieldname'
  *								is the absolute field name (ie: tablename.fieldname).  All imported records will attain
  *								these default values.
  * @type array([string] -> [mixed])
  *
  * @return						Case 1: The import succeeds.
  *									Case 1.1: if commit = false return Import Table name where data is stored.
  *									Case 1.2: If commit = true return array of Dataface_Record objects that were inserted.
  *								Case 2: The import failed
  *									return PEAR_Error object.
  *
  *
  * Usage:
  * -------
  * $data = '<phonelist>
  *				<listentry>
  *					<name>John Smith</name><number>555-555-5555</number>
  *				</listentry>
  *				<listentry>
  *					<name>Susan Moore</name><number>444-444-4444</number>
  *				</listentry>
  *			</phonelist>';
  * 
  * 		// assume that we have an import filter called 'XML_Filter' that can import the above data.
  * 
  * $directory = new Dataface_Record('Directory', array('Name'=>'SFU Directory'));
  * 		// assume that the Directory table has a relationship called 'phonelist' and we want to 
  *		// import the above data into this relationship.
  *
  * $io = new Dataface_IO('Directory');
  * $importTableName = $io->importData(	$directory,		// The record that owns the relationship where imported records will be added
  *										$data, 			// The raw data to import
  *										'XML_Filter', 	// The name of the impot
  *										'phonelist'
  *									);
  *		// Since we didn't set the $commit flag, the data has been imported into an import table
  *		// whose name is stored now in $importTableName.
  *
  *  //
  *  // Now suppose we have confirmed that the import is what we want to do and we are ready to import
  *	// the data into the database.
  * $records = $io->importData($directory, $importTableName, null, 'phonelist', true );
  *
  * echo $records[0]->val('name'); 	// should output 'John Smith'
  * echo $records[0]->val('number'); // should output '555-555-5555'
  * echo $records[1]->val('name'); 	// should output 'Susan Moore'
  * echo $records[1]->val('number'); // should output '444-444-4444'
  * 
  *  // note that at this point the records in $records are already persisted to the database
  *
  */
 function importData(&$record, $data, $importFilter = null, $relationshipName = null, $commit = false, $defaultValues = array())
 {
     if ($relationshipName === null) {
         /*
          * No relationship is specified so our import table is just the current table.
          */
         $table =& $this->_table;
     } else {
         /*
          * A relationship is specified so we are actually importing the records into the
          * domain table of the relationship.
          */
         $relationship =& $this->_table->getRelationship($relationshipName);
         $tablename = $relationship->getDomainTable();
         if (PEAR::isError($tablename)) {
             /*
              * This relationship does not have a domain table.. so we will just take the destination table.
              */
             $destinationTables =& $relationship->getDestinationTables();
             if (count($destinationTables) <= 0) {
                 trigger_error(df_translate('scripts.Dataface.IO.importData.ERROR_NO_DESTINATION_TABLES', "Error occurred while attempting to parse import data into a table.  The relationship '" . $relationship->getName() . "' of table '" . $this->_table->tablename . "' has not destination tables listed.  It should have at least one.\n", array('relationship' => $relationship->getName(), 'table' => $this->_table->tablename)) . Dataface_Error::printStackTrace(), E_USER_ERROR);
             }
             $tablename = $destinationTables[0]->tablename;
         }
         if (PEAR::isError($tablename)) {
             trigger_error($tablename->toString() . Dataface_Error::printStackTrace(), E_USER_ERROR);
         }
         $table =& Dataface_Table::loadTable($tablename);
         $rel_io = new Dataface_IO($tablename);
         $io =& $rel_io;
     }
     if (!$commit) {
         // If data is provided, we must parse it and prepare it for
         // import
         $records = $table->parseImportData($data, $importFilter, $defaultValues);
         if (PEAR::isError($records)) {
             /*
              * The import didn't work with the specified import filter, so we will
              * try the other filters.
              */
             $records = $table->parseImportData($data, null, $defaultValues);
         }
         if (PEAR::isError($records)) {
             /*
              * Apparently we have failed to import the data, so let's just 
              * return the errors.
              */
             return $records;
         }
         // Now we will load the values of the records into an array
         // so that we can store it in the session
         $importData = array('table' => $table->tablename, 'relationship' => $relationshipName, 'defaults' => $defaultValues, 'importFilter' => $importFilter, 'record' => null, 'rows' => array());
         if (isset($record)) {
             $importData['record'] = $record->getId();
         }
         foreach ($records as $r) {
             if (is_a($r, 'Dataface_ImportRecord')) {
                 // The current record is actually an ImportRecord
                 $importData['rows'][] = $r->toArray();
             } else {
                 $importData['rows'][] = $r->vals(array_keys($r->_table->fields(false, true)));
                 unset($r);
             }
         }
         $dumpFile = tempnam(sys_get_temp_dir(), 'dataface_import');
         $handle = fopen($dumpFile, "w");
         if (!$handle) {
             trigger_error("Could not write import data to dump file {$dumpFile}", E_USER_ERROR);
         }
         fwrite($handle, serialize($importData));
         fclose($handle);
         $_SESSION['__dataface__import_data__'] = $dumpFile;
         return $dumpFile;
     }
     if (!@$_SESSION['__dataface__import_data__']) {
         trigger_error("No import data to import", E_USER_ERROR);
     }
     $dumpFile = $_SESSION['__dataface__import_data__'];
     $importData = unserialize(file_get_contents($dumpFile));
     if ($importData['table'] != $table->tablename) {
         return PEAR::raiseError("Unexpected table name in import data.  Expected " . $table->tablename . " but received " . $importData['table']);
     }
     $inserted = array();
     $i = 0;
     foreach ($importData['rows'] as $row) {
         if (isset($row['__CLASS__']) and isset($row['__CLASSPATH__'])) {
             // This row is an import record - not merely a Dataface_Record
             // object so it provides its own logic to import the records.
             import($row['__CLASSPATH__']);
             $class = $row['__CLASS__'];
             $importRecord = new $class($row);
             $res = $importRecord->commit($record, $relationshipName);
             if (PEAR::isError($res)) {
                 return $res;
             }
         } else {
             $values = array();
             foreach (array_keys($row) as $key) {
                 if (!is_int($key)) {
                     $values[$key] = $row[$key];
                 }
             }
             if ($relationshipName === null) {
                 /*
                  * These records are not being added to a relationship.  They are just being added directly
                  * into the table.
                  */
                 $defaults = array();
                 // for absolute field name keys for default values, we will strip out the table name.
                 foreach (array_keys($defaultValues) as $key) {
                     if (strpos($key, '.') !== false) {
                         list($tablename, $fieldname) = explode('.', $key);
                         if ($tablename == $this->_table->tablename) {
                             $defaults[$fieldname] = $defaultValues[$key];
                         } else {
                             continue;
                         }
                     } else {
                         $defaults[$key] = $defaultValues[$key];
                     }
                 }
                 $values = array_merge($defaults, $values);
                 $insrecord = new Dataface_Record($this->_table->tablename, $values);
                 $inserted[] =& $insrecord;
                 $this->write($insrecord);
                 $insrecord->__destruct();
                 unset($insrecord);
             } else {
                 /*
                  * The records are being added to a relationship so we need to make sure that we add the appropriate
                  * entries to the "join" tables as well.
                  */
                 foreach (array_keys($values) as $key) {
                     $values[$table->tablename . '.' . $key] = $values[$key];
                     unset($values[$key]);
                 }
                 $values = array_merge($defaultValues, $values);
                 /*
                  * Let's check if all of the keys are set.  If they are then the record already exists.. we
                  * just need to update the record.
                  *
                  */
                 $rvalues = array();
                 foreach ($values as $valkey => $valval) {
                     if (strpos($valkey, '.') !== false) {
                         list($tablename, $fieldname) = explode('.', $valkey);
                         if ($tablename == $table->tablename) {
                             $rvalues[$fieldname] = $valval;
                         }
                     }
                 }
                 $rrecord = new Dataface_Record($table->tablename, array());
                 $rrecord->setValues($rvalues);
                 // we set the values in a separate call because we want to be able to do an update
                 // and setting values in the constructer sets the snapshot (ie: it will think that
                 // no values have changed.
                 if ($io->recordExists($rrecord)) {
                     /*
                      * The record already exists, so we update it and then add it to the relationship.
                      *
                      */
                     if (Dataface_PermissionsTool::edit($rrecord)) {
                         /*
                          * We only edit the record if we have permission to do so.
                          */
                         $result = $io->write($rrecord);
                         if (PEAR::isError($result)) {
                             trigger_error($result->toString() . Dataface_Error::printStackTrace(), E_USER_ERROR);
                         }
                     }
                     $relatedRecord = new Dataface_RelatedRecord($record, $relationshipName, $values);
                     $inserted[] =& $relatedRecord;
                     $qb = new Dataface_QueryBuilder($this->_table->tablename);
                     $sql = $qb->addExistingRelatedRecord($relatedRecord);
                     $res2 = $this->performSQL($sql);
                     unset($relatedRecord);
                 } else {
                     $relatedRecord = new Dataface_RelatedRecord($record, $relationshipName, $values);
                     $inserted[] =& $relatedRecord;
                     $qb = new Dataface_QueryBuilder($this->_table->tablename);
                     $sql = $qb->addRelatedRecord($relatedRecord);
                     $res2 = $this->performSQL($sql);
                     unset($relatedRecord);
                 }
                 unset($rrecord);
             }
         }
         unset($row);
     }
     @unlink($dumpFile);
     unset($_SESSION['__dataface__import_data__']);
     return $inserted;
 }
Ejemplo n.º 2
0
 function test_add_related_record_sql()
 {
     $s = new Dataface_Record('Profiles', array());
     $builder = new Dataface_QueryBuilder('Profiles');
     $s->setValue('id', 15);
     $newRecord = new Dataface_RelatedRecord($s, "addresses");
     //print_r($s->relationships());
     $res = $builder->addRelatedRecord($newRecord);
     if (PEAR::isError($res)) {
         echo $res->toString();
     }
     $this->assertEquals(array('Addresses' => "INSERT INTO `Addresses` (`profileid`) VALUES ('15')"), $res);
     $newCourse = new Dataface_RelatedRecord($s, "courses");
     $res = $builder->addRelatedRecord($newCourse);
     if (PEAR::isError($res)) {
         echo $res->toString();
     }
     $this->assertEquals(array('Courses' => "INSERT INTO `Courses` () VALUES ()", 'Student_Courses' => "INSERT INTO `Student_Courses` (`studentid`,`courseid`) VALUES ('15','__Courses__auto_increment__')"), $res);
     $newAppointment = new Dataface_RelatedRecord($s, "appointments", array('profileid' => 2));
     $res = $builder->addRelatedRecord($newAppointment);
     if (PEAR::isError($res)) {
         echo $res->toString();
     }
     $this->assertEquals(array('Appointments' => "INSERT INTO `Appointments` (`profileid`) VALUES ('15')"), $res);
 }