public function updateItems(array $updatedFieldValues, EarthIT_Schema_ResourceClass $rc, EarthIT_Storage_ItemFilter $filter, array $options = array())
 {
     $rcName = $rc->getName();
     $matchedKeys = array();
     if (isset($this->items[$rcName])) {
         foreach ($this->items[$rcName] as $k => $item) {
             if ($filter->matches($item)) {
                 $matchedKeys[] = $k;
             }
         }
     }
     $updated = array();
     foreach ($matchedKeys as $k) {
         $item = $this->items[$rcName][$k];
         $item = $updatedFieldValues + $item;
         $id = EarthIT_Storage_Util::itemId($item, $rc);
         if ($id !== null and $id !== $k) {
             // TODO: Look at options to determine if updating is allowed
             // to overwrite other items
             unset($this->items[$rcName][$k]);
             $this->items[$rcName][$id] = $item;
             $k = $id;
         }
         $updated[$k] = $item;
     }
     return $updated;
 }
 protected static function findReference($refRef, EarthIT_Schema_ResourceClass $rc, EarthIT_Schema $schema = null, &$refName = null, &$refIsPlural = null, $fuzzyMatch = true)
 {
     $refRef = self::maybeMinimize($refRef, $fuzzyMatch);
     $refs = $rc->getReferences();
     if ($fuzzyMatch) {
         foreach ($refs as $k => $ref) {
             if (EarthIT_Schema_WordUtil::minimize($k) == $refRef) {
                 $refName = $k;
                 $refIsPlural = false;
                 return $ref;
             }
         }
     } else {
         if (isset($refs[$refRef])) {
             $refIsPlural = false;
             $refName = $refRef;
             return $refs[$refName];
         }
     }
     if ($schema !== null) {
         $rcs = $schema->getResourceClasses();
         // Look for one based on explicit inverse name
         foreach ($rcs as $trcName => $trc) {
             foreach ($rc->getReferences() as $ref) {
                 $refInverseName = $ref->getFirstPropertyValue(EarthIT_CMIPREST_NS::INVERSE_NAME);
                 $refPluralInverseName = $ref->getFirstPropertyValue(EarthIT_CMIPREST_NS::INVERSE_COLLECTION_NAME, EarthIT_Schema_WordUtil::pluralize($refInverseName));
                 $matchRefInverseName = self::maybeMinimize($refInverseName, $fuzzyMatch);
                 $matchRefPluralInverseName = self::maybeMinimize($refPluralInverseName, $fuzzyMatch);
                 // plural takes priority if plural name = singular name
                 if ($matchRefPluralInverseName == $refRef) {
                     $refName = $refPluralInverseName;
                     $refIsPlural = true;
                     return new EarthIT_Schema_Reference($trcName, $ref->getTargetFieldNames(), $ref->getOriginFieldNames());
                 }
                 if ($matchRefInverseName == $refRef) {
                     $refName = $refInverseName;
                     $refIsPlural = false;
                     return new EarthIT_Schema_Reference($trcName, $ref->getTargetFieldNames(), $ref->getOriginFieldNames());
                 }
             }
         }
         // Look for one based on class name = ref ref
         foreach ($rcs as $trcName => $trc) {
             $trcCollectionName = $trc->getFirstPropertyValue(self::COLLECTION_NAME, EarthIT_Schema_WordUtil::pluralize($trcName));
             $matchTrcCollectionName = self::maybeMinimize($trcCollectionName, $fuzzyMatch);
             $matchTrcName = self::maybeMinimize($trcName, $fuzzyMatch);
             $found = false;
             // plural takes priority if plural name = singular name
             if ($matchTrcCollectionName == $refRef) {
                 $found = true;
                 $refIsPlural = true;
                 $refName = $trcCollectionName;
             } else {
                 if ($matchTrcName == $refRef) {
                     $found = true;
                     $refIsPlural = false;
                     $refName = $trcName;
                 }
             }
             if ($found) {
                 // Found a resource class that could work
                 // if it has an appropriate reverse reference.
                 foreach ($trc->getReferences() as $ref) {
                     if ($ref->getTargetClassName() == $rc->getName()) {
                         return new EarthIT_Schema_Reference($trcName, $ref->getTargetFieldNames(), $ref->getOriginFieldNames());
                     }
                 }
             }
         }
     }
     return null;
 }
 public static function itemIdRegex(EarthIT_Schema_ResourceClass $rc)
 {
     $pk = $rc->getPrimaryKey();
     if ($pk === null or count($pk->getFieldNames()) == 0) {
         throw new Exception("No ID regex because no primary key for " . $rc->getName() . ".");
     }
     $fields = $rc->getFields();
     $parts = array();
     foreach ($pk->getFieldNames() as $fn) {
         $field = $fields[$fn];
         $datatype = $field->getType();
         $fRegex = $datatype->getRegex();
         if ($fRegex === null) {
             throw new Exception("Can't build ID regex because ID component field '{$fn}' is of type '" . $datatype->getName() . "', which doesn't have a regex.");
         }
         $parts[] = "({$fRegex})";
     }
     return implode("-", $parts);
 }