willdurand/propel-typehintable-behavior
Installation:
TypehintableBehavior.php from the repo into your Laravel project (e.g., app/Propel/Behaviors/).propel.ini or build.properties):
propel.behavior.typehintable.class = app/Propel/Behaviors/TypehintableBehavior
First Use Case:
schema.xml:
<table name="user">
<column name="id" type="integer" primaryKey="true" autoIncrement="true" />
<column name="role" type="varchar" size="255" />
<behavior name="typehintable">
<parameter name="role" value="App\Models\Role" />
</behavior>
</table>
php artisan propel:build to generate type-hinted base classes.Verify:
_BaseUser.php for type-hinted methods like:
public function setRole(App\Models\Role $role = null)
Type-Hinting Columns:
role column → App\Models\Role).<parameter name="email" value="App\Models\UserEmail" />
public function setEmail(App\Models\UserEmail $email = null)
Type-Hinting Relationships:
<parameter name="group" value="App\Models\Group" />
public function addGroup(App\Models\Group $group)
public function removeGroup(App\Models\Group $group)
Nullable Parameters:
<parameter name="nullable_columns" value="role, bio" />
public function setRole(App\Models\Role $role = null)
public function setBio(string $bio = null)
Integration with Laravel:
namespace App\Models;
use Propel\Runtime\ActiveQuery\ModelCriteria;
use Propel\Runtime\Map\TableMap;
class User extends \BaseUser
{
// Override or extend type-hinted methods
public function setRole(Role $role = null)
{
if ($role && !$role->isValid()) {
throw new \InvalidArgumentException("Invalid role");
}
parent::setRole($role);
}
}
Query Builder Compatibility:
$users = UserQuery::create()
->filterByRole(RoleQuery::create()->findPk(1))
->find();
Schema Regeneration:
php artisan propel:build) overwrites _Base*.php files. Backup or use version control for these files.php artisan propel:build --write-sql to preview changes before applying.Circular Dependencies:
User ↔ Group) may cause circular references.<parameter name="group" value="App\Contracts\GroupInterface" />
Propel Cache:
php artisan propel:build --clear-cache
IDE Autocompletion:
@mixin annotations in your model stubs:
/** @mixin \BaseUser */
class User extends \BaseUser {}
Third-Party Constraints:
@SuppressWarnings or create wrapper classes.Check Generated Files:
_Base*.php files in app/Propel/om/ to verify type hints are applied correctly.Propel Logs:
propel.ini:
propel.logger = debug
storage/logs/laravel.log for behavior-related errors.Parameter Validation:
TYPEHINT values in schema.xml are fully qualified class names (e.g., App\Models\Role, not Role).Custom Type Hints:
class CustomTypehintableBehavior extends TypehintableBehavior
{
protected function getTypeHint($columnName, $table)
{
if ($columnName === 'status') {
return \App\Models\Status::class;
}
return parent::getTypeHint($columnName, $table);
}
}
Composite Types:
arrayCollection behavior for complex types:
<behavior name="typehintable">
<parameter name="tags" value="App\Models\Tag[]" />
</behavior>
Laravel Service Providers:
$this->app->bind(
App\Models\User::class,
function () {
return new App\Models\User();
}
);
Testing:
$mockRole = $this->createMock(Role::class);
$user->setRole($mockRole);
$this->assertSame($mockRole, $user->getRole());
How can I help you explore Laravel packages today?