127 lines
5.0 KiB
PHP
127 lines
5.0 KiB
PHP
|
|
<?php
|
||
|
|
declare(strict_types=1);
|
||
|
|
|
||
|
|
/** @var string $buttonId 주소 검색 버튼 id */
|
||
|
|
$buttonId = $buttonId ?? 'btn-kakao-postcode';
|
||
|
|
/** @var string $zipName 우편번호 input name */
|
||
|
|
$zipName = $zipName ?? 'ds_zip';
|
||
|
|
/** @var string $roadName 도로명 input name */
|
||
|
|
$roadName = $roadName ?? 'ds_addr';
|
||
|
|
/** @var string $jibunName 지번 input name */
|
||
|
|
$jibunName = $jibunName ?? 'ds_addr_jibun';
|
||
|
|
/** @var string $sidoFieldName 카카오 시·도 → hidden name (비우면 미설정) */
|
||
|
|
$sidoFieldName = $sidoFieldName ?? '';
|
||
|
|
/** @var string $sigunguFieldName 카카오 시·군·구 → hidden name */
|
||
|
|
$sigunguFieldName = $sigunguFieldName ?? '';
|
||
|
|
/** @var string $detailFieldName 상세주소 input name (건물명 등, 비우면 미사용) */
|
||
|
|
$detailFieldName = $detailFieldName ?? '';
|
||
|
|
/**
|
||
|
|
* @var array{lg_sido?: string, lg_gugun?: string}|null $tenantScope 지자체 관할 검사(비우면 미검사)
|
||
|
|
*/
|
||
|
|
$tenantScope = $tenantScope ?? null;
|
||
|
|
/** @var bool $roadBaseOnly true면 도로명에 건물명 괄호 미부착(상세로 이전) */
|
||
|
|
$roadBaseOnly = ! empty($roadBaseOnly);
|
||
|
|
?>
|
||
|
|
<script src="https://t1.daumcdn.net/mapjsapi/bundle/postcode/prod/postcode.v2.js"></script>
|
||
|
|
<script>
|
||
|
|
(function () {
|
||
|
|
var btnId = <?= json_encode($buttonId, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT) ?>;
|
||
|
|
var zipName = <?= json_encode($zipName, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT) ?>;
|
||
|
|
var roadName = <?= json_encode($roadName, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT) ?>;
|
||
|
|
var jibunName = <?= json_encode($jibunName, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT) ?>;
|
||
|
|
var sidoFieldName = <?= json_encode($sidoFieldName, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT) ?>;
|
||
|
|
var sigunguFieldName = <?= json_encode($sigunguFieldName, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT) ?>;
|
||
|
|
var detailFieldName = <?= json_encode($detailFieldName, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT) ?>;
|
||
|
|
var roadBaseOnly = <?= $roadBaseOnly ? 'true' : 'false' ?>;
|
||
|
|
var tenantScope = <?= json_encode($tenantScope ?? (object) [], JSON_UNESCAPED_UNICODE | JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT) ?>;
|
||
|
|
|
||
|
|
function compactStr(s) {
|
||
|
|
return String(s || '').replace(/\s+/g, '');
|
||
|
|
}
|
||
|
|
|
||
|
|
function tokenMatches(needle, primary, blob) {
|
||
|
|
var n = compactStr(needle);
|
||
|
|
if (!n) return true;
|
||
|
|
var b = compactStr(blob);
|
||
|
|
if (b.indexOf(n) !== -1) return true;
|
||
|
|
var p = compactStr(primary);
|
||
|
|
if (p.indexOf(n) !== -1) return true;
|
||
|
|
if (n.indexOf(p) !== -1 && p) return true;
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
function addressAllowedByTenant(data) {
|
||
|
|
var lgSido = tenantScope && tenantScope.lg_sido ? String(tenantScope.lg_sido) : '';
|
||
|
|
var lgGugun = tenantScope && tenantScope.lg_gugun ? String(tenantScope.lg_gugun) : '';
|
||
|
|
if (!lgSido && !lgGugun) return true;
|
||
|
|
var sido = data.sido || '';
|
||
|
|
var sigungu = data.sigungu || '';
|
||
|
|
var road = data.roadAddress || '';
|
||
|
|
var jibun = data.jibunAddress || '';
|
||
|
|
var zip = data.zonecode || '';
|
||
|
|
var blob = sido + ' ' + sigungu + ' ' + road + ' ' + jibun + ' ' + zip;
|
||
|
|
if (lgSido && !tokenMatches(lgSido, sido, blob)) return false;
|
||
|
|
if (lgGugun && !tokenMatches(lgGugun, sigungu, blob)) return false;
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
function bind() {
|
||
|
|
var btn = document.getElementById(btnId);
|
||
|
|
if (!btn) return;
|
||
|
|
var form = btn.closest('form');
|
||
|
|
if (!form) return;
|
||
|
|
|
||
|
|
function field(n) {
|
||
|
|
return form.querySelector('[name="' + n + '"]');
|
||
|
|
}
|
||
|
|
|
||
|
|
btn.addEventListener('click', function () {
|
||
|
|
if (typeof daum === 'undefined' || !daum.Postcode) {
|
||
|
|
window.alert('주소 검색 스크립트를 불러오지 못했습니다. 네트워크를 확인해 주세요.');
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
new daum.Postcode({
|
||
|
|
oncomplete: function (data) {
|
||
|
|
if (!addressAllowedByTenant(data)) {
|
||
|
|
window.alert('작업 중인 지자체 관할이 아닌 주소입니다. 해당 시·구 주소를 검색해 주세요.');
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
var zipEl = field(zipName);
|
||
|
|
var roadEl = field(roadName);
|
||
|
|
var jibunEl = field(jibunName);
|
||
|
|
if (zipEl) zipEl.value = data.zonecode || '';
|
||
|
|
|
||
|
|
var roadAddr = data.roadAddress || '';
|
||
|
|
if (!roadBaseOnly && data.buildingName !== '') {
|
||
|
|
roadAddr += (roadAddr !== '' ? ' (' + data.buildingName + ')' : data.buildingName);
|
||
|
|
}
|
||
|
|
if (roadEl) roadEl.value = roadAddr;
|
||
|
|
|
||
|
|
if (jibunEl) jibunEl.value = data.jibunAddress || '';
|
||
|
|
|
||
|
|
if (sidoFieldName) {
|
||
|
|
var sidoEl = field(sidoFieldName);
|
||
|
|
if (sidoEl) sidoEl.value = data.sido || '';
|
||
|
|
}
|
||
|
|
if (sigunguFieldName) {
|
||
|
|
var sigEl = field(sigunguFieldName);
|
||
|
|
if (sigEl) sigEl.value = data.sigungu || '';
|
||
|
|
}
|
||
|
|
if (detailFieldName && roadBaseOnly) {
|
||
|
|
var detEl = field(detailFieldName);
|
||
|
|
if (detEl) detEl.value = data.buildingName || '';
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}).open();
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
if (document.readyState === 'loading') {
|
||
|
|
document.addEventListener('DOMContentLoaded', bind);
|
||
|
|
} else {
|
||
|
|
bind();
|
||
|
|
}
|
||
|
|
})();
|
||
|
|
</script>
|