Use php-imap classes to parse new mails from server, with Symfony 2.7

489 Views Asked by At

I'm working on Symfony 2.7. I have to create a mail client to retrieve and send mails from the mail server (IMAP protocol); to do this, I used the php-imap classes, with a bundle (included with composer). But I'm not sure about the way I should use them : Do I extend the classes to represent my Mail and Mailbox objects, or should I create new classes from scratch ?

I don't want to manipulate IMAP straight from my controllers, I think it would be too long to process. Is that right?

Is it a good idea to create a "watcher" (periodic command executed by cron) to parse new mails every 2 minutes or so, create new mails entity from them, and send the waiting ones? Could I do that while extending the php-imap classes? This way I would use one class only? But wouldn't that be too heavy to store for the database ?

What's the correct way to fetch only new mails ? Do I have to use a specific function, like imap_check, or do I do that by a search criteria (like date from the last check) ? I tried with criteria "NEW", but that was unsuccessful.

Also, the mailboxes I have to parse are quite heavy. I tried to make a search in one of them with "ALL" criteria, but it's really long to process ! Am I doing it right ? Do I just have to be patient ?

Here's what I did for the "watcher" function :

use PhpImap\Mailbox as ImapMailbox;

class GetNewMailsCommand extends ContainerAwareCommand
{

    $em = $this->getContainer()->get('doctrine')->getEntityManager();

    $mailboxes = $em->getRepository('MIPMailBundle:MailBox')->findAllActive();

    foreach ($mailboxes as $mailbox){
        $imapBox = new ImapMailbox('{'.$mailbox->getServer().':143/notls/norsh/novalidate-cert}INBOX', $mailbox->getAdress(), $mailbox->getPassword());

        if ($mailbox->getMails() == null || empty($mailbox->getMails())){
            $mailsIds = $imapBox->searchMailbox('ALL');
            if(!$mailsIds) {
                $output->writeln($mailbox->getAdress() . " is empty");
            }
        } else {
            $mailsIds = $imapBox->searchMailbox('NEW');
            if(!$mailsIds) {
                $output->writeln("No new mail for " . $mailbox->getAdress());
            }
        }

        foreach ($mailsIds as $mailId){
            $imapMail = $imapBox->getMail($mailId);

            $mail = new Mail($mailbox, false);
            $mail->setSubject($imapMail->subject);
            $mail->setSender($imapMail->fromAddress);
            $mail->setCc($imapMail->cc);
            $mail->setBcc($imapMail->bcc);
            $mail->setToString($imapMail->toString);
            $mail->setContent($imapMail->textPlain);
            $mail->setDate(new \DateTime($imapMail->date));

            foreach ($imapMail->to as $toAddress){
                $mail->addRecipient($toAddress);
            }

            $em->persist($mail);
        }
    }

    $em->flush();

And here's my entities :

class MailBox
{
/**
 * @var integer
 *
 * @ORM\Column(name="id", type="integer")
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="AUTO")
 */
private $id;

/**
 * @var
 *
 * @ORM\OneToOne(targetEntity="\MIP\CRMBundle\Entity\Agency", inversedBy="mailBox", cascade={"persist"})
 * @ORM\JoinColumn(name="user_id", referencedColumnName="id", nullable=true)
 */
private $user;

/**
 * @var Agency
 *
 * @ORM\ManyToMany(targetEntity="\MIP\CRMBundle\Entity\Agency", inversedBy="mailBoxShared")
 * @ORM\JoinTable(name="mailbox_shared")
 */
private $sharedTo;

/**
 * @var
 *
 * @ORM\OneToMany(targetEntity="Mail", mappedBy="mailBox")
 */
private $mails;

/**
 * @var boolean
 *
 * @ORM\Column(name="active", type="boolean")
 */
private $active;

/**
 * @var string
 *
 * @ORM\Column(name="adress", type="string", length=255)
 */
private $adress;

/**
 * @var string
 *
 * @ORM\Column(name="server", type="string", length=255)
 */
private $server;

/**
 * @var string
 *
 * @ORM\Column(name="password", type="string", length=255)
 */
private $password;

/**
 * @var integer
 *
 * @ORM\Column(name="port", type="integer")
 */
private $port;

/**
 * MailBox constructor.
 */
public function __construct()
{
    $this->sharedTo = new ArrayCollection();
    $this->mails = new ArrayCollection();
}


class Mail
{


/**
 * @var integer
 *
 * @ORM\Column(name="id", type="integer")
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="AUTO")
 */
private $id;

/**
 * @var string
 *
 * @ORM\Column(name="sender", type="string", length=255)
 */
private $sender;

/**
 * @var array
 *
 * @ORM\Column(name="recipients", type="json_array", nullable=true)
 */
private $recipients;

/**
 * @var string
 *
 * @ORM\Column(name="toString", type="string", nullable=true)
 */
private $toString;

/**
 * @var array
 *
 * @ORM\Column(name="cc", type="json_array", nullable=true)
 */
private $cc;

/**
 * @var array
 *
 * @ORM\Column(name="bcc", type="json_array", nullable=true)
 */
private $bcc;

/**
 * @var string
 *
 * @ORM\Column(name="subject", type="string", length=255, nullable=true)
 */
private $subject;

/**
 * @var \DateTime
 *
 * @ORM\Column(name="date", type="datetime")
 */
private $date;

/**
 * @var string
 *
 * @ORM\Column(name="content", type="text", nullable=true)
 */
private $content;

/**
 * @var
 *
 * @ORM\OneToMany(targetEntity="MIP\CRMBundle\Entity\File", mappedBy="mail", cascade={"persist", "remove"})
 * @ORM\JoinColumn(name="file_id", referencedColumnName="id", nullable=true)
 */
protected $files;

/**
 * @var ArrayCollection
 */
private $attached;

/**
 * @var MailBox
 * @ORM\ManyToOne(targetEntity="MailBox", inversedBy="mails")
 * @ORM\JoinColumn(name="mailBox_id", referencedColumnName="id")
 */
private $mailBox;

/**
 * @var LabelSticker
 *
 * @ORM\ManyToMany(targetEntity="\MIP\MailBundle\Entity\LabelSticker", mappedBy="mails")
 */
private $labels;

/**
 * @var boolean
 */
private $readed;

/**
 * @var boolean
 */
private $sent;



/**
 * Constructor
 * @param MailBox $mailbox
 * @param boolean $readed
 */
public function __construct($mailbox, $readed)
{
    $this->files = new ArrayCollection();
    $this->date = new \DateTime('now');
    $this->mailBox = $mailbox;
    $this->readed = $readed;
}

Thanks for your help !

0

There are 0 best solutions below