Piwik学习 -- 插件开发
这个版本的piwik比较旧,此文档仅作参考
最近为了给自己的web系统添加一个运营数据分析和展示的功能,本打算自己纯手工打造,但是发现成本太高,时间和精力方面不允许。在网上查阅了一些资料,发现目前有许多开源的web数据分析系统,所以拿来主意,决定找一个合适的开源web分析工具。最终选择了piwik,理由如下:
- Piwik采用LAMP开发,我的系统也是,所以可以复用运营环境。
 - Piwik的架构设计比较通用,可以开发插件进行扩展。
 - Piwik的数据显示比较强大,至少看上去如此。例如有曲线图,直方图,饼图,标签云等等。插件可以通过拖拽的方式任意布置。
 - 开源,免费,并且有相对完整的文档。
 
经过了一段时间的摸索,我终于将开发插件的流程梳理清楚了,记录于此,作为备忘。目前使用的Piwik是1.9.2版本(当前最新版本),这点很重要。Piwik的部分接口不向前兼容,以至于很多基于早期版本开发的插件在当前版本无法使用(吐槽:Piwik官方网站上提供的第三方插件几乎都不能在1.9.2上正常运行)。本文的主要内容如下:
- Piwik工作原理
 - 安装部署Piwik
 - 安装Piwik插件
 - Piwik插件结构
 - Hello World,你懂的!
 - Piwik模版
 - Piwik图形视图
 - 待了解的地方 ……
 
Piwik工作原理
Piwik是一个web系统,主要用于web运营分析。它会部署在你自己的apache和mysql中,这样运营数据都在你自己的服务器里!安装好Piwik后,它会提供一段js代码,你只需要将这些代码嵌入到你web中的每个网页中(如果你的系统是用模版开发的,具有相同的footer模版,那么这里最适合放入这段代码),那么每当这些网页被访问时,这些数据就会传回给Piwik服务器。这里会有个问题,由于数据收集代码放在html中,那么异步请求无法被统计到,因为这些请求不会返回完整的页面,而是部分页面或数据。不要紧,piwik提供web日志分析的功能(具体配置见这里),这样就可以统计出所有的访问数据。
安装部署Piwik
安装Piwik的确很简单:下载开发包,解压到apahce服务器web根目录,配置piwik。Piwik在第一次访问时,提供了一个非常简介的安装向导,指导你一步一步的配置好piwik,具体步骤见这里。
安装Piwik插件
插件的安装也很简单,只需要将插件拷贝到piwik_src/plugins目录下面,然后去piwik配置页面启用插件。具体步骤,参见这里。
Piwik插件结构
Piwik源代码目录下的plugins目录中是Piwik官方插件,其实官方插件是最好的学习参考。要创建你自己的第一个插件,首先需要给插件取一个响亮的名称,这里就姑且称之为“BourneliPlugin”吧!然后创建目录piwik_src/plugins/BourneliPlugin。接下来,需要在此目录下,创建两个比较重要的文件:
- BourneliPlugin.php:定义插件的基本信息、插件的位置
 - Controller.php:插件的CGI方法,可以理解为Web MVC模式中的Controller,Piwik框架会将插件相关的Url映射到Controller.php中的方法。
 
Hello World,你懂的!
按照上面的目录结构,你的第一个插件的基本骨架就搭建成功了,现在我们来写点什么,实现我们的第一个“Hello World”吧。先看看BourneliPlugin.php代码,如下:
| 
 1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
 | 
<?phpclass Piwik_BourneliPlugin extends Piwik_Plugin {    /**     * 插件描述信息。     */    public function getInformation(){        return array(            'description' => '这时bourneli的插件',            'homepage' => 'http://qfs.sng.local/',            'author' => 'bourneli',            'author_homepage' => 'http://cnblogs.com/bourneli/',            'license' => 'GPL v3 or later',            'license_homepage' => 'http://www.gnu.org/licenses/gpl.html',            'version' => '0.1',            'translationAvailable' => false,        );    }    // 加载插件    function postLoad(){        Piwik_AddWidget('Bourneli Test', 'hello world', 'BourneliPlugin', 'helloWorld');    }} | 
上面的代码主要定义的插件的基本信息和插件挂接的位置,需要注意一下几点:
- 类的名称必须是Piwik_BourneliPlugin并且继承类Piwik_Plugin。聪明的你可能已经发现类名的规律:Piwik_<YourPluginName>(大小写不敏感)。确实,<YourPluginName>代表插件目录和插件文件的名称。如果不按照这个约定,piwik是无法找到插件。
 - 需要实现getInformation函数,此函数返回插件描述信息,方便在Piwik的插件管理器中找到我们的插件。
 - 实现postLoad方法,在此方法中挂接插件。此方法有四个参数,分别是,widgetCategory,widgetName,ControllerName和ControllerAction,前面两个主要是显示作用,用于在主界面的widget管理器中找到你的插件。第三个方法是控制器方法,对应Controller.php中的类,第四个参数是第三个参数对应类中的具体方法,用于响应用户的请求。
 
接下来看看Controller.php中的代码:
| 
 1 
2 
3 
4 
5 
6 
7 
8 
9 
 | 
<?phpclass Piwik_BourneliPlugin_Controller extends Piwik_Controller{    function helloWorld(){        echo 'This is hello from Bourneli<br/>';        echo 'This is hello from Bourneli<br/>';        echo 'This is hello from Bourneli<br/>';        echo 'This is hello from Bourneli<br/>';    }} | 
对,你没有看错,Controller.php中的代码就是这么简单!需要注意一下几点
- 类的名称遵循这个规律:Piwik_<YourPluginName>_Controller,否则Piwik_AddWidget的第三个参数无法找到对应类。
 - 类继承Piwik_Controller类
 - helloWorld方法对应Piwik_AddWidget函数的第四个参数,输出将直接显示在widget的面板中。
 
OK,写完了代码,现在可以将BourneliPlugin整个目录拷贝到piwik_src/plugins目录下,看看效果了。
首先,进入插件管理页面,如下图:

对应导航:setting à Plugings à BourneliPlugin。可以看到description这一栏中显示的文本就是在getInformation函数中对应的字段输出的信息。点击最右边的“Active”,启用插件(否则不会出现在widget面板中)。
接下来,去widget面板中打开我们的“hello world”插件。如下图:

可以看到Piwik_AddWidget函数中的第一个和第二个参数出现在哪里?最后点击“hello world”,可以到我们的插件出现在Dashboard中,如下图:

Piwik模版
使用PHP开发web,一般都会使用模版机制,这样可以将view和model分开。Piwik也提供模版功能,Piwik没有自己造车,而是直接使用了smarty模版库,所以使用过smarty的同学一定不会陌生。即时没有使用过,smarty的官方文档比较完备,可以网上搜索查阅。接下来演示一个例子,看看如何在插件中使用模版。首先,在BournliPlugin目录下添加一个templates目录,并且在templates目录中添加文件myTpl.tpl,内容如下:
| 
 1 
2 
 | 
This is a string '{$myString}' from template.<br><h1>今天的天气真实糟透了!</h1> | 
(写这篇文章的时候天气真的很糟!)
然后在Controller.php中添加下面的代码(前面例子中出现的代码备省略了):
| 
 1 
2 
3 
4 
5 
6 
7 
8 
9 
 | 
<?phpclass Piwik_BourneliPlugin_Controller extends Piwik_Controller{    ……      function templateDemo(){        $view = Piwik_View::factory('myTpl');        $view->myString = 'okkkkkkkkkkkkkk';        echo $view->render();    }} | 
添加的函数是一个新的插件函数,用于模版调用,可以看到第一行使用Piwik的视图工厂,加载一个视图对象,并将此对象与模版绑定。然后直接将字符串“okkkkkkkkkkkkkk”赋值给模版中的变量myString,最后渲染并输出。
还没完,虽然写了这个函数,但是没有将其挂接到Piwik的widget面板中(即时不挂接面板,也可以访问,有兴趣的读者可以通过抓包看看如何访问),在BourneliPlugin.php中添加下面的代码:
| 
 1 
2 
3 
4 
5 
6 
7 
8 
9 
 | 
<?phpclass Piwik_BourneliPlugin extends Piwik_Plugin {    ...     // 加载插件    function postLoad(){        ...         Piwik_AddWidget('Bourneli Test', 'template demo', 'BourneliPlugin', 'templateDemo');    }} | 
为了突出重点,前面相同的代码已经省略。我们来看看效果,如下:

Piwik图形视图
Piwik内置了一些图形视图,比如趋势图,直方图,饼图,云图等。并且提供了十分简单的API供我们调用,我们所做的只是提供数据。先来看看几种图形:

感觉是不是很拉风!使用上面的功能很简单,可以通过Piwik_src/plugins/ExampleUI这个插件来了解具体的使用,此插件专门用作demo。我在这里简要说名一下步骤:
- 首先在BourneliPlugin目录下创建名为API.php的文件,在此文件中创建名为Piwik_BourneliPlugin_API的类,命名规则为Piwik_YourPluginName_API。需要注意,此类必须实现单一模式。
 - Piwik_BourneliPlugin_API中的方法主要是用于获取数据并将你的数据填充到名为Piwik_DataTable的容器中,该类是Piwik自定义类,用于统一数据格式。
 - 最后在Controller中的CGI方法中将对应视图与API中的数据提供方法链接起来,就可以完成数据展示了。
 
这里提供实验的完整例子,读者也可以查看Piwik官方提供的ExampleUI这个例子中的源代码,相信会更好,因为本人也是参照这个例子完成实验的。同时,不要忘记直接查看Piwik的源代码,这样会更直接。
待了解的地方
- 目前还不太清楚如何使用Piwik收集的PV,UV数据,也不知道如何扩展Piwik数据收集和数据处理功能,这些是后续需要梳理清除的重点。
 - 需要了解Piwik整体实现的框架,粗略看了一下Piwik的代码,发现写得还是比较优美的,这种插件化设计必然值得学习和掌握。
 - Piwik还可以将他自己的一些widget集成到其他系统中,这样可以提供多途径了解系统的状态,所以也是需要学习的。
 
参考资料
Piwik官方网站:http://piwik.org/
Piwik学习 -- 插件开发的更多相关文章
- 我的第一个jQuery插件开发(日期选择器,datePicker),功能还不完善,但用于学习参考已经足够了。
		
一.学习jQuery插件开发网上的帖子很多,插件开发的方式也有好几种,现在推荐一个帖子讲述的特别好,我也是这篇文张的基础上学习的. 参考:http://www.cnblogs.com/ajianbey ...
 - Mybatis源码学习第八天(总结)
		
源码学习到这里就要结束了; 来总结一下吧 Mybatis的总体架构 这次源码学习我们,学习了重点的模块,在这里我想说一句,源码的学习不是要所有的都学,一行一行的去学,这是错误的,我们只需要学习核心,专 ...
 - 为WLW开发Latex公式插件
		
WLW是写博客的利器,支持离线.格式排版等,而且拥有众多的插件.博客园推荐了代码插入插件,但是没有提供WLW的公式编译插件.目前我的一般做法是:先在Word下使用MathType编辑好公式,然后将公式 ...
 - 我所知道的Javascript
		
javascript到了今天,已经不再是我10多年前所认识的小脚本了.最近我也开始用javascript编写复杂的应用,所以觉得有必要将自己的javascript知识梳理一下.同大家一起分享javas ...
 - 如何开发原生的 JavaScript 插件(知识点+写法)
		
一.前言 通过 "WWW" 原则我们来了解 JavaScript 插件这个东西 第一个 W "What" -- 是什么?什么是插件,我就不照搬书本上的抽象概念了 ...
 - Windows Live Writer介绍及相关问题解决
		
今天本来想说更新一篇我的文章,更新的过程中添加了很多的内容,里面的图片太多了,导致我浏览器占用的内存不断增大,浏览器变得很卡,最后过了好久我终于更新完文章打算保存的时候居然卡住,然后所有我更新的文字和 ...
 - jquery学习笔记---jquery插件开发
		
http://www.cnblogs.com/Wayou/p/jquery_plugin_tutorial.html jquery插件开发:http://www.cnblogs.com/damonla ...
 - 【转载】【JQuery学习】jQuery插件开发
		
JQuery做得最好的就是他的闭包和扩展性.超级简单的扩展方法,让更多的人可以轻松的开发定制自己的jQuery插件.下面的东西是转载过来当做学习材料的.虽然貌似有点古老,但是jQuery的变更一直都不 ...
 - WORDPRESS插件开发学习(一)HELLO WORLD
		
WORDPRESS插件开发学习系列文章第一篇,在每篇文章的后面追加固定的字符“Hello World” 一.打开wordpress目录->wp-content->plugins 二.在pl ...
 
随机推荐
- python day11 ——1. 函数名的使⽤ 2. 闭包 3. 迭代器
			
⼀. 函数名的运⽤. 1.函数名的内存地址 def func(): print("呵呵") print(func) 结果: <function func at 0x11 ...
 - 临时调用call()与apply()方法
			
当在某个局域范围内要调用构造函数中或者其他局域范围内的方法 此时可以用到临时调用方法call与apply 虽然这两个方法都是起临时调用的功能,但是用法不一样 call(obj,val) obj:对象名 ...
 - think in java 读书笔记
			
第三章 操作符 3.1 更简单的打印语句 原:System.out.println("打印"); 简单:print("我是更简单的"); =======需要 ...
 - 路由器DHCP服务及DHCP中继
			
实验要求:掌握路由配置DHCP服务配置 拓扑如下: R1enable 进入特权模式config terminal 进入全局模式interface s0/0/0 进入端口ip address 192 ...
 - simhash
			
1,SimHash https://yanyiwu.com/work/2014/01/30/simhash-shi-xian-xiang-jie.html 64位Hash为什么海明距离选3? http ...
 - FreeModbus LINUXTCP Compile ERROR
			
/********************************************************************************* * FreeModbus LINU ...
 - python三大框架之一(flask介绍)
			
Flask , Django, Tornado 是python中常用的框架,也是python的三大框架.它们的区别是:Flask: 轻量级框架: Django:重量级框架: Tornado:性能最好 ...
 - CentOS7安装PostgreSQL10,pgadmin4
			
======PostgreSQL10 CentOS7=================FYI:https://tecadmin.net/install-postgresql-server-centos ...
 - CSU 1588 合并果子
			
Description 现在有n堆果子,第i堆有ai个果子.现在要把这些果子合并成一堆,每次合并的代价是两堆果子的总果子数.求合并所有果子的最小代价. Input 第一行包含一个整数T(T<=5 ...
 - exception in thread "http-apr-80-exec-24" java.lang.OutOfMemoryError:PermGen...
			
今天客户说项目访问不了了,我急忙看了下告警,发现上报:“exception in thread "http-apr-80-exec-24" java.lang.OutOfMemor ...