sitepress = $sitepress; $this->wpdb = $wpdb; } /** * Add hooks. */ 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. * * @return bool */ private function is_admin_or_xmlrpc() { $is_admin = is_admin(); $is_xmlrpc = ( defined( 'XMLRPC_REQUEST' ) && XMLRPC_REQUEST ); return $is_admin || $is_xmlrpc; } /** * Check if we are uploading plugin or theme. * * @return bool */ private function is_uploading_plugin_or_theme() { global $action; return ( isset( $action ) && ( 'upload-plugin' === $action || 'upload-theme' === $action ) ); } /** * Filter views. * * @param array $views Views. * * @return array */ public function views_upload_actions( $views ) { global $pagenow; if ( 'upload.php' === $pagenow ) { // Get current language. $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 ); } else { $href_base = 'upload.php'; $href_args = array(); } if ( 'all' !== $lang ) { $sql = $this->wpdb->prepare( " SELECT COUNT(p.id) FROM {$this->wpdb->posts} AS p INNER JOIN {$this->wpdb->prefix}icl_translations AS t ON p.id = t.element_id WHERE p.post_type = 'attachment' AND t.element_type='post_attachment' AND t.language_code = %s ", $lang ); switch ( $key ) { case 'all': $and = " AND p.post_status != 'trash' "; break; case 'detached': $and = " AND p.post_status != 'trash' AND p.post_parent = 0 "; break; case 'trash': $and = " AND p.post_status = 'trash' "; break; default: if ( isset( $href_args['post_mime_type'] ) ) { $and = " AND p.post_status != 'trash' " . wp_post_mime_type_where( $href_args['post_mime_type'], 'p' ); } else { $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_and = $sql . $and; $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 ); // phpcs:enable if ( null === $res ) { $res = $this->wpdb->get_col( $sql ); } // Replace count. $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 ); } } return $views; } /** * Check if the image is not duplicated to another post before deleting it physically. * * @param string $file Full file name. * * @return string|null */ public function delete_file_filter( $file ) { if ( $file ) { $file_name = $this->get_file_name( $file ); $sql = "SELECT pm.meta_id, pm.post_id FROM {$this->wpdb->postmeta} AS pm WHERE pm.meta_value = %s AND pm.meta_key='_wp_attached_file'"; $attachment_prepared = $this->wpdb->prepare( $sql, [ $file_name ] ); $attachment = $this->wpdb->get_row( $attachment_prepared ); if ( ! empty( $attachment ) ) { $file = null; } } return $file; } private function get_file_name( $file ) { $file_name = $this->get_file_name_without_size_from_full_name( $file ); $upload_dir = wp_upload_dir(); $path_parts = explode( "/", Str::replace( $upload_dir['basedir'], '', $file ) ); if ( $path_parts ) { $path_parts[ count( $path_parts ) - 1 ] = $file_name; } return ltrim( implode( '/', $path_parts ), '/' ); } /** * 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 ); return $file_name; } }