Pull to refresh

Мусор в именах файлов или прячем наших лебедей (wordpress)

Reading time 3 min
Views 6.2K
random_file_names

Вступление


Некоторые камеры категорически отказываются задавать имена файлам на основе timestamp, используя обычный счетчик. В обиходе эта мелочь действительно кажется мелочью, но в интернете вырастает в проблему, позволяющую особо любопытным шерстить сайт в поисках фотографий P1100812.jpg и P1100813.jpg после просмотра P1100811.jpg.

Варианты решения:


  • добавить статичный префикс
  • добавить динамичный префикс

Теперь надо определиться как добавить префикс, сделать ли это через самописный скрипт до загрузки фоток, переименовав все локальные фотографии (сила науки, о нет!) или в момент загрузки на сервер. Не глядя, без вздрогнутых мышц лица, был выбрал вариант «на сервер!».

Техническая реализация:


  • она есть! = пишем ручками
  • её нет! = готовый плагин для wordpress

К счастью или к сожалению, поиск плагинов выдал список outdated на старые версии wordpress. Поэтому вооружившись гуглом и затем np++ было найдено, что:
  • обработка аплоада файлов на плечах /wp-includes/functions.php
  • имя файла *генерируется в функции wp_unique_filename

*генерируется — это я немного загнул, просто проверяется на уникальность/корректность и изменяется в случае, но это, судя по коду, конечная инстанция.

И так, открываем файл functions.php, находим в нем тело функции wp_unique_filename, там строку $filename = sanitize_file_name($filename); и радостно правим её!

Как её править?

Например как (один из вариантов):
  • $filename = crc32(md5(microtime()).sanitize_file_name($filename))."_".sanitize_file_name($filename);
  • $filename = md5(microtime().sanitize_file_name($filename))."_".sanitize_file_name($filename);
  • $filename = crc32("blablabla".microtime().sanitize_file_name($filename))."_".sanitize_file_name($filename);
  • $filename = любые душе угодные хеши php и что-нибудь рандомное.sanitize_file_name($filename);

microtime() — выполняет роль ГПСЧ, выдавая текущее серверное время.

Мы оставляет текущий алгоритм работы wp_unique_filename, лишь добавляя к началу файла наш мусор.

Я для себя выбрал вариант CRC32(магия эльфов)."_".sanitize_file_name($filename);, так как CRC32 не уродует внешне файл (имя), добавляя немножко цыферек/буковок, превращая "random_file_names.png" в удобоваримый "255298064_random_file_names.png", что всяко приятнее глазу чем "ae812e87bbbf3a068807fe763721c38a_random_file_names.png".

Итог: 
  • простое решение в одну строку
  • приватные файлы чуть приватнее (хоть и в паблик системе)

Бонус:
3894406080_P1100810.jpg и 3765414138_P1100811.jpg

P1100810 P1100811

В той же папке есть P1100827.jpg

upd:
Конечно, надо понимать, что при обновлении WP может обновить (=перетереть) functions.php. Поэтому данную процедуру надо будет повторить.

Автоматизация:

Принцип: найти во всем файле строку $filename = sanitize_file_name($filename); и заменить её на выбранную вами (в примере это $filename = crc32(md5(microtime()).sanitize_file_name($filename))."_".sanitize_file_name($filename);).

Cоздать файл functions.php.diff следующего содержания в папке /wp-includes

Для префикса вида «12345_image.jpg»



--- functions.php.orig  2015-04-20 06:39:25.000000000 +0000
+++ functions.php.new   2015-05-04 17:45:27.000000000 +0000
@@ -1 +1 @@
-       $filename = sanitize_file_name($filename);
+       $filename = crc32(md5(mt_rand().microtime()).sanitize_file_name($filename))."_".sanitize_file_name($filename);


Для суффикса вида «image_12345_.jpg»



--- old.php	2015-05-06 10:39:17.847753325 +0000
+++ new.php	2015-05-06 10:39:31.459794157 +0000
@@ -1 +1,2 @@
-	$filename = sanitize_file_name($filename);
+	$filename = sanitize_file_name($filename);
+	$filename = pathinfo($filename, PATHINFO_FILENAME).'_'.crc32(md5(mt_rand().microtime()).sanitize_file_name($filename)).(pathinfo($filename, PATHINFO_EXTENSION)?'.'.pathinfo($filename, PATHINFO_EXTENSION):'');


Выполнить в папке «на сухую»
patch --dry-run functions.php -i functions.php.diff

Если все ОК, получим приблизительно такой ответ:
checking file functions.php
Hunk #1 succeeded at 1862 (offset 1861 lines).


Затем патчим по-настоящему:
patch functions.php -i functions.php.diff

Получаем ответ вида:
patching file functions.php
Hunk #1 succeeded at 1862 (offset 1861 lines).


Старый файл будет иметь имя "functions.php.orig".

Как уже писал выше, вместо crc32 можно использовать хеш функции, значения которых в виду громоздкости можно обрезать. В силу личных предпочтений были оставлены числа от crc32.

upd2: (20150506) Добавлен вариант для суффикса между именем файла и расширением. Для файлов без расширения (если закачка таких разрешена) суффикс будет добавлен к окончанию.

upd3: (20150506) Добавлен mt_rand() и более короткий вариант для суффикса, предложенный maximw.
Tags:
Hubs:
-9
Comments 50
Comments Comments 50

Articles