willdurand/propel-publishable-behavior
Propel behavior that adds publish/unpublish support to your models and queries. Provides isPublished(), publish()/unpublish(), optional publication timeframes (start/end), and query filters to include/exclude unpublished records or fetch currently active publications.
Installation:
composer require willdurand/propel-publishable-behavior:dev-master
Add to propel.ini or build.properties:
propel.behavior.publishable.class = vendor.willdurand.propel-publishable-behavior.src.PublishableBehavior
Apply to a Model: Add the behavior to your schema XML:
<behavior name="publishable" />
Run php propel-build-model and php propel-build-all.
First Use Case: Check if a model is published:
$post = PostQuery::create()->findOne(1);
if ($post->isPublished()) {
// Render published content
}
Basic CRUD with Publish Status:
// Publish a post
$post->publish();
// Unpublish a post
$post->unpublish();
// Check status
if ($post->isPublished()) { ... }
Query Filtering:
// Get only published posts
$publishedPosts = PostQuery::create()->filterPublished()->find();
// Get unpublished posts
$unpublishedPosts = PostQuery::create()->filterUnpublished()->find();
// Include all posts (published or not)
$allPosts = PostQuery::create()->includeUnpublished()->find();
Publication Date Range Queries:
// Posts published within a date range
$posts = PostQuery::create()
->filterByPublicationActive('2023-01-01...2023-12-31')
->find();
Soft Deletes + Publishable: Combine with soft-delete behaviors for archiving unpublished content without hard deletion.
<behavior name="publishable" />
<behavior name="timestampable" />
API Endpoints: Use middleware to enforce publish status:
Route::get('/posts', function () {
return PostQuery::create()->filterPublished()->find();
})->middleware('check.publishable');
Admin Panels: Add a toggle UI for publish/unpublish actions in admin interfaces (e.g., Laravel Nova, Backpack).
Schema Migration:
published_at and unpublished_at columns automatically. Ensure your database schema matches Propel’s expectations.php propel-build-schema after adding the behavior to regenerate the schema.Null Handling:
unpublished_at defaults to NULL for published records. Avoid direct NULL comparisons in queries; use the provided methods (filterPublished()).Transaction Conflicts:
publish()/unpublish() methods accept a PropelPDO for explicit transactions. Omit to use the default connection.$con = Propel::getConnection();
$con->beginTransaction();
try {
$post->publish($con);
$con->commit();
} catch (\Exception $e) {
$con->rollBack();
}
Query Caching:
->find() (not ->findOne()) for consistent results with filterPublished().Column Mismatch:
If isPublished() returns unexpected results, verify the published_at/unpublished_at columns exist in the database.
DESCRIBE your_table;
Behavior Registration:
Ensure the propel.ini path is correct. Use absolute paths if relative paths fail:
propel.behavior.publishable.class = /full/path/to/vendor/willdurand/propel-publishable-behavior/src/PublishableBehavior
Custom Publication Logic:
Override isPublished() in your model for business-specific rules:
public function isPublished() {
if (!$this->getPublishedAt()) return false;
if ($this->getUnpublishedAt()) return false;
// Add custom logic (e.g., check approval status)
return $this->approved;
}
Bulk Operations: Use Propel’s batch operations for bulk publish/unpublish:
$posts = PostQuery::create()->find();
foreach ($posts as $post) {
$post->publish();
}
// Optimize with batch updates (advanced)
Event Hooks: Listen for publish/unpublish events via Propel’s event system (if extended):
Propel::getEventDispatcher()->addListener('post.publish', function ($event) {
// Log or notify
});
How can I help you explore Laravel packages today?