Permalink
Branch: master
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
177 lines (142 sloc) 4.16 KB
<?php
namespace BeyondCode\Mailbox\Routing;
use ReflectionFunction;
use Illuminate\Support\Str;
use Illuminate\Support\Collection;
use Illuminate\Container\Container;
use BeyondCode\Mailbox\InboundEmail;
use BeyondCode\Mailbox\Concerns\HandlesParameters;
use Illuminate\Routing\RouteDependencyResolverTrait;
use ZBateson\MailMimeParser\Header\Part\AddressPart;
use BeyondCode\Mailbox\Concerns\HandlesRegularExpressions;
class Route
{
use HandlesParameters;
use HandlesRegularExpressions;
use RouteDependencyResolverTrait;
const FROM = 'from';
const TO = 'to';
const CC = 'cc';
const SUBJECT = 'subject';
const FALLBACK = 'fallback';
const CATCH_ALL = 'catch-all';
protected $mailbox;
protected $subject;
protected $pattern;
protected $action;
protected $container;
protected $matches = [];
protected $wheres = [];
public function __construct(string $subject, string $pattern, $action)
{
$this->subject = $subject;
$this->pattern = $pattern;
$this->action = $action;
}
public function setContainer(Container $container)
{
$this->container = $container;
return $this;
}
public function subject()
{
return $this->subject;
}
public function action()
{
return $this->action;
}
public function pattern()
{
return $this->pattern;
}
public function matches(InboundEmail $message): bool
{
$subjects = $this->gatherMatchSubjectsFromMessage($message);
return Collection::make($subjects)->first(function (string $subject) {
return $this->matchesRegularExpression($subject);
}) !== null;
}
protected function gatherMatchSubjectsFromMessage(InboundEmail $message)
{
switch ($this->subject) {
case self::FROM:
return [$message->from()];
break;
case self::TO:
return $this->convertMessageAddresses($message->to());
break;
case self::CC:
return $this->convertMessageAddresses($message->cc());
break;
case self::SUBJECT:
return [$message->subject()];
break;
}
}
/**
* @param $addresses AddressPart[]
* @return array
*/
protected function convertMessageAddresses($addresses): array
{
return Collection::make($addresses)
->map(function (AddressPart $address) {
return $address->getEmail();
})->toArray();
}
public function run(InboundEmail $email)
{
$this->container = $this->container ?: new Container;
if ($this->isMailboxAction()) {
$this->runMailbox($email);
} else {
$this->runCallable($email);
}
}
protected function isMailboxAction()
{
return is_string($this->action);
}
protected function runMailbox(InboundEmail $email)
{
$method = $this->getMailboxMethod();
$parameters = $this->resolveClassMethodDependencies(
[$email] + $this->parametersWithoutNulls(), $this->getMailbox(), $method
);
return $this->getMailbox()->{$method}(...array_values($parameters));
}
protected function runCallable(InboundEmail $email)
{
$callable = $this->action;
return $callable(...array_values($this->resolveMethodDependencies(
[$email] + $this->parametersWithoutNulls(), new ReflectionFunction($this->action)
)));
}
public function getMailbox()
{
if (! $this->mailbox) {
$class = $this->parseMailboxCallback()[0];
$this->mailbox = $this->container->make(ltrim($class, '\\'));
}
return $this->mailbox;
}
/**
* Get the controller method used for the route.
*
* @return string
*/
protected function getMailboxMethod()
{
return $this->parseMailboxCallback()[1] ?? '__invoke';
}
/**
* Parse the controller.
*
* @return array
*/
protected function parseMailboxCallback()
{
return Str::parseCallback($this->action);
}
}