Exemplo n.º 1
0
 /**
  * Checks to see if a record exists.  If so, it updates, else it creates
  *
  * @param String      $object       The type of object to perform upsert on
  * @param Array       $records      Array of records to upsert.  Should be passed in the same format as used with
  *                                  create and update
  * @param Mixed       $nameField    the field name used for lookup of existence
  * @param Mixed       $keyField     the field name used for the internal key (needed for update)
  * @param api_session $session      An active api_session object
  * @param bool        $readOnlyName Optional.  You shouldn't normally set this to true unless the value in the
  *                                  name field is actually set by the platform and you're passing a formulated value
  *                                  that should not be passed in the create or update
  *
  * @throws Exception
  * @return null
  */
 public static function upsert($object, $records, $nameField, $keyField, api_session $session, $readOnlyName = false)
 {
     if (count($records) > 100) {
         throw new Exception("You can only upsert up to 100 records at a time.  You passed " . count($records) . " {$object} records.");
     }
     $keys = array();
     foreach ($records as $record) {
         $keys[] = htmlspecialchars(str_replace('\'', '\\', $record[$object][$nameField]));
     }
     $where = "{$nameField} in ('" . join("','", $keys) . "')";
     $existingRecords = api_post::readByQuery($object, $where, "{$nameField},{$keyField}", $session);
     if (!is_array($existingRecords)) {
         $existingRecords = array();
     }
     $toUpdate = array();
     $toCreate = array();
     if (count($existingRecords) == 0) {
         if ($readOnlyName == true) {
             foreach ($records as $key => $rec) {
                 unset($records[$key][$object][$nameField]);
             }
         }
         api_post::create($records, $session);
     } else {
         // convert the result into an array of keys
         $existingKeys = array();
         foreach ($existingRecords as $rec) {
             $existingKeys[] = $rec[$nameField];
         }
         // also create an index by name
         $existingByName = array();
         foreach ($existingRecords as $rec) {
             $existingByName[$rec[$nameField]] = $rec[$keyField];
         }
         foreach ($records as $rec) {
             if (in_array($rec[$object][$nameField], $existingKeys)) {
                 $toUpdate[] = $rec;
             } else {
                 $toCreate[] = $rec;
             }
         }
         // convert the create and update arrays into operable structures
         if (count($toCreate) > 0) {
             if ($readOnlyName === true) {
                 foreach ($toCreate as $key => $rec) {
                     unset($toCreate[$key][$object][$nameField]);
                 }
             }
             api_post::create($toCreate, $session);
         }
         if (count($toUpdate) > 0) {
             foreach ($toUpdate as $updateKey => $updateRec) {
                 $toUpdate[$updateKey][$object][$keyField] = $existingByName[$updateRec[$object][$nameField]];
                 if ($readOnlyName === true) {
                     unset($toUpdate[$updateKey][$object][$nameField]);
                 }
             }
             api_post::update($toUpdate, $session);
         }
     }
 }