: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
* Class handling the ad positioning and migrating values from previous solutions.
class Advanced_Ads_Ad_Positioning {
* The instance of the current ad.
* The structure of these output options.
* @param Advanced_Ads_Ad $ad The current ad object.
public function __construct( Advanced_Ads_Ad $ad ) {
* Migrate option from a previous solution where floating was an additional setting.
private function migrate_values() {
$options = $this->get_options();
$this->positioning['margin'] = array_merge(
$this->positioning['margin'],
array_map( function($value) { return (int)$value; }, $options['margin'] )
$this->positioning['position'] = $options['position'];
// instead of having an empty value, set an explicit default.
if ( empty( $this->positioning['position'] ) ) {
$this->positioning['position'] = 'none';
$this->positioning['clearfix'] = false;
// left, center, right are the old values, if it's none of these we've already migrated.
if ( ! in_array( $this->positioning['position'], [ 'left', 'center', 'right' ], true ) ) {
// ensure we get an array with min two elements.
$position = explode( '_', $this->positioning['position'] . '_' );
// explicitly set clearfix option.
$this->positioning['clearfix'] = $position[0] !== 'center' && $position[1] === 'nofloat';
if ( $this->positioning['position'] === 'center' ) {
$this->positioning['position'] = 'center_nofloat';
$this->positioning['clearfix'] = ! empty( $options['clearfix'] );
$this->positioning['position'] .= $this->positioning['clearfix'] ? '_nofloat' : '_float';
* Filter the option value for Advanced_Ads_Ad.
* This ensures we don't have to update the whole positioning process but can change only the wp-admin side of things.
private function filter_values() {
foreach ( $this->positioning as $key => $value ) {
add_filter( "advanced-ads-ad-option-output.{$key}", function() use ( $value ) {
if ( is_array( $value ) ) {
foreach ( $value as $sub_key => $sub_value ) {
add_filter( "advanced-ads-ad-option-output.{$sub_key}", function() use ( $sub_value ) {
* Set up the positioning options with title, description and icon.
private function setup_positioning_options() {
'title' => __( "Theme’s Default", 'advanced-ads' ),
'description' => __( 'The ad will behave as predefined by the theme.', 'advanced-ads' ),
'title' => _x( 'Float', 'Layout options "Text Flow" heading', 'advanced-ads' ),
'description' => __( 'Text will wrap around the ad and its margin.', 'advanced-ads' ),
'title' => _x( 'Block', 'Layout options "Text Flow" heading', 'advanced-ads' ),
'description' => __( 'Text will continue after the ad and its margin.', 'advanced-ads' ),
* Concatenate the templates and prepare inline styles and scripts.
public function return_admin_view() {
return $this->positioning_admin_view() . $this->spacing_admin_view();
* Include the positioning view.
private function positioning_admin_view() {
$positioning = $this->positioning['position'];
$positioning_options = $this->setup_positioning_options();
include_once __DIR__ . '/../views/ad-positioning.php';
* Include the spacing/margin view.
private function spacing_admin_view() {
$is_centered = explode( '_', $this->positioning['position'] )[0] === 'center';
'label' => _x( 'Top', 'Ad positioning spacing label', 'advanced-ads' ),
'label' => _x( 'Right', 'Ad positioning spacing label', 'advanced-ads' ),
'label' => _x( 'Bottom', 'Ad positioning spacing label', 'advanced-ads' ),
'label' => _x( 'Left', 'Ad positioning spacing label', 'advanced-ads' ),
foreach ( $spacings as $direction => $item ) {
$spacings[ $direction ]['value'] = (int) $this->positioning['margin'][ $direction ];
include_once __DIR__ . '/../views/ad-spacing.php';
* Get a well-formed array to work with.
private function get_options() {
$options = $this->ad->options();
if ( empty( $options['output'] ) ) {
return $this->positioning;
return wp_parse_args( $options['output'], $this->positioning );