blob: e2e9b8d7be481a67d914603107cbfab4cef5411c [file] [log] [blame]
<?php
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
*
* OODT Balance
* Web Application Base Framework
*
* ApplicationResponse: Provides functions for dynamically constructing
* and delivering a response to a resource request.
*
* @author ahart
*
*/
class Org_Apache_Oodt_Balance_Core_ApplicationResponse {
protected $config;
protected $request;
protected $headers;
protected $header;
protected $view;
protected $footer;
protected $stylesheets = array();
protected $javascripts = array();
protected $data;
const DYN_JS_TAG = '<!-- JAVASCRIPTS -->';
const DYN_CSS_TAG = '<!-- STYLESHEETS -->';
/**
* Constructor
*
* @param array $config
* @param Org_Apache_Oodt_Balance_Core_ApplicationRequest $request
*/
public function __construct($config,
Org_Apache_Oodt_Balance_Core_ApplicationRequest $request) {
$this->config = $config;
$this->request = $request;
$this->headers = array();
$this->header = HOME . "/{$config['header_file_path']}";
$this->footer = HOME . "/{$config['footer_file_path']}";
}
/**
* Generates a response by processing the requested view,
* including any header and footer views (if needed) as specified
* by the application config file.
*
* Available options:
* skipHeader: boolean (default = false) If present, omits header processing
* skipFooter: boolean (default = false) If present, omits footer processing
* skipHooks: boolean (default = false) If present, omits hook processing
*
* @param array $options
*/
public function process($options = array()) {
// Merge defaults with provided options
$defaults = array(
'skipHeader' => false,
'skipFooter' => false,
'skipHooks' => false,
);
$options += $defaults;
if (!$options['skipHooks']) {
// Include the appropriate hooks.php file
include ((App::Get()->request->isModule
? App::Get()->request->modulePath
: HOME ) . '/hooks.php');
// Run 'before_all' hook for all requests
if (function_exists('hook_before_all')) {
hook_before_all();
}
}
// Preprocessing for a view
if (!$this->request->isScript) {
ob_start(); // Start buffering the output
// Check that the requested view exists
if (file_exists($this->request->viewPath)) {
// Run the beforeView hook
if (!$options['skipHooks'] && function_exists('hook_before_view')) {
hook_before_view();
}
// Process the view
include($this->request->viewPath);
} else {
include(HOME . "/views/errors/404.php"); // 404 error page
}
$this->view = ob_get_contents();
ob_clean();
// Determine the header view (if any) to include
if (!$options['skipHeader'] && $this->header && is_file($this->header)) {
// Run the beforeHeader hook
if (!$options['skipHooks'] && function_exists('hook_before_header')) {
hook_before_header();
}
// Process the header
if (!empty($this->header)) {include($this->header);}
$this->header = ob_get_contents();
ob_clean();
}
// Determine the footer view (if any) to include
if (!$options['skipFooter'] && $this->footer && is_file($this->footer)) {
// Run the beforeFooter hook
if (!$options['skipHooks'] && function_exists('hook_before_footer')) {
hook_before_footer();
}
// Process the footer
if (!empty($this->footer)) {include($this->footer);}
$this->footer = ob_get_contents();
ob_clean();
}
ob_end_clean(); // Stop buffering the output
} else {
require_once( $this->request->scriptPath );
exit();
}
}
/**
* Actually sends the response (using 'echo') out to the
* client's browser.
*/
public function send() {
if ($this->request->isScript) {
if (is_file($this->request->scriptPath)) {
require_once($this->request->scriptPath);
} else {
header("Location: " . SITE_ROOT . "/errors/404");
}
} else {
// Process any dynamically added content
$this->processDynamicContent();
// Run the beforeSend hook
if (function_exists('hook_before_send')) {
hook_before_send();
}
foreach ($this->headers as $header) {
header($header);
}
if ($this->header) {
echo $this->header;
}
echo $this->view;
if ($this->footer) {
echo $this->footer;
}
// Run the afterSend hook
if (function_exists('hook_after_send')) {
hook_after_send();
}
}
}
public static function sendFatal($message) {
// Store the message in the session
$_SESSION['fail_message'] = $message;
// Clear any old output and restart buffering the output
ob_clean();
ob_start();
// Build the 404 error page
include(LIB . "/views/errors/fail.php");
// Get the contents as a string and flush the buffer
$content = ob_get_contents();
// Stop buffering output
ob_end_clean();
// Send the response
echo $content;
exit();
}
/**
* Replace special tags with their dynamically assigned content. Currently, the only
* special tags are for defining an area for CSS and JavaScript imports.
*
*/
protected function processDynamicContent() {
// Dynamically insert CSS
$this->header = str_replace(self::DYN_CSS_TAG,implode("\r\n",$this->stylesheets),$this->header);
$this->view = str_replace(self::DYN_CSS_TAG,implode("\r\n",$this->stylesheets),$this->view);
$this->footer = str_replace(self::DYN_CSS_TAG,implode("\r\n",$this->stylesheets),$this->footer);
// Dynamically insert JS
$this->header = str_replace(self::DYN_JS_TAG,implode("\r\n",$this->javascripts),$this->header);
$this->view = str_replace(self::DYN_JS_TAG,implode("\r\n",$this->javascripts),$this->view);
$this->footer = str_replace(self::DYN_JS_TAG,implode("\r\n",$this->javascripts),$this->footer);
}
public function useHeaderFile($path) {
$this->header = $path;
}
public function useFooterFile($path) {
$this->footer = $path;
}
public function sendHeader($headerContent) {
$this->headers[] = $headerContent;
}
public function getHeaderContent() {
return $this->header;
}
public function getViewContent() {
return $this->view;
}
public function getFooterContent() {
return $this->footer;
}
public function data($key = null, $value = null) {
// Return the data store associated with this request
if ($key == null && $value == null) {
return $this->data;
}
// Return the stored value for the provided key
if ($value == null) {
return isset($this->data[$key])
? $this->data[$key]
: null;
}
// Set the stored value for the key to the provided value
$this->data[$key] = $value;
}
public function addStylesheet($href,$condition='') {
// Build the string for the css import
$str = "<link rel=\"stylesheet\" type=\"text/css\" href=\"{$href}\"/>";
if (!empty($condition)) {
$str = "<!--[if {$condition}]>{$str}<![endif]-->";
}
$this->stylesheets[] = $str;
}
/**
* Add javascript resources to the response
*
* This function provides a clean way to programmatically include arbitrary
* Javascript resources in the response. Depending upon the value
* provided for 'isRaw', the contents of 'src' will either be interpreted
* as the 'src' attribute or the body content of the generated <script> block.
*
* @param string src - Either the url to the resource to include (if
* 'isRaw' = false) or a string representing the
* raw Javascript to include (if 'isRaw' = true)
* @param boolean isRaw - Controls how 'src' is interpreted. If set to false
* (default), 'src' will be interpreted as a URL to the
* Javascript resource to include. If set to true, 'src'
* will be interpreted as a string of raw Javascript.
*/
public function addJavascript($src, $isRaw = false) {
if ($isRaw === true) {
// Build a script container for the raw javascript
$str = "<script type=\"text/javascript\">{$src}</script>";
$this->javascripts[] = $str;
} else {
// Build the string for the javascript file import
$str = "<script type=\"text/javascript\" src=\"{$src}\"></script>";
$this->javascripts[] = $str;
}
}
}