/** * @param TypeInterface $type */ public function buildType(TypeInterface $type) { $base_class_name = Inflector::classify(Inflector::singularize($type->getName())); $base_class_extends = '\\' . ltrim($type->getBaseClassExtends(), '\\'); $base_class_build_path = $this->getBuildPath() ? "{$this->getBuildPath()}/Base/{$base_class_name}.php" : null; $result = []; $result[] = '<?php'; $result[] = ''; if ($this->getStructure()->getConfig('header_comment')) { $result = array_merge($result, explode("\n", $this->getStructure()->getConfig('header_comment'))); $result[] = ''; } $base_class_namespace = $this->getStructure()->getNamespace() ? $this->getStructure()->getNamespace() . '\\Base' : 'Base'; $result[] = 'namespace ' . $base_class_namespace . ';'; $result[] = ''; $result[] = '/**'; $this->buildBaseClassDocBlockProperties('', $result); $result[] = ' * @package ' . $base_class_namespace; $result[] = ' */'; $interfaces = $traits = []; foreach ($type->getTraits() as $interface => $implementations) { if ($interface != '--just-paste-trait--') { $interfaces[] = '\\' . ltrim($interface, '\\'); } if (count($implementations)) { foreach ($implementations as $implementation) { $traits[] = '\\' . ltrim($implementation, '\\'); } } } $result[] = 'abstract class ' . $base_class_name . ' extends ' . $base_class_extends . (empty($interfaces) ? '' : ' implements ' . implode(', ', $interfaces)); $result[] = '{'; if (count($traits)) { $trait_tweaks_count = count($type->getTraitTweaks()); $result[] = ' use ' . implode(', ', $traits) . ($trait_tweaks_count ? '{' : ';'); if ($trait_tweaks_count) { for ($i = 0; $i < $trait_tweaks_count - 1; ++$i) { $result[] = ' ' . $type->getTraitTweaks()[$i] . ($i < $trait_tweaks_count - 2 ? ',' : ''); } $result[] = ' }'; } $result[] = ''; } $result[] = ' /**'; $result[] = ' * Name of the table where records are stored.'; $result[] = ' *'; $result[] = ' * @var string'; $result[] = ' */'; $result[] = ' protected $table_name = ' . var_export($type->getTableName(), true) . ';'; $fields = $type->getAllFields(); $this->buildFields($fields, ' ', $result); $this->buildGeneratedFields(array_keys($type->getGeneratedFields()), ' ', $result); if (count($type->getProtectedFields())) { $result[] = ''; $result[] = ' /**'; $result[] = ' * List of protected fields.'; $result[] = ' *'; $result[] = ' * @var array'; $result[] = ' */'; $result[] = ' protected $protected_fields = [' . implode(', ', array_map(function ($field) { return var_export($field, true); }, $type->getProtectedFields())) . '];'; } if ($type->getOrderBy() != ['id']) { $result[] = ''; $result[] = ' /**'; $result[] = ' * @var string[]'; $result[] = ' */'; $result[] = ' protected $order_by = [' . implode(', ', array_map(function ($value) { return var_export($value, true); }, $type->getOrderBy())) . '];'; } $this->buildConfigureMethod($type->getGeneratedFields(), ' ', $result); foreach ($type->getAssociations() as $association) { $association->buildClassMethods($this->getStructure(), $type, $this->getStructure()->getType($association->getTargetTypeName()), $result); } foreach ($fields as $field) { if ($field instanceof ScalarField && $field->getShouldBeAddedToModel() && $field->getName() != 'id') { $this->buildFieldGetterAndSetter($field, ' ', $result); } } foreach ($type->getGeneratedFields() as $field_name => $caster) { $this->buildGeneratedFieldGetter($field_name, $caster, ' ', $result); } $build_custom_get_field_value = false; foreach ($fields as $field) { if ($field instanceof ScalarField && $field->getShouldBeAddedToModel() && !empty($field->getDeserializingCode('raw_value'))) { $build_custom_get_field_value = true; break; } } if ($build_custom_get_field_value) { $result[] = ''; $result[] = ' /**'; $result[] = ' * {@inheritdoc}'; $result[] = ' */'; $result[] = ' public function getFieldValue($field, $default = null)'; $result[] = ' {'; $result[] = ' $value = parent::getFieldValue($field, $default);'; $result[] = ''; $result[] = ' if ($value === null) {'; $result[] = ' return null;'; $result[] = ' } else {'; $result[] = ' switch ($field) {'; foreach ($fields as $field) { if ($field instanceof ScalarField && $field->getShouldBeAddedToModel() && !empty($field->getDeserializingCode('value'))) { $result[] = ' case ' . var_export($field->getName(), true) . ':'; $result[] = ' return ' . $field->getDeserializingCode('value') . ';'; } } $result[] = ' }'; $result[] = ''; $result[] = ' return $value;'; $result[] = ' }'; $result[] = ' }'; } $result[] = ''; $result[] = ' /**'; $result[] = ' * {@inheritdoc}'; $result[] = ' */'; $result[] = ' public function &setFieldValue($name, $value)'; $result[] = ' {'; $result[] = ' if ($value === null) {'; $result[] = ' parent::setFieldValue($name, null);'; $result[] = ' } else {'; $result[] = ' switch ($name) {'; $casters = []; foreach ($fields as $field) { if ($field instanceof ScalarField && $field->getShouldBeAddedToModel()) { $casting_code = $field->getCastingCode('value'); if (empty($casters[$casting_code])) { $casters[$casting_code] = []; } $casters[$casting_code][] = $field->getName(); } } foreach ($casters as $caster_code => $casted_field_names) { foreach ($casted_field_names as $casted_field_name) { $result[] = ' case ' . var_export($casted_field_name, true) . ':'; } $result[] = ' return parent::setFieldValue($name, ' . $caster_code . ');'; } $result[] = ' default:'; $result[] = ' if ($this->isLoading()) {'; $result[] = ' return parent::setFieldValue($name, $value);'; $result[] = ' } else {'; $result[] = ' if ($this->isGeneratedField($name)) {'; $result[] = ' throw new \\LogicException("Generated field $name cannot be set by directly assigning a value");'; $result[] = ' } else {'; $result[] = ' throw new \\InvalidArgumentException("Field $name does not exist in this table");'; $result[] = ' }'; $result[] = ' }'; $result[] = ' }'; $result[] = ' }'; $result[] = ''; $result[] = ' return $this;'; $result[] = ' }'; $this->buildJsonSerialize($type->getSerialize(), ' ', $result); $this->buildCompositeFieldMethods($type->getFields(), ' ', $result); $this->buildValidate($type->getFields(), $type->getAssociations(), ' ', $result); $result[] = '}'; $result[] = ''; $result = implode("\n", $result); if ($this->getBuildPath()) { file_put_contents($base_class_build_path, $result); } else { eval(ltrim($result, '<?php')); } $this->triggerEvent('on_class_built', [$base_class_name, $base_class_build_path]); }
/** * Prepare CREATE TABLE statement for the given type. * * @param TypeInterface $type * @return string */ public function prepareCreateTableStatement(TypeInterface $type) { $result = []; $result[] = 'CREATE TABLE IF NOT EXISTS ' . $this->getConnection()->escapeTableName($type->getName()) . ' ('; $generaterd_field_indexes = []; foreach ($type->getAllFields() as $field) { if ($field instanceof ScalarField) { $result[] = ' ' . $this->prepareFieldStatement($field) . ','; } if ($field instanceof JsonFieldInterface) { foreach ($field->getValueExtractors() as $value_extractor) { $result[] = ' ' . $this->prepareGeneratedFieldStatement($field, $value_extractor) . ','; if ($value_extractor->getAddIndex()) { $generaterd_field_indexes[] = new Index($value_extractor->getFieldName()); } } } } $indexes = $type->getAllIndexes(); if (!empty($generaterd_field_indexes)) { $indexes = array_merge($indexes, $generaterd_field_indexes); } foreach ($indexes as $index) { $result[] = ' ' . $this->prepareIndexStatement($index) . ','; } $last_line = count($result) - 1; $result[$last_line] = rtrim($result[$last_line], ','); $result[] = ') ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;'; return implode("\n", $result); }