1<?php 2/** 3 * Copyright 2012-2017 Horde LLC (http://www.horde.org/) 4 * 5 * See the enclosed file LICENSE for license information (ASL). If you 6 * did not receive this file, see http://www.horde.org/licenses/apache. 7 * 8 * @author Michael Bunk <mb@computer-leipzig.com> 9 * @author Jan Schneider <jan@horde.org> 10 * @package Ingo 11 */ 12 13/** 14 * Ingo_Transport_Ispconfig implements an Ingo transport driver to allow 15 * scripts to be installed and set active on an ISPConfig server. 16 * 17 * Ingo_Transport_ 18 * 19 * @author Michael Bunk <mb@computer-leipzig.com> 20 * @author Jan Schneider <jan@horde.org> 21 * @package Ingo 22 */ 23class Ingo_Transport_Ispconfig extends Ingo_Transport_Base 24{ 25 /** 26 * The SOAP connection 27 * 28 * @var SoapClient 29 */ 30 protected $_soap; 31 32 /** 33 * The SOAP session id 34 * 35 * @var string 36 */ 37 protected $_soap_session; 38 39 /** 40 * The current vacation details. 41 * 42 * @var array 43 */ 44 protected $_details = null; 45 46 47 /** 48 * Sets a script running on the backend. 49 * 50 * @param array $script The filter script information. Passed elements: 51 * - 'name': (string) the script name. 52 * - 'recipes': (array) the filter recipe objects. 53 * - 'script': (string) the filter script. 54 * 55 * @throws Ingo_Exception 56 */ 57 public function setScriptActive($script) 58 { 59 $vacation = null; 60 foreach ($script['recipes'] as $recipe) { 61 if ($recipe['rule'] == Ingo::RULE_VACATION) { 62 $vacation = $recipe['object']->vacation; 63 break; 64 } else { 65 throw new Ingo_Exception('The ISPConfig transport driver only supports vacation rules.'); 66 } 67 } 68 69 if (!$vacation) { 70 return; 71 } 72 73 // Fill mailuser_id and client_id. 74 $this->_getUserDetails($this->_params['password']); 75 76 try { 77 $user = $this->_soap->mail_user_get( 78 $this->_soap_session, $this->_details['mailuser_id']); 79 80 $user['autoresponder'] = $recipe['object']->disable ? 'n' : 'y'; 81 // UNIX timestamp. 82 $start = $vacation->getVacationStart(); 83 $end = $vacation->getVacationEnd(); 84 if (empty($start)) { 85 $start = time(); 86 } 87 if (empty($end)) { 88 $end = time(); 89 } 90 $user['autoresponder_start_date'] = array( 91 'year' => date('Y', $start), 92 'month' => date('m', $start), 93 'day' => date('d', $start), 94 'hour' => date('H', $start), 95 'minute' => date('i', $start)); 96 $user['autoresponder_end_date'] = array( 97 'year' => date('Y', $end), 98 'month' => date('m', $end), 99 'day' => date('d', $end), 100 'hour' => 23, 101 'minute' => 59); 102 // $vacation->getVacationSubject() not supported by ISPConfig 103 $user['autoresponder_text'] = $vacation->getVacationReason(); 104 // otherwise ISPConfig calculates the hash of this hash... braindead 105 unset($user['password']); 106 107 $this->_soap->mail_user_update( 108 $this->_soap_session, $this->_details['client_id'], 109 $this->_details['mailuser_id'], $user); 110 } catch (SoapFault $e) { 111 throw new Ingo_Exception($e); 112 } 113 } 114 115 /** 116 * Retrieves the current vacation details for the user. 117 * 118 * @param string $password The password for user. 119 * 120 * @return array Vacation details 121 * @throws Ingo_Exception 122 */ 123 protected function _getUserDetails($password) 124 { 125 if (!is_null($this->_details)) { 126 return $this->_details; 127 } 128 129 $this->_checkConfig(); 130 $this->_connect(); 131 132 try { 133 $users = $this->_soap->mail_user_get( 134 $this->_soap_session, 135 array('login' => $this->_params['username'])); 136 } catch (SoapFault $e) { 137 throw new Ingo_Exception($e); 138 } 139 if (count($users) != 1) { 140 throw new Ingo_Exception( 141 sprintf(_("%d users with login %s found, one expected."), 142 count($users), 143 $this->_params['username'])); 144 } 145 146 $user = $users[0]; 147 $this->_details['vacation'] = 148 ($user['autoresponder'] === 'y') ? 'Y' : 'N'; 149 $this->_details['message'] = $user['autoresponder_text']; 150 $this->_details['mailuser_id'] = $user['mailuser_id']; 151 // 0 == admin 152 $this->_details['client_id'] = 0; 153 $this->_details['autoresponder_start_date'] = 154 $user['autoresponder_start_date']; 155 $this->_details['autoresponder_end_date'] = 156 $user['autoresponder_end_date']; 157 return $this->_details; 158 } 159 160 /** 161 * Checks if the realm has a specific configuration. If not, tries to fall 162 * back on the default configuration. If still not a valid configuration 163 * then returns an exception. 164 * 165 * @throws Ingo_Exception 166 */ 167 protected function _checkConfig() 168 { 169 if (empty($this->_params['soap_uri']) || 170 empty($this->_params['soap_user']) ) { 171 throw new Ingo_Exception('The Ingo Ispconfig transport is not properly configured, edit your ingo/config/backends.local.php.'); 172 } 173 } 174 175 /** 176 * Connects to the SOAP server. 177 * 178 * @throws Ingo_Exception 179 */ 180 protected function _connect() 181 { 182 if ($this->_soap) { 183 return; 184 } 185 186 $soap_uri = $this->_params['soap_uri']; 187 $client = new SoapClient(null, array( 188 'location' => $soap_uri . 'index.php', 189 'uri' => $soap_uri)); 190 191 try { 192 if (!$session_id = $client->login( 193 $this->_params['soap_user'], 194 $this->_params['soap_pass'])) { 195 throw new Ingo_Exception( 196 sprintf(_("Login to %s failed."), $soap_uri)); 197 } 198 } catch (SoapFault $e) { 199 throw new Ingo_Exception($e); 200 } 201 202 $this->_soap = &$client; 203 $this->_soap_session = $session_id; 204 } 205} 206