Completed
Push — feat_email_envelope ( e5445d )
by Stefano
02:37
created

Envelope::bcc()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 6
Code Lines 5

Duplication

Lines 3
Ratio 50 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 3
loc 6
rs 9.2
cc 4
eloc 5
nc 3
nop 1
1
<?php
2
3
/**
4
 * Email\Envelope
5
 *
6
 * Wraps and compile a MIME Email envelope.
7
 *
8
 * @package core
9
 * @author [email protected]
10
 * @copyright Caffeina srl - 2016 - http://caffeina.com
11
 */
12
13
namespace Email;
14
15
class Envelope {
16
17
  protected  $uid,
18
             $to,
19
             $from,
20
             $cc,
21
             $bcc,
22
             $replyTo,
23
             $subject,
24
             $message,
25
             $contentType = 'text/html; charset="utf-8"',
26
             $attachments,
27
             $compiled_head,
28
             $compiled_body;
29
30
  public function __construct($email=null){
31
    if ($email) {
32
      $email = (object)$email;
33
      if(isset($email->to))           $this->to($email->to);
34
      if(isset($email->from))         $this->from($email->from);
35
      if(isset($email->cc))           $this->cc($email->cc);
36
      if(isset($email->bcc))          $this->bcc($email->bcc);
37
      if(isset($email->replyTo))      $this->replyTo($email->replyTo);
38
      if(isset($email->subject))      $this->subject($email->subject);
39
      if(isset($email->message))      $this->message($email->message);
40
      if(isset($email->attachments))  $this->attach($email->attachments);
41
    }
42
    $this->uid  = '_CORE_'.md5(uniqid(time()));
43
44
  }
45
46
  protected function add_emails(&$pool, $emails, $append=true){
47
    $this->compiled_head = null;
48
    foreach ((array)$emails as $values) {
49
      foreach(preg_split('/\s*,\s*/',$values) as $value) {
50
        if(strpos($value,'<')!==false){
51
          $value   = str_replace('>','',$value);
52
          $parts   = explode('<',$value,2);
53
          $name    = trim(current($parts));
54
          $email   = trim(end($parts));
55
          $address = "$name <{$email}>";
56
        } else {
57
          $address = $value;
58
        }
59
        if ($append) $pool[] = $address; else $pool = $address;
60
      }
61
    }
62
  }
63
64
  public function from($value=null){
65 View Code Duplication
    if ($value!==null && $value) {
66
      $this->add_emails($this->from, $value, false);
67
    } else if ($value===false) $this->from = false;
68
    return $this->from;
69
  }
70
71
  public function to($value=null){
72 View Code Duplication
    if ($value!==null && $value) {
73
      $this->add_emails($this->to, $value);
74
    } else if ($value===false) $this->to = [];
75
    return $this->to;
76
  }
77
78
  public function cc($value=null){
79 View Code Duplication
    if ($value!==null && $value) {
80
      $this->add_emails($this->cc, $value);
81
    } else if ($value===false) $this->cc = [];
82
    return $this->cc;
83
  }
84
85
  public function bcc($value=null){
86 View Code Duplication
    if ($value!==null && $value) {
87
      $this->add_emails($this->bcc, $value);
88
    } else if ($value===false) $this->bcc = [];
89
    return $this->bcc;
90
  }
91
92
  public function replyTo($value=null){
93 View Code Duplication
    if ($value!==null && $value) {
94
      $this->add_emails($this->replyTo, $value, false);
95
    } else if ($value===false) $this->replyTo = false;
96
    return $this->replyTo;
97
  }
98
99
  public function subject($value=null){
100
    if ($value!==null && $value) {
101
      $this->compiled_head = null;
102
      $this->subject = $value;
103
    } else if ($value===false) $this->subject = false;
104
    return $this->subject;
105
  }
106
107 View Code Duplication
  public function contentType($value=null){
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
108
    if ($value!==null && $value) {
109
      $this->compiled_body = null;
110
      $this->contentType = $value;
111
    } else if ($value===false) $this->contentType = false;
0 ignored issues
show
Documentation Bug introduced by
The property $contentType was declared of type string, but false is of type false. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
112
    return $this->contentType;
113
  }
114
115 View Code Duplication
  public function message($value=null){
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
116
    if ($value!==null && $value) {
117
      $this->compiled_body = null;
118
      $this->message = $value;
119
    } else if ($value===false) $this->message = false;
120
    return $this->message;
121
  }
122
123
  public function attach($file){
124
    $this->compiled_body = null;
125
    if (isset($file->content) || isset($file['content'])) {
126
      $this->attachments[] = $file;
127
    } else foreach ((array)$file as $curfile) {
128
      $this->attachments[] = $curfile;
129
    }
130
  }
131
132
  public function head($recompile=false){
133
    if ($recompile || null === $this->compiled_head){
134
      $head   = [];
135
      $head[] = "Subject: {$this->subject}";
136
      if($this->from)                        $head[] = "From: {$this->from}";
137
      if(is_array($this->to)  && $this->to)  $head[] = "To: "  . implode(', ',$this->to);
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->to of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
138 View Code Duplication
      if(is_array($this->cc)  && $this->cc)  $head[] = "Cc: "  . implode(', ',$this->cc);
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->cc of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
139 View Code Duplication
      if(is_array($this->bcc) && $this->bcc) $head[] = "Bcc: " . implode(', ',$this->bcc);
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->bcc of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
140
      if($this->replyTo)                     $head[] = "Reply-To: {$this->replyTo}";
141
      $head[] = 'MIME-Version: 1.0';
142
      $head[] = "Content-Type: multipart/mixed; boundary=\"{$this->uid}\"";
143
144
      $this->compiled_head = implode("\r\n", $head);
145
    }
146
    return $this->compiled_head;
147
  }
148
149
  public function body($recompile=false){
150
    if ($recompile || null === $this->compiled_body){
151
      $body[] = "--{$this->uid}";
0 ignored issues
show
Coding Style Comprehensibility introduced by
$body was never initialized. Although not strictly required by PHP, it is generally a good practice to add $body = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
152
      $body[] = "Content-Type: {$this->contentType}";
153
      $body[] = "Content-Transfer-Encoding: quoted-printable";
154
      $body[] = '';
155
      $body[] = quoted_printable_encode($this->message);
156
      $body[] = '';
157
158
      if ($this->attachments) foreach ((array)$this->attachments as $file) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->attachments of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
159
160
        if (is_string($file)) {
161
          $name = basename($file);
162
          $data = file_get_contents($file);
163
        } else {
164
          $name = isset($file['name'])    ? $file['name']    : 'untitled';
165
          $data = isset($file['content']) ? $file['content'] : '';
166
        }
167
168
        $body[] = "--{$this->uid}";
169
        $body[] = "Content-Type: application/octet-stream; name=\"{$name}\"";
170
        $body[] = "Content-Transfer-Encoding: base64";
171
        $body[] = "Content-Disposition: attachment; filename=\"{$name}\"";
172
        $body[] = '';
173
        $body[] = chunk_split(base64_encode($data));
174
        $body[] = '';
175
      }
176
177
      $body[] = "--{$this->uid}--";
178
179
      $this->compiled_body = implode("\r\n", $body);
180
    }
181
    return $this->compiled_body;
182
  }
183
184
  public function build(){
185
    return $this->head() . "\r\n" . $this->body();
186
  }
187
188
}
189