lbry.com/view/Response.class.php
2016-09-01 18:48:12 -04:00

346 lines
No EOL
8.4 KiB
PHP

<?php
/**
* Description of Response
*
* @author jeremy
*/
class Response
{
const HEADER_STATUS = 'Status';
const HEADER_LOCATION = 'Location';
const HEADER_CACHE_CONTROL = 'Cache-Control';
const HEADER_LAST_MODIFIED = 'Last-Modified';
const HEADER_ETAG = 'Etag';
const HEADER_CONTENT_TYPE = 'Content-Type';
const HEADER_CONTENT_LENGTH = 'Content-Length';
const HEADER_CONTENT_DISPOSITION = 'Content-Disposition';
const HEADER_CONTENT_TYPE_OPTIONS = 'X-Content-Type-Options';
protected static
$metaDescription = '',
$metaTitle = '',
$jsCalls = [],
$assets = [
'js' => [
'/js/jquery-2.1.3.min.js',
'/js/global.js'
],
'css' => []
],
$headers = [],
$headersSent = false,
$content = '',
$contentSent = false,
$isHeadersOnly = false,
// $bodyCssClasses = [],
$metaImages = [];
public static function setMetaDescription($description)
{
static::$metaDescription = $description;
}
public static function addMetaImage($url)
{
static::$metaImages[] = $url;
}
public static function addMetaImages(array $urls)
{
foreach ($urls as $url)
{
static::addMetaImage($url);
}
}
public static function getMetaDescription()
{
return static::$metaDescription ?: 'A Content Revolution';
}
public static function getMetaImages()
{
return static::$metaImages ?: ['https://lbry.io/img/lbry-dark-1600x528.png'];
}
public static function setMetaTitle($title)
{
static::$metaTitle = $title;
}
public static function getMetaTitle()
{
return static::$metaTitle;
}
public static function guessMetaTitle($content)
{
$title = '';
preg_match_all('/<h(1|2)[^>]*>([^<]+)</', $content, $titleMatches);
foreach ($titleMatches[1] as $matchIndex => $headerValue)
{
if ($headerValue == '1' || !$title)
{
$title = $titleMatches[2][$matchIndex];
if ($headerValue == '1')
{
return $title;
}
}
}
return $title;
}
public static function getJsCalls()
{
return static::$jsCalls;
}
public static function jsOutputCallback($js)
{
static::$jsCalls[] = $js;
return '';
}
public static function addJsAsset($src)
{
static::$assets['js'][$src] = $src;
}
public static function getJsAssets()
{
return static::$assets['js'];
}
public static function send()
{
static::sendHeaders();
static::sendContent();
}
public static function setContent(string $content)
{
static::$content = $content;
}
public static function getContent(): string
{
return static::$content;
}
public static function sendContent()
{
if (static::$contentSent)
{
throw new LogicException('Content has already been sent. It cannot be sent twice');
}
if (!static::$isHeadersOnly)
{
echo static::$content;
}
static::$contentSent = true;
}
public static function setIsHeadersOnly(bool $isHeadersOnly = true)
{
static::$isHeadersOnly = $isHeadersOnly;
}
public static function setDownloadHttpHeaders($name, $type = null, $size = null, $noSniff = true)
{
static::setHeaders(array_filter([
'Content-Disposition' => 'attachment;filename=' . $name,
'Content-Type' => $type ? 'application/zip' : null,
'Content-Length' => $size ?: null,
'X-Content-Type-Options' => $noSniff ? 'nosniff' : null,
]));
}
public static function setContentEtag()
{
static::setHeader(static::HEADER_ETAG, md5(static::getContent()));
}
public static function enableHttpCache(int $seconds = 300)
{
static::addCacheControlHeader('max-age', $seconds);
}
public static function addCacheControlHeader(string $name, $value = null)
{
$cacheControl = static::getHeader(static::HEADER_CACHE_CONTROL);
$currentHeaders = [];
if ($cacheControl)
{
foreach (preg_split('/\s*,\s*/', $cacheControl) as $tmp)
{
$tmp = explode('=', $tmp);
$currentHeaders[$tmp[0]] = isset($tmp[1]) ? $tmp[1] : null;
}
}
$currentHeaders[strtr(strtolower($name), '_', '-')] = $value;
$headers = [];
foreach ($currentHeaders as $key => $currentVal)
{
$headers[] = $key . ($currentVal !== null ? '=' . $currentVal : '');
}
static::setHeader(static::HEADER_CACHE_CONTROL, implode(', ', $headers));
}
public static function setHeader($name, $value)
{
static::$headers[$name] = $value;
}
public static function setHeaders($headers, $overwrite = true)
{
foreach ($headers as $name => $value)
{
if ($overwrite || !static::getHeader($name))
{
static::setHeader($name, $value);
}
}
}
public static function getHeader($name, $default = null)
{
return isset(static::$headers[$name]) ? static::$headers[$name] : $default;
}
public static function getHeaders(): array
{
return static::$headers;
}
public static function setStatus($status)
{
static::setHeader(static::HEADER_STATUS, $status);
}
public static function setDefaultSecurityHeaders()
{
$defaultHeaders = [
'Content-Security-Policy' => "frame-ancestors 'none'",
'X-Frame-Options' => 'DENY',
'X-XSS-Protection' => '1',
];
if (IS_PRODUCTION)
{
$defaultHeaders['Strict-Transport-Security'] = 'max-age=31536000';
}
static::setHeaders($defaultHeaders, false);
}
public static function sendHeaders()
{
if (static::$headersSent)
{
throw new LogicException('Headers have already been sent. They cannot be sent twice');
}
$headers = static::getHeaders();
if (isset($headers[static::HEADER_STATUS]))
{
$status = 'HTTP/1.0 ' . $headers[static::HEADER_STATUS] . ' ' . static::getStatusTextForCode($headers[static::HEADER_STATUS]);
header($status);
if (substr(php_sapi_name(), 0, 3) == 'cgi')
{
// fastcgi servers cannot send this status information because it was sent by them already due to the HTT/1.0 line
// so we can safely unset them. see ticket #3191
unset($headers[static::HEADER_STATUS]);
}
}
foreach ($headers as $name => $value)
{
header($name . ': ' . $value);
}
static::$headersSent = true;
}
public static function getStatusTextForCode($code)
{
$statusTexts = [
'100' => 'Continue',
'101' => 'Switching Protocols',
'200' => 'OK',
'201' => 'Created',
'202' => 'Accepted',
'203' => 'Non-Authoritative Information',
'204' => 'No Content',
'205' => 'Reset Content',
'206' => 'Partial Content',
'300' => 'Multiple Choices',
'301' => 'Moved Permanently',
'302' => 'Found',
'303' => 'See Other',
'304' => 'Not Modified',
'305' => 'Use Proxy',
'306' => '(Unused)',
'307' => 'Temporary Redirect',
'400' => 'Bad Request',
'401' => 'Unauthorized',
'402' => 'Payment Required',
'403' => 'Forbidden',
'404' => 'Not Found',
'405' => 'Method Not Allowed',
'406' => 'Not Acceptable',
'407' => 'Proxy Authentication Required',
'408' => 'Request Timeout',
'409' => 'Conflict',
'410' => 'Gone',
'411' => 'Length Required',
'412' => 'Precondition Failed',
'413' => 'Request Entity Too Large',
'414' => 'Request-URI Too Long',
'415' => 'Unsupported Media Type',
'416' => 'Requested Range Not Satisfiable',
'417' => 'Expectation Failed',
'419' => 'Authentication Timeout',
'422' => 'Unprocessable Entity',
'426' => 'Upgrade Required',
'429' => 'Too Many Requests',
'500' => 'Internal Server Error',
'501' => 'Not Implemented',
'502' => 'Bad Gateway',
'503' => 'Service Unavailable',
'504' => 'Gateway Timeout',
'505' => 'HTTP Version Not Supported',
];
return isset($statusTexts[$code]) ? $statusTexts[$code] : null;
}
protected static function normalizeHeaderName($name)
{
return preg_replace_callback(
'/\-(.)/',
function ($matches) { return '-' . strtoupper($matches[1]); },
strtr(ucfirst(strtolower($name)), '_', '-')
);
}
// public static function addBodyCssClass($classOrClasses)
// {
// static::$bodyCssClasses = array_unique(array_merge(static::$bodyCssClasses, (array)$classOrClasses));
// }
//
// public static function getBodyCssClasses()
// {
// return static::$bodyCssClasses;
// }
}