зеркало из https://github.com/mozilla/pjs.git
Reworked the database. we now have "question sets" which will allow us versioning
This commit is contained in:
Родитель
11b41fa276
Коммит
ab4df73b13
|
@ -11,7 +11,7 @@ class ResultsController extends AppController {
|
||||||
* Model's this controller uses
|
* Model's this controller uses
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
var $uses = array('Application','Result','Intention','Issue');
|
var $uses = array('Application','Collection','Choice','Result');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cake Helpers
|
* Cake Helpers
|
||||||
|
@ -62,8 +62,7 @@ class ResultsController extends AppController {
|
||||||
$_input_name = $this->Sanitize->Sql(isset($this->data['application'][0]) ? $this->data['application'][0] : (isset($this->params['url']['application']) ? $this->params['url']['application'] : ''));
|
$_input_name = $this->Sanitize->Sql(isset($this->data['application'][0]) ? $this->data['application'][0] : (isset($this->params['url']['application']) ? $this->params['url']['application'] : ''));
|
||||||
$_input_ua = $this->Sanitize->Sql(isset($this->data['ua'][0]) ? $this->data['ua'][0] : (isset($this->params['url']['ua']) ? $this->params['url']['ua'] : ''));
|
$_input_ua = $this->Sanitize->Sql(isset($this->data['ua'][0]) ? $this->data['ua'][0] : (isset($this->params['url']['ua']) ? $this->params['url']['ua'] : ''));
|
||||||
|
|
||||||
// Please, oh please can we talk about standards in the future. :) The ua
|
// The ua comes over $_GET in the form:
|
||||||
// comes over $_GET in the form:
|
|
||||||
// x.x.x.x (aa-bb)
|
// x.x.x.x (aa-bb)
|
||||||
// Where x is the versions and a and b are locale information. We're not
|
// Where x is the versions and a and b are locale information. We're not
|
||||||
// interested in the locale information,
|
// interested in the locale information,
|
||||||
|
@ -83,7 +82,6 @@ class ResultsController extends AppController {
|
||||||
|
|
||||||
$app_id = $app->getLastInsertID();
|
$app_id = $app->getLastInsertID();
|
||||||
|
|
||||||
// Warning: hard coding ahead! - Hopefully this is a temporary thing.
|
|
||||||
// The database will handle any combination of questions
|
// The database will handle any combination of questions
|
||||||
// (issues/intentions) and applications+versions. However, since we're
|
// (issues/intentions) and applications+versions. However, since we're
|
||||||
// adding stuff in that comes in over the URL, we kinda have to guess at
|
// adding stuff in that comes in over the URL, we kinda have to guess at
|
||||||
|
@ -92,18 +90,18 @@ class ResultsController extends AppController {
|
||||||
// then manually adding those values to the table.
|
// then manually adding those values to the table.
|
||||||
if (stristr($this->params['url']['application'], 'Firefox') !== false) {
|
if (stristr($this->params['url']['application'], 'Firefox') !== false) {
|
||||||
// Intention Id's
|
// Intention Id's
|
||||||
$this->Intention->query("INSERT INTO applications_intentions VALUES ({$app_id}, 1), ({$app_id}, 2), ({$app_id}, 3), ({$app_id}, 9)");
|
$this->Application->query("INSERT INTO applications_collections VALUES ({$app_id}, ".DEFAULT_FIREFOX_INTENTION_SET_ID.")");
|
||||||
|
|
||||||
// Issue Id's
|
// Issue Id's
|
||||||
$this->Issue->query("INSERT INTO applications_issues VALUES ({$app_id}, 1), ({$app_id}, 2), ({$app_id}, 3), ({$app_id}, 4), ({$app_id}, 5), ({$app_id}, 6), ({$app_id}, 7), ({$app_id}, 8), ({$app_id}, 9), ({$app_id}, 15)");
|
$this->Application->query("INSERT INTO applications_collections VALUES ({$app_id}, ".DEFAULT_FIREFOX_ISSUE_SET_ID.")");
|
||||||
|
|
||||||
} elseif (stristr($this->params['url']['application'], 'Thunderbird') !== false) {
|
} elseif (stristr($this->params['url']['application'], 'Thunderbird') !== false) {
|
||||||
|
|
||||||
// Intention Id's
|
// Intention Id's
|
||||||
$this->Intention->query("INSERT INTO applications_intentions VALUES ({$app_id}, 5), ({$app_id}, 6), ({$app_id}, 7), ({$app_id}, 8), ({$app_id}, 9)");
|
$this->Application->query("INSERT INTO applications_collections VALUES ({$app_id}, ".DEFAULT_THUNDERBIRD_INTENTION_SET_ID.")");
|
||||||
|
|
||||||
// Issue Id's
|
// Issue Id's
|
||||||
$this->Issue->query("INSERT INTO applications_issues VALUES ({$app_id}, 10), ({$app_id}, 11), ({$app_id}, 12), ({$app_id}, 13), ({$app_id}, 14), ({$app_id}, 15)");
|
$this->Application->query("INSERT INTO applications_collections VALUES ({$app_id}, ".DEFAULT_THUNDERBIRD_ISSUE_SET_ID.")");
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// Whatever they entered doesn't have firefox or thunderbird in it.
|
// Whatever they entered doesn't have firefox or thunderbird in it.
|
||||||
|
@ -118,13 +116,12 @@ class ResultsController extends AppController {
|
||||||
$_conditions = "name LIKE '{$_input_name}' AND version LIKE '{$_input_ua}' AND 1=1";
|
$_conditions = "name LIKE '{$_input_name}' AND version LIKE '{$_input_ua}' AND 1=1";
|
||||||
$_application = $this->Application->findAll($_conditions);
|
$_application = $this->Application->findAll($_conditions);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pull the information for our radio buttons (only the
|
// Pull the information for our radio buttons (only the
|
||||||
// questions for their applications will be shown)
|
// questions for their applications will be shown)
|
||||||
$this->set('intentions', $this->Intention->Application->findById($_application[0]['Application']['id']));
|
$this->set('intentions', $this->Application->getIntentions($this->Sanitize->sql($_application[0]['Application']['id'])));
|
||||||
|
|
||||||
// Checkboxes
|
// Checkboxes
|
||||||
$this->set('issues', $this->Issue->Application->findById($_application[0]['Application']['id']));
|
$this->set('issues', $this->Application->getIssues($this->Sanitize->sql($_application[0]['Application']['id'])));
|
||||||
|
|
||||||
// We'll need the url parameters to put in hidden fields
|
// We'll need the url parameters to put in hidden fields
|
||||||
$this->set('url_params', $this->Sanitize->html($this->params['url']));
|
$this->set('url_params', $this->Sanitize->html($this->params['url']));
|
||||||
|
@ -166,6 +163,9 @@ class ResultsController extends AppController {
|
||||||
// We'll need to include the graphing libraries
|
// We'll need to include the graphing libraries
|
||||||
$this->set('include_graph_libraries', true);
|
$this->set('include_graph_libraries', true);
|
||||||
|
|
||||||
|
// Fill in our question sets
|
||||||
|
$this->set('collections',$this->Application->getCollectionsFromUrl($this->params['url'],'issue'));
|
||||||
|
|
||||||
// Core data to show on page
|
// Core data to show on page
|
||||||
$this->set('descriptionAndTotalsData',$this->Result->getDescriptionAndTotalsData($this->params['url']));
|
$this->set('descriptionAndTotalsData',$this->Result->getDescriptionAndTotalsData($this->params['url']));
|
||||||
}
|
}
|
||||||
|
@ -215,8 +215,17 @@ class ResultsController extends AppController {
|
||||||
// Get rid of the header/footer/etc.
|
// Get rid of the header/footer/etc.
|
||||||
$this->layout = null;
|
$this->layout = null;
|
||||||
|
|
||||||
|
// Auto generated .csv's are turned off since they were taking too much
|
||||||
|
// cpu/ram. If you turn them back on, be sure to check the code - there was
|
||||||
|
// a substantial database change between the time they were disabled and now.
|
||||||
|
return false;
|
||||||
|
|
||||||
|
$csv = new csv();
|
||||||
|
|
||||||
|
$csv->loadDataFromArray($this->Result->getCsvExportData($this->params['url'], false));
|
||||||
|
|
||||||
// Our CSV library sends headers and everything. Keep the view empty!
|
// Our CSV library sends headers and everything. Keep the view empty!
|
||||||
csv_send_csv($this->Result->getCsvExportData($this->params['url']));
|
$csv->sendCSV();
|
||||||
|
|
||||||
// I'm not exiting here in case someone is going to use post callback stuff.
|
// I'm not exiting here in case someone is going to use post callback stuff.
|
||||||
// In development, that means extra lines get added to our CSVs, but in
|
// In development, that means extra lines get added to our CSVs, but in
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
<?php
|
<?php
|
||||||
|
uses('Sanitize');
|
||||||
class Application extends AppModel {
|
class Application extends AppModel {
|
||||||
var $name = 'Application';
|
var $name = 'Application';
|
||||||
|
|
||||||
|
@ -10,14 +11,177 @@ class Application extends AppModel {
|
||||||
//var $hasOne = array('Result');
|
//var $hasOne = array('Result');
|
||||||
|
|
||||||
var $hasAndBelongsToMany = array(
|
var $hasAndBelongsToMany = array(
|
||||||
'Intention' => array(
|
'Collection' => array( 'className' => 'Collection')
|
||||||
'className' => 'Intention',
|
|
||||||
'order' => 'pos'
|
|
||||||
),
|
|
||||||
'Issue' => array(
|
|
||||||
'className' => 'Issue',
|
|
||||||
'order' => 'pos'
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
var $Sanitize;
|
||||||
|
|
||||||
|
function Application() {
|
||||||
|
parent::AppModel();
|
||||||
|
|
||||||
|
$this->Sanitize = new Sanitize();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @param int application id
|
||||||
|
* @return array set of intentions
|
||||||
|
*/
|
||||||
|
function getIntentions($id) {
|
||||||
|
// this should never happen...
|
||||||
|
if (!is_numeric($id)) {
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
|
$_query = "
|
||||||
|
SELECT
|
||||||
|
*
|
||||||
|
FROM
|
||||||
|
applications
|
||||||
|
JOIN applications_collections ON application_id = applications.id
|
||||||
|
JOIN collections ON collections.id = applications_collections.collection_id
|
||||||
|
JOIN choices_collections ON choices_collections.collection_id = collections.id
|
||||||
|
JOIN choices ON choices.id = choices_collections.choice_id
|
||||||
|
WHERE
|
||||||
|
applications.id={$id}
|
||||||
|
AND
|
||||||
|
choices.type='intention'";
|
||||||
|
|
||||||
|
return $this->query($_query);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int application id
|
||||||
|
* @return array set of issues
|
||||||
|
*/
|
||||||
|
function getIssues($id)
|
||||||
|
{
|
||||||
|
// this should never happen...
|
||||||
|
if (!is_numeric($id)) {
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
|
$_max_id = $this->getMaxCollectionId($id,'issue');
|
||||||
|
if (!is_numeric($_max_id[0][0]['max'])) {
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$_query = "
|
||||||
|
SELECT
|
||||||
|
*
|
||||||
|
FROM
|
||||||
|
applications
|
||||||
|
JOIN applications_collections ON application_id = applications.id
|
||||||
|
JOIN collections ON collections.id = applications_collections.collection_id
|
||||||
|
JOIN choices_collections ON choices_collections.collection_id = collections.id
|
||||||
|
JOIN choices ON choices.id = choices_collections.choice_id
|
||||||
|
WHERE
|
||||||
|
applications.id={$id}
|
||||||
|
AND
|
||||||
|
choices.type='issue'
|
||||||
|
AND
|
||||||
|
collections.id={$_max_id[0][0]['max']}
|
||||||
|
";
|
||||||
|
|
||||||
|
return $this->query($_query);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getMaxCollectionId($id, $type)
|
||||||
|
{
|
||||||
|
if (!is_numeric($id)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$_type = $this->Sanitize->sql($type);
|
||||||
|
|
||||||
|
$_query = "
|
||||||
|
SELECT
|
||||||
|
MAX(collections.id) as max
|
||||||
|
FROM
|
||||||
|
applications
|
||||||
|
JOIN applications_collections ON application_id = applications.id
|
||||||
|
JOIN collections ON collections.id = applications_collections.collection_id
|
||||||
|
JOIN choices_collections ON choices_collections.collection_id = collections.id
|
||||||
|
JOIN choices ON choices.id = choices_collections.choice_id
|
||||||
|
WHERE
|
||||||
|
applications.id={$id}
|
||||||
|
AND
|
||||||
|
choices.type='{$_type}'
|
||||||
|
";
|
||||||
|
|
||||||
|
return $this->query($_query);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array cake url array
|
||||||
|
* @return array set of collections
|
||||||
|
*/
|
||||||
|
function getCollectionsFromUrl($params, $type)
|
||||||
|
{
|
||||||
|
// Clean parameters for inserting into SQL
|
||||||
|
$params = $this->cleanArrayForSql($params);
|
||||||
|
|
||||||
|
$_conditions = "1=1";
|
||||||
|
// Firstly, determine our application
|
||||||
|
if (!empty($params['product'])) {
|
||||||
|
|
||||||
|
// product's come in looking like:
|
||||||
|
// Mozilla Firefox 1.5.0.1
|
||||||
|
$_exp = explode(' ',urldecode($params['product']));
|
||||||
|
|
||||||
|
if(count($_exp) == 3) {
|
||||||
|
$_product = $_exp[0].' '.$_exp[1];
|
||||||
|
|
||||||
|
$_version = $_exp[2];
|
||||||
|
|
||||||
|
$_conditions .= " AND `Application`.`name` LIKE '{$_product}'";
|
||||||
|
$_conditions .= " AND `Application`.`version` LIKE '{$_version}'";
|
||||||
|
} else {
|
||||||
|
// defaults I guess?
|
||||||
|
$_conditions .= " AND `Application`.`name` LIKE '".DEFAULT_APP_NAME."'";
|
||||||
|
$_conditions .= " AND `Application`.`version` LIKE '".DEFAULT_APP_VERSION."'";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// I'm providing a default here, because otherwise all results will be
|
||||||
|
// returned (across all applications) and that is not desired
|
||||||
|
$_conditions .= " AND `Application`.`name` LIKE '".DEFAULT_APP_NAME."'";
|
||||||
|
$_conditions .= " AND `Application`.`version` LIKE '".DEFAULT_APP_VERSION."'";
|
||||||
|
}
|
||||||
|
|
||||||
|
$_application_id = $this->findAll($_conditions, 'Application.id');
|
||||||
|
return $this->getCollections($_application_id[0]['Application']['id'], $type);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int application id
|
||||||
|
* @param string choice type (either 'issue' or 'intention' right now)
|
||||||
|
* @return array set of collections
|
||||||
|
*/
|
||||||
|
function getCollections($id, $type)
|
||||||
|
{
|
||||||
|
// this should never happen...
|
||||||
|
if (!is_numeric($id)) {
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
|
$_type = $this->Sanitize->sql($type);
|
||||||
|
$_query = "
|
||||||
|
SELECT
|
||||||
|
*
|
||||||
|
FROM
|
||||||
|
applications
|
||||||
|
JOIN applications_collections ON application_id = applications.id
|
||||||
|
JOIN collections ON collections.id = applications_collections.collection_id
|
||||||
|
JOIN choices_collections ON choices_collections.collection_id = collections.id
|
||||||
|
JOIN choices ON choices.id = choices_collections.choice_id
|
||||||
|
WHERE
|
||||||
|
applications.id={$id}
|
||||||
|
AND
|
||||||
|
choices.type='{$_type}'
|
||||||
|
GROUP BY collections.description
|
||||||
|
ORDER BY collections.id DESC";
|
||||||
|
|
||||||
|
return $this->query($_query);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
|
|
|
@ -2,17 +2,22 @@
|
||||||
class Result extends AppModel {
|
class Result extends AppModel {
|
||||||
var $name = 'Result';
|
var $name = 'Result';
|
||||||
|
|
||||||
var $belongsTo = array('Application', 'Intention');
|
var $belongsTo = array('Application');
|
||||||
|
|
||||||
var $hasAndBelongsToMany = array('Issue' =>
|
var $hasAndBelongsToMany = array('Choice' =>
|
||||||
array('className' => 'Issue',
|
array('className' => 'Choice',
|
||||||
'joinTable' => 'issues_results',
|
|
||||||
'foreignKey'=> 'issue_id',
|
|
||||||
'assocationForeignKey'=>'result_id',
|
|
||||||
'uniq' => true
|
'uniq' => true
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
var $Sanitize;
|
||||||
|
|
||||||
|
function Result()
|
||||||
|
{
|
||||||
|
parent::appModel();
|
||||||
|
$this->Sanitize = new Sanitize();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Count's all the comments, according to the parameters.
|
* Count's all the comments, according to the parameters.
|
||||||
* @param array URL parameters
|
* @param array URL parameters
|
||||||
|
@ -59,15 +64,15 @@ class Result extends AppModel {
|
||||||
array_push($_conditions, "`Application`.`version` LIKE '{$_version}'");
|
array_push($_conditions, "`Application`.`version` LIKE '{$_version}'");
|
||||||
} else {
|
} else {
|
||||||
// defaults I guess?
|
// defaults I guess?
|
||||||
array_push($_conditions, "`Application`.`name` LIKE 'Mozilla Firefox'");
|
array_push($_conditions, "`Application`.`name` LIKE '".DEFAULT_APP_NAME."'");
|
||||||
array_push($_conditions, "`Application`.`version` LIKE '1.5'");
|
array_push($_conditions, "`Application`.`version` LIKE '".DEFAULT_APP_VERSION."'");
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// I'm providing a default here, because otherwise all results will be
|
// I'm providing a default here, because otherwise all results will be
|
||||||
// returned (across all applications) and that is not desired
|
// returned (across all applications) and that is not desired
|
||||||
array_push($_conditions, "`Application`.`name` LIKE 'Mozilla Firefox'");
|
array_push($_conditions, "`Application`.`name` LIKE '".DEFAULT_APP_NAME."'");
|
||||||
array_push($_conditions, "`Application`.`version` LIKE '1.5'");
|
array_push($_conditions, "`Application`.`version` LIKE '".DEFAULT_APP_VERSION."'");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do the actual query
|
// Do the actual query
|
||||||
|
@ -124,34 +129,43 @@ class Result extends AppModel {
|
||||||
array_push($_conditions, "`Application`.`version` LIKE '{$_version}'");
|
array_push($_conditions, "`Application`.`version` LIKE '{$_version}'");
|
||||||
} else {
|
} else {
|
||||||
// defaults I guess?
|
// defaults I guess?
|
||||||
array_push($_conditions, "`Application`.`name` LIKE 'Mozilla Firefox'");
|
array_push($_conditions, "`Application`.`name` LIKE '".DEFAULT_APP_NAME."'");
|
||||||
array_push($_conditions, "`Application`.`version` LIKE '1.5'");
|
array_push($_conditions, "`Application`.`version` LIKE '".DEFAULT_APP_VERSION."'");
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// I'm providing a default here, because otherwise all results will be
|
// I'm providing a default here, because otherwise all results will be
|
||||||
// returned (across all applications) and that is not desired
|
// returned (across all applications) and that is not desired
|
||||||
array_push($_conditions, "`Application`.`name` LIKE 'Mozilla Firefox'");
|
array_push($_conditions, "`Application`.`name` LIKE '".DEFAULT_APP_NAME."'");
|
||||||
array_push($_conditions, "`Application`.`version` LIKE '1.5'");
|
array_push($_conditions, "`Application`.`version` LIKE '".DEFAULT_APP_VERSION."'");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save ourselves quite a few joins
|
// Save ourselves quite a few joins
|
||||||
$this->unBindModel(array('hasAndBelongsToMany' => array('Issue')));
|
|
||||||
$comments = $this->findAll($_conditions, null, $pagination['order'], $pagination['show'], $pagination['page']);
|
$comments = $this->findAll($_conditions, null, $pagination['order'], $pagination['show'], $pagination['page']);
|
||||||
|
|
||||||
if ($privacy) {
|
if ($privacy) {
|
||||||
// Pull out all the email addresses and phone numbers
|
// Pull out all the email addresses and phone numbers. The original
|
||||||
|
// lines are below, but commented out for the sake of speed.
|
||||||
|
// preg_replace() will replace a single level of an array according to a
|
||||||
|
// pattern. This behavior doesn't seem to be documented (at this time), so I'm not sure
|
||||||
|
// if they are going to "fix" it later. If they do, you can replace the
|
||||||
|
// current code with the commented ones, but realize it will take about
|
||||||
|
// twice as long.
|
||||||
foreach ($comments as $var => $val) {
|
foreach ($comments as $var => $val) {
|
||||||
|
|
||||||
// Handle foo@bar.com
|
// Handle foo@bar.com
|
||||||
$_email_regex = '/\ ?(.+)?@(.+)?\.(.+)?\ ?/';
|
$_email_regex = '/\ ?(.+)?@(.+)?\.(.+)?\ ?/';
|
||||||
$comments[$var]['Result']['comments'] = preg_replace($_email_regex,'$1@****.$3',$comments[$var]['Result']['comments']);
|
$comments[$var]['Result'] = preg_replace($_email_regex,'$1@****.$3',$comments[$var]['Result']);
|
||||||
$comments[$var]['Result']['intention_text'] = preg_replace($_email_regex,'$1@****.$3',$comments[$var]['Result']['intention_text']);
|
|
||||||
|
//$comments[$var]['Result']['comments'] = preg_replace($_email_regex,'$1@****.$3',$comments[$var]['Result']['comments']);
|
||||||
|
//$comments[$var]['Result']['intention_text'] = preg_replace($_email_regex,'$1@****.$3',$comments[$var]['Result']['intention_text']);
|
||||||
|
|
||||||
// Handle xxx-xxx-xxxx
|
// Handle xxx-xxx-xxxx
|
||||||
$_phone_regex = '/([0-9]{3})[ .-]?[0-9]{4}/';
|
$_phone_regex = '/([0-9]{3})[ .-]?[0-9]{4}/';
|
||||||
$comments[$var]['Result']['comments'] = preg_replace($_phone_regex,'$1-****',$comments[$var]['Result']['comments']);
|
$comments[$var]['Result'] = preg_replace($_phone_regex,'$1-****',$comments[$var]['Result']);
|
||||||
$comments[$var]['Result']['intention_text'] = preg_replace($_phone_regex,'$1-****',$comments[$var]['Result']['intention_text']);
|
|
||||||
|
//$comments[$var]['Result']['comments'] = preg_replace($_phone_regex,'$1-****',$comments[$var]['Result']['comments']);
|
||||||
|
//$comments[$var]['Result']['intention_text'] = preg_replace($_phone_regex,'$1-****',$comments[$var]['Result']['intention_text']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -220,14 +234,14 @@ class Result extends AppModel {
|
||||||
$_query .= " AND `applications`.`version` LIKE '{$_version}'";
|
$_query .= " AND `applications`.`version` LIKE '{$_version}'";
|
||||||
} else {
|
} else {
|
||||||
// defaults I guess?
|
// defaults I guess?
|
||||||
$_query .= " AND `applications`.`name` LIKE 'Mozilla Firefox'";
|
$_query .= " AND `applications`.`name` LIKE '".DEFAULT_APP_NAME."'";
|
||||||
$_query .= " AND `applications`.`version` LIKE '1.5'";
|
$_query .= " AND `applications`.`version` LIKE '".DEFAULT_APP_VERSION."'";
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// I'm providing a default here, because otherwise all results will be
|
// I'm providing a default here, because otherwise all results will be
|
||||||
// returned (across all applications) and that is not desired
|
// returned (across all applications) and that is not desired
|
||||||
$_query .= " AND `applications`.`name` LIKE 'Mozilla Firefox'";
|
$_query .= " AND `applications`.`name` LIKE '".DEFAULT_APP_NAME."'";
|
||||||
$_query .= " AND `applications`.`version` LIKE '1.5'";
|
$_query .= " AND `applications`.`version` LIKE '".DEFAULT_APP_VERSION."'";
|
||||||
}
|
}
|
||||||
|
|
||||||
$_query .= " ORDER BY `results`.`created` ASC";
|
$_query .= " ORDER BY `results`.`created` ASC";
|
||||||
|
@ -236,7 +250,6 @@ class Result extends AppModel {
|
||||||
|
|
||||||
// Since we're exporting to a CSV, we need to flatten the results into a 2
|
// Since we're exporting to a CSV, we need to flatten the results into a 2
|
||||||
// dimensional table array
|
// dimensional table array
|
||||||
$newdata = array();
|
|
||||||
|
|
||||||
foreach ($res as $result) {
|
foreach ($res as $result) {
|
||||||
|
|
||||||
|
@ -244,18 +257,28 @@ class Result extends AppModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($privacy) {
|
if ($privacy) {
|
||||||
// Pull out all the email addresses and phone numbers
|
// Pull out all the email addresses and phone numbers. The original
|
||||||
|
// lines are below, but commented out for the sake of speed.
|
||||||
|
// preg_replace() will replace a single level of an array according to a
|
||||||
|
// pattern. This behavior doesn't seem to be documented (at this time), so I'm not sure
|
||||||
|
// if they are going to "fix" it later. If they do, you can replace the
|
||||||
|
// current code with the commented ones, but realize it will take about
|
||||||
|
// twice as long.
|
||||||
foreach ($newdata as $var => $val) {
|
foreach ($newdata as $var => $val) {
|
||||||
|
|
||||||
// Handle foo@bar.com
|
// Handle foo@bar.com
|
||||||
$_email_regex = '/\ ?(.+)?@(.+)?\.(.+)?\ ?/';
|
$_email_regex = '/\ ?(.+)?@(.+)?\.(.+)?\ ?/';
|
||||||
$newdata[$var]['comments'] = preg_replace($_email_regex,'$1@****.$3',$newdata[$var]['comments']);
|
$newdata[$var] = preg_replace($_email_regex,'$1@****.$3',$newdata[$var]);
|
||||||
$newdata[$var]['intention_other'] = preg_replace($_email_regex,'$1@****.$3',$newdata[$var]['intention_other']);
|
|
||||||
|
//$newdata[$var]['comments'] = preg_replace($_email_regex,'$1@****.$3',$newdata[$var]['comments']);
|
||||||
|
//$newdata[$var]['intention_other'] = preg_replace($_email_regex,'$1@****.$3',$newdata[$var]['intention_other']);
|
||||||
|
|
||||||
// Handle xxx-xxx-xxxx
|
// Handle xxx-xxx-xxxx
|
||||||
$_phone_regex = '/([0-9]{3})[ .-]?[0-9]{4}/';
|
$_phone_regex = '/([0-9]{3})[ .-]?[0-9]{4}/';
|
||||||
$newdata[$var]['comments'] = preg_replace($_phone_regex,'$1-****',$newdata[$var]['comments']);
|
$newdata[$var] = preg_replace($_phone_regex,'$1-****',$newdata[$var]);
|
||||||
$newdata[$var]['intention_other'] = preg_replace($_phone_regex,'$1-****',$newdata[$var]['intention_other']);
|
|
||||||
|
//$newdata[$var]['comments'] = preg_replace($_phone_regex,'$1-****',$newdata[$var]['comments']);
|
||||||
|
//$newdata[$var]['intention_other'] = preg_replace($_phone_regex,'$1-****',$newdata[$var]['intention_other']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -281,7 +304,7 @@ class Result extends AppModel {
|
||||||
|
|
||||||
/* Below is the original query for this function. It was beautiful and
|
/* Below is the original query for this function. It was beautiful and
|
||||||
* brought back just what we needed. However, it took 5.5s to run with 43000
|
* brought back just what we needed. However, it took 5.5s to run with 43000
|
||||||
* results, and since that number is just going up, it won't due to have a
|
* results, and since that number is just going up, it won't do to have a
|
||||||
* query take that long (especially one on the front page).
|
* query take that long (especially one on the front page).
|
||||||
|
|
||||||
//It would be nice to drop something like this in the SELECT:
|
//It would be nice to drop something like this in the SELECT:
|
||||||
|
@ -323,34 +346,56 @@ class Result extends AppModel {
|
||||||
$_conditions .= " AND `Application`.`version` LIKE '{$_version}'";
|
$_conditions .= " AND `Application`.`version` LIKE '{$_version}'";
|
||||||
} else {
|
} else {
|
||||||
// defaults I guess?
|
// defaults I guess?
|
||||||
$_conditions .= " AND `Application`.`name` LIKE 'Mozilla Firefox'";
|
$_conditions .= " AND `Application`.`name` LIKE '".DEFAULT_APP_NAME."'";
|
||||||
$_conditions .= " AND `Application`.`version` LIKE '1.5'";
|
$_conditions .= " AND `Application`.`version` LIKE '".DEFAULT_APP_VERSION."'";
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// I'm providing a default here, because otherwise all results will be
|
// I'm providing a default here, because otherwise all results will be
|
||||||
// returned (across all applications) and that is not desired
|
// returned (across all applications) and that is not desired
|
||||||
$_conditions .= " AND `Application`.`name` LIKE 'Mozilla Firefox'";
|
$_conditions .= " AND `Application`.`name` LIKE '".DEFAULT_APP_NAME."'";
|
||||||
$_conditions .= " AND `Application`.`version` LIKE '1.5'";
|
$_conditions .= " AND `Application`.`version` LIKE '".DEFAULT_APP_VERSION."'";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save ourselves some joins
|
|
||||||
$this->Application->unBindModel(array('hasAndBelongsToMany' => array('Intention','Issue')));
|
|
||||||
|
|
||||||
$_application_id = $this->Application->findAll($_conditions, 'Application.id');
|
$_application_id = $this->Application->findAll($_conditions, 'Application.id');
|
||||||
|
|
||||||
|
// Next determine our collection
|
||||||
|
if (!empty($params['collection'])) {
|
||||||
|
$_collection_id = $this->Choice->Collection->findByDescription($params['collection']);
|
||||||
|
$clear = true;
|
||||||
|
foreach ($_collection_id['Application'] as $var => $val) {
|
||||||
|
if ($_application_id[0]['Application']['id'] == $val['id']) {
|
||||||
|
$clear = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($clear) {
|
||||||
|
$_id = $this->Application->getMaxCollectionId($_application_id[0]['Application']['id'], 'issue');
|
||||||
|
$_collection_id['Collection']['id'] = $_id[0][0]['max'];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$_id = $this->Application->getMaxCollectionId($_application_id[0]['Application']['id'], 'issue');
|
||||||
|
$_collection_id['Collection']['id'] = $_id[0][0]['max'];
|
||||||
|
}
|
||||||
|
|
||||||
// The second query will retrieve all the issues that are related to our
|
// The second query will retrieve all the issues that are related to our
|
||||||
// application.
|
// application.
|
||||||
$_query = "
|
$_query = "
|
||||||
SELECT
|
SELECT
|
||||||
issues.description, issues.id
|
choices.description, choices.id
|
||||||
FROM
|
FROM
|
||||||
applications_issues, issues
|
choices
|
||||||
WHERE
|
JOIN choices_collections ON choices_collections.choice_id = choices.id
|
||||||
applications_issues.application_id = {$_application_id[0]['Application']['id']}
|
JOIN collections ON collections.id = choices_collections.collection_id
|
||||||
AND
|
JOIN applications_collections ON applications_collections.collection_id = collections.id
|
||||||
issues.id = applications_issues.issue_id
|
JOIN applications ON applications.id = applications_collections.application_id
|
||||||
|
AND applications.id = {$_application_id[0]['Application']['id']}
|
||||||
|
AND choices.type = 'issue'
|
||||||
|
";
|
||||||
|
if (!empty($_collection_id['Collection']['id'])) {
|
||||||
|
$_query .= "AND collections.id = {$_collection_id['Collection']['id']}";
|
||||||
|
}
|
||||||
|
$_query .= "
|
||||||
ORDER BY
|
ORDER BY
|
||||||
issues.description DESC
|
choices.description DESC
|
||||||
";
|
";
|
||||||
|
|
||||||
$_issues = $this->query($_query);
|
$_issues = $this->query($_query);
|
||||||
|
@ -363,24 +408,27 @@ class Result extends AppModel {
|
||||||
// Cake has a pretty specific way it stores data, and this is consistent
|
// Cake has a pretty specific way it stores data, and this is consistent
|
||||||
// with the old query. Here we start our results array so it's holding the
|
// with the old query. Here we start our results array so it's holding the
|
||||||
// descriptions and a zeroed total
|
// descriptions and a zeroed total
|
||||||
$_results[$val['issues']['id']]['issues']['description'] = $val['issues']['description'];
|
$_results[$val['choices']['id']]['choices']['description'] = $val['choices']['description'];
|
||||||
$_results[$val['issues']['id']][0]['total'] = 0; // default to nothing - this will get filled in later
|
$_results[$val['choices']['id']][0]['total'] = 0; // default to nothing - this will get filled in later
|
||||||
|
|
||||||
// Since we're already walking through this loop, we might as well build
|
// Since we're already walking through this loop, we might as well build
|
||||||
// up a query string to get our totals
|
// up a query string to get our totals
|
||||||
$_issue_ids .= empty($_issue_ids) ? $val['issues']['id'] : ', '.$val['issues']['id'];
|
$_issue_ids .= empty($_issue_ids) ? $val['choices']['id'] : ',
|
||||||
|
'.$val['choices']['id'];
|
||||||
}
|
}
|
||||||
|
|
||||||
$_query = "
|
$_query = "
|
||||||
SELECT
|
SELECT
|
||||||
issues_results.issue_id, count(id)
|
choices_results.choice_id, count(results.id)
|
||||||
AS
|
AS
|
||||||
total
|
total
|
||||||
FROM
|
FROM
|
||||||
issues_results
|
results
|
||||||
JOIN results ON results.id=issues_results.result_id
|
JOIN choices_results ON results.id = choices_results.result_id
|
||||||
AND results.application_id={$_application_id[0]['Application']['id']}
|
WHERE
|
||||||
AND issues_results.issue_id in ({$_issue_ids})
|
results.application_id = {$_application_id[0]['Application']['id']}
|
||||||
|
AND
|
||||||
|
choices_results.choice_id in ({$_issue_ids})
|
||||||
";
|
";
|
||||||
|
|
||||||
if (!empty($params['start_date'])) {
|
if (!empty($params['start_date'])) {
|
||||||
|
@ -401,13 +449,13 @@ class Result extends AppModel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$_query .= "GROUP BY issue_id";
|
$_query .= " GROUP BY choices_results.choice_id";
|
||||||
|
|
||||||
$ret = $this->query($_query);
|
$ret = $this->query($_query);
|
||||||
|
|
||||||
foreach ($ret as $var => $val) {
|
foreach ($ret as $var => $val) {
|
||||||
// fill in the totals we retrieved
|
// fill in the totals we retrieved
|
||||||
$_results[$val['issues_results']['issue_id']][0]['total'] = $val[0]['total'];
|
$_results[$val['choices_results']['choice_id']][0]['total'] = $val[0]['total'];
|
||||||
}
|
}
|
||||||
|
|
||||||
return $_results;
|
return $_results;
|
||||||
|
@ -427,10 +475,10 @@ class Result extends AppModel {
|
||||||
// Apparently these are all escaped for us by cake. It still makes me
|
// Apparently these are all escaped for us by cake. It still makes me
|
||||||
// nervous.
|
// nervous.
|
||||||
$_application_id = $data['Application']['id'];
|
$_application_id = $data['Application']['id'];
|
||||||
$_intention_id = $data['Result']['intention_id'];
|
$_intention_id = $data['Intention']['id']; // Doesn't quite conform to cake standards
|
||||||
$_comments = $data['Result']['comments'];
|
$_comments = $data['Result']['comments'];
|
||||||
$_issues_text = $data['issues_results']['other'];
|
$_issues_text = $this->Sanitize->Sql($data['Issue']['text']);
|
||||||
$_intention_text = $data['Result']['intention_text'];
|
$_intention_text = $this->Sanitize->Sql($data['Intention']['text']);
|
||||||
// Joined for legacy reasons
|
// Joined for legacy reasons
|
||||||
$_user_agent = mysql_real_escape_string("{$data['ua'][0]} {$data['lang'][0]}");
|
$_user_agent = mysql_real_escape_string("{$data['ua'][0]} {$data['lang'][0]}");
|
||||||
$_http_user_agent = mysql_real_escape_string($_SERVER['HTTP_USER_AGENT']);
|
$_http_user_agent = mysql_real_escape_string($_SERVER['HTTP_USER_AGENT']);
|
||||||
|
@ -443,16 +491,21 @@ class Result extends AppModel {
|
||||||
// Special cases for the "other" fields. If their corresponding option isn't
|
// Special cases for the "other" fields. If their corresponding option isn't
|
||||||
// set, we don't want the field values.
|
// set, we don't want the field values.
|
||||||
// issue is determined below
|
// issue is determined below
|
||||||
$_issue_array = $this->Issue->findByDescription('other');
|
$this->Choice->unBindModel(array('hasAndBelongsToMany' => array('Result')));
|
||||||
$_intention_array = $this->Intention->findByDescription('other');
|
$this->Choice->unBindModel(array('hasAndBelongsToMany' => array('Collection')));
|
||||||
|
//$_issue_array = $this->Issue->findByDescription('other');
|
||||||
|
$_conditions = "description LIKE 'Other' AND type='intention'";
|
||||||
|
$_intention_array = $this->Choice->findAll($_conditions);
|
||||||
|
|
||||||
if ($_intention_id != $_intention_array['Intention']['id']) {
|
$_conditions = "description LIKE 'Other' AND type='issue'";
|
||||||
|
$_issue_array = $this->Choice->findAll($_conditions);
|
||||||
|
|
||||||
|
if ($_intention_id != $_intention_array[0]['Choice']['id']) {
|
||||||
|
echo 'not equal!';
|
||||||
$_intention_text = '';
|
$_intention_text = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->set('application_id', $_application_id);
|
$this->set('application_id', $_application_id);
|
||||||
$this->set('intention_id', $_intention_id);
|
|
||||||
$this->set('intention_text', $_intention_text);
|
|
||||||
$this->set('comments', $_comments);
|
$this->set('comments', $_comments);
|
||||||
$this->set('useragent', $_user_agent);
|
$this->set('useragent', $_user_agent);
|
||||||
$this->set('http_user_agent', $_http_user_agent);
|
$this->set('http_user_agent', $_http_user_agent);
|
||||||
|
@ -460,12 +513,29 @@ class Result extends AppModel {
|
||||||
// We kinda overrode $this's save(), so we'll have to ask our guardians
|
// We kinda overrode $this's save(), so we'll have to ask our guardians
|
||||||
parent::save();
|
parent::save();
|
||||||
|
|
||||||
|
$_result_id = $this->getLastInsertID();
|
||||||
|
|
||||||
// The issues_results table isn't represented by a class in cake, so we have
|
// Insert our intention
|
||||||
|
if (!empty($_intention_id)) {
|
||||||
|
$_query = "
|
||||||
|
INSERT INTO choices_results(
|
||||||
|
result_id,
|
||||||
|
choice_id,
|
||||||
|
other
|
||||||
|
) VALUES (
|
||||||
|
{$_result_id},
|
||||||
|
{$_intention_id},
|
||||||
|
'{$_intention_text}'
|
||||||
|
)
|
||||||
|
";
|
||||||
|
$this->query($_query);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// The choices_results table isn't represented by a class in cake, so we have
|
||||||
// to do the query manually.
|
// to do the query manually.
|
||||||
if (!empty($data['Issue']['id'])) {
|
if (!empty($data['Issue']['id'])) {
|
||||||
|
|
||||||
$_result_id = $this->getLastInsertID();
|
|
||||||
$_query = '';
|
$_query = '';
|
||||||
|
|
||||||
foreach ($data['Issue']['id'] as $var => $val) {
|
foreach ($data['Issue']['id'] as $var => $val) {
|
||||||
|
@ -475,15 +545,15 @@ class Result extends AppModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the 'other' id matches the id we're putting in, add the issue text
|
// If the 'other' id matches the id we're putting in, add the issue text
|
||||||
$_other_text = ($val == $_issue_array['Issue']['id']) ? $_issues_text : '';
|
$_other_text = ($val == $_issue_array[0]['Choice']['id']) ? $_issues_text : '';
|
||||||
|
|
||||||
$_query .= empty($_query) ? "({$_result_id},{$val},'{$_other_text}')" : ",({$_result_id},{$val},'{$_other_text}')";
|
$_query .= empty($_query) ? "({$_result_id},{$val},'{$_other_text}')" : ",({$_result_id},{$val},'{$_other_text}')";
|
||||||
}
|
}
|
||||||
|
|
||||||
$_query = "
|
$_query = "
|
||||||
INSERT INTO issues_results(
|
INSERT INTO choices_results(
|
||||||
result_id,
|
result_id,
|
||||||
issue_id,
|
choice_id,
|
||||||
other
|
other
|
||||||
) VALUES
|
) VALUES
|
||||||
{$_query}
|
{$_query}
|
||||||
|
@ -494,5 +564,6 @@ class Result extends AppModel {
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
|
|
|
@ -32,5 +32,25 @@ class ExportHelper
|
||||||
|
|
||||||
return "{$this->webroot}{$url}{$seperator}{$arguments}";
|
return "{$this->webroot}{$url}{$seperator}{$arguments}";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function buildCsvExportString($params)
|
||||||
|
{
|
||||||
|
if (array_key_exists('product', $params)) {
|
||||||
|
$filename = $params['product'];
|
||||||
|
} else {
|
||||||
|
$filename = DEFAULT_APP_NAME.' '.DEFAULT_APP_VERSION;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Our filenames have underscores
|
||||||
|
$filename = str_replace(' ','_',$filename);
|
||||||
|
|
||||||
|
$filename = "export-{$filename}.csv";
|
||||||
|
|
||||||
|
if (is_readable(ROOT.DS.APP_DIR.DS.WEBROOT_DIR.DS.'export'.DS.$filename)) {
|
||||||
|
return "{$this->webroot}export/{$filename}";
|
||||||
|
} else {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
<?php echo $html->formTag('/results/add'); ?>
|
<?php echo $html->formTag('/results/add'); ?>
|
||||||
|
|
||||||
<?php if(!empty($intentions['Intention'])): ?>
|
<?php if(!empty($intentions)): ?>
|
||||||
<h2>How did you intend to use <?php echo $intentions['Application']['name']; ?> when you installed it?</h2>
|
<h2>How did you intend to use <?php echo $intentions[0]['applications']['name']; ?> when you installed it?</h2>
|
||||||
<?php foreach ($intentions['Intention'] as $var => $val) : ?>
|
<?php foreach ($intentions as $var => $val) : ?>
|
||||||
<input type="radio" name="data[Result][intention_id]" id="radio<?php echo $val['id']; ?>" value="<?php echo $val['id']; ?>"><label for="radio<?php echo $val['id']; ?>"><?php echo $val['description']; ?></label>
|
<input type="radio" name="data[Intention][id]" id="radio<?php echo $val['choices']['id']; ?>" value="<?php echo $val['choices']['id']; ?>"><label for="radio<?php echo $val['choices']['id']; ?>"><?php echo $val['choices']['description']; ?></label>
|
||||||
<?php
|
<?php
|
||||||
if ($val['description'] == 'Other') {
|
if ($val['choices']['description'] == 'Other') {
|
||||||
echo $html->input('Result/intention_text');
|
echo $html->input('Intention/text');
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
?>
|
||||||
|
@ -14,21 +14,20 @@
|
||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<?php if(!empty($issues)): ?>
|
||||||
<?php if(!empty($issues['Issue'])): ?>
|
<h2>Why did you uninstall <?php echo $issues[0]['applications']['name']; ?>? (select all that apply)</h2>
|
||||||
<h2>Why did you uninstall <?php echo $intentions['Application']['name']; ?>? (select all that apply)</h2>
|
<?php foreach ($issues as $var => $val) : ?>
|
||||||
<?php foreach ($issues['Issue'] as $var => $val) : ?>
|
<input type="checkbox" name="data[Issue][id][]" id="checkbox<?php echo $val['choices']['id']; ?>" value="<?php echo $val['choices']['id']; ?>"><label for="checkbox<?php echo $val['choices']['id']; ?>"><?php echo $val['choices']['description']; ?></label>
|
||||||
<input type="checkbox" name="data[Issue][id][]" id="checkbox<?php echo $val['id']; ?>" value="<?php echo $val['id']; ?>"><label for="checkbox<?php echo $val['id']; ?>"><?php echo $val['description']; ?></label>
|
|
||||||
<?php
|
<?php
|
||||||
if ($val['description'] == 'Other') {
|
if ($val['choices']['description'] == 'Other') {
|
||||||
echo $html->input('issues_results/other');
|
echo $html->input('Issue/text');
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
<br />
|
<br />
|
||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
|
||||||
<h2>How can we improve <?php echo $intentions['Application']['name']; ?>?</h2>
|
<h2>How can we improve <?php echo $intentions[0]['applications']['name']; ?>?</h2>
|
||||||
<p>Please share your ideas, suggestions or details about any issues below.</p>
|
<p>Please share your ideas, suggestions or details about any issues below.</p>
|
||||||
<p><?php echo $html->textarea('Result/comments',array('id'=>'comments'));?></p>
|
<p><?php echo $html->textarea('Result/comments',array('id'=>'comments'));?></p>
|
||||||
|
|
||||||
|
@ -37,6 +36,5 @@
|
||||||
<?php echo $html->hidden('ua', 'value="'.$url_params['ua'].'"') ?>
|
<?php echo $html->hidden('ua', 'value="'.$url_params['ua'].'"') ?>
|
||||||
<?php echo $html->hidden('lang', 'value="'.$url_params['lang'].'"') ?>
|
<?php echo $html->hidden('lang', 'value="'.$url_params['lang'].'"') ?>
|
||||||
|
|
||||||
|
|
||||||
<p><?php echo $html->submit('Save') ?></p>
|
<p><?php echo $html->submit('Save') ?></p>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
<h1><?php echo Inflector::humanize($this->name); ?></h1>
|
<h1><?php echo Inflector::humanize($this->name); ?></h1>
|
||||||
|
|
||||||
<div id="queryform">
|
<div id="queryform">
|
||||||
<?php echo $html->formTag('/results/','get'); ?>
|
<?php echo $html->formTag('/results/','get');?>
|
||||||
<span>
|
<span>
|
||||||
<label for="start_date">Start Date:</label>
|
<label for="start_date">Start:</label>
|
||||||
<input type="text" name="start_date" id="start_date" value="<? echo isset($url_params['start_date']) ? $url_params['start_date'] : ''; ?>" />
|
<input type="text" name="start_date" id="start_date" value="<? echo isset($url_params['start_date']) ? $url_params['start_date'] : ''; ?>" />
|
||||||
<label for="end_date">End Date:</label>
|
<label for="end_date">End:</label>
|
||||||
<input type="text" name="end_date" id="end_date" value="<? echo isset($url_params['end_date']) ? $url_params['end_date'] : ''; ?>" />
|
<input type="text" name="end_date" id="end_date" value="<? echo isset($url_params['end_date']) ? $url_params['end_date'] : ''; ?>" />
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
|
@ -20,6 +20,24 @@
|
||||||
|
|
||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
</select>
|
</select>
|
||||||
|
<?php if (!empty($collections)) : ?>
|
||||||
|
<label for="collection">Questions:</label>
|
||||||
|
<select name="collection" id="collection">
|
||||||
|
<?php
|
||||||
|
foreach ($collections as $select) :
|
||||||
|
$collection = $select['collections']['description'];
|
||||||
|
// php's built in functions won't decode UTF-8 or numeric
|
||||||
|
// entities. Since we've only got 1, I'm putting in this to
|
||||||
|
// get this done quickly. :(
|
||||||
|
$url_params['collection'] = str_replace('-','-',urldecode($url_params['collection']));
|
||||||
|
echo "{$url_params['collection']}<br />";
|
||||||
|
$selected = ($collection == trim($url_params['collection'])) ? ' selected="selected" ' : '';
|
||||||
|
?>
|
||||||
|
<option<?=$selected?>><?=$collection?></option>
|
||||||
|
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</select>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
<input type="submit" name="submit" id="submit" value="Go" />
|
<input type="submit" name="submit" id="submit" value="Go" />
|
||||||
</form>
|
</form>
|
||||||
|
@ -43,7 +61,7 @@
|
||||||
}
|
}
|
||||||
foreach ($descriptionAndTotalsData as $var => $val) {
|
foreach ($descriptionAndTotalsData as $var => $val) {
|
||||||
// We're putting this in a js string, so escape the double quotes
|
// We're putting this in a js string, so escape the double quotes
|
||||||
$_description = str_replace('"','\"',$val['issues']['description']);
|
$_description = str_replace('"','\"',$val['choices']['description']);
|
||||||
$_percentage = intval(($val[0]['total'] / $_total)*100);
|
$_percentage = intval(($val[0]['total'] / $_total)*100);
|
||||||
|
|
||||||
$_dataset .= "[{$_count}, {$val[0]['total']}, \"{$_description} (n={$val[0]['total']}, {$_percentage}%)\"], ";
|
$_dataset .= "[{$_count}, {$val[0]['total']}, \"{$_description} (n={$val[0]['total']}, {$_percentage}%)\"], ";
|
||||||
|
@ -56,12 +74,12 @@
|
||||||
<table class="results" summary="Firefox Uninstallation results.">
|
<table class="results" summary="Firefox Uninstallation results.">
|
||||||
<tr><th>Reason for uninstalling</th><th>Total</th></tr>
|
<tr><th>Reason for uninstalling</th><th>Total</th></tr>
|
||||||
<?php foreach ($descriptionAndTotalsData as $var => $val) : ?>
|
<?php foreach ($descriptionAndTotalsData as $var => $val) : ?>
|
||||||
<tr><td><?=$val['issues']['description']?></td><td><?=$val[0]['total']?></td></tr>
|
<tr><td><?=$val['choices']['description']?></td><td><?=$val[0]['total']?></td></tr>
|
||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
</table>
|
</table>
|
||||||
</canvas>
|
</canvas>
|
||||||
</div>
|
</div>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript"><!--
|
||||||
var layout = new PlotKit.Layout("bar", {"barOrientation":"horizontal"});
|
var layout = new PlotKit.Layout("bar", {"barOrientation":"horizontal"});
|
||||||
layout.addDataset("results", <?=$_dataset?>);
|
layout.addDataset("results", <?=$_dataset?>);
|
||||||
layout.evaluate();
|
layout.evaluate();
|
||||||
|
@ -78,11 +96,17 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
plotter.render();
|
plotter.render();
|
||||||
</script>
|
--></script>
|
||||||
|
|
||||||
|
|
||||||
<div id="exportbox">
|
<div id="exportbox">
|
||||||
<a href="<?php echo $export->buildUrlString('results/comments/',$url_params); ?>">View Any Associated Comments»</a><br />
|
<a href="<?php echo $export->buildUrlString('results/comments/',$url_params); ?>">View Any Associated Comments»</a><br />
|
||||||
|
<?php
|
||||||
|
$export_url = $export->buildCsvExportString($url_params);
|
||||||
|
if (!empty($export_url)):
|
||||||
|
?>
|
||||||
|
<a href="<?php echo $export_url; ?>">Download the Complete Dataset»</a><br />
|
||||||
|
<?php endif; ?>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<?php else: ?>
|
<?php else: ?>
|
||||||
|
|
Загрузка…
Ссылка в новой задаче