diff options
-rw-r--r-- | .gitmodules | 3 | ||||
-rw-r--r-- | README.md | 1 | ||||
-rw-r--r-- | classes/BusinessAdmin.php | 22 | ||||
-rw-r--r-- | classes/Constants.php | 2 | ||||
-rw-r--r-- | classes/Contact.php | 11 | ||||
-rw-r--r-- | classes/Mail.php | 32 | ||||
-rw-r--r-- | classes/Mailer.php | 100 | ||||
-rw-r--r-- | classes/Offer.php | 26 | ||||
-rw-r--r-- | conf.php | 2 | ||||
-rw-r--r-- | conf.private.example.php | 13 | ||||
-rw-r--r-- | include/offers-view.php | 148 | ||||
-rw-r--r-- | include/offers.php | 20 | ||||
-rw-r--r-- | install/index.php | 21 | ||||
-rw-r--r-- | install/upgrade.php | 21 | ||||
m--------- | modules/PHPMailer | 0 |
15 files changed, 354 insertions, 68 deletions
diff --git a/.gitmodules b/.gitmodules index 2698b7a..5c4d8bd 100644 --- a/.gitmodules +++ b/.gitmodules @@ -7,3 +7,6 @@ [submodule "modules/braintree"] path = modules/braintree url = https://github.com/braintree/braintree_php.git +[submodule "modules/PHPMailer"] + path = modules/PHPMailer + url = https://github.com/PHPMailer/PHPMailer @@ -172,6 +172,7 @@ are listed by name and removal time. This way, you never really lose your file. ### 0.5 (Jul 28, 2016) +0.5.2 Emails. 0.5.1 Files are hidden from the world. 0.5 Braintree integration. diff --git a/classes/BusinessAdmin.php b/classes/BusinessAdmin.php index 7c3c76c..83fa4b3 100644 --- a/classes/BusinessAdmin.php +++ b/classes/BusinessAdmin.php @@ -407,6 +407,28 @@ class BusinessAdmin { } /** + * Create a new mail + * + * @param PDO $pdo The database connection + * @param int $contactId The contactId for the new mail + * @param int $offerId The offerId for the new mail + * @param string $subject + * + * @throws PDOException If something went wrong with the database + * + * @return Mail|bool A new instance of the Mail class, or false on failure + */ + public static function createMail($pdo, $contactId, $offerId, $subject) { + $stmt = $pdo->prepare("INSERT INTO `".Constants::db_prefix."mail` (`contactId`, `offerId`, `subject`) VALUES (?,?,?)"); + $stmt->execute([$contactId, $offerId, $subject]); + if ($stmt->rowCount() == 1) { + return new Mail($pdo, $pdo->lastInsertId()); + } else { + return false; + } + } + + /** * Format a date nicely * * @todo implement $relatively = true diff --git a/classes/Constants.php b/classes/Constants.php index fbac6cf..7528630 100644 --- a/classes/Constants.php +++ b/classes/Constants.php @@ -78,5 +78,5 @@ class Constants { const password_cost = 10; /** @const version Version of BusinessAdmin. Don't change this yourself! */ - const version = '0.5.1'; + const version = '0.5.2'; } diff --git a/classes/Contact.php b/classes/Contact.php index 6ab4803..4a82ade 100644 --- a/classes/Contact.php +++ b/classes/Contact.php @@ -73,4 +73,15 @@ class Contact extends Model { throw new Exception($error[2]); } } + + /** + * Make a mailer to send to this contact + * + * @return Mailer The mailer + */ + public function mailer() { + $mailer = new Mailer($this->pdo); + $mailer->addAddress($this->email, $this->name); + return $mailer; + } } diff --git a/classes/Mail.php b/classes/Mail.php new file mode 100644 index 0000000..dcc5cf5 --- /dev/null +++ b/classes/Mail.php @@ -0,0 +1,32 @@ +<?php +/** + * Provides the Mail class + * + * @author Camil Staps + * + * BusinessAdmin: administrative software for small companies + * Copyright (C) 2015 Camil Staps (ViviSoft) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** + * An extension to Model for the mail table + */ +class Mail extends Model { + /** {@inheritDoc} */ + public + $table = 'mail', + $fillable_columns = ['contactId', 'offerId', 'subject']; +} diff --git a/classes/Mailer.php b/classes/Mailer.php new file mode 100644 index 0000000..782afc3 --- /dev/null +++ b/classes/Mailer.php @@ -0,0 +1,100 @@ +<?php +/** + * Provides the Mailer class + * + * @author Camil Staps + * + * BusinessAdmin: administrative software for small companies + * Copyright (C) 2015 Camil Staps (ViviSoft) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** + * An extension to PHPMailer to set some defaults + */ +class Mailer extends PHPMailer { + /** + * {@inheritDoc} + * + * @param PDO $_pdo A PDO instance for database connection + * @param mixed $exceptions For PHPMailer::__construct() + */ + public function __construct($_pdo, $exceptions = null) { + parent::__construct($exceptions); + + $this->pdo = $_pdo; + + $this->isSMTP(); + $this->Host = SMTP_HOST; + $this->SMTPAuth = SMTP_AUTH; + $this->Username = SMTP_USERNAME; + $this->Password = SMTP_PASSWORD; + $this->SMTPSecure = SMTP_SECURE; + $this->Port = SMTP_PORT; + + if (defined('SMTP_OPTIONS')) + $this->SMTPOptions = json_decode(SMTP_OPTIONS, true); + + $from = explode(';', MAILER_FROM); + $this->setFrom($from[0], $from[1]); + + if (defined('MAILER_REPLY_TO')) { + $replyto = explode(';', MAILER_REPLY_TO); + $this->addReplyTo($replyto[0], $replyto[1]); + } + + if (defined('MAILER_CC')) + foreach (explode(';', MAILER_CC) as $cc) + $this->addCC($cc); + if (defined('MAILER_BCC')) + foreach (explode(';', MAILER_BCC) as $bcc) + $this->addBCC($bcc); + } + + /** + * Set the contact this mail should be sent to + * + * @param Contact $contact The contact + */ + public function setContact($contact) { + $this->addAddress($contact->email, $contact->name); + $this->contactId = $contact->id; + } + + /** + * Set the offer this email is about + * + * @param Offer $offer The offer + */ + public function setOffer($offer) { + $this->setContact($offer->getContact()); + $this->offerId = $offer->id; + } + + /** + * {@inheritDoc} + * + * Then store it in the database. + */ + public function send() { + if (!parent::send()) { + return false; + } + + BusinessAdmin::createMail($this->pdo, $this->contactId, $this->offerId, $this->Subject); + + return true; + } +} diff --git a/classes/Offer.php b/classes/Offer.php index 16e0d20..7b0d2fc 100644 --- a/classes/Offer.php +++ b/classes/Offer.php @@ -294,6 +294,32 @@ class Offer extends Model{ } /** + * Make a mailer to send about this offer + * + * @return Mailer The mailer + */ + public function mailer() { + $mailer = new Mailer($this->pdo); + $mailer->setOffer($this); + return $mailer; + } + + /** + * Send the invoice to the contact + * + * @return bool The result of Mailer::send + */ + public function send() { + $mailer = $this->mailer(); + + $mailer->addAttachment($this->getInvoiceFile()->getFilenamePath()); + $mailer->Subject = 'Your invoice'; + $mailer->Body = 'Here is your invoice.'; + + return $mailer->send(); + } + + /** * Make a new assignment linked to this order * * @param string $title The title for this assignment @@ -56,6 +56,8 @@ if (BRAINTREE_ENABLED) { Braintree_Configuration::merchantId(BRAINTREE_MERCHANT); Braintree_Configuration::publicKey(BRAINTREE_KEY_PUBLIC); Braintree_Configuration::privateKey(BRAINTREE_KEY_PRIVATE); + + require_once('modules/PHPMailer/PHPMailerAutoload.php'); } require_once('classes/Calculatable.php'); // Some definitions that are required diff --git a/conf.private.example.php b/conf.private.example.php index a9275b1..b389c4c 100644 --- a/conf.private.example.php +++ b/conf.private.example.php @@ -12,3 +12,16 @@ define('BRAINTREE_ENVIRONMENT', 'sandbox'); define('BRAINTREE_MERCHANT', ...); define('BRAINTREE_KEY_PUBLIC', ...); define('BRAINTREE_KEY_PRIVATE', ...); + +// Mailer settings +define('SMTP_HOST', ...); +define('SMTP_AUTH', true); +define('SMTP_USERNAME', ...); +define('SMTP_PASSWORD', ...); +define('SMTP_SECURE', 'tls'); +define('SMTP_PORT', 587); +define('SMTP_OPTIONS', ...); // JSON array, can be used to turn off SSL verification (http://stackoverflow.com/a/28759959/1544337) + +define('MAILER_FROM', 'MY_EMAIL;MY_NAME'); +define('MAILER_REPLY_TO', ...); +define('MAILER_BCC', 'MY_EMAIL'); diff --git a/include/offers-view.php b/include/offers-view.php index 802f42f..d96e9ed 100644 --- a/include/offers-view.php +++ b/include/offers-view.php @@ -22,70 +22,6 @@ require_once('./login.php'); $_offer = new Offer($_pdo, $_id); ?> <div class="col-lg-6"> - <div class="panel panel-default" id="panel-timeline"> - <div class="panel-heading"> - <i class="fa fa-clock-o fa-fw"></i> Timeline - </div> - <!-- /.panel-heading --> - <div class="panel-body"> - <ul class="timeline"> - <?php - $list = array(); - $sort_list = array(); - - $temp = array( - 'id' => $_offer->id, - 'contact' => $_offer->getContact()->name, - 'assignments' => '', - 'assignments_header' => '' - ); - foreach ($_offer->getAssignments() as $assignment) { - $temp['assignments'] .= "<b>{$assignment->title}</b><br/><span class='smaller'>(".Constants::invoice_valuta."{$assignment->calculate(Calculatable::SUBTOTAL)} excl. VAT, ".Constants::invoice_valuta."{$assignment->calculate(Calculatable::TOTAL)} incl. VAT)</span><br/><p>{$assignment->getHTMLDescription()}</p>"; - $temp['assignments_header'] .= "<b>{$assignment->title}</b><br/><span class='smaller'>(".Constants::invoice_valuta."{$assignment->calculate(Calculatable::SUBTOTAL)} excl. VAT, ".Constants::invoice_valuta."{$assignment->calculate(Calculatable::TOTAL)} incl. VAT)</span><br/>"; - } - $list[] = array_merge($temp, array('type' => 'start', 'time' => $_offer->start_date, 'description' => 'Offer started')); - $sort_list[] = $_offer->start_date . $_offer->id . 0; - $list[] = array_merge($temp, array('type' => 'end', 'time' => $_offer->end_date, 'description' => 'Offer ended')); - $sort_list[] = $_offer->end_date . $_offer->id . 1; - if ($_offer->invoice_date > 0) { - $list[] = array_merge($temp, array('type' => 'invoice', 'time' => $_offer->invoice_date, 'description' => 'Invoice sent')); - $sort_list[] = $_offer->invoice_date . $_offer->id . 2; - if ($_offer->getPaymentReceived() > 0) { - $list[] = array_merge($temp, array('type' => 'payment_received', 'time' => $_offer->getPaymentReceived(), 'description' => 'Payment received')); - $sort_list[] = $_offer->getPaymentReceived() . $_offer->id . 3; - } - } - - array_multisort($sort_list, SORT_DESC, $list); - $i = 0; - foreach ($list as $item) { - if ($item['time'] > time()) { - continue; - } - echo "<li" . ($i++ % 2 == 0 ? ' class="timeline-inverted"' : '') . ">"; - switch ($item['type']) { - case 'start': echo "<div class='timeline-badge info' title='{$item['description']}'><i class='fa fa-circle-o-notch'></i></div>"; break; - case 'end': echo "<div class='timeline-badge primary' title='{$item['description']}'><i class='fa fa-circle-o'></i></div>"; break; - case 'invoice': echo "<div class='timeline-badge warning' title='{$item['description']}'><i class='fa fa-check-circle-o'></i></div>"; break; - case 'payment_received': echo "<div class='timeline-badge success' title='{$item['description']}'><i class='fa fa-eur'></i></div>"; break; - } - echo "<div class='timeline-panel'>"; - echo "<div class='timeline-heading'><h4 class='timeline-title'>#{$item['id']} to {$item['contact']}: {$item['description']}</h4><p><small class='text-muted'><i class='fa fa-clock-o fa-fw'></i> ".BusinessAdmin::formatDate($item['time'],false,true,true)."</small></p></div>"; - switch ($item['type']) { - case 'start': echo "<div class='timeline-body'>{$item['assignments']}</div>"; break; - default: echo "<div class='timeline-body'>{$item['assignments_header']}</div>"; - } - echo "</div>"; - echo "</li>"; - } - ?> - </ul> - </div> - <!-- /.panel-body --> - </div> - <!-- /.panel --> -</div> -<div class="col-lg-6"> <div class="panel panel-default"> <div class="panel-heading">Assignments</div> <div class="panel-body table-responsive"> @@ -171,3 +107,87 @@ $_offer = new Offer($_pdo, $_id); </div> </div> </div> +<div class="clearfix"></div> +<div class="col-md-6"> + <div class="panel panel-default"> + <div class="panel-heading">Tools</div> + <div class="panel-body"> + <?php + $accepted = $_offer->accepted ? + ['Accepted', 'btn-success'] : + ['Not accepted', 'btn-default']; + $eligible = $_offer->getPaymentEligibility() ? + ['Eligible for online payment', 'btn-success'] : + ['Not eligible for online payment', 'btn-default']; + ?> + <a title='<?=$accepted[0]?>' href='?id=<?=$_offer->id?>&toggle_accept=<?=$_offer->id?>' class='btn <?=$accepted[1]?>'><i class='fa fa-fw fa-check'></i> <?=$accepted[0]?></a> + <a title='<?=$eligible[0]?>' href='?id=<?=$_offer->id?>&toggle_payment_eligibility=<?=$_offer->id?>' class='btn <?=$eligible[1]?>'><i class='fa fa-fw fa-credit-card'></i> <?=$eligible[0]?></a> + <a title='Send invoice' href='?id=<?=$_offer->id?>&send_invoice=<?=$_offer->id?>' class='btn btn-info'><i class='fa fa-fw fa-envelope'></i> Send invoice to contact</a> + <a title='Delete' href='?delete=<?=$_offer->id?>' class='btn btn-danger'><i class='fa fa-fw fa-times'></i> Delete</a> + </div> + </div> +</div> +<div class="col-md-6"> + <div class="panel panel-default" id="panel-timeline"> + <div class="panel-heading"> + <i class="fa fa-clock-o fa-fw"></i> Timeline + </div> + <!-- /.panel-heading --> + <div class="panel-body"> + <ul class="timeline"> + <?php + $list = array(); + $sort_list = array(); + + $temp = array( + 'id' => $_offer->id, + 'contact' => $_offer->getContact()->name, + 'assignments' => '', + 'assignments_header' => '' + ); + foreach ($_offer->getAssignments() as $assignment) { + $temp['assignments'] .= "<b>{$assignment->title}</b><br/><span class='smaller'>(".Constants::invoice_valuta."{$assignment->calculate(Calculatable::SUBTOTAL)} excl. VAT, ".Constants::invoice_valuta."{$assignment->calculate(Calculatable::TOTAL)} incl. VAT)</span><br/><p>{$assignment->getHTMLDescription()}</p>"; + $temp['assignments_header'] .= "<b>{$assignment->title}</b><br/><span class='smaller'>(".Constants::invoice_valuta."{$assignment->calculate(Calculatable::SUBTOTAL)} excl. VAT, ".Constants::invoice_valuta."{$assignment->calculate(Calculatable::TOTAL)} incl. VAT)</span><br/>"; + } + $list[] = array_merge($temp, array('type' => 'start', 'time' => $_offer->start_date, 'description' => 'Offer started')); + $sort_list[] = $_offer->start_date . $_offer->id . 0; + $list[] = array_merge($temp, array('type' => 'end', 'time' => $_offer->end_date, 'description' => 'Offer ended')); + $sort_list[] = $_offer->end_date . $_offer->id . 1; + if ($_offer->invoice_date > 0) { + $list[] = array_merge($temp, array('type' => 'invoice', 'time' => $_offer->invoice_date, 'description' => 'Invoice sent')); + $sort_list[] = $_offer->invoice_date . $_offer->id . 2; + if ($_offer->getPaymentReceived() > 0) { + $list[] = array_merge($temp, array('type' => 'payment_received', 'time' => $_offer->getPaymentReceived(), 'description' => 'Payment received')); + $sort_list[] = $_offer->getPaymentReceived() . $_offer->id . 3; + } + } + + array_multisort($sort_list, SORT_DESC, $list); + $i = 0; + foreach ($list as $item) { + if ($item['time'] > time()) { + continue; + } + echo "<li" . ($i++ % 2 == 0 ? ' class="timeline-inverted"' : '') . ">"; + switch ($item['type']) { + case 'start': echo "<div class='timeline-badge info' title='{$item['description']}'><i class='fa fa-circle-o-notch'></i></div>"; break; + case 'end': echo "<div class='timeline-badge primary' title='{$item['description']}'><i class='fa fa-circle-o'></i></div>"; break; + case 'invoice': echo "<div class='timeline-badge warning' title='{$item['description']}'><i class='fa fa-check-circle-o'></i></div>"; break; + case 'payment_received': echo "<div class='timeline-badge success' title='{$item['description']}'><i class='fa fa-eur'></i></div>"; break; + } + echo "<div class='timeline-panel'>"; + echo "<div class='timeline-heading'><h4 class='timeline-title'>#{$item['id']} to {$item['contact']}: {$item['description']}</h4><p><small class='text-muted'><i class='fa fa-clock-o fa-fw'></i> ".BusinessAdmin::formatDate($item['time'],false,true,true)."</small></p></div>"; + switch ($item['type']) { + case 'start': echo "<div class='timeline-body'>{$item['assignments']}</div>"; break; + default: echo "<div class='timeline-body'>{$item['assignments_header']}</div>"; + } + echo "</div>"; + echo "</li>"; + } + ?> + </ul> + </div> + <!-- /.panel-body --> + </div> + <!-- /.panel --> +</div> diff --git a/include/offers.php b/include/offers.php index 8be7530..dbe5df0 100644 --- a/include/offers.php +++ b/include/offers.php @@ -37,6 +37,7 @@ require('./header.php'); // ?toggle_payment_eligibility=<id> Toggle the payment eligibility of the offer with id <id> // ?generate_invoice=<id> Generate an invoice for the offer with id <id> // ?trash_invoice=<id> Trash the invoice file + // ?send_invoice=<id> Send invoice to contact // ?delete=<id> Delete the offer with id <id> //------------------------------------------------------------------------------ @@ -137,6 +138,25 @@ require('./header.php'); echo "</div>"; } + // Send invoice + if (isset($_GET['send_invoice'])) { + echo "<div class='col-lg-12'>"; + $id = (int) $_GET['send_invoice']; + try { + $offer = new Offer($_pdo, $id); + if ($offer->send()) { + echo "<div class='alert alert-success alert-dismissable'><button type='button' class='close fa fa-times' data-dismiss='alert' aria-hidden='true'></button>The invoice for offer {$id} has been sent to {$offer->getContact()->email}.</div>"; + } else { + echo "<div class='alert alert-danger alert-dismissable'><button type='button' class='close fa fa-times' data-dismiss='alert' aria-hidden='true'></button>The invoice could not be sent due to an unknown error.</div>"; + } + } catch (PDOException $e) { + echo "<div class='alert alert-danger alert-dismissable'><button type='button' class='close fa fa-times' data-dismiss='alert' aria-hidden='true'></button>The invoice could not be sent due to a PDO error.</div>"; + } catch (Exception $e) { + echo "<div class='alert alert-warning alert-dismissable'><button type='button' class='close fa fa-times' data-dismiss='alert' aria-hidden='true'></button>The offer with id {$id} could not be found.</div>"; + } + echo "</div>"; + } + // Delete offer if (isset($_GET['delete'])) { echo "<div class='col-lg-12'>"; diff --git a/install/index.php b/install/index.php index 519e3c5..19cd5a4 100644 --- a/install/index.php +++ b/install/index.php @@ -75,6 +75,17 @@ if (isset($_GET['create_tables'])) { UNIQUE KEY `filename` (`filename`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1"); + $_pdo->query("CREATE TABLE IF NOT EXISTS `".Constants::db_prefix."mail` ( + `id` smallint(5) unsigned NOT NULL AUTO_INCREMENT, + `contactId` smallint(5) unsigned NOT NULL, + `offerId` smallint(5) unsigned DEFAULT NULL, + `date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `subject` varchar(100) NOT NULL, + PRIMARY KEY (`id`), + KEY `contactId` (`contactId`), + KEY `offerId` (`offerId`) + ) ENGINE=InnoDB DEFAULT CHARSET=latin1;"); + $_pdo->query("CREATE TABLE IF NOT EXISTS `".Constants::db_prefix."offer` ( `id` smallint(5) unsigned NOT NULL AUTO_INCREMENT, `contactId` smallint(5) unsigned NOT NULL, @@ -110,13 +121,17 @@ if (isset($_GET['create_tables'])) { $_pdo->query("ALTER TABLE `".Constants::db_prefix."assignment` ADD CONSTRAINT `assignment_ibfk_1` FOREIGN KEY (`offerId`) REFERENCES `".Constants::db_prefix."offer` (`id`)"); - $_pdo->query("ALTER LE `".Constants::db_prefix."contact` + $_pdo->query("ALTER TABLE `".Constants::db_prefix."contact` ADD CONSTRAINT `contact_ibfk_1` FOREIGN KEY (`clientId`) REFERENCES `".Constants::db_prefix."client` (`id`)"); - $_pdo->query("ALTER LE `".Constants::db_prefix."discount` + $_pdo->query("ALTER TABLE `".Constants::db_prefix."discount` ADD CONSTRAINT `discount_ibfk_1` FOREIGN KEY (`offerId`) REFERENCES `".Constants::db_prefix."offer` (`id`);"); - $_pdo->query("ALTER LE `".Constants::db_prefix."offer` + $_pdo->query("ALTER TABLE `".Constants::db_prefix."mail` + ADD CONSTRAINT `mail_ibfk_1` FOREIGN KEY (`contactId`) REFERENCES `".Constants::db_prefix."contact` (`id`) ON UPDATE CASCADE, + ADD CONSTRAINT `mail_ibfk_2` FOREIGN KEY (`offerId`) REFERENCES `".Constants::db_prefix."offer` (`id`) ON UPDATE CASCADE;"); + + $_pdo->query("ALTER TABLE `".Constants::db_prefix."offer` ADD CONSTRAINT `offer_ibfk_1` FOREIGN KEY (`invoice_fileId`) REFERENCES `".Constants::db_prefix."file` (`id`), ADD CONSTRAINT `offer_ibfk_2` FOREIGN KEY (`contactId`) REFERENCES `".Constants::db_prefix."contact` (`id`)"); diff --git a/install/upgrade.php b/install/upgrade.php index db0c913..c759df0 100644 --- a/install/upgrade.php +++ b/install/upgrade.php @@ -141,6 +141,27 @@ if (isset($_GET['upgrade'])) { } } + if (lower_version($_GET['upgrade'], '0.5.2')) { + try { + $_pdo->query("CREATE TABLE IF NOT EXISTS `".Constants::db_prefix."mail` ( + `id` smallint(5) unsigned NOT NULL AUTO_INCREMENT, + `contactId` smallint(5) unsigned NOT NULL, + `offerId` smallint(5) unsigned DEFAULT NULL, + `date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `subject` varchar(100) NOT NULL, + PRIMARY KEY (`id`), + KEY `contactId` (`contactId`), + KEY `offerId` (`offerId`) + ) ENGINE=InnoDB DEFAULT CHARSET=latin1;"); + + $_pdo->query("ALTER TABLE `".Constants::db_prefix."mail` + ADD CONSTRAINT `mail_ibfk_1` FOREIGN KEY (`contactId`) REFERENCES `".Constants::db_prefix."contact` (`id`) ON UPDATE CASCADE, + ADD CONSTRAINT `mail_ibfk_2` FOREIGN KEY (`offerId`) REFERENCES `".Constants::db_prefix."offer` (`id`) ON UPDATE CASCADE;"); + } catch (PDOException $e) { + echo "Altering the database structure failed with a PDOException ({$e->getCode()}): {$e->getMessage()}<br/>" . $e->getTraceAsString(); + } + } + echo "<br/>All done."; } ?> diff --git a/modules/PHPMailer b/modules/PHPMailer new file mode 160000 +Subproject 4f7967ac91a25e8838fdb59df2f45030a1d39bc |