I'm having a problem with some emails not being delivered with some ISP email address
Common email example reported by users : "xx#free.fr", "#bellsouth.net"
I don't really have a way to "test" why they don't get the emails. I told them to verify spam folder and they aren't there.. I have test account for popular email service "gmail, hotmail" and they work fine.
The emails I'm sending are common emails from my domain website (registration, confirm account, forgot password). I don't send any bulk email. I'm using goDaddy as hosting service.
I have set up SPF on my domain, and the email are sent with PHP(codeIgniter) - See bottom for how the mail is sent with code
Here is an example of mail that I sent that is blocked by theses ISP:
Delivered-To: tdfdestgmfdsailmaxmt123okdddf3#gmail.com
Received: by 10.112.159.166 with SMTP id xd6csp1482168lbb;
Wed, 17 Dec 2014 10:27:57 -0800 (PST)
X-Received: by 10.50.61.238 with SMTP id t14mr9680303igr.34.1418840877015;
Wed, 17 Dec 2014 10:27:57 -0800 (PST)
Return-Path: <admin#maximumtrainer.com>
Received: from p3nlsmtpcp01-03.prod.phx3.secureserver.net (p3nlsmtpcp01-03.prod.phx3.secureserver.net. [184.168.200.142])
by mx.google.com with ESMTP id hh16si4059486icb.62.2014.12.17.10.27.56
for <tdfdestgmfdsailmaxmt123okdddf3#gmail.com>;
Wed, 17 Dec 2014 10:27:56 -0800 (PST)
Received-SPF: pass (google.com: domain of admin#maximumtrainer.com designates 184.168.200.142 as permitted sender) client-ip=184.168.200.142;
Authentication-Results: mx.google.com;
spf=pass (google.com: domain of admin#maximumtrainer.com designates 184.168.200.142 as permitted sender) smtp.mail=admin#maximumtrainer.com
Received: from p3plcpnl0063.prod.phx3.secureserver.net ([184.168.200.112])
by p3nlsmtpcp01-03.prod.phx3.secureserver.net with : CPANEL :
id UiR51p01s2S0Aj401iR5yP; Wed, 17 Dec 2014 11:25:05 -0700
Received: from p3plcpnl0063.prod.phx3.secureserver.net ([184.168.200.112]:34603 helo=maximumtrainer.com)
by p3plcpnl0063.prod.phx3.secureserver.net with esmtpa (Exim 4.84)
(envelope-from <admin#maximumtrainer.com>)
id 1Y1JKF-0001bp-W0
for tdfdestgmfdsailmaxmt123okdddf3#gmail.com; Wed, 17 Dec 2014 11:27:56 -0700
User-Agent: CodeIgniter
Date: Wed, 17 Dec 2014 18:27:55 +0000
From: "Maximum Trainer" <admin#maximumtrainer.com>
To: tdfdestgmfdsailmaxmt123okdddf3#gmail.com
Subject: =?utf-8?Q?Bienvenue?=
Reply-To: "admin#maximumtrainer.com" <admin#maximumtrainer.com>
X-Sender: admin#maximumtrainer.com
X-Mailer: CodeIgniter
X-Priority: 3 (Normal)
Message-ID: <5491cb2be1fa8#maximumtrainer.com>
Mime-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 8bit
X-AntiAbuse: This header was added to track abuse, please include it with any abuse report
X-AntiAbuse: Primary Hostname - p3plcpnl0063.prod.phx3.secureserver.net
X-AntiAbuse: Original Domain - gmail.com
X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12]
X-AntiAbuse: Sender Address Domain - maximumtrainer.com
X-Get-Message-Sender-Via: p3plcpnl0063.prod.phx3.secureserver.net: authenticated_id: admin#maximumtrainer.com
X-Source:
X-Source-Args:
X-Source-Dir:
CodeIgniter sender function:
function send_confirmation_mail($email, $first_name, $confirm_code) {
$CI =& get_instance();
$CI->load->library('email'); // load library
$CI->email->from ( 'admin#maximumtrainer.com', 'Maximum Trainer' );
$CI->email->to ( $email );
$CI->email->subject ( lang('email_activate_title') );
$link = base_url(). index_page(). lang('url_confirm_user'). "/". $confirm_code;
$message = lang('email_hello'). $first_name. ", \r\n".
lang('email_activate_thank_you'). "\r\n\r\n".
lang('email_activate_click_link'). "\r\n".
$link. "\r\n\r\n".
lang('email_activate_farewwell'). "\r\n".
lang('email_linkMT');
$CI->email->message( $message );
if ( ! $CI->email->send()) {
$CI->messages->add("error send_confirmation_mail", "error");
return false;
}
return true;
}
Server config :
$config['useragent'] = 'CodeIgniter';
$config['protocol'] = 'smtp';
#$config['mailpath'] = '/usr/sbin/sendmail';
$config['smtp_host'] = 'p3plcpnl0063.prod.phx3.secureserver.net';
$config['smtp_user'] = 'yyyyyy#maximumtrainer.com';
$config['smtp_pass'] = 'xxxxxxx';
$config['smtp_port'] = 25; #465 to test doesnt seem to work
$config['smtp_timeout'] = 5;
$config['wordwrap'] = FALSE;
$config['wrapchars'] = 76;
$config['mailtype'] = 'text';
$config['charset'] = 'utf-8';
$config['validate'] = FALSE;
$config['priority'] = 3;
$config['crlf'] = "\r\n";
$config['newline'] = "\r\n";
$config['bcc_batch_mode'] = FALSE;
$config['bcc_batch_size'] = 200;
Are there any services to diagnose what could be the cause of the problem? I can't register for free with these email providers in order to test.
Related
my problem is that PHPMailer (PHPMailer-master 6.0.3 to be exact) does not deliver emails when I run it with Xampp and Windows10.
(I found a lot of comments on that subject but none of them led to a solution.)
The following code runs fine on a remote server:
<?php
// Import PHPMailer classes into the global namespace
// These must be at the top of your script, not inside a function
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
// 'PHPMailer' here actually is the original folder 'PHPMailer-master'
// from unpacking the downloaded file PHPMailer-master.zip
require 'vendor/PHPMailer/src/Exception.php';
require 'vendor/PHPMailer/src/PHPMailer.php';
require 'vendor/PHPMailer/src/SMTP.php';
echo (extension_loaded('openssl')?'SSL loaded':'SSL not loaded')."\n";
$mail = new PHPMailer(true); // Passing `true` enables exceptions
try {
//Server settings
$mail->SMTPDebug = 2; // Enable verbose debug output
$mail->$mail->isSendmail(); // corrected
$mail->Host = 'smtp.kabelmail.de'; //smtp1.example.com;smtp2.example.com'; // Specify main and backup SMTP servers
$mail->SMTPAuth = true; // Enable SMTP authentication
$mail->Username = 'myname#kabelmail.de'; // SMTP username
$mail->Password = 'mypassword'; // SMTP password
$mail->SMTPSecure = 'tls'; // Enable TLS encryption, `ssl` also accepted
$mail->Port = 465; // TCP port to connect to
//Recipients
$mail->setFrom('from#example.com', 'Mailer');
$mail->addAddress('myname#kabelmail.de', 'myname'); // Add a recipient
// $mail->addAddress('ellen#example.com'); // Name is optional
$mail->addReplyTo('myname#web.de', 'Antwort');
//$mail->addCC('cc#example.com');
//$mail->addBCC('bcc#example.com');
//Attachments
//$mail->addAttachment('/var/tmp/file.tar.gz'); // Add attachments
//$mail->addAttachment('/tmp/image.jpg', 'new.jpg'); // Optional name
//Content
$mail->isHTML(true); // Set email format to HTML
$mail->Subject = 'Here is the subject:localhost';
$mail->Body = 'This is the HTML message body <b>in bold!</b>';
$mail->AltBody = ' body in plain text for non-HTML mail lients';
$mail->send();
echo 'Message has been sent';
} catch (Exception $e) {
echo 'Message could not be sent.';
echo 'Mailer Error: ' . $mail->ErrorInfo;
}
?>
I left the script above as it is and modified php.ini for Xampp in accordance with the comments at Phpmailer not working running from localhost (XAMPP):
[mail function]
SMTP=smtp.kabelmail.de
smtp_port=465
sendmail_from = to#kabelmail.de
sendmail_path ="C:\xampp\sendmail\sendmail.exe\"
;(I also tried sendmail_path = "\"C:\xampp\sendmail\sendmail.exe\" -t" but without success.)
mail.log="C:\xampp\php\logs\php_mail.log"
These are the modifications to sendmail.ini:
[sendmail]
smtp_server=smtp.kabelmail.de
smtp_port=465
smtp_ssl=auto
error_logfile=error.log
debug_logfile=debug.log
auth_username=myname#kabelmail.de
auth_password=mypassword
Results:
1. With the settings above I got this message:
SSL loaded 2018-01-11 12:06:10 SERVER -> CLIENT: 421 4.3.2 Too many open connections.
2018-01-11 12:06:10 CLIENT -> SERVER: EHLO localhost
2018-01-11 12:06:10 SERVER -> CLIENT:
2018-01-11 12:06:10 SMTP ERROR: EHLO command failed:
2018-01-11 12:06:10 SMTP NOTICE: EOF caught while checking if connected
SMTP Error: Could not connect to SMTP host.
SMTP Error: Could not connect to SMTP host.
Message could not be sent.Mailer Error: SMTP Error: Could not connect to SMTP host.
I then replaced $mail->isSendmail(); by $mail->isMail();
The message that showed up now was
SSL loaded Message has been sent
That is what I was looking for, but - there was no message in the mailbox.!!!
php_mail.log had this information, which doesn't look suspicious to me:
[11-Jan-2018 13:09:32 Europe/Berlin] mail() on [C:\xampp\htdocs\to\vendor\PHPMailer\src\PHPMailer.php:768]: To: "name" <myname#kabelmail.de> -- Headers: Date: Thu, 11 Jan 2018 13:09:32 +0100 From: Mailer <from#example.com> Reply-To: Antwort <myname#web.de> Message-ID: <VuAQ3BR022MQyNd3hKCoguqr50Ry9TPG4vIRL2ZmFg#localhost> X-Mailer: PHPMailer 6.0.3 (https://github.com/PHPMailer/PHPMailer) MIME-Version: 1.0 Content-Type: multipart/alternative; boundary="b1_VuAQ3BR022MQyNd3hKCoguqr50Ry9TPG4vIRL2ZmFg" Content-Transfer-Encoding: 8bit
Can somebody give me a hint what might be wrong?
I have been working on that for several days now but obviously I am missing something basic.
--- Edit Jan. 12, 2018 -------------------------------------------------
$mail->isSendmail(); is the setting that is ok on the remote server!
Solved.
The breakthrough was reached when I moved to smtp.web.de.
I now get the the messages from client and server ($mail->SMTPDebug = 2;).
The server still complained about
$mail->setFrom('from#example.com', 'Mailer');
saying
"MAIL FROM command failed: 550-Requested action not taken: mailbox unavailable550 Sender address is not allowed".
Replacing it by
$mail->setFrom('myname#web.de', 'via web.de');
did the job. But not all servers complain about that. Dogado.de for instance does not.
Finally:
$mail->SMTPDebug = 0; // suppresses server and client messages for production use
$mail->CharSet = "UTF-8"; // for correct umlauts
Summary:
The following code can be used on a local machine (Xampp, Netbeans) as well as on a remote server.
<?php
// Import PHPMailer classes into the global namespace
// These must be at the top of your script, not inside a function
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
// adjust path accordingly!
require 'vendor/PHPMailer/src/Exception.php';
require 'vendor/PHPMailer/src/PHPMailer.php';
require 'vendor/PHPMailer/src/SMTP.php';
// is ssl loaded? (test only):
//echo (extension_loaded('openssl')?'SSL loaded, ':'SSL not loaded, ')."\n";
$mail = new PHPMailer(true); // Passing `true` enables exceptions
try {
$mail->SMTPDebug = 0; // production use
$mail->isSMTP(); // Set mailer to use SMTP
//=== using web.de ========================================
// adjust settings to your project!
$mail->Host = 'smtp.web.de'; //smtp1.example.com;smtp2.example.com';
// Specify main and backup SMTP servers
$mail->Username = 'myname#web.de'; // SMTP username
$mail->Port = 587; // TCP port to connect to
$mail->setFrom('myname#web.de', 'über web.de'); // required by web.de
$mail->Password = 'mypassword'; // SMTP password
//==========================================================
$mail->SMTPAuth = true; // Enable SMTP authentication
$mail->SMTPSecure = 'tls'; // Enable TLS encryption, `ssl` also accepted
//Recipients
$mail->addAddress('myname#kabelmail.de', 'my name'); // Add a recipient
$mail->addAddress('myname#web.de'); // Name is optional
$mail->CharSet = "UTF-8"; // because of umlauts
//$mail->addCC('cc#example.com');
//$mail->addBCC('bcc#example.com');
//Attachments
//$mail->addAttachment('/var/tmp/file.tar.gz'); // Add attachments
//$mail->addAttachment('/tmp/image.jpg', 'new.jpg'); // Optional name
//Content
$mail->isHTML(true); // Set email format to HTML
$mail->Subject = 'Here is the subject';
$mail->Body = 'This is the HTML message body <b>in bold! groß süß ähnlich Ökonom</b>';
$mail->AltBody = 'This is the body in plain text for non-HTML mail clients: groß süß ähnlich Ökonom';
$mail->send();
echo 'Message has been sent';
} catch (Exception $e) {
echo 'Message could not be sent.';
echo 'Mailer Error: ' . $mail->ErrorInfo;
}
I am using the square connect php sdk, and I am getting the following error, and haven't been able to find any solution. I am trying to push a few new categories that have been added on my app (within mysql database).
Building the catelogObject
foreach ($push_array as $key => $cat_name) {
$category = $this->products_lib->get_category($cat_name);
$idempotency_key = uniqid('',true);
$push_obj = new stdClass();
$push_obj->type = 'CATEGORY';
$push_obj->id = '#' . trim($category->name);
$push_obj->category_data = ['name'=>trim($category->name)];
$push_obj->present_at_all_locations = true;
$catelogObject = ["idempotency_key" => $idempotency_key, 'object' => $push_obj];
print_r($catelogObject);
$response = $square_connect->upsert_category($catelogObject);
}
Produces
(
[idempotency_key] => 5996186208eae4.27853833
[object] => stdClass Object
(
[type] => CATEGORY
[id] => #Drinks
[category_data] => Array
(
[name] => Drinks
)
[present_at_all_locations] => 1
)
)
square_connect class
class SquareConnect {
private $access_token = "***********************";
private $sandbox_access_token = "sandbox-*********************";
public function get_locations() {
SquareConnect\Configuration::getDefaultConfiguration()->setAccessToken($this->access_token);
$locations_api = new \SquareConnect\Api\LocationsApi();
echo $locations_api->listLocations();
}
public function get_categories() {
SquareConnect\Configuration::getDefaultConfiguration()->setAccessToken($this->access_token);
$api = new \SquareConnect\Api\CatalogApi();
$retobj = json_decode($api->listCatalog(null, 'CATEGORY'));
// $categories = $retobj->objects;
return $retobj->objects;
}
public function upsert_category($category_object) {
SquareConnect\Configuration::getDefaultConfiguration()->setAccessToken($this->access_token);
$api = new \SquareConnect\Api\CatalogApi();
// return $apiResponse = json_decode($api->UpsertCatalogObject($category_object));
print_r(json_decode($api->UpsertCatalogObject($category_object))) ;
}
public function get_items() {
SquareConnect\Configuration::getDefaultConfiguration()->setAccessToken($this->access_token);
$api = new \SquareConnect\Api\CatalogApi();
echo $api->listCatalog(null, 'ITEM');
}
}
When I run the code, I get the following error :
Fatal error: Access to undeclared static property: stdClass::$swaggerTypes in /vendor/square/connect/lib/ObjectSerializer.php on line 43
Hope that is clear enough, and thanks in advance for assistance
Edit
[DEBUG] HTTP Request body ~BEGIN~
~END~
[DEBUG] HTTP Response body ~BEGIN~
{"objects":[{"type":"CATEGORY","id":"52IJHDSD67VAQNJ3GQB5TVRX","updated_at":"2017-08-16T19:50:58.373Z","version":1502913058373,"is_deleted":false,"custom_attributes":[{"name":"straight_fire_type","int_value":0}],"present_at_all_locations":true,"category_data":{"name":"Candy"}},{"type":"CATEGORY","id":"KFB7DDQYPG532F66SYAYAD4W","updated_at":"2017-06-13T19:45:27.653Z","version":1497383127653,"is_deleted":false,"present_at_all_locations":true,"category_data":{"name":"Sandwiches"}},{"type":"CATEGORY","id":"SJVUDRCAMQBSRM7FAEBQATBS","updated_at":"2017-06-13T19:45:35.181Z","version":1497383135181,"is_deleted":false,"present_at_all_locations":true,"category_data":{"name":"Specials"}}]}
~END~
* Hostname was NOT found in DNS cache
* Trying 74.122.190.85...
* Connected to connect.squareup.com (74.122.190.85) port 443 (#0)
* successfully set certificate verify locations:
* CAfile: /etc/pki/tls/certs/ca-bundle.crt
CApath: none
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
* Server certificate:
* subject: C=US; ST=California; L=San Francisco; O=Square, Inc.; CN=*.squareup.com
* start date: 2016-12-07 00:44:04 GMT
* expire date: 2017-12-16 01:14:02 GMT
* subjectAltName: connect.squareup.com matched
* issuer: C=US; O=Entrust, Inc.; OU=See www.entrust.net/legal-terms; OU=(c) 2012 Entrust, Inc. - for authorized use only; CN=Entrust Certification Authority - L1K
* SSL certificate verify ok.
> GET /v2/catalog/list?types=CATEGORY HTTP/1.1
User-Agent: Square-Connect-PHP/2.2.1
Host: connect.squareup.com
Accept: application/json
Content-Type: application/json
Authorization: Bearer sq0atp-WrF2m45lEzQVzCqAxSA_oA
< HTTP/1.1 200 OK
< Content-Type: application/json
< Vary: Origin, Accept-Encoding
< X-Content-Type-Options: nosniff
< X-Download-Options: noopen
< X-Frame-Options: SAMEORIGIN
< X-Permitted-Cross-Domain-Policies: none
< X-Xss-Protection: 1; mode=block
< Date: Fri, 18 Aug 2017 02:29:24 GMT
< Keep-Alive: timeout=60
< Strict-Transport-Security: max-age=631152000
< content-length: 687
<
* Connection #0 to host connect.squareup.com left intact
EDIT - Solution: Need to change the object property of $catelogObject to an array not an object as the square connect api documentation instructs
foreach ($push_array as $key => $cat_name) {
$category = $this->products_lib->get_category($cat_name);
$idempotency_key = uniqid('',true);
$push_obj = [];
$push_obj['type'] = 'CATEGORY';
$push_obj['id'] = '#' . trim($category->name);
$push_obj['category_data'] = ['name'=>trim($category->name)];
$push_obj['present_at_all_locations'] = true;
$catelogObject = ["idempotency_key" => $idempotency_key, 'object' => $push_obj];
print_r($catelogObject);
$response = $square_connect->upsert_category($catelogObject);
}
Consider this sample of code that takes an array of addresses and sends each of them an email using the mailables feature.
//In my controller
$email = new EmailToWinners($sender_name, $letter);
foreach ($recipients as $recipient){
Mail::to($recipient)->send($email);
}
//In my App\Mail\EmailToWinner
public function build()
{
return $this->view('emails.winner-email');
}
The emails all get sent fine but when I was testing this I noticed, it's stacking the emails up.
So I get this in the logs.
[2017-02-16 15:58:59] local.DEBUG: Message-ID: <250443348fee18f568f4f263153d5101#testing.dev>
Date: Thu, 16 Feb 2017 15:58:59 +0000
Subject: Email To Winner
From: Example Dev <example#me.dev>
To: 1#example.com
MIME-Version: 1.0
Content-Type: text/html; charset=utf-8
Content-Transfer-Encoding: quoted-printable
[2017-02-16 15:58:59] local.DEBUG: Message-ID: <1b5f39ef0cc17d4d8573019f3d5ec808#testing.dev>
Date: Thu, 16 Feb 2017 15:58:59 +0000
Subject: Email To Winner
From: Example Dev <example#me.dev>
To: 1#example.com, 2#example.com
MIME-Version: 1.0
Content-Type: text/html; charset=utf-8
Content-Transfer-Encoding: quoted-printable
[2017-02-16 15:58:59] local.DEBUG: Message-ID: <ddf6c62a7f881f9381693435b48ef5a3#testing.dev>
Date: Thu, 16 Feb 2017 15:58:59 +0000
Subject: Email To Winner
From: Example Dev <example#me.dev>
To: 1#example.com, 2#example.com, 3#example.com
MIME-Version: 1.0
Content-Type: text/html; charset=utf-8
Content-Transfer-Encoding: quoted-printable
If you look at the emails. The first email shows to
1#example.com
The second shows to
1#example.com, 2#example.com
The third shows 1#example.com, 2#example.com, 3#example.com
So the first person gets 3 emails.
What am I doing wrong?
You can pass to to method a collection of users:
Mail::to($recipients)->send(new EmailToWinners());
From Lavavel Mail Docs:
The to method accepts an email address, a user instance, or a collection of users. If you pass an object or collection of objects, the mailer will automatically use their email and name properties when setting the email recipients, so make sure these attributes are available on your objects
I think you need to make a new email object for each recipient like this.
foreach ($recipients as $recipient){
Mail::to('$recipient')->send(new EmailToWinners($sender_name, $letter));
}
I'm trying to access the Team rooms functionality in Visual Studio Team Services (VSTS)
With a valid token if I make a request to :
https://.visualstudio.com/DefaultCollection/_apis/chat/rooms?api-version=1.0
I get an error 401. I have tested the token and I can make requests to other endpoints without an issue.
status code: 401, headers {
"Content-Length" = 10828;
"Content-Type" = "text/html; charset=utf-8";
Date = "Fri, 17 Feb 2017 09:36:17 GMT";
Server = "Microsoft-IIS/10.0";
"Strict-Transport-Security" = "max-age=31536000; includeSubDomains";
"Www-Authenticate" = Bearer;
p3p = "CP=\"CAO DSP COR ADMa DEV CONo TELo CUR PSA PSD TAI IVDo OUR SAMi BUS DEM NAV STA UNI COM INT PHY ONL FIN PUR LOC CNT\"";
"x-content-type-options" = nosniff;
"x-frame-options" = SAMEORIGIN;
"x-powered-by" = "ASP.NET";
"x-tfs-processid" = "925585e2-35c8-4691-b646-c96e48f04ee0";
"x-tfs-serviceerror" = "TF400813%3a+Resource+not+available+for+anonymous+access.+Client+authentication+required.";
"x-tfs-soapexception" = "%3c%3fxml+version%3d%221.0%22+encoding%3d%22utf-8%22%3f%3e%3csoap%3aEnvelope+xmlns%3asoap%3d%22http%3a%2f%2fwww.w3.org%2f2003%2f05%2fsoap-envelope%22%3e%3csoap%3aBody%3e%3csoap%3aFault%3e%3csoap%3aCode%3e%3csoap%3aValue%3esoap%3aReceiver%3c%2fsoap%3aValue%3e%3csoap%3aSubcode%3e%3csoap%3aValue%3eInvalidIdentityException%3c%2fsoap%3aValue%3e%3c%2fsoap%3aSubcode%3e%3c%2fsoap%3aCode%3e%3csoap%3aReason%3e%3csoap%3aText+xml%3alang%3d%22en%22%3eTF400813%3a+Resource+not+available+for+anonymous+access.+Client+authentication+required.%3c%2fsoap%3aText%3e%3c%2fsoap%3aReason%3e%3c%2fsoap%3aFault%3e%3c%2fsoap%3aBody%3e%3c%2fsoap%3aEnvelope%3e";
"x-vss-s2stargetservice" = "00000002-0000-8888-8000-000000000000/visualstudio.com";
} })
You need to grant application the Team rooms (read and write) permission.
So, check the application you registered whether has the Team rooms (read and write) scope. Also check the web application config file (web.config) whether there is vso.chat_write in Scope (key) value.
For example:
<add key="Scope" value="vso.agentpools vso.build vso.chat_write vso.code vso.dashboards vso.identity vso.packaging vso.release vso.test vso.work"/>
Hope I will get my question as clear as possible. I am working on a small java application using the JavaFX library for the gui. am doing a POP Connection and storing Messages as ObservableList. For this I am using javax.mail. I am passing this observablelist to a tableview and with the following i am passing the required values to the TableColumns:
fromColumn.setCellValueFactory(
new PropertyValueFactory<Message,String>("from")
);
subjectColumn.setCellValueFactory(
new PropertyValueFactory<Message,String>("subject")
);
dateColumn.setCellValueFactory(
new PropertyValueFactory<Message,String>("sentDate")
);
Subject and sentDate are beeing read-in perfectly. But unfortunately "from" is adding object-references to TableColumn, since the From-Attribute in the Message-Class is a InternetAdress-Object and its toString()-method isnt returning a string but probably a reference. And the result is the follwoing being shown in fromColumn:
[Ljavax.mail.internet.InternetAddress;#3596cd38
Anybody knows the solution how I could get the String-Value of the InternetAdress being showed in the mentioned Column?
Thanks in Advance
I think you need to define a custom cell value factory to get at the address information in the format you need rather than using the PropertyValueFactory.
The following sample is for a read only table - if the message data in the table needs to be editable, then the solution will be significantly more complicated.
fromColumn.setCellValueFactory(new Callback<CellDataFeatures<Message, String>, ObservableValue<String>>() {
#Override public ObservableValue<String> call(CellDataFeatures<Message, String> m) {
// m.getValue() returns the Message instance for a particular TableView row
return new ReadOnlyObjectWrapper<String>(Arrays.toString(m.getValue().getFrom()));
}
});
Here is an executable sample (plus sample data files) which demonstrate use of the custom cell value factory. Place the sample data files in the same directory as the application java program and ensure your build system copies the sample files to the build output directory which contains the compiled class file for the application. You will need the javamail jar files on your path to compile and run the application.
import java.io.*;
import java.util.Arrays;
import java.util.logging.*;
import javafx.application.Application;
import javafx.beans.property.ReadOnlyObjectWrapper;
import javafx.beans.value.ObservableValue;
import javafx.collections.*;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.control.TableColumn.CellDataFeatures;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
import javafx.stage.Stage;
import javafx.util.Callback;
import javax.mail.*;
import javax.mail.internet.MimeMessage;
public class MailTableSample extends Application {
private TableView<Message> table = new TableView<Message>();
public static void main(String[] args) { launch(args);}
#Override public void start(Stage stage) {
stage.setTitle("Table View Sample");
final Label label = new Label("Mail");
label.setFont(new Font("Arial", 20));
table.setEditable(false);
TableColumn subjectColumn = new TableColumn("Subject");
subjectColumn.setMinWidth(100);
subjectColumn.setCellValueFactory(
new PropertyValueFactory<Message, String>("subject")
);
TableColumn sentDate = new TableColumn("Sent");
sentDate.setMinWidth(100);
sentDate.setCellValueFactory(
new PropertyValueFactory<Message, String>("sentDate")
);
TableColumn fromColumn = new TableColumn("From");
fromColumn.setMinWidth(200);
fromColumn.setCellValueFactory(new Callback<CellDataFeatures<Message, String>, ObservableValue<String>>() {
#Override public ObservableValue<String> call(CellDataFeatures<Message, String> m) {
try {
// m.getValue() returns the Message instance for a particular TableView row
return new ReadOnlyObjectWrapper<String>(Arrays.toString(m.getValue().getFrom()));
} catch (MessagingException ex) {
Logger.getLogger(MailTableSample.class.getName()).log(Level.SEVERE, null, ex);
return null;
}
}
});
table.setItems(fetchMessages());
table.getColumns().addAll(fromColumn, subjectColumn, sentDate);
table.setPrefSize(600, 200);
final VBox vbox = new VBox();
vbox.setSpacing(5);
vbox.setPadding(new Insets(10));
vbox.getChildren().addAll(label, table);
stage.setScene(new Scene(vbox));
stage.show();
}
private ObservableList<Message> fetchMessages() {
ObservableList<Message> messages = FXCollections.observableArrayList();
try {
Session session = Session.getDefaultInstance(System.getProperties());
for (int i = 0; i < 3; i++) {
InputStream mboxStream = new BufferedInputStream(
getClass().getResourceAsStream("msg_" + (i+1) + ".txt")
);
Message message = new MimeMessage(session, mboxStream);
messages.add(message);
}
} catch (MessagingException ex) {
Logger.getLogger(MailTableSample.class.getName()).log(Level.SEVERE, null, ex);
}
return messages;
}
}
msg_1.txt
From cras#irccrew.org Tue Jul 23 19:39:23 2002
Received: with ECARTIS (v1.0.0; list dovecot); Tue, 23 Jul 2002 19:39:23 +0300 (EEST)
Return-Path: <cras#irccrew.org>
Delivered-To: dovecot#procontrol.fi
Received: from shodan.irccrew.org (shodan.irccrew.org [80.83.4.2])
by danu.procontrol.fi (Postfix) with ESMTP id 434B423848
for <dovecot#procontrol.fi>; Tue, 23 Jul 2002 19:39:23 +0300 (EEST)
Received: by shodan.irccrew.org (Postfix, from userid 6976)
id 175FA4C0A0; Tue, 23 Jul 2002 19:39:23 +0300 (EEST)
Date: Tue, 23 Jul 2002 19:39:23 +0300
From: Timo Sirainen <tss#iki.fi>
To: dovecot#procontrol.fi
Subject: [dovecot] first test mail
Message-ID: <20020723193923.J22431#irccrew.org>
Mime-Version: 1.0
Content-Disposition: inline
User-Agent: Mutt/1.2.5i
Content-Type: text/plain; charset=us-ascii
X-archive-position: 1
X-ecartis-version: Ecartis v1.0.0
Sender: dovecot-bounce#procontrol.fi
Errors-to: dovecot-bounce#procontrol.fi
X-original-sender: tss#iki.fi
Precedence: bulk
X-list: dovecot
X-IMAPbase: 1096038620 0000010517
X-UID: 1
Status: O
lets see if it works
msg_2.txt
From cras#irccrew.org Mon Jul 29 02:17:12 2002
Received: with ECARTIS (v1.0.0; list dovecot); Mon, 29 Jul 2002 02:17:12 +0300 (EEST)
Return-Path: <cras#irccrew.org>
Delivered-To: dovecot#procontrol.fi
Received: from shodan.irccrew.org (shodan.irccrew.org [80.83.4.2])
by danu.procontrol.fi (Postfix) with ESMTP id 8D21723848
for <dovecot#procontrol.fi>; Mon, 29 Jul 2002 02:17:12 +0300 (EEST)
Received: by shodan.irccrew.org (Postfix, from userid 6976)
id 8BAD24C0A0; Mon, 29 Jul 2002 02:17:11 +0300 (EEST)
Date: Mon, 29 Jul 2002 02:17:11 +0300
From: John Smith <jsmithspam#yahoo.com>
To: dovecot#procontrol.fi
Subject: [dovecot] Dovecot 0.93 released
Message-ID: <20020729021711.W22431#irccrew.org>
Mime-Version: 1.0
Content-Disposition: inline
User-Agent: Mutt/1.2.5i
Content-Type: text/plain; charset=us-ascii
X-archive-position: 2
X-ecartis-version: Ecartis v1.0.0
Sender: dovecot-bounce#procontrol.fi
Errors-to: dovecot-bounce#procontrol.fi
X-original-sender: tss#iki.fi
Precedence: bulk
X-list: dovecot
X-UID: 2
Status: O
First alpha quality release, everything critical is now implemented. From
now on it's mostly stabilization and optimization. Features that can't break
existing code could still be added, especially SSL and authentication stuff.
msg_3.txt
From cras#irccrew.org Wed Jul 31 22:48:41 2002
Received: with ECARTIS (v1.0.0; list dovecot); Wed, 31 Jul 2002 22:48:41 +0300 (EEST)
Return-Path: <cras#irccrew.org>
Delivered-To: dovecot#procontrol.fi
Received: from shodan.irccrew.org (shodan.irccrew.org [80.83.4.2])
by danu.procontrol.fi (Postfix) with ESMTP id F141123829
for <dovecot#procontrol.fi>; Wed, 31 Jul 2002 22:48:40 +0300 (EEST)
Received: by shodan.irccrew.org (Postfix, from userid 6976)
id 42ED44C0A0; Wed, 31 Jul 2002 22:48:40 +0300 (EEST)
Date: Wed, 31 Jul 2002 22:48:39 +0300
From: Timo Sirainen <tss#iki.fi>
To: dovecot#procontrol.fi
Subject: [dovecot] v0.95 released
Message-ID: <20020731224839.H22431#irccrew.org>
Mime-Version: 1.0
Content-Disposition: inline
User-Agent: Mutt/1.2.5i
Content-Type: text/plain; charset=us-ascii
X-archive-position: 3
X-ecartis-version: Ecartis v1.0.0
Sender: dovecot-bounce#procontrol.fi
Errors-to: dovecot-bounce#procontrol.fi
X-original-sender: tss#iki.fi
Precedence: bulk
X-list: dovecot
X-UID: 3
Status: O
v0.95 2002-07-31 Timo Sirainen <tss#iki.fi>
+ Initial SSL support using GNU TLS, tested with v0.5.1.
TLS support is still missing.
+ Digest-MD5 authentication method
+ passwd-file authentication backend
+ Code cleanups
- Found several bugs from mempool and ioloop code, now we should
be stable? :)
- A few corrections for long header field handling
Sample program output:
This is a Java 8 version of jewelsea's solution but in awesome lambdas:
fromColumn.setCellValueFactory(m -> {
// m.getValue() returns the Message instance for a particular TableView row
return new ReadOnlyObjectWrapper<String>(Arrays.toString(m.getValue().getFrom()));
}
});
Lol, gotta love lambdas
Using the above mentioned solution, wether I use it as it is or I accept the advices of Eclipse i add a try/catch and a further return value, which looks like this at the end:
fromColumn.setCellValueFactory(new Callback<CellDataFeatures<Message, String>, ObservableValue<String>>() {
public ObservableValue<String> call(CellDataFeatures<Message, String> m) {
// m.getValue() returns the Message instance for a particular TableView row
try {
return new ReadOnlyObjectWrapper<String>(Arrays.toString(m.getValue().getFrom()));
} catch (MessagingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
});
The result is the same, I am getting a (visual) empty tableview. This means that even the tablecolumns are empty using this setCellFactury()-solution. Well, as workaround I could define a class where I could store al the three values as a String and then pass it to setCellValueFactory() using PropertyValueFactory, but I hope to get it done properly.
Any further advices?
best regards