diff --git a/include/class.client.php b/include/class.client.php index 3e55929014452469378aece33cd35295dbaed194..9f29b0e10ee6118b9ba19ff860e447ec85c0bcd0 100644 --- a/include/class.client.php +++ b/include/class.client.php @@ -196,13 +196,23 @@ class EndUser extends AuthenticatedUser { if(!$this->user || !is_callable(array($this->user, $name))) - return false; + return $this->getVar(substr($name, 3)); return $args ? call_user_func_array(array($this->user, $name), $args) : call_user_func(array($this->user, $name)); } + function getVar($tag) { + $u = $this; + // Traverse the $user properties of all nested user objects to get + // to the User instance with the custom data + while (isset($u->user)) + $u = $u->user; + if (method_exists($u, 'getVar')) + return $u->getVar($tag); + } + function getId() { //We ONLY care about user ID at the ticket level if ($this->user instanceof Collaborator) diff --git a/include/class.dynamic_forms.php b/include/class.dynamic_forms.php index ef7c476a8168ce0bc55112faa5fc682aada04116..46c8460ef91772294f05cb0a96562e702c4a5e8f 100644 --- a/include/class.dynamic_forms.php +++ b/include/class.dynamic_forms.php @@ -381,7 +381,10 @@ class DynamicFormField extends VerySimpleModel { array($this->getField(), $what), $args); } - function getField() { + function getField($cache=true) { + if (!$cache) + return new FormField($this->ht); + if (!isset($this->_field)) $this->_field = new FormField($this->ht); return $this->_field; diff --git a/include/class.filter.php b/include/class.filter.php index 50d32f6e3e530b6912956cb1b79aae2fddad0c7f..2370ab6640ba791257c8e96aecc34b46874f5f61 100644 --- a/include/class.filter.php +++ b/include/class.filter.php @@ -870,6 +870,7 @@ class TicketFilter { 'X-Autorespond' => '*', 'X-Mail-Autoreply' => '*', 'X-Autogenerated' => 'REPLY', + 'X-AMAZON-MAIL-RELAY-TYPE' => 'NOTIFICATION', ); foreach ($auto_headers as $header=>$find) { diff --git a/include/class.mailparse.php b/include/class.mailparse.php index d498a77f7fd99bfe737fc1a9bddef58b505baa53..48a402dfb013e724f1b8eb9c1d683007fa5d896e 100644 --- a/include/class.mailparse.php +++ b/include/class.mailparse.php @@ -140,8 +140,8 @@ class Mail_Parse { /* static */ function splitHeaders($headers_text, $as_array=false) { $headers = preg_split("/\r?\n/", $headers_text); for ($i=0, $k=count($headers); $i<$k; $i++) { - # XXX: Might tabs be used here? - if (substr($headers[$i], 0, 1) == " ") { + // first char might be whitespace (" " or "\t") + if (in_array($headers[$i][0], array(" ", "\t"))) { # Continuation from previous header (runon to next line) $j=$i-1; while (!isset($headers[$j]) && $j>0) $j--; $headers[$j] .= " ".ltrim($headers[$i]); @@ -365,7 +365,7 @@ class Mail_Parse { || !strcasecmp($part->ctype_primary,'application')))) { if (isset($part->d_parameters['filename'])) - $filename = $part->d_parameters['filename']; + $filename = Format::mimedecode($part->d_parameters['filename'], $this->charset); elseif (isset($part->d_parameters['filename*'])) // Support RFC 6266, section 4.3 and RFC, and RFC 5987 $filename = Format::decodeRfc5987( @@ -374,7 +374,7 @@ class Mail_Parse { // Support attachments that do not specify a content-disposition // but do specify a "name" parameter in the content-type header. elseif (isset($part->ctype_parameters['name'])) - $filename = $part->ctype_parameters['name']; + $filename = Format::mimedecode($part->ctype_parameters['name'], $this->charset); elseif (isset($part->ctype_parameters['name*'])) $filename = Format::decodeRfc5987( $part->ctype_parameters['name*']); diff --git a/include/class.thread.php b/include/class.thread.php index c69eb28549412bd25454a24f7df97334299331aa..24016f02d3305ca0d82701f4a5d27bc5d4287d36 100644 --- a/include/class.thread.php +++ b/include/class.thread.php @@ -424,8 +424,17 @@ Class ThreadEntry { function getUser() { - if (!isset($this->user)) - $this->user = User::lookup($this->getUserId()); + if (!isset($this->user)) { + if (!($ticket = $this->getTicket())) + return null; + + if ($ticket->getOwnerId() == $ticket->getUserId()) + $this->user = new TicketOwner( + User::lookup($this->getUserId()), $ticket); + else + $this->user = Collborator::lookup(array( + 'userId'=>$this->getUserId(), 'ticketId'=>$this->getTicketId())); + } return $this->user; } diff --git a/include/class.ticket.php b/include/class.ticket.php index b46f151b001ad30366fb5be4686ae694e3d6edb9..f0d4c770f251741bd386c28512599da2ed6aaa2b 100644 --- a/include/class.ticket.php +++ b/include/class.ticket.php @@ -1244,7 +1244,7 @@ class Ticket { if($tag && is_callable(array($this, 'get'.ucfirst($tag)))) return call_user_func(array($this, 'get'.ucfirst($tag))); - switch(strtolower($tag)) { + switch(mb_strtolower($tag)) { case 'phone': case 'phone_number': return $this->getPhoneNumber(); @@ -1292,7 +1292,6 @@ class Ticket { return $this->getOwner(); break; default: - $tag = mb_strtolower($tag); if (isset($this->_answers[$tag])) // The answer object is retrieved here which will // automatically invoke the toString() method when the diff --git a/include/class.user.php b/include/class.user.php index 31ceddb4522a3acd06764a2a67ff4b849b6aae3a..eaa6af0bd034e337476fc8943fed1b8114103fc3 100644 --- a/include/class.user.php +++ b/include/class.user.php @@ -262,7 +262,7 @@ class User extends UserModel { if($tag && is_callable(array($this, 'get'.ucfirst($tag)))) return call_user_func(array($this, 'get'.ucfirst($tag))); - $tag = strtolower($tag); + $tag = mb_strtolower($tag); foreach ($this->getDynamicData() as $e) if ($a = $e->getAnswer($tag)) return $a; diff --git a/include/staff/dynamic-form.inc.php b/include/staff/dynamic-form.inc.php index ca7dcf82e558f17ac828f4bc34d65808f1ba9ac2..5f9905c40807faad2d30df2d49a1d0d0c1f5744c 100644 --- a/include/staff/dynamic-form.inc.php +++ b/include/staff/dynamic-form.inc.php @@ -154,7 +154,11 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info); $('#field-config').show(); return false; "><i class="icon-edit"></i> Config</a> - <?php } ?></td> + <?php } ?> + <div class="error" style="white-space:normal"><?php + if ($ferrors['type']) echo $ferrors['type']; + ?></div> + </td> <td><input type="checkbox" name="private-<?php echo $id; ?>" <?php if ($f->get('private')) echo 'checked="checked"'; ?> <?php echo $force_privacy ?>/></td> diff --git a/scp/forms.php b/scp/forms.php index 60cbe78570e98a4251fb26a4efe27744bca60ba3..245ed33712b80c508ad47c68ee0d4b225265c820 100644 --- a/scp/forms.php +++ b/scp/forms.php @@ -51,6 +51,13 @@ if($_POST) { $field->addError('Field variable name is not unique', 'name'); if (preg_match('/[.{}\'"`; ]/u', $field->get('name'))) $field->addError('Invalid character in variable name. Please use letters and numbers only.', 'name'); + // Subject (Issue Summary) must always have data + if ($form->get('type') == 'T' && $field->get('name') == 'subject') { + if (($f = $field->getField(false)->getImpl()) && !$f->hasData()) + $field->addError('The issue summary must be a field ' + .'that supports user input, such as short answer', + 'type'); + } if ($field->get('name')) $names[] = $field->get('name'); if ($field->isValid())