Manage gallery image with customised URL in Magento

Magento 后台对产品图片的管理操作非常简单,直接在浏览器里从本地上传,然后指定哪个作大图(image)、哪个作小图(small image)、哪个作缩略图(thumbnail)。这种傻瓜式的操作有三大缺点:

  • 不适合大批量图片的管理;
  • 图片上传后图片的存放位置乱序,不方便远程文件管理。(abc.jpg 上传后被存放在 /media/catalog/product/a/b/abc.jpg。如果之前已经有同名文件,新上传的文件自动更名为abc_1.jpg, abc_2.jpg,以此类推。)
  • 搜索引擎会从图片的 URL 里获取图片的部分信息,杂乱的 URL 不利于图片 SEO。

我认为最理想的图片管理模式是:在本地按产品分类分级维护一个图片库,用 FTP 上传到服务器,在 Magento 后台可以浏览这些文件(对 Magento 来说是本地文件),然后为某个产品选定它的大图、小图和缩略图。这样 Magento 里保存的图片位置信息就保持了自定义的产品分类信息。

Magento 的自动缩放图功能很好用,但自动缩放图生成的文件 URL 又臭又长,肯定不利于 SEO,而且服务器硬盘上留下一大堆乱序规则生成的文件夹,实在难看(有种屋子没打扫的感觉)。鉴于一个优质的电子商务网站本应该对整站的图片大小有统一的规范,不妨在本地制作好小图和缩略图,不依赖 Magento 的自动缩放图功能。

好多年前我就想做个 Magento module 来优化 Magento 的图片管理,但事务繁忙,也不知道什么时候能静下心写代码。与其让听众苦等我的 module,不如我介绍一下 Magento 数据库中 gallery 的结构,让大家懂得直接操作数据库去搭 product 和 local images 之间的桥。

首先做两个准备工作。

一是查好每个产品的 ID 备用。如果人可以 SKU 识别产品,那就准备一张 SKU – ID 的一一对应表;如果人可以 product name 识别产品,那就准备一张 product name – ID 的一一对应表。

二是把每个产品的大图、小图和缩略图命名得有意义,比如是大图是 product-name-1.jpg, product-name-2.jpg, product-name-3.jpg,小图是 product-name-s.jpg,缩略图是 product-name-t.jpg(因为 small 和 thumbnail 不是产品的关键字,所以没必要拼写完整,用自己人能看明白的代号就可以)。FTP 上传图片至 /media/catalog/product/category-name/sub-category-name/SKU/,一个产品的图片归在一个文件夹下。

现在开始正式操作数据库。操作涉及到 4 个产品属性(attribute)和 4 张表(table)。

4 个产品属性:image, small_image, thumbnail, media_gallery.

4 张表:magento_eav_attribute, magento_catalog_product_entity_media_gallery, magento_catalog_product_entity_media_gallery_value, magento_catalog_product_entity_varchar.

第一步:在 magento_eav_attribute 中查出 4 个产品属性的 attribute_id。在我碰到的 Magento 早期版本中,4 个产品属性的 attribute_id 分别是:

  • image: 70
  • small_image: 71
  • thumbnail: 72
  • media_gallery: 73

在最新的 1.7.0.0 中,4 个产品属性的 attribute_id 分别是:

  • image: 85
  • small_image: 86
  • thumbnail: 87
  • media_gallery: 88

当然可以顺便看一下 product 的 entity_type_id,不出意外的话,这应该是 4。后面会用到。

第二步:在 magento_catalog_product_entity_media_gallery 插入记录。一张图片就是一条记录,插入记录就是定义产品和图片之间一对多的关系。

Insert record to magento_catalog_product_entity_media_gallery
Insert record to magento_catalog_product_entity_media_gallery

magento_catalog_product_entity_media_gallery 中各 column 的意义是:

  • value_id:记录 ID,可以留空让数据库自动生成。
  • attribute_id:media_gallery 的 attribute_id。
  • entity_id:产品 ID。
  • value:文件存放位置信息(略去 /media/catalog/product 部分)。
Gallery records for one product
Gallery records for one product

做完这两步就可以在 Magento 后台 Manage Products 的 Images 那一页上看到属于这产品的图片。后面几步可以移至 Magento 后台完成。我继续介绍如何直接操作数据库,是让大家知道如何用数据库的导入功能去批量处理。

第三步:在 magento_catalog_product_entity_media_gallery_value 插入记录。这等效于在 Magento 后台为每个图片在各个商店设定 Label, Sort Order, Exclude 值。

如果只有一个商店,一条 magento_catalog_product_entity_media_gallery 记录就对应一条 magento_catalog_product_entity_media_gallery_value 记录。

如果有多个商店,default store_id 就是 0,先按一条 magento_catalog_product_entity_media_gallery 记录对应一条 magento_catalog_product_entity_media_gallery_value 插入记录。假设另有两个商店,store_id 分别是 1 和 2,store_id 1 沿用 store_id 0 的 default 值,store_id 2 则使用一组不同的 label/position/disable 值。这样,不需要为 store_id 1 多插入一条记录,因为 Magento 的 Website/Storegroup/Storeview 的规则是没有额外记录就是使用 default value。只需要为 store_id 2 多插入一条记录,这条记录优先于 default value,但只为 store_id 2 而生效。

magento_catalog_product_entity_media_gallery_value 中各 column 的意义是:

  • value_id:匹配 magento_catalog_product_entity_media_gallery 的记录 ID。
  • store_id:商店 ID。
  • label:图片说明。
  • position:图片排序。
  • disabled:0 就是不 Exclude,1 就是 Exclude。
Insert record to magento_catalog_product_entity_media_gallery_value
Insert record to magento_catalog_product_entity_media_gallery_value
Disable (Exclude) small image and thumbnail
Disable (Exclude) small image and thumbnail

第四步:在 magento_catalog_product_entity_varchar 插入记录。这等效于在 Magento 后台为每个产品在各个商店设定哪个是默认大图(大图可以有多张,只有一张是默认的)、哪个是小图、哪个是缩略图。

magento_catalog_product_entity_varchar 中各 column 的意义是:

  • value_id:记录 ID,可以留空让数据库自动生成。
  • entity_type_id:不出意外的话,应该填 4。
  • attribute_id:image/small_image/thumbnail 的 attribute_id。
  • store_id:商店 ID。
  • entity_id:产品 ID。
  • value:文件存放位置信息(略去 /media/catalog/product 部分)
Insert record to magento_catalog_product_entity_varchar
Insert record to magento_catalog_product_entity_varchar

假设以前用 Magento 后台上传过产品图片,删除了,保存产品,这时,服务器硬盘上的图片不会随之删除,数据库里的 image/small_image/thumbnail 记录也不会随之删除(只是 value column 的值被 NULL 代替)。这也是我不喜欢用 Magento 后台来管理产品图片的一个原因。

Duplicate record error
Duplicate record error

这些 NULL 值的记录会导致插入不成功,因为 magento_catalog_product_entity_vartype 有规定 entity_id, attribute_id, store_id 三值组的唯一性。不让插的话编辑原记录。

Search by attribute_id and entity_id
Search by attribute_id and entity_id
Search result by attribute_id and entity_id
Search result by attribute_id and entity_id

或者,把原有的 image/small_image/thumbnail 记录全删了,再插。

Search by attribute_id
Search by attribute_id
Search result by attribute_id
Search result by attribute_id

这四步做完后,Magento 前后台就显示了指定的图片。

Magento GUI manage products images
Magento GUI manage products images
Magento store front product page
Magento store front product page

这时 Magento 的自动缩放图功能仍在生效,需要修改模板让 Magento 直接使用指定的大图、小图和缩略图,这里不再多述。

Leave a comment

Your email address will not be published. Required fields are marked *