PageRenderTime 33ms CodeModel.GetById 2ms app.highlight 12ms RepoModel.GetById 1ms app.codeStats 0ms

/openconstructor/lib/site/pagecompiler._wc

http://openconstructor.googlecode.com/
Unknown | 655 lines | 630 code | 25 blank | 0 comment | 0 complexity | 38c76019a0c147dbadc52e154ad45c2c MD5 | raw file
  1<?php
  2/**
  3 * Copyright 2003 - 2007 eSector Solutions, LLC
  4 *
  5 * All rights reserved.
  6 *
  7 * This file is part of Open Constructor (http://www.openconstructor.org/).
  8 *
  9 * Open Constructor is free software; you can redistribute it and/or
 10 * modify it under the terms of the GNU General Public License version 2
 11 * as published by the Free Software Foundation.
 12 *
 13 * Open Constructor is distributed in the hope that it will be useful,
 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 16 * GNU General Public License for more details.
 17 *
 18 * The GNU General Public License can be found at
 19 * http://www.gnu.org/copyleft/gpl.html
 20 *
 21 * @author Sanjar Akhmedov
 22 *
 23 * $Id: pagecompiler._wc,v 1.44 2007/03/10 20:31:18 sanjar Exp $
 24 */
 25define('PAGE_LOCATION_EMPTY', 0);
 26define('PAGE_LOCATION_EXT', 1);
 27define('PAGE_LOCATION_INT', 2);
 28define('PAGE_LOCATION_ROUTE', 3);
 29
 30class PageCompiler {
 31	var $reader, $tree;
 32
 33	function PageCompiler() {
 34		$this->reader = & new PageReader();
 35	}
 36
 37	function &compile(&$page) {
 38		$result = null;
 39		$location = $this->_parsePageLocation($page);
 40		switch($location['type']) {
 41			case PAGE_LOCATION_EMPTY:
 42				if(!$page->router) {
 43					$result = &$this->compilePlainPage($page, $location['query']);
 44					$result[$page->uri.'index._wc'] = null;
 45				} else
 46					$result = &$this->compileRoutedPage($page, $page->uri, $page->name);
 47			break;
 48			case PAGE_LOCATION_EXT:
 49				$result = &$this->compileRedirectPage($page, $location['page']);
 50				$result[$page->uri.'index._wc'] = null;
 51			break;
 52			case PAGE_LOCATION_INT:
 53				$result = &$this->compileLinkedPage($page, $location['page'], $location['query']);
 54				$result[$page->uri.'index._wc'] = null;
 55			break;
 56			case PAGE_LOCATION_ROUTE:
 57				$result = &$this->compileRoutedPage($page, $location['page'], $location['name'], $location['param'], $location['query']);
 58			break;
 59		}
 60		return $result;
 61	}
 62
 63	function generateSitemap() {
 64		require_once(LIBDIR.'/tree/export/sitemapview._wc');
 65		$tree = &$this->_getSiteTree(true);
 66		return "<?php\n".
 67			PageCompiler::_getWcSign('').
 68			"\n".
 69			$tree->export(new TreeSiteMapView()).
 70			"?>";
 71	}
 72
 73	function &compilePlainPage(&$page, $query = '') {
 74		$result = null;
 75		$content = "<?php\n".
 76			PageCompiler::_getWcSign().
 77			"\n".
 78			PageCompiler::_getQueryDef($query).
 79			$this->_getCommonPart($page).
 80			"\n".
 81			$this->_getAuthenticatingPart($page).
 82			"\n".
 83			PageCompiler::_getPageBuildingPart($page).
 84			"\n".
 85			PageCompiler::_getOutputPart($page).
 86			"?>";
 87		$result = array($page->uri.'index.php' => $content);
 88		return $result;
 89	}
 90
 91	function &compileRedirectPage(&$page, $href) {
 92		$result = null;
 93		$content = "<?php\n".
 94			PageCompiler::_getWcSign().
 95			"\n".
 96			sprintf("\theader('Location: %s');\n", $href{0} == '/' ? "http://'.\$_SERVER['HTTP_HOST'].'".addslashes($href) : addslashes($href)).
 97			"\tdie();\n".
 98			"?>";
 99		$result = array($page->uri.'index.php' => $content);
100		return $result;
101	}
102
103	function &compileLinkedPage(&$page, $link, $query = '') {
104		$result = null;
105		$content = "<?php\n".
106			PageCompiler::_getWcSign().
107			"\n".
108			PageCompiler::_getRecurseCheck($page).
109			"\n".
110			PageCompiler::_getQueryDef($query).
111			"\tinclude(\$_SERVER['DOCUMENT_ROOT'].'$link');\n".
112			"\tdie();\n".
113			"?>";
114		$result = array($page->uri.'index.php' => $content);
115		return $result;
116	}
117
118	function &compileRoutedPage(&$page, $route, $name, $pathInfo = '/', $query = '') {
119		$result = null;
120		if($page->uri == $route || $page->router) {
121			$result = &$this->compilePlainPage($page, $query);
122			$result[$page->uri.'index._wc'] = $result[$page->uri.'index.php'];
123		} else
124			$result = array($page->uri.'index._wc' => null);
125		$routerContent = "<?php\n".
126			PageCompiler::_getWcSign().
127			"\n".
128			PageCompiler::_getRecurseCheck($page).
129			"\n".
130			($page->uri != $route ? PageCompiler::_getQueryDef($query) : '').
131			"\trequire_once(\$_SERVER['DOCUMENT_ROOT'].'".WCHOME."/lib/router._wc');\n";
132		if($page->uri == $route)
133			$routerContent .= sprintf(
134				"\t\$info = isset(\$_SERVER['PATH_INFO']) ? \$_SERVER['PATH_INFO'] : '%s';\n", addslashes($pathInfo)
135			);
136		else
137			$routerContent .= sprintf(
138				"\t\$info = '%s';\n", addslashes($pathInfo)
139			);
140		$routerContent .=
141			"\t\$router = & new Router('$route', '$name', \$info);\n";
142		if($route != $page->uri) {
143			$tree = &$this->_getSiteTree();
144			$router = $tree->getPageByUri($route);
145			$routerContent .= sprintf(
146				"\t@include(\$_SERVER['DOCUMENT_ROOT'].'$route'.(\$router->target ? \$router->target.'/index.php' : 'index.%s'));\n"
147				, $this->reader->getPageRouter($router->id) == $router->id ? '_wc' : 'php'
148			);
149		} else {
150			$routerContent .=
151				"\t@include(\$_SERVER['DOCUMENT_ROOT'].'$route'.(\$router->target ? \$router->target.'/index.php' : 'index._wc'));\n";
152		}
153		$routerContent .=
154			"\tinclude(\$_SERVER['DOCUMENT_ROOT'].'".WCHOME."/404.php');\n".
155			"\tdie();\n".
156			"?>";
157		$result[$page->uri.'index.php'] = $routerContent;
158		return $result;
159	}
160
161	function _getQueryDef($queryString, $indent = "\t") {
162		$result = '';
163		if($queryString) {
164			$query = array();
165			parse_str($queryString, $query);
166			foreach($query as $k => $v)
167				if($k{0} == '!' && strlen($k) > 1) {
168					$result .= sprintf(
169						"{$indent}\$_GET['%1\$s'] = '%2\$s';\n"
170						, addslashes(substr($k, 1)), addslashes($v)
171					);
172				} else {
173					$result .= sprintf(
174						"{$indent}if(!isset(\$_GET['%1\$s']))\n{$indent}\t\$_GET['%1\$s'] = '%2\$s';\n"
175						, addslashes($k), addslashes($v)
176					);
177				}
178		}
179		return $result;
180	}
181
182	function _getCommonPart(&$page, $i = "\t") {
183		static $files;
184		$result = '';
185		if(!is_array($files)) {
186			$files = array(
187				"\$_SERVER['DOCUMENT_ROOT'].'/openconstructor/lib/commons._wc'",
188				"LIBDIR.'/context._wc'",
189				"LIBDIR.'/security/siteauthentication._wc'",
190				"LIBDIR.'/site/webpage._wc'",
191				"LIBDIR.'/site/sitemap._wc'",
192			);
193		}
194		$router = $this->reader->getPageRouter($page);
195		if($router)// && $router != $page->id)
196			$result .=
197				$i."if(!isset(\$router)) {\n".
198				$i."	@include(\$_SERVER['DOCUMENT_ROOT'].'{$GLOBALS['_wchome']}/404.php');\n".
199				$i."	die();\n".
200				$i."}\n\n";
201		$result .=
202			$i."require_once(".implode(");\n{$i}require_once(", $files).");\n".
203			"\n".
204			$i."\$ctx = &Context::getInstance();\n";
205		if($router) {
206			$result .= $i."\$ctx->router = &\$router;\n";
207		} else {
208			$result .=
209				$i."if(isset(\$router))\n".
210				$i."	\$ctx->router = &\$router;\n";
211		}
212		$phpcallback = array();
213		$objects = &$page->getObjects();
214		foreach($objects as $id => $obj)
215			if($obj['observer'] && $obj['type'] == 'phpcallback' && $obj['block'] != '')
216				$phpcallback[] = sprintf("\$ctx->_attachEventListener('%s', %s);", $obj['block'], PageCompiler::_getCreateObserverStatement($id));
217		if(sizeof($phpcallback))
218			$result .=
219				"\n".
220				$i."require_once(LIBDIR.'/wcobject._wc');\n".
221				$i."require_once(LIBDIR.'".PageCompiler::_getClassFile('phpcallback')."');\n".
222				$i.implode("\n$i", $phpcallback)."\n".
223				"\n";
224		$result .=
225			$i."\$ctx->_fireEvent('onInitialize');\n".
226			$i."_register_phase('Initializing');\n".
227			"\n".
228			$i."require_once(ROOT.FILES.'/map._wc');\n".
229			$i."\$ctx->map = &\$map;\n".
230			$i.sprintf("\$page = &\$map->_newPage($page->id, '%s');\n", PageCompiler::_escapeSingleQuotes($this->_getPageTitle($page))).
231			$i."\$ctx->page = &\$page;\n".
232			$i."\$ctx->_fireEvent('onLoadSitemap');\n".
233			$i."_register_phase('Loading sitemap');\n";
234		return $result;
235	}
236
237	function _getAuthenticatingPart(&$page, $i = "\t") {
238		$profiles = $this->_getPageProfileProps($page);
239		$result =
240			$i."if(\$page->isSecure()) {\n".
241			$i."	session_start();\n".
242			$i."	require_once(LIBDIR.'/security/resource._wc');\n".
243			$i."	require_once(LIBDIR.'/security/wcs._wc');\n".
244			$i."	Authentication::importFromSession();\n".
245			$i."	\$page->authenticationPage = _getAuthenticationPage();\n".
246			$i."	\$page->sRes = & new WCSResource(&\$page->uri, WCS_ROOT_ID, 0);\n";
247		$tree = &$this->_getSiteTree();
248		$node = &$tree->node[$page->id];
249		$authCheck = array();
250		while(($node = &$node->parent) != null)
251			$authCheck[] =
252				$i."	\$page->sRes->setGroup(\$map->id[$node->id]['usr']);\t// ".$node->getFullKey('/')."\n".
253				$i."	WCS::requireAuthentication(&\$page);\n";
254		$authCheck[] =
255				$i."	\$ctx->_fireEventArgs('onBeforeAuth', \$args = array('page' => &\$page));	unset(\$args);\n";
256		$result .= implode('', array_reverse($authCheck)).
257			$i."	\$page->sRes->setGroup(\$map->id[$page->id]['usr']);\t// $page->uri\n".
258			$i."	WCS::requireAuthentication(&\$page);\n".
259			$i."	_register_phase('Authenticating user');\n".
260			$i."	\$auth = &SiteAuthentication::createFrom(Authentication::getInstance());\n".
261			$i."} elseif(isset(\$_COOKIE[session_name()])) {\n".
262			$i."	session_start();\n".
263			$i."	\$auth = &SiteAuthentication::createFromSession();\n".
264			$i."} else {\n".
265			$i."	\$auth = new SiteAuthentication();\n".
266			$i."}\n";
267		if($profiles['load'] > 0)
268			$result .=
269				$i.sprintf("\$auth->_loadProfile(%d, %s);\n", $profiles['load'], $profiles['dynamic'] ? 'true' : 'false');
270		$result .=
271			$i."\$ctx->_setAuthentication(\$auth);	unset(\$auth);\n";
272		return $result;
273	}
274
275	function _getPageBuildingPart(&$page, $i = "\t") {
276		$result =
277			$i."define('WCI_ENABLED', WCI_ALLOWED && \$ctx->auth->isWciEditor());\n".
278			"\n".
279			$i."require_once(LIBDIR.'/smarty/wcsmarty._wc');\n".
280			$i."\$smarty = & new WCSmarty();\n".
281			$i."\$smarty->_ctx = &\$ctx;\n".
282			$i."\$ctx->_smarty = &\$smarty;\n".
283			$i."\$ctx->_fireEvent('onCreateSmarty');\n".
284			$i."_register_phase('Creating Smarty instance');\n".
285			"\n".
286			$i.sprintf("\$page->setTemplate('%s.tpl');\n", $page->tpl > 0 ? $page->tpl : "file:'.LIBDIR.'/tpl/page");
287		if($page->caching) {
288			$cid = PageCompiler::_compileCacheVary($page->cacheVary);
289			$result .=
290				$i."\$smarty->caching = !WCI_ENABLED && WC_PAGE_CACHING ? 2 : 0;\n".
291				$i.sprintf("\$smarty->cache_lifetime = %d;\n", $page->cacheLife ? $page->cacheLife : -1).
292				$i.sprintf("\$page->_cacheGz = \$smarty->caching && WC_PAGE_CACHE_GZ && %s && !headers_sent() && (strpos(@\$_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== false);\n", $page->cacheGz ? 'true' : 'false');
293			if($cid)
294				$result .= $i."if(\$ctx->router) \$r = &\$ctx->router->param; else \$r = array();\n";
295			$result .=
296				$i.sprintf("\$page->_setUID(\"{\$page->id}%s\n", $cid ? "|\".sprintf('%x', crc32($cid)));" : '");').
297				$i.sprintf("\$page->_cacheId = \"p\".\$page->_uid.(\$page->_cacheGz ? '%1\$sgz' : '');\n", $cid ? '-' : '|');
298			if($cid)
299				$result .= $i."unset(\$r);\n";
300			$result .=
301				$i."\$_isCached = false;\n".
302				$i."if(!\$smarty->caching || !(\$_isCached = \$smarty->is_cached(\$page->tpl, \$page->_cacheId))) {\n".
303				PageCompiler::_getPageBuildingCore($page, strlen($i) ? $i.$i{0} : "\t").
304				$i."} elseif(\$_isCached) {\n".
305				$i."	\$page->_eTag = '\"'.\$page->id.sprintf('-%x-%d', crc32(\$page->_uid), \$smarty->_cache_info['timestamp']).'\"';\n".
306				$i."	if(@\$_SERVER['HTTP_IF_NONE_MATCH'] == \$page->_eTag)\n".
307				$i."		\$page->status = 304;\n".
308				$i."}\n";
309		} else {
310			$result .=
311				$i."\$smarty->caching = 0;\n".
312				"\n".
313				PageCompiler::_getPageBuildingCore($page, $i);
314		}
315		return $result;
316	}
317
318	function _getPageBuildingCore(&$page, $i = "\t") {
319		static $robots;
320		if(!is_array($robots))
321			$robots = array(
322				ROBOTS_I_F => 'INDEX,FOLLOW',
323				ROBOTS_I_NOF => 'INDEX,NOFOLLOW',
324				ROBOTS_NOI_F => 'NOINDEX,FOLLOW',
325				ROBOTS_NOI_NOF => 'NOINDEX,NOFOLLOW'
326			);
327		$result = '';
328		$contentType = $this->reader->getPageContentType($page);
329		$links = $this->reader->getPageLinks($page->id);
330		if(sizeof($links)) {
331			$tree = &$this->_getSiteTree();
332			foreach($links as $id)
333				$linkUris[] = $tree->node[$id]->getFullKey('/');
334			$result .= sprintf($i."\$page->links = array(%s); // %s\n", implode(', ', $links), implode(', ', $linkUris));
335			unset($linkUris);
336		}
337		$result .=
338			$i."require_once(LIBDIR.'/site/pagecrumbs._wc');\n".
339			$i."\$ctx->crumbs = &Crumbs::getInstance();\n".
340			"\n".
341			$i."\$page->robots = '{$robots[$page->robots]}';\n".
342			$i.sprintf("\$page->keywords = '%s';\n", @htmlspecialchars($page->meta['keywords'], ENT_QUOTES, 'UTF-8')).
343			$i.sprintf("\$page->description = '%s';\n", @htmlspecialchars($page->meta['description'], ENT_QUOTES, 'UTF-8')).
344			$i."\$page->generator = 'Open Constructor '.(WC_MODE_DEBUG ? WC_VERSION_FULL : WC_VERSION);\n";
345		if(sizeof($page->css) > 1)
346			$result .= $i.sprintf("\$page->setStyleSheet(array(FILES.'/css/%s'));\n", implode("', FILES.'/css/", $page->css));
347		else
348			$result .= $i.sprintf("\$page->setStyleSheet(%s);\n", sizeof($page->css) ? "FILES.'/css/{$page->css[0]}'" : "''");
349		foreach(PageCompiler::_getFavicons() as $icon)
350			$result .= $i.sprintf("\$page->addFavicon('%s', '%s'%s);\n", $icon[0], $icon[1], isset($icon[2]) ? ", '{$icon[2]}'" : '');
351		$result .=
352			$i.sprintf("\$page->setContentType('%s');\n", $contentType).
353			$i.sprintf("\$page->_caching = \$smarty->caching && %s;\n", $page->caching ? 'true' : 'false').
354			"\n";
355		$includes = array();
356		$objects = &$page->getObjects();
357		foreach($objects as $id => $obj)
358			if($obj['block'] != '' && ($filename = PageCompiler::_getClassFile($obj['type'])) != null)
359				$includes[$filename] = "require_once(LIBDIR.'$filename');";
360		if(sizeof($includes)) {
361			$result .=
362				$i."require_once(LIBDIR.'/wcobject._wc');\n".
363				$i.implode("\n$i", $includes)."\n".
364				"\n".
365				$i."\$objects = &\$page->_getObjects();\n".
366				$i."\$ctx->_fireEventArgs('onLoadObjects', \$args = array('objects' => &\$objects));	unset(\$args, \$objects);\n".
367				$i."\$ctx->_registerObjects(\$page->_getObjects());\n".
368				$i."_register_phase('Loading objects');\n".
369				$i."\$ctx->_fireEvent('onLoadBlocks');\n".
370				$i."_register_phase('Registering objects');\n".
371				"\n".
372				$i."\$ctx->_buildCrumbs();\n".
373				$i."_register_phase('Building crumbs');\n".
374				"\n";
375		}
376		$result .=
377			$i."\$smarty->assign_by_ref('ctx', \$ctx);\n".
378			$i."\$smarty->assign_by_ref('page', \$ctx->page);\n".
379			$i."\$smarty->assign_by_ref('map', \$ctx->map);\n".
380			$i."\$smarty->assign_by_ref('idMap', \$ctx->map->id);\n".
381			$i."\$smarty->assign_by_ref('uriMap', \$ctx->map->uri);\n".
382			$i."\$ctx->_fireEvent('onSmartyAssign');\n";
383		if(sizeof($objects)) {
384			$pre = array();
385			foreach($objects as $id => $obj)
386				if($obj['block'] == 'PRE' && ($obj['type'] == 'phpinclude' || $obj['type'] == 'phpcallback'))
387					$pre[] = "\$ctx->objects[$id]->run();";
388			if(sizeof($pre))
389				$result .= $i.implode("\n$i", $pre)."\n\n";
390		}
391		return $result;
392	}
393
394	function _getOutputPart(&$page, $i = "\t") {
395		$result = '';
396		$result .=
397			$i."if(\$page->status == 404 || \$page->status == 304) {\n".
398			$i."	\$content = null;\n".
399			$i."} else {\n".
400			$i."	if(\$page->_caching && \$page->_cacheGz)\n".
401			$i."		\$smarty->register_outputfilter('smarty_outputfilter_gzip');\n".
402			$i."	\$content = \$smarty->fetch(\$page->tpl, \$page->_cacheId);\n".
403			$i."}\n".
404			$i."_register_phase('Fetching content');\n".
405			"\n".
406			$i."switch(\$page->status) {\n".
407			$i."	case 404:\n".
408			$i."		if(!WCI_ENABLED && WC_PAGE_CACHING && \$smarty->caching)\n".
409			$i."			\$smarty->clear_cache(null, \$page->_cacheId);\n".
410			$i."		unset(\$content, \$smarty, \$page, \$map, \$__report);\n".
411			$i."		if(defined('WC_STATUS_404')) {\n".
412			$i."			@include(\$_SERVER['DOCUMENT_ROOT'].WCHOME.'/404.php');\n".
413			$i."		} else\n".
414			$i."			header('Location: http://'.\$_SERVER['HTTP_HOST'].WCHOME.'/404.php?from='.urlencode(\$_SERVER['REQUEST_URI']));\n".
415			$i."		die();\n".
416			$i."	break;\n".
417			$i."	case 304:\n".
418			$i."		header('HTTP/1.1 304 Not Modified');\n".
419			$i."		header('Cache-control: public, must-revalidate');\n".
420			$i."	break;\n".
421			$i."	default:\n".
422			$i."		\$printReport = \$page->isCommentable() && !\$page->_cacheGz && (WC_MODE_DEBUG || \$ctx->auth->groupId == WCS_ADMINS_ID);\n".
423			$i."		\$bufferSize = sendOutput(\$content, !\$printReport);\n".
424			$i."		_register_phase('Sending output [ '.number_format(strlen(\$content)).' bytes, buffer = '.number_format(\$bufferSize).' bytes ]');\n".
425			$i."		if(\$printReport)\n".
426			$i."			print_report();\n".
427			$i."		unset(\$content, \$smarty, \$ctx, \$map, \$page, \$__report);\n".
428			$i."}\n".
429			$i."die();\n";
430		return $result;
431	}
432
433	function _getCreateObserverStatement($objId) {
434		require_once(LIBDIR.'/objmanager._wc');
435		$result = 'null';
436		$obj = ObjManager::load($objId);
437		if($obj)
438			switch($obj->obj_type) {
439				case 'phpcallback':
440					$srcId = file_exists(ROOT.FILES.$obj->sourcePath.intval($obj->source).'._wc') ? $obj->source : 0;
441					$result = sprintf("PHPCallback::_newCallback(%d, '%s')", $srcId, addslashes($obj->name));
442				break;
443			}
444		return $result;
445	}
446
447	function _getPageTitle(&$page) {
448		$result = array($page->cTitle);
449		if($page->addTitle) {
450			$db = &WCDB::bo();
451			$res = $db->query(
452				"SELECT p.addtitle, p.ctitle".
453				" FROM {$this->reader->treeTable} t1, {$this->reader->treeTable} t2, {$this->reader->pagesTable} p".
454				" WHERE t1.id = {$page->id} AND t2.num < t1.num AND (t2.next = 0 OR t2.next > t1.num) AND t2.id = p.id".
455				" ORDER BY t2.num DESC"
456			);
457			if(mysql_num_rows($res) > 0) {
458				$at = true;
459				while($at && ($r = mysql_fetch_assoc($res))) {
460					$result[] = $r['ctitle'];
461					$at = $r['addtitle'] > 0;
462				}
463			}
464			mysql_free_result($res);
465			$result = array_reverse($result);
466		}
467		return implode('.', $result);
468	}
469
470	function _getPageProfileProps(&$page) {
471		$result = array('load' => $page->profilesLoad, 'dynamic' => $page->profilesDynamic);
472		if($page->profilesInherit) {
473			$db = &WCDB::bo();
474			$res = $db->query(
475				"SELECT p.profilesload, p.profilesdynamic".
476				" FROM {$this->reader->treeTable} t1, {$this->reader->treeTable} t2, {$this->reader->pagesTable} p".
477				" WHERE t1.id = {$page->id} AND t2.num < t1.num AND (t2.next = 0 OR t2.next > t1.num) AND t2.id = p.id AND (p.profilesinherit = 0 OR t2.num = 0)".
478				" ORDER BY t2.num DESC".
479				" LIMIT 1"
480			);
481			$r = mysql_fetch_row($res);
482			mysql_free_result($res);
483			$result['load'] = (int) @$r[0];
484			$result['dynamic'] = @$r[1] > 0;
485		}
486		return $result;
487	}
488
489	function _parsePageLocation(&$page) {
490		$result = array('type' => PAGE_LOCATION_EMPTY, 'query' => '');
491		if(!empty($page->location)) {
492			$result['type'] = PAGE_LOCATION_EXT;
493			$result['page'] = $page->location;
494			if($page->linkTo > 0) {
495				$tree = &$this->_getSiteTree();
496				$result['type'] = PAGE_LOCATION_INT;
497				$result['page'] = $tree->node[$page->linkTo]->getFullKey('/').'index.php';
498			} elseif($page->location{0} == '/') {
499				$url = parse_url("http://{$_SERVER['HTTP_HOST']}{$page->location}");
500				if(substr($url['path'], -10) == '/index.php' && empty($url['fragment'])) {
501					$uri = substr($url['path'], 0, -9);
502					$tree = &$this->_getSiteTree();
503					if($tree->uriExists($uri)) {
504						if($uri == $page->uri) {
505							$result['type'] = PAGE_LOCATION_EMPTY;
506							$result['page'] = '';
507						} else {
508							$result['type'] = PAGE_LOCATION_INT;
509							$result['page'] = $uri.'index.php';
510						}
511						$result['query'] = @$url['query'];
512					}
513				} elseif(($p = utf8_strpos($url['path'], '/index.php/')) !== false && empty($url['fragment'])) {
514					$uri = utf8_substr($url['path'], 0, $p + 1);
515					$tree = &$this->_getSiteTree();
516					if($tree->uriExists($uri)) {
517						$result['type'] = PAGE_LOCATION_ROUTE;
518						$result['page'] = $uri;
519						$route = $tree->getPageByUri($uri);
520						$result['name'] = $route->key;
521						$result['param'] = utf8_substr($url['path'], $p + 10); // 10 = strlen('/index.php/');
522						$result['query'] = (string) @$url['query'];
523						unset($route);
524					}
525				}
526			}
527		}
528		return $result;
529	}
530
531	function &_getSiteTree($reload = false) {
532		if($reload || !is_object($this->tree))
533			$this->tree = &$this->reader->getTree();
534		return $this->tree;
535	}
536
537	function _compileCacheVary($cacheVary) {
538		$result = '';
539		$params = array();
540		$found = preg_match_all('/\{(ctx|get|route)\.([\-\.a-z0-9_]+)\}/ui', $cacheVary, $params);
541		if($found) {
542			foreach($params[1] as $i => $v)
543				switch($v) {
544					case 'ctx': $result[] = sprintf('$ctx->getParam(\'%s\')', $params[2][$i]); break;
545					case 'get': $result[] = sprintf('@$_GET[\'%s\']', $params[2][$i]); break;
546					case 'route': $result[] = sprintf('@$r[\'%s\']', $params[2][$i]); break;
547				}
548			$result = implode('.chr(255).', $result);
549		}
550		return $result;
551	}
552
553	function _getWcSign($indent = "\t") {
554		static $sign;
555		if(!is_array($sign)) {
556			$auth = &Authentication::getOriginal();
557			$sign = array(
558				"// Generated by Open Constructor ".WC_VERSION_FULL." [{$auth->userLogin}]",
559				'// '.date('D, j M Y H:i:s'),
560				'',
561				'// Do not edit this file. All changes that were made manually will be overwritten.'
562			);
563		}
564		return $indent.implode("\n$indent", $sign)."\n";
565	}
566
567	function _escapeSingleQuotes($str) {
568		return strtr($str, array('\'' => '\\\'', '\\' => '\\\\'));
569	}
570
571	function _getRecurseCheck(&$page, $i = "\t") {
572		$uid = 'WCP_'.sprintf('%X', crc32($page->id));
573		return
574			$i."if(defined('$uid')) {\n".
575			$i."	die(\"\\n<p>Recursive inclusion of $page->uri</p>\\n\");\n".
576			$i."} else\n".
577			$i."	define('$uid', 1);\n";
578	}
579
580	function &_getFavicons() {
581		static $icons;
582		if(!is_array($icons)) {
583			$icons = array();
584			if(@file_exists($_SERVER['DOCUMENT_ROOT'].'/favicon.ico'))
585				$icons[] = array('/favicon.ico', 'shortcut icon', 'image/x-icon');
586			if(@file_exists($_SERVER['DOCUMENT_ROOT'].'/favicon.gif'))
587				$icons[] = array('/favicon.gif', 'icon', 'image/gif');
588			if(@file_exists($_SERVER['DOCUMENT_ROOT'].'/favicon.png'))
589				$icons[] = array('/favicon.png', 'icon', 'image/png');
590		}
591		return $icons;
592	}
593
594	function _getClassFile($class) {
595		static $classes;
596		if(!is_array($classes)) {
597			$classes = array(
598				'htmltextbody'=>'/htmltext/htmltextbody._wc',
599				'htmltexthl'=>'/htmltext/htmltexthl._wc',
600				'htmltexthlintro'=>'/htmltext/htmltexthlintro._wc',
601				'publicationhl'=>'/publication/publicationhl._wc',
602				'publicationhlintro'=>'/publication/publicationhlintro._wc',
603				'publicationmainintro'=>'/publication/publicationmainintro._wc',
604				'publicationbody'=>'/publication/publicationbody._wc',
605				'publicationpager'=>'/publication/publicationpager._wc',
606				'publicationlist'=>'/publication/publicationlist._wc',
607				'publicationlistintro'=>'/publication/publicationlistintro._wc',
608				'eventcalendar'=>'/event/eventcalendar._wc',
609				'eventhl'=>'/event/eventhl._wc',
610				'eventhlintro'=>'/event/eventhlintro._wc',
611				'eventpager'=>'/event/eventpager._wc',
612				'eventbody'=>'/event/eventbody._wc',
613				'galleryhl'=>'/gallery/galleryhl._wc',
614				'galleryimage'=>'/gallery/galleryimage._wc',
615				'gallerypager'=>'/gallery/gallerypager._wc',
616				'galleryimgpager'=>'/gallery/galleryimgpager._wc',
617				'textrandom'=>'/textpool/textrandom._wc',
618				'phpcallback'=>'/phpsource/phpcallback._wc',
619				'phpinclude'=>'/phpsource/phpinclude._wc',
620				'gballmessages'=>'/guestbook/gballmessages._wc',
621				'gbaddmsglogic'=>'/guestbook/gbaddmsglogic._wc',
622				'gblist'=>'/guestbook/gblist._wc',
623				'gbmsgbody'=>'/guestbook/gbmsgbody._wc',
624				'gbmsghl'=>'/guestbook/gbmsghl._wc',
625				'gbpager'=>'/guestbook/gbpager._wc',
626				'miscfetchtpl'=>'/miscellany/miscfetchtpl._wc',
627				'misccrumbs'=>'/miscellany/misccrumbs._wc',
628				'miscinjector'=>'/miscellany/miscinjector._wc',
629				'miscsendmail'=>'/miscellany/miscsendmail._wc',
630				'filehl'=>'/file/filehl._wc',
631				'filepager'=>'/file/filepager._wc',
632				'usersauthorize'=>'/users/usersauthorize._wc',
633				'userslogout'=>'/users/userslogout._wc',
634				'articlebody'=>'/article/articlebody._wc',
635				'articlebodypager'=>'/article/articlebodypager._wc',
636				'articlehl'=>'/article/articlehl._wc',
637				'articlehlintro'=>'/article/articlehlintro._wc',
638				'articlepager'=>'/article/articlepager._wc',
639				'articlerelated'=>'/article/articlerelated._wc',
640				'hybridtree'=>'/hybrid/view/hybridtree._wc',
641				'hybridhl'=>'/hybrid/view/hybridhl._wc',
642				'hybridbar'=>'/hybrid/view/hybridbar._wc',
643				'hybridpager'=>'/hybrid/view/hybridpager._wc',
644				'hybridbody'=>'/hybrid/view/hybridbody._wc',
645				'hybridbodyedit'=>'/hybrid/view/hybridbodyedit._wc',
646				'ratingrate'=>'/rating/ratingrate._wc',
647				'ratingratelogic'=>'/rating/ratingratelogic._wc',
648				'searchdss'=>'/search/searchdss._wc',
649				'searchdsspager'=>'/search/searchdsspager._wc'
650			);
651		}
652		return isset($classes[$class]) ? $classes[$class] : null;
653	}
654}
655?>