之前创建了骨架目录并且激活了新模块,现在要为模块创建前台和后台的控制器。
1. 首先在app/code/local/Voodoo/News/controllers/ 中创建一个名为IndexController.php的前端控制器:
class Voodoo_News_IndexController extends Mage_Core_Controller_Front_Action{
public function indexAction()
{
$resource = Mage::getSingleton('core/resource');
$read = $resource->getConnection('core_read');
$newsTable = $resource->getTableName('news');
$select = $read->select()->from($newsTable, array('news_id', 'title', 'filename','content', 'status'))->where('status', 1)->order('created_time DESC');
$news = $read->fetchAll($select);
Mage::register('list', $news);
$this->loadLayout();
$this->renderLayout();
}
public function viewAction()
{
$news_id = $this->getRequest()->getParam('id');
if ($news_id != null && $news_id != '') {
$news = Mage::getModel('news/news')->load($news_id)->getData();
} else {
$news = null;
}
/**
* If no param we load a the last created item
*/
if ($news == null) {
$resource = Mage::getSingleton('core/resource');
$read = $resource->getConnection('core_read');
$newsTable = $resource->getTableName('news');
$select = $read->select()->from($newsTable, array('news_id', 'filename', 'title','content', 'status', 'update_time'))->where('status', 1)->order('created_time DESC');
$news = $read->fetchRow($select);
}
Mage::register('news', $news);
$this->loadLayout();
$this->renderLayout();
}
}
这个controller是前端控制器,主要负责加载和显示文章列表和内容,index 控制器负责现实文章列表,当用户点击指定文章时,跳转到view动作,显示指定文章的详细信息,magento中访问数据库需要创建一个core_resource对象,这个对象可以用来执行sql语句。
接下来创建一个后台控制器NewsController.php,放在app/code/local/Voodoo/News/controllers/Adminhtml/目录下:
class Voodoo_News_Adminhtml_NewsController extends Mage_Adminhtml_Controller_action
{
protected function _initAction()
{
$this->loadLayout()->_setActiveMenu('news/items')->_addBreadcrumb(Mage::helper('adminhtml')->__('Items Manager'), Mage::helper('adminhtml')->__('Item Manager'));
return $this;
}
public function indexAction()
{
$this->_initAction();
$this->_addContent($this->getLayout()->createBlock('news/adminhtml_news'));
$this->renderLayout();
}
public function editAction()
{
$id = $this->getRequest()->getParam('id');
$model = Mage::getModel('news/news')->load($id);
if ($model->getId() || $id == 0) {
$data = Mage::getSingleton('adminhtml/session')->getFormData(true);
if (!empty($data)) {
$model->setData($data);
}
Mage::register('news_data', $model);
$this->loadLayout();
$this->_setActiveMenu('news/items');
$this->_addBreadcrumb(Mage::helper('adminhtml')->__('Item Manager'), Mage::helper('adminhtml')->__('News Item Manager'));
$this->_addBreadcrumb(Mage::helper('adminhtml')->__('Item News'), Mage::helper('adminhtml')->__('Item News'));
$this->getLayout()->getBlock('head')->setCanLoadExtJs(true);
$this->_addContent($this->getLayout()->createBlock('news/adminhtml_news_edit'))->_addLeft($this->getLayout()->createBlock('news/adminhtml_news_edit_tabs'));
$this->renderLayout();
} else {
Mage::getSingleton('adminhtml/session')->addError(Mage::helper('news')->__('Item does not exist'));
$this->_redirect('*/*/');
}
}
public function newAction()
{
$this->_forward('edit');
}
public function saveAction()
{
if ($data = $this->getRequest()->getPost()) {
if (isset($_FILES['filename']['name']) && $_FILES['filename']['name'] != '') {
try {
/* Starting upload */
$uploader = new Varien_File_Uploader('filename');
// Any extention would work
$uploader->setAllowedExtensions(array('jpg', 'jpeg','gif', 'png'));
$uploader->setAllowRenameFiles(false);
$uploader->setFilesDispersion(false);
// We set media as the upload dir
$path = Mage::getBaseDir('media') . DS . 'news' . DS;
$uploader->save($path, $_FILES['filename']['name']);
} catch (Exception $e) {
}
//this way the name is saved in DB
$data['filename'] = $_FILES['filename']['name'];
}
$model = Mage::getModel('news/news');
$model->setData($data)->setId($this->getRequest()->getParam('id'));
try {
if ($model->getCreatedTime == NULL || $model->getUpdateTime() == NULL) {
$model->setCreatedTime(now())->setUpdateTime(now());
} else {
$model->setUpdateTime(now());
}
$model->save();
Mage::getSingleton('adminhtml/session')->addSuccess(Mage::helper('news')->__('Item was successfully saved'));
Mage::getSingleton('adminhtml/session')->setFormData(false);
if ($this->getRequest()->getParam('back')) {
$this->_redirect('*/*/edit', array('id' => $model->getId()));
return;
}
$this->_redirect('*/*/');
return;
} catch (Exception $e) {
Mage::getSingleton('adminhtml/session')->addError($e->getMessage());
Mage::getSingleton('adminhtml/session')->setFormData($data);
$this->_redirect('*/*/edit', array('id' => $this->getRequest()->getParam('id')));
return;
}
}
Mage::getSingleton('adminhtml/session')->addError(Mage::helper('news')->__('Unable to find item to save'));
$this->_redirect('*/*/');
}
public function deleteAction(){
if ($this->getRequest()->getParam('id') > 0) {
try {
$model = Mage::getModel('news/news');
$model->setId($this->getRequest()->getParam('id'))->delete();
Mage::getSingleton('adminhtml/session')->addSuccess(Mage::helper('adminhtml')->__('Item was successfully deleted'));
$this->_redirect('*/*/');
} catch (Exception $e) {
Mage::getSingleton('adminhtml/session')->addError($e->getMessage());
$this->_redirect('*/*/edit', array('id' => $this->getRequest()->getParam('id')));
}
}
$this->_redirect('*/*/');
}
public function massDeleteAction(){
$newsIds = $this->getRequest()->getParam('news');
if (!is_array($newsIds)) {
Mage::getSingleton('adminhtml/session')->addError(Mage::helper('adminhtml')->__('Please select item(s)'));
} else {
try {
foreach ($newsIds as $newsId) {
$news = Mage::getModel('news/news')->load($newsId);
$news->delete();
}
Mage::getSingleton('adminhtml/session')->addSuccess(Mage::helper('adminhtml')->__('Total of %d record(s) were successfully deleted',count($newsIds)));
} catch (Exception $e) {
Mage::getSingleton('adminhtml/session')->addError($e->getMessage());
}
}
$this->_redirect('*/*/index');
}
public function massStatusAction(){
$newsIds = $this->getRequest()->getParam('news');
if (!is_array($newsIds)) {
Mage::getSingleton('adminhtml/session')->addError($this->__('Please select item(s)'));
} else {
try {
foreach ($newsIds as $newsId) {
$news = Mage::getSingleton('news/news')->load($newsId)->setStatus($this->getRequest()->getParam('status'))->setIsMassupdate(true)->save();
}
$this->_getSession()->addSuccess($this->__('Total of %d record(s) were successfully updated', count($newsIds)));
} catch (Exception $e) {
$this->_getSession()->addError($e->getMessage());
}
}
$this->_redirect('*/*/index');
}
public function exportCsvAction()
{
$fileName = 'news.csv';
$content = $this->getLayout()->createBlock('news/adminhtml')->getCsv();
$this->_sendUploadResponse($fileName, $content);
}
public function exportXmlAction()
{
$fileName = 'news.xml';
$content = $this->getLayout()->createBlock('news/adminhtml_news_grid')->getXml();
$this->_sendUploadResponse($fileName, $content);
}
protected function _sendUploadResponse($fileName, $content,$contentType='application/octet-stream')
{
$response = $this->getResponse();
$response->setHeader('HTTP/1.1 200 OK', '');
$response->setHeader('Pragma', 'public', true);
$response->setHeader('Cache-Control', 'must-revalidate, postcheck=0, pre-check=0', true);
$response->setHeader('Content-Disposition', 'attachment;filename=' . $fileName);
$response->setHeader('Last-Modified', date('r'));
$response->setHeader('Accept-Ranges', 'bytes');
$response->setHeader('Content-Length', strlen($content));
$response->setHeader('Content-type', $contentType);
$response->setBody($content);
$response->sendResponse();
die;
}
}
这个控制器主要负责后台的一些动作,比如增删查改。在_initAction()里面,我们做了三件事:加载布局,在后台设置活动菜单,

,还有添加面包屑的文本
Index action则创建一个news/adminhtml_news block和加载对应布局。其他action则不一一熬述。
调用edit操作时,用户点击编辑链接在新闻列表下新闻项目管理一节。相关新闻的编号是从ID参数和传递的消息模型中抓取,以获取具体的新闻。如果给定的新闻I产生的结果,它传递的新闻形式的数据来填充与形式给定的数据。新闻编辑表单提交后,数据的saveaction传递与更新的消息ID。还有一些其他的任务,已
实现这个方法,如装载布局,建立活动的菜单,加入面包屑的文本等等。
newAction()用于跳转到edit动作
saveActon()则用于与模型层交互,保存输入的信息
deleteAction()用于删除指定的文章
massDeleteAction()则是批量删除
massStatusAction()为批量状态修改
exportCsvAction()用于到处cvs文件
exportXmlAction()则用于导入xml文件
_sendUploadResponse则是当导出xml文件时设置http报头
Magento的控制器其实和zend framework的控制器工作原理一样,控制器必须在MVC模式下工作,它操纵模型,决定哪些视图来显示用户的要求和其他因素的基础上传递数据,查看每个用户响应,或完全关闭控制并跳转到另一个控制器。他总是保持一个控制器尽量瘦小,业务逻辑则尽量交给model来处理,skinny controller and fat model !