mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-22 21:40:55 +01:00
MetaMTA
This commit is contained in:
parent
74eb6d2bd5
commit
bc57b12ef0
18 changed files with 676 additions and 8 deletions
|
@ -17,7 +17,7 @@ celerity_register_resource_map(array(
|
||||||
),
|
),
|
||||||
'aphront-form-view-css' =>
|
'aphront-form-view-css' =>
|
||||||
array(
|
array(
|
||||||
'path' => '/res/17285e65/rsrc/css/aphront/form-view.css',
|
'path' => '/res/51ec6383/rsrc/css/aphront/form-view.css',
|
||||||
'type' => 'css',
|
'type' => 'css',
|
||||||
'requires' =>
|
'requires' =>
|
||||||
array(
|
array(
|
||||||
|
@ -25,7 +25,7 @@ celerity_register_resource_map(array(
|
||||||
),
|
),
|
||||||
'aphront-panel-view-css' =>
|
'aphront-panel-view-css' =>
|
||||||
array(
|
array(
|
||||||
'path' => '/res/d1ce0c3d/rsrc/css/aphront/panel-view.css',
|
'path' => '/res/fe62e634/rsrc/css/aphront/panel-view.css',
|
||||||
'type' => 'css',
|
'type' => 'css',
|
||||||
'requires' =>
|
'requires' =>
|
||||||
array(
|
array(
|
||||||
|
@ -74,7 +74,7 @@ celerity_register_resource_map(array(
|
||||||
),
|
),
|
||||||
'differential-changeset-view-css' =>
|
'differential-changeset-view-css' =>
|
||||||
array(
|
array(
|
||||||
'path' => '/res/921d3a0c/rsrc/css/application/differential/changeset-view.css',
|
'path' => '/res/658d181a/rsrc/css/application/differential/changeset-view.css',
|
||||||
'type' => 'css',
|
'type' => 'css',
|
||||||
'requires' =>
|
'requires' =>
|
||||||
array(
|
array(
|
||||||
|
|
|
@ -19,6 +19,7 @@ phutil_register_library_map(array(
|
||||||
'AphrontDialogView' => 'view/dialog',
|
'AphrontDialogView' => 'view/dialog',
|
||||||
'AphrontErrorView' => 'view/form/error',
|
'AphrontErrorView' => 'view/form/error',
|
||||||
'AphrontFileResponse' => 'aphront/response/file',
|
'AphrontFileResponse' => 'aphront/response/file',
|
||||||
|
'AphrontFormCheckboxControl' => 'view/form/control/checkbox',
|
||||||
'AphrontFormControl' => 'view/form/control/base',
|
'AphrontFormControl' => 'view/form/control/base',
|
||||||
'AphrontFormFileControl' => 'view/form/control/file',
|
'AphrontFormFileControl' => 'view/form/control/file',
|
||||||
'AphrontFormMarkupControl' => 'view/form/control/markup',
|
'AphrontFormMarkupControl' => 'view/form/control/markup',
|
||||||
|
@ -111,6 +112,11 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorFileUploadController' => 'applications/files/controller/upload',
|
'PhabricatorFileUploadController' => 'applications/files/controller/upload',
|
||||||
'PhabricatorFileViewController' => 'applications/files/controller/view',
|
'PhabricatorFileViewController' => 'applications/files/controller/view',
|
||||||
'PhabricatorLiskDAO' => 'applications/base/storage/lisk',
|
'PhabricatorLiskDAO' => 'applications/base/storage/lisk',
|
||||||
|
'PhabricatorMetaMTAController' => 'applications/metamta/controller/base',
|
||||||
|
'PhabricatorMetaMTADAO' => 'applications/metamta/storage/base',
|
||||||
|
'PhabricatorMetaMTAListController' => 'applications/metamta/controller/list',
|
||||||
|
'PhabricatorMetaMTAMail' => 'applications/metamta/storage/mail',
|
||||||
|
'PhabricatorMetaMTASendController' => 'applications/metamta/controller/send',
|
||||||
'PhabricatorPHID' => 'applications/phid/storage/phid',
|
'PhabricatorPHID' => 'applications/phid/storage/phid',
|
||||||
'PhabricatorPHIDAllocateController' => 'applications/phid/controller/allocate',
|
'PhabricatorPHIDAllocateController' => 'applications/phid/controller/allocate',
|
||||||
'PhabricatorPHIDController' => 'applications/phid/controller/base',
|
'PhabricatorPHIDController' => 'applications/phid/controller/base',
|
||||||
|
@ -155,6 +161,7 @@ phutil_register_library_map(array(
|
||||||
'AphrontDialogView' => 'AphrontView',
|
'AphrontDialogView' => 'AphrontView',
|
||||||
'AphrontErrorView' => 'AphrontView',
|
'AphrontErrorView' => 'AphrontView',
|
||||||
'AphrontFileResponse' => 'AphrontResponse',
|
'AphrontFileResponse' => 'AphrontResponse',
|
||||||
|
'AphrontFormCheckboxControl' => 'AphrontFormControl',
|
||||||
'AphrontFormControl' => 'AphrontView',
|
'AphrontFormControl' => 'AphrontView',
|
||||||
'AphrontFormFileControl' => 'AphrontFormControl',
|
'AphrontFormFileControl' => 'AphrontFormControl',
|
||||||
'AphrontFormMarkupControl' => 'AphrontFormControl',
|
'AphrontFormMarkupControl' => 'AphrontFormControl',
|
||||||
|
@ -226,6 +233,11 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorFileUploadController' => 'PhabricatorFileController',
|
'PhabricatorFileUploadController' => 'PhabricatorFileController',
|
||||||
'PhabricatorFileViewController' => 'PhabricatorFileController',
|
'PhabricatorFileViewController' => 'PhabricatorFileController',
|
||||||
'PhabricatorLiskDAO' => 'LiskDAO',
|
'PhabricatorLiskDAO' => 'LiskDAO',
|
||||||
|
'PhabricatorMetaMTAController' => 'PhabricatorController',
|
||||||
|
'PhabricatorMetaMTADAO' => 'PhabricatorLiskDAO',
|
||||||
|
'PhabricatorMetaMTAListController' => 'PhabricatorMetaMTAController',
|
||||||
|
'PhabricatorMetaMTAMail' => 'PhabricatorMetaMTADAO',
|
||||||
|
'PhabricatorMetaMTASendController' => 'PhabricatorMetaMTAController',
|
||||||
'PhabricatorPHID' => 'PhabricatorPHIDDAO',
|
'PhabricatorPHID' => 'PhabricatorPHIDDAO',
|
||||||
'PhabricatorPHIDAllocateController' => 'PhabricatorPHIDController',
|
'PhabricatorPHIDAllocateController' => 'PhabricatorPHIDController',
|
||||||
'PhabricatorPHIDController' => 'PhabricatorController',
|
'PhabricatorPHIDController' => 'PhabricatorController',
|
||||||
|
|
|
@ -93,6 +93,12 @@ class AphrontDefaultApplicationConfiguration
|
||||||
'common/(?<type>\w+)/$'
|
'common/(?<type>\w+)/$'
|
||||||
=> 'PhabricatorTypeaheadCommonDatasourceController',
|
=> 'PhabricatorTypeaheadCommonDatasourceController',
|
||||||
),
|
),
|
||||||
|
|
||||||
|
'/mail/' => array(
|
||||||
|
'$' => 'PhabricatorMetaMTAListController',
|
||||||
|
'send/$' => 'PhabricatorMetaMTASendController',
|
||||||
|
'view/(?<id>\d+)/$' => 'PhabricatorMetaMTAViewController',
|
||||||
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -63,7 +63,7 @@ class AphrontRequest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final public function getArr($name, $default = null) {
|
final public function getArr($name, $default = array()) {
|
||||||
if (isset($this->requestData[$name]) &&
|
if (isset($this->requestData[$name]) &&
|
||||||
is_array($this->requestData[$name])) {
|
is_array($this->requestData[$name])) {
|
||||||
return $this->requestData[$name];
|
return $this->requestData[$name];
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright 2011 Facebook, Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
abstract class PhabricatorMetaMTAController extends PhabricatorController {
|
||||||
|
|
||||||
|
public function buildStandardPageResponse($view, array $data) {
|
||||||
|
$page = new PhabricatorStandardPageView();
|
||||||
|
|
||||||
|
$page->setApplicationName('MetaMTA');
|
||||||
|
$page->setBaseURI('/mail/');
|
||||||
|
$page->setTitle(idx($data, 'title'));
|
||||||
|
$page->setGlyph("@");
|
||||||
|
$page->appendChild($view);
|
||||||
|
|
||||||
|
$response = new AphrontWebpageResponse();
|
||||||
|
return $response->setContent($page->render());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
16
src/applications/metamta/controller/base/__init__.php
Normal file
16
src/applications/metamta/controller/base/__init__.php
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is automatically generated. Lint this module to rebuild it.
|
||||||
|
* @generated
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_module('phabricator', 'aphront/response/webpage');
|
||||||
|
phutil_require_module('phabricator', 'applications/base/controller/base');
|
||||||
|
phutil_require_module('phabricator', 'view/page/standard');
|
||||||
|
|
||||||
|
phutil_require_module('phutil', 'utils');
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_source('PhabricatorMetaMTAController.php');
|
|
@ -0,0 +1,53 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright 2011 Facebook, Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class PhabricatorMetaMTAListController extends PhabricatorMetaMTAController {
|
||||||
|
|
||||||
|
public function processRequest() {
|
||||||
|
$mails = id(new PhabricatorMetaMTAMail())->loadAllWhere(
|
||||||
|
'1 = 1 ORDER BY id DESC LIMIT 100');
|
||||||
|
|
||||||
|
$rows = array();
|
||||||
|
foreach ($mails as $mail) {
|
||||||
|
$rows[] = array(
|
||||||
|
$mail->getID(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$table = new AphrontTableView($rows);
|
||||||
|
$table->setHeaders(
|
||||||
|
array(
|
||||||
|
'ID',
|
||||||
|
));
|
||||||
|
$table->setColumnClasses(
|
||||||
|
array(
|
||||||
|
null,
|
||||||
|
));
|
||||||
|
|
||||||
|
$panel = new AphrontPanelView();
|
||||||
|
$panel->appendChild($table);
|
||||||
|
$panel->setHeader('MetaMTA Messages');
|
||||||
|
$panel->setCreateButton('Send New Message', '/mail/send/');
|
||||||
|
|
||||||
|
return $this->buildStandardPageResponse(
|
||||||
|
$panel,
|
||||||
|
array(
|
||||||
|
'title' => 'MetaMTA',
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
17
src/applications/metamta/controller/list/__init__.php
Normal file
17
src/applications/metamta/controller/list/__init__.php
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is automatically generated. Lint this module to rebuild it.
|
||||||
|
* @generated
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_module('phabricator', 'applications/metamta/controller/base');
|
||||||
|
phutil_require_module('phabricator', 'applications/metamta/storage/mail');
|
||||||
|
phutil_require_module('phabricator', 'view/control/table');
|
||||||
|
phutil_require_module('phabricator', 'view/layout/panel');
|
||||||
|
|
||||||
|
phutil_require_module('phutil', 'utils');
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_source('PhabricatorMetaMTAListController.php');
|
|
@ -0,0 +1,145 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright 2011 Facebook, Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class PhabricatorMetaMTASendController extends PhabricatorMetaMTAController {
|
||||||
|
|
||||||
|
public function processRequest() {
|
||||||
|
|
||||||
|
$request = $this->getRequest();
|
||||||
|
|
||||||
|
if ($request->isFormPost()) {
|
||||||
|
$mail = new PhabricatorMetaMTAMail();
|
||||||
|
$mail->addTos($request->getArr('to'));
|
||||||
|
$mail->addCCs($request->getArr('cc'));
|
||||||
|
$mail->setSubject($request->getStr('subject'));
|
||||||
|
$mail->setBody($request->getStr('body'));
|
||||||
|
|
||||||
|
// TODO!
|
||||||
|
// $mail->setFrom($request->getViewerContext()->getUserID());
|
||||||
|
$mail->setSimulatedFailureCount($request->getInt('failures'));
|
||||||
|
$mail->setIsHTML($request->getInt('html'));
|
||||||
|
$mail->save();
|
||||||
|
if ($request->getInt('immediately')) {
|
||||||
|
$mail->sendNow($force_send = true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return id(new AphrontRedirectResponse())
|
||||||
|
->setURI('/mail/view/'.$mail->getID().'/');
|
||||||
|
}
|
||||||
|
|
||||||
|
$failure_caption =
|
||||||
|
"Enter a number to simulate that many consecutive send failures before ".
|
||||||
|
"really attempting to deliver via the underlying MTA.";
|
||||||
|
|
||||||
|
|
||||||
|
$form = new AphrontFormView();
|
||||||
|
$form->setAction('/mail/send/');
|
||||||
|
$form
|
||||||
|
->appendChild(
|
||||||
|
'<p class="aphront-form-instructions">This form will send a normal '.
|
||||||
|
'email using MetaMTA as a transport mechanism.</p>')
|
||||||
|
->appendChild(
|
||||||
|
id(new AphrontFormTokenizerControl())
|
||||||
|
->setLabel('To')
|
||||||
|
->setName('to')
|
||||||
|
->setDatasource('/typeahead/common/user/'))
|
||||||
|
->appendChild(
|
||||||
|
id(new AphrontFormTokenizerControl())
|
||||||
|
->setLabel('CC')
|
||||||
|
->setName('cc')
|
||||||
|
->setDatasource('/typeahead/common/user/'))
|
||||||
|
->appendChild(
|
||||||
|
id(new AphrontFormTextControl())
|
||||||
|
->setLabel('Subject')
|
||||||
|
->setName('subject'))
|
||||||
|
->appendChild(
|
||||||
|
id(new AphrontFormTextAreaControl())
|
||||||
|
->setLabel('Body')
|
||||||
|
->setName('body'))
|
||||||
|
->appendChild(
|
||||||
|
id(new AphrontFormTextControl())
|
||||||
|
->setLabel('Simulate Failures')
|
||||||
|
->setName('failures')
|
||||||
|
->setCaption($failure_caption))
|
||||||
|
->appendChild(
|
||||||
|
id(new AphrontFormCheckboxControl())
|
||||||
|
->setLabel('HTML')
|
||||||
|
->addCheckbox('html', '1', 'Send as HTML email.'))
|
||||||
|
->appendChild(
|
||||||
|
id(new AphrontFormCheckboxControl())
|
||||||
|
->setLabel('Send Now')
|
||||||
|
->addCheckbox(
|
||||||
|
'immediately',
|
||||||
|
'1',
|
||||||
|
'Send immediately, not via MetaMTA background script.'))
|
||||||
|
->appendChild(
|
||||||
|
id(new AphrontFormSubmitControl())
|
||||||
|
->setValue('Send Mail'));
|
||||||
|
|
||||||
|
$panel = new AphrontPanelView();
|
||||||
|
$panel->setHeader('Send Email');
|
||||||
|
$panel->appendChild($form);
|
||||||
|
$panel->setWidth(AphrontPanelView::WIDTH_WIDE);
|
||||||
|
|
||||||
|
return $this->buildStandardPageResponse(
|
||||||
|
$panel,
|
||||||
|
array(
|
||||||
|
'title' => 'Send Mail',
|
||||||
|
));
|
||||||
|
/*
|
||||||
|
return
|
||||||
|
<metamta:standard-page title="Send Email">
|
||||||
|
<tools:form width="wide" method="post" action={URI::getRequestURI()}>
|
||||||
|
<h1>Send Email</h1>
|
||||||
|
<tools:fieldset>
|
||||||
|
<tools:instructions>This form will send a normal email using MetaMTA
|
||||||
|
as a transport mechanism.</tools:instructions>
|
||||||
|
<tools:control type="text" label="To">
|
||||||
|
<tools:tokenizer name="to" datasource="mailable" />
|
||||||
|
</tools:control>
|
||||||
|
<tools:control type="text" label="CC">
|
||||||
|
<tools:tokenizer name="cc" datasource="mailable" />
|
||||||
|
</tools:control>
|
||||||
|
<tools:control type="text" label="Subject">
|
||||||
|
<input type="text" name="subject" />
|
||||||
|
</tools:control>
|
||||||
|
<tools:control type="textarea" label="Body">
|
||||||
|
<textarea name="body"></textarea>
|
||||||
|
</tools:control>
|
||||||
|
<tools:control type="text" label="Simulate Failures"
|
||||||
|
caption={$failure_caption}>
|
||||||
|
<input type="text" name="failures" />
|
||||||
|
</tools:control>
|
||||||
|
<tools:control type="checkbox" label="HTML">
|
||||||
|
<input type="checkbox" name="html" value="1" />
|
||||||
|
Send as HTML email.
|
||||||
|
</tools:control>
|
||||||
|
<tools:control type="checkbox" label="Send Now">
|
||||||
|
<input type="checkbox" name="immediately" value="1" />
|
||||||
|
Send immediately, not via MetaMTA daemon.
|
||||||
|
</tools:control>
|
||||||
|
<tools:control type="submit">
|
||||||
|
<button>Send Email</button>
|
||||||
|
</tools:control>
|
||||||
|
</tools:fieldset>
|
||||||
|
</tools:form>
|
||||||
|
</metamta:standard-page>;
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
19
src/applications/metamta/controller/send/__init__.php
Normal file
19
src/applications/metamta/controller/send/__init__.php
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is automatically generated. Lint this module to rebuild it.
|
||||||
|
* @generated
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_module('phabricator', 'aphront/response/redirect');
|
||||||
|
phutil_require_module('phabricator', 'applications/metamta/controller/base');
|
||||||
|
phutil_require_module('phabricator', 'applications/metamta/storage/mail');
|
||||||
|
phutil_require_module('phabricator', 'view/form/base');
|
||||||
|
phutil_require_module('phabricator', 'view/form/control/submit');
|
||||||
|
phutil_require_module('phabricator', 'view/layout/panel');
|
||||||
|
|
||||||
|
phutil_require_module('phutil', 'utils');
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_source('PhabricatorMetaMTASendController.php');
|
|
@ -0,0 +1,25 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright 2011 Facebook, Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
abstract class PhabricatorMetaMTADAO extends PhabricatorLiskDAO {
|
||||||
|
|
||||||
|
public function getApplicationName() {
|
||||||
|
return 'metamta';
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
12
src/applications/metamta/storage/base/__init__.php
Normal file
12
src/applications/metamta/storage/base/__init__.php
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is automatically generated. Lint this module to rebuild it.
|
||||||
|
* @generated
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_module('phabricator', 'applications/base/storage/lisk');
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_source('PhabricatorMetaMTADAO.php');
|
218
src/applications/metamta/storage/mail/PhabricatorMetaMTAMail.php
Normal file
218
src/applications/metamta/storage/mail/PhabricatorMetaMTAMail.php
Normal file
|
@ -0,0 +1,218 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright 2011 Facebook, Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See #394445 for an explanation of why this thing even exists.
|
||||||
|
*/
|
||||||
|
class PhabricatorMetaMTAMail extends PhabricatorMetaMTADAO {
|
||||||
|
|
||||||
|
const STATUS_QUEUE = 'queued';
|
||||||
|
const STATUS_SENT = 'sent';
|
||||||
|
const STATUS_FAIL = 'fail';
|
||||||
|
|
||||||
|
const MAX_RETRIES = 250;
|
||||||
|
const RETRY_DELAY = 5;
|
||||||
|
|
||||||
|
protected $parameters;
|
||||||
|
protected $status;
|
||||||
|
protected $message;
|
||||||
|
protected $retryCount;
|
||||||
|
protected $nextRetry;
|
||||||
|
protected $relatedPHID;
|
||||||
|
|
||||||
|
public function __construct() {
|
||||||
|
|
||||||
|
$this->status = self::STATUS_QUEUE;
|
||||||
|
$this->retryCount = 0;
|
||||||
|
$this->nextRetry = time();
|
||||||
|
$this->parameters = array();
|
||||||
|
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getConfiguration() {
|
||||||
|
return array(
|
||||||
|
self::CONFIG_SERIALIZATION => array(
|
||||||
|
'parameters' => self::SERIALIZATION_JSON,
|
||||||
|
),
|
||||||
|
) + parent::getConfiguration();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function setParam($param, $value) {
|
||||||
|
$this->parameters[$param] = $value;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getParam($param) {
|
||||||
|
return idx($this->parameters, $param);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getSubject() {
|
||||||
|
return $this->getParam('subject');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addTos(array $phids) {
|
||||||
|
$this->setParam('to', $phids);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addCCs(array $phids) {
|
||||||
|
$this->setParam('cc', $phids);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addHeader($name, $value) {
|
||||||
|
$this->parameters['headers'][$name] = $value;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setFrom($from) {
|
||||||
|
$this->setParam('from', $from);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setReplyTo($phid) {
|
||||||
|
$this->setParam('reply-to', $phid);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setSubject($subject) {
|
||||||
|
$this->setParam('subject', $subject);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setBody($body) {
|
||||||
|
$this->setParam('body', $body);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setIsHTML($html) {
|
||||||
|
$this->setParam('is-html', $html);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getSimulatedFailureCount() {
|
||||||
|
return nonempty($this->getParam('simulated-failures'), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setSimulatedFailureCount($count) {
|
||||||
|
$this->setParam('simulated-failures', $count);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function sendNow($force_send = false) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
if (!$force_send) {
|
||||||
|
if ($this->getStatus() != self::STATUS_QUEUE) {
|
||||||
|
throw new Exception("Trying to send an already-sent mail!");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (time() < $this->getNextRetry()) {
|
||||||
|
throw new Exception("Trying to send an email before next retry!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
require_module_lazy('intern/mailer');
|
||||||
|
try {
|
||||||
|
$mailer = new InternMailer();
|
||||||
|
foreach ($this->parameters as $key => $value) {
|
||||||
|
switch ($key) {
|
||||||
|
case 'from':
|
||||||
|
$mailer->setFrom($value);
|
||||||
|
break;
|
||||||
|
case 'reply-to':
|
||||||
|
$mailer->addReplyTo($value);
|
||||||
|
break;
|
||||||
|
case 'to':
|
||||||
|
$mailer->addTos($value);
|
||||||
|
break;
|
||||||
|
case 'cc':
|
||||||
|
$mailer->addCCs($value);
|
||||||
|
break;
|
||||||
|
case 'headers':
|
||||||
|
foreach ($value as $header_key => $header_value) {
|
||||||
|
$mailer->addHeader($header_key, $header_value);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'body':
|
||||||
|
$mailer->setBody($value);
|
||||||
|
break;
|
||||||
|
case 'subject':
|
||||||
|
$mailer->setSubject($value);
|
||||||
|
break;
|
||||||
|
case 'is-html':
|
||||||
|
if ($value) {
|
||||||
|
$mailer->setIsHTML(true);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// Just discard.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$mailer->addHeader('X-Mail-Transport-Agent', 'MetaMTA');
|
||||||
|
|
||||||
|
if (!$mailer->hasValidRecipients()) {
|
||||||
|
throw new Exception("Permanent failure: no valid recipients.");
|
||||||
|
}
|
||||||
|
} catch (Exception $ex) {
|
||||||
|
$this->setStatus(self::STATUS_FAIL);
|
||||||
|
$this->setMessage($ex->getMessage());
|
||||||
|
$this->save();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->getRetryCount() < $this->getSimulatedFailureCount()) {
|
||||||
|
$ok = false;
|
||||||
|
$error = 'Simulated failure.';
|
||||||
|
} else {
|
||||||
|
$ok = $mailer->send();
|
||||||
|
$error = $mailer->getError();
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
$error = null;
|
||||||
|
$ok = true;
|
||||||
|
|
||||||
|
if (!$ok) {
|
||||||
|
$this->setMessage($error);
|
||||||
|
if ($this->getRetryCount() > self::MAX_RETRIES) {
|
||||||
|
$this->setStatus(self::STATUS_FAIL);
|
||||||
|
} else {
|
||||||
|
$this->setRetryCount($this->getRetryCount() + 1);
|
||||||
|
$next_retry = time() + ($this->getRetryCount() * self::RETRY_DELAY);
|
||||||
|
$this->setNextRetry($next_retry);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$this->setStatus(self::STATUS_SENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->save();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getReadableStatus($status_code) {
|
||||||
|
static $readable = array(
|
||||||
|
self::STATUS_QUEUE => "Queued for Delivery",
|
||||||
|
self::STATUS_FAIL => "Delivery Failed",
|
||||||
|
self::STATUS_SENT => "Sent",
|
||||||
|
);
|
||||||
|
$status_code = coalesce($status_code, '?');
|
||||||
|
return idx($readable, $status_code, $status_code);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
14
src/applications/metamta/storage/mail/__init__.php
Normal file
14
src/applications/metamta/storage/mail/__init__.php
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is automatically generated. Lint this module to rebuild it.
|
||||||
|
* @generated
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_module('phabricator', 'applications/metamta/storage/base');
|
||||||
|
|
||||||
|
phutil_require_module('phutil', 'utils');
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_source('PhabricatorMetaMTAMail.php');
|
|
@ -87,7 +87,7 @@ abstract class AphrontFormControl extends AphrontView {
|
||||||
|
|
||||||
if (strlen($this->getLabel())) {
|
if (strlen($this->getLabel())) {
|
||||||
$label =
|
$label =
|
||||||
'<label>'.
|
'<label class="aphront-form-label">'.
|
||||||
phutil_escape_html($this->getLabel()).
|
phutil_escape_html($this->getLabel()).
|
||||||
':'.
|
':'.
|
||||||
'</label>';
|
'</label>';
|
||||||
|
|
68
src/view/form/control/checkbox/AphrontFormCheckboxControl.php
Executable file
68
src/view/form/control/checkbox/AphrontFormCheckboxControl.php
Executable file
|
@ -0,0 +1,68 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright 2011 Facebook, Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class AphrontFormCheckboxControl extends AphrontFormControl {
|
||||||
|
|
||||||
|
private $boxes = array();
|
||||||
|
|
||||||
|
public function addCheckbox($name, $value, $label, $checked = false) {
|
||||||
|
$this->boxes[] = array(
|
||||||
|
'name' => $name,
|
||||||
|
'value' => $value,
|
||||||
|
'label' => $label,
|
||||||
|
'checked' => $checked,
|
||||||
|
);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getCustomControlClass() {
|
||||||
|
return 'aphront-form-control-checkbox';
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function renderInput() {
|
||||||
|
$rows = array();
|
||||||
|
foreach ($this->boxes as $box) {
|
||||||
|
$id = celerity_generate_unique_node_id();
|
||||||
|
$checkbox = phutil_render_tag(
|
||||||
|
'input',
|
||||||
|
array(
|
||||||
|
'id' => $id,
|
||||||
|
'type' => 'checkbox',
|
||||||
|
'name' => $box['name'],
|
||||||
|
'value' => $box['value'],
|
||||||
|
'checked' => $box['checked'] ? 'checked' : null,
|
||||||
|
));
|
||||||
|
$label = phutil_render_tag(
|
||||||
|
'label',
|
||||||
|
array(
|
||||||
|
'for' => $id,
|
||||||
|
),
|
||||||
|
phutil_escape_html($box['label']));
|
||||||
|
$rows[] =
|
||||||
|
'<tr>'.
|
||||||
|
'<td>'.$checkbox.'</td>'.
|
||||||
|
'<th>'.$label.'</th>'.
|
||||||
|
'</tr>';
|
||||||
|
}
|
||||||
|
return
|
||||||
|
'<table class="aphront-form-control-checkbox-layout">'.
|
||||||
|
implode("\n", $rows).
|
||||||
|
'</table>';
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
15
src/view/form/control/checkbox/__init__.php
Normal file
15
src/view/form/control/checkbox/__init__.php
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is automatically generated. Lint this module to rebuild it.
|
||||||
|
* @generated
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_module('phabricator', 'infratructure/celerity/api');
|
||||||
|
phutil_require_module('phabricator', 'view/form/control/base');
|
||||||
|
|
||||||
|
phutil_require_module('phutil', 'markup');
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_source('AphrontFormCheckboxControl.php');
|
|
@ -8,7 +8,7 @@
|
||||||
padding: 1em;
|
padding: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.aphront-form-view label {
|
.aphront-form-view label.aphront-form-label {
|
||||||
padding-top: 4px;
|
padding-top: 4px;
|
||||||
width: 19%;
|
width: 19%;
|
||||||
float: left;
|
float: left;
|
||||||
|
@ -64,7 +64,7 @@
|
||||||
text-align: right;
|
text-align: right;
|
||||||
clear: both;
|
clear: both;
|
||||||
margin-right: 25%;
|
margin-right: 25%;
|
||||||
margin-left: 15%;
|
margin-left: 20%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.aphront-error-view {
|
.aphront-error-view {
|
||||||
|
@ -76,10 +76,24 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.aphront-form-instructions {
|
.aphront-form-instructions {
|
||||||
margin: 2em 3%;
|
margin: 0.75em 3% 1.25em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.aphront-form-control-static .aphront-form-input {
|
.aphront-form-control-static .aphront-form-input {
|
||||||
padding-top: 4px;
|
padding-top: 4px;
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
table.aphront-form-control-checkbox-layout {
|
||||||
|
margin-top: 3px;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.aphront-form-control-checkbox-layout th {
|
||||||
|
padding-top: 2px;
|
||||||
|
padding-left: 0.35em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.aphront-form-control-checkbox-layout td input {
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue