Skip to content

Commit

Permalink
Merge pull request #64 from tsteur/dashboardapi
Browse files Browse the repository at this point in the history
refs #3913 provide a simple API for dashboards
  • Loading branch information
Matthieu Aubry committed Apr 25, 2013
2 parents 85a30e3 + 9b5f738 commit 4affef7
Show file tree
Hide file tree
Showing 3 changed files with 325 additions and 127 deletions.
154 changes: 154 additions & 0 deletions plugins/Dashboard/API.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
<?
/**
* This API is the <a href='http://piwik.org/docs/analytics-api/reference/' target='_blank'>Dashboard API</a>: it gives information about dashboards.
*
* @package Piwik_API
*/
class Piwik_Dashboard_API
{
/**
* @var Piwik_Dashboard_API
*/
static private $instance = null;

private $dashboard = null;

public function __construct()
{
$this->dashboard = new Piwik_Dashboard();
}

/**
* @return Piwik_Dashboard_API
*/
static public function getInstance()
{
if (null == self::$instance) {
self::$instance = new self;
}

return self::$instance;
}

/**
* Get each dashboard that belongs to a user including the containing widgets that are placed within each dashboard.
* If the user has not created any dashboard yet, the default dashboard will be returned.
*
* @return array[]
*/
public function getDashboards()
{
$dashboards = $this->getUserDashboards();

if (empty($dashboards)) {
$dashboards = array($this->getDefaultDashboard());
}

return $dashboards;
}

/**
* Get the default dashboard.
*
* @return array[]
*/
public function getDefaultDashboard()
{
$defaultLayout = $this->dashboard->getDefaultLayout();
$defaultLayout = $this->dashboard->decodeLayout($defaultLayout);

$defaultDashboard = array('name' => Piwik_Translate('Dashboard_Dashboard'), 'layout' => $defaultLayout);

$widgets = $this->getExistingWidgetsWithinDashboard($defaultDashboard);

return $this->buildDashboard($defaultDashboard, $widgets);
}

/**
* Get all dashboards which a user has created.
*
* @return array[]
*/
public function getUserDashboards()
{
$userLogin = Piwik::getCurrentUserLogin();
$userDashboards = $this->dashboard->getAllDashboards($userLogin);

$dashboards = array();

foreach ($userDashboards as $userDashboard) {

if ($this->hasDashboardColumns($userDashboard)) {
$widgets = $this->getExistingWidgetsWithinDashboard($userDashboard);
$dashboards[] = $this->buildDashboard($userDashboard, $widgets);
}

}

return $dashboards;
}

private function getExistingWidgetsWithinDashboard($dashboard)
{
$columns = $this->getColumnsFromDashboard($dashboard);

$widgets = array();
$columns = array_filter($columns);

foreach ($columns as $column) {
foreach ($column as $widget) {

if ($this->widgetIsNotHidden($widget) && $this->widgetExists($widget)) {
$module = $widget->parameters->module;
$action = $widget->parameters->action;

$widgets[] = array('module' => $module, 'action' => $action);
}
}
}

return $widgets;
}

private function getColumnsFromDashboard($dashboard)
{
if (is_array($dashboard['layout'])) {

return $dashboard['layout'];
}

return $dashboard['layout']->columns;
}

private function hasDashboardColumns($dashboard)
{
if (is_array($dashboard['layout'])) {

return !empty($dashboard['layout']);
}

return !empty($dashboard['layout']->columns);
}

private function buildDashboard($dashboard, $widgets)
{
return array('name' => $dashboard['name'], 'widgets' => $widgets);
}

private function widgetExists($widget)
{
if (empty($widget->parameters)) {
return false;
}

$module = $widget->parameters->module;
$action = $widget->parameters->action;

return Piwik_IsWidgetDefined($module, $action);
}

private function widgetIsNotHidden($widget)
{
return empty($widget->isHidden);
}
}
140 changes: 27 additions & 113 deletions plugins/Dashboard/Controller.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,18 @@
*/
class Piwik_Dashboard_Controller extends Piwik_Controller
{
/**
* @var Piwik_Dashboard
*/
private $dashboard;

protected function init()
{
parent::init();

$this->dashboard = new Piwik_Dashboard();
}

protected function _getDashboardView($template)
{
$view = Piwik_View::factory($template);
Expand Down Expand Up @@ -43,7 +55,7 @@ public function index()
if (!Piwik::isUserIsAnonymous()) {
$login = Piwik::getCurrentUserLogin();

$view->dashboards = Piwik_Dashboard::getAllDashboards($login);
$view->dashboards = $this->dashboard->getAllDashboards($login);
}
echo $view->render();
}
Expand Down Expand Up @@ -73,7 +85,7 @@ public function getDashboardLayout()
public function resetLayout()
{
$this->checkTokenInUrl();
$layout = $this->getDefaultLayout();
$layout = $this->dashboard->getDefaultLayout();
$idDashboard = Piwik_Common::getRequestVar('idDashboard', 1, 'int');
if (Piwik::isUserIsAnonymous()) {
$session = new Piwik_Session_Namespace("Piwik_Dashboard");
Expand Down Expand Up @@ -114,29 +126,6 @@ protected function updateDashboardName($login, $idDashboard, $name)
Piwik_Query($query, $paramsBind);
}

/**
* Returns the layout in the DB for the given user, or false if the layout has not been set yet.
* Parameters must be checked BEFORE this function call
*
* @param string $login
* @param int $idDashboard
*
* @return bool
*/
protected function _getLayoutForUser($login, $idDashboard)
{
$paramsBind = array($login, $idDashboard);
$query = sprintf('SELECT layout FROM %s WHERE login = ? AND iddashboard = ?',
Piwik_Common::prefixTable('user_dashboard'));
$return = Piwik_FetchAll($query, $paramsBind);

if (count($return) == 0) {
return false;
}

return $return[0]['layout'];
}

/**
* Removes the dashboard with the given id
*/
Expand Down Expand Up @@ -168,9 +157,9 @@ public function getAllDashboards()
echo '[]';
return;
}
$login = Piwik::getCurrentUserLogin();

$dashboards = Piwik_Dashboard::getAllDashboards($login);
$login = Piwik::getCurrentUserLogin();
$dashboards = $this->dashboard->getAllDashboards($login);

Piwik_DataTable_Renderer_Json::sendHeaderJSON();
echo Piwik_Common::json_encode($dashboards);
Expand All @@ -196,7 +185,7 @@ public function createNewDashboard()
$layout = '{}';

if ($type == 'default') {
$layout = $this->getDefaultLayout();
$layout = $this->dashboard->getDefaultLayout();
}

$query = sprintf('INSERT INTO %s (login, iddashboard, name, layout) VALUES (?, ?, ?, ?)',
Expand Down Expand Up @@ -232,7 +221,7 @@ public function copyDashboardToUser()
$name = urldecode(Piwik_Common::getRequestVar('name', '', 'string'));
$user = urldecode(Piwik_Common::getRequestVar('user', '', 'string'));
$idDashboard = Piwik_Common::getRequestVar('dashboardId', 0, 'int');
$layout = $this->_getLayoutForUser($login, $idDashboard);
$layout = $this->dashboard->getLayoutForUser($login, $idDashboard);

if ($layout !== false) {
$nextId = $this->getNextIdDashboard($user);
Expand Down Expand Up @@ -297,105 +286,30 @@ public function saveLayoutAsDefault()
protected function getLayout($idDashboard)
{
if (Piwik::isUserIsAnonymous()) {

$session = new Piwik_Session_Namespace("Piwik_Dashboard");
if (!isset($session->dashboardLayout)) {
return $this->getDefaultLayout();

return $this->dashboard->getDefaultLayout();
}

$layout = $session->dashboardLayout;

} else {
$layout = $this->_getLayoutForUser(Piwik::getCurrentUserLogin(), $idDashboard);
$layout = $this->dashboard->getLayoutForUser(Piwik::getCurrentUserLogin(), $idDashboard);
}

if (!empty($layout)) {
$layout = $this->removeDisabledPluginFromLayout($layout);
$layout = $this->dashboard->removeDisabledPluginFromLayout($layout);
}

if (empty($layout)) {
$layout = $this->getDefaultLayout();
}
return $layout;
}

protected function removeDisabledPluginFromLayout($layout)
{
$layout = str_replace("\n", "", $layout);
// if the json decoding works (ie. new Json format)
// we will only return the widgets that are from enabled plugins
$layoutObject = Piwik_Common::json_decode($layout, $assoc = false);

if (is_array($layoutObject)) {
$layoutObject = (object)array(
'config' => array('layout' => '33-33-33'),
'columns' => $layoutObject
);
}

if (empty($layoutObject) || empty($layoutObject->columns)) {
$layoutObject = (object)array(
'config' => array('layout' => '33-33-33'),
'columns' => array()
);
$layout = $this->dashboard->getDefaultLayout();
}

foreach ($layoutObject->columns as &$row) {
if (!is_array($row)) {
$row = array();
continue;
}

foreach ($row as $widgetId => $widget) {
if (isset($widget->parameters->module)) {
$controllerName = $widget->parameters->module;
$controllerAction = $widget->parameters->action;
if (!Piwik_IsWidgetDefined($controllerName, $controllerAction)) {
unset($row[$widgetId]);
}
} else {
unset($row[$widgetId]);
}
}
}
$layout = Piwik_Common::json_encode($layoutObject);
return $layout;
}

protected function getDefaultLayout()
{
$defaultLayout = $this->_getLayoutForUser('', 1);

if (empty($defaultLayout)) {
$topWidget = '';
if (Piwik::isUserIsSuperUser()) {
$topWidget = '{"uniqueId":"widgetCoreHomegetDonateForm",'
. '"parameters":{"module":"CoreHome","action":"getDonateForm"}},';
} else {
$topWidget = '{"uniqueId":"widgetCoreHomegetPromoVideo",'
. '"parameters":{"module":"CoreHome","action":"getPromoVideo"}},';
}

$defaultLayout = '[
[
{"uniqueId":"widgetVisitsSummarygetEvolutionGraphcolumnsArray","parameters":{"module":"VisitsSummary","action":"getEvolutionGraph","columns":"nb_visits"}},
{"uniqueId":"widgetLivewidget","parameters":{"module":"Live","action":"widget"}},
{"uniqueId":"widgetVisitorInterestgetNumberOfVisitsPerVisitDuration","parameters":{"module":"VisitorInterest","action":"getNumberOfVisitsPerVisitDuration"}}
],
[
' . $topWidget . '
{"uniqueId":"widgetReferersgetKeywords","parameters":{"module":"Referers","action":"getKeywords"}},
{"uniqueId":"widgetReferersgetWebsites","parameters":{"module":"Referers","action":"getWebsites"}}
],
[
{"uniqueId":"widgetUserCountryMapvisitorMap","parameters":{"module":"UserCountryMap","action":"visitorMap"}},
{"uniqueId":"widgetUserSettingsgetBrowser","parameters":{"module":"UserSettings","action":"getBrowser"}},
{"uniqueId":"widgetReferersgetSearchEngines","parameters":{"module":"Referers","action":"getSearchEngines"}},
{"uniqueId":"widgetVisitTimegetVisitInformationPerServerTime","parameters":{"module":"VisitTime","action":"getVisitInformationPerServerTime"}},
{"uniqueId":"widgetExampleRssWidgetrssPiwik","parameters":{"module":"ExampleRssWidget","action":"rssPiwik"}}
]
]';
}
$defaultLayout = $this->removeDisabledPluginFromLayout($defaultLayout);
return $defaultLayout;
}

/**
* Returns all available column layouts for the dashboard
*
Expand Down
Loading

0 comments on commit 4affef7

Please sign in to comment.