: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
* Create new options based on import information.
* @param array $decoded decoded XML.
private function import_options( &$decoded ) {
if ( isset( $decoded['options'] ) && is_array( $decoded['options'] ) ) {
foreach ( $decoded['options'] as $option_name => $imported_option ) {
// Ignore options not belonging to advanced ads.
0 !== strpos( $option_name, 'advads-' )
&& 0 !== strpos( $option_name, 'advads_' )
&& 0 !== strpos( $option_name, 'advanced-ads' )
&& 0 !== strpos( $option_name, 'advanced_ads' )
$existing_option = get_option( $option_name, [] );
if ( ! is_array( $imported_option ) ) {
if ( ! is_array( $existing_option ) ) {
$option_to_import = array_merge( $existing_option, $imported_option );
/* translators: %s: Option name. */
$this->messages[] = [ 'update', sprintf( __( 'Option was updated: <em>%s</em>', 'advanced-ads' ), $option_name ) ];
update_option( $option_name, WordPress::maybe_unserialize( $option_to_import ) );
* @return bool false if error, true otherwise
private function handle_upload() {
$uploads_dir = wp_upload_dir();
if ( ! empty( $uploads_dir['error'] ) ) {
$this->messages[] = [ 'error', $uploads_dir['error'] ];
$import_dir = $uploads_dir['basedir'] . '/advads-import';
$this->import_id = $import_dir . '/' . md5( time() . NONCE_SALT );
if ( ! is_dir( $import_dir) && ! wp_mkdir_p( $import_dir ) ) {
/* translators: %s import directory */
$this->messages[] = [ 'error', sprintf( __( 'Failed to create import directory <em>%s</em>', 'advanced-ads' ), $import_dir ) ];
if ( ! is_writable( $import_dir ) ) {
/* translators: %s import directory */
$this->messages[] = [ 'error', sprintf( __( 'Import directory is not writable: <em>%s</em>', 'advanced-ads' ), $import_dir ) ];
if ( ! @file_exists( $import_dir . '/index.php') ) {
@touch( $import_dir . '/index.php' );
if ( ! isset( $_FILES['import'] ) ) {
$this->messages[] = [ 'error', __( 'File is empty, uploads are disabled or post_max_size is smaller than upload_max_filesize in php.ini', 'advanced-ads' ) ];
$file = $_FILES['import'];
// determine if uploaded file exceeds space quota.
$file = apply_filters( 'wp_handle_upload_prefilter', $file );
if ( ! empty( $file['error'] ) ) {
/* translators: %s error in file */
$this->messages[] = [ 'error', sprintf( __( 'Failed to upload file, error: <em>%s</em>', 'advanced-ads' ), $file['error'] ) ];
if ( ! ( $file['size'] > 0 ) ) {
$this->messages[] = [ 'error', __( 'File is empty.', 'advanced-ads' ), $file['error'] ];
if ( ! is_uploaded_file( $file['tmp_name'] ) || ! @ move_uploaded_file( $file['tmp_name'], $this->import_id ) || ! is_readable( $this->import_id ) ) {
/* translators: %s import id */
$this->messages[] = [ 'error', sprintf( __( 'The file could not be created: <em>%s</em>. This is probably a permissions problem', 'advanced-ads' ), $this->import_id ) ];
// Set correct file permissions.
$stat = stat( dirname( $import_dir ) );
$perms = $stat['mode'] & 0000666;
@ chmod( $this->import_id, $perms );
// cleanup in case of failed import.
wp_schedule_single_event( time() + 10 * MINUTE_IN_SECONDS, 'advanced-ads-cleanup-import-file', [ $this->import_id ] );
* Ad content manipulations
* @param string $content Content.
* @return string $content
private function process_ad_content( $content ) {
if ( preg_match_all( '/\<advads_import_img\>(\S+?)\<\/advads_import_img\>/i', $content, $matches ) ) {
foreach ( $matches[1] as $k => $url ) {
if ( isset( $this->created_attachments[ $url ] ) ) {
$replacement_map[ $url ] = $this->created_attachments[ $url ]['attachment_url'];
} else if ( $attachment = $this->upload_image_from_url( $url ) ) {
$link = ( $link = get_attachment_link( $attachment['post_id'] ) ) ? sprintf( '<a href="%s">%s</a>', esc_url( $link ), __( 'Edit', 'advanced-ads' ) ) : '';
/* translators: 1: Attachment ID 2: Attachment link */
$this->messages[] = [ 'update', sprintf( __( 'New attachment created <em>%1$s</em> %2$s', 'advanced-ads' ), $attachment['post_id'], $link ) ];
$this->created_attachments[ $url ] = $attachment;
$replacement_map[ $url ] = $attachment['attachment_url'];
$content = str_replace( [ '<advads_import_img>', '</advads_import_img>' ], '', $content );
if ( count( $replacement_map ) ) {
$content = str_replace( array_keys( $replacement_map ), array_values( $replacement_map ), $content );
return $this->replace_placeholders( $content );
* @param string $content The content.
* @return string with replaced placeholders
private function replace_placeholders( $content ) {
$content = str_replace( '{ADVADS_BASE_URL}', ADVADS_BASE_URL, $content );
* Upload image from URL and create attachment
* @param string $image_url Image url.
* @return array with indices: post_id, attachment_url, false on failure
private function upload_image_from_url( $image_url ) {
$file_name = basename( current( explode( '?', $image_url ) ) );
$wp_filetype = wp_check_filetype( $file_name, null );
$parsed_url = @parse_url( $image_url );
$image_url = str_replace( ' ', '%20', $image_url );
if ( ! $wp_filetype['type'] ) {
/* translators: %s image url */
$this->messages[] = [ 'error', sprintf( __( 'Invalid filetype <em>%s</em>', 'advanced-ads' ), $image_url ) ];
if ( ! $parsed_url || ! is_array( $parsed_url ) ) {
/* translators: %s image url */
$this->messages[] = [ 'error', sprintf( __( 'Error getting remote image <em>%s</em>', 'advanced-ads' ), $image_url ) ];
$response = wp_safe_remote_get( $image_url, [ 'timeout' => 20 ] );
if ( is_wp_error( $response ) || 200 !== wp_remote_retrieve_response_code( $response ) ) {
/* translators: %s image url */
$this->messages[] = [ 'error', sprintf( __( 'Error getting remote image <em>%s</em>', 'advanced-ads' ), $image_url ) ];
$upload = wp_upload_bits( $file_name, '', wp_remote_retrieve_body( $response ) );
if ( $upload['error'] ) {
/* translators: %s image url */
$this->messages[] = [ 'error', sprintf( __( 'Error getting remote image <em>%s</em>', 'advanced-ads' ), $image_url ) ];
$filesize = filesize( $upload['file'] );
@unlink( $upload['file'] );
/* translators: %s image url */
$this->messages[] = [ 'error', sprintf( __( 'Zero size file downloaded <em>%s</em>', 'advanced-ads' ), $image_url ) ];
* Get allowed image mime types.
* @var string Single mime type.
$mime_types = array_filter( get_allowed_mime_types(), function( $mime_type ) {
return preg_match( '/image\//', $mime_type );
$fileinfo = @getimagesize( $upload['file'] );
if ( ! $fileinfo || ! in_array( $fileinfo['mime'], $mime_types, true ) ) {
@unlink( $upload['file'] );
/* translators: %s image url */
$this->messages[] = [ 'error', sprintf( __( 'Error getting remote image <em>%s</em>', 'advanced-ads' ), $image_url ) ];
'post_title' => $file_name,
'post_mime_type' => $wp_filetype['type'],
'guid' => $upload['url'],
if ( ! function_exists( 'wp_generate_attachment_metadata' ) ) {
require_once( ABSPATH . 'wp-admin/includes/image.php' );
$post_id = wp_insert_attachment( $new_post, $upload['file'] );
wp_update_attachment_metadata( $post_id, wp_generate_attachment_metadata( $post_id, $upload['file'] ) );
return [ 'post_id' => $post_id, 'attachment_url' => wp_get_attachment_url( $post_id ) ];
public function get_messages() {