/** * Validates the attribute of the object. * If there is any error, the error message is added to the object. * @param AnnotatedInterface $model the object being validated * @param string $attribute the attribute being validated */ public function isValid(AnnotatedInterface $model, $attribute) { $value = $model->{$attribute}; if ($this->allowEmpty && empty($value)) { return true; } $className = empty($this->className) ? get_class($model) : $this->className; $compareModel = new $className(); $criteria = (new Criteria())->decorateWith($compareModel); $criteria->addCond($attribute, '==', $value); if ($this->criteria !== []) { $criteria->mergeWith($this->criteria); } ScenarioManager::setScenario($compareModel, ValidatorInterface::ScenarioValidate); $finder = new Finder($compareModel); $found = $finder->find($criteria); // Not found entirely if (null === $found) { return true; } // Same pk if (PkManager::compare($found, $model)) { return true; } $label = ManganMeta::create($model)->field($attribute)->label; $this->addError('msgTaken', ['{attribute}' => $label, '{value}' => $value]); return false; }
public function read($model, $name, &$dbValues, $transformatorClass = TransformatorInterface::class) { if (!$dbValues) { $fieldMeta = ManganMeta::create($model)->field($name); $model->{$name} = $fieldMeta->default; return; } /** * NOTE: Documents must be sorted as $dbRefs, * however mongo does not guarantiee sorting by list of id's. * This require sorting in php. * If document has composite key this must be taken care too * while comparision for sorting is made. */ $refs = []; $unsortedRefs = []; $pks = []; $sort = []; // Collect primary keys foreach ($dbValues as $key => $dbValue) { $dbValue['_class'] = DbRef::class; $dbRef = $transformatorClass::toModel($dbValue); // Collect keys separatelly for each type $pks[$dbRef->class][$key] = $dbRef->pk; $sort[$key] = $dbRef->pk; } // Fetch all types of db ref's en masse $i = 0; $unsortedPks = []; foreach ($pks as $referenced => $pkValues) { if (empty($referenced)) { continue; } // Find all referenced documents $refModel = new $referenced(); $found = (new RawFinder($refModel))->findAllByPk($pkValues); if (!$found) { continue; } foreach ($found as $document) { // Collect unsorted documents $unsortedRefs[$i] = $document; // Collect pk's $unsortedPks[$i] = PkManager::getFromArray($document, $refModel); $i++; } } // Find existing documents $existing = []; foreach ($model->{$name} as $key => $document) { foreach ($sort as $i => $pk) { if (PkManager::compare($pk, $document)) { // Set existing document with key same as in sort $existing[$i] = $document; } } } // Sort as stored ref foreach ($sort as $key => $pk) { foreach ($unsortedRefs as $i => $document) { if (PkManager::compare($pk, $unsortedPks[$i])) { if (array_key_exists($key, $existing)) { // Update existing instance $refs[$key] = $transformatorClass::toModel($document, $existing[$key], $existing[$key]); } else { // Create new instance $refs[$key] = $transformatorClass::toModel($document); } } } } $model->{$name} = $refs; }