Also see https://github.com/the-djmaze/snappymail/tree/master/plugins/example
PHP
class Plugin extends \RainLoop\Plugins\AbstractPlugin
{
public function __construct();
/** Returns static::NAME */
public function Name(): string;
/** Returns /README file contents or static::DESCRIPTION */
public function Description(): string;
/** When $bLangs is boolean it sets the value, else returns current value */
public function UseLangs(?bool $bLangs = null): bool;
/** When true the result is empty string, else the error message */
public function Supported(): string;
/** Initialize settings */
public function Init(): void;
public function FilterAppDataPluginSection(bool $bAdmin, bool $bAuth, array &$aConfig): void;
/** Returns array of all plugin Property options for use in Admin -> Extensions -> Plugin cog wheel */
protected function configMapping(): array;
/** With this function you hook to an event
* $sHookName see chapter "Hooks" below for available names
* $sFunctionName the name of a function in this class
*/
final protected function addHook(string $sHookName, string $sFunctionName): self;
final protected function addCss(string $sFile, bool $bAdminScope = false): self;
final protected function addJs(string $sFile, bool $bAdminScope = false): self;
final protected function addTemplate(string $sFile, bool $bAdminScope = false): self;
final protected function addJsonHook(string $sActionName, string $sFunctionName): self;
/**
* You may register your own service actions.
* Url is like /?{actionname}/etc.
* Predefined actions of \RainLoop\ServiceActions that can't be registered are:
* - admin
* - AdminAppData
* - AppData
* - Append
* - Backup
* - BadBrowser
* - CspReport
* - Css
* - Json
* - Lang
* - Mailto
* - NoCookie
* - NoScript
* - Ping
* - Plugins
* - ProxyExternal
* - Raw
* - Sso
* - Upload
* - UploadBackground
* - UploadContacts
*/
final protected function addPartHook(string $sActionName, string $sFunctionName): self
final public function Config(): \RainLoop\Config\Plugin;
final public function Manager(): \RainLoop\Plugins\Manager;
final public function Path(): string;
final public function ConfigMap(bool $flatten = false): array;
/**
* Returns result of Actions->DefaultResponse($sFunctionName, $mData) or json_encode($mData)
*/
final protected function jsonResponse(string $sFunctionName, $mData): mixed;
final public function jsonParam(string $sKey, $mDefault = null): mixed;
final public function getUserSettings(): array;
final public function saveUserSettings(array $aSettings): bool;
}
JavaScript
class PluginPopupView extends rl.pluginPopupView
{
// Happens when DOM is created
onBuild(dom) {}
// Happens before showModal()
beforeShow(...params) {}
// Happens after showModal()
onShow(...params) {}
// Happens after showModal() animation transitionend
afterShow() {}
// Happens when user hits Escape or Close key
// return false to prevent closing, use close() manually
onClose() {}
// Happens before animation transitionend
onHide() {}
// Happens after animation transitionend
afterHide() {}
}
PluginPopupView.showModal();
$Plugin->addHook('hook.name', 'functionName');
params:
string &$sEmail
Happens in resolveLoginCredentials($sEmail) BEFORE resolving domain name.
This is the pure text from the login screen (DoLogin) or the SSO feature (ServiceSso) received by LoginProcess().
- DoLogin() -> LoginProcess() -> resolveLoginCredentials($sEmail)
- ServiceSso() -> LoginProcess() -> resolveLoginCredentials($sEmail)
So $sEmail can just have the value `test` without a domain.
params:
string &$sEmail
string &$sPassword
Happens in resolveLoginCredentials($sEmail) AFTER resolving domain name.
So $sEmail always has a domain (for example `test` is now `test@example.com`).
params:
string &$sEmail
string &$sImapUser
string &$sPassword
string &$sSmtpUser
$sEmail is the domain imap->fixUsername() without shortening.
$sImapUser is the domain imap->fixUsername() for login into IMAP.
$sSmtpUser is the domain smtp->fixUsername() for login into SMTP.
params:
\RainLoop\Model\MainAccount $oAccount
params:
\RainLoop\Model\Account $oAccount
\MailSo\Imap\ImapClient $oImapClient
\MailSo\Imap\Settings $oSettings
params:
\RainLoop\Model\Account $oAccount
\MailSo\Imap\ImapClient $oImapClient
\MailSo\Imap\Settings $oSettings
params:
\RainLoop\Model\Account $oAccount
\MailSo\Imap\ImapClient $oImapClient
\MailSo\Imap\Settings $oSettings
params:
\RainLoop\Model\Account $oAccount
\MailSo\Imap\ImapClient $oImapClient
bool $bSuccess
\MailSo\Imap\Settings $oSettings
params:
array &$aHeaders
Allows you to fetch more MIME headers for messages.
params:
\RainLoop\Model\Account $oAccount
\MailSo\Sieve\SieveClient $oSieveClient
\MailSo\Sieve\Settings $oSettings
params:
\RainLoop\Model\Account $oAccount
\MailSo\Sieve\SieveClient $oSieveClient
\MailSo\Sieve\Settings $oSettings
params:
\RainLoop\Model\Account $oAccount
\MailSo\Sieve\SieveClient $oSieveClient
\MailSo\Sieve\Settings $oSettings
params:
\RainLoop\Model\Account $oAccount
\MailSo\Sieve\SieveClient $oSieveClient
bool $bSuccess
\MailSo\Sieve\Settings $oSettings
params:
\RainLoop\Model\Account $oAccount
\MailSo\Smtp\SmtpClient $oSmtpClient
\MailSo\Smtp\Settings $oSettings
params:
\RainLoop\Model\Account $oAccount
\MailSo\Smtp\SmtpClient $oSmtpClient
\MailSo\Smtp\Settings $oSettings
params:
\RainLoop\Model\Account $oAccount
\MailSo\Smtp\SmtpClient $oSmtpClient
\MailSo\Smtp\Settings $oSettings
params:
\RainLoop\Model\Account $oAccount
\MailSo\Smtp\SmtpClient $oSmtpClient
bool $bSuccess
\MailSo\Smtp\Settings $oSettings
Called by RainLoop\ServiceActions::ServiceJson() {actionname} is one of the RainLoop\Actions::Do{ActionName}(), or an extension action as "Plugin{ActionName}" added with Plugin::addJsonHook() and called in JavaScript using rl.pluginRemoteRequest().
params: none
params:
array &$aResponse
Obsolete, use json.after-{actionname}
Obsolete, use json.before-{actionname}
Obsolete, use json.after-{actionname}
params:
\RainLoop\Model\Account $oAccount
params:
string $sMethodName
array &$aCurrentActionParams
params:
bool $bAdmin
array &$aAppData
params:
\RainLoop\Config\Application $oConfig
params:
\MailSo\Mime\Message $oMessage
Happens before send/save message
params:
\MailSo\Mime\Message $oMessage
\RainLoop\Model\Account $oAccount
params:
\RainLoop\Model\Domain $oDomain
params:
string $sName
mixed &$mResult
\RainLoop\Model\Account $oAccount
params:
array &$aPaths
params:
string &$sLanguage
bool $bAdmin
Allows you to set a different language
params:
\RainLoop\Model\Account $oAccount
\MailSo\Mime\Message $oMessage
string &$sTextConverted
Happens before send/save message
params:
\RainLoop\Model\Account $oAccount
\MailSo\Mime\Message $oMessage
string &$sTextConverted
Happens before send/save message
Called by DoSendMessage and DoSendReadReceiptMessage
params:
\RainLoop\Model\Account $oAccount
\MailSo\Mime\EmailCollection $oRcpt
params:
\RainLoop\Model\Account $oAccount
\MailSo\Mime\Message $oMessage
string &$sText
params:
\MailSo\Mime\Message $oMessage
Happens when reading message
params:
\MailSo\Mime\Message $oMessage
Happens before save message
params:
\MailSo\Mime\Message $oMessage
Happens before send message
params:
\RainLoop\Model\Account $oAccount
resource &$rMessageStream
int &$iMessageStreamSize
params:
\MailSo\Mime\Message $oMessage
\RainLoop\Model\Account $oAccount
params:
\RainLoop\Model\Account $oAccount
\MailSo\Mime\Message $oMessage
string &$sFrom
filter.smtp-hidden-rcpt
params:
\RainLoop\Model\Account $oAccount
\MailSo\Mime\Message $oMessage
array &$aHiddenRcpt
Called by DoSendMessage and DoSendReadReceiptMessage
params:
\RainLoop\Model\Account $oAccount
resource &$rMessageStream
int &$iMessageStreamSize
params:
array &$aResponse
params:
\SnappyMail\AttachmentsAction $oData
params:
string &$sQuery
int &$iLimit
\RainLoop\Model\Account $oAccount
params:
\SnappyMail\HTTP\CSP $oCSP
Allows you to edit the policy, like:
`$oCSP->script[] = "'strict-dynamic'";`
Obsolete, use json.after-{actionname}
Obsolete, use json.after-{actionname}
Obsolete, use json.after-{actionname}
params:
string $sName
mixed &$mResult
Use to show a specific message.
dispatchEvent(
new CustomEvent(
'mailbox.message.show',
{
detail: {
folder: 'INBOX',
uid: 1
},
cancelable: false
}
)
);
event.detail value is one of:
0. NoPreview
1. SidePreview
2. BottomPreview
event.detail = the ViewModel class
Happens immediately after the ViewModel constructor.
See accessible properties as https://github.com/the-djmaze/snappymail/blob/master/dev/Knoin/AbstractViews.js
event.detail = the ViewModel class
Happens after the full build (vm.onBuild()) and contains viewModelDom
event.detail = the ViewModel class
Happens after the model is made visible (vm.afterShow())
event.detail = FormData
cancelable using preventDefault()
event.detail = { error: int, data: {JSON response} }
event.detail = FormData
cancelable using preventDefault()
event.detail = { error: int, data: {JSON response} }
event.detail = 'screenname'
cancelable using preventDefault()
event.detail = { squire: SquireUI, actions: object }
`actions` is the toolbar structure.
```javascript
block-of-buttons: {
button-name: {
select: ['selectbox options'],
html: 'button text',
cmd: () => `command to execute`,
key: 'keyboard shortcut',
matches: 'HTML elements that match'
}
}
```
See [SquireUI.js](https://github.com/the-djmaze/snappymail/blob/master/dev/External/SquireUI.js)
for all default toolbar actions.
Converts HTML to text
Converts text to HTML
Examples in
- ./change-password/js/ChangePasswordUserSettings.js
- ./example/js/ExampleUserSettings.js
- ./kolab/js/settings.js
- ./two-factor-auth/js/TwoFactorAuthSettings.js
Examples in
- ./example/js/ExampleAdminSettings.js:34: rl.addSettingsViewModelForAdmin(ExampleAdminSettings, 'ExampleAdminSettingsTab',
Returns true or false when in '?admin' area
A knockout observable array of all folders/mailboxes
class AbstractViewPopup