ThinkSNS 1.6
二次开发指南(beta版)

2009年
智士软件(北京)有限公司
北京市海淀区上地十街辉煌国际2号楼2301室 010 - 59714755
序言
这是2009年的第一次,忙碌了太久的企业项目,ThinkSNS终于又开始啦,太多的期待和等待,我们听到很多很多声音,不管怎么样,我们回来啦!,在这沉寂的一年多时间里,我们经历过多次的波折,团队一度徘徊在解散的边缘,生存的压力也中断了产品的持续性开发。直到09年的5月底,我们终于有了足够的人力和精力来重新启动产品。
在产品开发之前,我们也不断的在讨论,究竟该用怎样的产品去满足不同用户的需求,我们并不认同SNS等同于webgame的发展思路,在我们看来,SNS的魅力在于它改变了信息的传播方式,如何做好最基本的功能——促进用户之间的交流才是产品的核心所在,至于通过哪些组件实现交流,可以让运营者根据自己的用户特性去选择,而通过游戏的交流只是其中很小的一部分,国内的互联网应用不会永远停留在娱乐阶段,我们希望着眼于未来——围绕社会化服务的核心,深度开发能给用户带来实际效用的交互组件。基于以上的想法,我们这一版产品的目标就是搭建一个完善的内核架构,独立的API,将应用与核心完全分离,让每个应用都可以在后台独立配置,并提供详尽的开发文档,使得更多的开发者可以很容易的开发出新的组件,丰富TS的组件,满足不同用户的社交需求。
最后感谢所有关注和支持ThinkSNS的朋友,如果你有什么疑问或建议,请在我们社区的群组里找到相应的官方群组并提交你的疑问或建议,我们会一直留意那里提交的问题并及时更改,如果是提交bug,请同时注明你的测试环境,方便我们发现问题所在,我们社区的网址是:http://i.thinksns.com
目录
ThinkSNS 1.6作为智士软件(北京)有限公司旗下最新产品,集成了众多ThinkSNS开发者在大型项目中的经验,并将这些宝贵的经验应用于新版的产品之中,不管是对于普通站长还是对于开发者来说,这都是一款值得期待的SNS产品。
ThinkSNS 1.6版汲取了国内几大SNS社区网站的优秀体验和设计,满足了众多站长用户的大众需求。同为一款开源产品,ThinkSNS在商业领域的运用,也使其完全能够满足并适用于企业的需求,并为企业增值和解决方案提供了有力的支持。
相对于ThinkSNS 1.0,最新版的ThinkSNS 1.6做了很大的改变,具体如下:
1、完整的产品构架、完善的基础应用、开箱即用。
2、内置API接口、后续支持自建平台、核心和应用分离。
3、完善的后台管理、可植入独立的应用管理。
4、正在完善IM应用,包括独立部署的WebIM和基于Air技术的客户端应用。
同时ThinkSNS官方将不断的促进ThinkSNS的完善和新技术的应用,使用者可以在官方社区里获得最新的应用插件与系统升级信息。
ThinkSNS 官方网站
ThinkSNS 1.6版 体验网站
本文档是ThinkSNS 1.6版本的二次开发指南,供二次开发人员使用。
核心: ThinkSNS 1.6的核心的指用户基本操作集成,通过接口给应用提供查询,插入核心信息的的能力。
应用: 别名组件,是基于核心的一个单独功能块,为用户提供某项特定服务。在ThinkSNS 1.6里应用是通过API与核心进行通信,应用与应用之间的耦合度低,并且所有的应用都可以在后台设置关闭和开启。
API: API(Application Programming Interface,应用程序编程接口)是一些预先定义的函数,目的是提供给应用程序与核心进行通信的能力,而又无需访问源码,或理解内部工作机制的细节。
注:本指南如没有特殊说明,所有的代码段都基于ThinkPHP 1.6环境开发的。
在应用/插件开发过程中,可以直接使用下面的全局变量:
$this->api 核心API调用的变量,使用例子:
$this->api->user_getLoggedInUser(); (获取当前登录的用户ID)
$this->opts 调用系统配置信息
$this->mid 当前登陆的用户ID
$this->uid 当前被浏览的用户ID
$this->my_name 当前登陆的用户昵称
$this->appid 当前应用ID 如果是THINKSNS核心,则appid=0
1、 本文档主要对ThinkSNS 1.6版本的核心架构进行描述,使设计和开发人员在开发ThinkSNS 1.6版本的应用时遵循统一的规范;
2、本文档描述了在ThinkSNS 1.6版本使用的常见设计机制;
3、本文档充分描述了在“核心+应用”中提到的可配置服务及可扩展服务,以便于在开发新的应用时使用;
4、本文档还对ThinkSNS 1.6版本的全局配置信息(例如:ThinkSNS 1.6版本Config)及官方提供的应用配置进行了详细说明。
独立API架构, 应用可配置, 二次开发的选择
为了达成这些设计目标我们采用了以下设计机制:
1。独立API架构:所有的应用单独开发;
2。应用可配置:后台可直接关闭或开启某个应用;
3。二次开发的选择:程序尽量简洁规范化,二次开发人员可以快速地熟悉定制开发的方式和修改现有的功能;
ThinkSNS 1.6版本采用了全新的构架方式,把应用与核心单独分离,使得系统框架更加清晰明了,方便第三方开发和安装新的应用。
┎━index.php 统一入口文件
┝━admin.php 网站后台地址文件
┝━cleancache.php 手动删除缓存文件
┝━config.inc.php 网站配置文件
┝━define.inc.php 常量定义文件
┝━thumb.php 自动缩略图文件
┝━admin 后台目录
┃ ┝ Common 公共文件目录
┃ ┝ Conf 项目配置目录
┃ ┝ Lang 语言包目录
┃ ┝ Lib 应用类库目录
┃ ┗ Tpl 模版文件目录
┝━apps 应用目录
┃ ┝ blog 日志目录
┃ ┝ event 活动目录
┃ ┝ mini 心情目录
┃ ┝ photo 相册目录
┃ ┝ share 分享目录
┃ ┝ vote 投票目录
┃ ┝ group 群组目录
┃ ┗…更多项目目录
┝━data 后台目录
┃ ┝ cache 静态缓存目录
┃ ┝ upload 上传文件目录
┃ ┗ user 用户信息目录
┝━public 网站公共目录
┃ ┝ Js JS文件目录
┃ ┝ Images 图片目录
┃ ┝ Languages 语文包目录
┃ ┗ Theme 风格主题包目录
┝━runtime 核心缓存目录
┝━thinkphp TS框架目录
┝━thinksns TS核心功能目录
所有的应用目录都放在apps/目录下,如果要开发一个新的应用也是在该目录下创建应用的目录。

ThinkSNS1.6核心结构图
ThinkSNS 1.6的核心包括两部分: 个人空间的基本功能和API库。个人空间的基本功能有个人资料,隐私,邀请,好友,动态,消息,留言板,随便看看。关于核心部分开发人员只需要了解API的调用方法即可,没必要花精力研究它的运作和机制,而API库的说明请阅读下面的API库栏目。
为了方便开发和优化系统结构,我们对ThinkPHP作了以下几点修改,特别是在核心Model里增加了findPage方法,它集成了findAll方法和分页方法,大大方便了程序的开发,如果使用ThinkPHP作为应用开发框架的话,推荐使用该方法。
2009-06-01
1、ThinkPHP.php的第28行
目的:修改runtime路径
2、ThinkPHP.php的第51行
目的:新增引入TS公共函数
3、ThinkPHP.php的第29行
Lib\Think\Template\ThinkTemplate.class.php 的第710行
目的:使<include标签可以认识__THEME__
4、Common\function.php中第569行
Lib\Think\Util\Widget.class.php 第27行
目的:当W函数找不到当前目录的插件的时候,去核心的插件目录去找
2009-06-02
1、convention.php中第151行
View.class.php中的第347行
目的:为了$this->success可以指向公共Theme目录
2009-6-10
1、ThinkPHP.php中第102行
目的:如果不存在runtime目录,则自动创建
2009-6-12
修改ThinkPHP/Mode/Model.class.php中的findPage方法,更加严格的判断了传入参数。使用方法和findAll类似,只传递第一个参数即可,@int|array $pageopt 传递数字,就是每页记录数,默认是20条。也可以传递数组:
$pageopt['pagesize'] Page类中的每页记录数
$pageopt['param'] Page类中的第三个参数
D('Share')->field('id, toUserName')->findPage(10);
输出格式如下所示,其中count和totalRows是总记录数,主要为了兼容性才需要变量,开发人员可以在两个中选用其一就可。totalPages是总分页数,nowPage是当前分页数,html是输出页码,data就是用findAll得到的结果。具体请参考分享应用的输出:
array(6) {
["count"] => string(2) "65"
["totalPages"] => float(7)
["totalRows"] => string(2) "65"
["nowPage"] => int(1)
["html"] => string(453) " <span class='current'>1</span>
<a href='/ts16//apps/share/index.php?s=/Index/list_friends&p=2'>2</a>
<a href='/ts16//apps/share/index.php?s=/Index/list_friends&p=3'>3</a>
<a href='/ts16//apps/share/index.php?s=/Index/list_friends&p=4'>4</a>
<a href='/ts16//apps/share/index.php?s=/Index/list_friends&p=5'>5</a>
<a href='/ts16//apps/share/index.php?s=/Index/list_friends&p=6'>6</a>
<a href='/ts16//apps/share/index.php?s=/Index/list_friends&p=2'>下一页</a>"
["data"] => array(10) {
[0] => array(16) {
["id"] => string(3) "181"
["toUserName"] => string(9) "水上铁"
}
[1] => array(16) {
["id"] => string(3) "171"
["toUserName"] => string(6) "奇鸟"
}
......
[9] => array(16) {
["id"] => string(3) "147"
["toUserName"] => string(9) "水上铁"
}
}
}
分享应用结构的最大特色是: 需求决定模板,模板决定变量。 分享的模板可以根据自己的需求直接在后台修改(包括分享的动态模板,分享应用里的列表模板),而模板里需要什么变量就直接在数据包以数组的方式增加就可以了。数据包里所有的变量以及相应的值与模板的变量是对应的(除了{WR}以及分享的基本变量),以下让我们看看分享的数据是怎么结合的。
为了方便扩展分享的类型和提高程序的灵活性,分享应用保存到数据库里的信息分为两部分,一部分是分享的基本信息,主要有:
信息 | 字段名 | 备注 |
分享类型ID | typeId | |
分享人ID | toUid | |
分享人名字 | toUserName | |
站内分享目标的ID | aimId | 如日志的ID |
站外分享的网址 | url | |
分享标题 | title | 由程序自动获取 |
描述 | info | |
增加时间 | cTime | 增加时系统自动赋值 |
浏览数 | viewNum | |
评论数 | comNum | |
是否已删除 | isDel | 回收站功能,值为1代表已删除,但可在后台恢复。 |
权限 | purview | 备用 |
推荐人ID | fromUid | 备用 |
推荐人姓名 | fromUserName | 备用 |
另一部分就是分享的核心数据: 数据包, 字段名为data (text), 采用数组保存相关数据,然后序列化后保存入库。数组保存的变量由相应的类型根据模板需要来决定并赋上相应的值,比如日志类型的模板(如下图)需要显示日志标题(title),发表日志人的ID(uid)和姓名(name)。列表里还需要一些简介(intro),日志内容(content)。

注:{WR}是当前网址,系统会自动转译。
所以组装日志的数据包如下图:

在分享应用里生成列表时,根据分享的类型ID(typeId)从缓存里提出相应的模板,然后把数据包反序列化得到一个数组,再循环数组并用str_replace方法转译模板。最终效果如下:

分享信息的来源结构如下:

URL输入: 主要是通过用户在分享应用列表里输入网址来分享站外的音乐、视频、Flash和网址。用户填写完相关信息(分享的网址, 通知好友, 描述)后点击提交的处理过程如下图:

分享别人的分享:
在分享应用里查看分享时可以选择再次分享,但为了防止产生过多的垃圾信息,站内所有能分享的信息用户只可以分享一次,都不能重复分享。
分享其它应用:
分享其它的应用,如日志,先用AJAX调用当前应用里的add_share_check函数先判断你是否为第一次分享,然后才弹出分享框,提交分享后也是在当前应用先组装数据包再通过API提交到数据库。
分享API接口:
之所以要通过API方式增加分享数据,是因为每个应用都是一个独立的项目,应用与应用之间耦合度很低,因此为了方便各应用增加分享数据和保持应用的独立性,全站采用API方式增加分享数据,也包括分享本身的增加。具体的API调用说明请查看API库里关于分享API的说明。以下是分享API的程序流程图。

增加数据后接下来就是列表显示,列表的方式只有四种:朋友的分享, 我的分享, 大家的分享和某人的分享,某人的分享类似我的分享,不同的是我的分享查询的不是当前登录人的ID,某人的分享可以是任意人的ID,当然,显示的模板也不一样。列表里还可以点击只查看某类型的分享。主要是判断GET有没有typeId这个参数,有并且不等于0则只显示相应类型的分享。否则显示全部类型的分享。

分享的内容页程序流程图如下图所示。为了显示多样性以及一些类型的内容显示和列表显示不一样,故没有引用模板渲染数据,而是每一类应用对应一个内容模板文件。它的命名规范是: content_类型别名。如日志的内容模板文件是: content_blog。

增加分享类型的步骤
1 在后台的'应用=>各类应用=>分享=>分类管理=>增加分类' 输入类型信息,包括该类型的列表模板
2 在后台的'高级=>模板管理=>动态模板=>增加动态模板' 增加分享动态模板,具体请参考增加动态模板的规则
3 增加分享的内容页html文件,文件名规定为: content_类型别名,如视频的别名是:video,则内容页为: content_video.html
4 在调用分享的应用里实现通过分享的API插入分享的内容,具体请参考分享的API说明。注:数组参数data里的所需要的变量由列表模板和动态模板所需要的变量决定。
更多应用说明日后完善......
ThinkSNS1.6的API接口比较简单,本文只介绍常用的API,开发人员如果有更多的需要可以直接在ThinkFrame/Api/Model里面看到所有的API接口。
1、user_getInfo(uids, fields, format)
描述:
返回指定用户的用户信息,返回形式为一个数组
参数说明:
参数 | 属性 | 空? | 说明 |
uids | string | 否 | 用户 ID,彼此之间用逗号分割。 |
fields | string | 否 | 指定返回用户的哪些信息。 |
format | string | 是 | 指定响应返回的格式。有 PHP (默认) 、 JSON 和 XML 这三种值可选。 |
调用Demo:
$this->api->user_getInfo("1, 2", "name, email");
(返回:
array(2) {
[0] => array(2) {
["name"] => string(6) "刘伟"
["email"] => string(13) "foxlw@126.com"
}
[1] => array(2) {
["name"] => string(6) "哈哈"
["email"] => string(10) "ttt@tt.com"
}
})
$this->api->user_getInfo("1, 2", "name,email", "json");
(返回:
string(94) "[{"name":"\u5218\u4f1f","email":"foxlw@126.com"},{"name":"\u54c8\u54c8","email":"ttt@tt.com"}]"
)
[注:
目前field可选的字段为:
id - 用户ID
name - 用户姓名。
handle - 昵称。
sex - 用户性别,返回值为 male 或 female。
birthday - 用户出生日期,返回值为 YYYY-MM-DD 格式,例如 1983-01-01。
blood_type - 用户血型。
relationship_status - 婚恋状态。
current_location - 当前居住地。
hometown_location - 家乡。
has_added_app - 是否安装了当前应用,返回 0 时表示没有安装,返回 1 时表示已安装。
admin_level - 用户权限信息。返回值为 ‘USER’ 时表示普通用户,返回为 ‘MANAGER’ 时表示为管理员
pic - 用户大尺寸头像的地址(仅当用户头像存在时返回)。
pic_thumb - 用户中尺寸头像的地址(仅当用户头像存在时返回)。
pic_small - 用户小尺寸头像的地址(仅当用户头像存在时返回)。
]
2、user_getLoggedInUser()
描述:
获取当前登录用户的ID。
参数说明:
无
调用DEMO:
$this->api->user_getLoggedInUser();
(返回:1)
描述:
获取当前登录用户的管理权限级别。
返回值可能为USER(普通用户)、MANAGER(站点管理员)
参数说明:
无
调用DEMO:
$this->api->user_getLoggedInUserLevel();
(返回 "USER")
描述:
获取用户的好友 ID 列表,如果uid为空则返回当前用户的好友 ID 列表,其中,当前用户依靠API user_getLoggedInUser()函数来确定。
参数说明:
参数 | 属性 | 空? | 说明 |
uid | int | 是 | 用户ID |
format | string | 是 | 指定响应返回的格式。有 PHP (默认) 、 JSON 这2种值可选。 |
调用DEMO:
$api->friend_get();
(返回:array(2) {
[0] => string(1) "2"
[1] => string(1) "3"
}
)
2、friend_areFriends($uid1,$uid2)
描述:
返回两个用户是否为好友。是好友时返回 1 或 true,不是好友时返回 0 或 false。
参数说明:
uid1 array 第一个用户的 ID。
uid2 array 第二个用户的 ID。
调用DEMO:
$api->friend_areFriends(1, 2);
(返回:true)
1、UserScore_setScore ($uid, $credit)
描述:
设置用户的积分
参数说明:
参数 | 属性 | 空? | 说明 |
uid | int | 否 | 需要积分操作的用户ID |
credit | array | 否 | 积分操作数组,如: $credit['action']='send_gift' 积分类型 $credit['actioncn']='赠送礼品' 类型说明 $credit['score']='-100' 扣除100个积分 $credit['experience']='10' 增加10个经验 |
2、UserScore_getScore($uid, $type = 'score')
描述:
获取用户积分
参数说明:
参数 | 属性 | 空? | 说明 |
uid | int | 否 | 用户ID |
type | varchar | 否 | 积分类型:score积分(默认),experience经验 |
3、UserScore_checkScore($uid, $score_type, $value)
描述:
判断用户积分是否足够
参数说明:
参数 | 属性 | 空? | 说明 |
uid | int | 否 | 用户ID |
score_type | varchar | 否 | 积分类型:score积分(默认) experience经验 |
value | int | 否 | 要比较的积分数 |
为了方便操作,我们在核心公共方法库里增加用户积分操作的函数:
setUserScore($uid, $credit){
$api = new TS_API();
$array = array();
foreach ($credit['credit'] as $key=>$score){
$temp = $api->UserScore_checkScore($uid,$key,$score);
$array[] = $temp === 0 ? true:$temp ;
$credit_rule[$key] = $score;
}
if(count(array_filter($array)) != count($array)) return false;
$credit_rule['action'] = $credit['action'];
$credit_rule['actioncn'] = $credit['actioncn'];
$credit_rule['info'] = isset($credit['info']) && !empty($credit['info'])?$credit['info']:'{action}{sign}了{score}分{typecn}';
//操作积分
$score_result = $api->UserScore_setScore($uid,$credit_rule);
return $score_result;
}
参数说明:
参数 | 属性 | 空? | 说明 |
uid | int | 否 | 需要积分操作的用户ID |
credit | array | 否 | 积分数组,如: $test['credit'] ['score'] = 10; //增加10个积分 $test['credit']['experience'] = 10; //增加10个经验 $test['action'] = 'send_gift'; //积分类型 $test['actioncn'] = '发送礼物'; //积分说明 |
调用DEMO:
$test['credit']['score'] = 10;
$test['credit']['experience'] = 10;
$test['action'] = 'send_gift';
$test['actioncn'] = '发送礼物';
$res = setUserScore($uid, $test);
(返回:200 成功 404 失败)
1、feed_publish($type, $title_data, $body_data, $appid)
描述:
动态发布方法,成功返回true,失败返回false
参数说明:
参数 | 属性 | 空? | 说明 |
type | string | 否 | 此条动态的类型 |
title_data | array | 否 | 动态标题数据,此数组中的键值和对应feed_template中title变量值 |
body_data | array | 是 | 动态内容数据,此数组中的键值和对应feed_template中body变量值,可选择 |
appid | int | 是 | 应用ID |
调用DEMO:
$title_data["num"] = 1;
$body_data['pic'] = '<img src="style/default/logo.gif">';
$this->api->feed_publish("photo", $title_data, $body_data);
(返回:true)
2、feed_get($map, $limit)
描述:
获取动态方法,失败返回false
参数说明:
参数 | 属性 | 空? | 说明 |
map | string或array | 是 | 查询动态的条件 |
limit | int | 是 | 返回的条数 |
调用DEMO:
$map['uid'] = $this->mid; //取我的动态
$this->api->feed_get($map, 10);
(返回:
array(3) {
[0] => array(2) {
["title"] => string(51) "<a href='space.php?1'>刘伟</a>上传了1张照片"
["body"] => string(61) "<img src="style/default/logo.gif">"
}
[1] => array(2) {
["title"] => string(51) "<a href='space.php?1'>刘伟</a>上传了1张照片"
["body"] => string(61) "<img src="style/default/logo.gif">"
}
[2] => array(2) {
["title"] => string(51) "<a href='space.php?1'>刘伟</a>上传了1张照片"
["body"] => string(61) "<img src="style/default/logo.gif">"
}
})
首先在后台“高级=》模板管理=》动态模板”增加一个动态类型(即动态模板)

然后在应用里需要发动态的地方参考以下方法调用API增加动态就可以了:
//添加一条动态
$body_data["src"] = getUserFace($this->mid);
$this->api->feed_publish("head", $title_data, $body_data);
又如群组发表话题的动态:

//添加动态
$title_data["actor"] = getUserName($this->mid);
$title_data['gid'] = $this->gid;
$title_data['group_name'] = $this->groupinfo['name'];
$body_data['title'] = msubstr($title, 0, 20);
$body_data['gid'] = $this->gid;
$body_data['tid'] = $tid;
$this->api->feed_publish('group_topic', $title_data, $body_data, $this->appId, 0, $this->gid);
强调一下模板里自定义了多少个{xxx},除{actor}和系统常量外,都需要赋值,否则会发意外而导致模板无法解析。
注: {actor}会在程序里统一赋值,在增加动态时不需要重复赋值。
1、notify_send($uids, $type, $title_data, $body_data, $url, $cate)
描述:向一个用户发送通知,发送的通知将被显示到用户通知页面上。
参数说明:
参数 | 属性 | 空? | 说明 |
uids | string或array | 否 | 指定接收通知用户的 ID,如果是string的话,每个 ID 之间用逗号分割。 |
type | string | 是 | 通知的类型,比如"photo" |
titile_data | string | 是 | 通知的标题 |
body_data | array | 是 | 通知的信息,以数组形式传入,键值和模板中的相对应 |
url | string | 是 | 查看此条通知的url |
cata | string | 是 | 目前可选的是"friend"(好友请求),"notification"(通知)【默认】,"message"(短消息) |
调用DEMO:
$fuid = intval($_POST["mini_uid"]);
$type = "mini_comment";
$title_data["mini"] = strip_tags($_POST["mini_con"]);
$body_data["comment"] = $_POST["comment"];
$url = __ROOT__."/apps/mini/index.php?s=/Index/friends/uid/".$_POST["mini_uid"]."#Fli".$_POST["mini_id"];
$r = $this->api->notify_send($fuid, $type, $title_data, $body_data, $url);
(返回:true)
2、notify_get($cate, $type, $pageLimit, $format )
描述:向一个用户发送通知,发送的通知将被显示到用户通知页面上。
参数说明:
参数 | 属性 | 空? | 说明 |
cata | string | 是 | 目前可选的是"friend"(好友请求),"notification"(通知)【默认】,"message"(短消息) |
type | string | 是 | 通知的类型,比如"photo" |
pageLimit | int | 是 | 每页显示通知数,默认10条 |
format | string | 是 | 指定响应返回的格式。有 PHP (默认) 、 JSON 这2种值可选。 |
调用DEMO:
$this->api->notify_get("notification");
(返回:
array(2) {
[0] => array(2) {
["title"] => string(24) "评论了你的心情aaa"
["body"] => string(62) "<a href='/TEST/TP1_6/Test/index.php/Photo/list/id/2'>PLMM!</a>"
}
[1] => array(2) {
["title"] => string(24) "评论了你的心情aaa"
["body"] => string(62) "<a href='/TEST/TP1_6/Test/index.php/Photo/list/id/2'>PLMM!</a>"
}
}
)
首先在后台“高级=》模板管理=》通知模板”增加一个通知类型(即动态模板)

然后在应用里需要发通知的地方参考以下方法调用API增加动态就可以了:
$uid = "111, 222";
$type = "gift_send";
$title["user"] = "水上铁";
$body['img'] = $this->__realityImage($giftInfo);
$body['content'] = t($sendInfo['sendInfo']);
$notify = $this->api->notify_send( $uid, $type, $title, $body );
1、comment_notify($type, $data, $appid)
功能说明
发送通知。
参数说明:
type string 评论的类型。在模型里是$type."_comment"的形式的模型名称
appid int 应用注册ID
$data array 数组。其中内容必须都传递
$data['toUid'] 当评论js回调函数执行的时候传递过来的数组中的toUid
$data['uids'] 评论主体的uid;
$data['url'] 被评论页面的完整url
$data['title_body']['comment] 通知的内容
$data['title_data']['title'] 被评论内容的标题
$data['title_data']['type'] 被评论应用的中文名
1、attach_upload($attach_type, $options)
参数说明:
参数 | 属性 | 空? | 说明 |
attach_type | string | 是 | 上传类型,默认为 attach ,可选 photo,files,doc,(类型是任意的只是标识来源,规则为 应用名_类型) |
options | array | 是 | 参数以数组传入,可选值如下 allow_exts: 允许的后缀名,多个参数以逗号分隔。 max_size: 允许的文件最大值。 save_path: 自定义的路径,必须是完整的路径。 save_name: 自定义的文件名。 |
增加了相册关联
如果传参$options里存在 save_photo 参数数组,则进行相关操作。
参数有:
albumId 保存到的相册ID,只要传这个参数,就同时保存照片到该相册
如:$options['save_photo']['albumId'] = 1
new_album boolean型,如果是true则新建相册,不建议使用
album_name 新建相册的名字,不建议使用
返回值
返回参数数组,status,info两个参数:
$info['status'] 上传成功为true,失败为false;
$info['info'] 为照片信息数组,上传失败时为错误信息字符串。
1、share_addShare($type, $aimId, $data, $info, $purview, $fri_ids, $url)
描述:插入一条站内分享
调用方法:
$this->api->share_addShare($type, $aimId, $data, $info, $purview, $fri_ids);
参数说明:
参数 | 属性 | 空? | 说明 |
type | array | 否 | type[typeId] 分享类型ID type[typeName] 分享类型名 |
aimId | string | 否 | 分享内容的ID |
data | array | 否 | 分享的信息,不同的类型的信息可不一样,请参考附录1 |
info | string | 是 | 描述 |
purview | int | 是 | 0:所有人,1:所有好友,2:私密(后面的可扩充) |
fri_ids | array | 是 | 同时通知给好友的ID |
url | string | 是 | 分享的通知里的“去看看”网址 |
返回值说明:
1 成功 0 失败 -1 已经分享 -2 分类出错 -3 内容为空 -4 不能分享自己的东西
2、share_getShareNum($uid=null)
描述:获取分享的数量
调用方法:
$this->api->share_getShareNum($uid);
参数说明:
参数 | 属性 | 空? | 说明 |
uid | array或string | 是 | 当uid值为空时返回当前网站全部分享的总数量; 当uid为一个数组时返回这些用户的分享的总数量 否则返回该uid用户的分享数量 |
3、share_isForbid($mid, $typeId, $aimId)
描述:是否已经分享过。
调用方法:
$this->api->share_isForbid($mid, $typeId, $aimId);
(没分享过返回:1,否则返回:-1)
参数说明:
参数 | 属性 | 空? | 说明 |
mid | int | 否 | 用户ID |
typeId | int | 否 | 分享类型ID,如日志的ID是5 |
aimId | int | 否 | 分享内容的ID |
1、site_get($format)
描述:
获取站点的信息。
参数说明:
可选 format string 指定响应返回的格式。有 PHP (默认) 、 JSON 这2种值可选。
调用DEMO:
$api->site_get();
(返回:array(2) {
["name"] => string(8) "ThinkSNS"
["url"] => string(23) "http://www.thinksns.com"
}
)
如果你还不知道ThinkPHP1.6中的插件如何用的话
请先阅读下面这个来自ThinkPHP官方论坛(http://bbs.thinkphp.cn/viewthread.php?tid=5701&extra=page%3D1)的帖子:
Widget扩展用于在页面根据需要输出不同的内容,Widget扩展的定义是在项目的Lib\Widget目录下面定义Widget类库,例如用于显示最近的评论的Widget
ShowCommentWidget.class.php
Widget类库需要继承Widget类,并且必须定义render方法实现,例如:
class ShowCommentWidget extends Widget{
public function render($data){
return '这是最新的'.$data['count'].'条评论信息';
}
}
复制代码
render方法必须使用return返回要输出的字符串信息,而不是直接输出。
Widget也可以调用Widget类的renderFile方法,渲染模板后进行输出,。
class ShowCommentWidget extends Widget{
public function render($data){
$content = $this->renderFile('Article:comment',$data);
return $content;
}
}
复制代码
定义好Widget类库后,只需要做的是在模板文件里面使用W方法调用Widget,例如
{:W('ShowComment')}
复制代码
通常Widget都有自己的调用参数来决定不同的输出内容
{:W('ShowComment',array('count'=>5))}
复制代码
参数必须使用索引数组传入。
在控制器里面也可以调用Widget类进行输出,在Action里面获取动态的Widget内容,可以使用下面的方式:
$content = W('ShowComment', array('count'=>5),true);
复制代码
第三个参数表示是否返回字符串,如果是false就表示直接输出。返回值可以用于其他用途。
在某个应用的模板中加入这句话
{:WW('Pub_ShowComment',array('xxx'=>"public1-widget"))}
即可调用公共Widget: "Pub_ShowComment" 插件
这样到时输出的时候,这块就会显示:public--->public1-widget
公共插件的统一目录是PUBLIC/Widget下,比如上个例子要调用的插件,可以这样写:
然后Pub_ShowCommentWidget.class.php中的内容如下:
<?php
class Pub_ShowCommentWidget extends Widget{
public function render($data){
$content = $this->Pub_renderFile('public1',$data);
return $content;
}
}
?>
然后public1.html的内容如下:
<p style="padding-left:60px">
public--->{$xxx}
</p>
需要注意的是命名规则:类名必须以Pub_开头,输出函数必须用Pub_renderFile函数,而不是ThinkPHP1.6核心默认的renderFile函数
模板调用举例:{:W('Comment',array( 'type'=>'share','appid'=>$share['id'],'mid'=>$share['toUid'],"face"=>getUserFace( $share['toUid'] ),'role'=>1,'filed'=>"toUid"))}
功能说明:
产生一个通用评论显示页面。需要在页面中自行定义一个回调js函数commentSuccess(json)来发送通知和更新调用的应用评论数。比如下面分享的回调函数:
public function commentSuccess(){
//json被反解析成了stdClass类型
$result = json_decode(stripslashes($_POST['data']));
//计数更新
$this->model->setInc('comNum','id='.$result->appid);
//发送两条消息<