aboutsummaryrefslogtreecommitdiff
path: root/install/ElggRewriteTester.php
blob: ab68da2b79b40acd9d1f3fbc601e20c15470c390 (plain)
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
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
<?php

/**
 * Elgg RewriteTester.
 * Test if URL rewriting is working.
 *
 * @package    Elgg.Core
 * @subpackage Installer
 */
class ElggRewriteTester {
	protected $webserver;
	protected $serverSupportsRemoteRead;
	protected $rewriteTestPassed;
	protected $htaccessIssue;

	/**
	 * Set the webserver as unknown.
	 */
	public function __construct() {
		$this->webserver = 'unknown';
	}

	/**
	 * Run the rewrite test and return a status array
	 *
	 * @param string $url  URL of rewrite test
	 * @param string $path Root directory of Elgg with trailing slash
	 *
	 * @return array
	 */
	public function run($url, $path) {

		$this->webserver = ElggRewriteTester::guessWebServer();

		$this->rewriteTestPassed = $this->runRewriteTest($url);

		if ($this->rewriteTestPassed == FALSE) {
			if ($this->webserver == 'apache' || $this->webserver == 'unknown') {
				if ($this->createHtaccess($path)) {
					$this->rewriteTestPassed = $this->runRewriteTest($url);
				}
			}
		}

		return $this->returnStatus($url);
	}

	/**
	 * Guess the web server from $_SERVER['SERVER_SOFTWARE']
	 *
	 * @return string
	 */
	public static function guessWebServer() {
		$serverString = strtolower($_SERVER['SERVER_SOFTWARE']);
		$possibleServers = array('apache', 'nginx', 'lighttpd', 'iis');
		foreach ($possibleServers as $server) {
			if (strpos($serverString, $server) !== FALSE) {
				return $server;
			}
		}
		return 'unknown';
	}

	/**
	 * Hit the rewrite test URL to determine if the rewrite rules are working
	 *
	 * @param string $url Rewrite test URL
	 *
	 * @return bool
	 */
	protected function runRewriteTest($url) {

		$this->serverSupportsRemoteRead = TRUE;

		if (function_exists('curl_init')) {
			// try curl if installed
			$ch = curl_init();
			curl_setopt($ch, CURLOPT_URL, $url);
			curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
			curl_setopt($ch, CURLOPT_TIMEOUT, 10);
			curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
			$response = curl_exec($ch);
			curl_close($ch);
			return $response === 'success';
		} else if (ini_get('allow_url_fopen')) {
			// use file_get_contents as fallback
			$response = file_get_contents($url);
			return $response === 'success';
		} else {
			$this->serverSupportsRemoteRead = FALSE;
			return FALSE;
		}
	}

	/**
	 * Create Elgg's .htaccess file or confirm that it exists
	 *
	 * @param string $path Elgg's root directory with trailing slash
	 *
	 * @return bool
	 */
	public function createHtaccess($path) {
		$filename = "{$path}.htaccess";
		if (file_exists($filename)) {
			// check that this is the Elgg .htaccess
			$data = file_get_contents($filename);
			if ($data === FALSE) {
				// don't have permission to read the file
				$this->htaccessIssue = 'read_permission';
				return FALSE;
			}
			if (strpos($data, 'Elgg') === FALSE) {
				$this->htaccessIssue = 'non_elgg_htaccess';
				return FALSE;
			} else {
				// check if this is an old Elgg htaccess
				if (strpos($data, 'RewriteRule ^rewrite.php$ install.php') == FALSE) {
					$this->htaccessIssue = 'old_elgg_htaccess';
					return FALSE;
				}
				return TRUE;
			}
		}

		if (!is_writable($path)) {
			$this->htaccessIssue = 'write_permission';
			return FALSE;
		}

		// create the .htaccess file
		$result = copy("{$path}htaccess_dist", $filename);
		if (!$result) {
			$this->htaccessIssue = 'cannot_copy';
			return FALSE;
		}

		return TRUE;
	}

	/**
	 * Create the status array required by the ElggInstaller
	 *
	 * @param string $url Rewrite test URL
	 *
	 * @return array
	 */
	protected function returnStatus($url) {
		if ($this->rewriteTestPassed) {
			return array(
				'severity' => 'pass',
				'message' => elgg_echo('install:check:rewrite:success'),
			);
		}

		if ($this->serverSupportsRemoteRead == FALSE) {
			$msg = elgg_echo('install:warning:rewrite:unknown', array($url));
			$msg .= elgg_view('install/js_rewrite_check', array('url' => $url));
			
			return array(
				'severity' => 'warning',
				'message' => $msg,
			);
		}

		if ($this->webserver == 'apache') {
			$serverString = elgg_echo('install:error:rewrite:apache');
			$msg = "$serverString\n\n";
			if (!isset($this->htaccessIssue)) {
				$msg .= elgg_echo('install:error:rewrite:allowoverride');
				$msg .= elgg_view('install/js_rewrite_check', array('url' => $url));
			
				return array(
					'severity' => 'failure',
					'message' => $msg,
				);
			}
			$msg .= elgg_echo("install:error:rewrite:htaccess:{$this->htaccessIssue}");
			return array(
				'severity' => 'failure',
				'message' => $msg,
			);
		}

		if ($this->webserver != 'unknown') {
			$serverString = elgg_echo("install:error:rewrite:{$this->webserver}");
			$msg = "$serverString\n\n";
			$msg .= elgg_echo("install:error:rewrite:altserver");
			return array(
				'severity' => 'failure',
				'message' => $msg,
			);
		}

		return array(
			'severity' => 'failure',
			'message' => elgg_echo('install:error:rewrite:unknown'),
		);
	}
}