Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v4.0.6 #1499

Merged
merged 15 commits into from
Mar 22, 2021
Merged

v4.0.6 #1499

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
# [4.0.6](https://github.com/phalcon/cphalcon/releases/tag/v4.0.6) (2021-03-22)
## Fixed
- Fixed model findFirst return type error [#1478](https://github.com/phalcon/phalcon-devtools/issues/1478)
- Added trailing semicolon to scaffolding crud views getters [#1477](https://github.com/phalcon/phalcon-devtools/issues/1477)
- Fixed optional options (namespace, abstract) checks on model create [#1491](https://github.com/phalcon/phalcon-devtools/issues/1491)
- Fixed wrong request filtering [#1468](https://github.com/phalcon/phalcon-devtools/issues/1468)
- Fixed empty namespace generation [#1467](https://github.com/phalcon/phalcon-devtools/issues/1467)
- Removed `model->getSource()` method generation due to its becoming final in `Phalcon\Mvc\Model` [#1297](https://github.com/phalcon/phalcon-devtools/issues/1297)
- Fixed model `--force` creation bugs [#1317](https://github.com/phalcon/phalcon-devtools/issues/1317)
- Fixed mapping of PascalCase table fields [#1463](https://github.com/phalcon/phalcon-devtools/issues/1463)


# [4.0.5](https://github.com/phalcon/cphalcon/releases/tag/v4.0.5) (2021-03-14)
## Fixed
- Fixed model creation failure in webtools due to wrong variable mutation [#1415](https://github.com/phalcon/phalcon-devtools/issues/1415)
Expand Down
7 changes: 1 addition & 6 deletions src/Builder/Component/AllModels.php
Original file line number Diff line number Diff line change
Expand Up @@ -85,14 +85,9 @@ public function build(): void
$genSettersGetters = $this->options->get('genSettersGetters', false);
$mapColumn = $this->options->get('mapColumn', false);

$adapter = $config->database->adapter;
$adapter = $config->database->adapter ?? 'Mysql';
$this->isSupportedAdapter($adapter);

$adapter = 'Mysql';
if (isset($config->database->adapter)) {
$adapter = $config->database->adapter;
}

if (is_object($config->database)) {
$configArray = $config->database->toArray();
} else {
Expand Down
6 changes: 4 additions & 2 deletions src/Builder/Component/Controller.php
Original file line number Diff line number Diff line change
Expand Up @@ -103,12 +103,14 @@ public function build()
*/
protected function constructNamespace(): string
{
$namespace = $this->options->get('namespace');
$namespace = $this->options->has('namespace')
? (string) $this->options->get('namespace') : null;

if ($namespace === null) {
return '';
}

if ($this->checkNamespace((string)$namespace)) {
if ($this->checkNamespace($namespace) && !empty(trim($namespace))) {
return 'namespace ' . $this->options->get('namespace') . ';' . PHP_EOL . PHP_EOL;
}

Expand Down
213 changes: 99 additions & 114 deletions src/Builder/Component/Model.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
use Phalcon\Validation;
use Phalcon\Validation\Validator\Email as EmailValidator;
use ReflectionClass;
use ReflectionClassConstant;
use ReflectionProperty;

/**
* Builder to generate models
Expand Down Expand Up @@ -111,23 +113,19 @@ public function build(): void
require_once $config->devtools->loader;
}

$namespace = '';
if ($this->modelOptions->hasOption('namespace') &&
$this->checkNamespace((string)$this->modelOptions->getOption('namespace'))) {
$namespace = $this->modelOptions->hasOption('namespace')
? (string) $this->modelOptions->getOption('namespace') : '';

if ($this->checkNamespace($namespace) && !empty(trim($namespace))) {
$namespace = 'namespace ' . $this->modelOptions->getOption('namespace') . ';' . PHP_EOL . PHP_EOL;
}

$genDocMethods = $this->modelOptions->getValidOptionOrDefault('genDocMethods', false);
$useSettersGetters = $this->modelOptions->getValidOptionOrDefault('genSettersGetters', false);

$adapter = $config->database->adapter;
$adapter = $config->database->adapter ?? 'Mysql';
$this->isSupportedAdapter($adapter);

$adapter = 'Mysql';
if (isset($config->database->adapter)) {
$adapter = $config->database->adapter;
}

if (is_object($config->database)) {
$configArray = $config->database->toArray();
} else {
Expand Down Expand Up @@ -167,40 +165,36 @@ public function build(): void

foreach ($referenceList as $tableName => $references) {
foreach ($references as $reference) {
if ($reference->getReferencedTable() != $this->modelOptions->getOption('name')) {
if ($reference->getReferencedTable() !== $this->modelOptions->getOption('name')) {
continue;
}

$entityNamespace = '';
if ($this->modelOptions->getOption('namespace')) {
$entityNamespace = $this->modelOptions->getOption('namespace')."\\";
}
$entityNamespace = $this->modelOptions->hasOption('namespace')
? $this->modelOptions->getOption('namespace')."\\" : '';

$refColumns = $reference->getReferencedColumns();
$columns = $reference->getColumns();
$initialize[] = $snippet->getRelation(
'hasMany',
$this->modelOptions->getOption('camelize') ? Utils::lowerCamelize($refColumns[0]) : $refColumns[0],
$this->getFieldName($refColumns[0]),
$entityNamespace . Text::camelize($tableName, '_-'),
$this->modelOptions->getOption('camelize') ? Utils::lowerCamelize($columns[0]) : $columns[0],
$this->getFieldName($columns[0]),
"['alias' => '" . Text::camelize($tableName, '_-') . "']"
);
}
}

foreach ($db->describeReferences($this->modelOptions->getOption('name'), $schema) as $reference) {
$entityNamespace = '';
if ($this->modelOptions->getOption('namespace')) {
$entityNamespace = $this->modelOptions->getOption('namespace');
}
$entityNamespace = $this->modelOptions->hasOption('namespace')
? $this->modelOptions->getOption('namespace') : '';

$refColumns = $reference->getReferencedColumns();
$columns = $reference->getColumns();
$initialize[] = $snippet->getRelation(
'belongsTo',
$this->modelOptions->getOption('camelize') ? Utils::lowerCamelize($columns[0]) : $columns[0],
$this->getFieldName($columns[0]),
$this->getEntityClassName($reference, $entityNamespace),
$this->modelOptions->getOption('camelize') ? Utils::lowerCamelize($refColumns[0]) : $refColumns[0],
$this->getFieldName($refColumns[0]),
"['alias' => '" . Text::camelize($reference->getReferencedTable(), '_-') . "']"
);
}
Expand All @@ -225,8 +219,6 @@ public function build(): void
}
}

$possibleMethods['getSource'] = true;

/** @noinspection PhpIncludeInspection */
require_once $modelPath;

Expand All @@ -237,7 +229,7 @@ public function build(): void
}
$reflection = new ReflectionClass($fullClassName);
foreach ($reflection->getMethods() as $method) {
if ($method->getDeclaringClass()->getName() != $fullClassName) {
if ($method->getDeclaringClass()->getName() !== $fullClassName) {
continue;
}

Expand Down Expand Up @@ -285,117 +277,60 @@ public function build(): void
}
}

$possibleFields = $possibleFieldsTransformed = [];
$possibleFieldsTransformed = [];
foreach ($fields as $field) {
$possibleFields[$field->getName()] = true;
if ($this->modelOptions->getOption('camelize')) {
$fieldName = Utils::lowerCamelize(Utils::camelize($field->getName(), '_-'));
} else {
$fieldName = Utils::lowerCamelize(Utils::camelize($field->getName(), '-'));
}
$fieldName = $this->getFieldName($field->getName());
$possibleFieldsTransformed[$fieldName] = true;
}

if (method_exists($reflection, 'getReflectionConstants')) {
foreach ($reflection->getReflectionConstants() as $constant) {
if ($constant->getDeclaringClass()->getName() != $fullClassName) {
if ($constant->getDeclaringClass()->getName() !== $fullClassName) {
continue;
}
$constantsPreg = '/^(\s*)const(\s+)'.$constant->getName().'([\s=;]+)/';
$endLine = $startLine = 0;
foreach ($linesCode as $line => $code) {
if (preg_match($constantsPreg, $code)) {
$startLine = $line;
break;
}
}
if (!empty($startLine)) {
$countLines = count($linesCode);
for ($i = $startLine; $i < $countLines; $i++) {
if (preg_match('/;(\s*)$/', $linesCode[$i])) {
$endLine = $i;
break;
}
}
}

if (!empty($startLine) && !empty($endLine)) {
$constantDeclaration = join(
'',
array_slice(
$linesCode,
$startLine,
$endLine - $startLine + 1
)
);
$attributes[] = PHP_EOL . " " . $constant->getDocComment() .
PHP_EOL . $constantDeclaration;
$constantsPreg = '/const(\s+)' . $constant->getName() . '([\s=;]+)/';
$attribute = $this->getAttribute($linesCode, $constantsPreg, $constant);
if (!empty($attribute)) {
$attributes[] = $attribute;
}
}
}

foreach ($reflection->getProperties() as $property) {
$propertyName = $property->getName();
/** @var null|string $possibleFieldsValue */
$possibleFieldsValue = $possibleFieldsTransformed[$propertyName];

if ($property->getDeclaringClass()->getName() != $fullClassName ||
!empty($possibleFieldsValue)) {
if (!empty($possibleFieldsTransformed[$propertyName])
|| $property->getDeclaringClass()->getName() !== $fullClassName
) {
continue;
}

$modifiersPreg = '';
switch ($property->getModifiers()) {
case \ReflectionProperty::IS_PUBLIC:
case ReflectionProperty::IS_PUBLIC:
$modifiersPreg = '^(\s*)public(\s+)';
break;
case \ReflectionProperty::IS_PRIVATE:
case ReflectionProperty::IS_PRIVATE:
$modifiersPreg = '^(\s*)private(\s+)';
break;
case \ReflectionProperty::IS_PROTECTED:
case ReflectionProperty::IS_PROTECTED:
$modifiersPreg = '^(\s*)protected(\s+)';
break;
case \ReflectionProperty::IS_STATIC + \ReflectionProperty::IS_PUBLIC:
case ReflectionProperty::IS_STATIC + ReflectionProperty::IS_PUBLIC:
$modifiersPreg = '^(\s*)(public?)(\s+)static(\s+)';
break;
case \ReflectionProperty::IS_STATIC + \ReflectionProperty::IS_PROTECTED:
case ReflectionProperty::IS_STATIC + ReflectionProperty::IS_PROTECTED:
$modifiersPreg = '^(\s*)protected(\s+)static(\s+)';
break;
case \ReflectionProperty::IS_STATIC + \ReflectionProperty::IS_PRIVATE:
case ReflectionProperty::IS_STATIC + ReflectionProperty::IS_PRIVATE:
$modifiersPreg = '^(\s*)private(\s+)static(\s+)';
break;
}

$modifiersPreg = '/' . $modifiersPreg . '\$' . $propertyName . '([\s=;]+)/';
$endLine = $startLine = 0;
foreach ($linesCode as $line => $code) {
if (preg_match($modifiersPreg, $code)) {
$startLine = $line;
break;
}
}

if (!empty($startLine)) {
$countLines = count($linesCode);
for ($i = $startLine; $i < $countLines; $i++) {
if (preg_match('/;(\s*)$/', $linesCode[$i])) {
$endLine = $i;
break;
}
}
}

if (!empty($startLine) && !empty($endLine)) {
$propertyDeclaration = join(
'',
array_slice(
$linesCode,
$startLine,
$endLine - $startLine + 1
)
);
$attributes[] = PHP_EOL . " " . $property->getDocComment() . PHP_EOL .
$propertyDeclaration;
$attribute = $this->getAttribute($linesCode, $modifiersPreg, $property);
if (!empty($attribute)) {
$attributes[] = $attribute;
}
}
} catch (\Exception $e) {
Expand All @@ -411,12 +346,9 @@ public function build(): void

$validations = [];
foreach ($fields as $field) {
$fieldName = $this->getFieldName($field->getName());

if ($field->getType() === Column::TYPE_CHAR) {
if ($this->modelOptions->getOption('camelize')) {
$fieldName = Utils::lowerCamelize(Utils::camelize($field->getName(), '_-'));
} else {
$fieldName = Utils::lowerCamelize(Utils::camelize($field->getName(), '-'));
}
$domain = [];
if (preg_match('/\((.*)\)/', (string)$field->getType(), $matches)) {
foreach (explode(',', $matches[1]) as $item) {
Expand All @@ -429,12 +361,7 @@ public function build(): void
}
}

if ($field->getName() == 'email') {
if ($this->modelOptions->getOption('camelize')) {
$fieldName = Utils::lowerCamelize(Utils::camelize($field->getName(), '_-'));
} else {
$fieldName = Utils::lowerCamelize(Utils::camelize($field->getName(), '-'));
}
if ($field->getName() === 'email') {
$validations[] = $snippet->getValidateEmail($fieldName);
$uses[] = $snippet->getUseAs(EmailValidator::class, 'EmailValidator');
}
Expand Down Expand Up @@ -466,8 +393,7 @@ public function build(): void
}

$type = $this->getPHPType($field->getType());
$fieldName = Utils::lowerCamelizeWithDelimiter($field->getName(), '-', true);
$fieldName = $this->modelOptions->getOption('camelize') ? Utils::lowerCamelize($fieldName) : $fieldName;
$fieldName = $this->getFieldName($field->getName());
$attributes[] = $snippet->getAttributes(
$type,
$useSettersGetters ? 'protected' : 'public',
Expand Down Expand Up @@ -572,6 +498,65 @@ public function build(): void
}
}

/**
* @param array $linesCode
* @param string $pattern
* @param ReflectionProperty|ReflectionClassConstant $attribute
*
* @return null|string
*/
protected function getAttribute(array $linesCode, string $pattern, $attribute): ?string
{
$endLine = $startLine = 0;
foreach ($linesCode as $line => $code) {
if (preg_match($pattern, $code)) {
$startLine = $line;
break;
}
}
if (!empty($startLine)) {
$countLines = count($linesCode);
for ($i = $startLine; $i < $countLines; $i++) {
if (preg_match('/;(\s*)$/', $linesCode[$i])) {
$endLine = $i;
break;
}
}
}

if (!empty($startLine) && !empty($endLine)) {
$attributeDeclaration = join(
'',
array_slice(
$linesCode,
$startLine,
$endLine - $startLine + 1
)
);
$attributeFormatted = $attributeDeclaration;
if (!empty($attribute->getDocComment())) {
$attributeFormatted = " " . $attribute->getDocComment() . PHP_EOL . $attribute;
}
return $attributeFormatted;
}

return null;
}

/**
* @param string $fieldName
*
* @return string
*/
protected function getFieldName(string $fieldName): string
{
if ($this->modelOptions->getOption('camelize')) {
return Utils::lowerCamelize(Utils::camelize($fieldName, '_-'));
}

return Utils::lowerCamelizeWithDelimiter($fieldName, '-', true);
}

/**
* Set path to model
*
Expand Down
Loading