: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
namespace Nextend\Framework\WordPress;
use Nextend\Framework\Asset\AssetManager;
use Nextend\Framework\Pattern\SingletonTrait;
use Nextend\WordPress\OutputBuffer;
private static $cssComment = '<!--n2css-->';
private $headTokens = array();
private $useAlternativeAction = false;
protected function init() {
$this->useAlternativeAction = true;
if (defined('WP_CLI') && WP_CLI) {
//Do not start output buffering while WP_CLI active
$this->outputBuffer = OutputBuffer::getInstance();
if (defined('SMART_SLIDER_OB_START') && SMART_SLIDER_OB_START >= 0) {
$this->outputBuffer->setExtraObStart(SMART_SLIDER_OB_START);
$this->addInjectCSSComment();
add_filter('wordpress_prepare_output', array(
public function prepareOutput($buffer) {
if (!empty($this->css)) {
$n2cssPos = strpos($buffer, self::$cssComment);
if ($n2cssPos !== false) {
$buffer = substr_replace($buffer, $this->css, $n2cssPos, strlen(self::$cssComment));
$parts = preg_split('/<\/head[\s]*>/i', $buffer, 2);
// There might be no head and it would result a notice.
if (count($parts) == 2) {
list($head, $body) = $parts;
* We must tokenize the HTML comments in the head to prepare for condition CSS/scripts
* Eg.: <!--[if lt IE 9]><link rel='stylesheet' href='ie8.css?ver=1.0' type='text/css' media='all'> <![endif]-->
$head = preg_replace_callback('/<!--.*?-->/s', array(
$head = preg_replace_callback('/<noscript>.*?<\/noscript>/s', array(
$lastStylesheetPosition = strrpos($head, "<link rel='stylesheet'");
if ($lastStylesheetPosition === false) {
$lastStylesheetPosition = strrpos($head, "<link rel=\"stylesheet\"");
if ($lastStylesheetPosition === false) {
$lastStylesheetPosition = strrpos($head, "<link");
if ($lastStylesheetPosition !== false) {
* Find the end of the tag <link tag
$lastStylesheetPositionEnd = strpos($head, ">", $lastStylesheetPosition);
if ($lastStylesheetPositionEnd !== false) {
* Insert CSS after the ending >
$head = substr_replace($head, $this->css, $lastStylesheetPositionEnd + 1, 0);
$head = preg_replace_callback('/<!--TOKEN([0-9]+)-->/', array(
$buffer = $head . '</head>' . $body;
if ($this->css != '' || $this->js != '') {
$parts = preg_split('/<\/head[\s]*>/', $buffer, 2);
return implode($this->css . $this->js . '</head>', $parts);
public function tokenizeHead($matches) {
$index = count($this->headTokens);
$this->headTokens[$index] = $matches[0];
return '<!--TOKEN' . $index . '-->';
public function restoreHeadTokens($matches) {
return $this->headTokens[$matches[1]];
private function finalizeCssJs() {
static $finalized = false;
if (class_exists('\\Nextend\\Framework\\Asset\\AssetManager', false)) {
$this->css = AssetManager::getCSS();
$this->js = AssetManager::getJs();
public function addInjectCSSComment() {
if (!$this->useAlternativeAction) {
add_action('wp_print_scripts', array(
* The Site editor fires the wp_print_scripts action inside a the wp.editSite.initializeEditor script.
* The Widgets editor fires the wp_print_scripts action inside a the wp.editWidgets.initialize script.
* The Customizer fires the wp_print_scripts action inside a the wp.customizeWidgets.initialize script.
add_action('admin_head', array(
public function removeInjectCSSComment() {
if (!$this->useAlternativeAction) {
remove_action('wp_print_scripts', array(
* The Site editor fires the wp_print_scripts action inside a the wp.editSite.initializeEditor script.
* The Widgets editor fires the wp_print_scripts action inside a the wp.editWidgets.initialize script.
* The Customizer fires the wp_print_scripts action inside a the wp.customizeWidgets.initialize script.
remove_action('admin_head', array(
public function injectCSSComment() {
echo wp_kses(self::$cssComment, array());