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

Revision 21886, 24.8 KB checked in by Seasoft, 12 years ago (diff)

#1848 (SC_Helper_Transform#construct エラー文言が不親切かも)

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