source: branches/version-2_12-dev/data/class/helper/SC_Helper_Transform.php @ 21829

Revision 21829, 24.7 KB checked in by Seasoft, 12 years ago (diff)

#1613 (typo修正・ソース整形・ソースコメントの改善)

Line 
1<?php
2/*
3 * This file is part of EC-CUBE
4 *
5 * Copyright(c) 2000-2012 LOCKON CO.,LTD. All Rights Reserved.
6 *
7 * http://www.lockon.co.jp/
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22 */
23
24/**
25 * テンプレートをDOM変形するためのヘルパークラス
26 *
27 * @package Helper
28 * @version $Id$
29 */
30class SC_Helper_Transform {
31    protected $objDOM;
32    protected $arrSmartyTagsOrg;
33    protected $arrSmartyTagsSub;
34    protected $smarty_tags_idx;
35    protected $arrErr;
36    protected $arrElementTree;
37    protected $arrSelectElements;
38    protected $html_source;
39    protected $header_source;
40    protected $footer_source;
41    protected $search_depth;
42
43    const ERR_TARGET_ELEMENT_NOT_FOUND = 1;
44
45    /**
46     * SmartyのHTMLソースをDOMに変換しておく
47     *
48     * @param string $source 変形対象のテンプレート
49     * @return void
50     */
51    public function __construct($source) {
52        $this->objDOM = new DOMDocument();
53        $this->objDOM->strictErrorChecking = false;
54        $this->snip_count      = 0;
55        $this->smarty_tags_idx = 0;
56        $this->arrErr          = array();
57        $this->arrElementTree  = array();
58        $this->arrSelectElements = array();
59        $this->html_source = $source;
60        $this->header_source = NULL;
61        $this->footer_source = NULL;
62        $this->search_depth = 0;
63
64        if (!in_array(mb_detect_encoding($source), array('ASCII', 'UTF-8'))) {
65            SC_Utils_Ex::sfDispSiteError(FREE_ERROR_MSG, '', true, 'テンプレートの文字コードがUTF-8ではありません');
66        }
67
68        // Smartyのコメントを削除
69        $source = preg_replace(
70            '/<\!--{\*.+?\*\}-->/s',
71            '',
72            $source
73        );
74
75        // headタグの内側を退避
76        $source = preg_replace_callback(
77            '/(<head[^>]*>)(.+)(<\/head>)/is',
78            array($this, 'lfCaptureHeadTags2Comment'),
79            $source
80        );
81
82        // JavaScript内にSmartyのタグが存在するものを、コメント形式に置換
83        $source = preg_replace_callback(
84            '/<script.+?\/script>/s',
85            array($this, 'lfCaptureSmartyTags2Comment'),
86            $source
87        );
88
89        // HTMLタグ内にSmartyのタグが存在するものを、まず置換する
90        $source = preg_replace_callback(
91            '/<(?:[^<>]*?(?:(<\!--\{.+?\}-->)|(?R))[^<>]*?)*?>/s',
92            array($this, 'lfCaptureSmartyTagsInTag'),
93            $source
94        );
95
96        // 通常のノードに属する部分を、コメント形式に置換
97        $source = preg_replace_callback(
98            '/<\!--{.+?\}-->/s',
99            array($this, 'lfCaptureSmartyTags2Comment'),
100            $source
101        );
102
103        // HTMLタグの有無、BODYタグの有無で動作を切り替える
104        if (preg_match('/^(.*?)(<html[^>]*>.+<\/html>)(.*?)$/is', $source, $arrMatches)) {
105            $this->header_source = $arrMatches[1];
106            $source = $arrMatches[2];
107            $this->footer_source = $arrMatches[3];
108        }
109        elseif (preg_match('/^.*?<body[^>]*>.+<\/body>.*$/is', $source)) {
110            $source = '<meta http-equiv="content-type" content="text/html; charset=UTF-8" /><html><!--TemplateTransformer start-->'.$source.'<!--TemplateTransformer end--></html>';
111        }
112        else {
113            $source = '<meta http-equiv="content-type" content="text/html; charset=UTF-8" /><html><body><!--TemplateTransformer start-->'.$source.'<!--TemplateTransformer end--></body></html>';
114        }
115
116        @$this->objDOM->loadHTML($source);
117        $this->lfScanChild($this->objDOM);
118    }
119
120
121    /**
122     * jQueryライクなセレクタを用いてエレメントを選択する
123     *
124     * @param string  $selector      セレクタ
125     * @param integer $index         インデックス(指定がある場合)
126     * @param boolean $require       エレメントが見つからなかった場合、エラーとするか
127     * @param string  $err_msg       エラーメッセージ
128     * @return SC_Helper_Transformオブジェクト
129     */
130    public function select($selector, $index = NULL, $require = true, $err_msg = NULL) {
131        $this->arrSelectElements = array();
132        $this->search_depth = 0;
133
134        $regex = $this->lfSelector2Regex($selector);    // セレクタをツリー検索用正規表現に変換
135
136        $cur_idx = 0;
137        // ツリーを初めから全検索する
138        for ($iLoop=0; $iLoop < count($this->arrElementTree); $iLoop++) {
139            if (preg_match($regex, $this->arrElementTree[$iLoop][0])) {
140                // インデックスが指定されていない(見つけたエレメント全て)、もしくは指定されたインデックスなら選択する
141                if (is_null($index) || $cur_idx == $index) {
142                    $this->lfAddElement($iLoop, $this->arrElementTree[$iLoop]);
143                }
144                $cur_idx++;
145            }
146        }
147
148        // 見つからなかった場合エラーとするならエラーを記録する
149        if ($require && $cur_idx == 0) {
150            $this->lfSetError(
151                $selector,
152                self::ERR_TARGET_ELEMENT_NOT_FOUND,
153                $err_msg
154            );
155        }
156
157        return $this;
158    }
159
160
161    /**
162     * jQueryライクなセレクタを用いて、選択したエレメント内をさらに絞り込む
163     *
164     * @param string  $selector      セレクタ
165     * @param integer $index         インデックス(指定がある場合)
166     * @param boolean $require       エレメントが見つからなかった場合、エラーとするか
167     * @param string  $err_msg       エラーメッセージ
168     * @return SC_Helper_Transformオブジェクト
169     */
170    public function find($selector, $index = NULL, $require = true, $err_msg = NULL) {
171        $arrParentElements = $this->arrSelectElements[$this->search_depth];
172        $this->search_depth++;
173        $this->arrSelectElements[$this->search_depth] = array();
174
175        foreach ($arrParentElements as $key => &$objElement) {
176            $regex = $this->lfSelector2Regex($selector, $objElement[0]);    // セレクタをツリー検索用正規表現に変換(親要素のセレクタを頭に付ける)
177
178            $cur_idx = 0;
179            // 親エレメント位置からツリーを検索する
180            for ($iLoop=$objElement[0]; $iLoop < count($this->arrElementTree); $iLoop++) {
181                if (preg_match($regex, $this->arrElementTree[$iLoop][0])) {
182                    // インデックスが指定されていない(見つけたエレメント全て)、もしくは指定されたインデックスなら選択する
183                    if (is_null($index) || $cur_idx == $index) {
184                        $this->lfAddElement($iLoop, $this->arrElementTree[$iLoop]);
185                    }
186                    $cur_idx++;
187                }
188            }
189        }
190
191        // 見つからなかった場合エラーとするならエラーを記録する
192        if ($require && count($this->arrSelectElements[$this->search_depth]) == 0) {
193            $this->lfSetError(
194                $selector,
195                self::ERR_TARGET_ELEMENT_NOT_FOUND,
196                $err_msg
197            );
198        }
199
200        return $this;
201    }
202
203
204    /**
205     * 選択状態を指定数戻す
206     *
207     * @param int $back_num 選択状態を戻す数
208     * @return SC_Helper_Transformオブジェクト
209     */
210    public function end($back_num = 1) {
211        if ($this->search_depth >= $back_num) {
212            $this->search_depth -= $back_num;
213        } else {
214            $this->search_depth = 0;
215        }
216
217        return $this;
218    }
219
220
221    /**
222     * 要素の前にHTMLを挿入
223     *
224     * @param string $html_snip 挿入するHTMLの断片
225     * @return SC_Helper_Transformオブジェクト
226     */
227    public function insertBefore($html_snip) {
228        foreach ($this->arrSelectElements[$this->search_depth] as $key => $objElement) {
229            $this->lfSetTransform('insertBefore', $objElement[0], $html_snip);
230        }
231        return $this;
232    }
233
234
235    /**
236     * 要素の後にHTMLを挿入
237     *
238     * @param string $html_snip 挿入するHTMLの断片
239     * @return SC_Helper_Transformオブジェクト
240     */
241    public function insertAfter($html_snip) {
242        foreach ($this->arrSelectElements[$this->search_depth] as $key => $objElement) {
243            $this->lfSetTransform('insertAfter', $objElement[0], $html_snip);
244        }
245        return $this;
246    }
247
248
249    /**
250     * 要素の先頭にHTMLを挿入
251     *
252     * @param string $html_snip 挿入するHTMLの断片
253     * @return SC_Helper_Transformオブジェクト
254     */
255    public function appendFirst($html_snip) {
256        foreach ($this->arrSelectElements[$this->search_depth] as $key => $objElement) {
257            $this->lfSetTransform('appendFirst', $objElement[0], $html_snip);
258        }
259        return $this;
260    }
261
262
263    /**
264     * 要素の末尾にHTMLを挿入
265     *
266     * @param string $html_snip 挿入するHTMLの断片
267     * @return SC_Helper_Transformオブジェクト
268     */
269    public function appendChild($html_snip) {
270        foreach ($this->arrSelectElements[$this->search_depth] as $key => $objElement) {
271            $this->lfSetTransform('appendChild', $objElement[0], $html_snip);
272        }
273        return $this;
274    }
275
276
277    /**
278     * 要素を指定したHTMLに置換
279     *
280     * @param string $html_snip 置換後のHTMLの断片
281     * @return SC_Helper_Transformオブジェクト
282     */
283    public function replaceElement($html_snip) {
284        foreach ($this->arrSelectElements[$this->search_depth] as $key => &$objElement) {
285            $this->lfSetTransform('replaceElement', $objElement[0], $html_snip);
286        }
287        return $this;
288    }
289
290
291    /**
292     * 要素を削除する
293     *
294     * @return SC_Helper_Transformオブジェクト
295     */
296    public function removeElement() {
297        foreach ($this->arrSelectElements[$this->search_depth] as $key => &$objElement) {
298            $this->lfSetTransform('replaceElement', $objElement[0], '');
299        }
300        return $this;
301    }
302
303
304    /**
305     * HTMLに戻して、Transform用に付けたマーカーを削除し、Smartyのタグを復元する
306     *
307     * @return string トランスフォーム済みHTML。まったくトランスフォームが行われなかった場合は元のHTMLを返す。。
308     */
309    public function getHTML() {
310        if (count($this->arrErr)) {
311            // エラーメッセージ組み立て
312            $err_msg = '';
313            foreach ($this->arrErr as $arrErr) {
314                if ($arrErr['err_msg']) {
315                    $err_msg .= '<br />'.$arrErr['err_msg'];
316                } else {
317                    if ($arrErr['type'] == self::ERR_TARGET_ELEMENT_NOT_FOUND) {
318                        $err_msg .= "<br />${arrErr['selector']} が存在しません";
319                    } else {
320                        $err_msg .= '<br />'.print_r($arrErr, true);
321                    }
322                }
323            }
324            // エラー画面表示
325            SC_Utils_Ex::sfDispSiteError(FREE_ERROR_MSG, '', true, 'テンプレートの操作に失敗しました。' . $err_msg);
326        } elseif ($this->snip_count) {
327            $html = $this->objDOM->saveHTML();
328            $html = preg_replace('/^.*(<html[^>]*>)/s', '$1', $html);
329            $html = preg_replace('/(<\/html>).*$/s', '$1', $html);
330            $html = preg_replace('/^.*<\!--TemplateTransformer start-->/s', '', $html);
331            $html = preg_replace('/<\!--TemplateTransformer end-->.*$/s', '', $html);
332            $html = preg_replace(
333                '/<\!--TemplateTransformerSnip start-->.*?<\!--TemplateTransformerSnip end-->/s',
334                '',
335                $html
336            );
337            $html = $this->header_source.$html.$this->footer_source;
338            $html = str_replace($this->arrSmartyTagsSub, $this->arrSmartyTagsOrg, $html);
339            return $html;
340        } else {
341            return $this->html_source;
342        }
343    }
344
345
346
347
348    /**
349     * DOMの処理の邪魔になるSmartyのタグを代理文字に置換する preg_replace_callback のコールバック関数
350     *
351     * コメント形式への置換
352     *
353     * @param array $arrMatches マッチしたタグの情報
354     * @return string 代わりの文字列
355     */
356    protected function lfCaptureSmartyTags2Comment(array $arrMatches) {
357        $substitute_tag = sprintf('<!--###%08d###-->', $this->smarty_tags_idx);
358        $this->arrSmartyTagsOrg[$this->smarty_tags_idx] = $arrMatches[0];
359        $this->arrSmartyTagsSub[$this->smarty_tags_idx] = $substitute_tag;
360        $this->smarty_tags_idx++;
361        return $substitute_tag;
362    }
363
364
365    /**
366     * DOMの処理の邪魔になるSmartyのタグを代理文字に置換する preg_replace_callback のコールバック関数
367     *
368     * コメント形式への置換
369     *
370     * @param array $arrMatches マッチしたタグの情報
371     * @return string 代わりの文字列
372     */
373    protected function lfCaptureHeadTags2Comment(array $arrMatches) {
374        $substitute_tag = sprintf('<!--###%08d###-->', $this->smarty_tags_idx);
375        $this->arrSmartyTagsOrg[$this->smarty_tags_idx] = $arrMatches[2];
376        $this->arrSmartyTagsSub[$this->smarty_tags_idx] = $substitute_tag;
377        $this->smarty_tags_idx++;
378
379        // 文字化け防止用のMETAを入れておく
380        $content_type_tag = '<!--TemplateTransformerSnip start-->';
381        $content_type_tag .= '<meta http-equiv="content-type" content="text/html; charset=UTF-8" />';
382        $content_type_tag .= '<!--TemplateTransformerSnip end-->';
383
384        return $arrMatches[1].$content_type_tag.$substitute_tag.$arrMatches[3];
385    }
386
387
388    /**
389     * DOMの処理の邪魔になるSmartyのタグを代理文字に置換する preg_replace_callback のコールバック関数
390     *
391     * HTMLエレメント内部の処理
392     *
393     * @param array $arrMatches マッチしたタグの情報
394     * @return string 代わりの文字列
395     */
396    protected function lfCaptureSmartyTagsInTag(array $arrMatches) {
397        // Smartyタグ内のクォートを処理しやすいよう、いったんダミーのタグに
398        $html = preg_replace_callback('/<\!--{.+?\}-->/s', array($this, 'lfCaptureSmartyTags2Temptag'), $arrMatches[0]);
399        $html = preg_replace_callback('/\"[^"]*?\"/s', array($this, 'lfCaptureSmartyTagsInQuote'), $html);
400        $html = preg_replace_callback('/###TEMP(\d{8})###/s', array($this, 'lfCaptureSmartyTags2Attr'), $html);
401        return $html;
402    }
403
404
405    /**
406     * DOMの処理の邪魔になるSmartyのタグを代理文字に置換する preg_replace_callback のコールバック関数
407     *
408     * ダミーへの置換実行
409     *
410     * @param array $arrMatches マッチしたタグの情報
411     * @return string 代わりの文字列
412     */
413    protected function lfCaptureSmartyTags2Temptag(array $arrMatches) {
414        $substitute_tag = sprintf('###TEMP%08d###', $this->smarty_tags_idx);
415        $this->arrSmartyTagsOrg[$this->smarty_tags_idx] = $arrMatches[0];
416        $this->arrSmartyTagsSub[$this->smarty_tags_idx] = $substitute_tag;
417        $this->smarty_tags_idx++;
418        return $substitute_tag;
419    }
420
421
422    /**
423     * DOMの処理の邪魔になるSmartyのタグを代理文字に置換する preg_replace_callback のコールバック関数
424     *
425     * クォート内(=属性値)内にあるSmartyタグ(ダミーに置換済み)を、テキストに置換
426     *
427     * @param array $arrMatches マッチしたタグの情報
428     * @return string 代わりの文字列
429     */
430    protected function lfCaptureSmartyTagsInQuote(array $arrMatches) {
431        $html = preg_replace_callback(
432            '/###TEMP(\d{8})###/s',
433            array($this, 'lfCaptureSmartyTags2Value'),
434            $arrMatches[0]
435        );
436        return $html;
437    }
438
439
440    /**
441     * DOMの処理の邪魔になるSmartyのタグを代理文字に置換する preg_replace_callback のコールバック関数
442     *
443     * テキストへの置換実行
444     *
445     * @param array $arrMatches マッチしたタグの情報
446     * @return string 代わりの文字列
447     */
448    protected function lfCaptureSmartyTags2Value(array $arrMatches) {
449        $tag_idx = (int)$arrMatches[1];
450        $substitute_tag = sprintf('###%08d###', $tag_idx);
451        $this->arrSmartyTagsSub[$tag_idx] = $substitute_tag;
452        return $substitute_tag;
453    }
454
455
456    /**
457     * DOMの処理の邪魔になるSmartyのタグを代理文字に置換する preg_replace_callback のコールバック関数
458     *
459     * エレメント内部にあって、属性値ではないものを、ダミーの属性として置換
460     *
461     * @param array $arrMatches マッチしたタグの情報
462     * @return string 代わりの文字列
463     */
464    protected function lfCaptureSmartyTags2Attr(array $arrMatches) {
465        $tag_idx = (int)$arrMatches[1];
466        $substitute_tag = sprintf('rel%08d="######"', $tag_idx);
467        $this->arrSmartyTagsSub[$tag_idx] = $substitute_tag;
468        return ' '.$substitute_tag.' '; // 属性はパース時にスペースが詰まるので、こちらにはスペースを入れておく
469    }
470
471
472    /**
473     * DOM Element / Document を走査し、name、class別に分類する
474     *
475     * @param  DOMNode $objDOMElement DOMNodeオブジェクト
476     * @return void
477     */
478    protected function lfScanChild(DOMNode $objDOMElement, $parent_selector = '') {
479        $objNodeList = $objDOMElement->childNodes;
480        if (is_null($objNodeList)) return;
481
482        foreach ($objNodeList as $element) {
483            // DOMElementのみ取り出す
484            if ($element instanceof DOMElement) {
485                $arrAttr = array();
486                $arrAttr[] = $element->tagName;
487                if (method_exists($element, 'getAttribute')) {
488                    // idを持っていればidを付加する
489                    if ($element->hasAttribute('id'))
490                        $arrAttr[] = '#'.$element->getAttribute('id');
491                    // classを持っていればclassを付加する(複数の場合は複数付加する)
492                    if ($element->hasAttribute('class')) {
493                        $arrClasses = preg_split('/\s+/', $element->getAttribute('class'));
494                        foreach ($arrClasses as $classname) $arrAttr[] = '.'.$classname;
495                    }
496                }
497                // 親要素のセレクタを付けてツリーへ登録する
498                $this_selector = $parent_selector.' '.implode('', $arrAttr);
499                $this->arrElementTree[] = array($this_selector, $element);
500                // エレメントが子孫要素を持っていればさらに調べる
501                if ($element->hasChildNodes()) $this->lfScanChild($element, $this_selector);
502            }
503        }
504    }
505
506
507    /**
508     * セレクタ文字列をツリー検索用の正規表現に変換する
509     *
510     * @param string $selector      セレクタ
511     * @param string $parent_index  セレクタ検索時の親要素の位置(子孫要素検索のため)
512     * @return string 正規表現文字列
513     */
514    protected function lfSelector2Regex($selector, $parent_index = NULL){
515        // jQueryライクなセレクタを正規表現に
516        $selector = preg_replace('/ *> */', ' >', $selector);   // 子セレクタをツリー検索用に 「A >B」の記法にする
517        $regex = '/';
518        if (!is_null($parent_index)) $regex .= preg_quote($this->arrElementTree[$parent_index][0], '/');    // (親要素の指定(絞り込み時)があれば頭に付加する(特殊文字はエスケープ)
519        $arrSelectors = explode(' ', $selector);
520        foreach ($arrSelectors as $sub_selector) {
521            if (preg_match('/^(>?)([\w\-]+)?(#[\w\-]+)?(\.[\w\-]+)*$/', $sub_selector, $arrMatch)) {
522                // 子セレクタ
523                if (isset($arrMatch[1]) && $arrMatch[1]) $regex .= ' ';
524                else $regex .= '.* ';
525                // タグ名
526                if (isset($arrMatch[2]) && $arrMatch[2]) $regex .= preg_quote($arrMatch[2], '/');
527                else $regex .= '([\w\-]+)?';
528                // id
529                if (isset($arrMatch[3]) && $arrMatch[3]) $regex .= preg_quote($arrMatch[3], '/');
530                else $regex .= '(#(\w|\-|#{3}[0-9]{8}#{3})+)?';
531                // class
532                if (isset($arrMatch[4]) && $arrMatch[4]) $regex .= '(\.(\w|\-|#{3}[0-9]{8}#{3})+)*'.preg_quote($arrMatch[4], '/').'(\.(\w|\-|#{3}[0-9]{8}#{3})+)*'; // class指定の時は前後にもclassが付いているかもしれない
533                else $regex .= '(\.(\w|\-|#{3}[0-9]{8}#{3})+)*';
534            }
535        }
536        $regex .= '$/i';
537
538        return $regex;
539    }
540
541
542    /**
543     * 見つかった要素をプロパティに登録
544     *
545     * @param integer $elementNo  エレメントのインデックス
546     * @param array   $arrElement インデックスとDOMオブジェクトをペアとした配列
547     * @return void
548     */
549    protected function lfAddElement($elementNo, array &$arrElement) {
550        if (!array_key_exists($arrElement[0], $this->arrSelectElements[$this->search_depth])) {
551            $this->arrSelectElements[$this->search_depth][$arrElement[0]] = array($elementNo, &$arrElement[1]);
552        }
553    }
554
555
556    /**
557     * DOMを用いた変形を実行する
558     *
559     * @param string $mode       実行するメソッドの種類
560     * @param string $target_key 対象のエレメントの完全なセレクタ
561     * @param string $html_snip  HTMLコード
562     * @return boolean
563     */
564    protected function lfSetTransform($mode, $target_key, $html_snip) {
565
566        $substitute_tag = sprintf('<!--###%08d###-->', $this->smarty_tags_idx);
567        $this->arrSmartyTagsOrg[$this->smarty_tags_idx] = $html_snip;
568        $this->arrSmartyTagsSub[$this->smarty_tags_idx] = $substitute_tag;
569        $this->smarty_tags_idx++;
570
571        $this->objDOM->createDocumentFragment();
572        $objSnip = $this->objDOM->createDocumentFragment();
573        $objSnip->appendXML($substitute_tag);
574
575        $objElement = false;
576        if (isset($this->arrElementTree[$target_key]) && $this->arrElementTree[$target_key][0]) {
577            $objElement = &$this->arrElementTree[$target_key][1];
578        }
579
580        if (!$objElement) return false;
581
582        try {
583            switch ($mode) {
584                case 'appendFirst':
585                    if ($objElement->hasChildNodes()) {
586                        $objElement->insertBefore($objSnip, $objElement->firstChild);
587                    } else {
588                        $objElement->appendChild($objSnip);
589                    }
590                    break;
591                case 'appendChild':
592                    $objElement->appendChild($objSnip);
593                    break;
594                case 'insertBefore':
595                    if (!is_object($objElement->parentNode)) return false;
596                    $objElement->parentNode->insertBefore($objSnip, $objElement);
597                    break;
598                case 'insertAfter':
599                    if ($objElement->nextSibling) {
600                         $objElement->parentNode->insertBefore($objSnip, $objElement->nextSibling);
601                    } else {
602                         $objElement->parentNode->appendChild($objSnip);
603                    }
604                    break;
605                case 'replaceElement':
606                    if (!is_object($objElement->parentNode)) return false;
607                    $objElement->parentNode->replaceChild($objSnip, $objElement);
608                    break;
609                default:
610                    break;
611            }
612            $this->snip_count++;
613        }
614        catch (Exception $e) {
615            SC_Utils_Ex::sfDispSiteError(FREE_ERROR_MSG, '', true, 'テンプレートの操作に失敗しました。');
616        }
617
618        return true;
619    }
620
621
622    /**
623     * セレクタエラーを記録する
624     *
625     * @param string  $selector    セレクタ
626     * @param integer $type        エラーの種類
627     * @param string  $err_msg     エラーメッセージ
628     * @return void
629     */
630    protected function lfSetError($selector, $type, $err_msg = NULL) {
631        $this->arrErr[] = array(
632            'selector'    => $selector,
633            'type'        => $type,
634            'err_msg'     => $err_msg
635        );
636    }
637}
Note: See TracBrowser for help on using the repository browser.