What is considered the correct place for my pagination to live when using a service/datamapper/domain object trio?
Example:
- Fetch ports with a few given criteria
- Paginate the results
- Know what page we are on, number of pages in total, number of results etc.. from the view class
The below is just something I wrote here and now, but it is similar to my application.
class PostController extends Controller
{
function viewPosts()
{
return $this->serviceFactory
->build('post')
->getPosts($aCriteria, $this->request->_get('page'), 10);
}
}
I am currently both calculating and storing pagination parameters in each service. Note that I am not pushing any data to the view from my controller.
class PostService extends AbstractService
{
public $posts;
public $iTotalPages; // This does not belong here does it?
function getPosts($aCriteria, $iPage, $iItemsPerPage)
{
$mapper = $this->dataMapperFactory->build('post');
// I do not know where to put the below
// (The parameters and the code itself)
$iCount = $mapper->count($aCriteria);
$iOffset = $iItemsPerPage * $iPage;
$this->iTotalPages = $iCount / $iItemsPerPage;
$this->posts = $mapper->find($aCriteria, $iOffset, $iOffset + $iItemsPerPage);
return $this->posts;
}
}
My views have access to the same instance of the Model layer as my controller, so I could call $service->iTotalPages
from the view, but that feels wrong.
class PostsView extends AbstractView
{
function viewPosts()
{
$service = $this->serviceFactory->build('post');
if(count($service->posts)>0) {
$this->template->assign_var('TOTAL_PAGES', $service->iTotalPages);
$this->template->assign_vars('POSTS', $service->posts);
}
}
}
Solutions?
1) Create a service for pagination and have the controller exchange data with the post service as required?
2) Create a helper class for pagination that each service can include? (How would such a class look like?)
3) Add generic pagination to the AbstractService?
4) Add some sort of pagination support to my Repos?