Last active
August 25, 2017 13:37
-
-
Save gmoqa/51e504a1424b87f3455c to your computer and use it in GitHub Desktop.
Symfony2 command to retrieve and save, emails by IMAP, save the email, attachments and analize a email content for set a specific Entity.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace AppBundle\Command; | |
use AppBundle\Entity\Evento; | |
use AppBundle\Entity\EventoAdjunto; | |
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand; | |
use Symfony\Component\Console\Input\InputArgument; | |
use Symfony\Component\Console\Input\InputInterface; | |
use Symfony\Component\Console\Input\InputOption; | |
use Symfony\Component\Console\Output\OutputInterface; | |
use Symfony\Component\HttpFoundation\File\File; | |
/** | |
* Class RetrieveEmailCommand | |
* @package AppBundle\Command | |
* author Guillermo Quinteros <gu.quinteros@gmail.com> | |
*/ | |
class RetrieveEmailCommand extends ContainerAwareCommand | |
{ | |
protected function configure() | |
{ | |
$this | |
->setName('retrieve:email') | |
->setDescription('Retrieve a email...') | |
; | |
} | |
/** | |
* Que elegancia la de Francia | |
* From Chile with ♥ | |
* @param InputInterface $input | |
* @param OutputInterface $output | |
* @return Object | |
*/ | |
protected function execute(InputInterface $input, OutputInterface $output) | |
{ | |
$em = $this->getContainer()->get('doctrine')->getManager(); | |
$output->writeln('<question> <gu.quinteros@gmail.com> - from Chile with ♥ </question>'); | |
$output->writeln('<question> Conectando con Gmail..... </question>'); | |
$imap_client = imap_open( | |
$this->getContainer()->getParameter('email.gmail.imap'), | |
$this->getContainer()->getParameter('email.gmail.account'), | |
$this->getContainer()->getParameter('email.gmail.pass') | |
); | |
if (!$imap_client) { | |
$output->writeln('<error>'.imap_last_error().'</error>'); | |
exit; | |
} | |
$output->writeln('<info> Conectado ✔</info>'); | |
$output->writeln('<question> Validando correos..... </question>'); | |
$emails = imap_search($imap_client, 'UNSEEN'); | |
if (!$emails || count($emails) < 1) { | |
$output->writeln('<info> No hay correos nuevos ✔</info>'); | |
exit; | |
} | |
$output->writeln('<info>'.count($emails).' - Recibido/s ✔</info>'); | |
$output->writeln('<question> Procesando..... </question>'); | |
foreach ($emails as $email_id) { | |
$header = imap_fetch_overview($imap_client, $email_id, 0); | |
$subject = imap_mime_header_decode($header[0]->subject); | |
$body = quoted_printable_decode(imap_fetchbody($imap_client, $email_id, 2.1)); | |
if (!strlen($body) > 0) { | |
$body = quoted_printable_decode(imap_fetchbody($imap_client, $email_id, 1.1)); | |
} | |
$structure = imap_fetchstructure($imap_client, $email_id); | |
$attachments = []; | |
if (isset($structure->parts) && count($structure->parts)) { | |
for ($i = 0; $i < count($structure->parts); $i++) { | |
$attachments[$i] = array( | |
'is_attachment' => false, | |
'filename' => '', | |
'name' => '', | |
'attachment' => '' | |
); | |
if ($structure->parts[$i]->ifdparameters) { | |
foreach ($structure->parts[$i]->dparameters as $object) { | |
if (strtolower($object->attribute) == 'filename') { | |
$attachments[$i]['is_attachment'] = true; | |
$attachments[$i]['filename'] = $object->value; | |
} | |
} | |
} | |
if ($structure->parts[$i]->ifparameters) { | |
foreach ($structure->parts[$i]->parameters as $object) { | |
if (strtolower($object->attribute) == 'name') { | |
$attachments[$i]['is_attachment'] = true; | |
$attachments[$i]['name'] = $object->value; | |
} | |
} | |
} | |
if ($attachments[$i]['is_attachment']) { | |
$attachments[$i]['attachment'] = imap_fetchbody($imap_client, $email_id, $i+1); | |
if ($structure->parts[$i]->encoding == 3) { | |
$attachments[$i]['attachment'] = base64_decode($attachments[$i]['attachment']); | |
} elseif ($structure->parts[$i]->encoding == 4) { | |
$attachments[$i]['attachment'] = quoted_printable_decode($attachments[$i]['attachment']); | |
} | |
} | |
} | |
} | |
$evento = new Evento(); | |
$emailData = $this->getEmailData(imap_utf8($body)); | |
$evento | |
->setAsunto(utf8_encode($subject[0]->text)) | |
->setBody(imap_utf8($body)) | |
->setDesde(utf8_encode($header[0]->from)) | |
->setFecha(new \DateTime()) | |
->setFechaCreacion(new \DateTime()) | |
->setFecha($emailData['fecha']) | |
->setDescripcion('Descripción') | |
->setEstado('Estado') | |
->setRit($emailData['RIT']) | |
->setRuc($emailData['RUC']) | |
->setTipo(1); | |
$em->persist($evento); | |
foreach ($attachments as $attachment) { | |
if ($attachment['attachment']) { | |
/** @var File $file */ | |
$file = $attachment['attachment']; | |
$fileName = uniqid().'-'.$attachment['filename']; | |
$pathDocument = $this->getContainer() | |
->getParameter('kernel.root_dir') . '/../web/uploads/adjuntos'; | |
file_put_contents($pathDocument.'/'.$fileName, $file); | |
$eventoAdjunto = new EventoAdjunto(); | |
$eventoAdjunto->setEvento($evento); | |
$eventoAdjunto->setFile($fileName); | |
$em->persist($eventoAdjunto); | |
} | |
} | |
imap_delete($imap_client, $email_id); | |
imap_close($imap_client, CL_EXPUNGE); | |
$output->writeln('<info>'.utf8_encode($subject[0]->text).' - Desde :'.$header[0]->from.' ✔ </info>'); | |
} | |
$em->flush(); | |
$output->writeln('<question>'.count($emails).'- Archivado/s ✔</question>'); | |
} | |
/** | |
* @param $body | |
* @return array | |
*/ | |
public function getEmailData($body) | |
{ | |
return [ | |
'RUC' => str_replace(' ', '', $this->getStringBetween($body, 'RUC', ',')), | |
'juzgado' => ltrim($this->getStringBetween($body, 'El', '.')), | |
'RIT' => str_replace(' ', '', $this->getStringBetween($body, 'RIT', '.')), | |
'fecha' => new \DateTime($this->getStringBetween($body, 'Date:(', ')')) | |
]; | |
} | |
/** | |
* @param $string | |
* @param $start | |
* @param $end | |
* @return string | |
*/ | |
public function getStringBetween($string, $start, $end) | |
{ | |
$string = ' ' . $string; | |
$ini = strpos($string, $start); | |
if ($ini == 0) { | |
return ''; | |
} | |
$ini += strlen($start); | |
$len = strpos($string, $end, $ini) - $ini; | |
return substr($string, $ini, $len); | |
} | |
} |
Excellent work! Saved me a lot of time ! Thanks a lot
Might be usefu for someone: for Office 365, I used those parameters:
mail.imap: '{outlook.office365.com:993/imap/ssl}INBOX'
mail.account: 'mail@domain.tld'
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks for this retrieve email command.
It's completely plug-and-play symfony ready, thanks!!!
I just wander what you with the 'Evento' entity? Is this like a queue to process the attachments or just an entity you use for something specific reason?
Regards,
Tim