Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/site/app/controllers/statistics_controller.php
diff options
context:
space:
mode:
authormorgamic@mozilla.com <morgamic@mozilla.com@4eb1ac78-321c-0410-a911-ec516a8615a5>2008-02-22 11:54:52 (GMT)
committer morgamic@mozilla.com <morgamic@mozilla.com@4eb1ac78-321c-0410-a911-ec516a8615a5>2008-02-22 11:54:52 (GMT)
commitc39b91aa1fcec112d0d055761595b348225c2c1c (patch)
tree69319fdb6bfc5e05bc04287e1955e17c5727629b /site/app/controllers/statistics_controller.php
parent8e160d15074fee4c0a1517015eb2062c26545b9a (diff)
Merging 3.2 branch back onto trunk at r10622.
git-svn-id: http://svn.mozilla.org/addons/trunk@10622 4eb1ac78-321c-0410-a911-ec516a8615a5
Diffstat (limited to 'site/app/controllers/statistics_controller.php')
-rw-r--r--site/app/controllers/statistics_controller.php356
1 files changed, 356 insertions, 0 deletions
diff --git a/site/app/controllers/statistics_controller.php b/site/app/controllers/statistics_controller.php
new file mode 100644
index 0000000..64970e2
--- /dev/null
+++ b/site/app/controllers/statistics_controller.php
@@ -0,0 +1,356 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/e
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Justin Scott <fligtar@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class StatisticsController extends AppController
+{
+ var $name = 'Statistics';
+ var $uses = array('Addon', 'Addontype', 'Application', 'User', 'Version');
+ var $components = array('Amo', 'Image', 'Stats');
+ var $helpers = array('Html', 'Javascript', 'Listing', 'Localization', 'Time');
+
+ /**
+ * Require login for all actions
+ */
+ function beforeFilter() {
+ $this->SimpleAuth->enabled = false;
+ $this->SimpleAcl->enabled = false;
+
+ // beforeFilter() is apparently called before components are initialized. Cake++
+ $this->Amo->startup($this);
+
+ // Clean post data
+ $this->Amo->clean($this->data);
+
+ $this->layout = 'mozilla';
+ $this->pageTitle = 'Statistics Dashboard'.' :: '.sprintf(_('addons_home_pagetitle'), APP_PRETTYNAME);
+
+ $this->cssAdd = array('stats/stats');
+ $this->publish('cssAdd', $this->cssAdd);
+
+ $this->jsAdd = array('stats/stats.js',);
+ $this->publish('jsAdd', $this->jsAdd);
+
+ $prescriptJS = "var statsURL = '".$this->url('/statistics/')."';";
+ $this->set('prescriptJS', $prescriptJS);
+
+ $this->breadcrumbs = array('Statistics Dashboard' => '/statistics/index');
+ $this->publish('breadcrumbs', $this->breadcrumbs);
+
+ $this->publish('subpagetitle', 'Statistics Dashboard');
+ }
+
+ /**
+ * Index
+ */
+ function index($addon_id = 0) {
+ // If add-on id was specified, go to its statistics
+ if (!empty($addon_id) || !empty($_GET['data']['Addon']['id'])) {
+ if (!empty($addon_id))
+ $this->addon($addon_id);
+ elseif (!empty($_GET['data']['Addon']['id']))
+ $this->addon($_GET['data']['Addon']['id']);
+
+ return;
+ }
+ // If not, figure out what to do
+ else {
+ $session = $this->Session->read('User');
+ $addons = $this->Addon->getAddonsByUser($session['id']);
+ $this->publish('addons', $addons);
+
+ // If user can access all add-on stats, pull all
+ if ($this->SimpleAcl->actionAllowed('Admin', 'ViewAnyStats', $this->Session->read('User'))) {
+ $otherAddons = $this->Addon->findAll(null, array('Addon.id', 'Addon.name'), null, null, null, -1);
+ }
+ else {
+ // Otherwise, pull all public stats add-ons
+ $otherAddons = $this->Addon->findAll("Addon.publicstats=1", array('Addon.id', 'Addon.name'), null, null, null, -1);
+ }
+
+ if (!empty($otherAddons)) {
+ foreach ($otherAddons as $otherAddon) {
+ $name = trim($otherAddon['Translation']['name']['string']);
+ if (!empty($name))
+ $other_addons[$otherAddon['Addon']['id']] = substr($name, 0, 50);
+ }
+ asort($other_addons);
+
+ $this->set('otherAddons', $other_addons);
+ }
+ }
+ }
+
+ /**
+ * Add-on Statistics
+ */
+ function addon($addon_id) {
+ $this->Amo->clean($addon_id);
+ $this->publish('addon_id', $addon_id);
+
+ $this->Addon->id = $addon_id;
+ if (!$addon = $this->Addon->read()) {
+ $this->flash(_('error_addon_notfound'), '/statistics/index');
+ return;
+ }
+
+ if (isset($this->namedArgs['format']) && $this->namedArgs['format'] == 'rss')
+ $rss = true;
+ else
+ $rss = false;
+
+ // Make sure user has permission to view this add-on's stats
+ if (!$this->_checkAccess($addon_id, $addon) &&
+ !($rss && !empty($this->namedArgs['key']) && md5($addon['Addon']['created']) == $this->namedArgs['key'])) {
+ $this->flash(_('devcp_error_addon_access_denied'), '/developers/index');
+ return;
+ }
+
+ $this->publish('suppressJQuery', true);
+ $this->jsAdd = array(
+ //'simile/timeplot/timeplot-api.js?local',
+ 'jquery-compressed.js',
+ //'simile/amo-bundle.compressed.js',
+ 'simile/amo-bundle.js',
+ 'stats/stats.js',
+ 'stats/dropdowns.js',
+ 'stats/colors.js',
+ 'stats/plot-selection.js',
+ 'stats/plots.js'
+ );
+ $this->publish('jsAdd', $this->jsAdd);
+
+ $this->cssAdd = array(
+ 'simile/bundle',
+ 'stats/stats',
+ 'stats/dropdowns'
+ );
+ $this->publish('cssAdd', $this->cssAdd);
+
+ // We only show the RSS key if the user could access if it wasn't public
+ if ($this->Amo->checkOwnership($addon_id, $addon, true) || $this->SimpleAcl->actionAllowed('Admin', 'ViewAnyStats', $this->Session->read('User')))
+ $key = "/key:".md5($addon['Addon']['created']);
+ else
+ $key = '';
+ $this->publish('key', $key);
+ $this->publish('rssAdd', array("/statistics/addon/{$addon['Addon']['id']}/format:rss{$key}"));
+
+ $this->publish('addon', $addon);
+ $this->publish('addon_name', $addon['Translation']['name']['string']);
+
+ $this->breadcrumbs["{$addon['Translation']['name']['string']} Statistics"] = '/statistics/addon/'.$addon_id;
+ $this->publish('breadcrumbs', $this->breadcrumbs);
+
+ $prescriptJS = "var Simile_urlPrefix = '".SITE_URL.$this->base.'/js/simile'."';";
+ $this->set('prescriptJS', $prescriptJS);
+
+ $session = $this->Session->read('User');
+ $this->publish('email', $session['email']);
+ $this->set('all_addons', $this->Addon->getAddonsByUser($session['id']));
+
+ // Add-on icon
+ $addonIcon = $this->Image->urlForAddonIcon($addon_id);
+ if (empty($addonIcon))
+ $addonIcon = $this->base.'/img/'.DEFAULT_ADDON_ICON;
+ $this->publish('addonIcon', $addonIcon);
+
+ // Data for overview
+ $stats = array('totaldownloads' => 0);
+ if (!$this->Config->getValue('stats_disabled') || $this->SimpleAcl->actionAllowed('*', '*', $this->Session->read('User'))) {
+ if ($statsQry = $this->Addon->query("SELECT totaldownloads, weeklydownloads FROM addons WHERE id={$addon_id}", true)) {
+ $stats['totaldownloads'] = $statsQry[0]['addons']['totaldownloads'];
+ $stats['weeklydownloads'] = $statsQry[0]['addons']['weeklydownloads'];
+ }
+ if ($statsQry = $this->Addon->query("SELECT AVG(count) FROM update_counts WHERE addon_id={$addon_id}", true))
+ $stats['avg_updatepings'] = $statsQry[0][0]['AVG(count)'];
+ if ($statsQry = $this->Addon->query("SELECT AVG(count) FROM download_counts WHERE addon_id={$addon_id}", true))
+ $stats['avg_downloads'] = $statsQry[0][0]['AVG(count)'];
+ if ($statsQry = $this->Addon->query("SELECT count, date FROM update_counts WHERE addon_id={$addon_id} ORDER BY date DESC LIMIT 2" ,true)) {
+ $stats['last_updatepings'] = $statsQry[0]['update_counts']['count'];
+ $stats['last_updatepings_date'] = $statsQry[0]['update_counts']['date'];
+ $stats['previous_updatepings'] = $statsQry[1]['update_counts']['count'];
+ $stats['previous_updatepings_date'] = $statsQry[1]['update_counts']['date'];
+ $stats['updateping_change'] = (($stats['last_updatepings'] - $stats['previous_updatepings']) / $stats['previous_updatepings']) * 100;
+ }
+ if ($statsQry = $this->Addon->query("SELECT count, date FROM download_counts WHERE addon_id={$addon_id} ORDER BY date DESC LIMIT 1", true)) {
+ $stats['last_downloads'] = $statsQry[0]['download_counts']['count'];
+ $stats['last_downloads_date'] = $statsQry[0]['download_counts']['date'];
+ }
+ }
+ $this->set('stats', $stats);
+
+ if (!$rss) {
+ $this->render('addon', 'mozilla');
+ }
+ else {
+ $this->publish('rss_title', "{$addon['Translation']['name']['string']} Statistics");
+ $this->publish('rss_description', "Daily summary of statistics for {$addon['Translation']['name']['string']}");
+ $this->render('rss/summary', 'rss');
+ }
+ }
+
+ /**
+ * CSV data
+ */
+ function csv($addon_id, $plot) {
+ $this->publish('addon_id', $addon_id);
+ $this->publish('plot', $plot);
+
+ $addon = $this->Addon->find("Addon.id={$addon_id}", null, null, -1);
+
+ // Make sure user has permission to view this add-on's stats
+ if (!$this->_checkAccess($addon_id, $addon))
+ return;
+
+ $csv = $this->Stats->historicalPlot($addon_id, $plot);
+
+ $this->set('csv', $csv);
+
+ // NO_MICROTIME suppresses the Cake page generation time output
+ define('NO_MICROTIME', true);
+ $this->render('csv', 'ajax');
+ }
+
+ /**
+ * JSON data
+ */
+ function json($addon_id, $type) {
+ $this->publish('addon_id', $addon_id);
+
+ $addon = $this->Addon->find("Addon.id={$addon_id}", null, null, -1);
+
+ // Make sure user has permission to view this add-on's stats
+ if (!$this->_checkAccess($addon_id, $addon))
+ return;
+
+ if ($type == 'summary')
+ $json = $this->Stats->getSummary($addon_id);
+
+ $this->set('json', $json);
+
+ // NO_MICROTIME suppresses the Cake page generation time output
+ define('NO_MICROTIME', true);
+ $this->render('json', 'ajax');
+ }
+
+ /**
+ * XML data
+ */
+ function xml($action, $type, $addon_id = 0) {
+ $addon = $this->Addon->find("Addon.id={$addon_id}", null, null, -1);
+
+ // Make sure user has permission
+ if (!empty($addon_id) && !$this->_checkAccess($addon_id, $addon)) {
+ return;
+ }
+
+ if ($action == 'events') {
+ if ($type == 'addon') {
+ $xml = $this->Stats->getEventsAddon($addon_id);
+ }
+ else {
+ $xml = $this->Stats->getEventsApp($type);
+ }
+ }
+
+ $this->set('xml', $xml);
+
+ // NO_MICROTIME suppresses the Cake page generation time output
+ define('NO_MICROTIME', true);
+ $this->render('xml', 'ajax');
+ }
+
+ /**
+ * Change dashboard settings
+ */
+ function settings($addon_id) {
+ $this->Amo->clean($addon_id);
+ $this->publish('addon_id', $addon_id);
+
+ // Disable query caching
+ foreach ($this->uses as $_model) {
+ $this->$_model->caching = false;
+ }
+
+ // Make sure user is owner in order to change this setting
+ if (!$this->Amo->checkOwnership($addon_id, null, true)) {
+ $this->flash(_('devcp_error_addon_access_denied'), '/statistics/addon/'.$addon_id);
+ return;
+ }
+
+ $this->Addon->id = $addon_id;
+
+ // Save data if POSTed
+ if (!empty($this->data)) {
+ $this->Addon->save($this->data);
+
+ $this->redirect('/statistics/addon/'.$addon_id.'/?settings');
+ return;
+ }
+
+ $addon = $this->Addon->read();
+ $this->publish('addon', $addon);
+
+ $session = $this->Session->read('User');
+ $this->publish('all_addons', $this->Addon->getAddonsByUser($session['id']));
+
+ $this->render('settings');
+ }
+
+ /**
+ * Determines if a user has access to view the add-on's stats
+ */
+ function _checkAccess($addon_id, $addon) {
+ // If add-on has opted-in to public stats, allow access
+ if ($addon['Addon']['publicstats'] == 1)
+ return true;
+
+ // If user can view any add-on's stats, allow access
+ if ($this->SimpleAcl->actionAllowed('Admin', 'ViewAnyStats', $this->Session->read('User')))
+ return true;
+
+ // If user is the add-on's author, allow access
+ if ($this->Amo->checkOwnership($addon_id, $addon))
+ return true;
+
+ // If no access yet, no access at all
+ return false;
+ }
+
+}
+
+?>