Skip to content

Commit

Permalink
Handle htaccess file according to burst safety mode
Browse files Browse the repository at this point in the history
  • Loading branch information
AleTorrisi committed Dec 18, 2024
1 parent 7366b50 commit fc14784
Show file tree
Hide file tree
Showing 7 changed files with 328 additions and 1 deletion.
2 changes: 2 additions & 0 deletions bootstrap.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,5 @@ function ( $features ) {
}

new PerformanceFeatureHooks();

require_once __DIR__ . '/includes/BurstSafetyMode/init.php';
59 changes: 59 additions & 0 deletions includes/BurstSafetyMode/Browser.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?php
namespace NewfoldLabs\WP\Module\Performance\BurstSafetyMode;
use NewfoldLabs\WP\Module\Performance\BurstSafetyMode\ResponseHeaderManager;
use WP_Forge\WP_Htaccess_Manager\htaccess;

class Browser {
/**
* The file marker name.
*
* @var string
*/
const MARKER = 'Newfold Browser Cache';

public function __construct() {
$responseHeaderManager = new ResponseHeaderManager();
$responseHeaderManager->addHeader( 'X-Newfold-Cache-Level', BURST_SAFETY_CACHE_LEVEL );
$this->addRules();
}

/**
* Add htaccess rules.
*
* @return void
*/
public static function addRules() {

$file_typ_expirations = array(
'default' => '1 week',
'text/html' => '8 hours',
'image/jpg' => '1 week',
'image/jpeg' => '1 week',
'image/gif' => '1 week',
'image/png' => '1 week',
'text/css' => '1 week',
'text/javascript' => '1 week',
'application/pdf' => '1 month',
'image/x-icon' => '1 year',
);

$tab = "\t";

$rules[] = '<IfModule mod_expires.c>';
$rules[] = "{$tab}ExpiresActive On";

foreach ( $file_typ_expirations as $file_type => $expiration ) {
if ( 'default' === $file_type ) {
$rules[] = "{$tab}ExpiresDefault \"access plus {$expiration}\"";
} else {
$rules[] = "{$tab}ExpiresByType {$file_type} \"access plus {$expiration}\"";
}
}

$rules [] = '</IfModule>';

$htaccess = new htaccess( self::MARKER );

return $htaccess->addContent( $rules );
}
}
116 changes: 116 additions & 0 deletions includes/BurstSafetyMode/ResponseHeaderManager.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
<?php

namespace NewfoldLabs\WP\Module\Performance\BurstSafetyMode;

use WP_Forge\WP_Htaccess_Manager\htaccess;
use function WP_Forge\WP_Htaccess_Manager\convertContentToLines;

class ResponseHeaderManager {

/**
* The file marker name.
*
* @var string
*/
const MARKER = 'Newfold Headers';

public $htaccess;

/**
* Constructor.
*/
public function __construct() {
$this->htaccess = new htaccess( self::MARKER );
}

/**
* Parse existing headers.
*
* @return array
*/
public function parseHeaders() {

$headers = array();

$content = $this->htaccess->readContent();
$lines = array_map( 'trim', convertContentToLines( $content ) );

array_shift( $lines ); // Remove opening IfModule
array_pop( $lines ); // Remove closing IfModule

$pattern = '/^Header set (.*) "(.*)"$/';

foreach ( $lines as $line ) {
if ( preg_match( $pattern, trim( $line ), $matches ) && isset( $matches[1], $matches[2] ) ) {
$headers[ $matches[1] ] = $matches[2];
}
}

return $headers;
}

/**
* Add a header.
*
* @param string $name Header name
* @param string $value Header value
*/
public function addHeader( string $name, string $value ) {
$this->setHeaders(
array_merge(
$this->parseHeaders(),
array( $name => $value )
)
);
}

/**
* Add multiple headers at once.
*
* @param string[] $headers
*/
public function addHeaders( array $headers ) {
$headers = array_merge( $this->parseHeaders(), $headers );
$this->setHeaders( $headers );
}

/**
* Remove a header.
*
* @param string $name Header name
*/
public function removeHeader( $name ) {
$headers = $this->parseHeaders();
unset( $headers[ $name ] );
$this->setHeaders( $headers );
}

/**
* Remove all headers.
*/
public function removeAllHeaders() {
$this->setHeaders( array() );
}

/**
* Set headers.
*
* @param array $headers
*/
public function setHeaders( array $headers ) {

if ( empty( $headers ) ) {
$this->htaccess->removeContent();

return;
}

$content = '<IfModule mod_headers.c>' . PHP_EOL;
foreach ( $headers as $key => $value ) {
$content .= "\t" . "Header set {$key} \"{$value}\"" . PHP_EOL;
}
$content .= '</IfModule>';

$this->htaccess->addContent( $content );
}
}
45 changes: 45 additions & 0 deletions includes/BurstSafetyMode/Skip404.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php
namespace NewfoldLabs\WP\Module\Performance\BurstSafetyMode;
use function WP_Forge\WP_Htaccess_Manager\addContent;
use function WP_Forge\WP_Htaccess_Manager\removeMarkers;

class Skip404 {
/**
* The file marker name.
*/
const MARKER = 'Newfold Skip 404 Handling for Static Files';

/**
* Constructor.
*/
public function __construct() {

$this->addRules();
}


/**
* Add our rules to the .htacces file.
*/
public static function addRules() {
$content = <<<HTACCESS
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !(robots\.txt|ads\.txt|[a-z0-9_\-]*sitemap[a-z0-9_\.\-]*\.(xml|xsl|html)(\.gz)?)
RewriteCond %{REQUEST_URI} \.(css|htc|less|js|js2|js3|js4|html|htm|rtf|rtx|txt|xsd|xsl|xml|asf|asx|wax|wmv|wmx|avi|avif|avifs|bmp|class|divx|doc|docx|eot|exe|gif|gz|gzip|ico|jpg|jpeg|jpe|webp|json|mdb|mid|midi|mov|qt|mp3|m4a|mp4|m4v|mpeg|mpg|mpe|webm|mpp|otf|_otf|odb|odc|odf|odg|odp|ods|odt|ogg|ogv|pdf|png|pot|pps|ppt|pptx|ra|ram|svg|svgz|swf|tar|tif|tiff|ttf|ttc|_ttf|wav|wma|wri|woff|woff2|xla|xls|xlsx|xlt|xlw|zip)$ [NC]
RewriteRule .* - [L]
</IfModule>
HTACCESS;

addContent( self::MARKER, $content );
}

/**
* Remove our rules from the .htaccess file.
*/
public static function removeRules() {
removeMarkers( self::MARKER );
}
}
61 changes: 61 additions & 0 deletions includes/BurstSafetyMode/init.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<?php

use NewfoldLabs\WP\Module\Performance\BurstSafetyMode\Skip404 as BurstSkip404;
use NewfoldLabs\WP\Module\Performance\BurstSafetyMode\Browser as BurstBrowser;
use NewfoldLabs\WP\Module\Performance\CacheTypes\Browser as CacheBrowser;
use NewfoldLabs\WP\Module\Performance\CacheTypes\Skip404 as CacheSkip404;
use NewfoldLabs\WP\Module\Performance\ResponseHeaderManager;


$newfold_burst_safety_mode = (bool) get_option( 'newfold_burst_safety_mode', false );
$newfold_cache_level = (int) get_option( 'newfold_cache_level', 0 );

// Check if Performance feature is enabled and it's necessary reset the cache options
if ( class_exists( 'NewfoldLabs\WP\Module\Performance\PerformanceFeatureHooks' ) ) {
if ( $newfold_burst_safety_mode ) {
$browser = new CacheBrowser();
$browser::maybeAddRules( $newfold_cache_level );

$skip_404_handling = (bool) get_option( 'newfold_skip_404_handling', true );

if ( ! $skip_404_handling ) {
$skip404 = new CacheSkip404();
$skip404::maybeAddRules( false );
}

$responseHeaderManager = new ResponseHeaderManager();
$responseHeaderManager->addHeader( 'X-Newfold-Cache-Level', $newfold_cache_level );

delete_option( 'newfold_burst_safety_mode' );
}
} else {
if ( ! $newfold_burst_safety_mode ) {
$files_to_include = array(
'htaccess' => BLUEHOST_PLUGIN_DIR . 'vendor/wp-forge/wp-htaccess-manager/includes/htaccess.php',
'htaccess_functions' => BLUEHOST_PLUGIN_DIR . 'vendor/wp-forge/wp-htaccess-manager/includes/functions.php',
'skip404' => BLUEHOST_PLUGIN_DIR . 'vendor/newfold-labs/wp-module-performance/includes/BurstSafetyMode/Skip404.php',
'browser' => BLUEHOST_PLUGIN_DIR . 'vendor/newfold-labs/wp-module-performance/includes/BurstSafetyMode/browser.php',
'response_header_manager' => BLUEHOST_PLUGIN_DIR . 'vendor/newfold-labs/wp-module-performance/includes/BurstSafetyMode/ResponseHeaderManager.php',
);

foreach ( $files_to_include as $path ) {
if ( file_exists( $path ) ) {
require_once $path;
}
}

define( 'BURST_SAFETY_CACHE_LEVEL', 3 );

$skip_404_handling = (bool) get_option( 'newfold_skip_404_handling', true );

if ( ! $skip_404_handling && class_exists( BurstSkip404::class ) ) {
$skip404 = new BurstSkip404();
}

if ( BURST_SAFETY_CACHE_LEVEL !== $newfold_cache_level && class_exists( BurstBrowser::class ) ) {
$browser = new BurstBrowser();
}

update_option( 'newfold_burst_safety_mode', true );
}
}
44 changes: 44 additions & 0 deletions includes/burstSafetyModeFunctions.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php
namespace NewfoldLabs\WP\Module\Performance;
use NewfoldLabs\WP\Module\Performance\CacheTypes\Browser;
use NewfoldLabs\WP\Module\Performance\CacheTypes\Skip404;
use NewfoldLabs\WP\Module\Performance\ResponseHeaderManager;

$newfold_burst_safety_mode = (bool) get_option( 'newfold_burst_safety_mode' );

$site_cache_level = get_option( 'newfold_cache_level', 3 );
$site_skip404 = (bool) get_option( 'newfold_skip_404_handling', true );

if ( $newfold_burst_safety_mode === false ) {

}else{

}

if ( defined( 'BURST_SAFETY_MODE' ) && BURST_SAFETY_MODE ) {
if ( $newfold_burst_safety_mode === false ) {
$current_level = get_option( Performance::OPTION_CACHE_LEVEL );
update_option( 'newfold_burst_safety_mode', true );
update_option( 'newfold_burst_safety_mode_site_cache_level', $current_level );
$browser = new Browser();
$browser::maybeAddRules( 3 );
if( function_exists( 'getSkip404Option' ) && ! getSkip404Option() ) {
$skip404 = new Skip404();
$skip404::maybeAddRules( true );
}
$responseHeaderManager = new ResponseHeaderManager();
$responseHeaderManager->addHeader( 'X-Newfold-Cache-Level', 3 );
}
} elseif ( $newfold_burst_safety_mode ) {
$cache_level = get_option( 'newfold_burst_safety_mode_site_cache_level' );
$browser = new Browser();
$browser::maybeAddRules( $cache_level );
if( function_exists( 'getSkip404Option' ) && ! getSkip404Option() ) {
$skip404 = new Skip404();
$skip404::maybeAddRules( false );
}
$responseHeaderManager = new ResponseHeaderManager();
$responseHeaderManager->addHeader( 'X-Newfold-Cache-Level', $cache_level );
delete_option( 'newfold_burst_safety_mode' );
delete_option( 'newfold_burst_safety_mode_site_cache_level' );
}
2 changes: 1 addition & 1 deletion tests/cypress/integration/performance.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ describe( 'Performance Page', function () {
} );

it( 'Is Accessible', () => {
cy.wait( 1000 );
cy.wait( 2000 );
cy.checkA11y( appClass + '-app-body' );
} );

Expand Down

0 comments on commit fc14784

Please sign in to comment.