控制器

在Matomo(以前的Piwik)中,控制器是负责输出HTML的对象。每个想要输出HTML的插件都应该定义自己的扩展控制器Piwik \插件\控制器

控制器中的每个公共方法都是公开的,并且可以通过HTTP请求调用。在创建控制器时,应该注意避免暴露不需要的方法。攻击者可能会使用这些方法。

控制器输出

控制器方法应该返回他们的输出(相对于回声荷兰国际集团(ing))。Matomo将假设输出是HTML,并自动处理适当的HTTP响应标头。如果您想输出HTML以外的内容,则必须使用内容类型HTTP响应头。例如:

@header(“application / json内容类型:;charset = utf - 8 ');

在Matomo UI中使用控制器方法

添加一个控制器方法到插件的控制器将允许它通过HTTP请求执行,但它不会自动显示在Matomo UI的某个地方。有两种方法可以让控制器方法的结果出现在Matomo UI中:

  • 添加一个链接到控制器方法的新菜单项
  • 使用AJAX调用控制器方法,然后显示结果

以下是如何做到两者兼顾的方法:

添加控制器方法作为菜单项

要在Matomo中添加菜单项,请阅读以下指南

通过AJAX调用控制器方法

如果您在Matomo上运行自己的自定义JavaScript,则可以使用AJAX动态调用控制器方法并显示结果。

例如:

//调用MyPlugin。myPage并将结果附加到#root元素的末尾var ajax = new ajaxHelper();ajax。addParams({模块:'MyPlugin',动作:'myPage'}, 'get');ajax。setCallback(function (response) {$('#root').append(response);});ajax.setFormat (html);ajax.send(假);

ajaxHelperJavaScript类存储在piwik /插件/睡眠/ javascript / ajaxHelper.js文件。

控制器方法约定

获取查询参数

与API方法不同,控制器方法不接受查询参数作为输入。如果需要访问查询参数值,请查看如何处理请求参数

生成输出

作为一个插件开发者,欢迎你以任何你喜欢的方式生成你的输出(只要它是安全的),在Matomo中没有什么会强迫你以特定的方式编码。也就是说,大多数Matomo控制器方法都有以下约定:

公共函数myControllerAction(){//第一步:如果这个控制器动作应该执行一些逻辑,首先执行$idSite = Common::getRequestVar('idSite');$period = Common::getRequestVar('period');$somethingResult = MyDoer::doSomething($idSite, $period);$view = new view ("@MyPlugin/myControllerAction.twig");$view->somethingResult = $somethingResult;$view->neededData = API::getInstance()->getNeededData();// Step 4: render view return $view->render();}

调用API方法

由于控制器方法不将查询参数值作为方法参数,因此在控制器方法中调用API方法有时会很麻烦。在这种情况下,控制器使用Piwik \ \ API请求类,它将所有查询参数转发给API方法。示例中的一些代码save ()方法中的注释插件控制器:

$view = new view ('@Annotations/saveAnnotation');$view->annotation = Request::processRequest("Annotations.save");返回视图- >渲染();

代码调用annotation APIsave ()方法转发所有查询参数,这样控制器方法就不必调用常见的::getRequestVar好几次了。

重用Controller方法

有时您可能希望使用属于另一个控制器的控制器方法(例如,嵌入由另一个控制器提供的控件)。您可以使用FrontController:调度()方法来完成此任务:

//控制器方法在我们的插件的控制器公共函数索引(){$view =新视图("@MyPlugin/index.twig");$view->realtimeMap = FrontController::getInstance()->dispatch($module = "UserCountryMap", $method = "realtimeMap");返回视图- >渲染();}

检查正确的HTTP方法

为了维护正确的HTTP语义,一些控制器方法应该检查是否使用了正确的HTTP请求方法来调用它们。例如,非只读操作通常通过帖子而不是得到.处理这些任务的控制器方法应该检查是否使用了POST:

公共函数myAdminTask(){//…做一些事情……if ($_SERVER["REQUEST_METHOD"] != "POST"){返回;} //…做一些事情……}

使用控制器方法作为API方法

一般来说,Matomo控制器中的大多数功能都将呈现一些HTML并返回。然而,有时你会有一些返回JSON的逻辑,但你不希望在API方法中公开(例如,在会话之外可调用)。在本例中,我们创建返回JSON的控制器方法。只要有可能,应该创建API方法而不是控制器方法,除非它需要访问会话,或者如果有不同的原因导致API方法不能工作。

不幸的是,它们并不是为此而设计的,所以你必须做一些额外的工作。除了发送内容类型标头时,必须回显json_encode维数据:

公共函数myControllerMethod(){//…检查访问…/ /……做一些有用的事情……$result =…//获取响应\Piwik\DataTable\Renderer\Json::sendHeaderJSON();结果返回json_encode(美元);}

注意:如果你的方法实际上没有返回任何东西,一个错误将导致UI,因为Matomo的前端将不知道如何处理一个空的响应。因此,如果您正在调用像这样的控制器方法,您确实需要返回一些东西(或确保Matomo不会将响应视为JSON)。

控制器的安全

像API方法一样,控制器方法应该确保当前用户是有效的,并被授权执行请求的操作或查看请求的数据。这意味着调用访问检查方法也应该在API方法中调用,并检查所提供的token_auth有效(经由控制器:checkTokenInUrl ()).

下面是一个安全控制器方法的例子:

公共函数myAdminTask() {Piwik::checkUserHasSuperUserAccess();$ this - > checkTokenInUrl ();if ($_SERVER["REQUEST_METHOD"] != "POST"){返回;} //…做一些事情……}
Baidu