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

Propel1 Laravel Package

palepurple/propel1

Fork of legacy Propel 1.x ORM with patches to keep it usable on modern PHP: PHP 7.2–7.4 test fixes, SQL injection fix for limit/offset, count() fix, PropelArrayFormatter fix, and extensive phpdoc updates to support Psalm on generated code.

View on GitHub
Deep Wiki
Context7
## Getting Started

### Minimal Steps
1. **Installation**:
   ```bash
   composer require palepurple/propel1

Ensure your composer.json includes "minimum-stability": "dev" if using PHP 7.x compatibility patches.

  1. Schema Setup:

    • Define your database schema in an XML file (e.g., schema.xml).
    • Generate Propel classes using the CLI:
      vendor/bin/propel-gen build --config=conf/build.properties
      
    • Load the schema into your database:
      vendor/bin/propel-gen sql build --config=conf/build.properties
      
  2. First Query:

    use MyProject\models\User;
    
    $users = UserQuery::create()->find();
    foreach ($users as $user) {
        echo $user->getName();
    }
    

Where to Look First

  • CLI Commands: vendor/bin/propel-gen for schema generation, reverse engineering, and migrations.
  • Generated Classes: Located in generated-conf/ (default). These include BasePeer, BaseModel, and Query classes.
  • Build Properties: conf/build.properties for configuration (e.g., database connections, output paths).
  • Documentation: Propel 1.x Official Docs (note: fork-specific fixes are minimal).

Implementation Patterns

Core Workflows

1. Model Interaction

  • CRUD Operations:
    // Create
    $user = new User();
    $user->setName('John Doe');
    $user->save();
    
    // Read
    $user = UserQuery::create()->findPk(1);
    
    // Update
    $user->setName('Jane Doe');
    $user->save();
    
    // Delete
    $user->delete();
    
  • Collections:
    $users = UserQuery::create()->filterByName('John')->find();
    foreach ($users as $user) {
        echo $user->getEmail();
    }
    

2. Query Building

  • Criteria API:
    $criteria = new Criteria();
    $criteria->add(UserPeer::NAME, 'John', Criteria::EQUAL);
    $criteria->addAscendingOrderByColumn(UserPeer::ID);
    $users = UserPeer::doSelect($criteria);
    
  • Fluent Query Interface:
    $users = UserQuery::create()
        ->filterByName('John')
        ->orderByName()
        ->find();
    

3. Relationships

  • One-to-Many:
    $user = UserQuery::create()->findPk(1);
    foreach ($user->getPosts() as $post) {
        echo $post->getTitle();
    }
    
  • Many-to-Many:
    $user = UserQuery::create()->findPk(1);
    foreach ($user->getRoles() as $role) {
        echo $role->getName();
    }
    

4. Behaviors

  • Timestampable:

    <behavior name="timestampable">
        <parameter name="createdColumnName" value="created_at"/>
        <parameter name="modifiedColumnName" value="updated_at"/>
    </behavior>
    

    Automatically sets created_at and updated_at on save.

  • Sluggable:

    <behavior name="sluggable">
        <parameter name="columnName" value="slug"/>
        <parameter name="scope" value="name"/>
    </behavior>
    

    Generates slugs from name and stores them in slug.

5. Migrations

  • Reverse Engineering:
    vendor/bin/propel-gen reverse --config=conf/build.properties
    
  • Schema Diff:
    vendor/bin/propel-gen diff --config=conf/build.properties
    

Integration Tips

  • Laravel Compatibility:

    • Use Propel alongside Laravel’s Eloquent by binding Propel’s BasePeer to a service container or facade.
    • Example:
      // In a service provider
      $this->app->singleton('propel', function () {
          return UserPeer::getDatabase();
      });
      
    • Access Propel models via:
      $user = app('propel')->getUserQuery()->findPk(1);
      
  • Dependency Injection:

    • Inject BasePeer or Query classes into controllers/services:
      public function __construct(UserQuery $userQuery) {
          $this->userQuery = $userQuery;
      }
      
  • Testing:

    • Use Propel’s PropelTestCase or Laravel’s DatabaseMigrations with Propel’s schema.
    • Example:
      public function testUserCreation() {
          $user = new User();
          $user->setName('Test');
          $user->save();
          $this->assertDatabaseHas('user', ['name' => 'Test']);
      }
      

Gotchas and Tips

Pitfalls

  1. PHP Version Incompatibilities:

    • The fork fixes PHP 7.x issues, but some legacy code may still fail on PHP 8.x.
    • Workaround: Use error_reporting(E_ALL & ~E_DEPRECATED) to suppress deprecation warnings.
  2. Schema Generation Quirks:

    • Composite Primary Keys: Ensure the auto-increment column is first in the schema definition for MySQL.
    • Reverse Engineering: Tables with identical column names may cause issues. Use skipSql in build.properties to debug:
      propel.generator.reverse.skipSql=true
      
  3. SQL Injection:

    • Always use Propel’s Criteria API or Query Builder for dynamic queries. Avoid raw SQL with execute() unless sanitized:
      // UNSAFE
      $query = "SELECT * FROM user WHERE name = '$name'";
      $stmt = UserPeer::getConnection()->prepare($query);
      $stmt->execute([$name]);
      
      // SAFE
      $users = UserQuery::create()->filterByName($name)->find();
      
  4. Behavior Conflicts:

    • Timestampable: Ensure created_at/updated_at columns exist before using the behavior.
    • Sluggable: Conflicts may arise with symfony_i18n. Use add_cleanup to handle duplicates:
      <parameter name="addCleanup" value="true"/>
      
  5. Caching Issues:

    • Propel caches table maps and queries. Clear the cache after schema changes:
      vendor/bin/propel-gen build --config=conf/build.properties --clear-cache
      
    • Or programmatically:
      Propel::getInstance()->clearInstancePool();
      
  6. Transaction Handling:

    • Propel uses PDO transactions. Wrap operations in try-catch:
      try {
          $user->save();
          $user->addPost($post);
          $user->getConnection()->commit();
      } catch (Exception $e) {
          $user->getConnection()->rollBack();
          throw $e;
      }
      

Debugging Tips

  1. Enable Logging:

    • Add to build.properties:
      propel.logger=debug
      
    • Logs appear in runtime/propel.log.
  2. Query Debugging:

    • Use DebugPDO to log SQL queries:
      $pdo = new DebugPDO(
          UserPeer::getConnection()->getWrappedConnection()
      );
      UserPeer::setConnection($pdo);
      
    • Outputs SQL to stderr or a file.
  3. Psalm Static Analysis:

    • The fork includes fixes for Psalm compatibility. Run:
      vendor/bin/psalm --init
      vendor/bin/psalm
      
  4. Common Errors:

    • "Table [X] not found": Verify the schema is up-to-date and the database connection is correct in build.properties.
    • "Column [Y] not found": Check for typos in column names or missing reverse-engineering steps.

Extension Points

  1. Custom Behaviors:

    • Extend PropelBehavior to create reusable logic (e.g., audit trails, soft deletes).
    • Example:
      class AuditBehavior extends PropelBehavior {
          public function buildTableMap(TableMapBuilder $builder) {
              $builder->addColumn('created_by', 'VARCHAR', 255);
          }
      }
      
  2. Query Interceptors:

    • Override Peer methods to modify queries:
      class UserPeer extends BaseUserPeer {
          public static function doSelect(Criteria $criteria) {
              $criteria->addAscendingOrderByColumn(self::NAME);
              return parent::doSelect($criteria);
          }
      }
      
  3. Model Events:

    • Use Propel’s event system for pre/post-save
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.
besmartand-pro/php-quality-config
sentix/ai-chatbot
terminal42/code-quality-tools
codifyo/ts-generator-bundle
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity