Having read many of Matthew Weier O'Phinney's posts regarding implementing ACL into Models, I have been focused on the best way to go about doing this. However, upon further research on best practices with Domain Objects, I understand that these models should not contain any reference to Data Mappers, or any CRUD operation.
Take for example ERM software which maintains inventory and handles shipments to/from companies based on sale and purchase orders. I imagine having a few domains...
- Company
- Shipment
- Order
- Product
- Assembly
- And a few others
Since Companies can have different Types (e.g. Manufacturer, Supplier, Retailer), this information is stored in numerous tables across my database (e.g. companies, types, company_types). Thus, I have a Data Mapper for my Company Domain which uses objects for the Zend_Db_Table instances of each database table.
In my Controller actions, I understand that there should be very little logic. For instance, creating a new Company may go something like this...
public function createAction()
{
// Receive JSON request from front end
$data = Zend_Json::decode($request);
$companyObj = new App_Model_Company();
$companyObj->populate($data);
$companyMapper = new App_Model_DataMapper_Company();
$companyMapper->save($companyObj);
}
With this in mind, I feel that it is best to incorporate my ACL checks into the DataMapper and Validation into the Domain Object. My Domain objects all extend off a base abstract class, which overloads PHP's magic __set
and __get
methods. In the constructor of each Domain Object, I define the properties of the object by populating a $_properties
array with keys. This way, my __set
method looks something like...
public function __set($property, $value)
{
$className = __CLASS__;
if(!array_key_exists($property, $this->_properties))
{
throw new Zend_Exception("Class [ $className ] has no property [ $property ]");
}
// @return Zend_Form
$validator = $this->getValidator();
/*
* Validate provided $value against Zend_Form element $property
*/
$this->properties[$property] = $value;
}
}
All my Data Mapper's save()
methods typehint App_Model_DomainObjectAbstract $obj
.
Question #1 - Since my Data Mapper will handle all CRUD actions, and the Domain object should really just contain properties specific to that domain, I feel like ACL checks belong in the Data Mapper - is this acceptable?
I was trying to avoid instantiating Data Mapper's in my Controllers, but this seems irrational now that I think I have a better understanding of this design pattern.
Question #2 - Am I over complicating this process, and should I instead write an ACL Plugin that extends Zend_Controller_Plugin_Abstract
and handles ACL based on incoming requests in the preDispatch()
method?
Thank you very much for your time!