WordPress.org

Make WordPress Core

Changes between Version 1 and Version 2 of Ticket #37989, comment 63


Ignore:
Timestamp:
11/10/2016 07:45:12 AM (2 years ago)
Author:
arthurvkuhrmeier
Comment:

Legend:

Unmodified
Added
Removed
Modified
  • Ticket #37989, comment 63

    v1 v2  
    11Searching for a solution myself I stumbled upon this thread. Happy to say, I found a way to fix this.
    22
    3 Luckily, WordPress uses two different variables to sanitize the title and the filename. First, let's fix the title:
     3'''EDIT:''' My first approach was a bit simpler, but I missed the fact that sanitize_title() is also used for creating slugs for posts etc.
     4
     5Luckily, WordPress uses two different variables to sanitize the title and the filename. We need to determine if a title is the file we just uploaded. The only way to do this is to browse the $_FILES global.
     6
     7First, we need to control the way filenames are sanitized. I prefer pure ASCII without spaces.
    48
    59{{{#!php
    610<?php
    711//===== Fix sanitized Media Titles - Part I =====
    8 function noobclub_sanitize_title ($title, $fallback_title, $context) {
    9         return ( strlen($fallback_title)  ?  $fallback_title  :  $title );
    10 }
    11 add_filter('sanitize_title', 'noobclub_sanitize_title', 10, 3);
    12 }}}
    13 The $fallback_title contains the original filename. In other words, we do not sanitize title and filename at all! '''So, use at your own risk.'''
    14 
    15 Next, let's sanitize the filename. I prefer filenames in pure ASCII without spaces:
    16 {{{#!php
    17 <?php
    18 //===== Fix sanitized Media Titles - Part II =====
    19 function noobclub_upload_filter ($file) {
    20         $name = explode('.', $file['name']);
    21         $ext  = array_pop($name);
    22         $name = implode('.', $name);
     12function noobclub_sanitize_filename ($name) {
    2313        //--- If your PHP version does not support transliterator, ---
    2414        //--- you'll have to find a different solution             ---
    2515        $name = transliterator_transliterate('Any-Latin; Latin-ASCII; [\u0080-\u7fff] remove', $name);
    2616        $name = sanitize_file_name(sanitize_title_with_dashes($name));
    27         $file['name'] = $name.'.'.$ext;
     17        return $name;
     18}
     19
     20//===== Fix sanitized Media Titles - Part II =====
     21function noobclub_upload_filter($file) {
     22        $name = explode('.', $file['name']);
     23        $ext  = array_pop($name);
     24        $name = implode('.', $name);
     25        $file['name'] = noobclub_sanitize_filename($name).'.'.$ext;
    2826        return $file;
    2927}
    3028add_filter('wp_handle_upload_prefilter', 'noobclub_upload_filter');
     29}}}
     30
     31Next we check if sanitize_title() wants to change our filename. The function also knows the original title, the same we sanitized right after upload. After sanitizing it must match the filename found in the $_FILES global.
     32{{{#!php
     33<?php
     34//===== Fix sanitized Media Titles - Part III =====
     35function noobclub_sanitize_title ($title, $fallback_title, $context) {
     36        if (count($_FILES)) {
     37                $fallback = noobclub_sanitize_filename($fallback_title);
     38                foreach ($_FILES as $file) {
     39                        $name_parts = pathinfo($file['name']);
     40                        $name = trim(substr( $file['name'], 0, -(1 + strlen($name_parts['extension'])) ));
     41                        if  ($name === $fallback && strlen($fallback_title))  return $fallback_title;
     42                }
     43        }
     44        return $title;
     45}
     46add_filter('sanitize_title', 'noobclub_sanitize_title', 10, 3);
    3147}}}
    3248Finally, I wanted the slug to be the same as the filename:
     
    3955                $name = array_pop($name);
    4056                $name = explode('.', $name);
     57                //--- You may add a unique prefix for media slugs:     ---
     58                //--- e.g. $data['post_name'] = 'media-'.reset($name); ---
    4159                $data['post_name'] = reset($name);
    4260        }