vinkla / wordplate

A boilerplate for WordPress, built with Composer and designed with sensible defaults.
2.11k stars 155 forks source link

Broken compatibility with caching plugins #242

Closed lkaisers closed 4 years ago

lkaisers commented 4 years ago

Expected Behavior

I can activate any caching plugin running WordPlate behind.

Actual Behavior

My site gets broken because almost every caching plugin defines the WP_CACHE var at the beginning of wp-config.php.

"Fatal error: strict_types declaration must be the very first statement in the script"

Steps to Reproduce the Problem

  1. Install and activate a caching plugin

Versions

vinkla commented 4 years ago

Thanks for reporting @lkaisers!

Do you think we could solve this by adding the WP_CACHE constant to the framework by default? Do the cache plugins check if the constant is defined before adding it to the wp-config.php file?


Sidenote: I know this is common in the WordPress community but I would say that any plugin writing to a PHP file should rethink their logic. It isn't safe to write to other PHP-files and it should not be allowed.

lkaisers commented 4 years ago

Thanks for your fast response! I checked the plugin files and they check for the constant in wp-config.php but I don't know if they only watch the first line. I tried to declare the variable in the .env file as well but that didn't solve the issue. I will do further checks (declare at the bottom) and notify you if I experienced sth new.

Question: What is the declare strict types thing for?

All in all I see it exactly as you do. Plugins should not just write anything to core files, especially at the beginning of the file.

Thank you for the support.

vinkla commented 4 years ago

I checked the plugin files and they check for the constant in wp-config.php but I don't know if they only watch the first line.

Could you please share a link to the code?

I tried to declare the variable in the .env file as well but that didn't solve the issue.

In order to make it work in the .env file we need to register it in the Application.php class.

Question: What is the declare strict types thing for?

https://stackoverflow.com/a/48723830

lkaisers commented 4 years ago

The check for the WP_CACHE constant is made in the plugin files of WP Rocket, relative to the plugin root directory in /inc/functions/files.php. You can also find the file contents at https://github.com/wp-media/wp-rocket/blob/master/inc/functions/files.php

/**
 * Added or set the value of the WP_CACHE constant
 *
 * @since 2.0
 *
 * @param bool $turn_it_on The value of WP_CACHE constant.
 * @return void
 */
function set_rocket_wp_cache_define( $turn_it_on ) {
    // If WP_CACHE is already define, return to get a coffee.
    if ( ! rocket_valid_key() || ( $turn_it_on && defined( 'WP_CACHE' ) && WP_CACHE ) ) {
        return;
    }

    if ( defined( 'IS_PRESSABLE' ) && IS_PRESSABLE ) {
        return;
    }

    // Get path of the config file.
    $config_file_path = rocket_find_wpconfig_path();
    if ( ! $config_file_path ) {
        return;
    }

    // Get content of the config file.
    $config_file = file( $config_file_path );

    // Get the value of WP_CACHE constant.
    $turn_it_on = $turn_it_on ? 'true' : 'false';

    /**
     * Filter allow to change the value of WP_CACHE constant
     *
     * @since 2.1
     *
     * @param string $turn_it_on The value of WP_CACHE constant.
    */
    $turn_it_on = apply_filters( 'set_rocket_wp_cache_define', $turn_it_on );

    // Lets find out if the constant WP_CACHE is defined or not.
    $is_wp_cache_exist = false;

    // Get WP_CACHE constant define.
    $constant = "define('WP_CACHE', $turn_it_on); // Added by WP Rocket" . "\r\n";

    foreach ( $config_file as &$line ) {
        if ( ! preg_match( '/^define\(\s*\'([A-Z_]+)\',(.*)\)/', $line, $match ) ) {
            continue;
        }

        if ( 'WP_CACHE' === $match[1] ) {
            $is_wp_cache_exist = true;
            $line              = $constant;
        }
    }
    unset( $line );

    // If the constant does not exist, create it.
    if ( ! $is_wp_cache_exist ) {
        array_shift( $config_file );
        array_unshift( $config_file, "<?php\r\n", $constant );
    }

    // Insert the constant in wp-config.php file.
    $handle = @fopen( $config_file_path, 'w' );
    foreach ( $config_file as $line ) {
        @fwrite( $handle, $line );
    }

    @fclose( $handle );

    // Update the writing permissions of wp-config.php file.
    $chmod = rocket_get_filesystem_perms( 'file' );
    rocket_direct_filesystem()->chmod( $config_file_path, $chmod );
}
vinkla commented 4 years ago

Great! Would you mind submitting a pull request to wordplate/framework adding the WP_CACHE constant? If not, I can add it to the next release. Let me know.

lkaisers commented 4 years ago

Perfect. It's the first time I submit a pull request but I'll try. Thank you!

vinkla commented 4 years ago

Closed in https://github.com/wordplate/framework/pull/93