@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.)
hq.recaptime.dev/wiki/Phorge
phorge
phabricator
1#!/usr/bin/env php
2<?php
3
4// NOTE: This script is very oldschool and takes the environment as an argument.
5// Some day, we could take a shot at cleaning this up.
6if ($argc > 1) {
7 foreach (array_slice($argv, 1) as $arg) {
8 if (!preg_match('/^-/', $arg)) {
9 $_SERVER['PHABRICATOR_ENV'] = $arg;
10 break;
11 }
12 }
13}
14
15$root = dirname(dirname(dirname(__FILE__)));
16require_once $root.'/scripts/__init_script__.php';
17require_once $root.'/externals/mimemailparser/__init.php';
18
19$args = new PhutilArgumentParser($argv);
20$args->parseStandardArguments();
21$args->parse(
22 array(
23 array(
24 'name' => 'process-duplicates',
25 'help' => pht(
26 "Process this message, even if it's a duplicate of another message. ".
27 "This is mostly useful when debugging issues with mail routing."),
28 ),
29 array(
30 'name' => 'env',
31 'wildcard' => true,
32 ),
33 ));
34
35if (!extension_loaded('mailparse')) {
36 throw new Exception(
37 pht(
38 'PhpMimeMailParser for handling incoming mail requires the PHP '.
39 'mailparse extension to be installed.'));
40}
41
42$parser = new \PhpMimeMailParser\Parser();
43$parser->setText(file_get_contents('php://stdin'));
44
45$content = array();
46foreach (array('text', 'html') as $part) {
47 $part_body = $parser->getMessageBody($part);
48 $content[$part] = $part_body;
49}
50
51$headers = $parser->getHeaders();
52
53if ($args->getArg('process-duplicates')) {
54 $headers['message-id'] = Filesystem::readRandomCharacters(64);
55}
56
57$received = new PhabricatorMetaMTAReceivedMail();
58$received->setHeaders($headers);
59$received->setBodies($content);
60
61$attachments = array();
62foreach ($parser->getAttachments() as $attachment) {
63 if (preg_match('@text/(plain|html)@', $attachment->getContentType()) &&
64 $attachment->getContentDisposition() == 'inline') {
65 // If this is an "inline" attachment with some sort of text content-type,
66 // do not treat it as a file for attachment. MimeMailParser already picked
67 // it up in the getMessageBody() call above. We still want to treat 'inline'
68 // attachments with other content types (e.g., images) as attachments.
69 continue;
70 }
71
72 $file = PhabricatorFile::newFromFileData(
73 $attachment->getContent(),
74 array(
75 'name' => $attachment->getFilename(),
76 'viewPolicy' => PhabricatorPolicies::POLICY_NOONE,
77 ));
78 $attachments[] = $file->getPHID();
79}
80
81try {
82 $received->setAttachments($attachments);
83 $received->save();
84 $received->processReceivedMail();
85} catch (Exception $e) {
86 $received
87 ->setMessage(pht('EXCEPTION: %s', $e->getMessage()))
88 ->save();
89
90 throw $e;
91}