Skip to content

Commit

Permalink
refs #1486 we do not want to have sql statements in controller, api a…
Browse files Browse the repository at this point in the history
…nd plugin class. Put them in a model, makes it also better testable
  • Loading branch information
tsteur committed Dec 20, 2013
1 parent 1e6cece commit 3bd9c0b
Show file tree
Hide file tree
Showing 5 changed files with 502 additions and 367 deletions.
296 changes: 12 additions & 284 deletions plugins/CustomAlerts/API.php
Expand Up @@ -13,14 +13,8 @@

namespace Piwik\Plugins\CustomAlerts;

use Exception;
use Piwik\Piwik;
use Piwik\Common;
use Piwik\Date;
use Piwik\Period;
use Piwik\Db;
use Piwik\Plugins\SitesManager\API as SitesManagerApi;
use Piwik\Plugins\API\API as MetadataApi;

/**
*
Expand All @@ -29,38 +23,19 @@
class API extends \Piwik\Plugin\API
{

private function getModel()
{
return new Model();
}

/**
* Returns a single Alert
*
* @param int $idAlert
*/
public function getAlert($idAlert)
{
$alert = Db::fetchAll("SELECT * FROM "
. Common::prefixTable('alert')
. " WHERE idalert = ?",
intval($idAlert)
);

if (!$alert) {
throw new Exception(Piwik::translate('CustomAlerts_AlertDoesNotExist', $idAlert));
}

$alert = $alert[0];

if (!Piwik::isUserIsSuperUserOrTheUser($alert['login'])) {
throw new Exception(Piwik::translate('CustomAlerts_AccessException', $idAlert));
}

// $idSites = Piwik_FetchAll("SELECT * FROM "
// . Common::prefixTable('alert_site')
// . " WHERE idalert = ?",
// intval($idAlert)
// );
//
// $alert['idsites'] = $idSites;

return $alert;
return $this->getModel()->getAlert($idAlert);
}

/**
Expand All @@ -72,83 +47,17 @@ public function getAlert($idAlert)
*/
public function getAlerts($idSites = array())
{
if (count($idSites)) {
Piwik::checkUserHasViewAccess($idSites);
} else {
Piwik::checkUserHasSomeViewAccess();
$idSites = SitesManagerApi::getInstance()->getSitesIdWithAtLeastViewAccess();
}

$alerts = Db::fetchAll(("SELECT * FROM "
. Common::prefixTable('alert')
. " WHERE idalert IN (
SELECT pas.idalert FROM " . Common::prefixTable('alert_site')
. " pas WHERE idsite IN (" . implode(",", $idSites) . ")) "
. "AND deleted = 0"
));

return $alerts;
return $this->getModel()->getAlert($idSites);
}

public function getTriggeredAlerts($period, $date, $login = false)
{
Piwik::checkUserIsSuperUserOrTheUser($login);

$this->checkPeriod($period);
$piwikDate = Date::factory($date);
$date = Period::factory($period, $piwikDate);

$db = Db::get();

$sql = "SELECT pa.idalert AS idalert,
pal.idsite AS idsite,
pa.name AS alert_name,
ps.name AS site_name,
login,
period,
report,
report_condition,
report_matched,
metric,
metric_condition,
metric_matched
FROM ". Common::prefixTable('alert_log') ." pal
JOIN ". Common::prefixTable('alert') ." pa
ON pal.idalert = pa.idalert
JOIN ". Common::prefixTable('site') ." ps
ON pal.idsite = ps.idsite
WHERE period = ?
AND ts_triggered BETWEEN ? AND ?";

if ($login !== false) {
$sql .= " AND login = \"" . $login . "\"";
}

return $db->fetchAll($sql, array(
$period,
$date->getDateStart()->getDateStartUTC(),
$date->getDateEnd()->getDateEndUTC())
);

return $this->getModel()->getTriggeredAlerts($period, $date, $login);
}

public function getAllAlerts($period)
{
Piwik::checkUserIsSuperUser();

$sql = "SELECT * FROM "
. Common::prefixTable('alert_site') . " alert, "
. Common::prefixTable('alert') . " alert_site "
. "WHERE alert.idalert = alert_site.idalert "
. "AND deleted = 0 ";

if ($this->isValidPeriod($period)) {
$sql .= sprintf("AND period = '%s'", $period);
} else {
throw new Exception("Invalid period given.");
}

return Db::fetchAll($sql);
return $this->getModel()->getAllAlerts($period);
}

/**
Expand All @@ -168,55 +77,7 @@ public function getAllAlerts($period)
*/
public function addAlert($name, $idSites, $period, $email, $metric, $metricCondition, $metricValue, $report, $reportCondition = '', $reportValue = '')
{
if (!is_array($idSites)) {
$idSites = array($idSites);
}

Piwik::checkUserHasViewAccess($idSites);

$name = $this->checkName($name);
$this->checkPeriod($period);

// save in db
$db = Db::get();
$idAlert = Db::fetchOne("SELECT max(idalert) + 1 FROM " . Common::prefixTable('alert'));
if ($idAlert == false) {
$idAlert = 1;
}

$newAlert = array(
'idalert' => $idAlert,
'name' => $name,
'period' => $period,
'login' => Piwik::getCurrentUserLogin(),
'enable_mail' => (int) $email,
'metric' => $metric,
'metric_condition' => $metricCondition,
'metric_matched' => (float) $metricValue,
'report' => $report,
'deleted' => 0,
);

if (!empty($reportCondition) && !empty($reportCondition)) {
$newAlert['report_condition'] = $reportCondition;
$newAlert['report_matched'] = $reportValue;
}

// Do we have a valid alert for all given idSites?
foreach ($idSites as $idSite) {
if (!$this->isValidAlert($newAlert, $idSite)) {
throw new Exception(Piwik::translate('Alerts_ReportOrMetricIsInvalid'));
}
}

$db->insert(Common::prefixTable('alert'), $newAlert);
foreach ($idSites as $idSite) {
$db->insert(Common::prefixTable('alert_site'), array(
'idalert' => $idAlert,
'idsite' => $idSite
));
}
return $idAlert;
return $this->getModel()->addAlert($name, $idSites, $period, $email, $metric, $metricCondition, $metricValue, $report, $reportCondition, $reportValue);
}

/**
Expand All @@ -237,61 +98,7 @@ public function addAlert($name, $idSites, $period, $email, $metric, $metricCondi
*/
public function editAlert($idAlert, $name, $idSites, $period, $email, $metric, $metricCondition, $metricValue, $report, $reportCondition = '', $reportValue = '')
{
if (!is_array($idSites)) {
$idSites = array($idSites);
}

Piwik::checkUserHasViewAccess($idSites);

// Is the name in a valid format?
$name = $this->checkName($name);

// Is the period valid?
$this->checkPeriod($period);

// Save in DB
$db = Db::get();

$alert = array(
'name' => $name,
'period' => $period,
'login' => 'admin', //Piwik::getCurrentUserLogin(),
'enable_mail' => (boolean) $email,
'metric' => $metric,
'metric_condition' => $metricCondition,
'metric_matched' => (float) $metricValue,
'report' => $report,
'deleted' => 0,
);

//
if (!empty($reportCondition) && !empty($reportCondition)) {
$alert['report_condition'] = $reportCondition;
$alert['report_matched'] = $reportValue;
} else {
$alert['report_condition'] = null;
$alert['report_matched'] = null;
}

// Do we have a valid alert for all given idSites?
foreach ($idSites as $idSite) {
if (!$this->isValidAlert($alert, $idSites)) {
throw new Exception(Piwik::translate('CustomAlerts_ReportOrMetricIsInvalid'));
}
}

$db->update(Common::prefixTable('alert'), $alert, "idalert = " . $idAlert);

$db->query("DELETE FROM " . Common::prefixTable("alert_site") . "
WHERE idalert = ?", $idAlert);

foreach ($idSites as $idSite) {
$db->insert(Common::prefixTable('alert_site'), array(
'idalert' => $idAlert,
'idsite' => $idSite
));
}
return $idAlert;
return $this->getModel()->editAlert($idAlert, $name, $idSites, $period, $email, $metric, $metricCondition, $metricValue, $report, $reportCondition, $reportValue);
}

/**
Expand All @@ -301,86 +108,7 @@ public function editAlert($idAlert, $name, $idSites, $period, $email, $metric, $
*/
public function deleteAlert($idAlert)
{
$alert = $this->getAlert($idAlert);

if (!$alert) {
throw new Exception(Piwik::translate('CustomAlerts_AlertDoesNotExist', $idAlert));
}

Piwik::checkUserIsSuperUserOrTheUser($alert['login']);

$db = Db::get();
$db->update(
Common::prefixTable('alert'),
array("deleted" => 1),
"idalert = " . $idAlert
);
$this->getModel()->deleteAlert($idAlert);
}

/**
* Checks whether a report + metric exists for
* the given idSites and if the a dimension is
* given (requires report_condition, report_matched)
*
* @param array alert
* @param int $idSite
* @return boolean
*/
private function isValidAlert($alert, $idSite)
{
list($module, $action) = explode(".", $alert['report']);

$report = MetadataApi::getInstance()->getMetadata($idSite, $module, $action);

// If there is no report matching module + action for idSite it's not valid.
if(count($report) == 0) {
return false;
}

// Merge all available metrics
$allMetrics = $report[0]['metrics'];
if (isset($report[0]['processedMetrics'])) {
$allMetrics = array_merge($allMetrics, $report[0]['processedMetrics']);
}
if (isset($report[0]['metricsGoal'])) {
$allMetrics = array_merge($allMetrics, $report[0]['metricsGoal']);
}
if (isset($report[0]['processedMetricsGoal'])) {
$allMetrics = array_merge($allMetrics, $report[0]['processedMetricsGoal']);
}

if (!in_array($alert['metric'], array_keys($allMetrics))) {
return false;
}

// If we have a dimension, we need to check if
// report_condition and report_matched is given.
if (isset($report[0]['dimension'])
&& (!isset($alert['report_condition']) || !isset($alert['report_matched']))) {
return false;
} else {
return true;
}

return false;
}

private function checkName($name)
{
return urldecode($name);
}

private function checkPeriod($period)
{
if (!$this->isValidPeriod($period)) {
throw new Exception(Piwik::translate('CustomAlerts_InvalidPeriod'));
}
}

private function isValidPeriod($period)
{
return in_array($period, array('day', 'week', 'month', 'year'));
}

}
?>
14 changes: 4 additions & 10 deletions plugins/CustomAlerts/Controller.php
Expand Up @@ -78,7 +78,7 @@ public function addNewAlert()

$view->alertGroups = array();
$view->alerts = $availableReports;
$view->alertGroupConditions = $this->alertGroupConditions;
$view->alertGroupConditions = $this->alertGroupConditions;
$view->alertMetricConditions = $this->alertMetricConditions;

return $view->render();
Expand All @@ -97,19 +97,13 @@ public function editAlert()
$sitesList = SitesManagerApi::getInstance()->getSitesWithAtLeastViewAccess();
$view->sitesList = $sitesList;

// Fetch sites that the alert was defined on.
$sql = "SELECT idsite FROM ".Common::prefixTable('alert_site')." WHERE idalert = ?";
$sites = Db::fetchAll($sql, $idAlert, \PDO::FETCH_COLUMN);
$idSites = array();
foreach ($sites as $site) {
$idSites[] = $site['idsite'];
}
$view->sitesDefined = $idSites;
$model = new Model();
$view->sitesDefined = $model->fetchSiteIdsTheAlertWasDefinedOn($idAlert);

$availableReports = MetadataApi::getInstance()->getReportMetadata();

$view->alerts = $availableReports;
$view->alertGroupConditions = $this->alertGroupConditions;
$view->alertGroupConditions = $this->alertGroupConditions;
$view->alertMetricConditions = $this->alertMetricConditions;

return $view->render();
Expand Down

0 comments on commit 3bd9c0b

Please sign in to comment.