Workflows

Improvements?

Let us know by posting here.

Attach workflows to permissions to require user or group approval before completing actions. Concrete includes single-step workflows, with multi-step workflows available as an enterprise add-on.

Workflows extend the permissions model, allowing any permission to be workflow-enabled. Actions can be queued as workflow requests.

Add Workflow to Custom Permission Key

To enable workflow on a custom permission key, modify the relevant install() method in your package controller. For instance, when adding a permission key for deleting a product:

$permission = Key::getByHandle('delete_product');
if (!is_object($permission)) {
    $view = Key::add('product', 'delete_product', 'Delete Product', '', false, false, $pkg);
}

Change the first false in Key::add to true:

$permission = Key::getByHandle('delete_product');
if (!is_object($permission)) {
    $view = Key::add('product', 'delete_product', 'Delete Product', '', true, false, $pkg);
}

This enables the workflow tab in the custom permission. You can now assign workflows to the "Delete Product" permission, visible when editing its access entities.

After attaching a workflow, update the delete action to incorporate it. Continue reading for further details.

Creating Custom Workflow Requests

To enable workflow for a permission, modify the related code to use a workflow request. Consider this example of code handling product deletion:

$p = Product::getByID($productID);
$pp = new Permissions($p);
if ($pp->canDeleteProduct()) {
    $p->delete();
}

This code checks the "delete_product" permission and, if granted, deletes the product. To make this workflowable, replace $p->delete() with a workflow request.

Workflow allows permissions to be protected by another level. For instance, Administrators can approve deletion, while Editors can initiate it. For this, assign full access to the "Delete Product" permission to Editors and give Administrators approval rights in the "Standard Workflow".

To implement this, create a "Delete Product" workflow request class in your package. This class, Concrete\Package\SuperStore\Workflow\Request\DeleteProductRequest, handles the workflow request details:

<?php
namespace Concrete\Package\SuperStore\Workflow\Request;
//... (other use statements)
class DeleteProductRequest extends Request
{
    protected $productID;
    // Constructor and other methods...

    public function approve(WorkflowProgress $wp)
    {
        $p = Product::getByID($this->productID);
        $p->delete();
        $wpr = new WorkflowProgressResponse();
        $wpr->setWorkflowProgressResponseURL(\URL::to('/dashboard/super_store/products'));
        return $wpr;
    }
    //... (other methods)
}

Replace the original code with one calling the workflow response:

$p = Product::getByID($productID);
$pp = new Permissions($p);
if ($pp->canDeleteProduct()) {
    $u = new User();
    $pkr = new DeleteProductWorkflowPrequest();
    $pkr->setRequestedProduct($p);
    $pkr->setRequesterUserID($u->getUserID());
    $response = $pkr->trigger();
    // Handle response
}

With this change, the "Delete Product" permission becomes workflowable.