/** * Performs a simple redirection to the specified URL (see below for details * on shorthand URLs). * * Shorthand URLs work as follows: * - <kbd>/^#/</kbd> -- Appends a URL hash to the current URL. * - <kbd>/^?/</kbd> -- Sets the query string for the current page. * - <kbd>/^&/</kbd> -- Appends all specified queries to the URL (Overwrite). * - <kbd>/^&&/</kbd> -- Appends all specified queries to the URL (No overwrite). * - <kbd>/^\//</kbd> -- Redirects to URL relative to root of site (prepends domain). * - <kbd>/^[a-z]*:\/\//</kbd> -- Redirects to absolute URL. * * There is also support for pausing redirects for debugging purposes. * * @see Debug::pauseOnRedirect() * * @param string $url Where to redirect to. * @param bool $permanent Whether to redirect permanently (default: false) * * @throws RedirectorException */ public static function redirect($url = null, $permanent = false) { $url = URL::ize($url); # Get the current render context $ctx = RenderContext::get(); # Check whether we should suspend redirects if (Debug::isEnabled() && (Debug::pauseOnRedirect() || Error::hasErred())) { echo '<div>'; printf('<p><strong>Paused Redirect:</strong> <a href="%s">%s</a></p>', $url, String::escapeHTML($url)); if (Error::hasErred()) { echo '<p><strong>Last Error:</strong></p>'; Debug::out(Error::getLast()); } echo '</div>'; exit; } # Write and close session to avoid losing changes: session_write_close(); # Perform redirect if (headers_sent()) { switch ($ctx->getLanguage()) { case RenderContext::LANG_HTML: case RenderContext::LANG_XHTML: $url = String::escapeJS($url, false); echo '<script type="text/javascript">window.location = \'' . $url . '\';</script>"'; break; default: throw new RedirectorException('Cannot redirect - headers sent and invalid render context.'); } } else { if ($permanent) { header('HTTP/1.1 301 Moved Permanently'); } header('Location: ' . $url); } # Output message just in case we have a silly browser [RFC2616] if (isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] != 'HEAD') { switch ($ctx->getLanguage()) { case RenderContext::LANG_HTML: case RenderContext::LANG_XHTML: printf('Redirecting to: <a href="%s">%s</a>.', $url, String::escapeHTML($url)); break; default: # Ignore } } # We've redirected, so stop executing now exit; }
/** * Outputs the HTML head of the page. */ public static function outputHead() { # HTTP Headers self::outputHeaders(); # XML declaration and doctype (if required). echo RenderContext::get()->renderPreContent(); # Opening <html> and <head> tags self::outputOpeningTags(); # Any <meta> tags self::outputMetaTags(); # page title self::outputTitleTag(); # links self::outputLinkTags(); # stylesheets self::outputStylesheetTags(); # external scripts self::outputExternalScriptTags(); # favicons self::outputFaviconTags(); self::outputEndHead(); }
/** * */ public function setUp() { Template::setPath(DATA_DIR . 'templates'); RenderContext::set(RenderContext::create(RenderContext::TYPE_HTML4_STRICT)); }
/** * @dataProvider truncateProvider() */ public function testTruncate($text, $length, $boundary, $ellipsis, $extension, $text_mode, $expected) { if ($text_mode) { $ctx = new RenderContext(); $ctx->setLanguage(RenderContext::LANG_TEXT); RenderContext::push($ctx); } else { $this->assertSame(RenderContext::get()->getLanguage(), RenderContext::LANG_HTML, 'Wrong RenderContext!'); } $this->assertSame($expected, String::truncate($text, $length, $boundary, $ellipsis, $extension)); if ($text_mode) { RenderContext::pop(); } }
/** * @dataProvider isXMLSyntaxProvider */ public function testIsXMLSyntax($language, $expected) { $ctx = new RenderContext($language); $this->assertSame($expected, $ctx->isXMLSyntax()); }
/** * Outputs the information in the correct format. * * @param bool $verbose Whether to output full information. * * @return string The benchmark data up to the current point. */ protected static function output($verbose = false) { # Choose comment string based on render context. $ctx = RenderContext::get(); switch ($ctx->getLanguage()) { case RenderContext::LANG_HTML: case RenderContext::LANG_XHTML: $prefix = '<!-- Benchmark:'; $postfix = '-->'; break; case RenderContext::LANG_JS: case RenderContext::LANG_CSS: $prefix = '/*** Benchmark:'; $postfix = '***/'; break; default: throw new BenchmarkException('Unsupported render context.'); } # Retrieve required data. $a =& self::$data[0]; $b =& self::$data[count(self::$data) - 1]; # Calculate time differences. $real = $b['time']['real'] - $a['time']['real']; $user = $b['time']['user'] - $a['time']['user']; $system = $b['time']['system'] - $a['time']['system']; # Generate output. $output = $prefix; if ($verbose) { $output .= PHP_EOL . ' '; $output .= sprintf('Time: %.5fs real, %.5fs user, %.5fs system', $real, $user, $system); if (isset($b['memory'])) { $output .= PHP_EOL . ' '; $output .= sprintf('Memory: %s current, %s peak', String::formatBytes($b['memory']['current'], false, null, 2), String::formatBytes($b['memory']['peak'], false, null, 2)); } $output .= PHP_EOL . ' '; $output .= sprintf('Queries: %d', $b['query']['count']); if (isset($b['cache'])) { $output .= PHP_EOL . ' '; $output .= sprintf('Cache: %d hits, %d misses, %s used, %s available', $b['cache']['hits'], $b['cache']['misses'], String::formatBytes($b['cache']['memory_used'], false, null, 2), String::formatBytes($b['cache']['memory_limit'], false, null, 2)); } $output .= ' '; } else { $output .= ' '; $output .= sprintf('Time: %.5fs', $real); $output .= '; '; $output .= sprintf('Memory: %s', String::formatBytes($b['memory']['peak'], false, null, 2)); $output .= '; '; $output .= sprintf('Queries: %d', $b['query']['count']); $output .= ' '; } $output .= $postfix . PHP_EOL; if (self::$print) { echo $output; } return $output; }
/** * */ public function setUp() { RenderContext::set(RenderContext::create(RenderContext::TYPE_HTML4_STRICT)); }
/** * Truncates a string to a specified length. Can choose whether to have an * ellipsis displayed. Can also preserve the extension of a filename, which * will force the ellipsis to prevent confusion. * * @param string $text The text to truncate. * @param integer $length The amount of text to show. * @param boolean $boundary Truncate at word boundary * @param boolean $ellipsis Whether to show an ellipsis. * @param boolean $extension If a file, do we want to keep the extension. * * @return string * * @todo Preserve HTML tags and entities. * @todo Split into multiple functions: truncate, truncateFilename, truncatePath, ... */ public static function truncate($text, $length, $boundary = true, $ellipsis = true, $extension = false) { $ctx = RenderContext::get(); $text = trim($text); if (mb_strlen($text) < $length) { return $text; } if ($extension) { $pos = mb_strrpos($text, '.'); if ($pos !== false) { $extn = mb_substr($text, $pos); $length -= mb_strlen($extn); } } $tail = ''; if ($ellipsis || $extension) { switch ($ctx->getLanguage()) { case RenderContext::LANG_HTML: case RenderContext::LANG_XHTML: case RenderContext::LANG_XML: $length -= 1; $tail = '…'; break; default: $length -= 3; $tail = '...'; } } $text = mb_substr($text, 0, $length); if ($boundary) { $pos = mb_strrpos($text, ' '); if ($pos !== false) { $text = mb_substr($text, 0, $pos); } } $text .= $tail; if ($extension && isset($extn)) { $text .= $extn; } return $text; }
*/ # Don't include Jerity more than once: if (defined('JERITY_ROOT_PATH')) { trigger_error('Jerity should not be included more than once.', E_USER_WARNING); return; } # Set some constants: /** * */ define('JERITY_ROOT_PATH', rtrim(__DIR__, '/')); /** * */ define('JERITY_PHP_VERSION', '5.3'); # Check PHP version: if (version_compare(PHP_VERSION, JERITY_PHP_VERSION, '<')) { trigger_error('Jerity requires PHP ' . JERITY_PHP_VERSION . ' or later.', E_USER_ERROR); } # Enable full error reporting (including strict standards and deprecated): $_er_ = error_reporting(E_ALL | E_STRICT | E_DEPRECATED); # Include the core utility class: require_once JERITY_ROOT_PATH . '/Base.php'; # Add root folder as an autoload directory: \Jerity\Base::addAutoloadDir(JERITY_ROOT_PATH); # Set default global render context to HTML 4.01 Strict: \Jerity\Core\RenderContext::set(\Jerity\Core\RenderContext::create(\Jerity\Core\RenderContext::TYPE_HTML4_STRICT)); # Restore original error reporting: error_reporting($_er_); unset($_er_); # vim:et:ts=2:sts=2:sw=2:nowrap:ft=php:fdm=marker
/** * */ public function testModularHead() { Chrome::setLanguage('en-gb'); Chrome::setTitle('Test title'); Chrome::clearMetadata(); Chrome::addMetadata('generator', 'Jerity'); Chrome::addMetadata('description', 'Jerity test case page'); Chrome::clearStylesheets(); Chrome::addStylesheet('/css/common.css', 15); Chrome::addStylesheet('/css/blah.css', 75); Chrome::addAlternateStylesheet('/css/theme1.css', 'Theme One', true); Chrome::addAlternateStylesheet('/css/theme2.css', 'Theme Two', false); Chrome::addAlternateStylesheet('/css/theme3.css', 'Theme Three', false); Chrome::clearScripts(); Chrome::addScript('/js/scriptaculous.js', 25); Chrome::addScript('/js/prototype.js', 15); Chrome::clearIcons(); Chrome::addIcon('/favicon.ico'); Chrome::addIcon('/img/icons/favicon.png', Chrome::ICON_PNG); ob_start(); Chrome::outputHead(); $a = ob_get_clean(); ob_start(); Chrome::outputHeaders(); echo RenderContext::get()->renderPreContent(); Chrome::outputOpeningTags(); Chrome::outputMetaTags(); Chrome::outputTitleTag(); Chrome::outputLinkTags(); Chrome::outputStylesheetTags(); Chrome::outputExternalScriptTags(); Chrome::outputFaviconTags(); Chrome::outputEndHead(); $b = ob_get_clean(); $this->assertSame($a, $b); }
/** * Returns the opening or closing character sequence used to mask content for * the specified tag. * * See the following link for more information: * {@link http://www.webdevout.net/articles/escaping-style-and-script-data} * * @param string $tag A tag name. * @param bool $open Whether we want the opening or closing sequence. * * @return string The opening or closing content mask. */ public static function getContentMask($tag, $open) { $tag = strtolower($tag); $is_html = RenderContext::get()->getLanguage() === RenderContext::LANG_HTML; switch ($tag) { case 'script': if (self::isImpliedCData($tag)) { return $open ? '<!--//--><![CDATA[//><!--' : '//--><!]]>'; } elseif ($is_html) { return $open ? '<!--' : '//-->'; } case 'style': if (self::isImpliedCData($tag)) { return $open ? '<!--/*--><![CDATA[/*><!--*/' : '/*]]>*/-->'; } elseif ($is_html) { return $open ? '<!--' : '-->'; } } return ''; }
/** * Render the item using the current global rendering context, and return it * as a string. * * @return string */ public function render() { if (empty($this->message)) { return ''; } # Get the current render context. $ctx = RenderContext::get(); # Render the message appropriately switch ($ctx->getLanguage()) { case RenderContext::LANG_HTML: case RenderContext::LANG_XHTML: $output = '<div class="' . $this->type . '">'; $output .= $this->message; $output .= '</div>'; break; case RenderContext::LANG_XML: $output = '<notification type="' . $this->type . '">'; $output .= $this->message; $output .= '</notification>'; break; default: # TODO: Throw exception as we don't know how to render? $output = ''; } return $output; }