Merge branch 'master' of github.com:gnuboard/yc5

This commit is contained in:
kagla
2015-11-02 13:51:58 +09:00
179 changed files with 32988 additions and 25498 deletions

View File

@ -12,6 +12,7 @@ $menu['menu100'] = array (
array('100910', '캡챠파일 일괄삭제',G5_ADMIN_URL.'/captcha_file_delete.php', 'cf_captcha', 1), array('100910', '캡챠파일 일괄삭제',G5_ADMIN_URL.'/captcha_file_delete.php', 'cf_captcha', 1),
array('100920', '썸네일파일 일괄삭제',G5_ADMIN_URL.'/thumbnail_file_delete.php', 'cf_thumbnail', 1), array('100920', '썸네일파일 일괄삭제',G5_ADMIN_URL.'/thumbnail_file_delete.php', 'cf_thumbnail', 1),
array('100500', 'phpinfo()', G5_ADMIN_URL.'/phpinfo.php', 'cf_phpinfo'), array('100500', 'phpinfo()', G5_ADMIN_URL.'/phpinfo.php', 'cf_phpinfo'),
array('100510', 'Browscap 업데이트', G5_ADMIN_URL.'/browscap.php', 'cf_browscap'),
array('100400', '부가서비스', G5_ADMIN_URL.'/service.php', 'cf_service') array('100400', '부가서비스', G5_ADMIN_URL.'/service.php', 'cf_service')
); );
?> ?>

View File

@ -95,26 +95,26 @@ $sql = " insert into {$g5['board_table']}
bo_use_cert = '{$board[bo_use_cert]}', bo_use_cert = '{$board[bo_use_cert]}',
bo_use_sns = '{$board[bo_use_sns]}', bo_use_sns = '{$board[bo_use_sns]}',
bo_sort_field = '{$board['bo_sort_field']}', bo_sort_field = '{$board['bo_sort_field']}',
bo_1_subj = '{$board['bo_1_subj']}', bo_1_subj = '".addslashes($board['bo_1_subj'])."',
bo_2_subj = '{$board['bo_2_subj']}', bo_2_subj = '".addslashes($board['bo_2_subj'])."',
bo_3_subj = '{$board['bo_3_subj']}', bo_3_subj = '".addslashes($board['bo_3_subj'])."',
bo_4_subj = '{$board['bo_4_subj']}', bo_4_subj = '".addslashes($board['bo_4_subj'])."',
bo_5_subj = '{$board['bo_5_subj']}', bo_5_subj = '".addslashes($board['bo_5_subj'])."',
bo_6_subj = '{$board['bo_6_subj']}', bo_6_subj = '".addslashes($board['bo_6_subj'])."',
bo_7_subj = '{$board['bo_7_subj']}', bo_7_subj = '".addslashes($board['bo_7_subj'])."',
bo_8_subj = '{$board['bo_8_subj']}', bo_8_subj = '".addslashes($board['bo_8_subj'])."',
bo_9_subj = '{$board['bo_9_subj']}', bo_9_subj = '".addslashes($board['bo_9_subj'])."',
bo_10_subj = '{$board['bo_10_subj']}', bo_10_subj = '".addslashes($board['bo_10_subj'])."',
bo_1 = '{$board['bo_1']}', bo_1 = '".addslashes($board['bo_1'])."',
bo_2 = '{$board['bo_2']}', bo_2 = '".addslashes($board['bo_2'])."',
bo_3 = '{$board['bo_3']}', bo_3 = '".addslashes($board['bo_3'])."',
bo_4 = '{$board['bo_4']}', bo_4 = '".addslashes($board['bo_4'])."',
bo_5 = '{$board['bo_5']}', bo_5 = '".addslashes($board['bo_5'])."',
bo_6 = '{$board['bo_6']}', bo_6 = '".addslashes($board['bo_6'])."',
bo_7 = '{$board['bo_7']}', bo_7 = '".addslashes($board['bo_7'])."',
bo_8 = '{$board['bo_8']}', bo_8 = '".addslashes($board['bo_8'])."',
bo_9 = '{$board['bo_9']}', bo_9 = '".addslashes($board['bo_9'])."',
bo_10 = '{$board['bo_10']}' "; bo_10 = '".addslashes($board['bo_10'])."' ";
sql_query($sql, false); sql_query($sql, false);
// 게시판 폴더 생성 // 게시판 폴더 생성

42
adm/browscap.php Normal file
View File

@ -0,0 +1,42 @@
<?php
$sub_menu = "100510";
include_once('./_common.php');
if ($is_admin != 'super')
alert('최고관리자만 접근 가능합니다.');
$g5['title'] = 'Browscap 업데이트';
include_once('./admin.head.php');
?>
<div id="processing">
<p>Browscap 정보를 업데이트하시려면 아래 업데이트 버튼을 클릭해 주세요.</p>
<div><button type="button" id="run_update">업데이트</button>
</div>
<script>
$(function() {
$("#run_update").on("click", function() {
$("#processing").html('<div class="update_processing"></div><p>Browscap 정보를 업데이트 중입니다.</p>');
$.ajax({
url: "./browscap_update.php",
async: true,
cache: false,
dataType: "html",
success: function(data) {
if(data != "") {
alert(data);
return false;
}
$("#processing").html("<div class='check_processing'></div><p>Browscap 정보를 업데이트 했습니다.</p>");
}
});
});
});
</script>
<?php
include_once('./admin.tail.php');
?>

21
adm/browscap_update.php Normal file
View File

@ -0,0 +1,21 @@
<?php
ini_set('memory_limit', '-1');
$sub_menu = "100510";
include_once('./_common.php');
// clean the output buffer
ob_end_clean();
if ($is_admin != 'super')
die('최고관리자만 접근 가능합니다.');
include_once(G5_PLUGIN_PATH.'/browscap/Browscap.php');
$browscap = new phpbrowscap\Browscap(G5_DATA_PATH.'/cache');
$browscap->updateMethod = 'cURL';
$browscap->cacheFilename = 'browscap_cache.php';
$browscap->updateCache();
die('');
?>

View File

@ -186,6 +186,14 @@ if(!isset($config['cf_sms_type'])) {
ADD `cf_sms_type` varchar(10) NOT NULL DEFAULT '' AFTER `cf_sms_use` ", true); ADD `cf_sms_type` varchar(10) NOT NULL DEFAULT '' AFTER `cf_sms_use` ", true);
} }
// 접속자 정보 필드 추가
if(!sql_query(" select vi_browser from {$g5['visit_table']} limit 1 ")) {
sql_query(" ALTER TABLE `{$g5['visit_table']}`
ADD `vi_browser` varchar(255) NOT NULL DEFAULT '' AFTER `vi_agent`,
ADD `vi_os` varchar(255) NOT NULL DEFAULT '' AFTER `vi_browser`,
ADD `vi_device` varchar(255) NOT NULL DEFAULT '' AFTER `vi_os` ", true);
}
if(!$config['cf_faq_skin']) $config['cf_faq_skin'] = "basic"; if(!$config['cf_faq_skin']) $config['cf_faq_skin'] = "basic";
if(!$config['cf_mobile_faq_skin']) $config['cf_mobile_faq_skin'] = "basic"; if(!$config['cf_mobile_faq_skin']) $config['cf_mobile_faq_skin'] = "basic";

View File

@ -432,6 +432,9 @@ td.td_grpset {width:160px;border-left:1px solid #e9ecee;text-align:center}
.td_tel {width:80px;text-align:center} .td_tel {width:80px;text-align:center}
.td_telbig {width:100px;text-align:center} .td_telbig {width:100px;text-align:center}
.td_test {width:50px;text-align:center} .td_test {width:50px;text-align:center}
.td_category1{width:130px;text-align:center}
.td_category2{width:100px;text-align:center}
.td_category3{width:80px;text-align:center}
.txt_true {color:#e8180c} .txt_true {color:#e8180c}
.txt_false {color:#ccc} .txt_false {color:#ccc}
@ -931,3 +934,10 @@ strong.sodr_nonpay {display:block;padding:5px 0;text-align:right}
.sms_table{padding:0 20px 40px;} .sms_table{padding:0 20px 40px;}
.sms_table table th{border:1px solid #ddd;padding:9px 0} .sms_table table th{border:1px solid #ddd;padding:9px 0}
.sms_table table td{border:1px solid #ddd;text-align:center;width:16%;padding:9px 0} .sms_table table td{border:1px solid #ddd;text-align:center;width:16%;padding:9px 0}
/* Browscap */
.update_processing{width:300px;height:300px;margin:0 auto;background:url(../img/ajax_loader.gif) no-repeat 0 0}
#processing{margin: 0 auto;padding: 70px 0;max-width: 800px;border: 1px solid #eee;background: #f9f9f9;text-align:center;}
#processing p{font-size:1.2em}
.check_processing {width:300px;height:300px;margin:0 auto;background:url(../img/check.png) no-repeat 50% 50% }
#processing button{background:#ff3061;border:none;color:#fff;padding: 15px;width:150px;margin-top:15px}

BIN
adm/img/ajax_loader.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

BIN
adm/img/check.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

View File

@ -29,6 +29,7 @@ $query_string = $qstr ? '?'.$qstr : '';
<li><a href="./visit_domain.php<?php echo $query_string ?>">도메인</a></li> <li><a href="./visit_domain.php<?php echo $query_string ?>">도메인</a></li>
<li><a href="./visit_browser.php<?php echo $query_string ?>">브라우저</a></li> <li><a href="./visit_browser.php<?php echo $query_string ?>">브라우저</a></li>
<li><a href="./visit_os.php<?php echo $query_string ?>">운영체제</a></li> <li><a href="./visit_os.php<?php echo $query_string ?>">운영체제</a></li>
<li><a href="./visit_device.php<?php echo $query_string ?>">접속기기</a></li>
<li><a href="./visit_hour.php<?php echo $query_string ?>">시간</a></li> <li><a href="./visit_hour.php<?php echo $query_string ?>">시간</a></li>
<li><a href="./visit_week.php<?php echo $query_string ?>">요일</a></li> <li><a href="./visit_week.php<?php echo $query_string ?>">요일</a></li>
<li><a href="./visit_date.php<?php echo $query_string ?>">일</a></li> <li><a href="./visit_date.php<?php echo $query_string ?>">일</a></li>

View File

@ -15,7 +15,9 @@ $sql = " select * from {$g5['visit_table']}
where vi_date between '{$fr_date}' and '{$to_date}' "; where vi_date between '{$fr_date}' and '{$to_date}' ";
$result = sql_query($sql); $result = sql_query($sql);
while ($row=sql_fetch_array($result)) { while ($row=sql_fetch_array($result)) {
$s = get_brow($row['vi_agent']); $s = $row['vi_browser'];
if(!$s)
$s = get_brow($row['vi_agent']);
$arr[$s]++; $arr[$s]++;
@ -70,7 +72,7 @@ while ($row=sql_fetch_array($result)) {
<tr class="<?php echo $bg; ?>"> <tr class="<?php echo $bg; ?>">
<td class="td_num"><?php echo $no ?></td> <td class="td_num"><?php echo $no ?></td>
<td class="td_category"><?php echo $key ?></td> <td class="td_category td_category1"><?php echo $key ?></td>
<td> <td>
<div class="visit_bar"> <div class="visit_bar">
<span style="width:<?php echo $s_rate ?>%"></span> <span style="width:<?php echo $s_rate ?>%"></span>

101
adm/visit_device.php Normal file
View File

@ -0,0 +1,101 @@
<?php
$sub_menu = "200800";
include_once('./_common.php');
auth_check($auth[$sub_menu], 'r');
$g5['title'] = '기기별 접속자집계';
include_once('./visit.sub.php');
$colspan = 5;
$max = 0;
$sum_count = 0;
$sql = " select * from {$g5['visit_table']}
where vi_date between '$fr_date' and '$to_date' ";
$result = sql_query($sql);
while ($row=sql_fetch_array($result)) {
$s = $row['vi_device'];
if(!$s)
$s = get_device($row['vi_agent']);
$arr[$s]++;
if ($arr[$s] > $max) $max = $arr[$s];
$sum_count++;
}
?>
<div class="tbl_head01 tbl_wrap">
<table>
<caption><?php echo $g5['title']; ?> 목록</caption>
<thead>
<tr>
<th scope="col">순위</th>
<th scope="col">접속기기</th>
<th scope="col">그래프</th>
<th scope="col">접속자수</th>
<th scope="col">비율(%)</th>
</tr>
</thead>
<tfoot>
<tr>
<td colspan="3">합계</td>
<td><strong><?php echo $sum_count ?></strong></td>
<td>100%</td>
</tr>
</tfoot>
<tbody>
<?php
$i = 0;
$k = 0;
$save_count = -1;
$tot_count = 0;
if (count($arr)) {
arsort($arr);
foreach ($arr as $key=>$value) {
$count = $arr[$key];
if ($save_count != $count) {
$i++;
$no = $i;
$save_count = $count;
} else {
$no = '';
}
if (!$key) {
$key = 'Unknown';
}
$rate = ($count / $sum_count * 100);
$s_rate = number_format($rate, 1);
$bg = 'bg'.($i%2);
?>
<tr class="<?php echo $bg; ?>">
<td class="td_num"><?php echo $no ?></td>
<td class="td_category td_category1"><?php echo $key ?></td>
<td>
<div class="visit_bar">
<span style="width:<?php echo $s_rate ?>%"></span>
</div>
</td>
<td class="td_numbig"><?php echo $count ?></td>
<td class="td_num"><?php echo $s_rate ?></td>
</tr>
<?php
}
} else {
echo '<tr><td colspan="'.$colspan.'" class="empty_table">자료가 없습니다.</td></tr>';
}
?>
</tbody>
</table>
</div>
<?php
include_once('./admin.tail.php');
?>

View File

@ -7,7 +7,7 @@ auth_check($auth[$sub_menu], 'r');
$g5['title'] = '접속자집계'; $g5['title'] = '접속자집계';
include_once('./visit.sub.php'); include_once('./visit.sub.php');
$colspan = 5; $colspan = 6;
$sql_common = " from {$g5['visit_table']} "; $sql_common = " from {$g5['visit_table']} ";
$sql_search = " where vi_date between '{$fr_date}' and '{$to_date}' "; $sql_search = " where vi_date between '{$fr_date}' and '{$to_date}' ";
@ -41,15 +41,25 @@ $result = sql_query($sql);
<th scope="col">IP</th> <th scope="col">IP</th>
<th scope="col">접속 경로</th> <th scope="col">접속 경로</th>
<th scope="col">브라우저</th> <th scope="col">브라우저</th>
<th scope="col">운영체제</th> <th scope="col">OS</th>
<th scope="col">접속기기</th>
<th scope="col">일시</th> <th scope="col">일시</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<?php <?php
for ($i=0; $row=sql_fetch_array($result); $i++) { for ($i=0; $row=sql_fetch_array($result); $i++) {
$brow = get_brow($row['vi_agent']); $brow = $row['vi_browser'];
$os = get_os($row['vi_agent']); if(!$brow)
$brow = get_brow($row['vi_agent']);
$os = $row['vi_os'];
if(!$os)
$os = get_os($row['vi_agent']);
$device = $row['vi_device'];
if(!$device)
$device = get_device($row['vi_agent']);
$link = ''; $link = '';
$link2 = ''; $link2 = '';
@ -83,8 +93,9 @@ $result = sql_query($sql);
<tr class="<?php echo $bg; ?>"> <tr class="<?php echo $bg; ?>">
<td class="td_category"><?php echo $ip ?></td> <td class="td_category"><?php echo $ip ?></td>
<td><?php echo $link ?><?php echo $title ?><?php echo $link2 ?></td> <td><?php echo $link ?><?php echo $title ?><?php echo $link2 ?></td>
<td class="td_category"><?php echo $brow ?></td> <td class="td_category td_category1"><?php echo $brow ?></td>
<td class="td_category"><?php echo $os ?></td> <td class="td_category td_category3"><?php echo $os ?></td>
<td class="td_category td_category2"><?php echo $device; ?></td>
<td class="td_datetime"><?php echo $row['vi_date'] ?> <?php echo $row['vi_time'] ?></td> <td class="td_datetime"><?php echo $row['vi_date'] ?> <?php echo $row['vi_time'] ?></td>
</tr> </tr>

View File

@ -15,7 +15,9 @@ $sql = " select * from {$g5['visit_table']}
where vi_date between '$fr_date' and '$to_date' "; where vi_date between '$fr_date' and '$to_date' ";
$result = sql_query($sql); $result = sql_query($sql);
while ($row=sql_fetch_array($result)) { while ($row=sql_fetch_array($result)) {
$s = get_os($row['vi_agent']); $s = $row['vi_os'];
if(!$s)
$s = get_os($row['vi_agent']);
$arr[$s]++; $arr[$s]++;
@ -63,7 +65,7 @@ while ($row=sql_fetch_array($result)) {
} }
if (!$key) { if (!$key) {
$key = '직접'; $key = 'Unknown';
} }
$rate = ($count / $sum_count * 100); $rate = ($count / $sum_count * 100);

View File

@ -9,7 +9,7 @@ $g5['title'] = '접속자검색';
include_once('./admin.head.php'); include_once('./admin.head.php');
include_once(G5_PLUGIN_PATH.'/jquery-ui/datepicker.php'); include_once(G5_PLUGIN_PATH.'/jquery-ui/datepicker.php');
$colspan = 5; $colspan = 6;
$listall = '<a href="'.$_SERVER['SCRIPT_NAME'].'">처음</a>'; //페이지 처음으로 (초기화용도) $listall = '<a href="'.$_SERVER['SCRIPT_NAME'].'">처음</a>'; //페이지 처음으로 (초기화용도)
?> ?>
@ -36,6 +36,7 @@ $listall = '<a href="'.$_SERVER['SCRIPT_NAME'].'">처음</a>'; //페이지 처
<th scope="col">접속 경로</th> <th scope="col">접속 경로</th>
<th scope="col">브라우저</th> <th scope="col">브라우저</th>
<th scope="col">OS</th> <th scope="col">OS</th>
<th scope="col">접속기기</th>
<th scope="col">일시</th> <th scope="col">일시</th>
</tr> </tr>
</thead> </thead>
@ -68,8 +69,17 @@ $listall = '<a href="'.$_SERVER['SCRIPT_NAME'].'">처음</a>'; //페이지 처
$result = sql_query($sql); $result = sql_query($sql);
for ($i=0; $row=sql_fetch_array($result); $i++) { for ($i=0; $row=sql_fetch_array($result); $i++) {
$brow = get_brow($row['vi_agent']); $brow = $row['vi_browser'];
$os = get_os($row['vi_agent']); if(!$brow)
$brow = get_brow($row['vi_agent']);
$os = $row['vi_os'];
if(!$os)
$os = get_os($row['vi_agent']);
$device = $row['vi_device'];
if(!$device)
$device = get_device($row['vi_agent']);
$link = ""; $link = "";
$referer = ""; $referer = "";
@ -92,16 +102,14 @@ $listall = '<a href="'.$_SERVER['SCRIPT_NAME'].'">처음</a>'; //페이지 처
else else
$ip = preg_replace("/([0-9]+).([0-9]+).([0-9]+).([0-9]+)/", G5_IP_DISPLAY, $row['vi_ip']); $ip = preg_replace("/([0-9]+).([0-9]+).([0-9]+).([0-9]+)/", G5_IP_DISPLAY, $row['vi_ip']);
if ($brow == '기타') $brow = '<span title="'.get_text($row['vi_agent']).'">'.$brow.'</span>';
if ($os == '기타') $os = '<span title="'.get_text($row['vi_agent']).'">'.$os.'</span>';
$bg = 'bg'.($i%2); $bg = 'bg'.($i%2);
?> ?>
<tr class="<?php echo $bg; ?>"> <tr class="<?php echo $bg; ?>">
<td class="td_id"><a href="<?php echo $_SERVER['SCRIPT_NAME']; ?>?sfl=vi_ip&amp;stx=<?php echo $ip; ?>"><?php echo $ip; ?></a></td> <td class="td_id"><a href="<?php echo $_SERVER['SCRIPT_NAME']; ?>?sfl=vi_ip&amp;stx=<?php echo $ip; ?>"><?php echo $ip; ?></a></td>
<td><?php echo $link.$title; ?></a></td> <td><?php echo $link.$title; ?></a></td>
<td class="td_idsmall"><?php echo $brow; ?></td> <td class="td_idsmall td_category1"><?php echo $brow; ?></td>
<td class="td_idsmall"><?php echo $os; ?></td> <td class="td_idsmall td_category3"><?php echo $os; ?></td>
<td class="td_idsmall td_category2"><?php echo $device; ?></td>
<td class="td_datetime"><a href="<?php echo $_SERVER['SCRIPT_NAME']; ?>?sfl=vi_date&amp;stx=<?php echo $row['vi_date']; ?>"><?php echo $row['vi_date']; ?></a> <?php echo $row['vi_time']; ?></td> <td class="td_datetime"><a href="<?php echo $_SERVER['SCRIPT_NAME']; ?>?sfl=vi_date&amp;stx=<?php echo $row['vi_date']; ?>"><?php echo $row['vi_date']; ?></a> <?php echo $row['vi_time']; ?></td>
</tr> </tr>
<?php } ?> <?php } ?>

View File

@ -62,6 +62,17 @@ $mb_8 = isset($_POST['mb_8']) ? trim($_POST['mb_8'])
$mb_9 = isset($_POST['mb_9']) ? trim($_POST['mb_9']) : ""; $mb_9 = isset($_POST['mb_9']) ? trim($_POST['mb_9']) : "";
$mb_10 = isset($_POST['mb_10']) ? trim($_POST['mb_10']) : ""; $mb_10 = isset($_POST['mb_10']) ? trim($_POST['mb_10']) : "";
$mb_name = clean_xss_tags($mb_name);
$mb_email = get_email_address($mb_email);
$mb_homepage = clean_xss_tags($mb_homepage);
$mb_tel = clean_xss_tags($mb_tel);
$mb_zip1 = preg_replace('/[^0-9]/', '', $mb_zip1);
$mb_zip2 = preg_replace('/[^0-9]/', '', $mb_zip2);
$mb_addr1 = clean_xss_tags($mb_addr1);
$mb_addr2 = clean_xss_tags($mb_addr2);
$mb_addr3 = clean_xss_tags($mb_addr3);
$mb_addr_jibeon = preg_match("/^(N|R)$/", $mb_addr_jibeon) ? $mb_addr_jibeon : '';
if ($w == '' || $w == 'u') { if ($w == '' || $w == 'u') {
if ($msg = empty_mb_id($mb_id)) alert($msg, "", true, true); // alert($msg, $url, $error, $post); if ($msg = empty_mb_id($mb_id)) alert($msg, "", true, true); // alert($msg, $url, $error, $post);
@ -119,17 +130,6 @@ if ($w == '' || $w == 'u') {
if ($msg = exist_mb_email($mb_email, $mb_id)) alert($msg, "", true, true); if ($msg = exist_mb_email($mb_email, $mb_id)) alert($msg, "", true, true);
} }
$mb_name = clean_xss_tags($mb_name);
$mb_email = get_email_address($mb_email);
$mb_homepage = clean_xss_tags($mb_homepage);
$mb_tel = clean_xss_tags($mb_tel);
$mb_zip1 = preg_replace('/[^0-9]/', '', $mb_zip1);
$mb_zip2 = preg_replace('/[^0-9]/', '', $mb_zip2);
$mb_addr1 = clean_xss_tags($mb_addr1);
$mb_addr2 = clean_xss_tags($mb_addr2);
$mb_addr3 = clean_xss_tags($mb_addr3);
$mb_addr_jibeon = preg_match("/^(N|R)$/", $mb_addr_jibeon) ? $mb_addr_jibeon : '';
// 사용자 코드 실행 // 사용자 코드 실행
@include_once($member_skin_path.'/register_form_update.head.skin.php'); @include_once($member_skin_path.'/register_form_update.head.skin.php');

View File

@ -15,7 +15,14 @@ if (get_cookie('ck_visit_ip') != $_SERVER['REMOTE_ADDR'])
if (isset($_SERVER['HTTP_REFERER'])) if (isset($_SERVER['HTTP_REFERER']))
$referer = escape_trim(clean_xss_tags($_SERVER['HTTP_REFERER'])); $referer = escape_trim(clean_xss_tags($_SERVER['HTTP_REFERER']));
$user_agent = escape_trim(clean_xss_tags($_SERVER['HTTP_USER_AGENT'])); $user_agent = escape_trim(clean_xss_tags($_SERVER['HTTP_USER_AGENT']));
$sql = " insert {$g5['visit_table']} ( vi_id, vi_ip, vi_date, vi_time, vi_referer, vi_agent ) values ( '{$vi_id}', '{$remote_addr}', '".G5_TIME_YMD."', '".G5_TIME_HIS."', '{$referer}', '{$user_agent}' ) "; // Browscap 캐시 파일이 있으면 실행
if(is_file(G5_DATA_PATH.'/cache/browscap_cache.php')) {
$browscap = get_browscap_info($_SERVER['HTTP_USER_AGENT']);
$vi_browser = $browscap->Comment;
$vi_os = $browscap->Platform;
$vi_device = $browscap->Device_Type;
}
$sql = " insert {$g5['visit_table']} ( vi_id, vi_ip, vi_date, vi_time, vi_referer, vi_agent, vi_browser, vi_os, vi_device ) values ( '{$vi_id}', '{$remote_addr}', '".G5_TIME_YMD."', '".G5_TIME_HIS."', '{$referer}', '{$user_agent}', '{$vi_browser}', '{$vi_os}', '{$vi_device}' ) ";
$result = sql_query($sql, FALSE); $result = sql_query($sql, FALSE);
// 정상으로 INSERT 되었다면 방문자 합계에 반영 // 정상으로 INSERT 되었다면 방문자 합계에 반영

View File

@ -9,8 +9,9 @@ define('G5_VERSION', '그누보드5');
define('G5_GNUBOARD_VER', '5.1.3');
define('G5_YOUNGCART_VER', '5.1.2'); define('G5_GNUBOARD_VER', '5.1.5');
define('G5_YOUNGCART_VER', '5.1.4');
// 이 상수가 정의되지 않으면 각각의 개별 페이지는 별도로 실행될 수 없음 // 이 상수가 정의되지 않으면 각각의 개별 페이지는 별도로 실행될 수 없음
define('_GNUBOARD_', true); define('_GNUBOARD_', true);

View File

@ -562,8 +562,9 @@ function html_purifier($html)
$config = HTMLPurifier_Config::createDefault(); $config = HTMLPurifier_Config::createDefault();
// data/cache 디렉토리에 CSS, HTML, URI 디렉토리 등을 만든다. // data/cache 디렉토리에 CSS, HTML, URI 디렉토리 등을 만든다.
$config->set('Cache.SerializerPath', G5_DATA_PATH.'/cache'); $config->set('Cache.SerializerPath', G5_DATA_PATH.'/cache');
$config->set('HTML.SafeEmbed', true); $config->set('HTML.SafeEmbed', false);
$config->set('HTML.SafeObject', true); $config->set('HTML.SafeObject', false);
$config->set('Output.FlashCompat', false);
$config->set('HTML.SafeIframe', true); $config->set('HTML.SafeIframe', true);
$config->set('URI.SafeIframeRegexp','%^(https?:)?//('.$safeiframe.')%'); $config->set('URI.SafeIframeRegexp','%^(https?:)?//('.$safeiframe.')%');
$config->set('Attr.AllowedFrameTargets', array('_blank')); $config->set('Attr.AllowedFrameTargets', array('_blank'));
@ -3176,4 +3177,22 @@ function check_vaild_callback($callback){
return true; return true;
} }
} }
// Browscap 정보 얻기
function get_browscap_info($agent)
{
if(!$agent)
return false;
include_once(G5_PLUGIN_PATH.'/browscap/Browscap.php');
$browscap = new phpbrowscap\Browscap(G5_DATA_PATH.'/cache');
$browscap->updateMethod = 'cURL';
$browscap->doAutoUpdate = false;
$browscap->cacheFilename = 'browscap_cache.php';
$info = $browscap->getBrowser($agent);
return $info;
}
?> ?>

View File

@ -1,7 +1,7 @@
<?php <?php
if (!defined('_GNUBOARD_')) exit; if (!defined('_GNUBOARD_')) exit;
@ini_set('memory_limit', '512M'); @ini_set('memory_limit', '-1');
// 게시글리스트 썸네일 생성 // 게시글리스트 썸네일 생성
function get_list_thumbnail($bo_table, $wr_id, $thumb_width, $thumb_height, $is_create=false, $is_crop=true, $crop_mode='center', $is_sharpen=false, $um_value='80/0.5/3') function get_list_thumbnail($bo_table, $wr_id, $thumb_width, $thumb_height, $is_create=false, $is_crop=true, $crop_mode='center', $is_sharpen=false, $um_value='80/0.5/3')

View File

@ -50,51 +50,22 @@ function visit($skin_dir='basic')
// get_browser() 함수는 이미 있음 // get_browser() 함수는 이미 있음
function get_brow($agent) function get_brow($agent)
{ {
$agent = strtolower($agent); $info = get_browscap_info($agent);
//echo $agent; echo "<br/>"; return $info->Comment;
if (preg_match("/msie ([1-9][0-9]\.[0-9]+)/", $agent, $m)) { $s = 'MSIE '.$m[1]; }
else if(preg_match("/firefox/", $agent)) { $s = "FireFox"; }
else if(preg_match("/chrome/", $agent)) { $s = "Chrome"; }
else if(preg_match("/x11/", $agent)) { $s = "Netscape"; }
else if(preg_match("/opera/", $agent)) { $s = "Opera"; }
else if(preg_match("/gec/", $agent)) { $s = "Gecko"; }
else if(preg_match("/bot|slurp/", $agent)) { $s = "Robot"; }
else if(preg_match("/internet explorer/", $agent)) { $s = "IE"; }
else if(preg_match("/mozilla/", $agent)) { $s = "Mozilla"; }
else { $s = "기타"; }
return $s;
} }
function get_os($agent) function get_os($agent)
{ {
$agent = strtolower($agent); $info = get_browscap_info($agent);
//echo $agent; echo "<br/>"; return $info->Platform;
}
if (preg_match("/windows 98/", $agent)) { $s = "98"; } function get_device($agent)
else if(preg_match("/windows 95/", $agent)) { $s = "95"; } {
else if(preg_match("/windows nt 4\.[0-9]*/", $agent)) { $s = "NT"; } $info = get_browscap_info($agent);
else if(preg_match("/windows nt 5\.0/", $agent)) { $s = "2000"; }
else if(preg_match("/windows nt 5\.1/", $agent)) { $s = "XP"; }
else if(preg_match("/windows nt 5\.2/", $agent)) { $s = "2003"; }
else if(preg_match("/windows nt 6\.0/", $agent)) { $s = "Vista"; }
else if(preg_match("/windows nt 6\.1/", $agent)) { $s = "Windows7"; }
else if(preg_match("/windows nt 6\.2/", $agent)) { $s = "Windows8"; }
else if(preg_match("/windows 9x/", $agent)) { $s = "ME"; }
else if(preg_match("/windows ce/", $agent)) { $s = "CE"; }
else if(preg_match("/mac/", $agent)) { $s = "MAC"; }
else if(preg_match("/linux/", $agent)) { $s = "Linux"; }
else if(preg_match("/sunos/", $agent)) { $s = "sunOS"; }
else if(preg_match("/irix/", $agent)) { $s = "IRIX"; }
else if(preg_match("/phone/", $agent)) { $s = "Phone"; }
else if(preg_match("/bot|slurp/", $agent)) { $s = "Robot"; }
else if(preg_match("/internet explorer/", $agent)) { $s = "IE"; }
else if(preg_match("/mozilla/", $agent)) { $s = "Mozilla"; }
else { $s = "기타"; }
return $s; return $info->Device_Type;
} }
?> ?>

View File

@ -1,8 +1,8 @@
<?php <?php
include_once('./_common.php'); include_once('./_common.php');
$sfl = trim($_REQUEST['sfl']); //$sfl = trim($_REQUEST['sfl']);
$stx = trim($_REQUEST['stx']); //$stx = trim($_REQUEST['stx']);
$g5['title'] = 'Q&amp;A'; $g5['title'] = 'Q&amp;A';
include_once(G5_MSHOP_PATH.'/_head.php'); include_once(G5_MSHOP_PATH.'/_head.php');

View File

@ -1,8 +1,8 @@
<?php <?php
include_once('./_common.php'); include_once('./_common.php');
$sfl = trim($_REQUEST['sfl']); //$sfl = trim($_REQUEST['sfl']);
$stx = trim($_REQUEST['stx']); //$stx = trim($_REQUEST['stx']);
$g5['title'] = 'REVIEW'; $g5['title'] = 'REVIEW';
include_once(G5_MSHOP_PATH.'/_head.php'); include_once(G5_MSHOP_PATH.'/_head.php');

View File

@ -22,7 +22,30 @@ add_stylesheet('<link rel="stylesheet" href="'.$member_skin_url.'/style.css">',
<section id="fregister_private"> <section id="fregister_private">
<h2>개인정보처리방침안내</h2> <h2>개인정보처리방침안내</h2>
<textarea readonly><?php echo get_text($config['cf_privacy']) ?></textarea> <div class="tbl_head01 tbl_wrap">
<table>
<caption>개인정보처리방침안내</caption>
<thead>
<tr>
<th>목적</th>
<th>항목</th>
<th>보유기간</th>
</tr>
</thead>
<tbody>
<tr>
<td>이용자 식별 및 본인여부 확인</td>
<td>아이디, 이름, 비밀번호</td>
<td>회원 탈퇴 시까지</td>
</tr>
<tr>
<td>고객서비스 이용에 관한 통지,<br>CS대응을 위한 이용자 식별</td>
<td>연락처 (이메일, 휴대전화번호)</td>
<td>회원 탈퇴 시까지</td>
</tr>
</tbody>
</table>
</div>
<fieldset class="fregister_agree"> <fieldset class="fregister_agree">
<label for="agree21">개인정보처리방침안내의 내용에 동의합니다.</label> <label for="agree21">개인정보처리방침안내의 내용에 동의합니다.</label>
<input type="checkbox" name="agree2" value="1" id="agree21"> <input type="checkbox" name="agree2" value="1" id="agree21">

View File

@ -80,6 +80,10 @@
.fregister_agree label {display:inline-block;margin-right:5px} .fregister_agree label {display:inline-block;margin-right:5px}
#fregister p {color:#e8180c;text-align:center} #fregister p {color:#e8180c;text-align:center}
#fregister .btn_confirm {margin:15px 0} #fregister .btn_confirm {margin:15px 0}
#fregister_private .tbl_head01 {margin:0}
#fregister_private .tbl_head01 th{;text-align:center;border:1px solid #d1dee2;width:33%}
#fregister_private .tbl_head01 td {border:1px solid #e9e9e9;background:#fff}
#fregister_private .tbl_head01 caption{position:absolute;font-size:0;line-height:0;overflow:hidden;top:0;color:#fff}
/* 회원가입 입력 */ /* 회원가입 입력 */
#fregisterform #reg_mb_email, #fregisterform .frm_address {width:100%} #fregisterform #reg_mb_email, #fregisterform .frm_address {width:100%}

1459
plugin/browscap/Browscap.php Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -7,7 +7,12 @@
class HTMLPurifier_ConfigSchema_Builder_ConfigSchema class HTMLPurifier_ConfigSchema_Builder_ConfigSchema
{ {
public function build($interchange) { /**
* @param HTMLPurifier_ConfigSchema_Interchange $interchange
* @return HTMLPurifier_ConfigSchema
*/
public function build($interchange)
{
$schema = new HTMLPurifier_ConfigSchema(); $schema = new HTMLPurifier_ConfigSchema();
foreach ($interchange->directives as $d) { foreach ($interchange->directives as $d) {
$schema->add( $schema->add(
@ -38,7 +43,6 @@ class HTMLPurifier_ConfigSchema_Builder_ConfigSchema
$schema->postProcess(); $schema->postProcess();
return $schema; return $schema;
} }
} }
// vim: et sw=4 sts=4 // vim: et sw=4 sts=4

View File

@ -7,10 +7,21 @@
class HTMLPurifier_ConfigSchema_Builder_Xml extends XMLWriter class HTMLPurifier_ConfigSchema_Builder_Xml extends XMLWriter
{ {
/**
* @type HTMLPurifier_ConfigSchema_Interchange
*/
protected $interchange; protected $interchange;
/**
* @type string
*/
private $namespace; private $namespace;
protected function writeHTMLDiv($html) { /**
* @param string $html
*/
protected function writeHTMLDiv($html)
{
$this->startElement('div'); $this->startElement('div');
$purifier = HTMLPurifier::getInstance(); $purifier = HTMLPurifier::getInstance();
@ -21,12 +32,23 @@ class HTMLPurifier_ConfigSchema_Builder_Xml extends XMLWriter
$this->endElement(); // div $this->endElement(); // div
} }
protected function export($var) { /**
if ($var === array()) return 'array()'; * @param mixed $var
* @return string
*/
protected function export($var)
{
if ($var === array()) {
return 'array()';
}
return var_export($var, true); return var_export($var, true);
} }
public function build($interchange) { /**
* @param HTMLPurifier_ConfigSchema_Interchange $interchange
*/
public function build($interchange)
{
// global access, only use as last resort // global access, only use as last resort
$this->interchange = $interchange; $this->interchange = $interchange;
@ -39,19 +61,26 @@ class HTMLPurifier_ConfigSchema_Builder_Xml extends XMLWriter
$this->buildDirective($directive); $this->buildDirective($directive);
} }
if ($this->namespace) $this->endElement(); // namespace if ($this->namespace) {
$this->endElement();
} // namespace
$this->endElement(); // configdoc $this->endElement(); // configdoc
$this->flush(); $this->flush();
} }
public function buildDirective($directive) { /**
* @param HTMLPurifier_ConfigSchema_Interchange_Directive $directive
*/
public function buildDirective($directive)
{
// Kludge, although I suppose having a notion of a "root namespace" // Kludge, although I suppose having a notion of a "root namespace"
// certainly makes things look nicer when documentation is built. // certainly makes things look nicer when documentation is built.
// Depends on things being sorted. // Depends on things being sorted.
if (!$this->namespace || $this->namespace !== $directive->id->getRootNamespace()) { if (!$this->namespace || $this->namespace !== $directive->id->getRootNamespace()) {
if ($this->namespace) $this->endElement(); // namespace if ($this->namespace) {
$this->endElement();
} // namespace
$this->namespace = $directive->id->getRootNamespace(); $this->namespace = $directive->id->getRootNamespace();
$this->startElement('namespace'); $this->startElement('namespace');
$this->writeAttribute('id', $this->namespace); $this->writeAttribute('id', $this->namespace);
@ -64,43 +93,52 @@ class HTMLPurifier_ConfigSchema_Builder_Xml extends XMLWriter
$this->writeElement('name', $directive->id->getDirective()); $this->writeElement('name', $directive->id->getDirective());
$this->startElement('aliases'); $this->startElement('aliases');
foreach ($directive->aliases as $alias) $this->writeElement('alias', $alias->toString()); foreach ($directive->aliases as $alias) {
$this->writeElement('alias', $alias->toString());
}
$this->endElement(); // aliases $this->endElement(); // aliases
$this->startElement('constraints'); $this->startElement('constraints');
if ($directive->version) $this->writeElement('version', $directive->version); if ($directive->version) {
$this->startElement('type'); $this->writeElement('version', $directive->version);
if ($directive->typeAllowsNull) $this->writeAttribute('allow-null', 'yes'); }
$this->text($directive->type); $this->startElement('type');
$this->endElement(); // type if ($directive->typeAllowsNull) {
if ($directive->allowed) { $this->writeAttribute('allow-null', 'yes');
$this->startElement('allowed'); }
foreach ($directive->allowed as $value => $x) $this->writeElement('value', $value); $this->text($directive->type);
$this->endElement(); // allowed $this->endElement(); // type
if ($directive->allowed) {
$this->startElement('allowed');
foreach ($directive->allowed as $value => $x) {
$this->writeElement('value', $value);
} }
$this->writeElement('default', $this->export($directive->default)); $this->endElement(); // allowed
$this->writeAttribute('xml:space', 'preserve'); }
if ($directive->external) { $this->writeElement('default', $this->export($directive->default));
$this->startElement('external'); $this->writeAttribute('xml:space', 'preserve');
foreach ($directive->external as $project) $this->writeElement('project', $project); if ($directive->external) {
$this->endElement(); $this->startElement('external');
foreach ($directive->external as $project) {
$this->writeElement('project', $project);
} }
$this->endElement();
}
$this->endElement(); // constraints $this->endElement(); // constraints
if ($directive->deprecatedVersion) { if ($directive->deprecatedVersion) {
$this->startElement('deprecated'); $this->startElement('deprecated');
$this->writeElement('version', $directive->deprecatedVersion); $this->writeElement('version', $directive->deprecatedVersion);
$this->writeElement('use', $directive->deprecatedUse->toString()); $this->writeElement('use', $directive->deprecatedUse->toString());
$this->endElement(); // deprecated $this->endElement(); // deprecated
} }
$this->startElement('description'); $this->startElement('description');
$this->writeHTMLDiv($directive->description); $this->writeHTMLDiv($directive->description);
$this->endElement(); // description $this->endElement(); // description
$this->endElement(); // directive $this->endElement(); // directive
} }
} }
// vim: et sw=4 sts=4 // vim: et sw=4 sts=4

View File

@ -10,18 +10,23 @@ class HTMLPurifier_ConfigSchema_Interchange
/** /**
* Name of the application this schema is describing. * Name of the application this schema is describing.
* @type string
*/ */
public $name; public $name;
/** /**
* Array of Directive ID => array(directive info) * Array of Directive ID => array(directive info)
* @type HTMLPurifier_ConfigSchema_Interchange_Directive[]
*/ */
public $directives = array(); public $directives = array();
/** /**
* Adds a directive array to $directives * Adds a directive array to $directives
* @param HTMLPurifier_ConfigSchema_Interchange_Directive $directive
* @throws HTMLPurifier_ConfigSchema_Exception
*/ */
public function addDirective($directive) { public function addDirective($directive)
{
if (isset($this->directives[$i = $directive->id->toString()])) { if (isset($this->directives[$i = $directive->id->toString()])) {
throw new HTMLPurifier_ConfigSchema_Exception("Cannot redefine directive '$i'"); throw new HTMLPurifier_ConfigSchema_Exception("Cannot redefine directive '$i'");
} }
@ -32,11 +37,11 @@ class HTMLPurifier_ConfigSchema_Interchange
* Convenience function to perform standard validation. Throws exception * Convenience function to perform standard validation. Throws exception
* on failed validation. * on failed validation.
*/ */
public function validate() { public function validate()
{
$validator = new HTMLPurifier_ConfigSchema_Validator(); $validator = new HTMLPurifier_ConfigSchema_Validator();
return $validator->validate($this); return $validator->validate($this);
} }
} }
// vim: et sw=4 sts=4 // vim: et sw=4 sts=4

View File

@ -7,71 +7,83 @@ class HTMLPurifier_ConfigSchema_Interchange_Directive
{ {
/** /**
* ID of directive, instance of HTMLPurifier_ConfigSchema_Interchange_Id. * ID of directive.
* @type HTMLPurifier_ConfigSchema_Interchange_Id
*/ */
public $id; public $id;
/** /**
* String type, e.g. 'integer' or 'istring'. * Type, e.g. 'integer' or 'istring'.
* @type string
*/ */
public $type; public $type;
/** /**
* Default value, e.g. 3 or 'DefaultVal'. * Default value, e.g. 3 or 'DefaultVal'.
* @type mixed
*/ */
public $default; public $default;
/** /**
* HTML description. * HTML description.
* @type string
*/ */
public $description; public $description;
/** /**
* Boolean whether or not null is allowed as a value. * Whether or not null is allowed as a value.
* @type bool
*/ */
public $typeAllowsNull = false; public $typeAllowsNull = false;
/** /**
* Lookup table of allowed scalar values, e.g. array('allowed' => true). * Lookup table of allowed scalar values.
* e.g. array('allowed' => true).
* Null if all values are allowed. * Null if all values are allowed.
* @type array
*/ */
public $allowed; public $allowed;
/** /**
* List of aliases for the directive, * List of aliases for the directive.
* e.g. array(new HTMLPurifier_ConfigSchema_Interchange_Id('Ns', 'Dir'))). * e.g. array(new HTMLPurifier_ConfigSchema_Interchange_Id('Ns', 'Dir'))).
* @type HTMLPurifier_ConfigSchema_Interchange_Id[]
*/ */
public $aliases = array(); public $aliases = array();
/** /**
* Hash of value aliases, e.g. array('alt' => 'real'). Null if value * Hash of value aliases, e.g. array('alt' => 'real'). Null if value
* aliasing is disabled (necessary for non-scalar types). * aliasing is disabled (necessary for non-scalar types).
* @type array
*/ */
public $valueAliases; public $valueAliases;
/** /**
* Version of HTML Purifier the directive was introduced, e.g. '1.3.1'. * Version of HTML Purifier the directive was introduced, e.g. '1.3.1'.
* Null if the directive has always existed. * Null if the directive has always existed.
* @type string
*/ */
public $version; public $version;
/** /**
* ID of directive that supercedes this old directive, is an instance * ID of directive that supercedes this old directive.
* of HTMLPurifier_ConfigSchema_Interchange_Id. Null if not deprecated. * Null if not deprecated.
* @type HTMLPurifier_ConfigSchema_Interchange_Id
*/ */
public $deprecatedUse; public $deprecatedUse;
/** /**
* Version of HTML Purifier this directive was deprecated. Null if not * Version of HTML Purifier this directive was deprecated. Null if not
* deprecated. * deprecated.
* @type string
*/ */
public $deprecatedVersion; public $deprecatedVersion;
/** /**
* List of external projects this directive depends on, e.g. array('CSSTidy'). * List of external projects this directive depends on, e.g. array('CSSTidy').
* @type array
*/ */
public $external = array(); public $external = array();
} }
// vim: et sw=4 sts=4 // vim: et sw=4 sts=4

View File

@ -6,32 +6,53 @@
class HTMLPurifier_ConfigSchema_Interchange_Id class HTMLPurifier_ConfigSchema_Interchange_Id
{ {
/**
* @type string
*/
public $key; public $key;
public function __construct($key) { /**
* @param string $key
*/
public function __construct($key)
{
$this->key = $key; $this->key = $key;
} }
/** /**
* @return string
* @warning This is NOT magic, to ensure that people don't abuse SPL and * @warning This is NOT magic, to ensure that people don't abuse SPL and
* cause problems for PHP 5.0 support. * cause problems for PHP 5.0 support.
*/ */
public function toString() { public function toString()
{
return $this->key; return $this->key;
} }
public function getRootNamespace() { /**
* @return string
*/
public function getRootNamespace()
{
return substr($this->key, 0, strpos($this->key, ".")); return substr($this->key, 0, strpos($this->key, "."));
} }
public function getDirective() { /**
* @return string
*/
public function getDirective()
{
return substr($this->key, strpos($this->key, ".") + 1); return substr($this->key, strpos($this->key, ".") + 1);
} }
public static function make($id) { /**
* @param string $id
* @return HTMLPurifier_ConfigSchema_Interchange_Id
*/
public static function make($id)
{
return new HTMLPurifier_ConfigSchema_Interchange_Id($id); return new HTMLPurifier_ConfigSchema_Interchange_Id($id);
} }
} }
// vim: et sw=4 sts=4 // vim: et sw=4 sts=4

View File

@ -5,21 +5,39 @@ class HTMLPurifier_ConfigSchema_InterchangeBuilder
/** /**
* Used for processing DEFAULT, nothing else. * Used for processing DEFAULT, nothing else.
* @type HTMLPurifier_VarParser
*/ */
protected $varParser; protected $varParser;
public function __construct($varParser = null) { /**
* @param HTMLPurifier_VarParser $varParser
*/
public function __construct($varParser = null)
{
$this->varParser = $varParser ? $varParser : new HTMLPurifier_VarParser_Native(); $this->varParser = $varParser ? $varParser : new HTMLPurifier_VarParser_Native();
} }
public static function buildFromDirectory($dir = null) { /**
$builder = new HTMLPurifier_ConfigSchema_InterchangeBuilder(); * @param string $dir
* @return HTMLPurifier_ConfigSchema_Interchange
*/
public static function buildFromDirectory($dir = null)
{
$builder = new HTMLPurifier_ConfigSchema_InterchangeBuilder();
$interchange = new HTMLPurifier_ConfigSchema_Interchange(); $interchange = new HTMLPurifier_ConfigSchema_Interchange();
return $builder->buildDir($interchange, $dir); return $builder->buildDir($interchange, $dir);
} }
public function buildDir($interchange, $dir = null) { /**
if (!$dir) $dir = HTMLPURIFIER_PREFIX . '/HTMLPurifier/ConfigSchema/schema'; * @param HTMLPurifier_ConfigSchema_Interchange $interchange
* @param string $dir
* @return HTMLPurifier_ConfigSchema_Interchange
*/
public function buildDir($interchange, $dir = null)
{
if (!$dir) {
$dir = HTMLPURIFIER_PREFIX . '/HTMLPurifier/ConfigSchema/schema';
}
if (file_exists($dir . '/info.ini')) { if (file_exists($dir . '/info.ini')) {
$info = parse_ini_file($dir . '/info.ini'); $info = parse_ini_file($dir . '/info.ini');
$interchange->name = $info['name']; $interchange->name = $info['name'];
@ -39,24 +57,30 @@ class HTMLPurifier_ConfigSchema_InterchangeBuilder
foreach ($files as $file) { foreach ($files as $file) {
$this->buildFile($interchange, $dir . '/' . $file); $this->buildFile($interchange, $dir . '/' . $file);
} }
return $interchange; return $interchange;
} }
public function buildFile($interchange, $file) { /**
* @param HTMLPurifier_ConfigSchema_Interchange $interchange
* @param string $file
*/
public function buildFile($interchange, $file)
{
$parser = new HTMLPurifier_StringHashParser(); $parser = new HTMLPurifier_StringHashParser();
$this->build( $this->build(
$interchange, $interchange,
new HTMLPurifier_StringHash( $parser->parseFile($file) ) new HTMLPurifier_StringHash($parser->parseFile($file))
); );
} }
/** /**
* Builds an interchange object based on a hash. * Builds an interchange object based on a hash.
* @param $interchange HTMLPurifier_ConfigSchema_Interchange object to build * @param HTMLPurifier_ConfigSchema_Interchange $interchange HTMLPurifier_ConfigSchema_Interchange object to build
* @param $hash HTMLPurifier_ConfigSchema_StringHash source data * @param HTMLPurifier_StringHash $hash source data
* @throws HTMLPurifier_ConfigSchema_Exception
*/ */
public function build($interchange, $hash) { public function build($interchange, $hash)
{
if (!$hash instanceof HTMLPurifier_StringHash) { if (!$hash instanceof HTMLPurifier_StringHash) {
$hash = new HTMLPurifier_StringHash($hash); $hash = new HTMLPurifier_StringHash($hash);
} }
@ -75,7 +99,13 @@ class HTMLPurifier_ConfigSchema_InterchangeBuilder
$this->_findUnused($hash); $this->_findUnused($hash);
} }
public function buildDirective($interchange, $hash) { /**
* @param HTMLPurifier_ConfigSchema_Interchange $interchange
* @param HTMLPurifier_StringHash $hash
* @throws HTMLPurifier_ConfigSchema_Exception
*/
public function buildDirective($interchange, $hash)
{
$directive = new HTMLPurifier_ConfigSchema_Interchange_Directive(); $directive = new HTMLPurifier_ConfigSchema_Interchange_Directive();
// These are required elements: // These are required elements:
@ -84,7 +114,9 @@ class HTMLPurifier_ConfigSchema_InterchangeBuilder
if (isset($hash['TYPE'])) { if (isset($hash['TYPE'])) {
$type = explode('/', $hash->offsetGet('TYPE')); $type = explode('/', $hash->offsetGet('TYPE'));
if (isset($type[1])) $directive->typeAllowsNull = true; if (isset($type[1])) {
$directive->typeAllowsNull = true;
}
$directive->type = $type[0]; $directive->type = $type[0];
} else { } else {
throw new HTMLPurifier_ConfigSchema_Exception("TYPE in directive hash '$id' not defined"); throw new HTMLPurifier_ConfigSchema_Exception("TYPE in directive hash '$id' not defined");
@ -92,7 +124,11 @@ class HTMLPurifier_ConfigSchema_InterchangeBuilder
if (isset($hash['DEFAULT'])) { if (isset($hash['DEFAULT'])) {
try { try {
$directive->default = $this->varParser->parse($hash->offsetGet('DEFAULT'), $directive->type, $directive->typeAllowsNull); $directive->default = $this->varParser->parse(
$hash->offsetGet('DEFAULT'),
$directive->type,
$directive->typeAllowsNull
);
} catch (HTMLPurifier_VarParserException $e) { } catch (HTMLPurifier_VarParserException $e) {
throw new HTMLPurifier_ConfigSchema_Exception($e->getMessage() . " in DEFAULT in directive hash '$id'"); throw new HTMLPurifier_ConfigSchema_Exception($e->getMessage() . " in DEFAULT in directive hash '$id'");
} }
@ -139,34 +175,45 @@ class HTMLPurifier_ConfigSchema_InterchangeBuilder
/** /**
* Evaluates an array PHP code string without array() wrapper * Evaluates an array PHP code string without array() wrapper
* @param string $contents
*/ */
protected function evalArray($contents) { protected function evalArray($contents)
return eval('return array('. $contents .');'); {
return eval('return array(' . $contents . ');');
} }
/** /**
* Converts an array list into a lookup array. * Converts an array list into a lookup array.
* @param array $array
* @return array
*/ */
protected function lookup($array) { protected function lookup($array)
{
$ret = array(); $ret = array();
foreach ($array as $val) $ret[$val] = true; foreach ($array as $val) {
$ret[$val] = true;
}
return $ret; return $ret;
} }
/** /**
* Convenience function that creates an HTMLPurifier_ConfigSchema_Interchange_Id * Convenience function that creates an HTMLPurifier_ConfigSchema_Interchange_Id
* object based on a string Id. * object based on a string Id.
* @param string $id
* @return HTMLPurifier_ConfigSchema_Interchange_Id
*/ */
protected function id($id) { protected function id($id)
{
return HTMLPurifier_ConfigSchema_Interchange_Id::make($id); return HTMLPurifier_ConfigSchema_Interchange_Id::make($id);
} }
/** /**
* Triggers errors for any unused keys passed in the hash; such keys * Triggers errors for any unused keys passed in the hash; such keys
* may indicate typos, missing values, etc. * may indicate typos, missing values, etc.
* @param $hash Instance of ConfigSchema_StringHash to check. * @param HTMLPurifier_StringHash $hash Hash to check.
*/ */
protected function _findUnused($hash) { protected function _findUnused($hash)
{
$accessed = $hash->getAccessed(); $accessed = $hash->getAccessed();
foreach ($hash as $k => $v) { foreach ($hash as $k => $v) {
if (!isset($accessed[$k])) { if (!isset($accessed[$k])) {
@ -174,7 +221,6 @@ class HTMLPurifier_ConfigSchema_InterchangeBuilder
} }
} }
} }
} }
// vim: et sw=4 sts=4 // vim: et sw=4 sts=4

View File

@ -12,36 +12,48 @@ class HTMLPurifier_ConfigSchema_Validator
{ {
/** /**
* Easy to access global objects. * @type HTMLPurifier_ConfigSchema_Interchange
*/ */
protected $interchange, $aliases; protected $interchange;
/**
* @type array
*/
protected $aliases;
/** /**
* Context-stack to provide easy to read error messages. * Context-stack to provide easy to read error messages.
* @type array
*/ */
protected $context = array(); protected $context = array();
/** /**
* HTMLPurifier_VarParser to test default's type. * to test default's type.
* @type HTMLPurifier_VarParser
*/ */
protected $parser; protected $parser;
public function __construct() { public function __construct()
{
$this->parser = new HTMLPurifier_VarParser(); $this->parser = new HTMLPurifier_VarParser();
} }
/** /**
* Validates a fully-formed interchange object. Throws an * Validates a fully-formed interchange object.
* HTMLPurifier_ConfigSchema_Exception if there's a problem. * @param HTMLPurifier_ConfigSchema_Interchange $interchange
* @return bool
*/ */
public function validate($interchange) { public function validate($interchange)
{
$this->interchange = $interchange; $this->interchange = $interchange;
$this->aliases = array(); $this->aliases = array();
// PHP is a bit lax with integer <=> string conversions in // PHP is a bit lax with integer <=> string conversions in
// arrays, so we don't use the identical !== comparison // arrays, so we don't use the identical !== comparison
foreach ($interchange->directives as $i => $directive) { foreach ($interchange->directives as $i => $directive) {
$id = $directive->id->toString(); $id = $directive->id->toString();
if ($i != $id) $this->error(false, "Integrity violation: key '$i' does not match internal id '$id'"); if ($i != $id) {
$this->error(false, "Integrity violation: key '$i' does not match internal id '$id'");
}
$this->validateDirective($directive); $this->validateDirective($directive);
} }
return true; return true;
@ -49,8 +61,10 @@ class HTMLPurifier_ConfigSchema_Validator
/** /**
* Validates a HTMLPurifier_ConfigSchema_Interchange_Id object. * Validates a HTMLPurifier_ConfigSchema_Interchange_Id object.
* @param HTMLPurifier_ConfigSchema_Interchange_Id $id
*/ */
public function validateId($id) { public function validateId($id)
{
$id_string = $id->toString(); $id_string = $id->toString();
$this->context[] = "id '$id_string'"; $this->context[] = "id '$id_string'";
if (!$id instanceof HTMLPurifier_ConfigSchema_Interchange_Id) { if (!$id instanceof HTMLPurifier_ConfigSchema_Interchange_Id) {
@ -67,8 +81,10 @@ class HTMLPurifier_ConfigSchema_Validator
/** /**
* Validates a HTMLPurifier_ConfigSchema_Interchange_Directive object. * Validates a HTMLPurifier_ConfigSchema_Interchange_Directive object.
* @param HTMLPurifier_ConfigSchema_Interchange_Directive $d
*/ */
public function validateDirective($d) { public function validateDirective($d)
{
$id = $d->id->toString(); $id = $d->id->toString();
$this->context[] = "directive '$id'"; $this->context[] = "directive '$id'";
$this->validateId($d->id); $this->validateId($d->id);
@ -108,9 +124,13 @@ class HTMLPurifier_ConfigSchema_Validator
/** /**
* Extra validation if $allowed member variable of * Extra validation if $allowed member variable of
* HTMLPurifier_ConfigSchema_Interchange_Directive is defined. * HTMLPurifier_ConfigSchema_Interchange_Directive is defined.
* @param HTMLPurifier_ConfigSchema_Interchange_Directive $d
*/ */
public function validateDirectiveAllowed($d) { public function validateDirectiveAllowed($d)
if (is_null($d->allowed)) return; {
if (is_null($d->allowed)) {
return;
}
$this->with($d, 'allowed') $this->with($d, 'allowed')
->assertNotEmpty() ->assertNotEmpty()
->assertIsLookup(); // handled by InterchangeBuilder ->assertIsLookup(); // handled by InterchangeBuilder
@ -119,7 +139,9 @@ class HTMLPurifier_ConfigSchema_Validator
} }
$this->context[] = 'allowed'; $this->context[] = 'allowed';
foreach ($d->allowed as $val => $x) { foreach ($d->allowed as $val => $x) {
if (!is_string($val)) $this->error("value $val", 'must be a string'); if (!is_string($val)) {
$this->error("value $val", 'must be a string');
}
} }
array_pop($this->context); array_pop($this->context);
} }
@ -127,15 +149,23 @@ class HTMLPurifier_ConfigSchema_Validator
/** /**
* Extra validation if $valueAliases member variable of * Extra validation if $valueAliases member variable of
* HTMLPurifier_ConfigSchema_Interchange_Directive is defined. * HTMLPurifier_ConfigSchema_Interchange_Directive is defined.
* @param HTMLPurifier_ConfigSchema_Interchange_Directive $d
*/ */
public function validateDirectiveValueAliases($d) { public function validateDirectiveValueAliases($d)
if (is_null($d->valueAliases)) return; {
if (is_null($d->valueAliases)) {
return;
}
$this->with($d, 'valueAliases') $this->with($d, 'valueAliases')
->assertIsArray(); // handled by InterchangeBuilder ->assertIsArray(); // handled by InterchangeBuilder
$this->context[] = 'valueAliases'; $this->context[] = 'valueAliases';
foreach ($d->valueAliases as $alias => $real) { foreach ($d->valueAliases as $alias => $real) {
if (!is_string($alias)) $this->error("alias $alias", 'must be a string'); if (!is_string($alias)) {
if (!is_string($real)) $this->error("alias target $real from alias '$alias'", 'must be a string'); $this->error("alias $alias", 'must be a string');
}
if (!is_string($real)) {
$this->error("alias target $real from alias '$alias'", 'must be a string');
}
if ($alias === $real) { if ($alias === $real) {
$this->error("alias '$alias'", "must not be an alias to itself"); $this->error("alias '$alias'", "must not be an alias to itself");
} }
@ -155,8 +185,10 @@ class HTMLPurifier_ConfigSchema_Validator
/** /**
* Extra validation if $aliases member variable of * Extra validation if $aliases member variable of
* HTMLPurifier_ConfigSchema_Interchange_Directive is defined. * HTMLPurifier_ConfigSchema_Interchange_Directive is defined.
* @param HTMLPurifier_ConfigSchema_Interchange_Directive $d
*/ */
public function validateDirectiveAliases($d) { public function validateDirectiveAliases($d)
{
$this->with($d, 'aliases') $this->with($d, 'aliases')
->assertIsArray(); // handled by InterchangeBuilder ->assertIsArray(); // handled by InterchangeBuilder
$this->context[] = 'aliases'; $this->context[] = 'aliases';
@ -180,27 +212,37 @@ class HTMLPurifier_ConfigSchema_Validator
/** /**
* Convenience function for generating HTMLPurifier_ConfigSchema_ValidatorAtom * Convenience function for generating HTMLPurifier_ConfigSchema_ValidatorAtom
* for validating simple member variables of objects. * for validating simple member variables of objects.
* @param $obj
* @param $member
* @return HTMLPurifier_ConfigSchema_ValidatorAtom
*/ */
protected function with($obj, $member) { protected function with($obj, $member)
{
return new HTMLPurifier_ConfigSchema_ValidatorAtom($this->getFormattedContext(), $obj, $member); return new HTMLPurifier_ConfigSchema_ValidatorAtom($this->getFormattedContext(), $obj, $member);
} }
/** /**
* Emits an error, providing helpful context. * Emits an error, providing helpful context.
* @throws HTMLPurifier_ConfigSchema_Exception
*/ */
protected function error($target, $msg) { protected function error($target, $msg)
if ($target !== false) $prefix = ucfirst($target) . ' in ' . $this->getFormattedContext(); {
else $prefix = ucfirst($this->getFormattedContext()); if ($target !== false) {
$prefix = ucfirst($target) . ' in ' . $this->getFormattedContext();
} else {
$prefix = ucfirst($this->getFormattedContext());
}
throw new HTMLPurifier_ConfigSchema_Exception(trim($prefix . ' ' . $msg)); throw new HTMLPurifier_ConfigSchema_Exception(trim($prefix . ' ' . $msg));
} }
/** /**
* Returns a formatted context string. * Returns a formatted context string.
* @return string
*/ */
protected function getFormattedContext() { protected function getFormattedContext()
{
return implode(' in ', array_reverse($this->context)); return implode(' in ', array_reverse($this->context));
} }
} }
// vim: et sw=4 sts=4 // vim: et sw=4 sts=4

View File

@ -8,59 +8,123 @@
*/ */
class HTMLPurifier_ConfigSchema_ValidatorAtom class HTMLPurifier_ConfigSchema_ValidatorAtom
{ {
/**
* @type string
*/
protected $context;
protected $context, $obj, $member, $contents; /**
* @type object
*/
protected $obj;
public function __construct($context, $obj, $member) { /**
$this->context = $context; * @type string
$this->obj = $obj; */
$this->member = $member; protected $member;
$this->contents =& $obj->$member;
/**
* @type mixed
*/
protected $contents;
public function __construct($context, $obj, $member)
{
$this->context = $context;
$this->obj = $obj;
$this->member = $member;
$this->contents =& $obj->$member;
} }
public function assertIsString() { /**
if (!is_string($this->contents)) $this->error('must be a string'); * @return HTMLPurifier_ConfigSchema_ValidatorAtom
return $this; */
} public function assertIsString()
{
public function assertIsBool() { if (!is_string($this->contents)) {
if (!is_bool($this->contents)) $this->error('must be a boolean'); $this->error('must be a string');
return $this;
}
public function assertIsArray() {
if (!is_array($this->contents)) $this->error('must be an array');
return $this;
}
public function assertNotNull() {
if ($this->contents === null) $this->error('must not be null');
return $this;
}
public function assertAlnum() {
$this->assertIsString();
if (!ctype_alnum($this->contents)) $this->error('must be alphanumeric');
return $this;
}
public function assertNotEmpty() {
if (empty($this->contents)) $this->error('must not be empty');
return $this;
}
public function assertIsLookup() {
$this->assertIsArray();
foreach ($this->contents as $v) {
if ($v !== true) $this->error('must be a lookup array');
} }
return $this; return $this;
} }
protected function error($msg) { /**
throw new HTMLPurifier_ConfigSchema_Exception(ucfirst($this->member) . ' in ' . $this->context . ' ' . $msg); * @return HTMLPurifier_ConfigSchema_ValidatorAtom
*/
public function assertIsBool()
{
if (!is_bool($this->contents)) {
$this->error('must be a boolean');
}
return $this;
} }
/**
* @return HTMLPurifier_ConfigSchema_ValidatorAtom
*/
public function assertIsArray()
{
if (!is_array($this->contents)) {
$this->error('must be an array');
}
return $this;
}
/**
* @return HTMLPurifier_ConfigSchema_ValidatorAtom
*/
public function assertNotNull()
{
if ($this->contents === null) {
$this->error('must not be null');
}
return $this;
}
/**
* @return HTMLPurifier_ConfigSchema_ValidatorAtom
*/
public function assertAlnum()
{
$this->assertIsString();
if (!ctype_alnum($this->contents)) {
$this->error('must be alphanumeric');
}
return $this;
}
/**
* @return HTMLPurifier_ConfigSchema_ValidatorAtom
*/
public function assertNotEmpty()
{
if (empty($this->contents)) {
$this->error('must not be empty');
}
return $this;
}
/**
* @return HTMLPurifier_ConfigSchema_ValidatorAtom
*/
public function assertIsLookup()
{
$this->assertIsArray();
foreach ($this->contents as $v) {
if ($v !== true) {
$this->error('must be a lookup array');
}
}
return $this;
}
/**
* @param string $msg
* @throws HTMLPurifier_ConfigSchema_Exception
*/
protected function error($msg)
{
throw new HTMLPurifier_ConfigSchema_Exception(ucfirst($this->member) . ' in ' . $this->context . ' ' . $msg);
}
} }
// vim: et sw=4 sts=4 // vim: et sw=4 sts=4

View File

@ -0,0 +1,14 @@
AutoFormat.RemoveEmpty.Predicate
TYPE: hash
VERSION: 4.7.0
DEFAULT: array('colgroup' => array(), 'th' => array(), 'td' => array(), 'iframe' => array('src'))
--DESCRIPTION--
<p>
Given that an element has no contents, it will be removed by default, unless
this predicate dictates otherwise. The predicate can either be an associative
map from tag name to list of attributes that must be present for the element
to be considered preserved: thus, the default always preserves <code>colgroup</code>,
<code>th</code> and <code>td</code>, and also <code>iframe</code> if it
has a <code>src</code>.
</p>
--# vim: et sw=4 sts=4

View File

@ -0,0 +1,16 @@
Core.AllowHostnameUnderscore
TYPE: bool
VERSION: 4.6.0
DEFAULT: false
--DESCRIPTION--
<p>
By RFC 1123, underscores are not permitted in host names.
(This is in contrast to the specification for DNS, RFC
2181, which allows underscores.)
However, most browsers do the right thing when faced with
an underscore in the host name, and so some poorly written
websites are written with the expectation this should work.
Setting this parameter to true relaxes our allowed character
check so that underscores are permitted.
</p>
--# vim: et sw=4 sts=4

View File

@ -2,9 +2,11 @@ Core.EscapeInvalidChildren
TYPE: bool TYPE: bool
DEFAULT: false DEFAULT: false
--DESCRIPTION-- --DESCRIPTION--
When true, a child is found that is not allowed in the context of the <p><strong>Warning:</strong> this configuration option is no longer does anything as of 4.6.0.</p>
<p>When true, a child is found that is not allowed in the context of the
parent element will be transformed into text as if it were ASCII. When parent element will be transformed into text as if it were ASCII. When
false, that element and all internal tags will be dropped, though text will false, that element and all internal tags will be dropped, though text will
be preserved. There is no option for dropping the element but preserving be preserved. There is no option for dropping the element but preserving
child nodes. child nodes.</p>
--# vim: et sw=4 sts=4 --# vim: et sw=4 sts=4

View File

@ -4,6 +4,6 @@ VERSION: 2.0.1
DEFAULT: NULL DEFAULT: NULL
--DESCRIPTION-- --DESCRIPTION--
A custom doctype for power-users who defined there own document A custom doctype for power-users who defined their own document
type. This directive only applies when %HTML.Doctype is blank. type. This directive only applies when %HTML.Doctype is blank.
--# vim: et sw=4 sts=4 --# vim: et sw=4 sts=4

View File

@ -11,7 +11,7 @@ DEFAULT: NULL
to check if a URI has passed through HTML Purifier with this line: to check if a URI has passed through HTML Purifier with this line:
</p> </p>
<pre>$checksum === sha1($secret_key . ':' . $url)</pre> <pre>$checksum === hash_hmac("sha256", $url, $secret_key)</pre>
<p> <p>
If the output is TRUE, the redirector script should accept the URI. If the output is TRUE, the redirector script should accept the URI.

View File

@ -4,7 +4,9 @@
// understand how to interpret this filter if it's a static method. // understand how to interpret this filter if it's a static method.
// It's all really silly, but if we go this route it might be reasonable // It's all really silly, but if we go this route it might be reasonable
// to coalesce all of these methods into one. // to coalesce all of these methods into one.
function htmlpurifier_filter_extractstyleblocks_muteerrorhandler() {} function htmlpurifier_filter_extractstyleblocks_muteerrorhandler()
{
}
/** /**
* This filter extracts <style> blocks from input HTML, cleans them up * This filter extracts <style> blocks from input HTML, cleans them up
@ -22,38 +24,77 @@ function htmlpurifier_filter_extractstyleblocks_muteerrorhandler() {}
*/ */
class HTMLPurifier_Filter_ExtractStyleBlocks extends HTMLPurifier_Filter class HTMLPurifier_Filter_ExtractStyleBlocks extends HTMLPurifier_Filter
{ {
/**
* @type string
*/
public $name = 'ExtractStyleBlocks'; public $name = 'ExtractStyleBlocks';
/**
* @type array
*/
private $_styleMatches = array(); private $_styleMatches = array();
/**
* @type csstidy
*/
private $_tidy; private $_tidy;
/**
* @type HTMLPurifier_AttrDef_HTML_ID
*/
private $_id_attrdef; private $_id_attrdef;
/**
* @type HTMLPurifier_AttrDef_CSS_Ident
*/
private $_class_attrdef; private $_class_attrdef;
/**
* @type HTMLPurifier_AttrDef_Enum
*/
private $_enum_attrdef; private $_enum_attrdef;
public function __construct() { public function __construct()
{
$this->_tidy = new csstidy(); $this->_tidy = new csstidy();
$this->_tidy->set_cfg('lowercase_s', false); $this->_tidy->set_cfg('lowercase_s', false);
$this->_id_attrdef = new HTMLPurifier_AttrDef_HTML_ID(true); $this->_id_attrdef = new HTMLPurifier_AttrDef_HTML_ID(true);
$this->_class_attrdef = new HTMLPurifier_AttrDef_CSS_Ident(); $this->_class_attrdef = new HTMLPurifier_AttrDef_CSS_Ident();
$this->_enum_attrdef = new HTMLPurifier_AttrDef_Enum(array('first-child', 'link', 'visited', 'active', 'hover', 'focus')); $this->_enum_attrdef = new HTMLPurifier_AttrDef_Enum(
array(
'first-child',
'link',
'visited',
'active',
'hover',
'focus'
)
);
} }
/** /**
* Save the contents of CSS blocks to style matches * Save the contents of CSS blocks to style matches
* @param $matches preg_replace style $matches array * @param array $matches preg_replace style $matches array
*/ */
protected function styleCallback($matches) { protected function styleCallback($matches)
{
$this->_styleMatches[] = $matches[1]; $this->_styleMatches[] = $matches[1];
} }
/** /**
* Removes inline <style> tags from HTML, saves them for later use * Removes inline <style> tags from HTML, saves them for later use
* @param string $html
* @param HTMLPurifier_Config $config
* @param HTMLPurifier_Context $context
* @return string
* @todo Extend to indicate non-text/css style blocks * @todo Extend to indicate non-text/css style blocks
*/ */
public function preFilter($html, $config, $context) { public function preFilter($html, $config, $context)
{
$tidy = $config->get('Filter.ExtractStyleBlocks.TidyImpl'); $tidy = $config->get('Filter.ExtractStyleBlocks.TidyImpl');
if ($tidy !== null) $this->_tidy = $tidy; if ($tidy !== null) {
$this->_tidy = $tidy;
}
$html = preg_replace_callback('#<style(?:\s.*)?>(.+)</style>#isU', array($this, 'styleCallback'), $html); $html = preg_replace_callback('#<style(?:\s.*)?>(.+)</style>#isU', array($this, 'styleCallback'), $html);
$style_blocks = $this->_styleMatches; $style_blocks = $this->_styleMatches;
$this->_styleMatches = array(); // reset $this->_styleMatches = array(); // reset
@ -69,12 +110,14 @@ class HTMLPurifier_Filter_ExtractStyleBlocks extends HTMLPurifier_Filter
/** /**
* Takes CSS (the stuff found in <style>) and cleans it. * Takes CSS (the stuff found in <style>) and cleans it.
* @warning Requires CSSTidy <http://csstidy.sourceforge.net/> * @warning Requires CSSTidy <http://csstidy.sourceforge.net/>
* @param $css CSS styling to clean * @param string $css CSS styling to clean
* @param $config Instance of HTMLPurifier_Config * @param HTMLPurifier_Config $config
* @param $context Instance of HTMLPurifier_Context * @param HTMLPurifier_Context $context
* @return Cleaned CSS * @throws HTMLPurifier_Exception
* @return string Cleaned CSS
*/ */
public function cleanCSS($css, $config, $context) { public function cleanCSS($css, $config, $context)
{
// prepare scope // prepare scope
$scope = $config->get('Filter.ExtractStyleBlocks.Scope'); $scope = $config->get('Filter.ExtractStyleBlocks.Scope');
if ($scope !== null) { if ($scope !== null) {
@ -102,7 +145,9 @@ class HTMLPurifier_Filter_ExtractStyleBlocks extends HTMLPurifier_Filter
$new_decls = array(); $new_decls = array();
foreach ($decls as $selector => $style) { foreach ($decls as $selector => $style) {
$selector = trim($selector); $selector = trim($selector);
if ($selector === '') continue; // should not happen if ($selector === '') {
continue;
} // should not happen
// Parse the selector // Parse the selector
// Here is the relevant part of the CSS grammar: // Here is the relevant part of the CSS grammar:
// //
@ -174,7 +219,7 @@ class HTMLPurifier_Filter_ExtractStyleBlocks extends HTMLPurifier_Filter
// delimiters // delimiters
$nsel = null; $nsel = null;
$delim = null; // guaranteed to be non-null after $delim = null; // guaranteed to be non-null after
// two loop iterations // two loop iterations
for ($i = 0, $c = count($basic_selectors); $i < $c; $i++) { for ($i = 0, $c = count($basic_selectors); $i < $c; $i++) {
$x = $basic_selectors[$i]; $x = $basic_selectors[$i];
if ($i % 2) { if ($i % 2) {
@ -189,7 +234,7 @@ class HTMLPurifier_Filter_ExtractStyleBlocks extends HTMLPurifier_Filter
$components = preg_split('/([#.:])/', $x, -1, PREG_SPLIT_DELIM_CAPTURE); $components = preg_split('/([#.:])/', $x, -1, PREG_SPLIT_DELIM_CAPTURE);
$sdelim = null; $sdelim = null;
$nx = null; $nx = null;
for ($j = 0, $cc = count($components); $j < $cc; $j ++) { for ($j = 0, $cc = count($components); $j < $cc; $j++) {
$y = $components[$j]; $y = $components[$j];
if ($j === 0) { if ($j === 0) {
if ($y === '*' || isset($html_definition->info[$y = strtolower($y)])) { if ($y === '*' || isset($html_definition->info[$y = strtolower($y)])) {
@ -249,7 +294,9 @@ class HTMLPurifier_Filter_ExtractStyleBlocks extends HTMLPurifier_Filter
} }
} }
} }
if (empty($new_selectors)) continue; if (empty($new_selectors)) {
continue;
}
$selector = implode(', ', $new_selectors); $selector = implode(', ', $new_selectors);
foreach ($style as $name => $value) { foreach ($style as $name => $value) {
if (!isset($css_definition->info[$name])) { if (!isset($css_definition->info[$name])) {
@ -258,8 +305,11 @@ class HTMLPurifier_Filter_ExtractStyleBlocks extends HTMLPurifier_Filter
} }
$def = $css_definition->info[$name]; $def = $css_definition->info[$name];
$ret = $def->validate($value, $config, $context); $ret = $def->validate($value, $config, $context);
if ($ret === false) unset($style[$name]); if ($ret === false) {
else $style[$name] = $ret; unset($style[$name]);
} else {
$style[$name] = $ret;
}
} }
$new_decls[$selector] = $style; $new_decls[$selector] = $style;
} }
@ -276,14 +326,13 @@ class HTMLPurifier_Filter_ExtractStyleBlocks extends HTMLPurifier_Filter
// that no funny business occurs (i.e. </style> in a font-family prop). // that no funny business occurs (i.e. </style> in a font-family prop).
if ($config->get('Filter.ExtractStyleBlocks.Escaping')) { if ($config->get('Filter.ExtractStyleBlocks.Escaping')) {
$css = str_replace( $css = str_replace(
array('<', '>', '&'), array('<', '>', '&'),
array('\3C ', '\3E ', '\26 '), array('\3C ', '\3E ', '\26 '),
$css $css
); );
} }
return $css; return $css;
} }
} }
// vim: et sw=4 sts=4 // vim: et sw=4 sts=4

View File

@ -3,36 +3,62 @@
class HTMLPurifier_Filter_YouTube extends HTMLPurifier_Filter class HTMLPurifier_Filter_YouTube extends HTMLPurifier_Filter
{ {
/**
* @type string
*/
public $name = 'YouTube'; public $name = 'YouTube';
public function preFilter($html, $config, $context) { /**
$pre_regex = '#<object[^>]+>.+?'. * @param string $html
'http://www.youtube.com/((?:v|cp)/[A-Za-z0-9\-_=]+).+?</object>#s'; * @param HTMLPurifier_Config $config
* @param HTMLPurifier_Context $context
* @return string
*/
public function preFilter($html, $config, $context)
{
$pre_regex = '#<object[^>]+>.+?' .
'(?:http:)?//www.youtube.com/((?:v|cp)/[A-Za-z0-9\-_=]+).+?</object>#s';
$pre_replace = '<span class="youtube-embed">\1</span>'; $pre_replace = '<span class="youtube-embed">\1</span>';
return preg_replace($pre_regex, $pre_replace, $html); return preg_replace($pre_regex, $pre_replace, $html);
} }
public function postFilter($html, $config, $context) { /**
* @param string $html
* @param HTMLPurifier_Config $config
* @param HTMLPurifier_Context $context
* @return string
*/
public function postFilter($html, $config, $context)
{
$post_regex = '#<span class="youtube-embed">((?:v|cp)/[A-Za-z0-9\-_=]+)</span>#'; $post_regex = '#<span class="youtube-embed">((?:v|cp)/[A-Za-z0-9\-_=]+)</span>#';
return preg_replace_callback($post_regex, array($this, 'postFilterCallback'), $html); return preg_replace_callback($post_regex, array($this, 'postFilterCallback'), $html);
} }
protected function armorUrl($url) { /**
* @param $url
* @return string
*/
protected function armorUrl($url)
{
return str_replace('--', '-&#45;', $url); return str_replace('--', '-&#45;', $url);
} }
protected function postFilterCallback($matches) { /**
* @param array $matches
* @return string
*/
protected function postFilterCallback($matches)
{
$url = $this->armorUrl($matches[1]); $url = $this->armorUrl($matches[1]);
return '<object width="425" height="350" type="application/x-shockwave-flash" '. return '<object width="425" height="350" type="application/x-shockwave-flash" ' .
'data="http://www.youtube.com/'.$url.'">'. 'data="//www.youtube.com/' . $url . '">' .
'<param name="movie" value="http://www.youtube.com/'.$url.'"></param>'. '<param name="movie" value="//www.youtube.com/' . $url . '"></param>' .
'<!--[if IE]>'. '<!--[if IE]>' .
'<embed src="http://www.youtube.com/'.$url.'"'. '<embed src="//www.youtube.com/' . $url . '"' .
'type="application/x-shockwave-flash"'. 'type="application/x-shockwave-flash"' .
'wmode="transparent" width="425" height="350" />'. 'wmode="transparent" width="425" height="350" />' .
'<![endif]-->'. '<![endif]-->' .
'</object>'; '</object>';
} }
} }

View File

@ -4,9 +4,6 @@
class HTMLPurifier_Language_en_x_test extends HTMLPurifier_Language class HTMLPurifier_Language_en_x_test extends HTMLPurifier_Language
{ {
} }
// vim: et sw=4 sts=4 // vim: et sw=4 sts=4

View File

@ -4,60 +4,52 @@ $fallback = false;
$messages = array( $messages = array(
'HTMLPurifier' => 'HTML Purifier', 'HTMLPurifier' => 'HTML Purifier',
// for unit testing purposes // for unit testing purposes
'LanguageFactoryTest: Pizza' => 'Pizza', 'LanguageFactoryTest: Pizza' => 'Pizza',
'LanguageTest: List' => '$1', 'LanguageTest: List' => '$1',
'LanguageTest: Hash' => '$1.Keys; $1.Values', 'LanguageTest: Hash' => '$1.Keys; $1.Values',
'Item separator' => ', ',
'Item separator' => ', ', 'Item separator last' => ' and ', // non-Harvard style
'Item separator last' => ' and ', // non-Harvard style
'ErrorCollector: No errors' => 'No errors detected. However, because error reporting is still incomplete, there may have been errors that the error collector was not notified of; please inspect the output HTML carefully.',
'ErrorCollector: At line' => ' at line $line',
'ErrorCollector: Incidental errors' => 'Incidental errors',
'Lexer: Unclosed comment' => 'Unclosed comment',
'Lexer: Unescaped lt' => 'Unescaped less-than sign (<) should be &lt;',
'Lexer: Missing gt' => 'Missing greater-than sign (>), previous less-than sign (<) should be escaped',
'Lexer: Missing attribute key' => 'Attribute declaration has no key',
'Lexer: Missing end quote' => 'Attribute declaration has no end quote',
'Lexer: Extracted body' => 'Removed document metadata tags',
'Strategy_RemoveForeignElements: Tag transform' => '<$1> element transformed into $CurrentToken.Serialized',
'Strategy_RemoveForeignElements: Missing required attribute' => '$CurrentToken.Compact element missing required attribute $1',
'Strategy_RemoveForeignElements: Foreign element to text' => 'Unrecognized $CurrentToken.Serialized tag converted to text',
'Strategy_RemoveForeignElements: Foreign element removed' => 'Unrecognized $CurrentToken.Serialized tag removed',
'Strategy_RemoveForeignElements: Comment removed' => 'Comment containing "$CurrentToken.Data" removed',
'Strategy_RemoveForeignElements: Foreign meta element removed' => 'Unrecognized $CurrentToken.Serialized meta tag and all descendants removed',
'Strategy_RemoveForeignElements: Token removed to end' => 'Tags and text starting from $1 element where removed to end',
'Strategy_RemoveForeignElements: Trailing hyphen in comment removed' => 'Trailing hyphen(s) in comment removed',
'Strategy_RemoveForeignElements: Hyphens in comment collapsed' => 'Double hyphens in comments are not allowed, and were collapsed into single hyphens',
'Strategy_MakeWellFormed: Unnecessary end tag removed' => 'Unnecessary $CurrentToken.Serialized tag removed',
'Strategy_MakeWellFormed: Unnecessary end tag to text' => 'Unnecessary $CurrentToken.Serialized tag converted to text',
'Strategy_MakeWellFormed: Tag auto closed' => '$1.Compact started on line $1.Line auto-closed by $CurrentToken.Compact',
'Strategy_MakeWellFormed: Tag carryover' => '$1.Compact started on line $1.Line auto-continued into $CurrentToken.Compact',
'Strategy_MakeWellFormed: Stray end tag removed' => 'Stray $CurrentToken.Serialized tag removed',
'Strategy_MakeWellFormed: Stray end tag to text' => 'Stray $CurrentToken.Serialized tag converted to text',
'Strategy_MakeWellFormed: Tag closed by element end' => '$1.Compact tag started on line $1.Line closed by end of $CurrentToken.Serialized',
'Strategy_MakeWellFormed: Tag closed by document end' => '$1.Compact tag started on line $1.Line closed by end of document',
'Strategy_FixNesting: Node removed' => '$CurrentToken.Compact node removed',
'Strategy_FixNesting: Node excluded' => '$CurrentToken.Compact node removed due to descendant exclusion by ancestor element',
'Strategy_FixNesting: Node reorganized' => 'Contents of $CurrentToken.Compact node reorganized to enforce its content model',
'Strategy_FixNesting: Node contents removed' => 'Contents of $CurrentToken.Compact node removed',
'AttrValidator: Attributes transformed' => 'Attributes on $CurrentToken.Compact transformed from $1.Keys to $2.Keys',
'AttrValidator: Attribute removed' => '$CurrentAttr.Name attribute on $CurrentToken.Compact removed',
'ErrorCollector: No errors' => 'No errors detected. However, because error reporting is still incomplete, there may have been errors that the error collector was not notified of; please inspect the output HTML carefully.',
'ErrorCollector: At line' => ' at line $line',
'ErrorCollector: Incidental errors' => 'Incidental errors',
'Lexer: Unclosed comment' => 'Unclosed comment',
'Lexer: Unescaped lt' => 'Unescaped less-than sign (<) should be &lt;',
'Lexer: Missing gt' => 'Missing greater-than sign (>), previous less-than sign (<) should be escaped',
'Lexer: Missing attribute key' => 'Attribute declaration has no key',
'Lexer: Missing end quote' => 'Attribute declaration has no end quote',
'Lexer: Extracted body' => 'Removed document metadata tags',
'Strategy_RemoveForeignElements: Tag transform' => '<$1> element transformed into $CurrentToken.Serialized',
'Strategy_RemoveForeignElements: Missing required attribute' => '$CurrentToken.Compact element missing required attribute $1',
'Strategy_RemoveForeignElements: Foreign element to text' => 'Unrecognized $CurrentToken.Serialized tag converted to text',
'Strategy_RemoveForeignElements: Foreign element removed' => 'Unrecognized $CurrentToken.Serialized tag removed',
'Strategy_RemoveForeignElements: Comment removed' => 'Comment containing "$CurrentToken.Data" removed',
'Strategy_RemoveForeignElements: Foreign meta element removed' => 'Unrecognized $CurrentToken.Serialized meta tag and all descendants removed',
'Strategy_RemoveForeignElements: Token removed to end' => 'Tags and text starting from $1 element where removed to end',
'Strategy_RemoveForeignElements: Trailing hyphen in comment removed' => 'Trailing hyphen(s) in comment removed',
'Strategy_RemoveForeignElements: Hyphens in comment collapsed' => 'Double hyphens in comments are not allowed, and were collapsed into single hyphens',
'Strategy_MakeWellFormed: Unnecessary end tag removed' => 'Unnecessary $CurrentToken.Serialized tag removed',
'Strategy_MakeWellFormed: Unnecessary end tag to text' => 'Unnecessary $CurrentToken.Serialized tag converted to text',
'Strategy_MakeWellFormed: Tag auto closed' => '$1.Compact started on line $1.Line auto-closed by $CurrentToken.Compact',
'Strategy_MakeWellFormed: Tag carryover' => '$1.Compact started on line $1.Line auto-continued into $CurrentToken.Compact',
'Strategy_MakeWellFormed: Stray end tag removed' => 'Stray $CurrentToken.Serialized tag removed',
'Strategy_MakeWellFormed: Stray end tag to text' => 'Stray $CurrentToken.Serialized tag converted to text',
'Strategy_MakeWellFormed: Tag closed by element end' => '$1.Compact tag started on line $1.Line closed by end of $CurrentToken.Serialized',
'Strategy_MakeWellFormed: Tag closed by document end' => '$1.Compact tag started on line $1.Line closed by end of document',
'Strategy_FixNesting: Node removed' => '$CurrentToken.Compact node removed',
'Strategy_FixNesting: Node excluded' => '$CurrentToken.Compact node removed due to descendant exclusion by ancestor element',
'Strategy_FixNesting: Node reorganized' => 'Contents of $CurrentToken.Compact node reorganized to enforce its content model',
'Strategy_FixNesting: Node contents removed' => 'Contents of $CurrentToken.Compact node removed',
'AttrValidator: Attributes transformed' => 'Attributes on $CurrentToken.Compact transformed from $1.Keys to $2.Keys',
'AttrValidator: Attribute removed' => '$CurrentAttr.Name attribute on $CurrentToken.Compact removed',
); );
$errorNames = array( $errorNames = array(
E_ERROR => 'Error', E_ERROR => 'Error',
E_WARNING => 'Warning', E_WARNING => 'Warning',
E_NOTICE => 'Notice' E_NOTICE => 'Notice'
); );
// vim: et sw=4 sts=4 // vim: et sw=4 sts=4

File diff suppressed because it is too large Load Diff

View File

@ -7,25 +7,30 @@ class HTMLPurifier_Printer
{ {
/** /**
* Instance of HTMLPurifier_Generator for HTML generation convenience funcs * For HTML generation convenience funcs.
* @type HTMLPurifier_Generator
*/ */
protected $generator; protected $generator;
/** /**
* Instance of HTMLPurifier_Config, for easy access * For easy access.
* @type HTMLPurifier_Config
*/ */
protected $config; protected $config;
/** /**
* Initialize $generator. * Initialize $generator.
*/ */
public function __construct() { public function __construct()
{
} }
/** /**
* Give generator necessary configuration if possible * Give generator necessary configuration if possible
* @param HTMLPurifier_Config $config
*/ */
public function prepareGenerator($config) { public function prepareGenerator($config)
{
$all = $config->getAll(); $all = $config->getAll();
$context = new HTMLPurifier_Context(); $context = new HTMLPurifier_Context();
$this->generator = new HTMLPurifier_Generator($config, $context); $this->generator = new HTMLPurifier_Generator($config, $context);
@ -39,45 +44,62 @@ class HTMLPurifier_Printer
/** /**
* Returns a start tag * Returns a start tag
* @param $tag Tag name * @param string $tag Tag name
* @param $attr Attribute array * @param array $attr Attribute array
* @return string
*/ */
protected function start($tag, $attr = array()) { protected function start($tag, $attr = array())
{
return $this->generator->generateFromToken( return $this->generator->generateFromToken(
new HTMLPurifier_Token_Start($tag, $attr ? $attr : array()) new HTMLPurifier_Token_Start($tag, $attr ? $attr : array())
); );
} }
/** /**
* Returns an end teg * Returns an end tag
* @param $tag Tag name * @param string $tag Tag name
* @return string
*/ */
protected function end($tag) { protected function end($tag)
{
return $this->generator->generateFromToken( return $this->generator->generateFromToken(
new HTMLPurifier_Token_End($tag) new HTMLPurifier_Token_End($tag)
); );
} }
/** /**
* Prints a complete element with content inside * Prints a complete element with content inside
* @param $tag Tag name * @param string $tag Tag name
* @param $contents Element contents * @param string $contents Element contents
* @param $attr Tag attributes * @param array $attr Tag attributes
* @param $escape Bool whether or not to escape contents * @param bool $escape whether or not to escape contents
* @return string
*/ */
protected function element($tag, $contents, $attr = array(), $escape = true) { protected function element($tag, $contents, $attr = array(), $escape = true)
{
return $this->start($tag, $attr) . return $this->start($tag, $attr) .
($escape ? $this->escape($contents) : $contents) . ($escape ? $this->escape($contents) : $contents) .
$this->end($tag); $this->end($tag);
} }
protected function elementEmpty($tag, $attr = array()) { /**
* @param string $tag
* @param array $attr
* @return string
*/
protected function elementEmpty($tag, $attr = array())
{
return $this->generator->generateFromToken( return $this->generator->generateFromToken(
new HTMLPurifier_Token_Empty($tag, $attr) new HTMLPurifier_Token_Empty($tag, $attr)
); );
} }
protected function text($text) { /**
* @param string $text
* @return string
*/
protected function text($text)
{
return $this->generator->generateFromToken( return $this->generator->generateFromToken(
new HTMLPurifier_Token_Text($text) new HTMLPurifier_Token_Text($text)
); );
@ -85,24 +107,29 @@ class HTMLPurifier_Printer
/** /**
* Prints a simple key/value row in a table. * Prints a simple key/value row in a table.
* @param $name Key * @param string $name Key
* @param $value Value * @param mixed $value Value
* @return string
*/ */
protected function row($name, $value) { protected function row($name, $value)
if (is_bool($value)) $value = $value ? 'On' : 'Off'; {
if (is_bool($value)) {
$value = $value ? 'On' : 'Off';
}
return return
$this->start('tr') . "\n" . $this->start('tr') . "\n" .
$this->element('th', $name) . "\n" . $this->element('th', $name) . "\n" .
$this->element('td', $value) . "\n" . $this->element('td', $value) . "\n" .
$this->end('tr') $this->end('tr');
;
} }
/** /**
* Escapes a string for HTML output. * Escapes a string for HTML output.
* @param $string String to escape * @param string $string String to escape
* @return string
*/ */
protected function escape($string) { protected function escape($string)
{
$string = HTMLPurifier_Encoder::cleanUTF8($string); $string = HTMLPurifier_Encoder::cleanUTF8($string);
$string = htmlspecialchars($string, ENT_COMPAT, 'UTF-8'); $string = htmlspecialchars($string, ENT_COMPAT, 'UTF-8');
return $string; return $string;
@ -110,32 +137,46 @@ class HTMLPurifier_Printer
/** /**
* Takes a list of strings and turns them into a single list * Takes a list of strings and turns them into a single list
* @param $array List of strings * @param string[] $array List of strings
* @param $polite Bool whether or not to add an end before the last * @param bool $polite Bool whether or not to add an end before the last
* @return string
*/ */
protected function listify($array, $polite = false) { protected function listify($array, $polite = false)
if (empty($array)) return 'None'; {
if (empty($array)) {
return 'None';
}
$ret = ''; $ret = '';
$i = count($array); $i = count($array);
foreach ($array as $value) { foreach ($array as $value) {
$i--; $i--;
$ret .= $value; $ret .= $value;
if ($i > 0 && !($polite && $i == 1)) $ret .= ', '; if ($i > 0 && !($polite && $i == 1)) {
if ($polite && $i == 1) $ret .= 'and '; $ret .= ', ';
}
if ($polite && $i == 1) {
$ret .= 'and ';
}
} }
return $ret; return $ret;
} }
/** /**
* Retrieves the class of an object without prefixes, as well as metadata * Retrieves the class of an object without prefixes, as well as metadata
* @param $obj Object to determine class of * @param object $obj Object to determine class of
* @param $prefix Further prefix to remove * @param string $sec_prefix Further prefix to remove
* @return string
*/ */
protected function getClass($obj, $sec_prefix = '') { protected function getClass($obj, $sec_prefix = '')
{
static $five = null; static $five = null;
if ($five === null) $five = version_compare(PHP_VERSION, '5', '>='); if ($five === null) {
$five = version_compare(PHP_VERSION, '5', '>=');
}
$prefix = 'HTMLPurifier_' . $sec_prefix; $prefix = 'HTMLPurifier_' . $sec_prefix;
if (!$five) $prefix = strtolower($prefix); if (!$five) {
$prefix = strtolower($prefix);
}
$class = str_replace($prefix, '', get_class($obj)); $class = str_replace($prefix, '', get_class($obj));
$lclass = strtolower($class); $lclass = strtolower($class);
$class .= '('; $class .= '(';
@ -164,13 +205,14 @@ class HTMLPurifier_Printer
break; break;
case 'css_importantdecorator': case 'css_importantdecorator':
$class .= $this->getClass($obj->def, $sec_prefix); $class .= $this->getClass($obj->def, $sec_prefix);
if ($obj->allow) $class .= ', !important'; if ($obj->allow) {
$class .= ', !important';
}
break; break;
} }
$class .= ')'; $class .= ')';
return $class; return $class;
} }
} }
// vim: et sw=4 sts=4 // vim: et sw=4 sts=4

View File

@ -2,10 +2,17 @@
class HTMLPurifier_Printer_CSSDefinition extends HTMLPurifier_Printer class HTMLPurifier_Printer_CSSDefinition extends HTMLPurifier_Printer
{ {
/**
* @type HTMLPurifier_CSSDefinition
*/
protected $def; protected $def;
public function render($config) { /**
* @param HTMLPurifier_Config $config
* @return string
*/
public function render($config)
{
$this->def = $config->getCSSDefinition(); $this->def = $config->getCSSDefinition();
$ret = ''; $ret = '';
@ -32,7 +39,6 @@ class HTMLPurifier_Printer_CSSDefinition extends HTMLPurifier_Printer
return $ret; return $ret;
} }
} }
// vim: et sw=4 sts=4 // vim: et sw=4 sts=4

View File

@ -7,17 +7,20 @@ class HTMLPurifier_Printer_ConfigForm extends HTMLPurifier_Printer
{ {
/** /**
* Printers for specific fields * Printers for specific fields.
* @type HTMLPurifier_Printer[]
*/ */
protected $fields = array(); protected $fields = array();
/** /**
* Documentation URL, can have fragment tagged on end * Documentation URL, can have fragment tagged on end.
* @type string
*/ */
protected $docURL; protected $docURL;
/** /**
* Name of form element to stuff config in * Name of form element to stuff config in.
* @type string
*/ */
protected $name; protected $name;
@ -25,24 +28,27 @@ class HTMLPurifier_Printer_ConfigForm extends HTMLPurifier_Printer
* Whether or not to compress directive names, clipping them off * Whether or not to compress directive names, clipping them off
* after a certain amount of letters. False to disable or integer letters * after a certain amount of letters. False to disable or integer letters
* before clipping. * before clipping.
* @type bool
*/ */
protected $compress = false; protected $compress = false;
/** /**
* @param $name Form element name for directives to be stuffed into * @param string $name Form element name for directives to be stuffed into
* @param $doc_url String documentation URL, will have fragment tagged on * @param string $doc_url String documentation URL, will have fragment tagged on
* @param $compress Integer max length before compressing a directive name, set to false to turn off * @param bool $compress Integer max length before compressing a directive name, set to false to turn off
*/ */
public function __construct( public function __construct(
$name, $doc_url = null, $compress = false $name,
$doc_url = null,
$compress = false
) { ) {
parent::__construct(); parent::__construct();
$this->docURL = $doc_url; $this->docURL = $doc_url;
$this->name = $name; $this->name = $name;
$this->compress = $compress; $this->compress = $compress;
// initialize sub-printers // initialize sub-printers
$this->fields[0] = new HTMLPurifier_Printer_ConfigForm_default(); $this->fields[0] = new HTMLPurifier_Printer_ConfigForm_default();
$this->fields[HTMLPurifier_VarParser::BOOL] = new HTMLPurifier_Printer_ConfigForm_bool(); $this->fields[HTMLPurifier_VarParser::BOOL] = new HTMLPurifier_Printer_ConfigForm_bool();
} }
/** /**
@ -50,32 +56,42 @@ class HTMLPurifier_Printer_ConfigForm extends HTMLPurifier_Printer
* @param $cols Integer columns of textarea, null to use default * @param $cols Integer columns of textarea, null to use default
* @param $rows Integer rows of textarea, null to use default * @param $rows Integer rows of textarea, null to use default
*/ */
public function setTextareaDimensions($cols = null, $rows = null) { public function setTextareaDimensions($cols = null, $rows = null)
if ($cols) $this->fields['default']->cols = $cols; {
if ($rows) $this->fields['default']->rows = $rows; if ($cols) {
$this->fields['default']->cols = $cols;
}
if ($rows) {
$this->fields['default']->rows = $rows;
}
} }
/** /**
* Retrieves styling, in case it is not accessible by webserver * Retrieves styling, in case it is not accessible by webserver
*/ */
public static function getCSS() { public static function getCSS()
{
return file_get_contents(HTMLPURIFIER_PREFIX . '/HTMLPurifier/Printer/ConfigForm.css'); return file_get_contents(HTMLPURIFIER_PREFIX . '/HTMLPurifier/Printer/ConfigForm.css');
} }
/** /**
* Retrieves JavaScript, in case it is not accessible by webserver * Retrieves JavaScript, in case it is not accessible by webserver
*/ */
public static function getJavaScript() { public static function getJavaScript()
{
return file_get_contents(HTMLPURIFIER_PREFIX . '/HTMLPurifier/Printer/ConfigForm.js'); return file_get_contents(HTMLPURIFIER_PREFIX . '/HTMLPurifier/Printer/ConfigForm.js');
} }
/** /**
* Returns HTML output for a configuration form * Returns HTML output for a configuration form
* @param $config Configuration object of current form state, or an array * @param HTMLPurifier_Config|array $config Configuration object of current form state, or an array
* where [0] has an HTML namespace and [1] is being rendered. * where [0] has an HTML namespace and [1] is being rendered.
* @param $allowed Optional namespace(s) and directives to restrict form to. * @param array|bool $allowed Optional namespace(s) and directives to restrict form to.
* @param bool $render_controls
* @return string
*/ */
public function render($config, $allowed = true, $render_controls = true) { public function render($config, $allowed = true, $render_controls = true)
{
if (is_array($config) && isset($config[0])) { if (is_array($config) && isset($config[0])) {
$gen_config = $config[0]; $gen_config = $config[0];
$config = $config[1]; $config = $config[1];
@ -91,29 +107,29 @@ class HTMLPurifier_Printer_ConfigForm extends HTMLPurifier_Printer
$all = array(); $all = array();
foreach ($allowed as $key) { foreach ($allowed as $key) {
list($ns, $directive) = $key; list($ns, $directive) = $key;
$all[$ns][$directive] = $config->get($ns .'.'. $directive); $all[$ns][$directive] = $config->get($ns . '.' . $directive);
} }
$ret = ''; $ret = '';
$ret .= $this->start('table', array('class' => 'hp-config')); $ret .= $this->start('table', array('class' => 'hp-config'));
$ret .= $this->start('thead'); $ret .= $this->start('thead');
$ret .= $this->start('tr'); $ret .= $this->start('tr');
$ret .= $this->element('th', 'Directive', array('class' => 'hp-directive')); $ret .= $this->element('th', 'Directive', array('class' => 'hp-directive'));
$ret .= $this->element('th', 'Value', array('class' => 'hp-value')); $ret .= $this->element('th', 'Value', array('class' => 'hp-value'));
$ret .= $this->end('tr'); $ret .= $this->end('tr');
$ret .= $this->end('thead'); $ret .= $this->end('thead');
foreach ($all as $ns => $directives) { foreach ($all as $ns => $directives) {
$ret .= $this->renderNamespace($ns, $directives); $ret .= $this->renderNamespace($ns, $directives);
} }
if ($render_controls) { if ($render_controls) {
$ret .= $this->start('tbody'); $ret .= $this->start('tbody');
$ret .= $this->start('tr'); $ret .= $this->start('tr');
$ret .= $this->start('td', array('colspan' => 2, 'class' => 'controls')); $ret .= $this->start('td', array('colspan' => 2, 'class' => 'controls'));
$ret .= $this->elementEmpty('input', array('type' => 'submit', 'value' => 'Submit')); $ret .= $this->elementEmpty('input', array('type' => 'submit', 'value' => 'Submit'));
$ret .= '[<a href="?">Reset</a>]'; $ret .= '[<a href="?">Reset</a>]';
$ret .= $this->end('td'); $ret .= $this->end('td');
$ret .= $this->end('tr'); $ret .= $this->end('tr');
$ret .= $this->end('tbody'); $ret .= $this->end('tbody');
} }
$ret .= $this->end('table'); $ret .= $this->end('table');
return $ret; return $ret;
@ -122,13 +138,15 @@ class HTMLPurifier_Printer_ConfigForm extends HTMLPurifier_Printer
/** /**
* Renders a single namespace * Renders a single namespace
* @param $ns String namespace name * @param $ns String namespace name
* @param $directive Associative array of directives to values * @param array $directives array of directives to values
* @return string
*/ */
protected function renderNamespace($ns, $directives) { protected function renderNamespace($ns, $directives)
{
$ret = ''; $ret = '';
$ret .= $this->start('tbody', array('class' => 'namespace')); $ret .= $this->start('tbody', array('class' => 'namespace'));
$ret .= $this->start('tr'); $ret .= $this->start('tr');
$ret .= $this->element('th', $ns, array('colspan' => 2)); $ret .= $this->element('th', $ns, array('colspan' => 2));
$ret .= $this->end('tr'); $ret .= $this->end('tr');
$ret .= $this->end('tbody'); $ret .= $this->end('tbody');
$ret .= $this->start('tbody'); $ret .= $this->start('tbody');
@ -139,40 +157,44 @@ class HTMLPurifier_Printer_ConfigForm extends HTMLPurifier_Printer
$url = str_replace('%s', urlencode("$ns.$directive"), $this->docURL); $url = str_replace('%s', urlencode("$ns.$directive"), $this->docURL);
$ret .= $this->start('a', array('href' => $url)); $ret .= $this->start('a', array('href' => $url));
} }
$attr = array('for' => "{$this->name}:$ns.$directive"); $attr = array('for' => "{$this->name}:$ns.$directive");
// crop directive name if it's too long // crop directive name if it's too long
if (!$this->compress || (strlen($directive) < $this->compress)) { if (!$this->compress || (strlen($directive) < $this->compress)) {
$directive_disp = $directive; $directive_disp = $directive;
} else { } else {
$directive_disp = substr($directive, 0, $this->compress - 2) . '...'; $directive_disp = substr($directive, 0, $this->compress - 2) . '...';
$attr['title'] = $directive; $attr['title'] = $directive;
} }
$ret .= $this->element( $ret .= $this->element(
'label', 'label',
$directive_disp, $directive_disp,
// component printers must create an element with this id // component printers must create an element with this id
$attr $attr
); );
if ($this->docURL) $ret .= $this->end('a'); if ($this->docURL) {
$ret .= $this->end('a');
}
$ret .= $this->end('th'); $ret .= $this->end('th');
$ret .= $this->start('td'); $ret .= $this->start('td');
$def = $this->config->def->info["$ns.$directive"]; $def = $this->config->def->info["$ns.$directive"];
if (is_int($def)) { if (is_int($def)) {
$allow_null = $def < 0; $allow_null = $def < 0;
$type = abs($def); $type = abs($def);
} else { } else {
$type = $def->type; $type = $def->type;
$allow_null = isset($def->allow_null); $allow_null = isset($def->allow_null);
} }
if (!isset($this->fields[$type])) $type = 0; // default if (!isset($this->fields[$type])) {
$type_obj = $this->fields[$type]; $type = 0;
if ($allow_null) { } // default
$type_obj = new HTMLPurifier_Printer_ConfigForm_NullDecorator($type_obj); $type_obj = $this->fields[$type];
} if ($allow_null) {
$ret .= $type_obj->render($ns, $directive, $value, $this->name, array($this->genConfig, $this->config)); $type_obj = new HTMLPurifier_Printer_ConfigForm_NullDecorator($type_obj);
}
$ret .= $type_obj->render($ns, $directive, $value, $this->name, array($this->genConfig, $this->config));
$ret .= $this->end('td'); $ret .= $this->end('td');
$ret .= $this->end('tr'); $ret .= $this->end('tr');
} }
@ -185,19 +207,33 @@ class HTMLPurifier_Printer_ConfigForm extends HTMLPurifier_Printer
/** /**
* Printer decorator for directives that accept null * Printer decorator for directives that accept null
*/ */
class HTMLPurifier_Printer_ConfigForm_NullDecorator extends HTMLPurifier_Printer { class HTMLPurifier_Printer_ConfigForm_NullDecorator extends HTMLPurifier_Printer
{
/** /**
* Printer being decorated * Printer being decorated
* @type HTMLPurifier_Printer
*/ */
protected $obj; protected $obj;
/** /**
* @param $obj Printer to decorate * @param HTMLPurifier_Printer $obj Printer to decorate
*/ */
public function __construct($obj) { public function __construct($obj)
{
parent::__construct(); parent::__construct();
$this->obj = $obj; $this->obj = $obj;
} }
public function render($ns, $directive, $value, $name, $config) {
/**
* @param string $ns
* @param string $directive
* @param string $value
* @param string $name
* @param HTMLPurifier_Config|array $config
* @return string
*/
public function render($ns, $directive, $value, $name, $config)
{
if (is_array($config) && isset($config[0])) { if (is_array($config) && isset($config[0])) {
$gen_config = $config[0]; $gen_config = $config[0];
$config = $config[1]; $config = $config[1];
@ -215,15 +251,19 @@ class HTMLPurifier_Printer_ConfigForm_NullDecorator extends HTMLPurifier_Printer
'type' => 'checkbox', 'type' => 'checkbox',
'value' => '1', 'value' => '1',
'class' => 'null-toggle', 'class' => 'null-toggle',
'name' => "$name"."[Null_$ns.$directive]", 'name' => "$name" . "[Null_$ns.$directive]",
'id' => "$name:Null_$ns.$directive", 'id' => "$name:Null_$ns.$directive",
'onclick' => "toggleWriteability('$name:$ns.$directive',checked)" // INLINE JAVASCRIPT!!!! 'onclick' => "toggleWriteability('$name:$ns.$directive',checked)" // INLINE JAVASCRIPT!!!!
); );
if ($this->obj instanceof HTMLPurifier_Printer_ConfigForm_bool) { if ($this->obj instanceof HTMLPurifier_Printer_ConfigForm_bool) {
// modify inline javascript slightly // modify inline javascript slightly
$attr['onclick'] = "toggleWriteability('$name:Yes_$ns.$directive',checked);toggleWriteability('$name:No_$ns.$directive',checked)"; $attr['onclick'] =
"toggleWriteability('$name:Yes_$ns.$directive',checked);" .
"toggleWriteability('$name:No_$ns.$directive',checked)";
}
if ($value === null) {
$attr['checked'] = 'checked';
} }
if ($value === null) $attr['checked'] = 'checked';
$ret .= $this->elementEmpty('input', $attr); $ret .= $this->elementEmpty('input', $attr);
$ret .= $this->text(' or '); $ret .= $this->text(' or ');
$ret .= $this->elementEmpty('br'); $ret .= $this->elementEmpty('br');
@ -235,10 +275,28 @@ class HTMLPurifier_Printer_ConfigForm_NullDecorator extends HTMLPurifier_Printer
/** /**
* Swiss-army knife configuration form field printer * Swiss-army knife configuration form field printer
*/ */
class HTMLPurifier_Printer_ConfigForm_default extends HTMLPurifier_Printer { class HTMLPurifier_Printer_ConfigForm_default extends HTMLPurifier_Printer
{
/**
* @type int
*/
public $cols = 18; public $cols = 18;
/**
* @type int
*/
public $rows = 5; public $rows = 5;
public function render($ns, $directive, $value, $name, $config) {
/**
* @param string $ns
* @param string $directive
* @param string $value
* @param string $name
* @param HTMLPurifier_Config|array $config
* @return string
*/
public function render($ns, $directive, $value, $name, $config)
{
if (is_array($config) && isset($config[0])) { if (is_array($config) && isset($config[0])) {
$gen_config = $config[0]; $gen_config = $config[0];
$config = $config[1]; $config = $config[1];
@ -262,6 +320,7 @@ class HTMLPurifier_Printer_ConfigForm_default extends HTMLPurifier_Printer {
foreach ($array as $val => $b) { foreach ($array as $val => $b) {
$value[] = $val; $value[] = $val;
} }
//TODO does this need a break?
case HTMLPurifier_VarParser::ALIST: case HTMLPurifier_VarParser::ALIST:
$value = implode(PHP_EOL, $value); $value = implode(PHP_EOL, $value);
break; break;
@ -281,25 +340,27 @@ class HTMLPurifier_Printer_ConfigForm_default extends HTMLPurifier_Printer {
$value = serialize($value); $value = serialize($value);
} }
$attr = array( $attr = array(
'name' => "$name"."[$ns.$directive]", 'name' => "$name" . "[$ns.$directive]",
'id' => "$name:$ns.$directive" 'id' => "$name:$ns.$directive"
); );
if ($value === null) $attr['disabled'] = 'disabled'; if ($value === null) {
$attr['disabled'] = 'disabled';
}
if (isset($def->allowed)) { if (isset($def->allowed)) {
$ret .= $this->start('select', $attr); $ret .= $this->start('select', $attr);
foreach ($def->allowed as $val => $b) { foreach ($def->allowed as $val => $b) {
$attr = array(); $attr = array();
if ($value == $val) $attr['selected'] = 'selected'; if ($value == $val) {
$attr['selected'] = 'selected';
}
$ret .= $this->element('option', $val, $attr); $ret .= $this->element('option', $val, $attr);
} }
$ret .= $this->end('select'); $ret .= $this->end('select');
} elseif ( } elseif ($type === HTMLPurifier_VarParser::TEXT ||
$type === HTMLPurifier_VarParser::TEXT || $type === HTMLPurifier_VarParser::ITEXT ||
$type === HTMLPurifier_VarParser::ITEXT || $type === HTMLPurifier_VarParser::ALIST ||
$type === HTMLPurifier_VarParser::ALIST || $type === HTMLPurifier_VarParser::HASH ||
$type === HTMLPurifier_VarParser::HASH || $type === HTMLPurifier_VarParser::LOOKUP) {
$type === HTMLPurifier_VarParser::LOOKUP
) {
$attr['cols'] = $this->cols; $attr['cols'] = $this->cols;
$attr['rows'] = $this->rows; $attr['rows'] = $this->rows;
$ret .= $this->start('textarea', $attr); $ret .= $this->start('textarea', $attr);
@ -317,8 +378,18 @@ class HTMLPurifier_Printer_ConfigForm_default extends HTMLPurifier_Printer {
/** /**
* Bool form field printer * Bool form field printer
*/ */
class HTMLPurifier_Printer_ConfigForm_bool extends HTMLPurifier_Printer { class HTMLPurifier_Printer_ConfigForm_bool extends HTMLPurifier_Printer
public function render($ns, $directive, $value, $name, $config) { {
/**
* @param string $ns
* @param string $directive
* @param string $value
* @param string $name
* @param HTMLPurifier_Config|array $config
* @return string
*/
public function render($ns, $directive, $value, $name, $config)
{
if (is_array($config) && isset($config[0])) { if (is_array($config) && isset($config[0])) {
$gen_config = $config[0]; $gen_config = $config[0];
$config = $config[1]; $config = $config[1];
@ -336,12 +407,16 @@ class HTMLPurifier_Printer_ConfigForm_bool extends HTMLPurifier_Printer {
$attr = array( $attr = array(
'type' => 'radio', 'type' => 'radio',
'name' => "$name"."[$ns.$directive]", 'name' => "$name" . "[$ns.$directive]",
'id' => "$name:Yes_$ns.$directive", 'id' => "$name:Yes_$ns.$directive",
'value' => '1' 'value' => '1'
); );
if ($value === true) $attr['checked'] = 'checked'; if ($value === true) {
if ($value === null) $attr['disabled'] = 'disabled'; $attr['checked'] = 'checked';
}
if ($value === null) {
$attr['disabled'] = 'disabled';
}
$ret .= $this->elementEmpty('input', $attr); $ret .= $this->elementEmpty('input', $attr);
$ret .= $this->start('label', array('for' => "$name:No_$ns.$directive")); $ret .= $this->start('label', array('for' => "$name:No_$ns.$directive"));
@ -351,12 +426,16 @@ class HTMLPurifier_Printer_ConfigForm_bool extends HTMLPurifier_Printer {
$attr = array( $attr = array(
'type' => 'radio', 'type' => 'radio',
'name' => "$name"."[$ns.$directive]", 'name' => "$name" . "[$ns.$directive]",
'id' => "$name:No_$ns.$directive", 'id' => "$name:No_$ns.$directive",
'value' => '0' 'value' => '0'
); );
if ($value === false) $attr['checked'] = 'checked'; if ($value === false) {
if ($value === null) $attr['disabled'] = 'disabled'; $attr['checked'] = 'checked';
}
if ($value === null) {
$attr['disabled'] = 'disabled';
}
$ret .= $this->elementEmpty('input', $attr); $ret .= $this->elementEmpty('input', $attr);
$ret .= $this->end('div'); $ret .= $this->end('div');

View File

@ -4,11 +4,16 @@ class HTMLPurifier_Printer_HTMLDefinition extends HTMLPurifier_Printer
{ {
/** /**
* Instance of HTMLPurifier_HTMLDefinition, for easy access * @type HTMLPurifier_HTMLDefinition, for easy access
*/ */
protected $def; protected $def;
public function render($config) { /**
* @param HTMLPurifier_Config $config
* @return string
*/
public function render($config)
{
$ret = ''; $ret = '';
$this->config =& $config; $this->config =& $config;
@ -28,8 +33,10 @@ class HTMLPurifier_Printer_HTMLDefinition extends HTMLPurifier_Printer
/** /**
* Renders the Doctype table * Renders the Doctype table
* @return string
*/ */
protected function renderDoctype() { protected function renderDoctype()
{
$doctype = $this->def->doctype; $doctype = $this->def->doctype;
$ret = ''; $ret = '';
$ret .= $this->start('table'); $ret .= $this->start('table');
@ -45,8 +52,10 @@ class HTMLPurifier_Printer_HTMLDefinition extends HTMLPurifier_Printer
/** /**
* Renders environment table, which is miscellaneous info * Renders environment table, which is miscellaneous info
* @return string
*/ */
protected function renderEnvironment() { protected function renderEnvironment()
{
$def = $this->def; $def = $this->def;
$ret = ''; $ret = '';
@ -59,28 +68,28 @@ class HTMLPurifier_Printer_HTMLDefinition extends HTMLPurifier_Printer
$ret .= $this->row('Block wrap name', $def->info_block_wrapper); $ret .= $this->row('Block wrap name', $def->info_block_wrapper);
$ret .= $this->start('tr'); $ret .= $this->start('tr');
$ret .= $this->element('th', 'Global attributes'); $ret .= $this->element('th', 'Global attributes');
$ret .= $this->element('td', $this->listifyAttr($def->info_global_attr),0,0); $ret .= $this->element('td', $this->listifyAttr($def->info_global_attr), null, 0);
$ret .= $this->end('tr'); $ret .= $this->end('tr');
$ret .= $this->start('tr'); $ret .= $this->start('tr');
$ret .= $this->element('th', 'Tag transforms'); $ret .= $this->element('th', 'Tag transforms');
$list = array(); $list = array();
foreach ($def->info_tag_transform as $old => $new) { foreach ($def->info_tag_transform as $old => $new) {
$new = $this->getClass($new, 'TagTransform_'); $new = $this->getClass($new, 'TagTransform_');
$list[] = "<$old> with $new"; $list[] = "<$old> with $new";
} }
$ret .= $this->element('td', $this->listify($list)); $ret .= $this->element('td', $this->listify($list));
$ret .= $this->end('tr'); $ret .= $this->end('tr');
$ret .= $this->start('tr'); $ret .= $this->start('tr');
$ret .= $this->element('th', 'Pre-AttrTransform'); $ret .= $this->element('th', 'Pre-AttrTransform');
$ret .= $this->element('td', $this->listifyObjectList($def->info_attr_transform_pre)); $ret .= $this->element('td', $this->listifyObjectList($def->info_attr_transform_pre));
$ret .= $this->end('tr'); $ret .= $this->end('tr');
$ret .= $this->start('tr'); $ret .= $this->start('tr');
$ret .= $this->element('th', 'Post-AttrTransform'); $ret .= $this->element('th', 'Post-AttrTransform');
$ret .= $this->element('td', $this->listifyObjectList($def->info_attr_transform_post)); $ret .= $this->element('td', $this->listifyObjectList($def->info_attr_transform_post));
$ret .= $this->end('tr'); $ret .= $this->end('tr');
$ret .= $this->end('table'); $ret .= $this->end('table');
@ -89,8 +98,10 @@ class HTMLPurifier_Printer_HTMLDefinition extends HTMLPurifier_Printer
/** /**
* Renders the Content Sets table * Renders the Content Sets table
* @return string
*/ */
protected function renderContentSets() { protected function renderContentSets()
{
$ret = ''; $ret = '';
$ret .= $this->start('table'); $ret .= $this->start('table');
$ret .= $this->element('caption', 'Content Sets'); $ret .= $this->element('caption', 'Content Sets');
@ -106,8 +117,10 @@ class HTMLPurifier_Printer_HTMLDefinition extends HTMLPurifier_Printer
/** /**
* Renders the Elements ($info) table * Renders the Elements ($info) table
* @return string
*/ */
protected function renderInfo() { protected function renderInfo()
{
$ret = ''; $ret = '';
$ret .= $this->start('table'); $ret .= $this->start('table');
$ret .= $this->element('caption', 'Elements ($info)'); $ret .= $this->element('caption', 'Elements ($info)');
@ -118,39 +131,39 @@ class HTMLPurifier_Printer_HTMLDefinition extends HTMLPurifier_Printer
$ret .= $this->end('tr'); $ret .= $this->end('tr');
foreach ($this->def->info as $name => $def) { foreach ($this->def->info as $name => $def) {
$ret .= $this->start('tr'); $ret .= $this->start('tr');
$ret .= $this->element('th', "<$name>", array('class'=>'heavy', 'colspan' => 2)); $ret .= $this->element('th', "<$name>", array('class' => 'heavy', 'colspan' => 2));
$ret .= $this->end('tr'); $ret .= $this->end('tr');
$ret .= $this->start('tr'); $ret .= $this->start('tr');
$ret .= $this->element('th', 'Inline content'); $ret .= $this->element('th', 'Inline content');
$ret .= $this->element('td', $def->descendants_are_inline ? 'Yes' : 'No'); $ret .= $this->element('td', $def->descendants_are_inline ? 'Yes' : 'No');
$ret .= $this->end('tr'); $ret .= $this->end('tr');
if (!empty($def->excludes)) { if (!empty($def->excludes)) {
$ret .= $this->start('tr'); $ret .= $this->start('tr');
$ret .= $this->element('th', 'Excludes'); $ret .= $this->element('th', 'Excludes');
$ret .= $this->element('td', $this->listifyTagLookup($def->excludes)); $ret .= $this->element('td', $this->listifyTagLookup($def->excludes));
$ret .= $this->end('tr'); $ret .= $this->end('tr');
} }
if (!empty($def->attr_transform_pre)) { if (!empty($def->attr_transform_pre)) {
$ret .= $this->start('tr'); $ret .= $this->start('tr');
$ret .= $this->element('th', 'Pre-AttrTransform'); $ret .= $this->element('th', 'Pre-AttrTransform');
$ret .= $this->element('td', $this->listifyObjectList($def->attr_transform_pre)); $ret .= $this->element('td', $this->listifyObjectList($def->attr_transform_pre));
$ret .= $this->end('tr'); $ret .= $this->end('tr');
} }
if (!empty($def->attr_transform_post)) { if (!empty($def->attr_transform_post)) {
$ret .= $this->start('tr'); $ret .= $this->start('tr');
$ret .= $this->element('th', 'Post-AttrTransform'); $ret .= $this->element('th', 'Post-AttrTransform');
$ret .= $this->element('td', $this->listifyObjectList($def->attr_transform_post)); $ret .= $this->element('td', $this->listifyObjectList($def->attr_transform_post));
$ret .= $this->end('tr'); $ret .= $this->end('tr');
} }
if (!empty($def->auto_close)) { if (!empty($def->auto_close)) {
$ret .= $this->start('tr'); $ret .= $this->start('tr');
$ret .= $this->element('th', 'Auto closed by'); $ret .= $this->element('th', 'Auto closed by');
$ret .= $this->element('td', $this->listifyTagLookup($def->auto_close)); $ret .= $this->element('td', $this->listifyTagLookup($def->auto_close));
$ret .= $this->end('tr'); $ret .= $this->end('tr');
} }
$ret .= $this->start('tr'); $ret .= $this->start('tr');
$ret .= $this->element('th', 'Allowed attributes'); $ret .= $this->element('th', 'Allowed attributes');
$ret .= $this->element('td',$this->listifyAttr($def->attr), array(), 0); $ret .= $this->element('td', $this->listifyAttr($def->attr), array(), 0);
$ret .= $this->end('tr'); $ret .= $this->end('tr');
if (!empty($def->required_attr)) { if (!empty($def->required_attr)) {
@ -165,64 +178,94 @@ class HTMLPurifier_Printer_HTMLDefinition extends HTMLPurifier_Printer
/** /**
* Renders a row describing the allowed children of an element * Renders a row describing the allowed children of an element
* @param $def HTMLPurifier_ChildDef of pertinent element * @param HTMLPurifier_ChildDef $def HTMLPurifier_ChildDef of pertinent element
* @return string
*/ */
protected function renderChildren($def) { protected function renderChildren($def)
{
$context = new HTMLPurifier_Context(); $context = new HTMLPurifier_Context();
$ret = ''; $ret = '';
$ret .= $this->start('tr'); $ret .= $this->start('tr');
$elements = array();
$attr = array();
if (isset($def->elements)) {
if ($def->type == 'strictblockquote') {
$def->validateChildren(array(), $this->config, $context);
}
$elements = $def->elements;
}
if ($def->type == 'chameleon') {
$attr['rowspan'] = 2;
} elseif ($def->type == 'empty') {
$elements = array(); $elements = array();
$attr = array(); } elseif ($def->type == 'table') {
if (isset($def->elements)) { $elements = array_flip(
if ($def->type == 'strictblockquote') { array(
$def->validateChildren(array(), $this->config, $context); 'col',
} 'caption',
$elements = $def->elements; 'colgroup',
} 'thead',
if ($def->type == 'chameleon') { 'tfoot',
$attr['rowspan'] = 2; 'tbody',
} elseif ($def->type == 'empty') { 'tr'
$elements = array(); )
} elseif ($def->type == 'table') { );
$elements = array_flip(array('col', 'caption', 'colgroup', 'thead', }
'tfoot', 'tbody', 'tr')); $ret .= $this->element('th', 'Allowed children', $attr);
}
$ret .= $this->element('th', 'Allowed children', $attr);
if ($def->type == 'chameleon') { if ($def->type == 'chameleon') {
$ret .= $this->element('td', $ret .= $this->element(
'<em>Block</em>: ' . 'td',
$this->escape($this->listifyTagLookup($def->block->elements)),0,0); '<em>Block</em>: ' .
$ret .= $this->end('tr'); $this->escape($this->listifyTagLookup($def->block->elements)),
$ret .= $this->start('tr'); null,
$ret .= $this->element('td', 0
'<em>Inline</em>: ' . );
$this->escape($this->listifyTagLookup($def->inline->elements)),0,0); $ret .= $this->end('tr');
$ret .= $this->start('tr');
$ret .= $this->element(
'td',
'<em>Inline</em>: ' .
$this->escape($this->listifyTagLookup($def->inline->elements)),
null,
0
);
} elseif ($def->type == 'custom') { } elseif ($def->type == 'custom') {
$ret .= $this->element('td', '<em>'.ucfirst($def->type).'</em>: ' . $ret .= $this->element(
$def->dtd_regex); 'td',
'<em>' . ucfirst($def->type) . '</em>: ' .
$def->dtd_regex
);
} else { } else {
$ret .= $this->element('td', $ret .= $this->element(
'<em>'.ucfirst($def->type).'</em>: ' . 'td',
$this->escape($this->listifyTagLookup($elements)),0,0); '<em>' . ucfirst($def->type) . '</em>: ' .
} $this->escape($this->listifyTagLookup($elements)),
null,
0
);
}
$ret .= $this->end('tr'); $ret .= $this->end('tr');
return $ret; return $ret;
} }
/** /**
* Listifies a tag lookup table. * Listifies a tag lookup table.
* @param $array Tag lookup array in form of array('tagname' => true) * @param array $array Tag lookup array in form of array('tagname' => true)
* @return string
*/ */
protected function listifyTagLookup($array) { protected function listifyTagLookup($array)
{
ksort($array); ksort($array);
$list = array(); $list = array();
foreach ($array as $name => $discard) { foreach ($array as $name => $discard) {
if ($name !== '#PCDATA' && !isset($this->def->info[$name])) continue; if ($name !== '#PCDATA' && !isset($this->def->info[$name])) {
continue;
}
$list[] = $name; $list[] = $name;
} }
return $this->listify($list); return $this->listify($list);
@ -230,13 +273,15 @@ class HTMLPurifier_Printer_HTMLDefinition extends HTMLPurifier_Printer
/** /**
* Listifies a list of objects by retrieving class names and internal state * Listifies a list of objects by retrieving class names and internal state
* @param $array List of objects * @param array $array List of objects
* @return string
* @todo Also add information about internal state * @todo Also add information about internal state
*/ */
protected function listifyObjectList($array) { protected function listifyObjectList($array)
{
ksort($array); ksort($array);
$list = array(); $list = array();
foreach ($array as $discard => $obj) { foreach ($array as $obj) {
$list[] = $this->getClass($obj, 'AttrTransform_'); $list[] = $this->getClass($obj, 'AttrTransform_');
} }
return $this->listify($list); return $this->listify($list);
@ -244,13 +289,17 @@ class HTMLPurifier_Printer_HTMLDefinition extends HTMLPurifier_Printer
/** /**
* Listifies a hash of attributes to AttrDef classes * Listifies a hash of attributes to AttrDef classes
* @param $array Array hash in form of array('attrname' => HTMLPurifier_AttrDef) * @param array $array Array hash in form of array('attrname' => HTMLPurifier_AttrDef)
* @return string
*/ */
protected function listifyAttr($array) { protected function listifyAttr($array)
{
ksort($array); ksort($array);
$list = array(); $list = array();
foreach ($array as $name => $obj) { foreach ($array as $name => $obj) {
if ($obj === false) continue; if ($obj === false) {
continue;
}
$list[] = "$name&nbsp;=&nbsp;<i>" . $this->getClass($obj, 'AttrDef_') . '</i>'; $list[] = "$name&nbsp;=&nbsp;<i>" . $this->getClass($obj, 'AttrDef_') . '</i>';
} }
return $this->listify($list); return $this->listify($list);
@ -258,15 +307,18 @@ class HTMLPurifier_Printer_HTMLDefinition extends HTMLPurifier_Printer
/** /**
* Creates a heavy header row * Creates a heavy header row
* @param string $text
* @param int $num
* @return string
*/ */
protected function heavyHeader($text, $num = 1) { protected function heavyHeader($text, $num = 1)
{
$ret = ''; $ret = '';
$ret .= $this->start('tr'); $ret .= $this->start('tr');
$ret .= $this->element('th', $text, array('colspan' => $num, 'class' => 'heavy')); $ret .= $this->element('th', $text, array('colspan' => $num, 'class' => 'heavy'));
$ret .= $this->end('tr'); $ret .= $this->end('tr');
return $ret; return $ret;
} }
} }
// vim: et sw=4 sts=4 // vim: et sw=4 sts=4

View File

@ -36,6 +36,6 @@ $gplus_url = $sns_send.'&amp;sns=gplus';
<li><a href="<?php echo $twitter_url; ?>" target="_blank"><img src="<?php echo G5_SNS_URL; ?>/icon/twitter.png" alt="트위터로 보내기"></a></li> <li><a href="<?php echo $twitter_url; ?>" target="_blank"><img src="<?php echo G5_SNS_URL; ?>/icon/twitter.png" alt="트위터로 보내기"></a></li>
<li><a href="<?php echo $gplus_url; ?>" target="_blank"><img src="<?php echo G5_SNS_URL; ?>/icon/gplus.png" alt="구글플러스로 보내기"></a></li> <li><a href="<?php echo $gplus_url; ?>" target="_blank"><img src="<?php echo G5_SNS_URL; ?>/icon/gplus.png" alt="구글플러스로 보내기"></a></li>
<?php if(G5_IS_MOBILE && $config['cf_kakao_js_apikey']) { ?> <?php if(G5_IS_MOBILE && $config['cf_kakao_js_apikey']) { ?>
<li><a href="javascript:kakaolink_send('<?php echo $sns_msg; ?>', '<?php echo urlencode('http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']); ?>');"><img src="<?php echo G5_SNS_URL; ?>/icon/kakaotalk.png" alt="카카오톡으로 보내기"></a> <li><a href="javascript:kakaolink_send('<?php echo $sns_msg; ?>', '<?php echo urlencode('http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']); ?>');"><img src="<?php echo G5_SNS_URL; ?>/icon/kakaotalk.png" alt="카카오톡으로 보내기"></a></li>
<?php } ?> <?php } ?>
</ul> </ul>

View File

@ -6,8 +6,8 @@ if (G5_IS_MOBILE) {
return; return;
} }
$sfl = trim($_REQUEST['sfl']); //$sfl = trim($_REQUEST['sfl']);
$stx = trim($_REQUEST['stx']); //$stx = trim($_REQUEST['stx']);
$g5['title'] = '상품문의'; $g5['title'] = '상품문의';
include_once('./_head.php'); include_once('./_head.php');

View File

@ -6,8 +6,8 @@ if (G5_IS_MOBILE) {
return; return;
} }
$sfl = trim($_REQUEST['sfl']); //$sfl = trim($_REQUEST['sfl']);
$stx = trim($_REQUEST['stx']); //$stx = trim($_REQUEST['stx']);
$g5['title'] = '사용후기'; $g5['title'] = '사용후기';
include_once('./_head.php'); include_once('./_head.php');

View File

@ -22,7 +22,30 @@ add_stylesheet('<link rel="stylesheet" href="'.$member_skin_url.'/style.css">',
<section id="fregister_private"> <section id="fregister_private">
<h2>개인정보처리방침안내</h2> <h2>개인정보처리방침안내</h2>
<textarea readonly><?php echo get_text($config['cf_privacy']) ?></textarea> <div class="tbl_head01 tbl_wrap">
<table>
<caption>개인정보처리방침안내</caption>
<thead>
<tr>
<th>목적</th>
<th>항목</th>
<th>보유기간</th>
</tr>
</thead>
<tbody>
<tr>
<td>이용자 식별 및 본인여부 확인</td>
<td>아이디, 이름, 비밀번호</td>
<td>회원 탈퇴 시까지</td>
</tr>
<tr>
<td>고객서비스 이용에 관한 통지,<br>CS대응을 위한 이용자 식별</td>
<td>연락처 (이메일, 휴대전화번호)</td>
<td>회원 탈퇴 시까지</td>
</tr>
</tbody>
</table>
</div>
<fieldset class="fregister_agree"> <fieldset class="fregister_agree">
<label for="agree21">개인정보처리방침안내의 내용에 동의합니다.</label> <label for="agree21">개인정보처리방침안내의 내용에 동의합니다.</label>
<input type="checkbox" name="agree2" value="1" id="agree21"> <input type="checkbox" name="agree2" value="1" id="agree21">

View File

@ -89,6 +89,9 @@
#fregister .fregister_agree label {display:inline-block;margin-right:5px} #fregister .fregister_agree label {display:inline-block;margin-right:5px}
#fregister p {color:#e8180c;text-align:center} #fregister p {color:#e8180c;text-align:center}
#fregister .btn_confirm {margin-bottom:20px} #fregister .btn_confirm {margin-bottom:20px}
#fregister_private .tbl_head01 th{;text-align:center;border:1px solid #d1dee2;width:33%}
#fregister_private .tbl_head01 td {border:1px solid #e9e9e9}
#fregister_private .tbl_head01 caption{position:absolute;font-size:0;line-height:0;overflow:hidden}
/* 회원가입 입력 */ /* 회원가입 입력 */
#fregisterform textarea {height:50px} #fregisterform textarea {height:50px}

View File

@ -35,12 +35,79 @@ add_stylesheet('<link rel="stylesheet" href="'.$member_skin_url.'/style.css">',
</div> </div>
</section> </section>
</form>
<?php // 쇼핑몰 사용시 여기부터 ?>
<?php if ($default['de_level_sell'] == 1) { // 상품구입 권한 ?>
<!-- 주문하기, 신청하기 -->
<?php if (preg_match("/orderform.php/", $url)) { ?>
<section id="mb_login_notmb">
<h2>비회원 구매</h2>
<p>
비회원으로 주문하시는 경우 포인트는 지급하지 않습니다.
</p>
<div id="guest_privacy">
<?php echo $default['de_guest_privacy']; ?>
</div>
<label for="agree">개인정보수집에 대한 내용을 읽었으며 이에 동의합니다.</label>
<input type="checkbox" id="agree" value="1">
<div class="btn_confirm">
<a href="javascript:guest_submit(document.flogin);" class="btn02">비회원으로 구매하기</a>
</div>
<script>
function guest_submit(f)
{
if (document.getElementById('agree')) {
if (!document.getElementById('agree').checked) {
alert("개인정보수집에 대한 내용을 읽고 이에 동의하셔야 합니다.");
return;
}
}
f.url.value = "<?php echo $url; ?>";
f.action = "<?php echo $url; ?>";
f.submit();
}
</script>
</section>
<?php } else if (preg_match("/orderinquiry.php$/", $url)) { ?>
<fieldset id="mb_login_od">
<legend>비회원 주문조회</legend>
<form name="forderinquiry" method="post" action="<?php echo urldecode($url); ?>" autocomplete="off">
<label for="od_id" class="od_id sound_only">주문번호<strong class="sound_only"> 필수</strong></label>
<input type="text" name="od_id" value="<?php echo $od_id ?>" id="od_id" placeholder="주문번호" required class="frm_input required" size="20">
<label for="id_pwd" class="od_pwd sound_only">비밀번호<strong class="sound_only"> 필수</strong></label>
<input type="password" name="od_pwd" size="20" id="od_pwd" placeholder="비밀번호" required class="frm_input required">
<input type="submit" value="확인" class="btn_submit">
</form>
</fieldset>
<section id="mb_login_odinfo">
<h2>비회원 주문조회 안내</h2>
<p>메일로 발송해드린 주문서의 <strong>주문번호</strong> 및 주문 시 입력하신 <strong>비밀번호</strong>를 정확히 입력해주십시오.</p>
</section>
<?php } ?>
<?php } ?>
<?php // 쇼핑몰 사용시 여기까지 반드시 복사해 넣으세요 ?>
<div class="btn_confirm"> <div class="btn_confirm">
<a href="<?php echo G5_URL ?>/">메인으로 돌아가기</a> <a href="<?php echo G5_URL ?>/">메인으로 돌아가기</a>
</div> </div>
</form>
</div> </div>
<script> <script>

View File

@ -22,7 +22,30 @@ add_stylesheet('<link rel="stylesheet" href="'.$member_skin_url.'/style.css">',
<section id="fregister_private"> <section id="fregister_private">
<h2>개인정보처리방침안내</h2> <h2>개인정보처리방침안내</h2>
<textarea readonly><?php echo get_text($config['cf_privacy']) ?></textarea> <div class="tbl_head01 tbl_wrap">
<table>
<caption>개인정보처리방침안내</caption>
<thead>
<tr>
<th>목적</th>
<th>항목</th>
<th>보유기간</th>
</tr>
</thead>
<tbody>
<tr>
<td>이용자 식별 및 본인여부 확인</td>
<td>아이디, 이름, 비밀번호</td>
<td>회원 탈퇴 시까지</td>
</tr>
<tr>
<td>고객서비스 이용에 관한 통지,<br>CS대응을 위한 이용자 식별</td>
<td>연락처 (이메일, 휴대전화번호)</td>
<td>회원 탈퇴 시까지</td>
</tr>
</tbody>
</table>
</div>
<fieldset class="fregister_agree"> <fieldset class="fregister_agree">
<label for="agree21">개인정보처리방침안내의 내용에 동의합니다.</label> <label for="agree21">개인정보처리방침안내의 내용에 동의합니다.</label>
<input type="checkbox" name="agree2" value="1" id="agree21"> <input type="checkbox" name="agree2" value="1" id="agree21">

View File

@ -80,6 +80,10 @@
.fregister_agree label {display:inline-block;margin-right:5px} .fregister_agree label {display:inline-block;margin-right:5px}
#fregister p {color:#e8180c;text-align:center} #fregister p {color:#e8180c;text-align:center}
#fregister .btn_confirm {margin:15px 0} #fregister .btn_confirm {margin:15px 0}
#fregister_private .tbl_head01 {margin:0}
#fregister_private .tbl_head01 th{;text-align:center;border:1px solid #d1dee2;width:33%}
#fregister_private .tbl_head01 td {border:1px solid #e9e9e9;background:#fff}
#fregister_private .tbl_head01 caption{position:absolute;font-size:0;line-height:0;overflow:hidden;top:0;color:#fff}
/* 회원가입 입력 */ /* 회원가입 입력 */
#fregisterform #reg_mb_email, #fregisterform .frm_address {width:100%} #fregisterform #reg_mb_email, #fregisterform .frm_address {width:100%}

View File

@ -22,7 +22,31 @@ add_stylesheet('<link rel="stylesheet" href="'.$member_skin_url.'/style.css">',
<section id="fregister_private"> <section id="fregister_private">
<h2>개인정보처리방침안내</h2> <h2>개인정보처리방침안내</h2>
<textarea readonly><?php echo get_text($config['cf_privacy']) ?></textarea> <div class="tbl_head01 tbl_wrap">
<table>
<caption>개인정보처리방침안내</caption>
<thead>
<tr>
<th>목적</th>
<th>항목</th>
<th>보유기간</th>
</tr>
</thead>
<tbody>
<tr>
<td>이용자 식별 및 본인여부 확인</td>
<td>아이디, 이름, 비밀번호</td>
<td>회원 탈퇴 시까지</td>
</tr>
<tr>
<td>고객서비스 이용에 관한 통지,<br>CS대응을 위한 이용자 식별</td>
<td>연락처 (이메일, 휴대전화번호)</td>
<td>회원 탈퇴 시까지</td>
</tr>
</tbody>
</table>
</div>
<fieldset class="fregister_agree"> <fieldset class="fregister_agree">
<label for="agree21">개인정보처리방침안내의 내용에 동의합니다.</label> <label for="agree21">개인정보처리방침안내의 내용에 동의합니다.</label>
<input type="checkbox" name="agree2" value="1" id="agree21"> <input type="checkbox" name="agree2" value="1" id="agree21">

View File

@ -89,6 +89,9 @@
#fregister .fregister_agree label {display:inline-block;margin-right:5px} #fregister .fregister_agree label {display:inline-block;margin-right:5px}
#fregister p {color:#e8180c;text-align:center} #fregister p {color:#e8180c;text-align:center}
#fregister .btn_confirm {margin-bottom:20px} #fregister .btn_confirm {margin-bottom:20px}
#fregister_private .tbl_head01 th{;text-align:center;border:1px solid #d1dee2;width:33%}
#fregister_private .tbl_head01 td {border:1px solid #e9e9e9}
#fregister_private .tbl_head01 caption{position:absolute;font-size:0;line-height:0;overflow:hidden}
/* 회원가입 입력 */ /* 회원가입 입력 */
#fregisterform textarea {height:50px} #fregisterform textarea {height:50px}