Skip to content

Commit

Permalink
Send Email Notifications on newly added reports
Browse files Browse the repository at this point in the history
Send these notifications to developers@phpmyadmin.net

Fix #31

Signed-off-by: Deven Bansod <devenbansod.bits@gmail.com>
  • Loading branch information
devenbansod committed Jun 5, 2017
1 parent 2a5c559 commit 29a6423
Show file tree
Hide file tree
Showing 10 changed files with 366 additions and 44 deletions.
3 changes: 3 additions & 0 deletions config/app_example.php
Expand Up @@ -324,4 +324,7 @@
'Session' => [
'defaults' => 'php',
],

'NotificationEmailTo' => 'developers@phpmyadmin.net',
'NotificationEmailFrom' => 'developers@phpmyadmin.net'
];
4 changes: 4 additions & 0 deletions config/app_travis.php
Expand Up @@ -323,4 +323,8 @@
'Session' => [
'defaults' => 'php',
],


'NotificationEmailTo' => '',
'NotificationEmailFrom' => ''
];
67 changes: 67 additions & 0 deletions src/Controller/Component/MailerComponent.php
@@ -0,0 +1,67 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */

/**
* Mailer component handling sending of report notification mails
*
* phpMyAdmin Error reporting server
* Copyright (c) phpMyAdmin project (https://www.phpmyadmin.net/)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) phpMyAdmin project (https://www.phpmyadmin.net/)
* @license https://opensource.org/licenses/mit-license.php MIT License
*
* @see https://www.phpmyadmin.net/
*/

namespace App\Controller\Component;

use Cake\Controller\Component;
use Cake\ORM\TableRegistry;
use Cake\Mailer\Email;
use Cake\Core\Configure;

/**
* Mailer component handling report notification emails.
*/
class MailerComponent extends Component
{
/**
* Send an email about the report to configured Email
*
* @param $viewVars Array of View Variables
*
* @return boolean if Email was sent
*/
public function sendReportMail($viewVars)
{
$email = new Email();
$emailTo = Configure::read('NotificationEmailsTo');
$emailFrom = Configure::read('NotificationEmailsFrom');

if (! $emailTo || $emailTo === ''
|| ! $emailFrom || $emailFrom === ''
) {
return false;
}

$email->transport('default')
->viewVars($viewVars)
->subject(
sprintf(
'A new report has been submitted on the Error Reporting Server: %s',
$viewVars['report']['id']
)
)
->template('report', 'default')
->emailFormat('html')
->to($emailTo)
->from($emailFrom)
->send();

return true;
}
}
62 changes: 58 additions & 4 deletions src/Controller/IncidentsController.php
Expand Up @@ -19,7 +19,9 @@

namespace App\Controller;

use Cake\Core\Configure;
use Cake\Network\Exception\NotFoundException;
use Cake\ORM\TableRegistry;

/**
* Incidents controller handling incident creation and rendering.
Expand All @@ -28,20 +30,23 @@ class IncidentsController extends AppController
{
public $uses = array('Incident', 'Notification');

public $components = array('Mailer');

public function create()
{
// Only allow POST requests
$this->request->allowMethod(['post']);

$bugReport = $this->request->input('json_decode', true);
$result = $this->Incidents->createIncidentFromBugReport($bugReport);
if (count($result) > 0
&& !in_array(false, $result)

if (count($result['incidents']) > 0
&& !in_array(false, $result['incidents'])
) {
$response = array(
'success' => true,
'message' => 'Thank you for your submission',
'incident_id' => $result, // Return a list of incident ids.
'incident_id' => $result['incidents'], // Return a list of incident ids.
);
} else {
$response = array(
Expand All @@ -54,7 +59,15 @@ public function create()
'Content-Type' => 'application/json',
'X-Content-Type-Options' => 'nosniff',
));
$this->response->body(json_encode($response, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES));
$this->response->body(
json_encode($response, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES)
);

// For all the newly added reports,
// send notification emails
foreach ($result['reports'] as $report_id) {
$this->_sendNotificationMail($report_id);
}

return $this->response;
}
Expand Down Expand Up @@ -100,4 +113,45 @@ public function view($incidentId)

$this->set('incident', $incident);
}

private function _sendNotificationMail($reportId)
{
$this->Reports = TableRegistry::get('Reports');
$report = $this->Reports->findById($reportId)->all()->first()->toArray();
$this->Reports->id = $reportId;

$viewVars = array(
'report' => $report,
'project_name' => Configure::read('GithubRepoPath'),
'incidents' => $this->Reports->getIncidents()->toArray(),
'incidents_with_description' => $this->Reports->getIncidentsWithDescription(),
'incidents_with_stacktrace' => $this->Reports->getIncidentsWithDifferentStacktrace(),
'related_reports' => $this->Reports->getRelatedReports(),
'status' => $this->Reports->status
);
$viewVars = array_merge($viewVars, $this->_getSimilarFields($reportId));

$this->Mailer->sendReportMail($viewVars);
}

protected function _getSimilarFields($id)
{
$this->Reports->id = $id;

$viewVars = array(
'columns' => TableRegistry::get('Incidents')->summarizableFields
);
$relatedEntries = array();

foreach (TableRegistry::get('Incidents')->summarizableFields as $field) {
list($entriesWithCount, $totalEntries) =
$this->Reports->getRelatedByField($field, 25, true);
$relatedEntries[$field] = $entriesWithCount;
$viewVars["${field}_distinct_count"] = $totalEntries;
}

$viewVars['related_entries'] = $relatedEntries;

return $viewVars;
}
}
13 changes: 11 additions & 2 deletions src/Model/Table/IncidentsTable.php
Expand Up @@ -152,15 +152,19 @@ public function __construct($id = false, $table = null, $ds = null)
*
* @param array $bugReport the bug report being submitted
*
* @return array of inserted incident ids. If the report/incident was not
* @return array of:
* 1. array of inserted incident ids. If the report/incident was not
* correctly saved, false is put in it place.
* 2. array of newly created report ids. If no new report was created,
* an empty array is returned
*/
public function createIncidentFromBugReport($bugReport)
{
if ($bugReport == null) {
return array(false);
}
$incident_ids = array(); // array to hold ids of all the inserted incidents
$new_report_ids = array(); // array to hold ids of all newly created reports

// Also sanitizes the bug report
$schematizedIncidents = $this->_getSchematizedIncidents($bugReport);
Expand Down Expand Up @@ -193,7 +197,9 @@ public function createIncidentFromBugReport($bugReport)
$report->created = date('Y-m-d H:i:s', time());
$report->modified = date('Y-m-d H:i:s', time());
$reportsTable->save($report);

$si['report_id'] = $report->id;
$new_report_ids[] = $report->id;
$si = $incidentsTable->newEntity($si);
$si->created = date('Y-m-d H:i:s', time());
$si->modified = date('Y-m-d H:i:s', time());
Expand All @@ -219,7 +225,10 @@ public function createIncidentFromBugReport($bugReport)
}
}

return $incident_ids;
return array(
'incidents' => $incident_ids,
'reports' => $new_report_ids
);
}

/**
Expand Down
163 changes: 163 additions & 0 deletions src/Template/Email/html/report.ctp
@@ -0,0 +1,163 @@
<?php
/**
* Report Notification Email Template
*
* phpMyAdmin Error reporting server
* Copyright (c) phpMyAdmin project (https://www.phpmyadmin.net/)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) phpMyAdmin project (https://www.phpmyadmin.net/)
* @license https://opensource.org/licenses/mit-license.php MIT License
*
* @see https://www.phpmyadmin.net/
*/
?>
<?php use Cake\Routing\Router; ?>

<p>
A new error report has been added on the phpMyAdmin's Error Reporting System.
</p>
<p>
The details of the report are as follows:
</p>

<table cellspacing="0" style="border:1px solid #333">
<tr>
<td style="width:20%">Error Type</td>
<td><?= $report['exception_type'] ? 'php' : 'js'; ?></td>
</tr>
<tr>
<td>Error Name</td>
<td><?= $report['error_name']; ?></td>
</tr>
<tr>
<td>Error Message</td>
<td><?= $report['error_message']; ?></td>
</tr>
<tr>
<td>PMA Versions</td>
<td>
<?=
$this->Reports->entriesFromIncidents(
$related_entries['pma_version'],
$pma_version_distinct_count,
'pma_version'
);
?>
</td>
</tr>
<tr>
<td>PHP Versions</td>
<td>
<?=
$this->Reports->entriesFromIncidents(
$related_entries['php_version'],
$php_version_distinct_count,
'php_version'
);
?>
</td>
</tr>
<tr>
<td>Browsers</td>
<td>
<?=
$this->Reports->entriesFromIncidents(
$related_entries['browser'],
$browser_distinct_count,
'browser'
);
?>
</td>
</tr>
<?php if ($incidents[0]['exception_type']): // php ?>
<tr>
<td>Location</td>
<td><?= $report['location']; ?></td>
</tr>
<tr>
<td>Line Number</td>
<td><?= $report['linenumber']; ?></td>
</tr>
<?php else: ?>
<tr>
<td>Script Name</td>
<td>
<?=
$this->Reports->entriesFromIncidents(
$related_entries['script_name'],
$script_name_distinct_count,
'script_name'
);
?>
</td>
</tr>
<?php endif; ?>
<tr>
<td>Configuration Storage</td>
<td>
<?=
$this->Reports->entriesFromIncidents(
$related_entries['configuration_storage'],
$configuration_storage_distinct_count,
'configuration_storage'
);
?>
</td>
</tr>
<tr>
<td>Server Software</td>
<td>
<?=
$this->Reports->entriesFromIncidents(
$related_entries['server_software'],
$server_software_distinct_count,
'server_software'
);
?>
</td>
</tr>
<tr>
<td>User OS</td>
<td>
<?=
$this->Reports->entriesFromIncidents(
$related_entries['user_os'],
$user_os_distinct_count,
'user_os'
);
?>
</td>
</tr>
<tr>
<td>Locale</td>
<td>
<?=
$this->Reports->entriesFromIncidents(
$related_entries['locale'],
$locale_distinct_count,
'locale'
);
?>
</td>
</tr>
<tr>
<td>Incident Count</td>
<td><?= count($incidents) . ' incidents of this bug'; ?></td>
</tr>
<tr>
<td>Submission Date</td>
<td>
<?= $report['created']; ?>
</td>
</tr>
</table>

<p>
You can view the detailed report at
<a href="<?= Router::url('/reports/view/' . $report['id'], true) ?>">
#<?= $report['id'] ?></a>.
</p>

0 comments on commit 29a6423

Please sign in to comment.