<?php namespace WPDataAccess\Macro { class WPDA_Macro { protected $raw_code = null; protected $raw_array = array(); protected $has_macros = false; public function __construct( $raw_code ) { $this->raw_code = $raw_code; if ( null !== $this->raw_code && '' !== str_replace( ' ', '', $this->raw_code ) ) { $this->raw_array = explode( "\n", $this->raw_code );//phpcs:ignore - 8.1 proof if ( is_array( $this->raw_array ) && count( $this->raw_array ) > 2 ) {//phpcs:ignore - 8.1 proof $this->has_macros = true; } } } public function exe_macro() { if ( $this->has_macros ) { $code = $this->macro_if( $this->raw_array ); return implode( ' ', $code ); } else { return $this->raw_code; } } protected function macro_if( $code_array ) { if ( ! is_array( $code_array ) ) { return $code_array; } $codeif = array(); $totalifs = 0; for ( $line = 0; $line < count( $code_array ); $line++ ) {//phpcs:ignore - 8.1 proof $code = $code_array[ $line ]; if ( $this->is_macro( 'if', $code ) ) { $totalifs++; // Process macro if $line_start = $line; $line_else = -1; $line_end = $line; // prevent PHP errors $ifs_found = 1; for ( $i = $line + 1; $i < count( $code_array ); $i++ ) {//phpcs:ignore - 8.1 proof if ( $this->is_macro( 'if', $code_array[ $i ] ) ) { $ifs_found++; } if ( $this->is_macro( 'else', $code_array[ $i ] ) ) { if ( 1 === $ifs_found ) { $line_else = $i; } } if ( $this->is_macro( 'endif', $code_array[ $i ] ) ) { if ( 1 === $ifs_found ) { $line_end = $i; } else { $ifs_found--; } } } if ( -1 === $line_else ) { // Get code between if and end if $code_slice = array_slice( $code_array, $line_start + 1, $line_end - $line_start - 1 );//phpcs:ignore - 8.1 proof } else { // Get code between if and else $code_slice = array_slice( $code_array, $line_start + 1, $line_else - $line_start - 1 );//phpcs:ignore - 8.1 proof // Get code between else and end if $code_else = array_slice( $code_array, $line_else + 1, $line_end - $line_else - 1 );//phpcs:ignore - 8.1 proof } // Process nested ifs $code_slice = $this->macro_if( $code_slice ); $condition = null; foreach ( array( '==', '!=', '<', '>' ) as $c ) { // Handle each condition individually in macro_if_check if ( $this->macro_if_has( $code, $c, $condition ) ) { if ( $this->macro_if_check( $condition, $c ) ) { $codeif = array_merge( $codeif, $code_slice );//phpcs:ignore - 8.1 proof } else { if ( $line_else > -1 ) { $codeif = array_merge( $codeif, $code_else );//phpcs:ignore - 8.1 proof } } $line = $line_end; break; } } } else { $codeif = array_merge( $codeif, array( $code_array[ $line ] ) );//phpcs:ignore - 8.1 proof } } if ( $totalifs === 0 ) { return $code_array; } else { return $codeif; } } protected function macro_if_has( $code, $if, &$condition ) { $condition = explode( $if, html_entity_decode( substr( str_replace( ' ', '', (string ) $code ), 8 ) ) );//phpcs:ignore - 8.1 proof return is_array( $condition ) && count( $condition ) === 2;//phpcs:ignore - 8.1 proof } protected function macro_if_check( $condition, $if ) { switch ( $if ) { case '=='; return is_array( $condition ) && count( $condition ) === 2 && $condition[0] == $condition[1];//phpcs:ignore - 8.1 proof break; case '!='; return is_array( $condition ) && count( $condition ) === 2 && $condition[0] != $condition[1];//phpcs:ignore - 8.1 proof break; case '<'; return is_array( $condition ) && count( $condition ) === 2 && $condition[0] < $condition[1];//phpcs:ignore - 8.1 proof break; case '>'; return is_array( $condition ) && count( $condition ) === 2 && $condition[0] > $condition[1];//phpcs:ignore - 8.1 proof break; } } protected function is_macro( $macro, $code ) { return "#macro{$macro}" === substr( str_replace( ' ', '', $code ), 0, strlen( "#macro{$macro}" ) ); } } }