您的位置:首页 > 编程语言 > PHP开发

Seagull PHP框架学习教程之模块生成器

2008-12-14 18:19 288 查看
如果你是一个熟练的PHP程序员,你完全可以跳过前面两节你已经非常熟悉的基本概念,直接try一下Seagull的module generator(模块生成器),当你安装完Seagull之后,你可以使用你在安装时设定的管理员账户登陆。当你成功登陆后会直接进入admin
GUI,选择单击左侧导航栏的“Module generator”即可进入Seagull的模块生成器,截屏如下:



事实上,Seagull框架下开发项目,你也就是程序员所需要做的工作仅仅是为Seagull开发一个个模块。而使用模块生成器,你可以很容易的生成一个Seagull模块所需要的文件目录结构,也就是上一节所提到的Seagull下一个模块所包含的那些文件。

我们看一下上面截屏中的各个选项:
“Module Name” 为所要创建的模块指定一个名称
“Manager Name” 指定一个名称来创建一个manager类
“Add following methods” 为这上面创建的manager类创建哪些method,选择你想要在这个manager 类中使用的方法
“Create CRUD Action” 如果上面所创建的manger类的各个action(也就是manager类的method)是对数据库的某个表进行操作时可以选择,这样Seagull会执行SGL_Task_CreateDataObjectEntities类,重新生成数据库所有表的DataObject类。
“Create Templates” 选中以创建默认的模板
“Create languages files” 是否要创建语言文件
“Create ini file” 是否要创建模块配置文件

注意事项:
当选中“Create CRUD Action”复选框时,如果数据库中没有和manager类名一样的表格时,Seagull会抛出如下错误:
Please generate a table (with the same name as your manager entity, eg, "pizza") in the database first.

如果Seagull是运行在linux类服务器上,还有可能出现权限不够的错误。由于module generator会在seagull的modules目录下生成模块所需要的一系列相关文件,所以web服务器(也就是运行web服务器的用户)需要对该目录拥有写的权限。否则seagull会抛出下列错误:
Please give the webserver write permissions to the modules directory

如果你所创建的模块已经存在,那么module generator将只会在指定的模块内创建一个指定的manager类,但是如果该模块内已经存在同名的managaer类,则Seagull会抛出如下错误:
Manager already exists - please choose another manager name

我用module generator创建了一个book模块,下面是module generator生成的book模块的文件目录截屏:



其中BookMgr.php就是我们所创建的这个book模块目前唯一的manager类:
<?php
/* Reminder: always indent with 4 spaces (no tabs). */
// +---------------------------------------------------------------------------+
// | Copyright (c) 2008, Demian Turner |
// | All rights reserved. |
// | |
// | Redistribution and use in source and binary forms, with or without |
// | modification, are permitted provided that the following conditions |
// | are met: |
// | |
// | o Redistributions of source code must retain the above copyright |
// | notice, this list of conditions and the following disclaimer. |
// | o Redistributions in binary form must reproduce the above copyright |
// | notice, this list of conditions and the following disclaimer in the |
// | documentation and/or other materials provided with the distribution. |
// | o The names of the authors may not be used to endorse or promote |
// | products derived from this software without specific prior written |
// | permission. |
// | |
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
// | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
// | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
// | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
// | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
// | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
// | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
// | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
// | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
// | |
// +---------------------------------------------------------------------------+
// | Seagull 0.6 |
// +---------------------------------------------------------------------------+
// | bookMgr.php |
// +---------------------------------------------------------------------------+
// | Author: George Zheng <xinhaozheng@gmail.com> |
// +---------------------------------------------------------------------------+
// $Id: ManagerTemplate.html,v 1.2 2005/04/17 02:15:02 demian Exp $

require_once 'DB/DataObject.php';
/**
* Type your class description here ...
*
* @package book
* @author George Zheng <xinhaozheng@gmail.com>
*/
class BookMgr extends SGL_Manager
{
function BookMgr()
{
SGL::logMessage(null, PEAR_LOG_DEBUG);
parent::SGL_Manager();

$this->pageTitle = 'Book Manager';
$this->template = 'bookList.html';

$this->_aActionsMapping = array(
'add' => array('add'),
'insert' => array('insert', 'redirectToDefault'),
'edit' => array('edit'),
'update' => array('update', 'redirectToDefault'),
'list' => array('list'),
'delete' => array('delete', 'redirectToDefault'),
);
}

function validate($req, &$input)
{
SGL::logMessage(null, PEAR_LOG_DEBUG);
$this->validated = true;
$input->error = array();
$input->pageTitle = $this->pageTitle;
$input->masterTemplate = $this->masterTemplate;
$input->template = $this->template;
$input->action = ($req->get('action')) ? $req->get('action') : 'list';
$input->aDelete = $req->get('frmDelete');
$input->submitted = $req->get('submitted');
$input->book = (object)$req->get('book');
$input->bookId = $req->get('frmBookID');

// if errors have occured
if (isset($aErrors) && count($aErrors)) {
SGL::raiseMsg('Please fill in the indicated fields');
$input->error = $aErrors;
$this->validated = false;
}
}

function display(&$output)
{
if ($this->conf['BookMgr']['showUntranslated'] == false) {
$c = &SGL_Config::singleton();
$c->set('debug', array('showUntranslated' => false));
}
}

function _cmd_add(&$input, &$output)
{
SGL::logMessage(null, PEAR_LOG_DEBUG);
$output->template = 'bookEdit.html';
$output->pageTitle = 'BookMgr :: Add';
$output->action = 'insert';
$output->wysiwyg = true;

}

function _cmd_insert(&$input, &$output)
{
SGL::logMessage(null, PEAR_LOG_DEBUG);
$book = DB_DataObject::factory($this->conf['table']['book']);
$book->setFrom($input->book);
$book->book_id = $this->dbh->nextId($this->conf['table']['book']);
$success = $book->insert();

if ($success !== false) {
SGL::raiseMsg('book insert successfull', false, SGL_MESSAGE_INFO);
} else {
SGL::raiseError('book insert NOT successfull',
SGL_ERROR_NOAFFECTEDROWS);
}
}

function _cmd_edit(&$input, &$output)
{
SGL::logMessage(null, PEAR_LOG_DEBUG);
$output->template = 'bookEdit.html';
$output->pageTitle = 'BookMgr :: Edit';
$output->action = 'update';
$output->wysiwyg = true;

$book = DB_DataObject::factory($this->conf['table']['book']);
$book->get($input->bookId);
$output->book = $book;

}

function _cmd_update(&$input, &$output)
{
SGL::logMessage(null, PEAR_LOG_DEBUG);
$book = DB_DataObject::factory($this->conf['table']['book']);
$book->book_id = $input->bookId;
$book->find(true);
$book->setFrom($input->book);
$success = $book->update();

if ($success !== false) {
SGL::raiseMsg('book update successfull', false, SGL_MESSAGE_INFO);
} else {
SGL::raiseError('book update NOT successfull',
SGL_ERROR_NOAFFECTEDROWS);
}

}

function _cmd_list(&$input, &$output)
{
SGL::logMessage(null, PEAR_LOG_DEBUG);
$output->template = 'bookList.html';
$output->pageTitle = 'BookMgr :: List';

// only execute if CRUD option selected
if (false) {
$query = " SELECT
0, 1
FROM {$this->conf['table']['book']}
";

$limit = $_SESSION['aPrefs']['resPerPage'];
$pagerOptions = array(
'mode' => 'Sliding',
'delta' => 3,
'perPage' => $limit,
);
$aPagedData = SGL_DB::getPagedData($this->dbh, $query, $pagerOptions);
if (PEAR::isError($aPagedData)) {
return false;
}
$output->aPagedData = $aPagedData;
$output->totalItems = $aPagedData['totalItems'];

if (is_array($aPagedData['data']) && count($aPagedData['data'])) {
$output->pager = ($aPagedData['totalItems'] <= $limit) ? false : true;
}
}
}

function _cmd_delete(&$input, &$output)
{
SGL::logMessage(null, PEAR_LOG_DEBUG);
if (is_array($input->aDelete)) {
foreach ($input->aDelete as $index => $bookId) {
$book = DB_DataObject::factory($this->conf['table']['book']);
$book->get($bookId);
$book->delete();
unset($book);
}
SGL::raiseMsg('book delete successfull', false, SGL_MESSAGE_INFO);
} else {
SGL::raiseError('book delete NOT successfull ' .
__CLASS__ . '::' . __FUNCTION__, SGL_ERROR_INVALIDARGS);
}

}
}
?>
需要注意的是,manager类从文件名到class名的规范,即有点类似于java中一个文件中至少有一个类,而且文件名就是以类名为文件名。同时从上面的代码你也可以看到action,也就是manager的action method。使用了Seagull框架后,程序员不需要做太多的工作,所有的工作只需要在各个相应的action内实现特定的业务逻辑。

细心的程序员可能会发现,在几乎所有的manager类中都包含有validate(),display()方法。事实上,默认的情况下,Seagull框架中的manager类采用validate,process,display流程。也就是说进入Seagull框架的所有数据都要经过下列这些方法的处理:

validate:未经处理的$_REQUEST数据以一个SGL_Request实例被传递给这个方法,进行数据验证(主要是服务端的数据验证,当然也可以做一些客户端可以执行的数据验证,不过建议不要将客户端能做的数据验证放在这里),最后通过验证的数据会被映射到$input对象(其实是一个SGL_Registry实例)。你可以查看一下上面代码中的validate方法进一步加深认识。

process:如果所有来自客户端的数据被验证有效, $input对象会被做为参数传递经该manager类的某个action method,也就是来自客户端所请求的action进行处理。$input对象的数据被操作加工完后会被映射到$output对象(SGL_Output类的实例)。如果验证结果是无效,那么将跳过action而直接将数据传递给display,并反馈错误信息给用户。

display:该方法主要目的是提供一个进行后期数据加工处理的途径,而且一般是做大部分action都会涉及到的数据加工,也就是说如果你有几个action有共同的任务需要做,你可以考虑放在这里而避免代码重复。

从上面的这个bookMgr可以看出,使用了Seagull框架以后,程序员的主要工作是创建manager类,并实现其中相应的validate,display和相关的action method。下一篇我会整体介绍一下Seagull框架已经为我们提供的工具类,也就是我们可以直接使用的API,包括发送邮件,图像上传及处理,缓存等一系列经常使用的功能。当你掌握了这些API之后,你的开发时间将大大的减少,这是我们选择Seagull的原因之一。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: