1: <?php
2:
3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16:
17: class PathStuffController
18: {
19: public $xoopsPath = array(
20: 'root' => '',
21: 'lib' => '',
22: 'data' => '');
23:
24: public $xoopsPathDefault = array(
25: 'lib' => 'xoops_lib',
26: 'data' => 'xoops_data');
27:
28: public $dataPath = array(
29: 'caches' => array(
30: 'xoops_cache',
31: 'smarty_cache',
32: 'smarty_compile'),
33: 'configs');
34:
35: public $path_lookup = array(
36: 'root' => 'ROOT_PATH',
37: 'data' => 'VAR_PATH',
38: 'lib' => 'PATH');
39:
40: public $xoopsUrl = '';
41: public $xoopsCookieDomain = '';
42:
43: public $validPath = array(
44: 'root' => 0,
45: 'data' => 0,
46: 'lib' => 0);
47:
48: public $validUrl = false;
49:
50: public $permErrors = array(
51: 'root' => null,
52: 'data' => null);
53:
54: 55: 56: 57:
58: public function __construct($xoopsPathDefault, $dataPath)
59: {
60: $this->xoopsPathDefault = $xoopsPathDefault;
61: $this->dataPath = $dataPath;
62:
63: if (isset($_SESSION['settings']['ROOT_PATH'])) {
64: foreach ($this->path_lookup as $req => $sess) {
65: $this->xoopsPath[$req] = $_SESSION['settings'][$sess];
66: }
67: } else {
68: $path = str_replace("\\", '/', realpath('../'));
69: if (substr($path, -1) === '/') {
70: $path = substr($path, 0, -1);
71: }
72: if (file_exists("$path/mainfile.dist.php")) {
73: $this->xoopsPath['root'] = $path;
74: }
75:
76: $this->xoopsPath['lib'] = dirname($path) . '/' . $this->xoopsPathDefault['lib'];
77:
78: if (!is_dir($this->xoopsPath['lib'] . '/')) {
79: $this->xoopsPath['lib'] = $path . '/' . $this->xoopsPathDefault['lib'];
80: }
81:
82: $this->xoopsPath['data'] = dirname($path) . '/' . $this->xoopsPathDefault['data'];
83:
84: if (!is_dir($this->xoopsPath['data'] . '/')) {
85: $this->xoopsPath['data'] = $path . '/' . $this->xoopsPathDefault['data'];
86: }
87: }
88: if (isset($_SESSION['settings']['URL'])) {
89: $this->xoopsUrl = $_SESSION['settings']['URL'];
90: } else {
91: $path = $GLOBALS['wizard']->baseLocation();
92: $this->xoopsUrl = substr($path, 0, strrpos($path, '/'));
93: }
94: if (isset($_SESSION['settings']['COOKIE_DOMAIN'])) {
95: $this->xoopsCookieDomain = $_SESSION['settings']['COOKIE_DOMAIN'];
96: } else {
97: $this->xoopsCookieDomain = xoops_getBaseDomain($this->xoopsUrl);
98: }
99: }
100:
101: public function execute()
102: {
103: $this->readRequest();
104: $valid = $this->validate();
105: if ($_SERVER['REQUEST_METHOD'] === 'POST') {
106: foreach ($this->path_lookup as $req => $sess) {
107: $_SESSION['settings'][$sess] = $this->xoopsPath[$req];
108: }
109: $_SESSION['settings']['URL'] = $this->xoopsUrl;
110: $_SESSION['settings']['COOKIE_DOMAIN'] = $this->xoopsCookieDomain;
111: if ($valid) {
112: $GLOBALS['wizard']->redirectToPage('+1');
113: } else {
114: $GLOBALS['wizard']->redirectToPage('+0');
115: }
116: }
117: }
118:
119: public function readRequest()
120: {
121: if ($_SERVER['REQUEST_METHOD'] === 'POST') {
122: $request = $_POST;
123: foreach ($this->path_lookup as $req => $sess) {
124: if (isset($request[$req])) {
125: $request[$req] = str_replace("\\", '/', trim($request[$req]));
126: if (substr($request[$req], -1) === '/') {
127: $request[$req] = substr($request[$req], 0, -1);
128: }
129: $this->xoopsPath[$req] = $request[$req];
130: }
131: }
132: if (isset($request['URL'])) {
133: $request['URL'] = trim($request['URL']);
134: if (substr($request['URL'], -1) === '/') {
135: $request['URL'] = substr($request['URL'], 0, -1);
136: }
137: $this->xoopsUrl = $request['URL'];
138: }
139: if (isset($request['COOKIE_DOMAIN'])) {
140: $tempCookieDomain = trim($request['COOKIE_DOMAIN']);
141: $tempParts = parse_url($tempCookieDomain);
142: if (!empty($tempParts['host'])) {
143: $tempCookieDomain = $tempParts['host'];
144: }
145: $request['COOKIE_DOMAIN'] = $tempCookieDomain;
146: $this->xoopsCookieDomain = $tempCookieDomain;;
147: }
148: }
149: }
150:
151: 152: 153:
154: public function validate()
155: {
156: foreach (array_keys($this->xoopsPath) as $path) {
157: if ($this->checkPath($path)) {
158: $this->checkPermissions($path);
159: }
160: }
161: $this->validUrl = !empty($this->xoopsUrl);
162: $validPaths = (array_sum(array_values($this->validPath)) == count(array_keys($this->validPath))) ? 1 : 0;
163: $validPerms = true;
164: foreach ($this->permErrors as $key => $errs) {
165: if (empty($errs)) {
166: continue;
167: }
168: foreach ($errs as $path => $status) {
169: if (empty($status)) {
170: $validPerms = false;
171: break;
172: }
173: }
174: }
175:
176: return ($validPaths && $this->validUrl && $validPerms);
177: }
178:
179: 180: 181: 182: 183:
184: public function checkPath($PATH = '')
185: {
186: $ret = 1;
187: if ($PATH === 'root' || empty($PATH)) {
188: $path = 'root';
189: if (is_dir($this->xoopsPath[$path]) && is_readable($this->xoopsPath[$path])) {
190: @include_once "{$this->xoopsPath[$path]}/include/version.php";
191: if (file_exists("{$this->xoopsPath[$path]}/mainfile.dist.php") && defined('XOOPS_VERSION')) {
192: $this->validPath[$path] = 1;
193: }
194: }
195: $ret *= $this->validPath[$path];
196: }
197: if ($PATH === 'lib' || empty($PATH)) {
198: $path = 'lib';
199: if (is_dir($this->xoopsPath[$path]) && is_readable($this->xoopsPath[$path])) {
200: $this->validPath[$path] = 1;
201: }
202: $ret *= $this->validPath[$path];
203: }
204: if ($PATH === 'data' || empty($PATH)) {
205: $path = 'data';
206: if (is_dir($this->xoopsPath[$path]) && is_readable($this->xoopsPath[$path])) {
207: $this->validPath[$path] = 1;
208: }
209: $ret *= $this->validPath[$path];
210: }
211:
212: return $ret;
213: }
214:
215: 216: 217: 218: 219: 220:
221: public function setPermission($parent, $path, &$error)
222: {
223: if (is_array($path)) {
224: foreach (array_keys($path) as $item) {
225: if (is_string($item)) {
226: $error[$parent . '/' . $item] = $this->makeWritable($parent . '/' . $item);
227: if (empty($path[$item])) {
228: continue;
229: }
230: foreach ($path[$item] as $child) {
231: $this->setPermission($parent . '/' . $item, $child, $error);
232: }
233: } else {
234: $error[$parent . '/' . $path[$item]] = $this->makeWritable($parent . '/' . $path[$item]);
235: }
236: }
237: } else {
238: $error[$parent . '/' . $path] = $this->makeWritable($parent . '/' . $path);
239: }
240:
241: return null;
242: }
243:
244: 245: 246: 247: 248:
249: public function checkPermissions($path)
250: {
251: $paths = array(
252: 'root' => array('mainfile.php', 'uploads', ),
253: 'data' => $this->dataPath);
254: $errors = array(
255: 'root' => null,
256: 'data' => null);
257:
258: if (!isset($this->xoopsPath[$path])) {
259: return false;
260: }
261: if (!isset($errors[$path])) {
262: return true;
263: }
264: $this->setPermission($this->xoopsPath[$path], $paths[$path], $errors[$path]);
265: if (in_array(false, $errors[$path])) {
266: $this->permErrors[$path] = $errors[$path];
267: }
268:
269: return true;
270: }
271:
272: 273: 274: 275: 276: 277: 278: 279: 280:
281: public function makeWritable($path, $create = true)
282: {
283: $mode = intval('0777', 8);
284: if (!file_exists($path)) {
285: if (!$create) {
286: return false;
287: } else {
288: mkdir($path, $mode);
289: }
290: }
291: if (!is_writable($path)) {
292: chmod($path, $mode);
293: }
294: clearstatcache();
295: if (is_writable($path)) {
296: $info = stat($path);
297: if ($info['mode'] & 0002) {
298: return 'w';
299: } elseif ($info['mode'] & 0020) {
300: return 'g';
301: }
302:
303: return 'u';
304: }
305:
306: return false;
307: }
308: }
309: