From ab4df73b134f02209f5e49e3ae97b01b70fb19bb Mon Sep 17 00:00:00 2001 From: "wclouser%mozilla.com" Date: Thu, 29 Jun 2006 21:41:14 +0000 Subject: [PATCH] Reworked the database. we now have "question sets" which will allow us versioning --- .../controllers/intentions_controller.php | 0 .../controllers/issues_controller.php | 0 .../controllers/results_controller.php | 33 ++- .../uninstall_survey/models/application.php | 180 ++++++++++++++- .../uninstall_survey/models/intention.php | 0 webtools/uninstall_survey/models/issue.php | 0 webtools/uninstall_survey/models/result.php | 211 ++++++++++++------ .../uninstall_survey/views/helpers/export.php | 20 ++ .../uninstall_survey/views/results/add.thtml | 28 ++- .../views/results/index.thtml | 38 +++- 10 files changed, 398 insertions(+), 112 deletions(-) delete mode 100644 webtools/uninstall_survey/controllers/intentions_controller.php delete mode 100644 webtools/uninstall_survey/controllers/issues_controller.php delete mode 100644 webtools/uninstall_survey/models/intention.php delete mode 100644 webtools/uninstall_survey/models/issue.php diff --git a/webtools/uninstall_survey/controllers/intentions_controller.php b/webtools/uninstall_survey/controllers/intentions_controller.php deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/webtools/uninstall_survey/controllers/issues_controller.php b/webtools/uninstall_survey/controllers/issues_controller.php deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/webtools/uninstall_survey/controllers/results_controller.php b/webtools/uninstall_survey/controllers/results_controller.php index ac40f3394c1..c81b3ee123a 100644 --- a/webtools/uninstall_survey/controllers/results_controller.php +++ b/webtools/uninstall_survey/controllers/results_controller.php @@ -11,7 +11,7 @@ class ResultsController extends AppController { * Model's this controller uses * @var array */ - var $uses = array('Application','Result','Intention','Issue'); + var $uses = array('Application','Collection','Choice','Result'); /** * 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_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 - // comes over $_GET in the form: + // The ua comes over $_GET in the form: // x.x.x.x (aa-bb) // Where x is the versions and a and b are locale information. We're not // interested in the locale information, @@ -83,7 +82,6 @@ class ResultsController extends AppController { $app_id = $app->getLastInsertID(); - // Warning: hard coding ahead! - Hopefully this is a temporary thing. // The database will handle any combination of questions // (issues/intentions) and applications+versions. However, since we're // 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. if (stristr($this->params['url']['application'], 'Firefox') !== false) { // 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 - $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) { // 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 - $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 { // 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"; $_application = $this->Application->findAll($_conditions); } - // Pull the information for our radio buttons (only the // 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 - $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 $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 $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 $this->set('descriptionAndTotalsData',$this->Result->getDescriptionAndTotalsData($this->params['url'])); } @@ -215,8 +215,17 @@ class ResultsController extends AppController { // Get rid of the header/footer/etc. $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! - 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. // In development, that means extra lines get added to our CSVs, but in diff --git a/webtools/uninstall_survey/models/application.php b/webtools/uninstall_survey/models/application.php index 59f8dc4ddb1..5b9ba6130e4 100644 --- a/webtools/uninstall_survey/models/application.php +++ b/webtools/uninstall_survey/models/application.php @@ -1,4 +1,5 @@ array( - 'className' => 'Intention', - 'order' => 'pos' - ), - 'Issue' => array( - 'className' => 'Issue', - 'order' => 'pos' - ) + 'Collection' => array( 'className' => 'Collection') ); + + 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); + } + } ?> diff --git a/webtools/uninstall_survey/models/intention.php b/webtools/uninstall_survey/models/intention.php deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/webtools/uninstall_survey/models/issue.php b/webtools/uninstall_survey/models/issue.php deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/webtools/uninstall_survey/models/result.php b/webtools/uninstall_survey/models/result.php index bf0aaf965e9..6aa08b8759f 100644 --- a/webtools/uninstall_survey/models/result.php +++ b/webtools/uninstall_survey/models/result.php @@ -2,17 +2,22 @@ class Result extends AppModel { var $name = 'Result'; - var $belongsTo = array('Application', 'Intention'); + var $belongsTo = array('Application'); - var $hasAndBelongsToMany = array('Issue' => - array('className' => 'Issue', - 'joinTable' => 'issues_results', - 'foreignKey'=> 'issue_id', - 'assocationForeignKey'=>'result_id', + var $hasAndBelongsToMany = array('Choice' => + array('className' => 'Choice', 'uniq' => true ) ); + var $Sanitize; + + function Result() + { + parent::appModel(); + $this->Sanitize = new Sanitize(); + } + /** * Count's all the comments, according to the parameters. * @param array URL parameters @@ -59,15 +64,15 @@ class Result extends AppModel { array_push($_conditions, "`Application`.`version` LIKE '{$_version}'"); } else { // defaults I guess? - array_push($_conditions, "`Application`.`name` LIKE 'Mozilla Firefox'"); - array_push($_conditions, "`Application`.`version` LIKE '1.5'"); + array_push($_conditions, "`Application`.`name` LIKE '".DEFAULT_APP_NAME."'"); + array_push($_conditions, "`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 - array_push($_conditions, "`Application`.`name` LIKE 'Mozilla Firefox'"); - array_push($_conditions, "`Application`.`version` LIKE '1.5'"); + array_push($_conditions, "`Application`.`name` LIKE '".DEFAULT_APP_NAME."'"); + array_push($_conditions, "`Application`.`version` LIKE '".DEFAULT_APP_VERSION."'"); } // Do the actual query @@ -124,34 +129,43 @@ class Result extends AppModel { array_push($_conditions, "`Application`.`version` LIKE '{$_version}'"); } else { // defaults I guess? - array_push($_conditions, "`Application`.`name` LIKE 'Mozilla Firefox'"); - array_push($_conditions, "`Application`.`version` LIKE '1.5'"); + array_push($_conditions, "`Application`.`name` LIKE '".DEFAULT_APP_NAME."'"); + array_push($_conditions, "`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 - array_push($_conditions, "`Application`.`name` LIKE 'Mozilla Firefox'"); - array_push($_conditions, "`Application`.`version` LIKE '1.5'"); + array_push($_conditions, "`Application`.`name` LIKE '".DEFAULT_APP_NAME."'"); + array_push($_conditions, "`Application`.`version` LIKE '".DEFAULT_APP_VERSION."'"); } // Save ourselves quite a few joins - $this->unBindModel(array('hasAndBelongsToMany' => array('Issue'))); $comments = $this->findAll($_conditions, null, $pagination['order'], $pagination['show'], $pagination['page']); 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) { // Handle foo@bar.com $_email_regex = '/\ ?(.+)?@(.+)?\.(.+)?\ ?/'; - $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']); + $comments[$var]['Result'] = preg_replace($_email_regex,'$1@****.$3',$comments[$var]['Result']); + + //$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 $_phone_regex = '/([0-9]{3})[ .-]?[0-9]{4}/'; - $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']); + $comments[$var]['Result'] = preg_replace($_phone_regex,'$1-****',$comments[$var]['Result']); + + //$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}'"; } else { // defaults I guess? - $_query .= " AND `applications`.`name` LIKE 'Mozilla Firefox'"; - $_query .= " AND `applications`.`version` LIKE '1.5'"; + $_query .= " AND `applications`.`name` LIKE '".DEFAULT_APP_NAME."'"; + $_query .= " AND `applications`.`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 - $_query .= " AND `applications`.`name` LIKE 'Mozilla Firefox'"; - $_query .= " AND `applications`.`version` LIKE '1.5'"; + $_query .= " AND `applications`.`name` LIKE '".DEFAULT_APP_NAME."'"; + $_query .= " AND `applications`.`version` LIKE '".DEFAULT_APP_VERSION."'"; } $_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 // dimensional table array - $newdata = array(); foreach ($res as $result) { @@ -244,18 +257,28 @@ class Result extends AppModel { } 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) { // Handle foo@bar.com $_email_regex = '/\ ?(.+)?@(.+)?\.(.+)?\ ?/'; - $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']); + $newdata[$var] = preg_replace($_email_regex,'$1@****.$3',$newdata[$var]); + + //$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 $_phone_regex = '/([0-9]{3})[ .-]?[0-9]{4}/'; - $newdata[$var]['comments'] = preg_replace($_phone_regex,'$1-****',$newdata[$var]['comments']); - $newdata[$var]['intention_other'] = preg_replace($_phone_regex,'$1-****',$newdata[$var]['intention_other']); + $newdata[$var] = preg_replace($_phone_regex,'$1-****',$newdata[$var]); + + //$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 * 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). //It would be nice to drop something like this in the SELECT: @@ -323,35 +346,57 @@ class Result extends AppModel { $_conditions .= " AND `Application`.`version` LIKE '{$_version}'"; } else { // defaults I guess? - $_conditions .= " AND `Application`.`name` LIKE 'Mozilla Firefox'"; - $_conditions .= " AND `Application`.`version` LIKE '1.5'"; + $_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 'Mozilla Firefox'"; - $_conditions .= " AND `Application`.`version` LIKE '1.5'"; + $_conditions .= " AND `Application`.`name` LIKE '".DEFAULT_APP_NAME."'"; + $_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'); + + // 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 // application. $_query = " SELECT - issues.description, issues.id + choices.description, choices.id FROM - applications_issues, issues - WHERE - applications_issues.application_id = {$_application_id[0]['Application']['id']} - AND - issues.id = applications_issues.issue_id - ORDER BY - issues.description DESC + choices + JOIN choices_collections ON choices_collections.choice_id = choices.id + JOIN collections ON collections.id = choices_collections.collection_id + JOIN applications_collections ON applications_collections.collection_id = collections.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 + choices.description DESC + "; $_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 // with the old query. Here we start our results array so it's holding the // descriptions and a zeroed total - $_results[$val['issues']['id']]['issues']['description'] = $val['issues']['description']; - $_results[$val['issues']['id']][0]['total'] = 0; // default to nothing - this will get filled in later + $_results[$val['choices']['id']]['choices']['description'] = $val['choices']['description']; + $_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 // 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 = " SELECT - issues_results.issue_id, count(id) + choices_results.choice_id, count(results.id) AS total FROM - issues_results - JOIN results ON results.id=issues_results.result_id - AND results.application_id={$_application_id[0]['Application']['id']} - AND issues_results.issue_id in ({$_issue_ids}) + results + JOIN choices_results ON results.id = choices_results.result_id + WHERE + results.application_id = {$_application_id[0]['Application']['id']} + AND + choices_results.choice_id in ({$_issue_ids}) "; 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); foreach ($ret as $var => $val) { // 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; @@ -427,10 +475,10 @@ class Result extends AppModel { // Apparently these are all escaped for us by cake. It still makes me // nervous. $_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']; - $_issues_text = $data['issues_results']['other']; - $_intention_text = $data['Result']['intention_text']; + $_issues_text = $this->Sanitize->Sql($data['Issue']['text']); + $_intention_text = $this->Sanitize->Sql($data['Intention']['text']); // Joined for legacy reasons $_user_agent = mysql_real_escape_string("{$data['ua'][0]} {$data['lang'][0]}"); $_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 // set, we don't want the field values. // issue is determined below - $_issue_array = $this->Issue->findByDescription('other'); - $_intention_array = $this->Intention->findByDescription('other'); - - if ($_intention_id != $_intention_array['Intention']['id']) { + $this->Choice->unBindModel(array('hasAndBelongsToMany' => array('Result'))); + $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); + + $_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 = ''; } $this->set('application_id', $_application_id); - $this->set('intention_id', $_intention_id); - $this->set('intention_text', $_intention_text); $this->set('comments', $_comments); $this->set('useragent', $_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 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. if (!empty($data['Issue']['id'])) { - $_result_id = $this->getLastInsertID(); $_query = ''; 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 - $_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 = " - INSERT INTO issues_results( + INSERT INTO choices_results( result_id, - issue_id, + choice_id, other ) VALUES {$_query} @@ -494,5 +564,6 @@ class Result extends AppModel { return false; } + } ?> diff --git a/webtools/uninstall_survey/views/helpers/export.php b/webtools/uninstall_survey/views/helpers/export.php index 6bb2b99e3ab..0e6281ac49f 100644 --- a/webtools/uninstall_survey/views/helpers/export.php +++ b/webtools/uninstall_survey/views/helpers/export.php @@ -32,5 +32,25 @@ class ExportHelper 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 ''; + } + } } ?> diff --git a/webtools/uninstall_survey/views/results/add.thtml b/webtools/uninstall_survey/views/results/add.thtml index bd0711d4947..7666891ebb6 100644 --- a/webtools/uninstall_survey/views/results/add.thtml +++ b/webtools/uninstall_survey/views/results/add.thtml @@ -1,12 +1,12 @@ formTag('/results/add'); ?> - -

How did you intend to use when you installed it?

- $val) : ?> - + +

How did you intend to use when you installed it?

+ $val) : ?> + input('Result/intention_text'); + if ($val['choices']['description'] == 'Other') { + echo $html->input('Intention/text'); } ?> @@ -14,21 +14,20 @@ - - -

Why did you uninstall ? (select all that apply)

- $val) : ?> - + +

Why did you uninstall ? (select all that apply)

+ $val) : ?> + input('issues_results/other'); + if ($val['choices']['description'] == 'Other') { + echo $html->input('Issue/text'); } ?>
-

How can we improve ?

+

How can we improve ?

Please share your ideas, suggestions or details about any issues below.

textarea('Result/comments',array('id'=>'comments'));?>

@@ -37,6 +36,5 @@ hidden('ua', 'value="'.$url_params['ua'].'"') ?> hidden('lang', 'value="'.$url_params['lang'].'"') ?> -

submit('Save') ?>

diff --git a/webtools/uninstall_survey/views/results/index.thtml b/webtools/uninstall_survey/views/results/index.thtml index 982b89f94fd..0e65211e605 100644 --- a/webtools/uninstall_survey/views/results/index.thtml +++ b/webtools/uninstall_survey/views/results/index.thtml @@ -1,11 +1,11 @@

name); ?>

- formTag('/results/','get'); ?> + formTag('/results/','get');?> - + - + @@ -20,6 +20,24 @@ + + + + @@ -43,7 +61,7 @@ } foreach ($descriptionAndTotalsData as $var => $val) { // 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); $_dataset .= "[{$_count}, {$val[0]['total']}, \"{$_description} (n={$val[0]['total']}, {$_percentage}%)\"], "; @@ -56,12 +74,12 @@ $val) : ?> - +
Reason for uninstallingTotal
- + -->
View Any Associated Comments»
+ buildCsvExportString($url_params); + if (!empty($export_url)): + ?> + Download the Complete Dataset»
+