HTMLヘルパーを拡張して、なるべく新しいコードを書かずに、
画像のリンク切れをさせずに代わりにnoimage画像を表示させます。
動作確認環境はPHP5.6.13、CakePHP2.6.4です。
ちなみにCakePHPは/app/webrootでphp -S localhost:8383
して動かしています。
.ctp
<div>
<?= $this->Html->image('myIcon.jpg')?>
</div>
<div>
<?= $this->Html->image('//localhost:8383/img/myIcon.jpg')?>
</div>
<div>
<?= $this->Html->image('http://localhost:8383/img/myIcon.jpg')?>
</div>
<div>
<?= $this->Html->image('https://localhost:8383/img/myIcon.jpg')?>
</div>
<div>
<?= $this->Html->image('noimage.jpg')?>
</div>
<div>
<?= $this->Html->image('anotherIcon.jpg')?>
</div>
今回myIcon.jpg
とnoimage.jpg
はあって表示され、anotherIcon.jpg
は存在せずリンク切れになっている状態とします。
この.ctpは変更せずに、うまいことHTMLヘルパーの拡張だけで済ませます。
CustomHtmlHelperで画像の存在チェック
CustomHtmlHelper.php
を作って、image()をオーバーライド。
画像のパスを出す前に一度ファイルの有無を確認して、ない場合はnoimageに変える。
<?php
App::uses('AppHelper', 'View/Helper');
App::import('Helper', 'Html');
class CustomHtmlHelper extends HtmlHelper {
public function image($path, $options = array()) { // override
// 画像のパスをパース(HtmlHelper::image()と同様)
$realPath = $this->assetUrl($path, $options + array('pathPrefix' => Configure::read('App.imageBaseUrl')));
// 同ホストの画像の場合のみ
if (!preg_match('|(https?:)?//|',$realPath) && !file_exists(WWW_ROOT.$realPath)) {
$path = 'noimage.jpg';
}
return parent::image($path, $options);
}
}
CustomHtmlHelperの読み込み
次にViewを変更する手間を省くために、Html
でCustomHtml
のヘルパーを読み出せるようにしてしまいます。
class AppController extends Controller {
public $helpers = array(
'Html' => array('className' => 'CustomHtml')
);
(略)
}
これで上のViewファイルで画像がない場合もnoimage.jpgが表示されるはずです。
ひとこと
ちょっと気持ち悪いのが、parent::image()でないでやる処理の一つと全く同じ処理をつけた形になっていること。
本当はparent::image()使わないで継承せずに純粋に上書きしたほうがスマートに書けるが、なるべく書く量を少なくしてみた。
noimageを出す時のサイズは別に指定する必要があったりと純粋にこれだけでnoimageを安心して出せるわけではない。
参考までにどうぞ。