protected function generateModelClassMethods($modelName) { $methods = array(); foreach ($this->modelsConfig->models[$modelName]->properties as $propName => $propConfig) { $name = ucfirst($propName); $this->lastProcessedElement = $modelName . '.' . $propName; if ($propName == 'id') { continue; } $type = $this->typeConverter->getPhpType($propConfig->type); $setterType = $this->typeConverter->getSetterPhpdocType($propConfig->type); $methods['force']['get' . $name] = $this->unindent(3, "\n /**\n * Do not override! Grace internals rely on these methods only containing the array access.\n * @return {$type}\n */\n public function get{$name}()\n {\n return \$this->properties['{$propName}'];\n }\n "); // TODO берём из конфига валидацию и по ней накидываем тут преобразования а-ля Phone::normalizePhone() // можно однако напороться на переопределённый сеттер, который это не делает if ($propConfig->isSettable) { $methods['optional']['set' . $name] = $this->unindent(4, "\n /**\n * @param {$setterType} \${$propName}\n * @return \$this\n */\n public function set{$name}(\${$propName})\n {\n return \$this->setProperty('{$propName}', \${$propName});\n }\n "); } if ($propConfig->resolvesToModelName) { $getterName = 'get' . ucfirst(substr($propName, 0, -2)); // removing Id suffix: regionId => getRegion $foreignClass = $this->classNameProvider->getModelClass($propConfig->resolvesToModelName); $finderProperty = lcfirst($propConfig->resolvesToModelName) . 'Finder'; $methods['force'][$getterName] = $this->unindent(4, "\n /**\n * Do not override\n * @return {$foreignClass}\n */\n public function {$getterName}()\n {\n return \$this->orm->{$finderProperty}->getByIdOrFalse(\$this->getProperty('{$propName}'));\n }\n "); } } // DB TO PHP CONVERSION $dbToPhpMethodBody = ''; foreach ($this->modelsConfig->models[$modelName]->properties as $propName => $propConfig) { $this->lastProcessedElement = $modelName . '.' . $propName; $propertyCode = $this->typeConverter->getDbToPhpConverterCode($propConfig->type); if ($propConfig->isNullable) { $dbToPhpMethodBody .= $this->unindent(1, "\n // {$propName}\n \$value = \$dbArray['{$propName}'];\n \$this->properties['{$propName}'] = (\$value === null) ? null : ({$propertyCode});\n "); } else { $dbToPhpMethodBody .= $this->unindent(1, "\n // {$propName}\n \$value = \$dbArray['{$propName}'];\n if (\$value === null) {\n throw new \\Grace\\ORM\\Type\\ConversionImpossibleException('Null is not allowed in {$modelName}.{$propName}');\n }\n \$this->properties['{$propName}'] = {$propertyCode};\n "); } } $methods['force']['setPropertiesFromDbArray'] = $this->unindent(2, "\n /** Do not override */\n protected function setPropertiesFromDbArray(array \$dbArray)\n {\n {$dbToPhpMethodBody}\n }\n "); // INITIAL PROPERTY VALUES $initPropsMethodBody = ''; foreach ($this->modelsConfig->models[$modelName]->properties as $propName => $propConfig) { $type = $propConfig->type; if ($propConfig->default) { $valueDef = $propConfig->default; $rawValueCode = $valueDef === 'now' ? '\\Grace\\ORM\\Type\\TypeTimestamp::format(time())' : var_export($valueDef, true); $isNullAllowed = $propConfig->isNullable; // TODO убрать необходимость в этом вызове $valueCode = '$this->orm->typeConverter->convertOnSetter(' . var_export($type, true) . ', ' . $rawValueCode . ', ' . var_export($isNullAllowed, true) . ')'; } else { if ($propConfig->isNullable) { $valueCode = 'null'; } else { $valueCode = $this->typeConverter->getPhpDefaultValueCode($type); } } $initPropsMethodBody .= "\n '{$propName}' => {$valueCode},"; } $initPropsMethodBody .= "\n "; $methods['force']['setDefaultPropertyValues'] = $this->unindent(2, "\n /** Do not override */\n protected function setDefaultPropertyValues()\n {\n \$this->properties = array({$initPropsMethodBody});\n }\n "); return $methods; }