horde_fetch()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 21
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 13
nc 1
nop 2
dl 0
loc 21
rs 9.8333
c 0
b 0
f 0
1
<?php
2
/**
3
 * Profiling of diverse mail functions
4
 *
5
 * For Apache FCGI you need the following rewrite rule:
6
 *
7
 * 	RewriteEngine on
8
 * 	RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization},L]
9
 *
10
 * Otherwise authentication request will be send over and over again, as password is NOT available to PHP!
11
 *
12
 * @link http://www.egroupware.org
13
 * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
14
 * @package mail
15
 * @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
16
 * @copyright (c) 2014 by Ralf Becker <RalfBecker-AT-outdoor-training.de>
17
 * @version $Id$
18
 */
19
20
$starttime = microtime(true);
21
22
$GLOBALS['egw_info'] = array(
23
	'flags' => array(
24
		'disable_Template_class' => True,
25
		'noheader'  => True,
26
		'currentapp' => 'mail',
27
		'autocreate_session_callback' => 'EGroupware\\Api\\Header\\Authenticate::autocreate_session_callback',
28
		'auth_realm' => 'EGroupware mail profile',
29
	)
30
);
31
include(dirname(__DIR__).'/header.inc.php');
32
33
$headertime = microtime(true);
34
35
use EGroupware\Api\Mail\Account as emailadmin_account;
36
use EGroupware\Api\Mail\Imap as emailadmin_imap;
37
38
// on which mail account do we work, if not specified use default one (connects to imap server!)
39
$acc_id = isset($_GET['acc_id']) && (int)$_GET['acc_id'] > 0 ? (int)$_GET['acc_id'] : emailadmin_account::get_default_acc_id();
40
// calling emailadmin_account::read with explicit account_id to not cache object for current user!
41
$account = emailadmin_account::read($acc_id, $GLOBALS['egw_info']['user']['account_id']);
42
43
// switching off caching by default
44
// if caching is enabled mail_times will always provit from previous running horde_times!
45
$cache = isset($_GET['cache']) && $_GET['cache'];
46
if (!$cache) unset(emailadmin_imap::$default_params['cache']);
47
48
$accounttime = microtime(true);
49
50
$times = array(
51
	'header' => $headertime - $starttime,
52
	'acc_id' => $acc_id,
53
	'account' => (string)$account,
54
	'cache' => $cache,
55
	'read' => $accounttime - $headertime,
56
);
57
58
php_times($account, $times);
59
horde_times($account, $times);
60
mail_times($acc_id, $times);
61
62
Header('Content-Type: application/json; charset=utf-8');
63
echo json_encode($times, JSON_PRETTY_PRINT);
64
65
function php_times($account, array &$times, $prefix='php_')
66
{
67
	$starttime = microtime(true);
68
	switch($account->acc_imap_ssl & ~emailadmin_account::SSL_VERIFY)
69
	{
70
		case emailadmin_account::SSL_SSL:
71
			$schema = 'ssl';
72
			break;
73
		case emailadmin_account::SSL_TLS:
74
			$schema = 'tls';
75
			break;
76
		case emailadmin_account::SSL_STARTTLS:
77
		default:
78
			$schema = 'tcp';
79
			break;
80
	}
81
	$error_number = $error_string = null;
82
	$stream = stream_socket_client(
83
		$schema . '://' . $account->acc_imap_host . ':' . $account->acc_imap_port,
84
		$error_number,
85
		$error_string,
86
		20,
87
		STREAM_CLIENT_CONNECT,
88
		/* @todo: As of PHP 5.6, TLS connections require valid certs.
89
		 * However, this is BC-breaking to this library. For now, keep
90
		 * pre-5.6 behavior. */
91
		stream_context_create(array(
92
			'ssl' => array(
93
				'verify_peer' => false,
94
				'verify_peer_name' => false
95
			)
96
		))
97
	);
98
	$connect_response = fgets($stream);
99
100
	// starttls (untested)
101
	if ($stream && ($account->acc_imap_ssl & ~emailadmin_account::SSL_VERIFY) == emailadmin_account::SSL_STARTTLS)
0 ignored issues
show
introduced by
$stream is of type false|resource, thus it always evaluated to false.
Loading history...
102
	{
103
		fwrite($stream, "10 STARTTLS\r\n");
104
		stream_socket_enable_crypto($stream, true, STREAM_CRYPTO_METHOD_TLS_CLIENT);
105
		$starttls_response = fgets($stream);
106
	}
107
	stream_set_timeout($stream, 20);
108
109
	if (function_exists('stream_set_read_buffer')) {
110
		stream_set_read_buffer($stream, 0);
111
	}
112
	stream_set_write_buffer($stream, 0);
113
114
	$connect = microtime(true);
115
116
	fwrite($stream, "20 LOGIN $account->acc_imap_username $account->acc_imap_password\r\n");
117
	$login_response = fgets($stream);
118
	$endtime = microtime(true);
119
120
	$times += array(
121
		$prefix.'connect' => $connect - $starttime,
122
		//$prefix.'connect_response' => $connect_response,
123
		$prefix.'login' => $endtime - $starttime,
124
		//$prefix.'login_response' => $login_response,
125
	);
126
127
	fclose($stream);
128
	unset($connect_response, $starttls_response, $login_response, $error_number, $error_string);
129
}
130
131
function mail_times($acc_id, array &$times, $prefix='mail_')
132
{
133
	global $cache;
134
	$starttime = microtime(true);
135
	// instanciate mail for given acc_id - have to set it as preference ;-)
136
	$GLOBALS['egw_info']['user']['preferences']['mail']['ActiveProfileID'] = $acc_id;
137
	// instanciation should call openConnection
138
	$mail_ui = new mail_ui();
139
	$mail_ui->mail_bo->openConnection($acc_id);
140
	$logintime = microtime(true);
141
142
	// fetch mailboxes
143
	$mboxes = $mail_ui->getFolderTree(/*$_fetchCounters=*/false, null, /*$_subscribedOnly=*/true,
0 ignored issues
show
Bug introduced by
The method getFolderTree() does not exist on mail_ui. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

143
	/** @scrutinizer ignore-call */ 
144
 $mboxes = $mail_ui->getFolderTree(/*$_fetchCounters=*/false, null, /*$_subscribedOnly=*/true,

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
144
		/*$_returnNodeOnly=*/true, $cache, /*$_popWizard=*/false);
145
	$listmailboxestime = microtime(true);
146
147
	// get first 20 mails
148
	$query = array(
149
		'start' => 0,
150
		'num_rows' => 20,
151
		'filter' => 'any',
152
		'filter2' => 'quick',
153
		'search' => '',
154
		'order' => 'date',
155
		'sort' => 'DESC',
156
	);
157
	$rows = $readonlys = array();
158
	$mail_ui->get_rows($query, $rows, $readonlys);
159
	$fetchtime = microtime(true);
160
161
	if (isset($_GET['uid']) && (int)$_GET['uid'] > 0)
162
	{
163
		$uid = (int)$_GET['uid'];
164
	}
165
	else	// use uid of first returned row
166
	{
167
		$row = array_shift($rows);
168
		$uid = $row['uid'];
169
	}
170
	$mail_ui->get_load_email_data($uid, null, 'INBOX');
171
	$bodytime = microtime(true);
172
173
	$times += array(
174
		$prefix.'login' => $logintime - $starttime,
175
		$prefix.'listmailboxes' => $listmailboxestime - $logintime,
176
		$prefix.'fetch' => $fetchtime - $listmailboxestime,
177
		$prefix.'total' => $fetchtime - $starttime,
178
		$prefix.'body' => $bodytime - $fetchtime,
179
		//$prefix.'mboxes' => $mboxes,
180
	);
181
	unset($mboxes);
182
	$mail_ui->mail_bo->icServer->close();
183
	$mail_ui->mail_bo->icServer->logout();
184
}
185
186
function horde_times(emailadmin_account $account, array &$times, $prefix='horde_')
187
{
188
	$starttime = microtime(true);
189
	$imap = $account->imapServer();
190
191
	// connect to imap server
192
	$imap->login();
193
	$logintime = microtime(true);
194
195
	// list all subscribed mailboxes incl. attributes and children
196
	$mboxes = $imap->listMailboxes('*', Horde_Imap_Client::MBOX_SUBSCRIBED, array(
197
		'attributes' => true,
198
		'children' => true,
199
	));
200
	$listmailboxestime = microtime(true);
201
202
	// fetch 20 newest mails
203
	horde_fetch($imap);
204
	$fetchtime = microtime(true);
205
206
	$times += array(
207
		$prefix.'login' => $logintime - $starttime,
208
		$prefix.'listmailboxes' => $listmailboxestime - $logintime,
209
		$prefix.'fetch' => $fetchtime - $listmailboxestime,
210
		$prefix.'total' => $fetchtime - $starttime,
211
		//$prefix.'mboxes' => $mboxes,
212
	);
213
	unset($mboxes);
214
	$imap->close();
215
	$imap->logout();
216
}
217
218
function horde_fetch(Horde_Imap_Client_Socket $client, $mailbox='INBOX')
219
{
220
	$squery = new Horde_Imap_Client_Search_Query();
221
	// using a date filter to limit returned uids, gives huge speed improvement on big mailboxes, because less uids returned
222
	//$squery->dateSearch(new DateTime('-30days'), Horde_Imap_Client_Search_Query::DATE_SINCE, false, false);
223
	$squery->flag('DELETED', $set=false);
224
	$sorted = $client->search($mailbox, $squery, array(
225
		'sort' => array(Horde_Imap_Client::SORT_REVERSE, Horde_Imap_Client::SORT_SEQUENCE),
226
	));
227
228
	$first20uids = new Horde_Imap_Client_Ids();
229
	$first20uids->add(array_slice($sorted['match']->ids, 0, 20));
230
231
	$fquery = new Horde_Imap_Client_Fetch_Query();
232
	$fquery->headers('headers', array('Subject', 'From', 'To', 'Cc', 'Date'), array('peek' => true,'cache' => true));
233
	$fquery->structure();
234
	$fquery->flags();
235
	$fquery->imapDate();
236
237
	return $client->fetch($mailbox, $fquery, array(
238
		'ids' => $first20uids,
239
	));
240
}
241