Warning: Cannot modify header information - headers already sent by (output started at /www/17joyscom/php/wp-config.php:149) in /www/17joyscom/php/wp-includes/feed-rss2.php on line 8
博客 - 17joys 开源PHPCMS http://www.17joys.com/php 17joys 基于AJAX的PHPCMS Thu, 13 May 2010 00:34:44 +0000 http://wordpress.org/?v=2.9.1 en hourly 1 【使用教程】DWZ富客户端框架,基于jQuery实现的Ajax RIA开源框架 http://www.17joys.com/php/ajax/ajax-140.html http://www.17joys.com/php/ajax/ajax-140.html#comments Thu, 13 May 2010 00:31:43 +0000 凉风 http://www.17joys.com/php/?p=140 HTML扩展
支持HTML扩展方式来调用DWZ组件

Ajax链接扩展

<a href=”xxx” target=“ajax” [rel=“boxId”]>
 
示例: <a href="w_alert.html" target="ajax" rel="container">提示窗口</a>

当前navTab中链接ajax post扩展

<a href="user.do?method=remove" target="navTabTodo">删除</a>

dialog链接扩展

<a href=”xxx” target=“dialog” [rel=“dialogId”]>

Html标签扩展方式示例:

<a href="w_dialog.html" target="dialog" rel="page2">弹出窗口</a>
 
或
 
<a class="button" href="demo_page1.html" target="dialog" rel="dlg_page1" title="[自定义标题]" width="800" height="480">打开窗口一</a>

JS调用方式示例:

$.pdialog.open(url, dlgId, title);
 
或
 
$.pdialog.open(url, dlgId, title, {width: 500, height: 300});

navTab链接扩展

<a href=”xxx” target=“navTab” [rel=“tabId”]>
 
示例: <a href="w_alert.html" target="navTab" rel="page1">提示窗口</a>

Tab组件扩展
开发人员不需写任何javacsript, 只要使用下面的html结构就可以.

<div class="tabs">
 
      <div class="tabsHeader">
 
            <div class="tabsHeaderContent">
 
                  <ul>
 
                        <li class="selected"><a href="#"><span>标题1</span></a></li>
 
                        <li><a href="#"><span>标题2</span></a></li>
 
                  </ul>
 
            </div>
 
      </div>
 
      <div class="tabsContent" style="height:150px;">
 
            <div>内容1</div>
 
            <div>内容2</div>
 
      </div>
 
      <div class="tabsFooter">
 
            <div class="tabsFooterContent"></div>
 
      </div>
 
</div>

容器高度自适应
容器高度自适应, 只要增加扩展属性layouth=”xx”, 单位是像素.

Layouth表示容器内工具栏高度. 浏览器窗口大小改变时容器高度自适应, 但容器内工具栏高度是固定的, 需要告诉js工具栏高度来计算出内容的高度.

示例: <div layouth=“150”>内容</div>

Table扩展
在table标签上增加class=”table”

<table layouth="170" class="table">
 
      <thead>
 
            <tr>
 
                  <th width="80">客户号</th>
 
                  <th width="100">客户名称</th>
 
                  <th align="right">证件号码</th>
 
                  <th width="100">建档日期</th>
 
            </tr>
 
      </thead>
 
      <tbody>
 
            <tr>
 
                  <td>iso127309</td>
 
                  <td>北京市政府</td>
 
                  <td>0-0001027766351528</td>
 
                  <td>2009-05-21</td>
 
            </tr>
 
      </tbody>
 
</table>

在线编辑器
在textarea标签上增加class=”editor”

示例:

<textarea class="editor" name="description" rows="15" cols="80">内容</textarea>

Ajax表单提交
普通Ajax表单提交方式
DWZ 表单提交dwz.ajax.js

Ajax 表单提交后自动调用默认回调函数, 操作成功或失败提示.

Form标签上增加 onsubmit=”return validateCallBack(this);

Ajax 表单提交后如果需要做一些其它处理也可以自定义一个回调函数. 例如下面表单提交成功后关闭当前navTab, 或者重新载入某个tab.

Form标签上增加onsubmit=”return validateCallBack(this, navTabAjaxDone)”

/**
 
 * navTabAjaxDone是DWZ框架中预定义的表单提交回调函数.
 
 * 服务器转回navTabId可以把那个tab标记为reloadFlag=1, 次下切换到那个tab时会重新载入内容. 
 
 * navTabId如果是closeCurrent就会关闭当前tab
 
 * navTabAjaxDone这个回调函数基本可以通用了,如果还有特殊需要也可以自定义回调函数.
 
 * 如果表单提交只提示操作是否成功, 就可以不指定回调函数. 框架会默认调用ajaxDone()
 
 * <form action="/userAction?method=save" onsubmit="return validateCallBack(this, navTabAjaxDone)">
 
 * 
 
 * form提交后返回json数据结构statusCode=200表示操作成功, 做页面跳转等操作. statusCode=300表示操作失败, 提示错误原因.
 
 * {"statusCode":"200", "message":"操作成功", "navTabId":"navNewsLi", "forwardUrl":"", "callbackType":"closeCurrent"}
 
 * {"statusCode":"300", "message":"操作失败"}
 
 */
 
function navTabAjaxDone(json){
 
      ajaxDone(json);
 
      if (json.statusCode == 200){
 
            if (json.navTabId){
 
                  navTab.reloadFlag(json.navTabId);
 
            } else {
 
                  navTabPageBreak();
 
            }
 
 
 
            if ("closeCurrent" == json.callbackType) {
 
                  navTab.closeCurrentTab();
 
            } else if ("forward" == json.callbackType) {
 
                  navTab.reload(json.fowrwardUrl);
 
            }
 
      }
 
}

示例:

<form method="post" action="url" class="pageForm required-validate" onsubmit="return validateCallBack(this);">
 
<div class="pageFormContent" layoutH="56">
 
      <p>
 
            <label>E-Mail:</label>
 
            <input class="required email" name="email" type="text" size="30" />
 
      </p>
 
      <p>
 
            <label>客户名称:</label>
 
            <input class="required" name="name" type="text" size="30" />
 
      </p>
 
</div>
 
<div class="formBar">
 
      <ul>
 
            <li>
 
                  <div class="buttonActive"><div class="buttonContent"><button type="submit">保存</button></div></div>
 
            </li>
 
            <li>
 
                  <div class="button"><div class="buttonContent"><button type="Button" onclick="navTab.closeCurrentTab()">取消</button></div></div>
 
            </li>
 
      </ul>
 
</div>
 
</form>

文件上传表单提交方式
因为Ajax不支持enctype=”multipart/form-data” 所以用隐藏iframe来处理无刷新表单提交.

<form method="post" action="url" class="pageForm required-validate" enctype="multipart/form-data" onsubmit="return ifarmeCallback(this);">
 
或
 
<form method="post" action="url" class="pageForm required-validate" enctype="multipart/form-data" onsubmit="return ifarmeCallback(this, xxxCallback);">

服务器端需要返回

<script type="text/javascript">
 
      var statusCode="${statusCode}";
 
      var message="${message}";                         
 
      var navTabId="${navTabId}";
 
 
 
      var response = {statusCode:statusCode,
 
                  message:message,
 
                  navTabId:navTabId
 
            }
 
      if(window.parent.donecallback) window.parent.donecallback(response);
 
</script>

Java服务器端表单处理示例

public class UserAction extends BaseAction {
 
 
 
public ActionForward changePwd(ActionMapping mapping, BaseActionForm bForm,
 
            HttpServletRequest request, HttpServletResponse response)
 
            throws IOException, ServletException {
 
      UserForm form = (UserForm) bForm;
 
 
 
      if (form.getOldPassword() == null
 
                  || "".equals(form.getOldPassword().trim())) {
 
            request.setAttribute("statusCode", 300);
 
            request.setAttribute("message", this.getMessage(request,
 
                  "msg.oldpassword.invalid"));
 
            return mapping.findForward("done");
 
      }
 
 
 
      User user = AppContextHolder.getContext().getUser();
 
 
 
      try {
 
            UserManager uManager = BusinessFactory.getFactory()
 
                        .getUserManager();
 
            uManager.changePassword(user, form.getOldPassword(), form
 
                        .getPassword());
 
            request.setAttribute("statusCode", 200);
 
            request.setAttribute("message", this.getMessage(request,
 
                  "msg.operation.success"));
 
      } catch (PasswordNotCorrectException e) {
 
            request.setAttribute("statusCode", 300);
 
            request.setAttribute("message", this.getMessage(request,
 
                  "msg.password.incorrect"));
 
      }
 
 
 
      return mapping.findForward("done");
 
}
 
protected ActionForward callbackForward(ActionMapping mapping,
 
            HttpServletRequest request) {
 
      if (ServerInfo.isAjax(request))
 
            return mapping.findForward("done");
 
      return mapping.findForward("callbackDone");
 
}
 
}
 
public class ServerInfo {
 
      public static boolean isAjax(HttpServletRequest request) {
 
            if (request != null
 
                        && "XMLHttpRequest".equalsIgnoreCase(request
 
                                    .getHeader("X-Requested-With")))
 
                  return true;
 
            return false;
 
}
 
}

DWZ js库介绍
DWZ框架初始化
在<head>引入必要的js库

DWZ框架初始化会自动读取dwz.frag.xml中的页面组件碎片代码.

dwz.frag.xml中定义了一些dwz组件碎片和提示信息, 需要初始化到DWZ环境中.

注意dwz.frag.xml路径问题.

假设dwz.frag.xml放在根目录下, 在<head>标签中调用DWZ.init(“dwz.frag.xml”)

<script type="text/javascript">
 
$(function(){
 
      DWZ.init("dwz.frag.xml", function(){
 
            initEnv();
 
            $("#themeList").theme({themeBase:"themes"});
 
      });
 
})
 
</script>

dwz.core.js
DWZ核心库主要功能是DWZ初始化, Javascript String增加了一些扩展方法.

dwz.ajax.js
ajax表单提交封装

dwz.alertMsg.js
Ø 确认提示框

alertMsg.confirm("您修改的资料未保存,请选择保存或取消!", {
 
                okCall: function(){
 
                                $.post(url, {accountId: accountId}, ajaxDone, "json");
 
                }
 
});

Ø 成功提示框 alertMsg.correct(‘您的数据提交成功!’)

Ø 错误提示框 alertMsg.error(‘您提交的数据有误,请检查后重新提交!’)

Ø 警告提示框 alertMsg.warn(‘您提交的数据有误,请检查后重新提交!’)

Ø 信息提示框 alertMsg.info(‘您提交的数据有误,请检查后重新提交!’)

dwz.jDialog.js
弹出层组件

dwz.barDrag.js
DWZ左边的活动面板

dwz.navTab.js
导航tab组件

dwz.scrollCenter.js
页面容器自动居中组件

dwz.stable.js
table组件

dwz.tree.js
tree组件

dwz.theme.js
切换界面主题风格

dwz.ui.js
页面效果初始化

dwz.validate.method.js
这是jquery.validate.js表单验证扩展方法

dwz.validate.zh.js
表单验证本地化

dwz.contextmenu.js
自定义鼠标右键菜单

示例:

$("body").contextMenu('navTabCM', {
 
      bindings:{
 
            closeCurrent:function(t){
 
                  // TODO
 
            },
 
            closeOther:function(t){
 
                  // TODO
 
            },
 
            closeAll:function(t){
 
                  // TODO
 
            }
 
      },
 
      ctrSub:function(m){
 
            var mCur = m.find("[rel='closeCurrent']");
 
            var mOther = m.find("[rel='closeOther']");
 
            var mAll = m.find("[rel='closeAll']");
 
            // TODO
 
      }
 
});
]]>
http://www.17joys.com/php/ajax/ajax-140.html/feed 0
DWZ富客户端框架(jQuery RIA framework)中国人自己的RIA开源框架 http://www.17joys.com/php/news/new-135.html http://www.17joys.com/php/news/new-135.html#comments Fri, 30 Apr 2010 08:54:03 +0000 凉风 http://www.17joys.com/php/?p=135 DWZ富客户端框架(jQuery RIA framework), 是中国人自己开发的Ajax RIA开源框架, 是基于jQuery实现的UI组件框架. DWZ富客户端框架比ExtJs简单实用,比较适合做二次开发,使用jQuery可以非常方便的 定制特定需求的UI组件,并以jQuery插件的形式发布出来.如有需要也可做定制化开发.

这个框架是我的好友开发,希望大家多多支持,17Joys CMS正在开发的用户中心,便建立在此开源框架的基础上。

DWZ简单介绍:

DWZ富客户端框架设计目标是简单实用, 让开发人员少写js甚至不写js的情况下, 也能用ajax做项目. 比较适合做二次开发.
DWZ使用jQuery可以非常方便的定制特定需求的UI组件, 并以jQuery插件的形式发布出来. 如有需要也可做定制化开发.
欢迎大家提出建议,我们将在下一版本中进一步调整和完善功能.
DWZ富客户端框架是开源项目,可以免费获取源码。希望更多的开发人员使用,共同推进国内整体ajax开发水平。
在线演示地址 http://dwz.duqn.com
在线文档 http://dwz.duqn.com/doc/dwz-user-guide.pdf
视频教材 http://dwz.duqn.com/doc/dwz-user-guide.swf
Google Code下载: http://code.google.com/p/dwz/

演示界面:

DWZ中国人开发的RIA框架

]]>
http://www.17joys.com/php/news/new-135.html/feed 0
17joys用户管理 添加用户 http://www.17joys.com/php/cms/cms-13-132.html http://www.17joys.com/php/cms/cms-13-132.html#comments Tue, 13 Apr 2010 03:21:47 +0000 凉风 http://www.17joys.com/php/?p=132 添加用户是我们写的第一个管理操作,以后类似的添加操作都可以模仿此操作编写
首先先上代码,下面的代码要放在UserAction类中

function add(){
	$role=new Model('Role');//创建一个用户分组模型
	$list=$role->select();//提取用户分组数据
	$this->assign('rlist',$list);//分组数据分配到视图上,为了在添加用户时选择所属分组
	$this->display();//调用模板显示
}
 
function insert(){
	$user=new UserModel();//创建用户模型
	if($data=$user->create()){//通过create方法获取表单数据,只有这样才能激活数据验证功能
		if(false!==$user->add()){//通过add方法把数据插入到数据库中
			$uid=$user->getLastInsID();//获取新增用户的编号,限于自动增长列
			$ru['role_id']=$_POST['role_id'];//获取选择的用户分组
			$ru['user_id']=$uid;//整合用户分组明细
			$roleuser=new Model('RoleUser');//创建用户分组明细模型
			$roleuser->add($ru);//添加用户分组明细信息
			$this->assign('jumpUrl',__URL__.'/index');//设定调整页面
			$this->success('操作成功,插入数据编号为:'.$uid);//成功页面提示信息
		}else{
			$this->error('操作失败:adduser'.$user->getDbError());//插入错误提示
		}
	}else{
		$this->error('操作失败:数据验证( '.$user->getError().' )');//getError方法获取数据验证失败信息
	}
}

视图文件就是创建一个表单即可,视图文件Tpl/default/User/add.html

<form action="__URL__/insert" method="post">
      <table class="admintable" id="admintable">
      <tr>
	<td class="key">用户名:<span class="red_font">*</span></td><td><input type="text" name="username" class="inputbox"  /></td>
      </tr>
      <tr>
	<td class="key">密码:<span class="red_font">*</span></td><td><input type="password" name="pwd" class="inputbox" /></td>
     </tr>
     <tr>
	<td class="key">昵称:<span class="red_font">*</span></td><td><input type="text" name="name" class="inputbox" /></td>
     </tr>
     <tr>
	<td class="key">邮箱:<span class="red_font">*</span></td><td><input type="text" name="email" class="inputbox" /></td>
     </tr>
     <tr>
	<td class="key">是否激活:<span class="red_font">*</span></td>
	<td>
	是<input type="radio" name="active" value="1" checked="checked" />
	否<input type="radio" name="active" value="0" />
	</td>
     </tr>
     <tr>
	<td class="key" valign="top">用户组:<span class="red_font">*</span></td>
	<td>
	<select name="role_id" size="10">
	<volist name="rlist" id="row">
		<option value="{$row['id']}">{$row['name']}</option>
	</volist>
	</select>
	</td>
     </tr>
     <tr>
	<td>
	<input class="button" type="submit" value="保存" />
	<input class="button" type="submit" value="应用" />
	<input class="button" type="button" onclick="history.go(-1);" value="取消" />
	</td>
     </tr>
</table>
</form>

以上就是添加用户操作,注意action要连接到inser操作上,表单中字段属性要与数据库字段一致,或者与模型中的映射字段一致。

]]>
http://www.17joys.com/php/cms/cms-13-132.html/feed 0
17joys用户管理功能-控制器 http://www.17joys.com/php/cms/cms-12-125.html http://www.17joys.com/php/cms/cms-12-125.html#comments Sat, 10 Apr 2010 06:42:26 +0000 凉风 http://www.17joys.com/php/?p=125 用户名模型创建完毕后,接下来就要完成控制器的定义了,也就是要决定用户都有哪些操作。

ThinkPHP采用模块和操作的方式来执行,首先,用户的请求会通过入口文件生成一个应用实例,应用控制器(我们称之为核心控制器)会管理整个用户执行的过程,并负责模块的调度和操作的执行,并且在最后销毁该应用实例。任何一个WEB行为都可以认为是一个模块的某个操作,系统会根据当前的URL来分析要执行的模块和操作。这个分析工作由URL调度器来实现,官方内置了Dispatcher类来完成该调度。

在Dispatcher调度器中,会根据URL:http://servername/appName/moduleName/actionName/params
来获取当前需要执行的项目(appName)、模块(moduleName)和操作(actionName),在某些情况下,appName可以不需要(通常是网站的首页,因为项目名称可以在入口文件中指定,这种情况下,appName就会被入口文件替代)。在复杂一点的情况下面,可能还会出现分组(groupName)。

每个模块是一个Action文件,类似于我们平常所说的控制器,系统会自动寻找项目类库Action目录下面的相关类,如果没有找到,则会定位到空模块,否则抛出异常。

而actionName操作是首先判断是否存在Action类的公共方法,如果不存在则会继续寻找父类中的方法,如果依然不存在,就会寻找是否存在自动匹配的模版文件。如果存在模版文件,那么就直接渲染模版输出。

因此应用开发中的一个重要过程就是给不同的模块定义具体的操作。一个应用如果不需要和数据库交互的时候可以不需要定义模型类,但是必须定义Action控制器。

Action控制器的定义非常简单,只要继承Action基础类就可以了,例如:

class UserAction extends Action{

}
如果我们要执行下面的URL

http://servername/index.php/User/add

你需要增加一个add方法就可以了,例如

Class UserAction extends Action{
 
  // 定义一个add操作方法,注意操作方法不需要任何参数
 
  Public function add(){
 
   // add操作方法的逻辑实现
 
   // ……
 
   $this->display(); // 输出模板页面
 
}
 
}

操作方法必须定义为Public类型,否则会报错。并注意操作方法的命名不要和内置的Action类的方法重复。系统会自动定位当前操作的模板文件,而默认的模板文件应该位于项目目录下面的Tpl\default\User\add.html。

17JoysCMS用户管理功能需要的操作就是:用户列表、创建用户、编辑用户、删除用户、插入用户数据、更新用户数据
所以控制器的结构如下

class UserAction extends CommonAction{
      /*
       用户列表
    */
      funciton index(){
      }
     /*
       添加用户
    */
      funciton add(){
      }
     /*
       编辑用户
    */
      funciton edit(){
      }
      /*
       删除用户
    */
      funciton delete(){
      }
      /*
       插入用户数据
    */
      funciton insert(){
      }
      /*
       更新用户数据
    */
      funciton update(){
      }
}

此文件保存于Action/UserAction.class.php文件中

]]>
http://www.17joys.com/php/cms/cms-12-125.html/feed 0
17Joys CMS企业网站管理系统 v1.0 正式发布 http://www.17joys.com/php/news/cms-11-117.html http://www.17joys.com/php/news/cms-11-117.html#comments Sat, 10 Apr 2010 06:23:43 +0000 凉风 http://www.17joys.com/php/?p=117 17Joys CMS是一套使用ThinkPHP框架开发,基于PHP+MYSQL免费开源的企业网站系统;

开发目的:为了让跟多的PHP爱好者掌握ThinkPHP框架开发,我们提供CMS源码作为教学案例,希望更多的PHP爱好者可以掌握,并且参与到我们17Joys CMS的开发团队中来

环境要求:php5+mysql5

功能及模块:

1,单元、分类、文章内容管理,可自定义开发内容组件,前台动态分配
2,菜单、菜单项管理,灵活的内容分配,可以指定菜单项绑定的内容,并支持无限级菜单项
3,模块管理,自定义开发内容模块:支持任意表现形式,菜单、最新文章、相关文章等。
4,用户、用户分组管理,强大的RBAC用户认证机制
5、支持SEO伪静态,内容缓存能提高程序执行速度
6、程序模板分离可以制作自己喜欢的网站且不需懂程序

安装方式:http://youdomain/Install/index.php

官方网站:http://www.17joys.com
17Joys开发教学网站:http://www.17joys.com/php
支持论坛:http://www.17joys.com/bbs

项目地址:http://code.google.com/p/17joys/
SVN地址:http://17joys.googlecode.com/svn/trunk/

下载地址:
本地下载
admin5分流

首页缩略图

]]>
http://www.17joys.com/php/news/cms-11-117.html/feed 0
公告:17Joys CMS系统正式上线 http://www.17joys.com/php/news/cms-10-113.html http://www.17joys.com/php/news/cms-10-113.html#comments Fri, 19 Mar 2010 09:13:38 +0000 凉风 http://www.17joys.com/php/?p=113 经过了2个多月断断续续的开发,17JoysCMS系统终于开发完毕,已经具备了文章发布、页面模块管理等基本功能,稍后整理完毕会发布源码给大家,欢迎大家给出建议。

乐学PHP 17Joys CMS企业建站系统

]]>
http://www.17joys.com/php/news/cms-10-113.html/feed 2
17joys的后台页面-去除AJAX框架版本 http://www.17joys.com/php/cms/cms-9-101.html http://www.17joys.com/php/cms/cms-9-101.html#comments Mon, 22 Feb 2010 07:38:08 +0000 凉风 http://www.17joys.com/php/?p=101 由于一些同学针对AJAX的研究还不是很深入,我发布一个去除AJAX框架版本的后台页面,这个后台是从之前在17joys后台代码-初步搭建发布的一个模板中挑选,并进行了修改,现在把修改之后的代码发布出来给大家学习使用,大家可以通过访问admin.php文件进行预览了,具体功能在后面会陆续添加进来。

代码下载:另存为下载

页面效果图:

首页代码:Admin/Tpl/default/Index/index.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>管理后台</title>
</head>
<frameset rows="64,*"  frameborder="NO" border="0" framespacing="0">
	<frame src="__ROOT__/admin.php/Public/top" noresize="noresize" frameborder="NO" name="topFrame" scrolling="no" marginwidth="0" marginheight="0" target="main" />
  <frameset cols="200,*"  rows="560,*" id="frame">
	<frame src="__ROOT__/admin.php/Public/left" name="leftFrame" noresize="noresize" marginwidth="0" marginheight="0" frameborder="0" scrolling="no" target="main" />
	<frame src="__ROOT__/admin.php/Public/main" name="main" marginwidth="0" marginheight="0" frameborder="0" scrolling="auto" target="_self" />
  </frameset>
<noframes>
  <body></body>
    </noframes>
</html>
]]>
http://www.17joys.com/php/cms/cms-9-101.html/feed 2
17joys用户管理功能-模型 http://www.17joys.com/php/cms/cms-m9-94.html http://www.17joys.com/php/cms/cms-m9-94.html#comments Wed, 27 Jan 2010 10:06:55 +0000 凉风 http://www.17joys.com/php/?p=94 现在后台页面的搭建工作已经完成,不知道大家有没有找到满意的模板,反正我是找到了,呵呵!接下来要做的就是后台的功能了,第一个需要完成的功能就是用户管理功能。对于功能的编写说白了主要就是对数据库的操作,数据的操作无外乎增、删、改、查这四大项,在ThinkPHP中叫CURD。
【注】:CURD是一个数据库技术中的缩写词,一般的项目开发的各种参数的基本功能都是CURD。它代表创建(Create)、更新(Update)、读取(Read)和删除(Delete)操作。

这CURD操作的任务就要交给模型来完成了,在ThinkPHP中基础的模型类就是Model类,该类完成了基本的CURD、ActiveRecord模式、连贯操作和统计查询,一些高级特性被封装到另外的模型类中,例如AdvModel高级模型类完成了一些包括文本字段、只读字段、序列化字段、乐观锁、多数据库连接等模型的高级特性,ViewModel视图模型类完成了模型的视图操作,RelationModel关联模型类完成了模型的关联操作。
基础模型类Model的设计非常灵活,甚至可以无需进行任何模型定义,就可以进行相关数据表的ORM和CURD操作,只有在需要封装单独的业务逻辑的时候,模型类才是必须被定义的。

下面就上正菜,用户模型类UserModel,这个类文件放在Lib/Model目录下,命名为UserModel.class.php,说到命名就要遵循规范,ThinkPHP要求数据库的表名和模型类的命名遵循一定的规范,首先数据库的表名和字段全部采用小写形式,模型类的命名规则是除去表前缀的数据表名称,并且首字母大写,然后加上模型类的后缀定义。
例如:UserModel 表示User数据对象,由于我之前项目配置的数据库的表前缀是 joys_,所以UserModel模型其对应的数据表应该是joys_user
【注】:表设计请看17joys网站后台功能设计-阶段1

当然如果你的规则和系统的约定不符合,也可以设置Model类的tableName属性进行自定义。

17joys的用户模型类

下面就是我的UserModel类代码

<?php
/*
* 功能:用户模型类
* 作者:马明
* 版本:1.0
* 开发时间:2010.1
*/
 
class UserModel extends Model {
	/*
	 * 表单验证
	 */
	protected  $_validate = array(
	//array(验证字段,验证规则,错误提示,验证条件,附加规则,验证时间)
		array('username','require','账号名必须存在!',1,'regex',3),
		array('username','','账号名已经存在!',1,'unique',1),
		array('rpwd','pwd','两次密码不一致!',0,'confirm'),
		array('name','require','用户名称必须存在!',1),
		array('email','require','邮箱不能为空!'),
		//array('email','','邮箱已经存在!',1,'unique',3),
		array('email','checkEmail','邮箱已经存在!',1,'callback',3),
		array('active',array(0,1),'启用:1 ; 停用:0',0,'in'),
	);
 
	/*
	 * 字段映射
	 */
	protected $_map=array(
		//'uname'=>'username',	
		'pwd'=>'password',
	);
 
	/*
	 * 自动填充
	 */
	protected $_auto=array(
	//array(填充字段,填充内容,填充条件,附加规则)
		array('password','md5',1,'function'),
		array('reg_date','getDate',1,'callback'),
		array('active','1'),
	);
 
	function getDate(){
		return date('Y-m-d H:i:s');
	}
 
	function checkEmail(){
		$user=new Model('User');
		if(empty($_POST['id'])){
			if($user->getByEmail($_POST['email'])){
				return false;
			}else{
				return true;
			}
		}else{
			if($user->where("id!={$_POST['id']} and email='{$_POST['email']}'")->find()){
				return false;
			}else{
				return true;
			}
		}
	}
}
?>

关于这个类文件的说明,稍后我会分开给大家讲解。

]]>
http://www.17joys.com/php/cms/cms-m9-94.html/feed 1
17joys的后台页面-视图 http://www.17joys.com/php/cms/cms-8-89.html http://www.17joys.com/php/cms/cms-8-89.html#comments Wed, 27 Jan 2010 09:28:10 +0000 凉风 http://www.17joys.com/php/?p=89 现在模块控制器有了,接下来当我们访问模块的操作时,就该给用户呈现页面了,这就是视图。终于轮到前台的XHTML+CSS+JavaScript大显身手了。

ThinkPHP的视图主要由View视图类和模板文件构成。视图类负责Action控制器类和模板文件之间沟通,Action类把数据通过View类传递到模板文件,而模板文件把接收到的数据转换成相应的数据格式显示。
【注】:视图仅仅是进行数据的输出显示,通常在视图渲染过程是不会改变数据本身的,而只是进行格式化输出和显示。

ThinkPHP内置了一个基于XML的性能卓越的模板引擎 ThinkTemplate,这是一个专门为ThinkPHP服务的内置模板引擎,无论在功能或是性能还有易用性方面都比Smarty优秀。这是ThinkPHP手册的原话,在我使用了一段时间后,发现还是有些小bug存在的,不过倒是无伤大雅,还是很不错的模板引擎,17joys决定就采用ThinkPHP提供的这款模板引擎进行开发,如果习惯Smarty模板引擎的同学,也可以很容易的更换,稍后我会把配置使用Smarty的方法发布出来。

下面开始创建模板,模板目录默认是项目下面的Tpl, 模板主题默认是default,模板主题功能是为了多模板切换而设计的,如果有多个模板主题的话,可以用TMPL_DEFAULT_THEME参数设置默认的模板主题名。以后我们可以很方便的定义前台模板主题了。

为了对模板文件更加有效的管理,ThinkPHP对模板文件进行目录划分,默认的模板文件定义规则是:
模板目录/模板主题/[分组名/]模块名/操作名+模板后缀

那针对Index模块的index操作,我们的模板存放路径:Tpl/default/Index/index.html
换做User模块的add操作,模板存放路径:Tpl/default/User/add.html

17joys模板目录效果图

当然后台代码就不需要向前台那么复杂了,一般我们都会考虑使用分帧的框架搭建,不过17joys采用的是纯AJAX后台,为了AJAX的调用和更新页面的考虑,所以页面使用的是DIV+CSS布局。

<body scroll="no">
<div id="layout">
		<div id="header">
			<div class="headerNav">
				<a class="logo" href="#">17joyslogo</a>
				<ul class="nav">
					<li><a href="#">切换角色</a></li>
					<li><a href="#">设置</a></li>
					<li><a href="#">反馈</a></li>
					<li><a href="#">帮助</a></li>
					<li><a href="#">退出</a></li>
				</ul>
				<ul class="themeList" id="themeList">
					<li class="t1" theme="default"><div class="selected">蓝色</div></li>
					<li class="t2" theme="green"><div>绿色</div></li>
					<li class="t3" theme="red"><div>红色</div></li>
					<li class="t4" theme="purple"><div>紫色</div></li>
					<li class="t5" theme="silver"><div>银色</div></li>
				</ul>
			</div>
		</div>
		<div id="leftside">
		<div id="sidebar_s" style="display:none;">
			<div class="collapse">
				<div class="toggleCollapse"><div>d</div></div>
			</div>
		</div>
		<div id="sidebar">
			<div class="toggleCollapse"><h2>主菜单</h2><div>收缩</div></div>
			<div class="accordion">
				<div class="accordionHeader">
					<h2><span>Folder</span>网站管理</h2>
				</div>
				<div class="accordionContent" style="display:block;">
					<ul class="tree treeFolder">
						<li><a href="tabsPage.html" target="navTab">控制面板</a>
							<ul>
								<li><a href="main.html">我的主页</a></li>
							</ul>
						</li>
						<li><a href="w_form.html" target="navTab" rel="joys_menu">菜单</a>
							<ul>
								<li><a href="w_button.html">菜单管理</a></li>
							</ul>
						</li>
					</ul>
				</div>
				<div class="accordionHeader">
					<h2><span>Folder</span>会员管理</h2>
				</div>
				<div class="accordionContent" style="display:block;">
					<ul class="tree treeFolder">
						<li><a href="tabsPage.html" target="navTab">会员管理</a>
							<ul>
								<li><a href="">会员资料管理</a></li>
								<li><a href="">添加会员</a></li>
							</ul>
						</li>
					</ul>
				</div>
			</div>
		</div>
		</div>
		<div id="container">
			<div id="navTab" class="tabsPage">
				<div class="tabsPageHeader">
					<div class="tabsPageHeaderContent">
						<ul class="navTab-tab">
							<li tabid="main" class="main"><a href="#"><span><span class="home_icon">我的主页</span></span></a></li>
						</ul>
					</div>
					<div class="tabsLeft">left</div>
					<div class="tabsRight">right</div>
					<div class="tabsMore">more</div>
				</div>
				<ul class="tabsMoreList">
					<li><a href="#">我的主页</a></li>
				</ul>
				<div class="navTab-panel tabsPageContent">
					<div></div>
				</div>
			</div>
		</div> 
		<div id="taskbar" style="left:0px; display:none;">
			<div class="taskbarContent">
				<ul style="width:50000px"></ul>
			</div>
			<div class="taskbarLeft taskbarLeftDisabled" style="display:none;">taskbarLeft</div>
			<div class="taskbarRight" style="display:none;">taskbarRight</div>
		</div>
		<div id="splitBar"></div>
		<div id="splitBarProxy"></div>
	</div>
 
	<div class="resizable" style=" display:;"></div>
	<div class="shadow" style=" display:; width:508px; top:148px; left:296px;">
		<div class="shadow_h">
			<div class="shadow_h_l"></div>
			<div class="shadow_h_r"></div>
			<div class="shadow_h_c"></div>
		</div>
		<div class="shadow_c">
			<div class="shadow_c_l" style="height:296px;"></div>
			<div class="shadow_c_r" style="height:296px;"></div>
			<div class="shadow_c_c" style="height:296px;"></div>
		</div>
		<div class="shadow_f">
			<div class="shadow_f_l"></div>
			<div class="shadow_f_r"></div>
			<div class="shadow_f_c"></div>
		</div>
	</div>
	<div id="alertBackground" class="alertBackground"></div>
</body>

这就是HTML代码部分,CSS部分暂时还没有整理完,有兴趣的同学可以自己尝试用CSS修饰一下,当然如果做出动态菜单效果的话,还需要JavaScript的帮助。当然大家也可以自己找一个写好了的后台HTML模板,在之前的一篇文章《17joys后台代码-初步搭建》中,我提供了一些后台模板,大家可以去下载使用。

]]>
http://www.17joys.com/php/cms/cms-8-89.html/feed 2
针对17joys控制器的扩展 http://www.17joys.com/php/cms/cms-7-86.html http://www.17joys.com/php/cms/cms-7-86.html#comments Wed, 27 Jan 2010 08:57:33 +0000 凉风 http://www.17joys.com/php/?p=86 在我们编写代码的时候,尽量要多考虑一些以后可能会附带的功能要求,为这些功能留下编写的余地,这样就能增加扩展性,我在查看ThinkPHP源码的时候发现,每次控制器初始化的时候都会去调用一个_initialize()方法,那我就思考,以后肯定会针对所有的控制器模块定义公共方法,所以我考虑扩展Action类,把这些公共方法都放进去,这就产生了CommonAction类。

CommonAction.class.php文件

<?php
class CommonAction extends Action {
	function _initialize(){
		header("Content-Type:text/html; charset=utf-8");
	}
}
?>

之前的IndexAction类文件修改为

<?php
class IndexAction extends CommonAction { //从CommonAction继续扩展继承
    public function index(){
        $this->display();
    }
}
?>

这样以后我就可以把更多的功能方法放到CommonAction类中,譬如权限验证等操作

【注】:ThinkPHP的Action类源码

39
40
41
42
43
44
45
46
public function __construct()
{
    //实例化视图类
   $this->view       = Think::instance('View');
    //控制器初始化
   if(method_exists($this,'_initialize'))
        $this->_initialize();
}
]]>
http://www.17joys.com/php/cms/cms-7-86.html/feed 0