1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
<?php
namespace Codeception\Lib\Connector;
use Codeception\Util\Stub;
use Symfony\Component\BrowserKit\Client;
use Symfony\Component\BrowserKit\Response;
class Yii1 extends Client
{
use Shared\PhpSuperGlobalsConverter;
/**
* http://localhost/path/to/your/app/index.php
* @var string url of the entry Yii script
*/
public $url;
/**
* Current application settings {@see Codeception\Module\Yii1::$appSettings}
* @var array
*/
public $appSettings;
/**
* Full path to your application
* @var string
*/
public $appPath;
/**
* Current request headers
* @var array
*/
private $headers;
/**
*
* @param \Symfony\Component\BrowserKit\Request $request
*
* @return \Symfony\Component\BrowserKit\Response
*/
public function doRequest($request)
{
$this->headers = [];
$_COOKIE = array_merge($_COOKIE, $request->getCookies());
$_SERVER = array_merge($_SERVER, $request->getServer());
$_FILES = $this->remapFiles($request->getFiles());
$_REQUEST = $this->remapRequestParameters($request->getParameters());
$_POST = $_GET = [];
if (strtoupper($request->getMethod()) == 'GET') {
$_GET = $_REQUEST;
} else {
$_POST = $_REQUEST;
}
// Parse url parts
$uriPath = ltrim(parse_url($request->getUri(), PHP_URL_PATH), '/');
$uriQuery = ltrim(parse_url($request->getUri(), PHP_URL_QUERY), '?');
$scriptName = trim(parse_url($this->url, PHP_URL_PATH), '/');
if (!empty($uriQuery)) {
$uriPath .= "?{$uriQuery}";
parse_str($uriQuery, $params);
foreach ($params as $k => $v) {
$_GET[$k] = $v;
}
}
// Add script name to request if none
if ($scriptName and strpos($uriPath, $scriptName) === false) {
$uriPath = "/{$scriptName}/{$uriPath}";
}
// Add forward slash if not exists
if (strpos($uriPath, '/') !== 0) {
$uriPath = "/{$uriPath}";
}
$_SERVER['REQUEST_METHOD'] = strtoupper($request->getMethod());
$_SERVER['REQUEST_URI'] = $uriPath;
/**
* Hack to be sure that CHttpRequest will resolve route correctly
*/
$_SERVER['SCRIPT_NAME'] = "/{$scriptName}";
$_SERVER['SCRIPT_FILENAME'] = $this->appPath;
ob_start();
\Yii::setApplication(null);
\Yii::createApplication($this->appSettings['class'], $this->appSettings['config']);
$app = \Yii::app();
// disabling logging. Logs slow down test execution
if ($app->hasComponent('log')) {
foreach ($app->getComponent('log')->routes as $route) {
$route->enabled = false;
}
}
if ($app->hasComponent('session')) { // disable regenerate id in session
$app->setComponent('session', Stub::make('CHttpSession', ['regenerateID' => false]));
}
$app->onEndRequest->add([$this, 'setHeaders']);
$app->run();
if ($app->hasComponent('db')) {
// close connection
$app->getDb()->setActive(false);
// cleanup metadata cache
$property = new \ReflectionProperty('CActiveRecord', '_md');
$property->setAccessible(true);
$property->setValue([]);
}
$content = ob_get_clean();
$headers = $this->getHeaders();
$statusCode = 200;
foreach ($headers as $header => $val) {
if ($header == 'Location') {
$statusCode = 302;
}
}
$response = new Response($content, $statusCode, $this->getHeaders());
return $response;
}
/**
* Set current client headers when terminating yii application (onEndRequest)
*/
public function setHeaders()
{
$this->headers = \Yii::app()->request->getAllHeaders();
}
/**
* Returns current client headers
* @return array headers
*/
public function getHeaders()
{
return $this->headers;
}
}