00001 <?php
00019 class PageRender2 extends SObject {
00022 protected $page;
00025 protected $options;
00026 protected $defaults;
00029 protected $inputs;
00030 protected $classes;
00031 protected $counters;
00032 private $auth;
00033
00036 const XML_PARSE_ERROR = 35;
00037
00044 public function __construct ($format = "") {
00045 $this->page = new SPage($format);
00046 $this->options = array();
00047 $this->inputs = array();
00048 $this->classes = array();
00049 $this->defaults = array();
00050 $this->counters = array();
00051 $this->errors = array();
00052 $this->auth = array();
00053 include(dirname(__FILE__) . "/config/PageRender2Config.php5");
00054 }
00055
00056
00057
00058
00059
00060
00070 public function getDefault ($key) {
00071 if (!isset($this->defaults[$key])) return "";
00072 return $this->defaults[$key];
00073 }
00074
00075 public function setDefault ($key, $value) {
00076 $this->defaults[$key] = $value;
00077 }
00078
00079
00080
00089 public function getClass ($key) {
00090 return $this->getHelper('classes', $key);
00091 }
00092
00102 public function setClass ($key, $value) {
00103 $this->classes[$key] = $value;
00104 }
00105
00106
00107
00119 public function getClassInstance ($key) {
00120 if(!isset($this->classes[$key])) {
00121 if (!class_exists($key)){
00122 $this->setPrettyError("getClassInstance", "can't find class '$key' to create an instance. "
00123 . "The class must be default, saved in the 'translate' directory, or included "
00124 . "directly.");
00125 return false;
00126 }
00127 $this->classes[$key] = new $key($this);
00128 }
00129 return $this->classes[$key];
00130 }
00131
00132
00142 public function getOption ($key) {
00143 if (!isset($this->options[$key])){ return $this->getDefault($key); }
00144 return $this->options[$key];
00145 }
00146
00155 public function setOption ($key, $value) {
00156 $this->options[$key] = $value;
00157 }
00158
00167 public function setToolkitTheme($theme) {
00168 Toolkit::setDefaultTheme($theme, true);
00169 }
00170
00180 public function rebaseCserdUrls($enable = true, $projectUrl = false) {
00181 if($enable) {
00182 if($projectUrl === false)
00183 $projectUrl = ltrim($GLOBALS['SITE_URL'], '/');
00184 global $PATH;
00185 SConfig::setOption('pr2.cserdUrlMap',
00186 array("!http://www.shodor.org/$projectUrl/!" => "$PATH[home]/"));
00187 }
00188 else
00189 SConfig::setOption('pr2.cserdUrlMap', null);
00190 }
00191
00192
00200 public function getPage() {
00201 return $this->page;
00202 }
00203
00204
00209 private function getHelper($array, $key)
00210 { if (!isset($this->$array[$key])) return false;
00211 return $this->$array[$key]; }
00212
00213
00222 public function getInput($key) {
00223 return $this->inputs[$key];
00224 }
00225
00234 public function getPageTemplate() {
00235 return $this->getClassInstance($this->getOption('template'));
00236 }
00237
00246 public function getLayout() {
00247 return $this->getClassInstance($this->getOption('layout'));
00248 }
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00308 public function add ($component, $options = array()) {
00309 $this->load($component, array_merge($options,
00310 array('inFormat' => 'tk', 'translator_tk' => 'STransTK')));
00311 }
00312
00327 public function includeJS ($filename, $root = '') {
00328 if(strpos($root, '/') === false) {
00329 switch($root) {
00330 default:
00331 case '':
00332 case 'ProjectJS':
00333 $root = SPath::getRelPath('ProjectJS');
00334 break;
00335 case 'DefaultSkin':
00336 case 'CustomSkin':
00337 $root = SPath::getRelPath($root) . '/js';
00338 break;
00339 }
00340 }
00341 $this->load('<script type="text/javascript" src="' . $root . '/' . $filename . '"></script>' . "\n",
00342 array('inFormat' => 'html', 'trans_target' => 'LibHeadTags'));
00343 }
00344
00359 public function includeCSS ($filename, $root = '') {
00360 if($root !== null) {
00361 if(strpos($root, '/') === false) {
00362 switch($root) {
00363 default:
00364 case '':
00365 case 'ProjectCSS':
00366 $root = SPath::getRelPath('ProjectCSS');
00367 break;
00368 case 'DefaultSkin':
00369 case 'CustomSkin':
00370 $root = SPath::getRelPath($root) . '/css';
00371 break;
00372 }
00373 }
00374 $root = "$root/";
00375 }
00376 else
00377 $root = '';
00378 $this->load('<link rel="stylesheet" type="text/css" href="' . $root . $filename . '" />' . "\n",
00379 array('inFormat' => 'html', 'trans_target' => 'ExtraHeadTags'));
00380 }
00381
00390 public function loadJS ($js, $slot = 'ExtraJS') {
00391 $this->load($js, array('inFormat' => 'html', 'trans_target' => $slot));
00392 }
00393
00401 public function loadCSS ($css) {
00402 $this->load($css, array('inFormat' => 'html', 'trans_target' => 'ExtraCSS'));
00403 }
00404
00421 public function load ($input, $options = array(), $name = "") {
00422
00423 if ($name == ""){
00424 $name = "untitled" . $this->counters['untitledSlot'];
00425 $this->counters['untitledSlot']++;
00426 }
00427
00428
00429
00430
00431
00432 if (($input instanceof SnapResource) || ($input instanceof SnapVersion)) {
00433 if ($input instanceof SnapResource) {
00434
00435 $r = $input;
00436 $v = $r->getActiveVersion();
00437
00438 if ($v === null) {
00439 $this->setPrettyError('load', 'No active version available.');
00440 return false;
00441 }
00442 } else {
00443 $v = $input;
00444 $r = $v->getResource();
00445 }
00446
00447 $cm = $v->getContentModule();
00448
00449 if (!isset($options['inFormat'])){
00450 $transCL = $cm->getTranslator();
00451 $trans = $this->getClassInstance($transCL);
00452 $format = $trans->getInFormat();
00453
00454 if ($format === false){
00455 $this->setPrettyError('load', 'No format found for this resource.');
00456 return false;
00457 }
00458
00459 $options['inFormat'] = $format;
00460 }
00461
00462 if (!isset($options["translator_$options[inFormat]"])) {
00463 $trans = $cm->getTranslator();
00464
00465 $options["translator_$options[inFormat]"] = $trans;
00466 }
00467
00468 $input = $cm;
00469 $options['_version'] = $v;
00470 $options['_resource'] = $r;
00471
00472 if(!isset($options['no_snap_css']) || $options['no_snap_css'] == false) {
00473 $ss = $r->getStylesheets();
00474 if(count($ss) > 0) {
00475 foreach($ss as $nm => $s) {
00476 if($s->getActiveVersion())
00477 $this->includeCSS($url = $s->getActiveVersion()->getContentModule()->getLinkURL(), null);
00478 }
00479 }
00480 }
00481 }
00482
00483
00484 $si = new SInput($input, $options, $this, $name);
00485 $this->inputs[$name] = $si;
00486
00487
00488
00489 if(isset($options['waitToTranslate']) && ($options['waitToTranslate'] == true)) {
00490 return true;
00491 }
00492
00493
00494 $si->translate();
00495
00496 $this->getWarningFrom($si);
00497
00498 if ($si->hasError()) {
00499 $this->getErrorFrom($si);
00500 return false;
00501 }
00502 return true;
00503 }
00504
00505
00506
00507
00508
00516 public function render() {
00517 $layoutClass = $this->getOption('layout');
00518 $templateClass = $this->getOption('template');
00519 $this->getClassInstance("$templateClass");
00520 $layoutInstance = $this->getClassInstance("$layoutClass");
00521
00522
00523
00524 if ($layoutInstance === false) {
00525 $this->setPrettyError('render', 'Specified Layout class not found.');
00526 return false;
00527 }
00528
00529
00530 $layoutInstance->layout();
00531 return true;
00532 }
00533
00542 public function renderPrint ($format = "html") {
00543 global $SWAT;
00544
00545
00546
00547
00548
00549
00550
00551
00552 if(in_array("tk2", SAutoLoad::getModules())) {
00553 $extraJS = Toolkit::prm_getExtraJS();
00554 $extraCSS = Toolkit::prm_getExtraCSS();
00555 $jsSource = Toolkit::prm_getJSSource();
00556 $cssSource = Toolkit::prm_getCSSSource();
00557 $hiddenForms = Toolkit::prm_getExtraForms();
00558
00559 $this->load($extraJS, array('inFormat' => 'html', 'trans_target' => 'ExtraJS'));
00560 $this->load($extraCSS, array('inFormat' => 'html', 'trans_target' => 'ExtraCSS'));
00561 $this->load($jsSource, array('inFormat' => 'html',
00562 'trans_target' => 'DefaultJSLinks'));
00563 $this->load($cssSource, array('inFormat' => 'html',
00564 'trans_target' => 'DefaultCSSLinks'));
00565 $this->load($hiddenForms, array('inFormat' => 'html',
00566 'trans_target' => 'Main'));
00567 }
00568
00569 if (in_array("xforms", SAutoLoad::getModules())) {
00570 $xformsUIBase = SPath::getRelPath('UI') . '/xforms/';
00571
00572 $ecss = $this->getPage()->getSlot('ExtraCSS');
00573 $ecss = '@import "' . $xformsUIBase . 'xforms.css";' . $ecss;
00574 $this->getPage()->setSlot('ExtraCSS', $ecss);
00575 $this->getPage()->appendToSlot('ExtraHeadTags',
00576 '<script src="' . SPath::getRelPath('UI')
00577 . '/xforms/xforms.js" type="text/javascript"></script>');
00578
00579 $this->setOption('prototype', true);
00580 }
00581
00582
00583
00584 $this->getWarningFrom($this->getPage());
00585 $this->getErrorFrom($this->getPage());
00586
00587
00588
00589 if (isset($SWAT) && ($SWAT instanceof SWAT)) {
00590
00591 $this->getWarningFrom($SWAT);
00592 $this->getErrorFrom($SWAT);
00593 }
00594
00595
00596 $page = $this->getPage();
00597
00598
00599
00600 if (SConfig::getOption('common.DISPLAY_ERRORS')) {
00601 $page->appendToSlot('Flash', $this->formatError($page->getFormat(), 'Error', $this->getError()));
00602 }
00603 if (SConfig::getOption('common.DISPLAY_WARNINGS')) {
00604 $page->appendToSlot('Flash', $this->formatError($page->getFormat(), 'Warning', $this->getWarning()));
00605 }
00606
00607
00608 $html = SErrorManager::prm_printMessages();
00609
00610 $this->load($html, array('inFormat' => 'html', 'trans_target' => 'Flash'));
00611
00612
00613
00614 $result = $this->render();
00615
00616 header('Content-type: text/' . $format . '; charset=utf-8');
00617
00618 if ($result === false) {
00619 print("<h1>PageRender2 failed with the following errors:</h1>");
00620 print($this->formatError($page->getFormat(), 'Errors', $this->getError()));
00621 print($this->formatError($page->getFormat(), 'Warnings', $this->getWarning()));
00622 exit();
00623 }
00624
00625 echo $page->getPage();
00626
00627
00628 if (isset($_GET['runTestSuite'])) {
00629 STestReporter::register('pr2.analytics', (strpos($content, '_gat._getTracker') !== false));
00630 STestReporter::register('pr2.commonVersion', SConfig::getDefault('common.commonDir'));
00631 }
00632
00633
00634 if ($this->getOption('cacheContentOnRender')){
00635 $this->updateCachedVersion();
00636 $caching = true;
00637 } else {
00638 $caching = false;
00639 }
00640
00641 if (isset($_GET['runTestSuite'])) {
00642 STestReporter::register('pr2.caching', $caching);
00643 }
00644
00645 }
00646
00647
00648
00649
00661 public function formatError($format, $title, $error, $indent = 0) {
00662 switch($format){
00663 case 'html':
00664
00665 if (!is_array($error)) {
00666 return ("<b>$title</b>: " . $error . "<br />");
00667 } else {
00668 $output = "";
00669 foreach($error as $e) {
00670 $output .= $this->formatError($format, $title, $e, $indent + 1);
00671 }
00672 return ($output == "") ? "" : "<div class='pr2error'>" . $output . "</div>";
00673 }
00674
00675 default:
00676 return "";
00677 }
00678
00679 }
00680
00689 public function flash($string = "") {
00690 $this->getPage()->appendToSlot('Flash', '<div class="flashNotice">' . $string . '</div>');
00691 }
00692
00701 public function flashAndExit($string = "") {
00702 $this->flash($string);
00703 $this->renderPrint();
00704 exit();
00705 }
00706
00718 public function flashAndRedirect($string, $url) {
00719 global $SWAT;
00720 $guser = $SWAT->getGlobalUser();
00721 $guser->setFlash($string);
00722 SWATFunctions::redirect($url);
00723 }
00724
00730 protected function runTestSuite($extras = null) {
00731 $content = $this->getPage()->getPage();
00732 $return = array();
00733 $return['pr2.analytics'] = (strpos($content, '_gat._getTracker') === false) ? 'off' : 'on';
00734 $return['pr2.commonVersion'] = SConfig::getDefault('common.commonDir');
00735 if ($extras != null)
00736 $return = array_merge($return, $extras);
00737 return $return;
00738 }
00739
00740
00741
00742
00743
00758 public function useCachedVersion ($lifetime = "") {
00759 if(!SConfig::getDefault('pageCache.enable'))
00760 return false;
00761
00762 if ($lifetime == "") $lifetime = $this->defaults['cacheLifetime'];
00763
00764 $filename = SCacheManager::checkPageCache();
00765 if($filename !== false) {
00766 header('Content-type: text/' .
00767 $this->page->getTargetType() . '; charset=utf-8');
00768 readfile($filename);
00769 if (isset($_GET['runTestSuite']))
00770 STestReporter::register('pr2.caching', true);
00771 exit();
00772 }
00773 else {
00774 $this->setOption('cacheContentOnRender', true);
00775 }
00776 return false;
00777 }
00778
00783 public function updateCachedVersion () {
00784 SCacheManager::addToPageCache($this->page);
00785 }
00786
00792 public function dropCache($uri = null) {
00793 SCacheManager::clearPageCache($uri);
00794 }
00795 }
00796
00797 ?>