1: <?php
2: namespace TIC\MailBundle\Repository;
3:
4: #use Doctrine\ORM\EntityRepository as BaseRepository;
5: use TIC\DormBundle\Base\TICRepository as BaseRepository;
6: use TIC\MailBundle\Entity\Template as Entity;
7:
8: /**
9: * Repository pour requêtes sur les entités des modèles de notification.
10: *
11: * @TODO voir si usage des traits RepositoryFilterable + optims PHP
12: */
13: class TemplateRepository extends BaseRepository
14: {
15: /**
16: * @var Listing default order
17: */
18: public $sortBy = ['ref' => 'ASC'];
19:
20: /**
21: * Liste des différentes valeurs existantes pour le champs 'target'.
22: * (permet l'alimentation des suggestions pour formulaire avec type_ahead)
23: *
24: * @return array Liste des différentes valeurs correspondantes
25: */
26: public function getTargets(): array
27: {
28: return $this->getFieldValues('target');
29: }
30:
31: /**
32: * Liste des modèles de notification restants à définir.
33: * (permet l'alimentation du sélecteur de références sur édition/création)
34: *
35: * @param array $templates Liste de toutes les références de modèles possibles
36: * @param string $current Référence à considérer disponible (exclue de la recherche)
37: * @return array Liste des références possibles non existantes (+ courante éventuelle)
38: */
39: public function listAvailableRefs(array $templates, string $current = null): array
40: {
41: if ($current === null) $current = '';
42:
43: $available = \array_combine($templates, $templates);
44:
45: $existing = $this->createQueryBuilder('m')
46: ->select('m.ref')
47: ->where('m.ref != :ref')
48: ->setParameter('ref', $current)
49: ->getQuery()->getResult('column');
50: ;
51: foreach ($existing as $ref) unset($available[$ref]);
52:
53: return $available;
54: }
55:
56: /**
57: * Analyse un fichier au format Mail/Mbox pour importer les données.
58: * (extraction dans un tableau associatif servant à initialiser chaque entité)
59: *
60: * @param object $fileinfo Instance SplFileInfo du fichier à importer
61: * @return string Message de l'exception en cas d'échec, ou Null si succès
62: */
63: public function importMail(object $fileinfo): ?string
64: {
65: $file = $fileinfo->openFile('r');
66:
67: $messages = array();
68: while (! $file->eof()) {
69: $data = array();
70:
71: // lecture des entêtes du message
72: $header = null;
73: while (! $file->eof()) {
74: $line = \rtrim($file->fgets(), "\r\n");
75: if (($line === '') && ($header !== null)) break;
76: if (\preg_match('/^([^:]+):\s+(.*)$/', $line, $m)) {
77: $header = $m[1];
78: $data[$header] = $m[2];
79: }
80: elseif (\preg_match('/^\s+([^\s].+)$/', $line, $m) && ($header !== null)) {
81: $data[$header].= $m[1];
82: }
83: }
84:
85: // lecture des body (text/plain, text/html, text/sms)
86: $boundary = (isset($data['Content-Type']) && \preg_match('/boundary=\"([^\"]+)\"/', $data['Content-Type'], $m)) ? $m[1] : null;
87: if ($boundary !== null) {
88: $body = $header = null;
89: while (! $file->eof()) {
90: $line = $file->fgets();
91: if (\preg_match('/^--' . $boundary . '(--)?/', $line, $m)) {
92: if (isset($m[1])) break;
93: $header = true; $body = null;
94: }
95: elseif ($header === true) {
96: if (\preg_match('/^[\r\n]*$/', $line, $m)) { $header = false; }
97: elseif (\preg_match('/^Content-Type:\s+text\/(plain|html|sms)/', $line, $m)) { $body = 'body_' . $m[1]; $data[$body] = ''; }
98: }
99: elseif ($body !== null) $data[$body].= $line;
100: }
101: } else {
102: $body = (isset($data['Content-Type']) && \preg_match('/\s+text\/(plain|html|sms)/', $data['Content-Type'], $m)) ? $m[1] : 'body_default';
103: $data[$body] = '';
104: while (! $file->eof()) {
105: $line = $file->fgets();
106: if (\preg_match('/^[\r\n]*$/', $line, $m)) break;
107: $data[$body].= $line;
108: }
109: }
110: if (isset($data['body_text']) && \preg_match('/^[\r\n]*$/', $data['body_text'])) $data['body_text'] = null;
111: if (isset($data['body_html']) && \preg_match('/^[\r\n]*$/', $data['body_html'])) $data['body_html'] = null;
112: if (isset($data['body_sms' ]) && \preg_match('/^[\r\n]*$/', $data['body_sms' ])) $data['body_sms' ] = null;
113:
114: // enregistrement des données du message
115: $ref = isset($data['X-TIC-Reference']) ? $data['X-TIC-Reference'] : null;
116: if ($ref !== null) {
117: if (! \array_key_exists($ref, $messages)) $messages[$ref] = array();
118: $locale = isset($data['Content-Language']) ? $data['Content-Language'] : '_DEFAULT_';
119: $messages[$ref][$locale] = $data;
120: }
121: }
122:
123: return $this->import($messages);
124: }
125:
126: /**
127: * Chargement des données d'un tableau associatif dans les entités correspondantes.
128: *
129: * @param array $messages Liste des données à importer pour chaque modèle (ref en clé)
130: * @return string Message de l'exception en cas d'échec, ou Null si succès
131: */
132: public function import(array $messages): ?string
133: {
134: if (empty($messages)) return null;
135: try {
136: $em = $this->getEntityManager();
137: foreach ($messages as $ref => $data) {
138: $item = $this->find($ref);
139: if (null === $item) {
140: $item = new Entity($ref);
141: $em->persist($item);
142: }
143: $item->import($data);
144: }
145: $em->flush();
146: } catch (\Exception $e) {
147: return $e->getMessage();
148: }
149: return null;
150: }
151:
152: }
153: