-
Notifications
You must be signed in to change notification settings - Fork 102
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #159 from ndm2/entity-property-hints
Entity property hints
- Loading branch information
Showing
6 changed files
with
330 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
<?php | ||
namespace Bake\View\Helper; | ||
|
||
use Cake\ORM\Association; | ||
use Cake\View\Helper; | ||
|
||
/** | ||
* DocBlock helper | ||
*/ | ||
class DocBlockHelper extends Helper | ||
{ | ||
/** | ||
* Converts an entity class type to its DocBlock hint type counterpart. | ||
* | ||
* @param string $type The entity class type (a fully qualified class name). | ||
* @param \Cake\ORM\Association $association The association related to the entity class. | ||
* @return string The DocBlock type | ||
*/ | ||
public function associatedEntityTypeToHintType($type, Association $association) | ||
{ | ||
if ($association->type() === Association::MANY_TO_MANY || | ||
$association->type() === Association::ONE_TO_MANY | ||
) { | ||
return $type . '[]'; | ||
} | ||
return $type; | ||
} | ||
|
||
/** | ||
* Builds a map of entity property names and DocBlock types for use | ||
* in generating `@property` hints. | ||
* | ||
* This method expects a property schema as generated by | ||
* `\Bake\Shell\Task\ModelTask::getEntityPropertySchema()`. | ||
* | ||
* The generated map has the format of | ||
* | ||
* ``` | ||
* [ | ||
* 'property-name' => 'doc-block-type', | ||
* ... | ||
* ] | ||
* ``` | ||
* | ||
* @see \Bake\Shell\Task\ModelTask::getEntityPropertySchema | ||
* | ||
* @param array $propertySchema The property schema to use for generating the type map. | ||
* @return array The property DocType map. | ||
*/ | ||
public function buildEntityPropertyHintTypeMap(array $propertySchema) | ||
{ | ||
$properties = []; | ||
foreach ($propertySchema as $property => $info) { | ||
switch ($info['kind']) { | ||
case 'column': | ||
$properties[$property] = $this->columnTypeToHintType($info['type']); | ||
break; | ||
|
||
case 'association': | ||
$type = $this->associatedEntityTypeToHintType($info['type'], $info['association']); | ||
if ($info['association']->type() === Association::MANY_TO_ONE) { | ||
$properties = $this->_insertAfter( | ||
$properties, | ||
$info['association']->foreignKey(), | ||
[$property => $type] | ||
); | ||
} else { | ||
$properties[$property] = $type; | ||
} | ||
break; | ||
} | ||
} | ||
return $properties; | ||
} | ||
|
||
/** | ||
* Converts a column type to its DocBlock type counterpart. | ||
* | ||
* This method only supports the default CakePHP column types, | ||
* custom column/database types will be ignored. | ||
* | ||
* @see \Cake\Database\Type | ||
* | ||
* @param string $type The column type. | ||
* @return null|string The DocBlock type, or `null` for unsupported column types. | ||
*/ | ||
public function columnTypeToHintType($type) | ||
{ | ||
switch ($type) { | ||
case 'string': | ||
case 'text': | ||
case 'uuid': | ||
return 'string'; | ||
|
||
case 'integer': | ||
case 'biginteger': | ||
return 'int'; | ||
|
||
case 'float': | ||
case 'decimal': | ||
return 'float'; | ||
|
||
case 'boolean': | ||
return 'bool'; | ||
|
||
case 'binary': | ||
return 'string|resource'; | ||
|
||
case 'date': | ||
case 'datetime': | ||
case 'time': | ||
case 'timestamp': | ||
return '\Cake\I18n\Time'; | ||
} | ||
|
||
return null; | ||
} | ||
|
||
/** | ||
* Inserts a value after a specific key in an associative array. | ||
* | ||
* In case the given key cannot be found, the value will be appended. | ||
* | ||
* @param array $target The array in which to insert the new value. | ||
* @param string $key The array key after which to insert the new value. | ||
* @param mixed $value The entry to insert. | ||
* @return array The array with the new value inserted. | ||
*/ | ||
protected function _insertAfter(array $target, $key, $value) | ||
{ | ||
$index = array_search($key, array_keys($target)); | ||
if ($index !== false) { | ||
$target = array_merge( | ||
array_slice($target, 0, $index + 1), | ||
$value, | ||
array_slice($target, $index + 1, null) | ||
); | ||
} else { | ||
$target += (array)$value; | ||
} | ||
return $target; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
23 changes: 23 additions & 0 deletions
23
tests/comparisons/Model/testBakeEntityWithPropertyTypeHints.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
<?php | ||
namespace App\Model\Entity; | ||
|
||
use Cake\ORM\Entity; | ||
|
||
/** | ||
* BakeArticle Entity. | ||
* | ||
* @property int $id | ||
* @property int $bake_user_id | ||
* @property \App\Model\Entity\BakeUser $bake_user | ||
* @property string $title | ||
* @property string $body | ||
* @property bool $published | ||
* @property \Cake\I18n\Time $created | ||
* @property \Cake\I18n\Time $updated | ||
* @property $unknown_type | ||
* @property \BakeTest\Model\Entity\Author[] $authors | ||
*/ | ||
class BakeArticle extends Entity | ||
{ | ||
|
||
} |