Discuz教程网

[二次开发] discuz x1.5中 后台管理--门户中的“制作专题”的功能扩展--调用外部网站的数据(二)

[复制链接]
authicon dly 发表于 2014-11-12 16:58:10 | 显示全部楼层 |阅读模式
discuz x1.5 DIY首页, 在首页使用DIY功能,调用其他网站的模块的数据。


上文分析到:

在源文件中搜索“contentblockclass_nav ” 找到了 文件 template\default\portal\portalcp_diy.htm

<div class="tbmu mbm" id="contentblockclass_nav" style="margin-top: -15px">

<!--{loop $_G['cache']['blockclass'] $key $value}-->
<a href="javascript:;" id="bcnav_$key" class="a" onclick="spaceDiy.switchBlockclass('$key');return false;">$value[name]</a>




$key = html  group  space member forum

$value[name] = 展示类 | 群组类 | 门户类 | 咨询站文章类 | 空间类 | 会员类 | 论坛类


通过以上代码,我们得知 要找到  $_G['cache']['blockclass'] 的定义/赋值;

function block_getclass($classname, $getstyle=false) {   // 例如  $calssname = forum_thread
global $_G;
if(!isset($_G['cache']['blockclass'])) {
loadcache('blockclass');
}
$theclass = array();
list($c1, $c2) = explode('_', $classname);// $c1=forum  $c2=thread  $calssname=forum_thread

if(is_array($_G['cache']['blockclass']) && isset($_G['cache']['blockclass'][$c1]['subs'][$classname])) {
$theclass = $_G['cache']['blockclass'][$c1]['subs'][$classname]; // 一个数组 // $_G['cache']['blockclass'][forum]['subs'][forum_thread

if($getstyle && !isset($theclass['style']))  // $getstyle=true  才有可能 对cache赋值
{
$query = DB::query('SELECT * FROM '.DB::table('common_block_style')." WHERE blockclass='$classname'");   // 'common_block_style'表结构分析
    while(($value=DB::fetch($query)))
    {
        $value['template'] = !empty($value['template']) ? (array)(unserialize($value['template'])) : array();
        $value['fields'] = !empty($value['fields']) ? (array)(unserialize($value['fields'])) : array();
        $key = 'blockstyle_'.$value['styleid'];
        $_G[$key] = $value;
        $theclass['style'][$value['styleid']] = $value;
    }
$_G['cache']['blockclass'][$c1]['subs'][$classname] = $theclass;   // 赋值的地方   
// $c1 -- 对应的$key   
// 'subs' == -- 对应的$value   
// $_G['cache']['blockclass'][$c1]['subs'][name] = 展示类  群组类

}
}
return $theclass;
}




再查找那些地方调用了这个函数呢?   
还有 就是 在那些文件中包括了 “展示类 | 群组类 | 门户类 | 咨询站文章类 | 空间类 | 会员类 | 论坛类  ” 的这些文字呢?



在全部源代码中搜索“展示类”,中文定义在  source\language\lang_blockclass.php
'blockclass_group' => '群组类',  



那么查找下 'blockclass_group'  在那里使用/调用了?
在全部源代码中搜索“展示类”,在 source\class\block\group\blockclass.php中使用。


$blockclass = array(
'name' => lang('blockclass', 'blockclass_group'),

);



搜索 其他词,“展示类 | 群组类 | 门户类 | 咨询站文章类 | 空间类 | 会员类 | 论坛类  ” ,都在 blockclass.php中,
只是 这些 blockclass.php在不同的文件夹下,但是在 同一个source\class\block\目录下

目录中有 article 、forum 、group 、html 、member 、portal 、space 分别对应了,“展示类 | 群组类 | 门户类 | 空间类 | 会员类 | 论坛类  ”;

文件中都包含了类似的多个文件:block_****.php

都包含了这个文件 blockclass.php(必须有的文件)
blockclass.php文件内容:
<?php

$blockclass = array(
'name' => lang('blockclass', 'blockclass_****'),

);


?>




要想再扩展一个类似的 ×××类, 我们应该在source\class\block\目录下 新建一个文件夹,文件里里的必须有一个文件叫 blockclass.php,
然后有一些其他文件,block_****.php(必须有的文件)



我们去全部代码中搜索“class/block”  注意,在liunx下 路径要做个 转义符 就是 “class\block” 变为 “class/block” 了。

function blockclass_cache() {
global $_G;
$data = $dirs = $styles = $dataconvert = array();
$dir = DISCUZ_ROOT.'/source/class/block/';
$dh = opendir($dir);  // 循环遍历文件夹下的文件

while(($filename=readdir($dh))) {
if(is_dir($dir.$filename) && substr($filename,0,1) != '.') {
    $dirs[$filename] = $dir.$filename.'/';
}
}



foreach($dirs as $name=>$dir) {
$blockclass = $blockconvert = array();
if(file_exists($dir.'blockclass.php')) {
include_once($dir.'blockclass.php');    /// 加载了  文件夹下的 blockclass.php文件
}



$dh = opendir($dir);  // 再次打开文件夹
while(($filename=readdir($dh))) {   // 循环遍历文件
$match = $info = $fieldsconvert = array();
$scriptname = $scriptclass = '';
if(preg_match('/^(block_[\w]+)\.php$/i', $filename, $match)) {   // 正则表达式 匹配文件  block_*****.php
$scriptclass = $match[1];
$scriptname = preg_replace('/^block_/i', '', $scriptclass);
include_once $dir.$filename;   // 循环 把其他文件也都加载了进来   例如  source\class\block\group\block_group.php  block_groupnew.php
if(class_exists($scriptclass)) {
$obj = new $scriptclass();   ///  实例化了 类的对象

if(method_exists($obj, 'name') && method_exists($obj, 'blockclass') && method_exists($obj, 'fields')
&& method_exists($obj, 'getsetting') && method_exists($obj, 'getdata')) {  
//  实例化的对象,必须包括这些函数/方法 例如 : 'name','blockclass','fields','getsetting','getdata'  我们新做的扩展类中,必须包括这些函数/方法
$info['name'] = $obj->name();
$info['blockclass'] = $obj->blockclass();
$info['fields'] = $obj->fields();
}



我们也要在全部代码中 ,搜索下 那些程序中调用了这个函数blockclass_cache()呢?

搜索的结果:有两处调用。
1. soucre\admincp\admincp_tools.php  是在管理员 使用 “更新缓存”的菜单时调用的,不太符合我们的逻辑。
2.  soucre\module\misc\misc_initsys.php 从文件名称中 大概判断为 initsys  系统初始化时 调用执行了此函数。

soucre\module\misc\misc_initsys.php的文件内容:

require_once libfile('function/cache');
updatecache();


require_once libfile('function/block');
blockclass_cache();


if($_G['config']['output']['tplrefresh']) {
$tpl = dir(DISCUZ_ROOT.'./data/template');
while($entry = $tpl->read()) {
if(preg_match("/\.tpl\.php$/", $entry)) {
@unlink(DISCUZ_ROOT.'./data/template/'.$entry);
}
}
$tpl->close();
}





下边 ,我们分析下  实例化后的 block_member

class block_member {  //  必须有个类的定义

function name() {   // //数据来源 下拉框  内容显示   例如:blockclass_member_script_member  ---  高级自定义, 我们要扩展的就可以直接为 “启德咨询站 ”
return lang('blockclass', 'blockclass_member_script_member');
}


function blockclass() { // // DIY时的 “模块”的一级菜单, “模块”的 二级菜单显示文字
return array('member', lang('blockclass', 'blockclass_member_member'));  //  'blockclass_member_member' => '会员模块',
}



/**
* 返回数据类中可供“模块模板”使用的字段
* 格式见示例:
* name 为该字段的显示名称
* formtype 决定编辑单条数据时该字段的显示方式: 类型有: text, textarea, date, title, summary, pic; 详见 portalcp_block.htm 模板(搜 $field[formtype] )
* datatype 决定该字段的数据展示,类型有: string, int, date, title, summary, pic; 详见 function_block.php 中 block_template 函数
* @return <type>
*/

function fields() {  // 取得数据后,对应的字段分析
global $_G;

}


/**
* 返回使用本数据类调用数据时的设置项
* 格式见示例:
* title 为显示的名称
* type 为表单类型, 有: text, password, number, textarea, radio, select, mselect, mradio, mcheckbox, calendar; 详见 function_block.php 中 block_makeform() 函数
* @return <type>
*/

function getsetting() {   // 取得在获取数据时的一些条件设置   例如显示多少条数据? 显示时间啊?
}


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

function getdata($style, $parameter) { // 取得数据的接口
return array('html' => '', 'data' => null);
}



}





===================================================================

要在discuz x1.5中,DIY功能中扩展功能模块/数据模块,我们必须要做的事情/步骤


1. 在 source\class\block\建立一个文件 例如: eiccms 文件(我们用来调用[size=+0]http://www.eic.org.cn
的网站的资讯类数据;文章标题和链接等信息)

2. 在 eiccms文件里 必须包括文件1:blockclass.php

必须包括一个文件:block_eiccms.php 定义一个类 为   class block_eiccms {}

3.  在block_eiccms类中,实现 以下方法:'name','blockclass','fields','getsetting','getdata'

包括了 设置显示的汉字, 包括模板模块中的数据字段,包括取的数据时的条件设置; 包括取出数据的方法(可以直接连接数据库取得数据,也可以使用调用数据接口-http/xml来获取数据)


4. 就可以调试功能了, 这时,每次的调试 都需要“更新缓存”  ,然我们不断的调试就可以实现了。






====================================================================



发现 在调用这些函数的地方都有查询数据库的操作: common_block 这个数据表就很关键了



$query = DB::query("SELECT b.*, tb.targettplname FROM ".DB::table('common_block')." b LEFT JOIN ".DB::table('common_template_block')." tb ON b.bid=tb.bid WHERE $wheresql $ordersql LIMIT $start,$perpage");




common_block 这个数据表  字段分析:  --- 对应这个表的操作 对应管理后台管理后台 --- 门户 --- 模块管理 (在DIY设置模块的参数,例如显示几条/显示什么格式样式/标题等信息) :

blockclass  --- 是数据块/模块的名称
例如:
portal_article  portal_topic
forum_thread  forum_attachment  
space_blog
group_thread  group_group



name  模块的名称/标识

title  模块的标题

uid username   编辑人的一些信息


picwidth picheight target   图片的一些设置信息


dateformat dateuformat 时间日期格式

param 一些参数设置 序列化数据存储

shownum 显示几条信息

cachetime  缓存时间



common_block_style 这个数据表  字段分析:   --- 对这个数据库表的操作在管理后台体现在: 后台管理 ---- 门户 ---- 模块模板(这个管理功能中):

blockclass   :  html_html  forum_forum   forum_attachment

name   :   [X1.5]版块名称列表      [X1.5]版块名称+总帖数     [X1.5]版块名称+总帖数(有序)    [X1.5]版块名称+今日发贴数   [X1.5]版块名称+今日发贴数(有序)

template  :  [size=+0]模块的HTML代码





在 使用discuz管理后台 -- 门户  --- 模块模板/模块管理 这个功能时,

有“模块模板 -  添加”模块模板时,首先要需要“选择模块分类”
有“模块管理  - 数据调用”时, 首先也要选择“模块分类”
----- 我们要分析 这个模块分类和我们使用DIY时的模块分类是不是一样的呢?



分析 “模块模板 -  添加” 的  “选择模块分类”

管理URL是 : http://bbs.dragonchen82.com/admin.php?action=blockstyle

根据 discuz的名称规则, 应该在  soucre\admincp\admincp_blockstyle.php

( discuz x1.5的文件对应规则 ,可查看 文章:“discuz x1.5的 管理后台逻辑分析  admin.php 逻辑分析 ”http://ggmmchou.blog.163.com/blog/static/593331492011444387769/     )






下边分析:admincp_blockstyle.php  


if($operation=='add' || $operation=='edit')  { // 添加/编辑}
elseif($operation=='delete')  { //删除 }
else{ //显示页面

$blockclass_sel = '<select name="blockclass">';  // 通过HTML页面的代码中的 select的名字,在这个文件中找到了位置
$blockclass_sel .= '<option value="">'.cplang('blockstyle_blockclass_sel').'</option>';
foreach($_G['cache']['blockclass'] as $key=>$value) {


}

仍然是 对 $_G['cache']['blockclass'] 的一个循环显示处理。 还得分析 $_G['cache']['blockclass'] 里的内容/值是什么? 在那里赋值的?

又回到了 我们 跟踪的 function_block.php 文件中 对$_G['cache']['blockclass'] 的赋值 :

function block_getclass($classname, $getstyle=false) { }  --- 回到了原来的思路上,看来我们得从上一点上 重新分析下思路。




discuz的后台 --- 模块管理 --列表中  的  编辑“属性”
http://bbs.eic.org.cn/portal.php?mod=portalcp&ac=block&op=block&bid=270&from=cp
这个地址 就是 对模块的设置的页面。 --- -- 这个也没有大的帮助,仍然无法找到 如何扩展DIY的数据来源/数据模块。

但是,我们找到了 portalcp_block.php 文件, 分析下这个文件:

include_once libfile('function/block');      // 加载了  function_block.php文件













其他文章:discuz X教程:教你如何添加自定义DIY模块,为模块添加扩展http://www.lifedo.cn/html/79/n-10479.html  

打开 source\\class\\block 目录:这个目录是为diy模块产生数据来源的目录,文件名格式为block_xxxx.php,这里文章来源是block_article.php这个文件(基类),其它名字前面类似的是扩展类 ,比如 block_articlenew.php 是产生最新文章的,block_articlehot.php是产生热门文章的,看名字就理解差不多了。

为了产生“最新威客任务”,我模仿最新文章
block_articlenew.php 构建了一个新文件(复制一个block_articlenew.php ),名为为block_articleweike.php ,编辑里面的类名和构造函数名,由原来的 block_articlenew替换为block_articleweike,也就是把里面的类名和构造函数名改为和文件名一样的字符(block_articleweike),这个类是继承自文章的基类,所以前面包含了基类的路径“require_once libfile(\'block/article\', \'class\');”

目前,构造函数只从新定义了一个成员函数 $this->setting = array()

我们要改造数据来源,就得重定义另外一个成员函数 function getdata($style, $parameter)  这个在基类里面有定义,我们从基类block_article.php 里面把这个成员函数复制,并把它粘贴到我们新扩展的类 block_articlenew.php 里面,这样我们修改数据来源就不影响其它的扩展类。


这个自行添加的数据来源 block_articlenew.php 就完成了。


我们在打开\\source\\include\\portal\\portal_blockclass.php 为数据来源添加diy显示入口(diy选择文章模块时候,数据来源出现“最新威客任务”下拉选框)


保存,更新缓存,打开你的diy,模块选择文章类,看看,是否是多了个下拉选择?

另,discuz!x的文件命名很有规则,大家看看就有体会了。数组里的key分别对应相关文件。

转自:http://ggmmchou.blog.163.com/blog/static/59333149201142075017844/




上一篇:企业建站也狂欢!双十一优惠送不停!
下一篇:Discuz定义首页DIY模块教程
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

1314学习网 ( 浙ICP备10214163号 )

GMT+8, 2025-5-2 03:33

Powered by Discuz! X3.4

© 2001-2013 Comsenz Inc.

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