5.2.16 RecommendationsTable Policy Reference
Last Updated: December 4, 2025
Status: Complete
Plugin: Awards
Source: plugins/Awards/src/Policy/RecommendationsTablePolicy.php
Overview
The RecommendationsTablePolicy class provides table-level authorization for recommendation workflow management within the Awards plugin. It implements sophisticated query scoping based on user approval authority and organizational scope.
Class Definition
namespace Awards\Policy;
class RecommendationsTablePolicy extends BasePolicy
RBAC Integration Architecture
Permission-Based Authorization
- Delegation Pattern: Authorization decisions delegated to
BasePolicy._hasPolicy() - Approval Level Discovery: Analyzes user permissions to identify approval authority
- Dynamic Filtering: Restricts recommendations to user’s approval levels
- Open Submission: Public recommendation creation support
BasePolicy Inheritance
The policy inherits standard table authorization methods and adds custom logic:
| Method | Purpose |
|---|---|
canIndex() |
Recommendation listing (inherited) |
scopeIndex() |
Custom query scoping with approval level filtering |
canAdd() |
Open recommendation submission |
canExport() |
CSV export authorization |
Custom Authorization Methods
scopeIndex()
Implements sophisticated recommendation filtering based on user approval authority.
public function scopeIndex(KmpIdentityInterface $user, $query)
Parameters:
$user- The user requesting data access$query- The base query to scope
Returns: Scoped query with authorization filtering
Scoping Process:
- Discovers branch access through
_getBranchIdsForPolicy() - Analyzes user policies to identify approval authority levels
- Extracts approval levels from
canApproveLevel*permission methods - Checks for global access sentinel (
branchIds[0] == -10000000bypasses branch scoping) - Applies branch scoping through
addBranchScopeQuery()for non-global users - Filters recommendations by award levels user can approve using
matching()
Example Query Transformation:
// Before scoping: All recommendations
$query = $this->Recommendations->find();
// After scoping: Branch-scoped + approval level filtered
$query = $table->addBranchScopeQuery($query, $branchIds);
$query = $query->matching('Awards.Levels', function ($q) use ($approvalLevels) {
return $q->where(['Levels.name IN' => $approvalLevels]);
});
Global Access Sentinel:
When _getBranchIdsForPolicy() returns a branch ID of -10000000 as the first element, it indicates the user has global access (e.g., super-user or kingdom-level permission). In this case, branch scoping is skipped entirely, and the user sees recommendations across all branches.
canAdd()
Provides open access for recommendation submission.
public function canAdd(KmpIdentityInterface $user, BaseEntity|Table $entity, ...$optionalArgs): bool
Returns: Always true - recommendation submission is open to all authenticated users.
Purpose: Enables public recommendation submission workflows while maintaining security through entity-level policies.
canExport()
Authorizes recommendation export to CSV.
public function canExport(KmpIdentityInterface $user, BaseEntity|Table $entity, ...$optionalArgs): bool
Returns: true if user has index permission
Purpose: Users who can list recommendations can also export them.
Authorization Flow
Query Scoping Flow
sequenceDiagram
participant Controller
participant Authorization
participant RecsTablePolicy
participant User
participant RecommendationPolicy
Controller->>Authorization: applyScope($query, 'index')
Authorization->>RecsTablePolicy: scopeIndex($user, $query)
RecsTablePolicy->>User: getPolicies($branchIds)
User-->>RecsTablePolicy: Branch Policies
RecsTablePolicy->>RecsTablePolicy: Extract canApproveLevel* methods
RecsTablePolicy->>RecsTablePolicy: Apply branch scoping
RecsTablePolicy->>RecsTablePolicy: Filter by approval levels
RecsTablePolicy-->>Authorization: Scoped Query
Authorization-->>Controller: Filtered Results
Approval Level Discovery
The policy discovers approval levels by analyzing user policies:
// User policies structure
$branchPolicies = [
"Awards\Policy\RecommendationPolicy" => [
"canApproveLevelAoA" => true,
"canApproveLevelGoA" => true,
// ... other methods
]
];
// Extracted approval levels
$approvalLevels = ['AoA', 'GoA'];
Usage Examples
Controller Integration
// Recommendation listing with automatic scoping
public function index() {
$this->Authorization->authorize($this->Recommendations, 'index');
// Query is automatically scoped by scopeIndex()
$query = $this->Recommendations->find()
->contain(['Awards', 'Members', 'Events']);
$scopedQuery = $this->Authorization->applyScope($query, 'index');
$recommendations = $this->paginate($scopedQuery);
$this->set(compact('recommendations'));
}
Workflow Management
// Service-level query scoping
$query = $this->Recommendations->find()
->contain(['Awards.Levels', 'Events', 'Members'])
->where(['state' => 'submitted']);
$authorizedQuery = $this->Authorization->applyScope($user, 'index', $query);
// Only returns recommendations at levels user can approve
Export Authorization
// CSV export
public function exportCsv() {
if ($this->Authorization->can($this->Recommendations, 'export')) {
$query = $this->Authorization->applyScope(
$this->Recommendations->find(),
'index'
);
// Export scoped data...
}
}
Open Submission
// Any authenticated user can submit
public function add() {
$this->Authorization->authorize($this->Recommendations, 'add');
// Always authorized - validation happens at entity level
$recommendation = $this->Recommendations->newEntity($this->request->getData());
$this->Recommendations->save($recommendation);
}
Integration Points
Recommendations Controller Integration
- Index Action: Automatic query scoping with approval level filtering
- Add Action: Open submission for community participation
- Export Action: CSV export with same scoping as index
- Workflow Operations: Scoped queries support workflow management
RBAC System Integration
- Permission Framework: Integration through BasePolicy inheritance
- Dynamic Permissions: Approval level discovery from policy methods
- Branch Scoping: Organizational access through branch filtering
Awards Plugin Integration
- Level Integration: Filters by award levels user can approve
- State Machine: Supports recommendation workflow management
- Entity Policy: Coordinates with RecommendationPolicy for entity-level authorization
Security Considerations
Access Control Security
- Authentication Required: All operations require authenticated identity
- Approval Authority: Users see only recommendations they can approve
- Branch Scoping: Organizational access through branch filtering
- Open Submission: Entity-level policies provide detailed authorization
Data Protection
- Query Filtering: Automatic filtering to authorized recommendations
- Level-Based Access: Recommendations filtered by approval authority
- Export Security: Export follows same authorization as viewing