diff options
author | morgamic@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) |
commit | c39b91aa1fcec112d0d055761595b348225c2c1c (patch) | |
tree | 69319fdb6bfc5e05bc04287e1955e17c5727629b /site/app/controllers/statistics_controller.php | |
parent | 8e160d15074fee4c0a1517015eb2062c26545b9a (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.php | 356 |
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; + } + +} + +?> |