: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
* WPML_Attachment_Action class file.
* Class WPML_Attachment_Action
class WPML_Attachment_Action implements IWPML_Action {
* WPML_Attachment_Action constructor.
* @param SitePress $sitepress Sitepress instance.
* @param wpdb $wpdb wpdb instance.
public function __construct( SitePress $sitepress, wpdb $wpdb ) {
$this->sitepress = $sitepress;
public function add_hooks() {
if ( $this->is_admin_or_xmlrpc() && ! $this->is_uploading_plugin_or_theme() ) {
$active_languages = $this->sitepress->get_active_languages();
if ( count( $active_languages ) > 1 ) {
add_filter( 'views_upload', array( $this, 'views_upload_actions' ) );
add_filter( 'attachment_link', array( $this->sitepress, 'convert_url' ), 10, 1 );
add_filter( 'wp_delete_file', array( $this, 'delete_file_filter' ) );
* Check if we are in site console or xmlrpc request is active.
private function is_admin_or_xmlrpc() {
$is_xmlrpc = ( defined( 'XMLRPC_REQUEST' ) && XMLRPC_REQUEST );
return $is_admin || $is_xmlrpc;
* Check if we are uploading plugin or theme.
private function is_uploading_plugin_or_theme() {
return ( isset( $action ) && ( 'upload-plugin' === $action || 'upload-theme' === $action ) );
* @param array $views Views.
public function views_upload_actions( $views ) {
if ( 'upload.php' === $pagenow ) {
$lang = $this->sitepress->get_current_language();
foreach ( $views as $key => $view ) {
// Extract the base URL and query parameters.
$href_count = preg_match( '/(href=["\'])([\s\S]+?)\?([\s\S]+?)(["\'])/', $view, $href_matches );
if ( $href_count && isset( $href_args ) ) {
$href_base = $href_matches[2];
wp_parse_str( $href_matches[3], $href_args );
$href_base = 'upload.php';
$sql = $this->wpdb->prepare(
FROM {$this->wpdb->posts} AS p
INNER JOIN {$this->wpdb->prefix}icl_translations AS t
WHERE p.post_type = 'attachment'
AND t.element_type='post_attachment'
AND t.language_code = %s ",
$and = " AND p.post_status != 'trash' ";
$and = " AND p.post_status != 'trash' AND p.post_parent = 0 ";
$and = " AND p.post_status = 'trash' ";
if ( isset( $href_args['post_mime_type'] ) ) {
$and = " AND p.post_status != 'trash' " . wp_post_mime_type_where( $href_args['post_mime_type'], 'p' );
$and = $this->wpdb->prepare( " AND p.post_status != 'trash' AND p.post_mime_type LIKE %s", $key . '%' );
// phpcs:disable WordPress.NamingConventions.ValidHookName.UseUnderscores
$and = apply_filters( 'wpml-media_view-upload-sql_and', $and, $key, $view, $lang );
$sql = apply_filters( 'wpml-media_view-upload-sql', $sql_and, $key, $view, $lang );
$res = apply_filters( 'wpml-media_view-upload-count', null, $key, $view, $lang );
$res = $this->wpdb->get_col( $sql );
$view = preg_replace( '/\((\d+)\)/', '(' . $res[0] . ')', $view );
// Replace href link, adding the 'lang' argument and the revised count.
$href_args['lang'] = $lang;
$href_args = array_map( 'urlencode', $href_args );
$new_href = add_query_arg( $href_args, $href_base );
$views[ $key ] = preg_replace( '/(href=["\'])([\s\S]+?)(["\'])/', '$1' . $new_href . '$3', $view );
* Check if the image is not duplicated to another post before deleting it physically.
* @param string $file Full file name.
public function delete_file_filter( $file ) {
static $saved_request = array();
$file_name = $this->get_file_name_without_size_from_full_name( $file );
if ( array_key_exists( $file_name, $saved_request ) ) {
$attachment = $saved_request[ $file_name ];
$sql = "SELECT pm.meta_id, pm.post_id FROM {$this->wpdb->postmeta} AS pm
WHERE pm.meta_value LIKE %s AND pm.meta_key='_wp_attached_file'";
$attachment_prepared = $this->wpdb->prepare( $sql, array( '%' . $file_name ) );
$attachment = $this->wpdb->get_row( $attachment_prepared );
$saved_request [ $file_name ] = $attachment;
if ( ! empty( $attachment ) ) {
* Get file name without a size, i.e. 'a-600x400.png' -> 'a.png'.
* @param string $file Full file name.
* @return mixed|string|string[]|null
private function get_file_name_without_size_from_full_name( $file ) {
$file_name = preg_replace( '/^(.+)\-\d+x\d+(\.\w+)$/', '$1$2', $file );
$file_name = preg_replace( '/^[\s\S]+(\/.+)$/', '$1', $file_name );
$file_name = str_replace( '/', '', $file_name );