Добавление водяных знаков (watermark) в Webasyst Shop-script

Для магазина Gadgets Mart понадобилось сделать защиту картинок. Shop-script очень большой продукт, достаточно мощный, но почему-то функционала добавления водяных знаков нет.  (по крайней мере он не вынесен в админку). Стал копать файлы, у них там полный бардак: куча дублирующих классов и библиотек, не внятная архитектура и полно хвостов от старой версии Shop-script. Не смотря на это Shop-script работает вполне неплохо. Самое забавное что через 5 минут ковыряния я нашел файл в котором есть метод создания водяного знака :) Осталось немного подправить код и все заработало...

Что я сделал:

В файле published/SC/html/scripts/core_functions/picture_functions.php добавил следующую функцию:

PHP:
  1. function wm($file, $width, $height, $destination_file = null,$watermark_file = null,$position = 'right', $alpha_level = 50){
  2. $width = intval($width);
  3. $height = intval($height);
  4. if ( !function_exists('gd_info') )
  5. return PEAR::raiseError('PHP extension gd not loaded', 1);
  6. //      return PEAR::raiseError (1, 1);
  7. $src_img = $this->read($file, $info);
  8. if(!$src_img)
  9. return PEAR::raiseError('Error read image', 1);
  10. //      return PEAR::raiseError (2, 1);
  11. if ( !function_exists('imagecreatetruecolor') )
  12. return PEAR::raiseError('function «imagecreatetruecolor» dosn\'t exists', 1);
  13. //      return PEAR::raiseError (3, 1);
  14. if ( !function_exists('imagecopyresized') )
  15. return PEAR::raiseError('function «imagecopyresized» dosn\'t exists', 1);
  16. //      return PEAR::raiseError (4, 1);
  17. if ( !function_exists('getimagesize') )
  18. return PEAR::raiseError('function «getimagesize» dosn\'t exists', 1);
  19. $src_width = imagesx($src_img);
  20. if(!$width) $width = $src_width;
  21. $src_height = imagesy($src_img);
  22. if(!$height) $height = $src_height;
  23. if ( $src_width> $src_height && $src_width> $width ){
  24. $ratio = $src_width/$src_height;
  25. $height /= $ratio;
  26. }elseif( $src_height> $height ) {
  27. $ratio = $src_height/$src_width;
  28. $width /= $ratio;
  29. }
  30. if($src_height <$height || $src_width <$width){
  31. $width = $src_width;
  32. $height = $src_height;
  33. }
  34. /*  if ($width == $src_width){//skip image resize
  35. if (($file!=$destination_file)&&!copy ($file, $destination_file)){
  36. //return PEAR::raiseError ('Error write image', 1);
  37. }
  38. return null;
  39. } */
  40. $dst_img = imagecreatetruecolor( $width, $height );
  41. if ( !$dst_img ) {
  42. @imagedestroy( $src_img );
  43. return PEAR::raiseError( «Error creating true color image {$width}&times;{$height}», 1 );
  44. //      return PEAR::raiseError ( 6, 1 );
  45. }
  46. if ( function_exists('imagecopyresampled') )
  47. $res = @imagecopyresampled ( $dst_img, $src_img, 0, 0, 0, 0, $src_width, $src_height, $src_width, $src_height );
  48. else
  49. $res = @imagecopyresized ( $dst_img, $src_img, 0, 0, 0, 0, $src_width, $src_height, $src_width, $src_height );
  50. if ( !$res ) {
  51. @imagedestroy( $srcIm );
  52. @imagedestroy( $destImg );
  53. return PEAR::raiseError( 'Error copy resized image', 1 );
  54. //      return PEAR::raiseError ( 7, 1 );
  55. }
  56. if(defined('CONF_PICTRESIZE_QUALITY')){
  57. $quality = intval(constant('CONF_PICTRESIZE_QUALITY'));
  58. $quality = ($quality>100)?100:(($quality&lt;0)?0:$quality);
  59. }else{
  60. $quality = 80;
  61. }
  62. //Future add watermark
  63. $watermark_file = DIR_IMG.'/watermark.png';
  64. if($watermark_file && file_exists($watermark_file)){
  65. $dst_img = $this->addWatermark($dst_img,$watermark_file,'right', 75);
  66. }
  67. $res = @imagejpeg( $dst_img, !is_null($destination_file)?$destination_file:$file, $quality);
  68. if(!$res)
  69. return PEAR::raiseError('Error write image', 1);
  70. //      return PEAR::raiseError (8, 1);
  71. @imagedestroy( $destImg );
  72. @imagedestroy( $srcIm );
  73. }

Там же в предпоследней строчке добавил:

PHP:
  1. Functions::register(new ns_image(), 'img_wm', 'wm');

Затем в файле published/SC/html/scripts/modules/products/_methods/b_product_settings.php нужно найти следующие строчки:

PHP:
  1. ...
  2. /**
  3. * Standard picture
  4. */
  5. $standard_file_name = $file_name;
  6. if(file_exists(DIR_PRODUCTS_PICTURES.'/'.$standard_file_name))
  7. $standard_file_name = getUnicFile(2, preg_replace('@\.([^\.]+)$@', '%s.$1', $file_name), DIR_PRODUCTS_PICTURES);
  8. if(
  9. PEAR::isError($res = Functions::exec('img_resize', array($orig_file, CONF_PRDPICT_STANDARD_SIZE, CONF_PRDPICT_STANDARD_SIZE, $temp_file)))
  10. PEAR::isError($res = Functions::exec('file_copy', array($temp_file, DIR_PRODUCTS_PICTURES.'/'.$standard_file_name)))
  11. ){
  12. $error = $res;
  13. Functions::exec('file_remove', array($temp_file));
  14. Functions::exec('file_remove', array($orig_file));
  15. break;
  16. }
  17. /**
  18. * Thumbnail picture
  19. */
  20. $thumbnail_file_name = preg_replace('@\.([^\.]+)$@', '_thm.$1', $file_name);
  21. if(file_exists(DIR_PRODUCTS_PICTURES.'/'.$thumbnail_file_name))
  22. $thumbnail_file_name = getUnicFile(2, preg_replace('@\.([^\.]+)$@', '%s.$1', $thumbnail_file_name), DIR_PRODUCTS_PICTURES);
  23. if(
  24. PEAR::isError($res = Functions::exec('img_resize', array($orig_file, CONF_PRDPICT_THUMBNAIL_SIZE, CONF_PRDPICT_THUMBNAIL_SIZE, $temp_file)))
  25. PEAR::isError($res = Functions::exec('file_copy', array($temp_file, DIR_PRODUCTS_PICTURES.'/'.$thumbnail_file_name)))
  26. ){
  27. $error = $res;
  28. Functions::exec('file_remove', array($temp_file));
  29. Functions::exec('file_remove', array($orig_file));
  30. Functions::exec('file_remove', array(DIR_PRODUCTS_PICTURES.'/'.$standard_file_name));
  31. break;
  32. }
  33. /**
  34. * Enlarged picture
  35. */
  36. $orig_size = getimagesize($orig_file);
  37. $standard_size = getimagesize(DIR_PRODUCTS_PICTURES.'/'.$standard_file_name);
  38. if($orig_size[0]>$standard_size[0] || $orig_size[1]>$standard_size[1]){
  39. $enlarged_file_name = preg_replace('@\.([^\.]+)$@', '_enl.$1', $file_name);
  40. if(file_exists(DIR_PRODUCTS_PICTURES.'/'.$enlarged_file_name))
  41. $enlarged_file_name = getUnicFile(2, preg_replace('@\.([^\.]+)$@', '%s.$1', $enlarged_file_name), DIR_PRODUCTS_PICTURES);
  42. if(
  43. PEAR::isError($res = Functions::exec('img_resize', array($orig_file, CONF_PRDPICT_ENLARGED_SIZE, CONF_PRDPICT_ENLARGED_SIZE, $temp_file)))
  44. PEAR::isError($res = Functions::exec('file_copy', array($temp_file, DIR_PRODUCTS_PICTURES.'/'.$enlarged_file_name)))
  45. ){
  46. $error = $res;
  47. Functions::exec('file_remove', array($temp_file));
  48. ...

И в зависимости от того на какую картинку вам нужно накладывать водяной знак, нужно заменить img_resize на img_wm. То есть если вы замените img_resize в блоке под комментарием «Standard picture», то ватермарк будет накладываться на картинки, которые отображаются при выборе конкретного продукта, если после комментария Thumbnail picture, то ватермарк будет накладываться на уменьшенные копии картинок, которые отображаются при выборе категории продукта. Если заменить в блоке «Enlarged picture», то водяной знак будет накладываться на картинки при увеличении фото продукта.

Ну и последнее нужно положить сам файлик с копирайтами в published/publicdata/{Название магазина}/attachments/SC/images/watermark.png

Сразу скажу, что после обновления движка Shop-script скорее всего этот функционал отвалится. Я проверял работоспособность этого метода на версиях: 280- 287. Перед эксперементами обязательно сделайте бэкап.

Уже отредактированные файлы

Если есть вопросы пишите в комментах...

P.S. Полезная ссылка на туже тему

Я обновил код в статье теперь все должно работать