Discuz教程网

[二次开发] Discuz第三方DIY模块拓展类的开发

[复制链接]
authicon dly 发表于 2015-2-14 12:10:24 | 显示全部楼层 |阅读模式


内置PHP类扩展方式

脚本目录
source/class/block/[模块大分类目录] ,此目录需要自行创建
必需的脚本
source/class/block/[模块大分类目录]/blockclass.php, 此文件为该目录中必需存在的文件,其内容为:
  1. <?php
  2.         $blockclass = array(
  3.                 'name' => '模块大分类名', //为此目录定义一个名字
  4.         );
  5.         ?>
复制代码

source/class/block/[模块大分类目录]/block_name.php
注意:脚本文件名必需以 block_ 开头,且类名必需和文件名一样。
语言包位置(非必需)
source/language/block/lang_name.php
内容示例
source/class/block/[模块大分类目录]/block_name.php内容示例:
  1. <?php

  2. class block_name {

  3.         /**
  4.          * 必须!
  5.          * 返回本数据调用类的显示名称(显示在创建模块时选择“模块数据”的下拉列表里)
  6.          * @return <type>
  7.          */
  8.         function name() {
  9.                 return '示例数据类';
  10.         }

  11.         /**
  12.          * 必须!
  13.          * 返回一个数组: 第一个值为本数据类所在的模块分类;第二个值为模块分类显示的名称(显示在 DIY 模块面板)
  14.          * @return <type>
  15.          */
  16.         function blockclass() {
  17.                 return array('sample', '示例分类');
  18.         }

  19.         /**
  20.          * 必须!
  21.          * 返回数据类中可供“模块样式”使用的字段。
  22.          * 格式见示例:
  23.          * name 为该字段的显示名称
  24.          * formtype 决定编辑单条数据时该字段的显示方式: 类型有: text, textarea, date, title, summary, pic; 详见 portalcp_block.htm 模板(搜 $field[formtype] )
  25.          * datatype 决定该字段的数据展示,类型有: string, int, date, title, summary, pic; 详见 function_block.php 中 block_template 函数
  26.          * @return <type>
  27.          */
  28.         function fields() {
  29.                 return array(
  30.                         'field1' => array('name' => '示例字段1', 'formtype' => 'text', 'datatype' => 'string'),
  31.                         'field2' => array('name' => '示例字段2', 'formtype' => 'title', 'datatype' => 'title'),
  32.                 );
  33.         }

  34.         /**
  35.          * 必须!
  36.          * 返回使用本数据类调用数据时的设置项
  37.          * 格式见示例:
  38.          * title 为显示的名称
  39.          * type 为表单类型, 有: text, password, number, textarea, radio, select, mselect, mradio, mcheckbox, calendar; 详见 function_block.php 中 block_makeform() 函数
  40.          * @return <type>
  41.          */
  42.         function getsetting() {
  43.                 return array(
  44.                         'param1' => array(
  45.                                 'title' => '数据调用参数1',
  46.                                 'type' => 'text',
  47.                                 'default' => ''
  48.                         ),
  49.                         'param2' => array(
  50.                                 'title' => '数据调用参数2',
  51.                                 'type' => 'mcheckbox',
  52.                                 'value' => array(
  53.                                         array('1', '选项1'),
  54.                                         array('2', '选项2'),
  55.                                 ),
  56.                                 'default' => '1'
  57.                         ),
  58.                 );
  59.         }

  60.         /**
  61.          * 必须!
  62.          * 处理设置参数,返回数据
  63.          * 返回数据有两种:
  64.          * 一种是返回 html,放到模块 summary 字段,直接显示; 返回格式为: array('html'=>'返回内容', 'data'=>null)
  65.          * 一种是返回 data,通过模块样式渲染后展示,返回的数据应该包含 fields() 函数中指定的所有字段; 返回格式为: array('html'=>'', 'data'=>array(array('title'=>'value1'), array('title'=>'value2')))
  66.          * 特别的:
  67.          * parameter 参数包含 getsetting() 提交后的内容; 并附加了字段:
  68.          * items ,为用户指定显示的模块数据条数;
  69.          * bannedids ,为用户选择屏蔽某数据时记录在模块中的该数据 id。 应该在获取数据时屏蔽该数据;
  70.          *
  71.          * 如果返回的数据给 data, 那么应该包含 fields() 函数指定的所有字段。并附加以下字段:
  72.          * id 标志该数据的 id,如果用户屏蔽某数据时,会将该数据的 id 添加到 parameter[bannedids] 里
  73.          * idtype 标志该数据的 idtype
  74.          *
  75.          * @param <type> $style 模块样式(见 common_block_style 表)。 可以根据模块样式中用到的字段来选择性的获取/不获取某些数据
  76.          * @param <type> $parameter 用户对 getsetting() 给出的表单提交后的内容。
  77.          * @return <type>
  78.          */
  79.         function getdata($style, $parameter) {

  80.                 // 返回summary
  81.                 return array('html' => '<p>这是一个演示模块数据类</p>', 'data' => null);

  82.                 // 返回数据
  83.                 // 需要注意: 除 id,idtype, title, url, pic, picflag, summary 几个字段外,其它字段需要放到 fields 数组里。 可以参考系统内置模块类 source/class/block/block_thread.php
  84.                 return array('html'=>'', 'data' => array(
  85.                         array(
  86.                                 'id' => '1',
  87.                                 'idtype' => 'sampleid',
  88.                                 'title' => 'title1',
  89.                                 'url' => '#',
  90.                                 'pic' => 'nophoto.gif',
  91.                                 'picflag' => '1',
  92.                                 'summary' => '',
  93.                                 'fields' => array(
  94.                                         'field1' => 'value1'
  95.                                 )
  96.                         )
  97.                 ));
  98.         }

  99. }

  100. ?>
复制代码

第三方 C/S 扩展方式

此扩展方式需要第三方提供一个服务端应用程序接口,为使用该服务的客户端提供数据。
服务端提供的数据必需为 XML 格式的数据,具体的 XML 规范请参考下面的详细说明。
XML 规范
配置规范

请示方式
客户端以 GET 的方式向服务器端提交以下参数请求此 XML 文档
  1. op=getconfig,此参数表示客户端要请求配置文档;
  2. clientid,客户端ID(服务器分配给客户端的ID);
  3. charset,客户端的数据编码
  4. sign=签名,如果服务器端没有设置通信密钥则此值为空,如果服务器端不使用签名则此值为通信密钥;签名机制
复制代码

规范内容包括Title和Data部分
Title部分
此部分是固定的代码且区分大小写
  1. <item id="Title"><![CDATA[Discuz! Block]]></item>
复制代码

Data部分
主要包括5个属性
  1. version 版本号(必需)
  2. name 模块名(必需)
  3. fields 可显示的字段,在模块样式中使用(必需)包括以下内容
  4.    name 为该字段的显示名称
  5.    formtype 决定编辑单条数据时该字段的显示方式: 类型有: text, textarea, date, title, summary, pic;
  6.    datatype 决定该字段的数据展示,类型有: string, int, date, title, summary, pic;
  7. getsetting 可设置和接收的参数(必需),包括以下内容
  8.    title 为显示的名称
  9.    type 为表单类型, 有: text, password, number, textarea, radio, select, mselect, mradio, mcheckbox, calendar;
  10. style 内置的显示样式(非必需)
复制代码

配置规范 XML 文档示例如下
  1. <?xml version="1.0" encoding="ISO-8859-1"?>
  2. <root>
  3.         <item id="Title"><![CDATA[Discuz! Block]]></item>
  4.         <item id="Data">
  5.                 <item id="version"><![CDATA[X1.5]]></item>
  6.                 <item id="name"><![CDATA[C/S 数据类]]></item>
  7.                 <item id="fields">
  8.                         <item id="url">
  9.                                 <item id="name"><![CDATA[链接地址]]></item>
  10.                                 <item id="formtype"><![CDATA[text]]></item>
  11.                                 <item id="datatype"><![CDATA[string]]></item>
  12.                         </item>
  13.                         <item id="title">
  14.                                 <item id="name"><![CDATA[标题]]></item>
  15.                                 <item id="formtype"><![CDATA[title]]></item>
  16.                                 <item id="datatype"><![CDATA[title]]></item>
  17.                         </item>
  18.                         <item id="pic">
  19.                                 <item id="name"><![CDATA[图片]]></item>
  20.                                 <item id="formtype"><![CDATA[pic]]></item>
  21.                                 <item id="datatype"><![CDATA[pic]]></item>
  22.                         </item>
  23.                         <item id="summary">
  24.                                 <item id="name"><![CDATA[简介]]></item>
  25.                                 <item id="formtype"><![CDATA[summary]]></item>
  26.                                 <item id="datatype"><![CDATA[summary]]></item>
  27.                         </item>
  28.                         <item id="author">
  29.                                 <item id="name"><![CDATA[作者]]></item>
  30.                                 <item id="formtype"><![CDATA[text]]></item>
  31.                                 <item id="datatype"><![CDATA[text]]></item>
  32.                         </item>
  33.                         <item id="authorid">
  34.                                 <item id="name"><![CDATA[作者ID]]></item>
  35.                                 <item id="formtype"><![CDATA[text]]></item>
  36.                                 <item id="datatype"><![CDATA[int]]></item>
  37.                         </item>
  38.                         <item id="field1">
  39.                                 <item id="name"><![CDATA[字段1]]></item>
  40.                                 <item id="formtype"><![CDATA[text]]></item>
  41.                                 <item id="datatype"><![CDATA[string]]></item>
  42.                         </item>
  43.                         <item id="field2">
  44.                                 <item id="name"><![CDATA[字段2]]></item>
  45.                                 <item id="formtype"><![CDATA[title]]></item>
  46.                                 <item id="datatype"><![CDATA[title]]></item>
  47.                         </item>
  48.                 </item>
  49.                 <item id="getsetting">
  50.                         <item id="param1">
  51.                                 <item id="title"><![CDATA[数据调用参数1]]></item>
  52.                                 <item id="type"><![CDATA[text]]></item>
  53.                                 <item id="default"><![CDATA[]]></item>
  54.                         </item>
  55.                         <item id="param2">
  56.                                 <item id="title"><![CDATA[数据调用参数2]]></item>
  57.                                 <item id="type"><![CDATA[mcheckbox]]></item>
  58.                                 <item id="value">
  59.                                         <item id="0">
  60.                                                 <item id="0"><![CDATA[1]]></item>
  61.                                                 <item id="1"><![CDATA[选项1]]></item>
  62.                                         </item>
  63.                                         <item id="1">
  64.                                                 <item id="0"><![CDATA[2]]></item>
  65.                                                 <item id="1"><![CDATA[选项2]]></item>
  66.                                         </item>
  67.                                 </item>
  68.                                 <item id="default"><![CDATA[1]]></item>
  69.                         </item>
  70.                         <item id="start">
  71.                                 <item id="title"><![CDATA[起始数据行数]]></item>
  72.                                 <item id="type"><![CDATA[text]]></item>
  73.                                 <item id="default"><![CDATA[0]]></item>
  74.                         </item>
  75.                 </item>
  76.                 <item id="style">
  77.                         <item id="0">
  78.                                 <item id="name"><![CDATA[模板名称]]></item>
  79.                                 <item id="template"><![CDATA[<div class="module cl xl xl1"><ul>[loop]<li><em><a href="home.php?uid={authorid}"><FONT COLOR="RED">{author}</FONT></a></em><a href="{url}">{title}</a></li>[/loop]</ul></div>]]></item>
  80.                         </item>
  81.                         <item id="1">
  82.                                 <item id="name"><![CDATA[模板名称红色]]></item>
  83.                                 <item id="template"><![CDATA[<div class="module cl xl xl1"><ul>[loop]<li><em><font color="red"><a href="home.php?uid={authorid}">{author}</a></font></em><a href="{url}">{title}</a></li>[/loop]</ul></div>]]></item>
  84.                         </item>
  85.                 </item>
  86.         </item>
  87. </root>
复制代码

数据规范
数据规范分为数据列表和HTML代码
数据列表格式
客户端在请求数据时以 POST 的方式提交客户端设置的参数值,参数值包括在配置规范中可设置和接收的参数 getsetting 指定的所有字段,除了设置的参数外,系统会以 POST 的方式追加以下参数:
  1. * op=getdata ,此参数表示客户端要请求数据;
  2. * clientid ,客户端ID(服务器分配给客户端的ID);
  3. * op=getdata ,此参数表示客户端要请求数据;
  4. * items ,为用户指定显示的模块数据条数;
  5. * bannedids ,为用户选择屏蔽某数据时记录在模块中的该数据 id,多个 id 以半角分号(,)分隔。 应该在获取数据时屏蔽该数据;
  6. * charset,客户端的数据编码
  7. * sign ,数据签名,如果服务器端没有设置通信密钥则此值为空,如果服务器端不使用签名则此值为通信密钥;签名机制
  8. 服务器端返回数据的 data 中应该包含 配置规范中可显示的字段 fields 指定的所有字段。并附加以下字段:
  9. * id 标志该数据的 id,如果用户屏蔽某数据时,会将该数据的 id 以 POST 的方式变量名为 bannedids,多个id以半角逗号(,)分隔提交到服务器端
  10. * picflag 如果有图片,则该值标志图片的类型,0 为 url、1 为本地、2 为 ftp 远程;如果图片是 Discuz! X 系统中的图片可以情况设置为 1 或 2,其它情况为 0
  11. 需要注意: 除 id,title, url, pic, picflag, summary 几个字段外,其它字段需要放到 fields 数组里。
复制代码

数据列表格式示例
  1. <?xml version="1.0" encoding="ISO-8859-1"?>
  2. <root>
  3.         <item id="html"><![CDATA[]]></item>
  4.         <item id="data">
  5.                 <item id="0">
  6.                         <item id="id"><![CDATA[14]]></item>
  7.                         <item id="title"><![CDATA[xml_block_title14]]></item>
  8.                         <item id="url"><![CDATA[xml_server.php]]></item>
  9.                         <item id="pic"><![CDATA[nophoto.gif]]></item>
  10.                         <item id="picflag"><![CDATA[1]]></item>
  11.                         <item id="summary"><![CDATA[]]></item>
  12.                         <item id="fields">
  13.                                 <item id="author"><![CDATA[xml_user14]]></item>
  14.                                 <item id="authorid"><![CDATA[14]]></item>
  15.                                 <item id="field1"><![CDATA[field1value14]]></item>
  16.                                 <item id="field2"><![CDATA[field2value14]]></item>
  17.                         </item>
  18.                 </item>
  19.                 <item id="1">
  20.                         <item id="id"><![CDATA[15]]></item>
  21.                         <item id="title"><![CDATA[xml_block_title15]]></item>
  22.                         <item id="url"><![CDATA[xml_server.php]]></item>
  23.                         <item id="pic"><![CDATA[nophoto.gif]]></item>
  24.                         <item id="picflag"><![CDATA[1]]></item>
  25.                         <item id="summary"><![CDATA[]]></item>
  26.                         <item id="fields">
  27.                                 <item id="author"><![CDATA[xml_user15]]></item>
  28.                                 <item id="authorid"><![CDATA[15]]></item>
  29.                                 <item id="field1"><![CDATA[field1value15]]></item>
  30.                                 <item id="field2"><![CDATA[field2value15]]></item>
  31.                         </item>
  32.                 </item>
  33.         </item>
  34. </root>
复制代码

HTML 代码格式
例示
  1. <?xml version="1.0" encoding="ISO-8859-1"?>
  2. <root>
  3.         <item id="html"><![CDATA[<div style="border:1px solid red;width:100px; height: 100px;">HTML CODE</div>]]></item>
  4.         <item id="data"><![CDATA[]]></item>
  5. </root>
复制代码

服务端应用程序接口示例
以下提供一个 PHP 版本的程序示例:
  1. <?php

  2. define('CHARSET', 'GBK'); //服务器端数据编码
  3. require './source/class/class_xml.php'; //XML格式的文档和array的相互转换的类
  4. error_reporting(7);

  5. $charset = $_GET['charset'] ? $_GET['charset'] : $_POST['charset']; //客户端数据编码
  6. //数据转码
  7. if(strtoupper($charset) != CHARSET) {
  8.         foreach($POST as $key => $value) {
  9.                 $POST[$key] = iconv($charset, CHARSET, $value);
  10.         }
  11.         foreach($GET as $key => $value) {
  12.                 $GET[$key] = iconv($charset, CHARSET, $value);
  13.         }
  14. }

  15. $data = array('html'=>'', 'data'=>''); //初始化要返回数据
  16. $sign = $_GET['sign'] ? $_GET['sign'] : $_POST['sign']; //获取客户端请求数据的签名
  17. $clientid = $_GET['clientid'] ? $_GET['clientid'] : $_POST['clientid']; //客户端ID

  18. $client = get_client_by_clientid($clientid); //得到客户端的相关信息
  19. if(empty($client)) { //客户端不存在
  20.         exit('CLIENT_NOT_EXISTS'); //直接返回失败
  21. }

  22. $datasign = ''; //数据签名
  23. if(!empty($_POST)) {
  24.         unset($_POST['sign']); //删除签名参数,此参数不参加签名计算
  25.         $datasign = get_sign($_POST, $client['key']); //计算数据的签名
  26. } else {
  27.         unset($_GET['sign']); //删除签名参数,此参数不参加签名计算
  28.         $datasign = get_sign($_GET, $client['key']); //计算数据的签名
  29. }

  30. if($datasign != $sign) { //签名不正确
  31.         exit('SIGN_ERROR'); //输入签名错误
  32. }

  33. if($_POST['op'] == 'getdata') { //判断是否为请求数据列表
  34.         $datalist = $data = array();//数据列表
  35.         $wherearr = array(); //SQL 条件数组

  36.         //获取客户端POST参数
  37.         $start = intval($_POST['start']); //起始数据行数
  38.         $limit = intval($_POST['items']); //要显示多少条数
  39.         $bannedids = addslashes($_POST['bannedids']); //客户端屏蔽的IDS
  40.         $param1 = addslashes($_POST['param1']); //数据调用参数1,假设此值要求为string型
  41.         $param2 = intval($_POST['param2']); //数据调用参数2,假设此值要求为int型

  42.         //处理参数1
  43.         if(!empty($param1)){
  44.                 $wherearr[] = "fieldsparam1='$param1'";
  45.         }
  46.         //处理参数2
  47.         if(!empty($param2)) {
  48.                 $wherearr[] = "fieldsparam2='$param2'";
  49.         }
  50.         //处理客户端屏蔽的IDS
  51.         if(!empty($bannedids)) {
  52.                 $banids = explode(',', $bannedids);
  53.                 $wherearr[] = "csid NOT IN (".implode("','", $banids)."')";
  54.         }
  55.         $where = !empty($wherearr) ? 'WHERE '.implode(' AND ', $wherearr) : ''; //构造条件
  56.         /*数据库相关处理
  57.         $query = DB::query('SELECT * FROM '.DB::table('tablename')." $where LIMIT $start, $limit"); //SQL查询
  58.         while($value = DB::fetch($query)) {
  59.                 //此处为数据处理逻辑代码
  60.                 $data[] = $value;
  61.         }
  62.          */

  63.         //以下为临时测试数据,正式环境请根据自己的业务做相关调整
  64.         $url = 'http://www.xxx.com/';
  65.         $data = range($start, $start + $limit);//构造临时的假数据
  66.         foreach($data as $value) {
  67.                 //需要注意: 除 id, title, url, pic, picflag, summary 几个字段外,其它字段需要放到 fields 数组里。
  68.                 $datalist[] = array(
  69.                         'id' => $value,
  70.                         'title' => 'xml_block_title'.$value, //标题
  71.                         'url' => $url.'xml_server.php?csid='.$value, //链接地址
  72.                         'pic' => $url.'/data/attachment/photo.gif', //图片地址
  73.                         'picflag' => '0', //0为url 1为本地 2 为ftp远程;如果图片是DX系统中的图片可以情况设置为1或2,其它情况为0
  74.                         'summary' => '', //简介
  75.                         'fields' => array( //配置规范中fields中指定的字段
  76.                                 'author' => 'xml_user'.$value,
  77.                                 'authorid' => $value,
  78.                                 'field1' => 'field1value'.$value,
  79.                                 'field2' => 'field2value'.$value
  80.                         )
  81.                 );
  82.         }
  83.         $data['data'] = $datalist;

  84.         //如果要返回HTML代码,可直接使用以下代码
  85.         //$data['html'] = 'HTML CODE';
  86.         $xml = array2xml($data); //转换为XML文档
  87. } else if($_GET['op'] == 'getconfig') {
  88.         $xml = file_get_contents('block_xml_sample.xml');//block_xml_sample.xml文件中的内容为 配置规范XML文档示例 的内容
  89. } else {
  90.         $xml = 'NO_OPERATION';
  91. }
  92. ob_end_clean();
  93. @header("Expires: -1");
  94. @header("Cache-Control: no-store, private, post-check=0, pre-check=0, max-age=0", FALSE);
  95. @header("Pragma: no-cache");
  96. header("Content-type: text/xml");
  97. echo $xml;
  98. exit();

  99. /**
  100. * 获得客户端信息
  101. * @param  $clientid
  102. * @return array 客户端信息数组
  103. */
  104. function get_client_by_clientid($clientid){
  105.         $client = array();
  106.         $clientid = intval($clientid);
  107.         if($clientid) {

  108.                 /*数据库相关处理
  109.                 $client = DB::fetch_first('SELECT * FROM '.DB::table('clienttable')." clientid='$clientid'"); //SQL查询
  110.                  */

  111.                 //以下为临时测试数据,正式环境请根据自己的业务做相关调整
  112.                 //模拟数据库
  113.                 $CLIENTSDB = array(
  114.                         '100000' => array(
  115.                                 'clientid' => '100000',
  116.                                 'key' => '*654%#(asd94',
  117.                         ),
  118.                         '200000' => array(
  119.                                 'clientid' => '200000',
  120.                                 'key' => '1#9!(@@34#94',
  121.                         ),
  122.                         '300000' => array(
  123.                                 'clientid' => '300000',
  124.                                 'key' => '7$@^8^$7as89',
  125.                         ),
  126.                         '400000' => array(
  127.                                 'clientid' => '400000',
  128.                                 'key' => '23@#86^%4&32',
  129.                         ),
  130.                 );
  131.                 $client = isset($CLIENTSDB[$clientid]) ? $CLIENTSDB[$clientid] : array();
  132.         }
  133.         return $client;
  134. }


  135. /**
  136. * 生成签名
  137. * @param array $para 参数数组
  138. * @param string $key 加密密钥
  139. * @return string 签名
  140. */
  141. function get_sign($para, $key = ''){
  142.         ksort($para);
  143.         $signarr = array();
  144.         foreach($para as $k => $v) {
  145.                 $signarr[] = $k.'='.$v;
  146.         }
  147.         $sign = implode('&', $signarr);
  148.         $sign = md5($sign.$key);
  149.         return $sign;
  150. }
  151. ?>
复制代码

签名机制
计算方法
待签名数据 + 通信密钥(服务器端提供给客户端的通信密钥)的MD5值作为签名。
所有HTTP请求中传递的参数(除sign外)按照参数名称字符升序的顺序串联起来(例如:k1=v1&k2=v2&k3=v3),构成待签名数据。
例如:请求配置文档需要以下参数:
  1. op=getconfig
  2. clientid=10000
  3. charset=utf-8
  4. 那么待签名数据就是:clientid=10000&op=getconfig&charset=utf-8。
复制代码

签名注意事项:
无论参数是否有值,只要在请示中传递即包含到待签名数据中。
根据 HTTP 协议要求,传递参数的值中如果存在特殊字符(如:&、@等),那么该值需要做 URL Encoding,这样请求接受方才能接受到正确的参数值。这种情况下,做签名时使用的应该是原生值而不是 encoding 之后的值。



上一篇:discuz第三方模块使用教程
下一篇:注册.TT域名,网站天天看!还有更多未被注册数字域名推荐!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

1314学习网 ( 浙ICP备10214163号 )

GMT+8, 2024-5-19 10:33

Powered by Discuz! X3.4

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表