| 
<?php//declare(strict_types=1);
 
 use Monolog\Handler\StreamHandler;
 use Monolog\Logger;
 use PageCache\PageCache;
 use PageCache\Tests\Integration\IntegrationWebServerTest;
 use Symfony\Component\Cache\Simple\FilesystemCache;
 
 ini_set('display_errors', 1);
 
 $docRoot = __DIR__;
 $libRoot = dirname(__DIR__.'/../../../../');
 
 require $libRoot.'/vendor/autoload.php';
 
 $logsDirectory  = $docRoot.'/logs';
 $cacheDirectory = $docRoot.'/cache';
 
 if (!file_exists($cacheDirectory) && !mkdir($cacheDirectory, 0777) && !is_dir($cacheDirectory)) {
 throw new Exception('Can not create cache directory');
 }
 
 if (!file_exists($logsDirectory) && !mkdir($logsDirectory, 0777) && !is_dir($logsDirectory)) {
 throw new RuntimeException('Can not create logs directory');
 }
 
 // Detect content file and query parameters
 $uri         = $_SERVER['REQUEST_URI'];
 $path        = parse_url($uri, PHP_URL_PATH);
 $contentFile = $docRoot.$path;
 
 parse_str(parse_url($uri, PHP_URL_QUERY), $query);
 $cacheName  = (string)$query[IntegrationWebServerTest::CACHE_TYPE_KEY];
 $loggerName = (string)$query[IntegrationWebServerTest::LOGGER_KEY];
 $clearCache = (bool)$query[IntegrationWebServerTest::CACHE_CLEAR_KEY];
 $redirect   = (bool)$query[IntegrationWebServerTest::REDIRECT_KEY];
 
 // Redirect to the same page if needed
 if ($redirect) {
 $redirectKey = IntegrationWebServerTest::REDIRECT_KEY;
 // Prevent endless redirects
 $uri = str_replace($redirectKey.'=1', $redirectKey.'=0', $uri);
 header('Location: '.$uri);
 }
 
 // Clear query string so default strategy would not rely on test configuration parameters
 $_SERVER['QUERY_STRING'] = null;
 
 // Instance with default configuration
 $pc = new PageCache();
 
 // Common configuration
 $pc->config()
 // 60 seconds is enough for testing both concurrency and single requests
 ->setCacheExpirationInSeconds(60)
 ->setLogFilePath($logsDirectory.'/page-cache.log')
 ->setEnableLog(true)
 ->setUseSession(true)
 ->setForwardHeaders(true)
 ->setSendHeaders(true);
 
 setCacheImplementation($pc, $cacheName, $cacheDirectory);
 setLoggerImplementation($pc, $loggerName, $logsDirectory);
 
 // Clear cache if needed (trying to create race conditions on empty cache)
 if ($clearCache) {
 $pc->clearAllCache();
 }
 
 // Initialize
 $pc->init();
 
 // Send headers (Last-Modified, Expires)
 $lastModifiedTimestamp = filemtime($contentFile);
 $expiresInTimestamp    = time() + $pc->config()->getCacheExpirationInSeconds();
 
 header('Last-Modified: '.gmdate("D, d M Y H:i:s \G\M\T", $lastModifiedTimestamp));
 header('Expires: '.gmdate("D, d M Y H:i:s \G\M\T", $expiresInTimestamp));
 
 // Send content
 include $contentFile;
 
 
 function setCacheImplementation(PageCache $pc, $name, $cacheDirectory)
 {
 if (!$name) {
 throw new RuntimeException('No cache implementation set');
 }
 
 switch ($name) {
 case IntegrationWebServerTest::CACHE_TYPE_INTERNAL:
 // Internal cache is used by default, needs only directory to set
 $pc->config()->setCachePath($cacheDirectory.DIRECTORY_SEPARATOR);
 break;
 
 case IntegrationWebServerTest::CACHE_TYPE_SYMFONY_FILESYSTEM:
 // Using basic symfony/cache
 $ttl          = $pc->config()->getCacheExpirationInSeconds() * 2;
 $cacheAdapter = new FilesystemCache('symfony-cache', $ttl, $cacheDirectory);
 $pc->setCacheAdapter($cacheAdapter);
 break;
 
 default:
 throw new RuntimeException('Unknown cache implementation key: '.$name);
 }
 }
 
 function setLoggerImplementation(PageCache $pc, $name, $logsDirectory)
 {
 if (!$name) {
 throw new RuntimeException('No logger implementation set');
 }
 
 switch ($name) {
 case IntegrationWebServerTest::LOGGER_INTERNAL:
 // Internal logger is used by default, needs only cache file to set
 $pc->config()->setLogFilePath($logsDirectory.DIRECTORY_SEPARATOR.'page-cache.internal.log');
 break;
 
 case IntegrationWebServerTest::LOGGER_MONOLOG:
 $logger = new Logger('default');
 $logger->pushHandler(new StreamHandler($logsDirectory.DIRECTORY_SEPARATOR.'page-cache.monolog.log'));
 
 $pc->setLogger($logger);
 break;
 
 default:
 throw new RuntimeException('Unknown logger implementation key: '.$name);
 }
 }
 
 
 |