Perforce Chronicle 2012.2/486814
API Documentation
|
Manages category operations (e.g. More...
Public Member Functions | |
addAction () | |
Add a category. | |
deleteAction () | |
Remove a content category. | |
editAction (array $params=null) | |
Edit a content category. | |
indexAction () | |
List categories. | |
init () | |
Use management layout for all actions. | |
moveAction () | |
Move a category. | |
Public Attributes | |
$contexts | |
Protected Member Functions | |
_restoreCategoriesHierarchy (P4Cms_Model_Iterator $match, P4Cms_Model_Iterator $categories) | |
Restore categories hierarchy by appending ancestors to the items contained in match so as for any sub-category, all its ancestors are also present. | |
_sortCategoriesRecursively ($categories, $sortKey, $sortFlags, $parentId=null) | |
Sort the given list of categories recursively to preserve parent-child relationships. |
Manages category operations (e.g.
add).
Category_ManageController::_restoreCategoriesHierarchy | ( | P4Cms_Model_Iterator $ | match, |
P4Cms_Model_Iterator $ | categories | ||
) | [protected] |
Restore categories hierarchy by appending ancestors to the items contained in match so as for any sub-category, all its ancestors are also present.
Parent categories that do not match, but must be included, are refered as obligatory. In addition, these obligatory items will be added an extra 'obligatory' field so they can be recognized.
P4Cms_Model_Iterator | $match | list with categories to keep |
P4Cms_Model_Iterator | $categories | list with categories where ancestors will be taken from |
{ // compose list with categories to keep $keepIds = array(); foreach ($match as $category) { $keepIds = array_merge( $keepIds, array($category->getId()), $category->getAncestorIds() ); } // make keep list unique as there may be duplicates $keepIds = array_unique($keepIds); // filter categories to keep only selected items $categories->filter('id', $keepIds); // append and mark obligatory categories $obligatory = array_diff($keepIds, $match->invoke('getId')); foreach ($categories as $category) { if (in_array($category->getId(), $obligatory)) { $category->setValue('obligatory', true); $match->append($category); } } }
Category_ManageController::_sortCategoriesRecursively | ( | $ | categories, |
$ | sortKey, | ||
$ | sortFlags, | ||
$ | parentId = null |
||
) | [protected] |
Sort the given list of categories recursively to preserve parent-child relationships.
Example:
Assume there are 2 categories, A, B where A has 2 childs A/B, A/C. The output is an array iterator with categories in the following order:
P4Cms_Model_Iterator | $categories | list of all categories used for getting the children |
string | array | $sortKey | key to sort categories by |
array | $sortFlags | sorting options |
string | null | $parentId | optional - parent category of the generated list (null by default) |
{ // get categories with given parent and sort them $childs = $categories ->filterByCallback( function($category, $parentId) { return $category->getParentId() === $parentId; }, $parentId, array(P4_Model_Iterator::FILTER_COPY) ) ->sortBy($sortKey, $sortFlags); // assemble categories list and append sorted sub-categories below each category $sortedCategories = new P4Cms_Model_Iterator; foreach ($childs as $category) { $sortedCategories[] = $category; $sortedChilds = $this->_sortCategoriesRecursively( $categories, $sortKey, $sortFlags, $category->getId() ); foreach ($sortedChilds as $childCategory) { $sortedCategories[] = $childCategory; } } return $sortedCategories; }
Category_ManageController::addAction | ( | ) |
Add a category.
{ // enforce permissions. $this->acl->check('categories', 'add'); // set up view $view = $this->view; $request = $this->getRequest(); $view->shortForm = $request->getParam('short', false); $view->headTitle()->set('Add Category'); // set up form $form = new Category_Form_Manage; $view->form = $form; $form->setIdPrefix($request->getParam('formIdPrefix')); if ($request->isPost()) { // if a valid data were posted, try to add the category if ($form->isValid($request->getPost())) { // populate the form with posted data $form->populate($request->getPost()); // create new category with collected values and save it. // try to add a category with posted data; it may fail when // ancestors don't exist $category = new Category_Model_Category; try { $category->setValues($form->getValues()) ->setId($form->composeCategoryId()) ->save(); } catch (InvalidArgumentException $e) { // handle the category ancestry does not exist exception if ($e->getMessage() == 'Cannot create new category; category ancestry does not exist.') { $form->getElement('parent')->addError( "Cannot create new category; category ancestor '" . $category->getParentId() . "' does not exist." ); } else { // re-thrown other exceptions throw $e; } } } // re-check whether form is valid (i.e. doesn't contain any error messages) if ($form->getMessages()) { // form is invalid; set bad request response code // and assign error messages to the view $this->getResponse()->setHttpResponseCode(400); $view->errors = $form->getMessages(); return; } // if we reached this point, form is valid; // set notification message $view->message = "Category '{$category->getTitle()}' has been successfully added."; // for traditional requests, add notification message and redirect if (!$this->contextSwitch->getCurrentContext()) { // notify user and return to category list. P4Cms_Notifications::add( $view->message, P4Cms_Notifications::SEVERITY_SUCCESS ); $this->redirector->gotoUrl($request->getBaseUrl()); } // assign details about new category to the view $view->category = $category; } }
Category_ManageController::deleteAction | ( | ) |
Remove a content category.
{ // enforce permissions. $this->acl->check('categories', 'manage'); // require post request method. $request = $this->getRequest(); if (!$request->isPost()) { throw new P4Cms_AccessDeniedException( "Cannot delete category. Request method must be http post." ); } $id = $request->getParam('id', $request->getParam('category')); $category = Category_Model_Category::fetch($id); $category->delete(); $this->view->category = $category; }
Category_ManageController::editAction | ( | array $ | params = null | ) |
Edit a content category.
array | $params | The values to apply |
{ // enforce permissions. $this->acl->check('categories', 'manage'); // set up view $view = $this->view; $view->headTitle()->set('Edit Category'); // fetch the content category to be edited. $request = $this->getRequest(); $id = $request->getParam('category'); $category = Category_Model_Category::fetch($id); // setup form $form = new Category_Form_Manage; $view->form = $form; $values = array_merge( $category->getValues(), array( 'parent' => $category->getParentId() ) ); $form->populate($values); // disable unique title check $form->setUniqueTitleRequired(false); // remove the current category and it's children from parent options. $newOptions = array(); foreach ($form->getElement('parent')->getMultiOptions() as $key => $label) { if ($key === $id or strpos($key, "$id/") === 0) { continue; } $newOptions[$key] = $label; } $form->getElement('parent')->setMultiOptions($newOptions); if ($request->isPost()) { // if params is specified, we use them to override the existing values // else item values come from request if (isset($params)) { $values = array_merge($category->getValues(), $params); } else { $values = $request->getPost(); } // if a valid data were posted, try to update the category if ($form->isValid($values)) { // populate the form with posted data $form->populate($values); // start a batch in case we're moving $adapter = $category->getAdapter(); $adapter->beginBatch("Edit category $id"); // if the id has changed, move the category $newId = $form->composeCategoryId(); if ($id !== $newId) { try { Category_Model_Category::move($id, $newId); } catch (InvalidArgumentException $e) { $form->getElement('parent')->addError($e->getMessage()); } } // set form values on category, and save it try { $category->setValues($form->getValues()) ->setId($newId) ->save(); } catch (InvalidArgumentException $e) { // handle the category ancestry does not exist exception if ($e->getMessage() == 'Cannot create new category; category ancestry does not exist.') { $form->getElement('parent')->addError( "Cannot create new category; category ancestor '" . $category->getParentId() . "' does not exist." ); } // re-throw other exceptions throw $e; } } // re-check whether form is valid (i.e. doesn't contain any error messages) if ($form->getMessages()) { // form is invalid; revert batch, set bad request response code // and assign error messages to the view $this->getResponse()->setHttpResponseCode(400); $view->errors = $form->getMessages(); if (isset($adapter)) { $adapter->revertBatch(); } return; } // at this point, form is valid; // attempt to commit the batch - cleanup on failure. try { $adapter->commitBatch(); } catch (Exception $e) { $adapter->revertBatch(); throw $e; } // set notification message $view->message = "Category '{$category->getTitle()}' has been updated."; // for traditional requests, add notification message and redirect if (!$this->contextSwitch->getCurrentContext()) { P4Cms_Notifications::add( $view->message, P4Cms_Notifications::SEVERITY_SUCCESS ); $this->redirector->gotoSimple('index'); } } }
Category_ManageController::indexAction | ( | ) |
List categories.
p4cms.category.grid.actions Modify the passed menu (add/modify/delete items) to influence the actions shown on entries in the Manage Categories grid. P4Cms_Navigation $actions A menu to hold grid actions.
p4cms.category.grid.data.item Return the passed item after applying any modifications (add properties, change values, etc.) to influence the row values sent to the Manage Categories grid. array $item The item to potentially modify. mixed $model The original object/array that was used to make the item. Ui_View_Helper_DataGrid $helper The view helper that broadcast this topic.
p4cms.category.grid.data Adjust the passed data (add properties, modify values, etc.) to influence the row values sent to the Manage Categories grid. Zend_Dojo_Data $data The data to be filtered. Ui_View_Helper_DataGrid $helper The view helper that broadcast this topic.
p4cms.category.grid.populate Adjust the passed iterator (possibly based on values in the passed form) to filter which categories will be shown on the Manage Categories grid. P4Cms_Model_Iterator $items An iterator of Category_Model_Category objects. P4Cms_Form_PubSubForm $form A form containing filter options.
p4cms.category.grid.render Make adjustments to the datagrid helper's options pre-render (e.g. change options to add columns) for the Manage Categories grid. Ui_View_Helper_DataGrid $helper The view helper that broadcast this topic.
p4cms.category.grid.form Make arbitrary modifications to the Manage Categories filters form. P4Cms_Form_PubSubForm $form The form that published this event.
p4cms.category.grid.form.subForms Return a Form (or array of Forms) to have them added to the Manage Categories filters form. The returned form(s) should have a 'name' set on them to allow them to be uniquely identified. P4Cms_Form_PubSubForm $form The form that published this event.
p4cms.category.grid.form.preValidate Allows subscribers to adjust the Manage Categories filters form prior to validation of the passed data. For example, modify element values based on related selections to permit proper validation. P4Cms_Form_PubSubForm $form The form that published this event. array $values An associative array of form values.
p4cms.category.grid.form.validate Return false to indicate the Manage Categories filters form is invalid. Return true to indicate your custom checks were satisfied, so form validity should be unchanged. P4Cms_Form_PubSubForm $form The form that published this event. array $values An associative array of form values.
p4cms.category.grid.form.populate Allows subscribers to adjust the Manage Categories filters form after it has been populated with the passed data. P4Cms_Form_PubSubForm $form The form that published this event. array $values The values passed to the populate method.
{ // enforce permissions. $this->acl->check('categories', 'manage'); // setup list options form $request = $this->getRequest(); $gridNamespace = 'p4cms.category.grid'; $form = new Ui_Form_GridOptions( array( 'namespace' => $gridNamespace ) ); $form->populate($request->getParams()); // set up view $view = $this->view; $view->form = $form; $view->pageSize = $request->getParam('count', 100); $view->rowOffset = $request->getParam('start', 0); $view->pageOffset = round($view->rowOffset / $view->pageSize, 0) + 1; $view->showAddLink = $this->acl->isAllowed('categories', 'add'); $view->headTitle()->set('Manage Categories'); // set DataGrid view helper namespace $helper = $view->dataGrid(); $helper->setNamespace($gridNamespace); // collect the actions from interested parties $actions = new P4Cms_Navigation; P4Cms_PubSub::publish($gridNamespace . '.actions', $actions); $view->actions = $actions; // early exit for standard requests (ie. not json) if (!$this->contextSwitch->getCurrentContext()) { $this->getHelper('helpUrl')->setUrl('navigation.category.overview.html'); return; } // fetch categories and make a copy for later use $categories = Category_Model_Category::fetchAll(); $copy = new P4Cms_Model_Iterator($categories->getArrayCopy()); // allow third-parties to influence list try { P4Cms_PubSub::publish($gridNamespace . '.populate', $categories, $form); } catch (Exception $e) { P4Cms_Log::logException("Error building categories list.", $e); } // restore categories hierarchy by appending ancestors to the // filtered categories $this->_restoreCategoriesHierarchy($categories, $copy); // prepare sorting options $sortKey = $request->getParam('sort', 'title'); $sortFlags = array( P4Cms_Model_Iterator::SORT_NATURAL, P4Cms_Model_Iterator::SORT_NO_CASE ); if (substr($sortKey, 0, 1) == '-') { $sortKey = substr($sortKey, 1); $sortFlags[] = P4Cms_Model_Iterator::SORT_DESCENDING; } else { $sortFlags[] = P4Cms_Model_Iterator::SORT_ASCENDING; } // compose list of sorted categories $view->categories = $this->_sortCategoriesRecursively($categories, $sortKey, $sortFlags); }
Category_ManageController::init | ( | ) |
Use management layout for all actions.
{ $this->getHelper('layout')->setLayout('manage-layout'); }
Category_ManageController::moveAction | ( | ) |
Move a category.
{ // enforce permissions. $this->acl->check('categories', 'manage'); $request = $this->getRequest(); $values = array("parent" => $request->getParam('parent')); $this->editAction($values); }
Category_ManageController::$contexts |
array( 'add' => array('partial' => 'get', 'json' => 'post'), 'edit' => array('partial' => 'get', 'json' => 'post'), 'delete' => array('partial' => 'get', 'json' => 'post'), 'index' => array('json'), 'move' => array('json' => 'post') )