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.
## 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.
Schema Setup:
schema.xml).vendor/bin/propel-gen build --config=conf/build.properties
vendor/bin/propel-gen sql build --config=conf/build.properties
First Query:
use MyProject\models\User;
$users = UserQuery::create()->find();
foreach ($users as $user) {
echo $user->getName();
}
vendor/bin/propel-gen for schema generation, reverse engineering, and migrations.generated-conf/ (default). These include BasePeer, BaseModel, and Query classes.conf/build.properties for configuration (e.g., database connections, output paths).// 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();
$users = UserQuery::create()->filterByName('John')->find();
foreach ($users as $user) {
echo $user->getEmail();
}
$criteria = new Criteria();
$criteria->add(UserPeer::NAME, 'John', Criteria::EQUAL);
$criteria->addAscendingOrderByColumn(UserPeer::ID);
$users = UserPeer::doSelect($criteria);
$users = UserQuery::create()
->filterByName('John')
->orderByName()
->find();
$user = UserQuery::create()->findPk(1);
foreach ($user->getPosts() as $post) {
echo $post->getTitle();
}
$user = UserQuery::create()->findPk(1);
foreach ($user->getRoles() as $role) {
echo $role->getName();
}
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.
vendor/bin/propel-gen reverse --config=conf/build.properties
vendor/bin/propel-gen diff --config=conf/build.properties
Laravel Compatibility:
BasePeer to a service container or facade.// In a service provider
$this->app->singleton('propel', function () {
return UserPeer::getDatabase();
});
$user = app('propel')->getUserQuery()->findPk(1);
Dependency Injection:
BasePeer or Query classes into controllers/services:
public function __construct(UserQuery $userQuery) {
$this->userQuery = $userQuery;
}
Testing:
PropelTestCase or Laravel’s DatabaseMigrations with Propel’s schema.public function testUserCreation() {
$user = new User();
$user->setName('Test');
$user->save();
$this->assertDatabaseHas('user', ['name' => 'Test']);
}
PHP Version Incompatibilities:
error_reporting(E_ALL & ~E_DEPRECATED) to suppress deprecation warnings.Schema Generation Quirks:
skipSql in build.properties to debug:
propel.generator.reverse.skipSql=true
SQL Injection:
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();
Behavior Conflicts:
created_at/updated_at columns exist before using the behavior.symfony_i18n. Use add_cleanup to handle duplicates:
<parameter name="addCleanup" value="true"/>
Caching Issues:
vendor/bin/propel-gen build --config=conf/build.properties --clear-cache
Propel::getInstance()->clearInstancePool();
Transaction Handling:
try-catch:
try {
$user->save();
$user->addPost($post);
$user->getConnection()->commit();
} catch (Exception $e) {
$user->getConnection()->rollBack();
throw $e;
}
Enable Logging:
build.properties:
propel.logger=debug
runtime/propel.log.Query Debugging:
DebugPDO to log SQL queries:
$pdo = new DebugPDO(
UserPeer::getConnection()->getWrappedConnection()
);
UserPeer::setConnection($pdo);
stderr or a file.Psalm Static Analysis:
vendor/bin/psalm --init
vendor/bin/psalm
Common Errors:
build.properties.Custom Behaviors:
PropelBehavior to create reusable logic (e.g., audit trails, soft deletes).class AuditBehavior extends PropelBehavior {
public function buildTableMap(TableMapBuilder $builder) {
$builder->addColumn('created_by', 'VARCHAR', 255);
}
}
Query Interceptors:
Peer methods to modify queries:
class UserPeer extends BaseUserPeer {
public static function doSelect(Criteria $criteria) {
$criteria->addAscendingOrderByColumn(self::NAME);
return parent::doSelect($criteria);
}
}
Model Events:
How can I help you explore Laravel packages today?