Magento の無料拡張機能OnePica ImageCdnに関連する質問があります。
「壊れた画像」をアップロードすると、壊れた画像がフロントエンドに表示されます。
では、長い話を始めましょう。
ImageCdn 拡張機能と「破損した画像」が原因で発生していることに気付きました。
ImageCdn のコードの一部:
OnePica_ImageCdn_Helper_Image
/**
* In older versions of Magento (<1.1.3) this method was used to get an image URL.
* However, 1.1.3 now uses the getUrl() method in the product > image model. This code
* was added for backwards compatibility.
*
* @return string
*/
public function __toString()
{
parent::__toString();
return $this->_getModel()->getUrl();
}
私の質問は、そのコードの目的を知っている人はいますか? 上記のコメントの意味がわかりません。いつも通りバグだと思うreturn $this->_getModel()->getUrl();
本当にバグですか、それとも私の間違った解釈ですか?
これは私がこれまでに行ったことです:
- イメージがあります
dummy.jpeg
- 調べてみると、それは「壊れた画像」であることがわかりました。
- 私は以下を使用してテストしました:
<?php print_r(getimagesize('dummy.jpeg')); ?>
結果:
Array ( [0] => 200 [1] => 200 [2] => 6 [3] => width="200" height="200" [bits] => 24 [mime] => image/x-ms-bmp )
もちろん、Preview
(Mac OSXで)
開いたときに見栄えが良いので、結果には驚きました。
- 次に、16進エディターを使用して開きます。最初の2バイトは次のとおりです。
BM
これはBMPの識別子です - 製品の .bmp 画像をアップロードしようとしました -> 失敗しました。画像を選択できません
- 同僚にも(Ubuntuで)アップロードするように依頼したところ、ファイルタイプの選択を「任意のファイル」に変更できました。「ファイルのアップロード」をクリックすると、そのタイプのファイルは許可されていないというエラー メッセージが表示されます。
- 私の頭に浮かんだのは、管理者が
.bmp
画像をアップロードしようとして失敗したことです。それから彼はそれをに改名し.jpeg
、成功しました。壊れた画像のロゴを表示せずに名前を変更できる画像の種類はわかりませんが(トピック外)。 - これらのシナリオは例外を引き起こします。私が追跡したものを分析します。
コードのトレース:
- アプリ/デザイン/フロントエンド/ベース/デフォルト/カタログ/製品/ビュー/media.phtml
<?php
$_img = '<img id="image" src="'.$this->helper('catalog/image')->init($_product, 'image').'" alt="'.$this->htmlEscape($this->getImageLabel()).'" title="'.$this->htmlEscape($this->getImageLabel()).'" />';
echo $_helper->productAttribute($_product, $_img, 'image');
?>
- そのコードから、画像の URL が以下を使用して生成されていることがわかります。
$this->helper('catalog/image')->init($_product, 'image')
- やった
Mage::log((string)$this->helper('catalog/image')->init($_product, 'image'));
結果:
http://local.m.com/media/catalog/product/cache/1/image/9df78eab33525d08d6e5fb8d27136e95/d/u/dummy.jpeg
.
- Mage_Catalog_Helper_Image
public function __toString()
{
try {
if( $this->getImageFile() ) {
$this->_getModel()->setBaseFile( $this->getImageFile() );
} else {
$this->_getModel()->setBaseFile( $this->getProduct()->getData($this->_getModel()->getDestinationSubdir()) );
}
if( $this->_getModel()->isCached() ) {
return $this->_getModel()->getUrl();
} else {
if( $this->_scheduleRotate ) {
$this->_getModel()->rotate( $this->getAngle() );
}
if ($this->_scheduleResize) {
$this->_getModel()->resize();
}
if( $this->getWatermark() ) {
$this->_getModel()->setWatermark($this->getWatermark());
}
Mage::log('pass');
$url = $this->_getModel()->saveFile()->getUrl();
Mage::log('not pass');
}
} catch( Exception $e ) {
$url = Mage::getDesign()->getSkinUrl($this->getPlaceholder());
}
return $url;
}
- で発生したエラー
$this->_getModel()->saveFile()->getUrl()
。コードの一部では、最終的に次のようになります。
Varien_Image_Adapter_Gd2
private function _getCallback($callbackType, $fileType = null, $unsupportedText = 'Unsupported image format.')
{
if (null === $fileType) {
$fileType = $this->_fileType;
}
if (empty(self::$_callbacks[$fileType])) {
//reach this line -> exception thrown
throw new Exception($unsupportedText);
}
if (empty(self::$_callbacks[$fileType][$callbackType])) {
throw new Exception('Callback not found.');
}
return self::$_callbacks[$fileType][$callbackType];
}
- 例外は前のコードでキャッチされました。
Mage_Catalog_Helper_Image
public function __toString()
{
...
} catch( Exception $e ) {
$url = Mage::getDesign()->getSkinUrl($this->getPlaceholder());
}
...
}
$url は次のようになりました。
http://local.m.com/skin/frontend/default/default/images/catalog/product/placeholder/image.jpg
- それで、それはプレースホルダー画像を生成したはずですよね? (ImageCdn 拡張子なし)
- いいえ、なぜなら
Mage_Catalog_Helper_Image
によって書き直されましたOnePica_ImageCdn_Helper_Image
public function __toString()
{
parent::__toString(); //the result is http://local.m.com/skin/frontend/default/default/images/catalog/product/placeholder/image.jpg but no variable store/process its value
return $this->_getModel()->getUrl(); //in the end it will return http://local.m.com/media/catalog/product/cache/1/image/9df78eab33525d08d6e5fb8d27136e95/d/u/dummy.jpeg
}
質問を忘れてしまった場合に備えて、そのコードの目的を知っている人はいますか? 上記のコメントの意味がわかりません。それは本当にバグですか、それとも私の間違った解釈ですか?