分享

走马观花SHOPNC [原创]

 sumi2005 2013-10-21
本帖最后由 kakashilw 于 2009-7-1 12:39 编辑

因为工作原因,最近又走马观花了几套开源产品。。。

在这里分享下走马观花shopnc时的笔记吧。。。

其实shopnc是半开源的产品,它的核心代码是加密的。。不过开源的部分还不少,而且还有注释,嘻嘻~~

ready?go!

--------------------------------------------------------------------------------------------------------------------------

1、index.php和index.html   之首页静态化生成

分析代码当然是从index.php开始喽,贴下代码

[php]
require ("global.inc.php");
//判断是否有安装文件
if (file_exists("install/index.php")){
// if (!is_writable("templates/install/templates_c")){
//  echo BasePath."/templates/install/templates_c have no permissions! Please Determine this Folder's  write permissions!";
//  exit;
// }
header("location:install/index.php");
exit;
}
class ShowIndex extends CommonFrameWork{
function main(){
  /**
   * 执行操作
   */
  switch($this->_input['action']){
   default:
    $this->_showindex();
  }
}
/**
  * 首页显示
  *
  */
function _showindex(){
  @header("location:home/index.php");
}
}
$index = new ShowIndex();
$index->main();
unset($index);
[/php]

很简单,通过global.inc.php载入核心类库,包括框架的核心代码(个人猜测应该是大白菜心的php框架吧)

然后跳转到home/index.php中去了。。

index.php中执行了

[php]
function main(){

  /**
   * 创建首页和频道静态页面对象
   */
  if (!is_object($this->obj_html_channel)){
  
   require_once("../home/html.channel.php"); //dump("eee");
   $this->obj_html_channel = new HtmlChannelManage();
  }

  /**
   * 创建商品分类对象
   */
  if (!is_object($this->objProductCate)){
   require_once ("productclass.class.php");
   $this->objProductCate = new ProductCategoryClass();
  }
   //return;
  /**
   * 创建商铺分类对象
   */
  if (!is_object($this->obj_shop_category)){
   require_once("shopcategory.class.php");
   $this->obj_shop_category = new ShopCategoryClass();
  }

  
  /**
   * 设置模板路径
   */
  $this->setsubtemplates("home");
  /**
   * 语言包
   */
  $this->getlang("index_show");
  /**
   * 执行操作
   */

  switch($this->_input['action']){
   case "aj_get_class":
    $this->_aj_get_class();
    break;
   case "getQuickLinks":
    $this->_getQuickLinks();
    break;
   case "index_html":
    $this->_index_html();
    break;
   default:
    $this->_showindex();
  }
}
[/php]

有注释,看看流程就可以了,具体代码就不细究了。。。

然后执行到了$this->_index_html();

这个是关键,就是传说中的【首页静态化】了。。看看人家是咋写的

这个函数中辗转反侧后到了最后这个方法了。。

[php]
function _make_language_html($language){
  //重新加载语言包
  unset($this->_lang);
  $this->_langType = $language['language_path'];
  $this->getlang("common");
  $this->getlang("index_show");
  $this->getlang("channel");
  //频道页面需要加载的内容
  //搜索中的商品类别
  require(BasePath."/cache/ProductClass_show.php");
  if (is_array($node_cache)){
   foreach ($node_cache as $k => $v){
    if ($v[4] == '0') {
     $v['id'] = $v[0];
     $v['name'] = $v[2];
     $SearchProductCateArray[] = $v;
    }
   }
  }
  /*取所有频道*/
  $condition["order_by"] = "channel_sort";
  $condition["state"] = "0";
  $condition["order_sort"] = "asc";
  $channel_all = $this->obj_channel->listChannel($condition,$page);
  unset($condition);
  //取模块参数配置文件 default
  $path = BasePath."/share/indexparam/";
  //模板参数
  $tpl_path = BasePath."/templates/".$this->_configinfo['websit']['templatesname'].'/home/index_tpl/';
  //判断改文件夹是否存在,如果不存在,则报错
  if (!is_dir($path)){
   return $this->_lang['langChannelIndexTempDirWrong'];
  }
  //通过LOCK标识,取模板文件名
  require_once("fileoperate.class.php");
  $file_array = FileOperate::listDir($tpl_path);
  //如果有LOCK后缀的文件,则表示文件名为模板当前使用名称
  if (is_array($file_array)){
   foreach ($file_array as $k => $v){
    if (strstr($v['name'],'.LOCK')){
     $template_name = substr($v['name'],0,strlen($v['name'])-5);
     if (!file_exists($tpl_path.$template_name)) {
      return $this->_lang['langChannelIndexHmtlTempIsNotExists'];
     }
     $template_name = substr($template_name,0,strlen($template_name)-5);
     break;
    }
   }
  }
  //判断是否为空,如果为空,则默认
  if($template_name == ''){
   $template_name = 'default';
  }
  if (file_exists($path.$this->_configinfo['websit']['templatesname'].".php")){
   require($path.$this->_configinfo['websit']['templatesname'].".php");
   //参数数组 $ChannelParamArray
   if (is_array($ChannelParamArray)){
    $module = array();/*模块页面代码*/
    //取各模块的参数 $k 为模块名称 下划线前两个单词为模块类型
    foreach ($ChannelParamArray as $k => $v){
     //判断模块类型
     $line = @explode("_",$k);
     $module_name = $line[0].'_'.$line[1];
     switch ($module_name){
      case "adv_module"://广告模块
      //如果是安装时,则判断是否安装演示数据,如果不安装的话,则不执行广告模块程序
      if (INSTALL_ISDATA == 'no'){//不安装
       break;
      }
      //判断是否是flash广告,如果不是则调用JS文件,是则调用模块模板
      //创建广告对象
      if (!is_object($this->obj_adv)){
       require_once ("advertisement.class.php");
       $this->obj_adv = new AdvertisementClass();
      }
      $condition_adv['code'] = $v['code'];
      $condition_adv['start_date'] = time();
      $condition_adv['end_date'] = time();
      $condition_adv['state'] = 0;
      $adv_list = $this->obj_adv->listAdv($condition_adv,$page);
      if ($adv_list[0]['adv_type'] == 2){//如果是flash
       $module[$k] = $this->advFlashHtmlCode($v['code']);
      }else {//其他广告类型,调用的是JS文件
       //判断广告的JS文件是否存在
       if (file_exists(BasePath."/html/js/".$v['code'].'.js')){
        $module[$k] = "<script src='".$this->_configinfo['websit']['site_url'].'/html/js/'.$v['code'].'.js'."'></script>";
       }else {
        return $this->_lang['langChannelAdvCreaLostPleaseAdvManageCreateFile'];
       }
      }
      break;
      case "vote_module"://投票模块
      $module[$k] = $this->voteHtmlCode($v);
      break;
      case "product_module"://商品模块
      $module[$k] = $this->productHtmlCode($v);
      break;
      case "shop_module"://商铺模块
      $module[$k] = $this->shopHtmlCode($v);
      break;
      case "pclass_module"://商品类别模块
      $module[$k] = $this->pclassHtmlCode($v);
      break;
      case "shopclass_module"://商铺类别模块
      $module[$k] = $this->shopclassHtmlCode($v);
      break;
     }
    }
    //关键词模板名称
    $keyword_html_name = BasePath.'/html/keyword/index.html';
    /**
     * 取得最新成交订单列表
     */
    if (!is_object($this->obj_product_order)){
     require_once("order.class.php");
     $this->obj_product_order = new ProductOrderClass();
    }
    $obj_order_condition[order] = "1";
    $this->obj_page_channel->pagebarnum(10);
    $product_order_array = $this->obj_product_order->getProductOrderList($obj_order_condition, $this->obj_page);
   
    //重新设置模板路径和语言包
    $this->setsubtemplates("home/index_tpl");
   
    /**
     * 页面输出
     */
    /*页头导航的样式判断*/
    $this->output('search_header_sign','1');
    //对模板上的模块标识符进行替换
    $this->output("product_order_array",$product_order_array);
    $this->output("keyword_html_name",$keyword_html_name);
    $this->output("search_cate",$SearchProductCateArray);//搜索中的商品类别
    $this->output('channel_all',   $channel_all);   //导航菜单频道
    $this->output('language_array',   $language);   //该语言种类
    $default_code = $this->fetchpage($template_name);//取输出到模板上的内容
    if (is_array($module)){
     foreach ($module as $k => $v){
      $line = "";
      $line = '<module>'.$k.'</module>';
      $replacements = $v;
      $default_code = @str_replace($line,$replacements,$default_code);
     }
    }
    $this_my_file = @preg_replace('/<module>.*?<[url=]\\/module>/is',"",$default_code[/url]);
    require_once("makehtml.class.php");
    /*根目录下生成文件*/
    //判断是否是默认语言,如果是则用
    if ($language['language_state'] == '1'){
     if (file_exists('../index.html')){
      @unlink('../index.html');
     }
     $file_name = '../index.html';
    }else {
     if (file_exists('../index_'.$language['language_path'].'.html')){
      @unlink('../index_'.$language['language_path'].'.html');
     }
     $file_name = '../index_'.$language['language_path'].'.html';
    }
    $this_my_file = str_replace("../","",$this_my_file);
    $patterns = array (
    '/home\\/home\\/category.php/is',
    '/href=\\"category.php/is',
    '/home\\/home\\/member.php/is',
    '/href=\\"member.php/is',
    '/home\\/home\\/channel.php/is',
    '/href=\\"channel.php/is',
    '/home\\/home\\/shop.php/is',
    '/href=\\"shop.php/is',
    '/home\\/home\\/shop_brand.php/is',
    '/href=\\"shop_brand.php/is',
    '/home\\/home\\/vote.php/is',
    '/=\\"vote.php/is',
    "/\\('vote.php/is",
    '/home\\/home\\/product.php/is',
    '/href=\\"product.php/is',
    '/home\\/home\\/productmessage.php/is',
    '/href=\\"productmessage.php/is',
    '/switcher.swf/is',
    '/js_statics_sign=1/is',
    "/\\'shop.php/is",
    "/\\'product.php/is",
    );
    $replacements = array (
    'home/category.php',
    'href="home/category.php',
    'home/member.php',
    'href="home/member.php',
    'home/channel.php',
    'href="home/channel.php',
    'home/shop.php',
    'href="home/shop.php',
    'home/shop_brand.php',
    'href="home/shop_brand.php',
    'home/vote.php',
    '="home/vote.php',
    "('home/vote.php",
    'home/product.php',
    'href="home/product.php',
    'home/productmessage.php',
    'href="home/productmessage.php',
    'switcher_html.swf',
    'js_statics_sign=3',
    "'home/shop.php",
    "'home/product.php",
    );
    $this_my_file = preg_replace($patterns,$replacements,$this_my_file);
   
    //如果使用动态访问,则不生成静态页
    if ($this->_configinfo['websit']['index_html'] == '0'){
     echo $this_my_file;exit;
    }
   
    if (!MakeHtml::tohtmlfile($file_name, $this_my_file)){
     return $this->_lang['langChannelIndexCreateLostFile'];
    }else {
     return true;
    }
   }
  }else {
   return $this->_lang['langChannelIndexCreateLostParamFile'];
  }
}
[/php]

很复杂,因为包含了多语言,栏目缓存等,不过就静态化的话,关键就是这句了

[php]MakeHtml::tohtmlfile($file_name, $this_my_file)[/php]

这个类他加密了,不过据我的猜测应该是fwrite之类的吧,这样就生成了index.html了。。

以后先判断根目录下有无这个文件,有就跳过去,没有则生成。。。

好了,先写这么多了。。。困了。。睡觉去了。。。

以后有空再写吧。。。。

694

主题

36

好友

1万

积分

千象

叫我K兄好了

Rank: 16Rank: 16Rank: 16Rank: 16

威望
5514
开源币
293
注册时间
2007-12-7
积分
11786
帖子
3015
主题
694
UID
52443

第一颗象牙 第二颗象牙 第三颗象牙 第四颗象牙

2#
发表于 2009-7-1 04:24:41 |只看该作者

2、SHOPNC的MVC

本帖最后由 kakashilw 于 2009-7-1 13:58 编辑

SHOPNC的MVC和现在主流框架的MVC还是有些区别的。。。

最大的不同在于,SHOPNC是多入口的,不同功能一个入口文件,然后再在main()函数中分发。。。

拿一个商品的展示页为例。。。。

[php]
require ("../global.inc.php");   //载入核心类库,这个上面提到过了
class ShowProduct extends CommonFrameWork{       //都集成CommonFrameWork这个类
    ...................

  function main(){
          ..............
   }

   .................
}

$product = new ShowProduct();
$product->main();
unset($product);
[/php]

每个入口文件大致是 这样的结构了。。。

OK,看着还是蛮简洁明了的。。。。

------------------------------------------------------------------------------------------------------------------------

好了,下面着重分析下main函数,因为这里面包含的是  初始化(类似构造函数的功能) , 路由转发  这几步内容

基本相当于MVC众的"C"了


(1)初始化,一般都是这种风格的。。。  

(PS:这里插一句,很佩服大白菜产品的代码风格,非常一致,看来之前他所说的一个员工拿到另一个的代码,最多半小时就能上手果真不是吹的,呵呵)

[php]
  /**
   * 创建商品对象
   */
  if (!is_object($this->obj_product)){
   require_once("product.class.php");
   $this->obj_product = new ProductClass();
  }
  /**
   * 创建验证对象
   */
  if (!is_object($this->objvalidate)){
   require_once("commonvalidate.class.php");
   $this->objvalidate = new CommonValidate();
  }
  /**
   * 网站提醒操作
   */
  if (!is_object($this->obj_remind)){
   require_once('remind.class.php');
   $this->obj_remind = new RemindClass();
  }
  /**
   * 创建会员对象
   */
  if (!is_object($this->obj_member)){
   require_once("member.class.php");
   $this->obj_member = new MemberClass();
  }
  /**
   * 初始化商品品牌类
   */
  if (!is_object($this->obj_product_brand)){
   require_once("product_brand.class.php");
   $this->obj_product_brand = new ProductBrandClass();
  }

  /**
   * 设置模板路径
   */
  $this->setsubtemplates("home");
  /**
   * 语言包
   */
  $this->getlang("product");
[/php]

(2)路由转发

[php]
  switch ($this->_input['action']){
   case "list":
    $this->_listproduct();
    break;
   case "textlist":
    $this->_listproduct();
    break;
   case "view":
    $this->_viewproduct();
    break;
   case "search":
    $this->output('InfoSelectorTarget',Common::getTargetMenu("search"));
    $this->_searchproduct();
    break;
   case "compare":
    $this->_compareproduct();
    break;
   case "compareresult":
    $this->_compareproductresult();
    break;
   case "compare_remove":
    $this->_compareremove();
    break;
   case "clean_reviewed":
    $this->_cleanreviewedproduct();
    break;
   case "check_code":
    $this->_check_code();
    break;
   case 'all':
    $this->_listproduct();
    break;
   case "setReview":
    $p_code = $this->_input['p_code'];
    $this->setReviewed($p_code);
    break;
   case "ajax_get_attribute":
    $this->_ajax_get_attribute();
    break;
   default:
    $this->_listproduct();
    break;
  }
[/php]

呵呵,有注释,看着就简单多了吧。。。
------------------------------------------------------------------------------------------------------------------


好了,下面看看MVC钟的"V"是怎样的。。。

拿_viewproduct()这个举例,可以看到函数的最下端有
[php]
   $this->output('pURL',$pURL);
   $this->output('pic_array',$pic_array);//商品图片列表
   $this->output('class_level',$class_level);
   $this->output("title_message"  , $title_p_name);     //TITLE内容
   $this->output("keyword_message", $keyword_p_name);     //关键字内容
   $this->output("ses_login", $_SESSION['s_login']);   //登陆信息
   $this->output("page_list", $page_list);
   $this->output("shop_info", $shop_info);
   $this->output("product_row", $product_row);
   $this->output("PathLinks", $cate_path);
   $this->output("ses_login", $_SESSION['s_login']);   //登陆信息
   $this->output("message_array", $message_array);   //商品留言
   $this->output("seller_info", $seller_info);  //商家信息
   $this->output("have_attribute", $have_attribute);
   $this->output("product_attribute", $product_attribute);
   $this->output("product_attribute_content", $product_attribute_content);
   $this->output("product_have_attribute", $pac_attribute);
   $this->output("payment_array", $payment_array);
   $this->output("currency_array", $currency_array);
   $this->output("product_order_array", $product_order_array);
   $this->output("lefttime", $text_left_time);
   $this->output("exchange_remark", $exchange_remark);
   $this->output("sel_area", $sel_area);
   $this->output("sel_brand", $sel_brand);
   $this->showpage("product.view");
[/php]

哈哈,用过smarty或框架的童鞋是不是很熟悉啊,对了,这个就是shopnc的模板引擎了。。。 对应的是home目录下的product.view.html了。。。


  1.             <p><tpl>$langUserStore</tpl>:<tpl> $shop_info.shop_name </tpl></p>
  2.             <p><tpl>$langMerchant</tpl>:<tpl> $seller_info.login_name </tpl></p>
  3.             <p><tpl>$langUserArea</tpl>:<tpl> $shop_info.shop_province </tpl></p>
复制代码


类似这种东东,用<tpl></tpl>标签类输出变量等。。。。

------------------------------------------------------------------------------------------------------------

C和V都讲了,只剩"M"了。。

[php]
  /**
   * 创建商品对象
   */
  if (!is_object($this->obj_product)){
   require_once("product.class.php");
   $this->obj_product = new ProductClass();
  }

...............................

   /**
    * 取得商品信息
    */
   $product_row = $this->obj_product->getProductRow($p_id);
[/php]

哈哈,看明白了吧。。这个“ProductClass”类就可以理解成M了。。它里面封装了很多product相关的业务逻辑。。。

好了,就简单写这么多吧。。。发帖子比看代码累多了。。。

最后赞一句,大白菜的产品的代码质量,规范等是看了这麽多产品中最好的一款了。。。

其中的权限控制,多语言,多模板都运用的相当不错。。。

特别是静态化方面,承载一定负载还是没问题的。。。

694

主题

36

好友

1万

积分

千象

叫我K兄好了

Rank: 16Rank: 16Rank: 16Rank: 16

威望
5514
开源币
293
注册时间
2007-12-7
积分
11786
帖子
3015
主题
694
UID
52443

第一颗象牙 第二颗象牙 第三颗象牙 第四颗象牙

3#
发表于 2009-7-1 04:24:44 |只看该作者

3、用户输入之检测

本帖最后由 kakashilw 于 2009-7-2 13:38 编辑

(1)前端

  1. <script language="JavaScript" type="text/javascript" src="<tpl> $site_url </tpl>/js/jquery/jquery.validate.js"></script>

  2. $(function(){
  3. $("#ownaddproduct").validate({
  4.   errorClass: "wrong",
  5.   rules: {
  6.    txtPname: {required:true},
  7.    txtPstorage: {
  8.     required:true,
  9.     number:true,
  10.     min: function(){
  11.       if($("#radioSelltype2").attr('checked')==true){
  12.        return 5;
  13.       }else{
  14.        return 1;
  15.       }
  16.      }
  17.    },
  18.    minimumBid: {
  19.     required: "#radioSelltype0:checked",
  20.     number: true,
  21.     min: function(){
  22.       if($("#radioSelltype0").attr('checked')==true){
  23.        return 0.01;
  24.       }else{
  25.        return 0;
  26.       }
  27.      }
  28.    },
  29.    price_step: {
  30.     required: "#radioSelltype0:checked",
  31.     number: true,
  32.     min: function(){
  33.      if($("#radioSelltype0").attr('checked')==true && $("#inc2").attr('checked')==true){
  34.       return 1;
  35.      }else{
  36.       return 0;
  37.      }
  38.     }
  39.    },
  40.    txtPprice: {required: "#radioSelltype1:checked",number: true,min: 0.01},
  41.    txtGroupprice: {required:"#radioSelltype2:checked",number:true,min: 0.01},
  42.    txtPoldprice: {required: "#radioSelltype2:checked",number: true,min: function(){return $("#txtGroupprice").val();}},
  43.    txtGroupmincount: {
  44.     required: "#radioSelltype2:checked",
  45.     number: true,
  46.     min: function(){
  47.      if($("#radioSelltype2").attr('checked')==true){
  48.       return 5;
  49.      }else{
  50.       return 0;
  51.      }
  52.     },
  53.     max:function(){
  54.      if($("#radioSelltype2").attr('checked')==true){
  55.       if($("#txtPstorage").val() >= 100){
  56.        return 100;
  57.       }else{
  58.        return $("#txtPstorage").val();
  59.       }
  60.      }else{
  61.       return 10000000;
  62.      }
  63.     }
  64.    },
  65.    area_id: {required: true},
  66.    pyTF: {
  67.     required: "#whopsBuyer:checked",
  68.     number: true,
  69.     min: function(){
  70.      if($("#whopsBuyer").attr('checked')==true){
  71.       return 1;
  72.      }else{
  73.       return 0;
  74.      }
  75.     }
  76.    },
  77.    kdTF: {
  78.     required: "#whopsBuyer:checked",
  79.     number: true,
  80.     min: function(){
  81.      if($("#whopsBuyer").attr('checked')==true){
  82.       return 1;
  83.      }else{
  84.       return 0;
  85.      }
  86.     }
  87.    },
  88.    emsTF: {
  89.     required: "#whopsBuyer:checked",
  90.     number: true,
  91.     min: function(){
  92.      if($("#whopsBuyer").attr('checked')==true){
  93.       return 1;
  94.      }else{
  95.       return 0;
  96.      }
  97.     }
  98.    },
  99.    slValiddays: {
  100.     required: true,
  101.     number: true,
  102.     min: 1,
  103.     max: 30
  104.    }
  105.   },
  106.   messages: {
  107.    txtPname: {required: "<tpl> $errProductNameEmpty </tpl>"},
  108.    txtPstorage: {
  109.     required: "<tpl> $errPstorage </tpl>",
  110.     number: "<tpl> $errPstorage </tpl>",
  111.     min: function(){
  112.      if($("#radioSelltype2").attr('checked')==true){
  113.       return "<tpl> $errPstorageByGroup </tpl>";
  114.      }else{
  115.       return "<tpl> $errPstorage </tpl>";
  116.      }
  117.     }
  118.    },
  119.    minimumBid: {required: "<tpl> $errMinimumbidWrong </tpl>",number: "<tpl> $errMinimumbidWrong </tpl>",min: "<tpl> $errMinimumbidWrong </tpl>"},
  120.    price_step: {required: "<tpl> $langProductAUserDefinedUppriceIsEmpty </tpl>",number: "<tpl> $langProductAUserDefinedUppriceIsEmpty </tpl>",min: "<tpl> $langProductAUserDefinedUppriceIsEmpty </tpl>"},
  121.    txtPprice: {required: "<tpl> $errPprice </tpl>",number: "<tpl> $errPprice </tpl>",min: "<tpl> $errPprice </tpl>"},
  122.    txtGroupprice: {required: "<tpl> $errGroupprice </tpl>",number: "<tpl> $errGroupprice </tpl>",min: "<tpl> $errGroupprice </tpl>"},
  123.    txtPoldprice: {required: "<tpl> $errPoldprice </tpl>",number: "<tpl> $errPoldprice </tpl>",min: "<tpl> $errPoldprice </tpl>"},
  124.    txtGroupmincount: {required: "<tpl> $errGroupmincount </tpl>",number: "<tpl> $errGroupmincount </tpl>",min:"<tpl> $errGroupmincount </tpl>",max:"<tpl> $errGroupmincount </tpl>"},
  125.    area_id: {required:"<tpl> $errProvince </tpl>"},
  126.    pyTF: {required: "<tpl> $langProductPyTFIsEmpty </tpl>",number: "<tpl> $langProductPyTFIsEmpty </tpl>",min: "<tpl> $langProductPyTFIsEmpty </tpl>"},
  127.    kdTF: {required: "<tpl> $langProductKdTFIsEmpty </tpl>",number: "<tpl> $langProductKdTFIsEmpty </tpl>",min: "<tpl> $langProductKdTFIsEmpty </tpl>"},
  128.    emsTF: {required: "<tpl> $langProductEMSTFIsEmpty </tpl>",number: "<tpl> $langProductEMSTFIsEmpty </tpl>",min: "<tpl> $langProductEMSTFIsEmpty </tpl>"},
  129.    slValiddays: {required: "<tpl> $errPSValiddays </tpl>",number: "<tpl> $errPSValiddays </tpl>",min: "<tpl> $errPSValiddays </tpl>",max: "<tpl> $errPSValiddays </tpl>"}
  130.   },
  131.   submitHandler: function() {
  132.    var check_sign = false;//货币选择状态标识
  133.    var payment_check = false;//支付方式选择状态标识
  134.    var predeposit_check = false;//预存款选择状态标识
  135.    var payment_alert_sign = false;//支付方式是否抛出错误信息标识
  136.    
  137.    //判断预存款选择状态
  138.    if($('#pay_predeposit').attr('checked') == true){
  139.     predeposit_check = true;
  140.    }
  141.    //验证支付方式的复选验证,是否全选,选中的支付方式是否选择了支付货币种类
  142.    $("#ownaddproduct input[@type=hidden]").each(function(){
  143.     if(this.name.indexOf('payment_cur_') == 0){
  144.      //判断支付方式是否被选择
  145.      str = this.name.split('payment_cur_');//取支付方式名称 str[1]
  146.      if($('#txtPayment_'+str[1]).attr('checked') == true){
  147.       //取该支付方式的货币种类字符串
  148.       str2 = $('#payment_cur_'+str[1]).val().split('|');
  149.       payment_check = true;//标识有选择的支付方式
  150.       //判断该选中的支付方式起码有一个支持的货币种类被选择
  151.       for(i=0;i<str2.length;i++){
  152.        if($('#currency_'+str2[i]).attr('checked') == true){
  153.         check_sign = true;
  154.         break;
  155.        }
  156.       }
  157.       if(check_sign == false){//没有选择货币
  158.        payment_alert_sign = true;
  159.       }
  160.      }
  161.     }
  162.     check_sign = false;
  163.    });
  164.    
  165.    if(predeposit_check == true){//选择预付款
  166.     if(payment_alert_sign == false){//判断是否有错误抛出:没有
  167.      var oEditor = FCKeditorAPI.GetInstance('txtPinfo');
  168.      $('#txtPinfo').val(oEditor.GetXHTML(true));
  169.      if($('#txtPinfo').val() != ''){
  170.       document.getElementById('ownaddproduct').submit();
  171.      }else{
  172.       alert('<tpl> $errPSInfoEmpty </tpl>');
  173.       return false;
  174.      }
  175.     }else{
  176.      alert('<tpl> $errPaymentSelCur </tpl>');
  177.      return false;
  178.     }
  179.    }else{//没有选择预存款
  180.     if(payment_alert_sign == false && payment_check == true){//判断是否有错误抛出并且选择了起码一种支付方式:没有
  181.      var oEditor = FCKeditorAPI.GetInstance('txtPinfo');
  182.      $('#txtPinfo').val(oEditor.GetXHTML(true));
  183.      if($('#txtPinfo').val() != ''){
  184.       document.getElementById('ownaddproduct').submit();
  185.      }else{
  186.       alert('<tpl> $errPSInfoEmpty </tpl>');
  187.       return false;
  188.      }
  189.     }else{
  190.      alert('<tpl> $errPaymentSelCur </tpl>');
  191.      return false;
  192.     }
  193.    }
  194.   }
  195. });
  196. });
复制代码


(2)后端
[php]
  $this->objvalidate->validateparam = array(
  array("input"=>$this->_input["txtPname"],"require"=>"true","message"=>$this->_lang['errPSNameEmpty']),
  array("input"=>$this->_input["slPCId"],"require"=>"true","message"=>$this->_lang['errPcidEmpty']),
  array("input"=>$this->_input["txtPinfo"],"require"=>"true","message"=>$this->_lang['errPSInfoEmpty']),
  array("input"=>$this->_input["radioSelltype"],"require"=>"true","validator"=>"Number","message"=>$this->_lang['errPSSelltype']),
  array("input"=>$this->_input["radioType"],"require"=>"true","validator"=>"Number","message"=>$this->_lang['errPSType']),
  array("input"=>$this->_input["txtPstorage"],"require"=>"true","validator"=>"Number","message"=>$this->_lang['errPSstorage']),
  //array("input"=>$this->_input["txtPprice"],"validator"=>"Currency","message"=>$this->_lang['errPSprice']),
  array("input"=>$this->_input["txtGroupprice"],"validator"=>"Currency","message"=>$this->_lang['errPSGroupprice']),
  array("input"=>$this->_input["txtPoldprice"],"validator"=>"Currency","message"=>$this->_lang['errPsPoldprice']),
  array("input"=>$this->_input["txtPoldprice"],"validator"=>"Compare","operator"=>">=","to"=>$this->_input["txtGroupprice"],"message"=>$this->_lang['errPSPriceNoGroupPrice']),
  array("input"=>$this->_input["txtGroupmincount"],"validator"=>"Number","message"=>$this->_lang['errPSGroupmincount']),
  array("input"=>$this->_input["area_id"],"require"=>"true","message"=>$this->_lang['errPProductAreaIsEmpty']),
  array("input"=>$this->_input["radioTransfee"],"require"=>"true","validator"=>"Number","message"=>$this->_lang['errPSTransfee']),
  array("input"=>$this->_input["radioInvoices"],"require"=>"true","validator"=>"Number","message"=>$this->_lang['errPSInvoices']),
  array("input"=>$this->_input["radioWarranty"],"require"=>"true","validator"=>"Number","message"=>$this->_lang['errPSWarranty']),
  array("input"=>$this->_input["slValiddays"],"require"=>"true","validator"=>"Number","message"=>$this->_lang['errPSValiddays']),
  array("input"=>$this->_input["chxAutopublish"],"validator"=>"Integer","message"=>$this->_lang['errPSAutopublish']),
  array("input"=>$this->_input["chxRecommended"],"validator"=>"Integer","message"=>$this->_lang['errPSRecommended']));
  $error = $this->objvalidate->validate();
  
  if($error != ""){
   $this->redirectPath("error","",$error);
  }
[/php]

694

主题

36

好友

1万

积分

千象

叫我K兄好了

Rank: 16Rank: 16Rank: 16Rank: 16

威望
5514
开源币
293
注册时间
2007-12-7
积分
11786
帖子
3015
主题
694
UID
52443

第一颗象牙 第二颗象牙 第三颗象牙 第四颗象牙

4#
发表于 2009-7-1 04:24:46 |只看该作者

SHOPNC的模板语言

本帖最后由 kakashilw 于 2009-7-3 01:06 编辑

这里就不研究原理了,看看用法吧

(1)if

  1. <tpl> if $search_header_sign eq '1' </tpl> class="current" <tpl> /if </tpl>
复制代码


(2)loop

  1.   <tpl> section name=i loop=$app </tpl>
  2.   <li><a href="<tpl> $app[i].url </tpl>"><tpl> $app[i].name </tpl></a></li>
  3.         <tpl> /section </tpl>
复制代码


(3)var
  1. <tpl> $site_url </tpl>
复制代码

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多