Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Propel Typehintable Behavior Laravel Package

willdurand/propel-typehintable-behavior

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    • Cherry-pick TypehintableBehavior.php from the repo into your Laravel project (e.g., app/Propel/Behaviors/).
    • Add the behavior class path to your Propel configuration (propel.ini or build.properties):
      propel.behavior.typehintable.class = app/Propel/Behaviors/TypehintableBehavior
      
  2. First Use Case:

    • Add the behavior to a schema table in 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>
      
    • Run php artisan propel:build to generate type-hinted base classes.
  3. Verify:

    • Check the generated _BaseUser.php for type-hinted methods like:
      public function setRole(App\Models\Role $role = null)
      

Implementation Patterns

Workflows

  1. Type-Hinting Columns:

    • Map database columns to PHP classes (e.g., role column → App\Models\Role).
    • Useful for enforcing type safety in setters/getters:
      <parameter name="email" value="App\Models\UserEmail" />
      
    • Generated output:
      public function setEmail(App\Models\UserEmail $email = null)
      
  2. Type-Hinting Relationships:

    • Add type hints to adder/remover methods for related tables:
      <parameter name="group" value="App\Models\Group" />
      
    • Generated output:
      public function addGroup(App\Models\Group $group)
      public function removeGroup(App\Models\Group $group)
      
  3. Nullable Parameters:

    • Explicitly mark nullable columns/relationships:
      <parameter name="nullable_columns" value="role, bio" />
      
    • Generated output:
      public function setRole(App\Models\Role $role = null)
      public function setBio(string $bio = null)
      
  4. Integration with Laravel:

    • Extend Propel-generated models in 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);
          }
      }
      
  5. Query Builder Compatibility:

    • Use type-hinted models in Laravel’s query builder:
      $users = UserQuery::create()
          ->filterByRole(RoleQuery::create()->findPk(1))
          ->find();
      

Gotchas and Tips

Pitfalls

  1. Schema Regeneration:

    • Regenerating the schema (php artisan propel:build) overwrites _Base*.php files. Backup or use version control for these files.
    • Tip: Use php artisan propel:build --write-sql to preview changes before applying.
  2. Circular Dependencies:

    • Type-hinting bidirectional relationships (e.g., UserGroup) may cause circular references.
    • Fix: Use interfaces or abstract classes for shared relationships:
      <parameter name="group" value="App\Contracts\GroupInterface" />
      
  3. Propel Cache:

    • Clear Propel’s runtime cache after schema changes:
      php artisan propel:build --clear-cache
      
  4. IDE Autocompletion:

    • Some IDEs (e.g., PHPStorm) may not recognize type hints in generated files. Use @mixin annotations in your model stubs:
      /** @mixin \BaseUser */
      class User extends \BaseUser {}
      
  5. Third-Party Constraints:

    • If integrating with libraries expecting raw Propel models (e.g., old versions of Laravel-Propel bridges), type hints may break compatibility.
    • Workaround: Use @SuppressWarnings or create wrapper classes.

Debugging

  1. Check Generated Files:

    • Inspect _Base*.php files in app/Propel/om/ to verify type hints are applied correctly.
  2. Propel Logs:

    • Enable debug logging in propel.ini:
      propel.logger = debug
      
    • Check logs at storage/logs/laravel.log for behavior-related errors.
  3. Parameter Validation:

    • Ensure TYPEHINT values in schema.xml are fully qualified class names (e.g., App\Models\Role, not Role).

Extension Points

  1. Custom Type Hints:

    • Override the behavior class to add dynamic type hints (e.g., based on runtime conditions):
      class CustomTypehintableBehavior extends TypehintableBehavior
      {
          protected function getTypeHint($columnName, $table)
          {
              if ($columnName === 'status') {
                  return \App\Models\Status::class;
              }
              return parent::getTypeHint($columnName, $table);
          }
      }
      
  2. Composite Types:

    • Combine with Propel’s arrayCollection behavior for complex types:
      <behavior name="typehintable">
          <parameter name="tags" value="App\Models\Tag[]" />
      </behavior>
      
    • Note: Requires Propel 2.0+ and custom behavior logic.
  3. Laravel Service Providers:

    • Bind Propel models to Laravel’s container for dependency injection:
      $this->app->bind(
          App\Models\User::class,
          function () {
              return new App\Models\User();
          }
      );
      
  4. Testing:

    • Mock type-hinted dependencies in PHPUnit:
      $mockRole = $this->createMock(Role::class);
      $user->setRole($mockRole);
      $this->assertSame($mockRole, $user->getRole());
      
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
comsave/common
alecsammon/php-raml-parser
chrome-php/wrench
lendable/composer-license-checker
typhoon/reflection
mesilov/moneyphp-percentage
mike42/gfx-php
bookdown/themes
aura/view
aura/html
aura/cli
povils/phpmnd
nayjest/manipulator
omnipay/tests
psr-mock/http-message-implementation
psr-mock/http-factory-implementation
psr-mock/http-client-implementation
voku/email-check
voku/urlify
rtheunissen/guzzle-log-middleware