You've already forked roundcube-aliasmanager
							
							
		
			
				
	
	
		
			245 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			245 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
<?php
 | 
						|
 | 
						|
class aliasmanager extends rcube_plugin {
 | 
						|
 | 
						|
	private $rcmail;
 | 
						|
 | 
						|
	private $postfixadmin_db;
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Initializes the plugin.
 | 
						|
	 */
 | 
						|
	public function init() {
 | 
						|
		$this->rcmail = rcube::get_instance();
 | 
						|
		$this->load_config();
 | 
						|
 | 
						|
		if ($dsn = $this->rcmail->config->get('postfixadmin_db_dsn')) {
 | 
						|
			$this->postfixadmin_db = rcube_db::factory($dsn, '', false);
 | 
						|
		} else {
 | 
						|
			throw new \Exception('cannot connect ot postfix db');
 | 
						|
		}
 | 
						|
 | 
						|
		if ($this->rcmail->task == "mail" || $this->rcmail->task == "settings") {
 | 
						|
			$this->include_stylesheet('assets/styles/app.css');
 | 
						|
		}
 | 
						|
 | 
						|
		if ($this->rcmail->task == "settings") {
 | 
						|
			$this->add_hook("settings_actions", [$this, "hookSettingsActions"]);
 | 
						|
			$this->register_action('plugin.aliasmanager', [$this, "onShowSettingsPage"]);
 | 
						|
 | 
						|
			$this->add_texts('localization/');
 | 
						|
 | 
						|
			switch ($this->rcmail->action) {
 | 
						|
				case 'plugin.aliasmanager-get-alias-list':
 | 
						|
					$this->onGetAliasList();
 | 
						|
					break;
 | 
						|
				case 'plugin.aliasmanager-add-alias':
 | 
						|
					$this->onAddAlias();
 | 
						|
					break;
 | 
						|
				case 'plugin.aliasmanager-toggle-alias':
 | 
						|
					$this->onToggleAlias();
 | 
						|
					break;
 | 
						|
				case 'plugin.aliasmanager-delete-alias':
 | 
						|
					$this->onDeleteAlias();
 | 
						|
					break;
 | 
						|
			}
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	public function hookSettingsActions($arg): array {
 | 
						|
		// add the menu item to the settings sidebar
 | 
						|
		$arg['actions'][] = [
 | 
						|
			'action' => 'plugin.aliasmanager',
 | 
						|
			'class'  => 'aliasmanager',
 | 
						|
			'label'  => 'settings_menu_label',
 | 
						|
			'title'  => 'settings_menu_label',
 | 
						|
			'domain' => 'aliasmanager',
 | 
						|
		];
 | 
						|
 | 
						|
		return $arg;
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Renders and returns the settings.html view.
 | 
						|
	 * @return mixed
 | 
						|
	 */
 | 
						|
	public function settingsPageHandler() {
 | 
						|
		$this->include_script('assets/scripts/app.js');
 | 
						|
 | 
						|
		$this->rcmail->output->add_label("settings_menu_label");
 | 
						|
 | 
						|
		return $this->view("elastic", "aliasmanager.settings", []);
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Creates and outputs the settings page.
 | 
						|
	 */
 | 
						|
	public function onShowSettingsPage() {
 | 
						|
		$this->register_handler('plugin.body', [$this, 'settingsPageHandler']);
 | 
						|
		$this->rcmail->output->set_pagetitle($this->gettext('aliasmanager'));
 | 
						|
		$this->rcmail->output->send('plugin');
 | 
						|
	}
 | 
						|
 | 
						|
	public function onGetAliasList() {
 | 
						|
		$alias_list = [];
 | 
						|
		$result = $this->postfixadmin_db->query('SELECT address as email, goto as users, active FROM alias WHERE address != goto AND goto = ? AND domain = ?', $this->rcmail->user->get_username(), $this->rcmail->config->get('alias_email_domain'));
 | 
						|
		foreach ($result as $row) {
 | 
						|
			$alias_list[] = [
 | 
						|
				'email'  => $row['email'],
 | 
						|
				'active' => $row['active'],
 | 
						|
			];
 | 
						|
		}
 | 
						|
 | 
						|
		$this->sendResponse(true, [
 | 
						|
			'data' => [
 | 
						|
				'alias_list' => $alias_list,
 | 
						|
			],
 | 
						|
		]);
 | 
						|
	}
 | 
						|
 | 
						|
	public function onAddAlias() {
 | 
						|
		$email = $_POST['email'] ?? null;
 | 
						|
		if (empty($email)) {
 | 
						|
			$this->sendResponse(false, [
 | 
						|
				'msg' => 'Email not set',
 | 
						|
			]);
 | 
						|
			return;
 | 
						|
		}
 | 
						|
 | 
						|
		$email_alias_domain = $this->rcmail->config->get('alias_email_domain');
 | 
						|
 | 
						|
		$email = $email.'-'.$this->generateRandomEmailAliasHash($this->rcmail->config->get('alias_email_hash_len', 7)).'@'.$email_alias_domain;
 | 
						|
 | 
						|
		$error = $this->postfixadmin_db->query('INSERT INTO alias (address, goto, domain, created, modified, active) VALUES (?, ?, ?, NOW(), NOW(), 1)', [$email, $this->rcmail->user->get_username(), $email_alias_domain]);
 | 
						|
		if (!$error) {
 | 
						|
			$this->sendResponse(false, [
 | 
						|
				'msg' => 'failed to add alias', // $this->postfixadmin_db->is_error()
 | 
						|
			]);
 | 
						|
			return;
 | 
						|
		}
 | 
						|
 | 
						|
		$this->sendResponse(true, []);
 | 
						|
	}
 | 
						|
 | 
						|
	public function onToggleAlias() {
 | 
						|
		$state = $_POST['state'] == 'true' ? 1 : 0;
 | 
						|
		$email = $_POST['email'];
 | 
						|
 | 
						|
		if (empty($email)) {
 | 
						|
			$this->sendResponse(false, [
 | 
						|
				'msg' => 'Email not set',
 | 
						|
			]);
 | 
						|
			return;
 | 
						|
		}
 | 
						|
 | 
						|
		$email_alias_domain = $this->rcmail->config->get('alias_email_domain');
 | 
						|
 | 
						|
		$error = $this->postfixadmin_db->query('UPDATE alias SET active = ? WHERE address = ? AND goto = ? AND domain = ?', [$state, $email, $this->rcmail->user->get_username(), $email_alias_domain]);
 | 
						|
		if (!$error) {
 | 
						|
			$this->sendResponse(false, [
 | 
						|
				'msg' => 'failed to toggle alias', // $this->postfixadmin_db->is_error()
 | 
						|
			]);
 | 
						|
			return;
 | 
						|
		}
 | 
						|
 | 
						|
		$this->sendResponse(true, []);
 | 
						|
	}
 | 
						|
 | 
						|
	public function onDeleteAlias() {
 | 
						|
		$email = $_POST['email'];
 | 
						|
		if (empty($email)) {
 | 
						|
			$this->sendResponse(false, [
 | 
						|
				'msg' => 'Email not set',
 | 
						|
			]);
 | 
						|
			return;
 | 
						|
		}
 | 
						|
 | 
						|
		$email_alias_domain = $this->rcmail->config->get('alias_email_domain');
 | 
						|
 | 
						|
		$error = $this->postfixadmin_db->query('DELETE FROM alias WHERE address = ? AND goto = ? AND domain = ?', [$email, $this->rcmail->user->get_username(), $email_alias_domain]);
 | 
						|
		if (!$error) {
 | 
						|
			$this->sendResponse(false, [
 | 
						|
				'msg' => 'failed to toggle alias', // $this->postfixadmin_db->is_error()
 | 
						|
			]);
 | 
						|
			return;
 | 
						|
		}
 | 
						|
 | 
						|
		$this->sendResponse(true, []);
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Sends ajax response in json format.
 | 
						|
	 *
 | 
						|
	 * IMPORTANT: When sending an error with an error message, use this format:
 | 
						|
	 * sendResponse(true, array('success' => false, 'errorMessage' => $message, 'other data'...)
 | 
						|
	 * This is because the standard way of setting $success and $errorMessage won't work properly with non-English
 | 
						|
	 * character sets (when the error is sent using http/1.0 500)
 | 
						|
	 *
 | 
						|
	 * @param bool $success
 | 
						|
	 * @param array $data
 | 
						|
	 */
 | 
						|
	private function sendResponse($success, $data = [], $errorMessage = false) {
 | 
						|
		if ($this->unitTest) {
 | 
						|
			return ["success" => $success, "data" => $data, "errorMessage" => $data['errorMessage']];
 | 
						|
		}
 | 
						|
 | 
						|
		if (ob_get_contents()) {
 | 
						|
			@ob_end_clean();
 | 
						|
		}
 | 
						|
 | 
						|
		if (!is_array($data)) {
 | 
						|
			$data = [];
 | 
						|
		}
 | 
						|
 | 
						|
		if (!isset($data['success'])) {
 | 
						|
			$data['success'] = (bool)$success;
 | 
						|
		}
 | 
						|
 | 
						|
		if ($success) {
 | 
						|
			exit(json_encode($data));
 | 
						|
		}
 | 
						|
 | 
						|
		if (empty($errorMessage)) {
 | 
						|
			$errorMessage = empty($data['errorMessage']) ? "Server error" : $data['errorMessage'];
 | 
						|
		}
 | 
						|
 | 
						|
		exit(@header("HTTP/1.0 500 ".$errorMessage));
 | 
						|
	}
 | 
						|
 | 
						|
	private function view($skin, $view, $data = false) {
 | 
						|
		if (empty($data) || !is_array($data)) {
 | 
						|
			$data = [];
 | 
						|
		}
 | 
						|
 | 
						|
		$parts = explode(".", $view);
 | 
						|
		$plugin = $parts[0];
 | 
						|
 | 
						|
		unset($parts[0]);
 | 
						|
		$html = file_get_contents(__DIR__."/../$plugin/skins/$skin/templates/".implode(".", $parts).".html");
 | 
						|
 | 
						|
		while (($i = strrpos($html, "[+")) !== false && ($j = strrpos($html, "+]")) !== false) {
 | 
						|
			$html = substr_replace($html, xrc()->gettext(substr($html, $i + 2, $j - $i - 2)), $i, $j - $i + 2);
 | 
						|
		}
 | 
						|
 | 
						|
		// replace our custom tags that can contain html tags
 | 
						|
		foreach ($data as $key => $val) {
 | 
						|
			if (is_string($val)) {
 | 
						|
				$html = str_replace("[~".$key."~]", $val, $html);
 | 
						|
			} else if (is_array($val)) {
 | 
						|
				$html = str_replace("[~".$key."~]", @json_encode($val), $html);
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		return $html;
 | 
						|
	}
 | 
						|
 | 
						|
	private function generateRandomEmailAliasHash($length = 10) {
 | 
						|
		$characters = '0123456789abcdefghijklmnopqrstuvwxyz';
 | 
						|
		$charactersLength = strlen($characters);
 | 
						|
		$randomString = '';
 | 
						|
		for ($i = 0; $i < $length; $i++) {
 | 
						|
			$randomString .= $characters[rand(0, $charactersLength - 1)];
 | 
						|
		}
 | 
						|
		return $randomString;
 | 
						|
	}
 | 
						|
} |