public static function wskl_country_ip_block()
 {
     // 옵션을 업데이트할 때 발생하는 값을 체크하여,
     // DB 덤프 등으로 옮겨 놓은 직후 임시 상태의 사이트에 대해서 IP 블록을 생략.
     $target = wskl_get_option('ip_block_target');
     if (site_url() != $target) {
         return;
     }
     // result sample: array( 'country' => KR, 'state' => '' );
     $result = WC_Geolocation::geolocate_ip($_SERVER['REMOTE_ADDR']);
     $white_list = preg_replace('/\\s+/', '', get_option('wskl_white_ipcode_list'));
     // not a valid white list. ip block will be disabled.
     if (empty($white_list)) {
         return;
     }
     // at least open for wp-login,
     $white_list = explode(',', $white_list);
     $allowed = FALSE;
     foreach ($white_list as $country_code) {
         if ($country_code == $result['country']) {
             $allowed = TRUE;
             break;
         }
     }
     if (!$allowed) {
         wp_die('Blocked by IP');
     }
 }
 public static function init()
 {
     add_action('admin_menu', array(__CLASS__, 'admin_menu'));
     add_action('wp_loaded', array(__CLASS__, 'handle_form_submit'));
     self::$keys_to_filter = array_merge(self::$fixed_filtered_keys, (array) wskl_get_option('config_editor_keys_to_filter', array()));
     self::$must_use_configs = apply_filters('wskl_config_editor_must_use_configs', self::$must_use_configs);
 }
 public static function factory()
 {
     $id = wskl_get_option('sms_provider_id');
     $password = wskl_get_option('sms_provider_password');
     $sender = wskl_get_option('sms_sender_phone');
     return new static($id, $password, $sender);
 }
function wskl_add_xdebug_session_start()
{
    $session_value = absint(wskl_get_option('develop_xdebug_session_id'));
    if ($session_value) {
        setcookie('XDEBUG_SESSION', $session_value, time() + HOUR_IN_SECONDS);
    } else {
        setcookie('XDEBUG_SESSION', '', time() - DAY_IN_SECONDS);
    }
}
 private static function output_term($term_slug, $fallback_text = '')
 {
     $post = WP_Post::get_instance(wskl_get_option('members_page_' . $term_slug));
     if (!$post) {
         echo $fallback_text;
     } else {
         echo '<h3>' . esc_html($post->post_title) . '</h3>';
         echo wpautop(wptexturize($post->post_content));
     }
 }
 /**
  * 문자 메시지 테스트 ajax 요청 응답
  *
  * @callback
  * @action       wp_ajax_dabory-sms-tester
  *
  * @throws \Exception
  */
 public static function do_message_testing()
 {
     wskl_verify_nonce('dabory-sms-tester-nonce', $_POST['dabory-sms-tester-nonce']);
     do_action('dabory_sms_load_provider_module');
     $dalin = WSKL_Dabory_SMS_Provider_MDalin::factory();
     $result = $dalin->send_message(array('remote_msg' => '[웹발신]테스트 문자입니다. ' . site_url(), 'remote_phone' => wskl_get_option('sms_sender_phone')));
     @header('Content-Type: application/json; charset=' . get_option('blog_charset'));
     echo wp_json_encode(array('success' => TRUE, 'data' => $result));
     die;
 }
 public static function register_buttons($buttons)
 {
     global $post;
     $post_alert = wskl_get_option('inactive-accounts_post_alert');
     $post_deactivation = wskl_get_option('inactive-accounts_post_deactivation');
     if ($post->ID != $post_alert && $post->ID != $post_deactivation) {
         return $buttons;
     }
     array_push($buttons, 'inactive_accounts_shortcodes_button');
     return $buttons;
 }
 function wskl_get_wp_log()
 {
     $log_file = WP_CONTENT_DIR . '/debug.log';
     if (file_exists($log_file)) {
         $log_text = tail_custom($log_file, wskl_get_option('develop_log_line', 100));
     } else {
         $log_text = 'LOG FILE NOT FOUND!';
     }
     // note: too many lines will refuse conversion.
     $log_text = htmlspecialchars($log_text, ENT_QUOTES);
     return $log_text;
 }
 public function shortcode_processing()
 {
     $active_span = wskl_get_option('inactive-accounts_active_span');
     $post_alert = wskl_get_option('inactive-accounts_post_alert');
     $post_deactivation = wskl_get_option('inactive-accounts_post_deactivation');
     if (!$active_span || $post_alert < 1 || $post_deactivation < 1) {
         $error_message = "Shortcode processing halted due to invalid setting values." . "\$active_span={$active_span}, " . "\$post_alert={$post_alert}, " . "\$post_deactivation={$post_deactivation}. ";
         error_log($error_message);
         return;
     }
     $this->active_span = $active_span;
     $this->add_shortcodes();
 }
 function test_wskl_get_option()
 {
     $option_name = 'test_option';
     $prefixed_option_name = wskl_get_option_name($option_name);
     update_option($prefixed_option_name, 'yes');
     $this->assertTrue(get_option($prefixed_option_name) === 'yes');
     $this->assertTrue('yes' === wskl_get_option($option_name));
     update_option($prefixed_option_name, 'no');
     $this->assertTrue(get_option($prefixed_option_name) === 'no');
     $this->assertTrue('no' === wskl_get_option($option_name));
     update_option($prefixed_option_name, '0');
     $this->assertTrue(get_option($prefixed_option_name) === '0');
     $this->assertTrue('0' === wskl_get_option($option_name));
     update_option($prefixed_option_name, 'test-value');
     $this->assertTrue(get_option($prefixed_option_name) === 'test-value');
     $this->assertTrue('test-value' === wskl_get_option($option_name));
 }
/**
 * Prepared for CloudFlare Flexible SSL.
 *
 * @return mixed|string|void
 */
function wskl_get_host_api_url()
{
    $cassandra_ip_address = wskl_get_option('cassandra_ip_address', '');
    $override_url = wskl_get_option('develop_cassandra_url');
    if (empty($cassandra_ip_address)) {
        $hostname = parse_url(WSKL_HOST_API_URL, PHP_URL_HOST);
        if ($hostname) {
            $cassandra_ip_address = gethostbyname($hostname);
            update_option(wskl_get_option_name('cassandra_ip_address'), $cassandra_ip_address);
        }
    }
    if (wskl_debug_enabled() && !empty($override_url)) {
        return $override_url;
    }
    if ($cassandra_ip_address == '127.0.0.1') {
        return WSKL_ALTERNATE_HOST_API_URL;
    }
    return WSKL_HOST_API_URL;
}
 public static function get_gateway_methods()
 {
     $enabled_methods = wskl_get_option('checkout_methods');
     $available_methods = array_keys(WSKL_Payment_Gates::get_checkout_methods());
     $result = array();
     $checkout_methods = array_intersect($enabled_methods, $available_methods);
     foreach ($checkout_methods as $key) {
         $class_name = 'WC_Gateway_WSKL_Iamport_' . ucfirst($key);
         if (class_exists($class_name)) {
             $result[] = $class_name;
         }
     }
     return $result;
 }
 public static function callback_pay_form_args(array $pay_form_args)
 {
     $pg_agency = wskl_get_option('pg_agency');
     if (wskl_is_option_enabled("enable_combined_tax_{$pg_agency}") && method_exists(__CLASS__, "combined_tax_{$pg_agency}")) {
         return call_user_func_array(array(__CLASS__, "combined_tax_{$pg_agency}"), array($pay_form_args));
     }
     return $pay_form_args;
 }
 /**
  * @callback
  * @filter    cron_schedules
  *
  * @param array $schedules
  *
  * @return array
  */
 public function add_cron_schedule($schedules)
 {
     /** @var WSKL_Inactive_Accounts_Admin $admin */
     $interval = wskl_get_option('inactive-accounts_interval');
     if (!$interval) {
         return $schedules;
     }
     $schedules['wskl_inactive_accounts_check_interval'] = array('interval' => $interval * HOUR_IN_SECONDS, 'display' => sprintf(_n('휴면계정: 매 %d 시간 마다.', '휴면계정: 매 %d 시간 마다.', 'wskl'), $interval));
     return $schedules;
 }
 public function customize_register_form($rows, $toggle)
 {
     if ($toggle != 'new' && $toggle != 'edit') {
         return $rows;
     }
     $custom_css = esc_textarea(wskl_get_option('members_registration_custom_css'));
     if (!empty($custom_css)) {
         //			wp_add_inline_style( 'wskl-frontend', $custom_css );
         $script = "<style type=\"text/css\">{$custom_css}</style>";
         echo $script;
     }
     // 주소 찾기 기능
     if (wskl_is_option_enabled('members_enable_postcode_button')) {
         $rows = self::include_postcode_button($rows);
     }
     // 비밀번호 강도 표시 알림
     if (wskl_is_option_enabled('members_password_strength_meter')) {
         self::add_psm_scripts('password', 'confirm_password');
     }
     foreach ($rows as &$row) {
         if ($row['meta'] == 'password') {
             $row['field_after'] = self::get_password_guide_output() . $row['field_after'];
         }
     }
     return $rows;
 }
 /**
  * 아임포트 활성화 시 대응 (우리도 아임포트를 쓸 경우에만 동작)
  *
  * @callback
  * @used-by wskl_plugin_monitor()
  */
 public static function iamport_plugin()
 {
     if (wskl_woocommerce_found() && wskl_get_option('pg_agency') == 'iamport') {
         add_action('admin_notices', array(__CLASS__, 'output_iamport_is_active'));
     }
 }
    private function settings_fields()
    {
        // specify settings fields
        $pg_agency = get_option(wskl_get_option_name('pg_agency'));
        $settings['preview'] = array('title' => __('일러두기', 'wskl'), 'description' => __('다보리를 만든 목적과 사용 방법 및 구매와 기술지원 방법과 업그레이드 등을 설명합니다.', 'wskl'), 'fields' => array(array('id' => 'dummy_1', 'label' => __('제작 목적', 'wskl'), 'description' => '<ol class="wskl-notice">' . '<li>' . __('워드프레스와 우커머스를 Cafe24나 고도몰처럼" 더 쉽고 더 편리하게 만들었습니다.', 'wskl') . '</li>' . '<li>' . __('쇼핑몰 영업에 꼭 필요한 기능만을 모두 담아서 최소의 비용으로 제공합니다.', 'wskl') . '</li>' . '<li>' . __('"다보리 마케팅 자동화 서버와 연동"하여 중소상공인을 위한 "마케팅 자동화" 서비스를 제공합니다.', 'wskl') . '</li>' . '</ol>', 'type' => 'caption', 'default' => ''), array('id' => 'dummy_2', 'label' => __('사용방법', 'wskl'), 'description' => __('<span class="wskl-notice">플러그인 인증키로 "제품 인증"을 하기 전에는 본플러그인의 기능을 사용할 수 없습니다.<br/></span>
						<a href="https://www.dabory.com/" target="_blank" >"다보리 플러그인 인증키 확인" 페이지로 바로가기</a>
					', 'wskl'), 'type' => 'caption', 'default' => ''), array('id' => 'dummy_5', 'label' => __('업데이트/기술지원', 'wskl'), 'description' => __('
						<a href="http://www.symphonysoft.co.kr/%ED%94%8C%EB%9F%AC%EA%B7%B8%EC%9D%B8/" target="_blank" >플러그인 다운로드</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="https://www.dabory.co.kr/cs/service/" target="_blank">기술지원 요청 바로가기</a>&nbsp;&nbsp;&nbsp;&nbsp;<a href="https://www.dabory.com/shoppingmall/webhosting/" target="_blank" >전용관리 웹호스팅 알아보기</a><br/>
					', 'wskl'), 'type' => 'caption', 'default' => ''), array('id' => 'enable_config_editor', 'label' => __('설정편집', 'wskl'), 'description' => __('간단한 wp-config.php 설정 편집 기능 사용.<br><span class="wskl-notice">이 설정은 wp-config.php 파일을 편집합니다. 유지보수시에만 제한적으로 이용하세요.</span>', 'wskl'), 'type' => 'checkbox', 'default' => '')));
        $payment_description = '';
        //		$essential_description            = '';
        //		$extension_description            = '';
        //		$marketing_automation_description = '';
        if (isset($_GET['tab']) && $_GET['tab'] == 'authentication') {
            $payment_description = sprintf('%s <a href="#" id="payment_license_activation">%s</a><br/><span id="payment_license_status">%s</span>', __('활성화 키를 입력후 기능을 활성화하십시오.', 'wskl'), __('키 인증', 'wskl'), WSKL_Auth::get_license_duration_string('payment'));
            //			$essential_description = sprintf(
            //				'%s <a href="#" id="essential_license_activation">%s</a><br/><span id="essential_license_status">%s</span>',
            //				__( '핵심기능 키를 입력후 기능을 활성화하십시오.', 'wskl' ),
            //				__( '핵심기능 인증', 'wskl' ),
            //				WSKL_Auth::get_license_duration_string( 'essential' )
            //			);
            //
            //			$extension_description = sprintf(
            //				'%s <a href="#" id="extension_license_activation">%s</a><br/><span id="extension_license_status">%s</span>',
            //				__( '확장기능 키를 입력후 기능을 활성화하십시오.', 'wskl' ),
            //				__( '확장기능 인증', 'wskl' ),
            //				WSKL_Auth::get_license_duration_string( 'extension' )
            //			);
            //
            //			$marketing_automation_description = sprintf(
            //				'%s <a href="#" id="marketing_automation_license_activation">%s</a><br/><span id="marketing_automation_license_status">%s</span>',
            //				__( '마케팅자동화 키를 입력후 기능을 활성화하십시오.', 'wskl' ),
            //				__( '마케팅자동화 인증', 'wskl' ),
            //				WSKL_Auth::get_license_duration_string( 'marketing' )
            //			);
        }
        $settings['authentication'] = array('title' => __('제품인증', 'wskl'), 'description' => __('제품 구매 또는 무료 사용시 www.dabory.com에서 부여된 활성화키로 플러그인을 먼저 활성화후 사용 가능합니다.<br/>
						<a href="https://www.dabory.com/my-account/view-order/" target="_blank" ><span class="wskl-notice">"다보리 플러그인 인증키 확인" 페이지로 바로가기</span></a>', 'wskl'), 'fields' => array(array('id' => 'dummy_3', 'label' => __('사이트 주소(URL)', 'wskl'), 'description' => __('
						' . get_option('siteurl') . '<br/>
						<span class="wskl-notice">인증키는 사이트 주소와 다보리 메타(meta) 서버 측과 동기화되어 활성화되므로 <br/>
						관리자모드 "설정"에서 "사이트를 변경하는 경우" 다시 기능 활성화를 하셔야 합니다. </span>
					', 'wskl'), 'type' => 'caption', 'default' => ''), array('id' => 'payment_license', 'label' => __('활성화 키', 'wskl'), 'description' => $payment_description, 'type' => 'longtext', 'default' => '', 'placeholder' => '')));
        $settings['checkout-payment-gates'] = array('title' => __('지불기능(A)', 'wskl'), 'description' => __('국내의 모든 지불 대행 회사의 결제 플러그인을 지원합니다.<br/>
						<span class="wskl-notice">현재 지원되지 않는 플러그인은 무료로 개발해드립니다.</span><br/>
			            결제대행(PG)회사를 추가하기를 원하는 경우  service@econoq.co.kr 로 메일 주시면  1주일이내에 개발해 드리겠습니다.<br/>
						<a href="http://www.symphonysoft.co.kr/" target="_blank">신규 플러그인 개발 요청 하러 가기</a><br/>', 'wskl'), 'fields' => array(array('id' => 'enable_sym_pg', 'label' => __('다보리 PG 사용 설정', 'wskl'), 'description' => __('다보리 PG (Payment Gateway) 기능 사용 여부를 설정합니다.', 'wskl'), 'type' => 'checkbox', 'default' => ''), array('id' => 'company', 'label' => __('회사명 입력 가능', 'wskl'), 'description' => __('사업자 대상 위주 판매의 경우 회사명을 입력 가능 설정을 합니다.', 'wskl'), 'type' => 'checkbox', 'default' => ''), array('id' => 'pg_agency', 'label' => __('결제대행업체', 'wskl'), 'description' => __('<span class="wskl-notice">변경시 자동으로 저장됩니다.</span> ', 'wskl'), 'type' => 'select', 'options' => WSKL_Payment_Gates::get_pay_gates(), 'default' => 'payapp')));
        switch ($pg_agency) {
            // 기존 PG Agency (Active-X 기반) 공통 설정 필드 #1
            case 'kcp':
            case 'inicis':
            case 'ags':
                $agencies_common_fields = (include WSKL_PATH . '/includes/admin/settings/structures/checkout-payment-gates/fields/classic-pg-agencies-common-fields-1.php');
                $settings['checkout-payment-gates']['fields'] = array_merge($settings['checkout-payment-gates']['fields'], $agencies_common_fields);
                break;
                // 페이앱 전용 필드 #1
            // 페이앱 전용 필드 #1
            case 'payapp':
                array_push($settings['checkout-payment-gates']['fields'], array('id' => 'checkout_methods', 'label' => __('결제방식 지정', 'wskl'), 'description' => __('&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;사용하실 결제방식을 지정해 주십시오.', 'wskl'), 'type' => 'checkbox_multi', 'options' => WSKL_Payment_Gates::get_checkout_methods(), 'default' => array('credit', '신용카드')));
                break;
                // 아임포트 전용 필드 #1
            // 아임포트 전용 필드 #1
            case 'iamport':
                array_push($settings['checkout-payment-gates']['fields'], array('id' => 'checkout_methods', 'label' => __('결제방식 지정', 'wskl'), 'description' => __('&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;사용하실 결제방식을 지정해 주십시오.', 'wskl'), 'type' => 'checkbox_multi', 'options' => WSKL_Payment_Gates::get_checkout_methods('iamport'), 'default' => array('credit', '신용카드')), array('id' => 'dummy_33', 'label' => __('아임포트 결정방법', 'wskl'), 'description' => __('<span class="wskl-notice">아임포트 결제와 관련된 내용은 아임포트 서버에서 실행되는 내용이므로 다보리에서 책임지지 않습니다. </span><br><a href="https://admin.iamport.kr/settings" target="_blank">아임포트 PG 설정 바로가기</a><br/>
						1. 아임포트에서는 현재 카카오페이, LGU+, KCP, 이니시스, JT-Net, 나이스정보통신이 지원되며 <br>가맹점 설정은 아임포트 사이트에 회원가입/로그인한 후 설정하여야 합니다.', 'wskl'), 'type' => 'caption', 'default' => ''));
                break;
        }
        switch ($pg_agency) {
            // 페이앱 전용 필드 #2: 인증사항
            case 'payapp':
                $settings['checkout-payment-gates']['fields'] = array_merge($settings['checkout-payment-gates']['fields'], include WSKL_PATH . '/includes/admin/settings/structures/checkout-payment-gates/fields/payapp/payapp-fields.php');
                break;
            case 'kcp':
                array_push($settings['checkout-payment-gates']['fields'], array('id' => 'kcp_sitename', 'label' => __('사이트이름', 'wskl'), 'description' => __('자체적으로 정한 사이트 이름을 입력해주십시오. (반드시 영문자로 설정하여 주시기 바랍니다.)', 'wskl'), 'type' => 'longtext', 'default' => '', 'placeholder' => __('예) 다보리 쇼핑몰', 'wskl')), array('id' => 'kcp_sitecd', 'label' => __('Site Code', 'wskl'), 'description' => __('KCP 에서 발급된 Site Code 를 정확히 입력해주십시오.(중요)', 'wskl'), 'type' => 'longtext', 'default' => '', 'placeholder' => __('예) T0000', 'wskl')), array('id' => 'kcp_sitekey', 'label' => __('Site Key', 'wskl'), 'description' => __('KCP 에서 발급된 Site Key를 정확히 입력해주십시오.(중요)', 'wskl'), 'type' => 'longtext', 'default' => '', 'placeholder' => __('예) 3grptw1.zW0GSo4PQdaGvsF__', 'wskl')), array('id' => 'dummy_11', 'label' => __('상점등록', 'wskl'), 'description' => __('<span class="wskl-notice">상점등록 과정은 매우 중요한 사항이므로  정확히 숙지하고 실행해주셔야 합니다. </span></br>
						1. KCP와 계약 체결 후 다음의 내용을 발급 받습니다.</br>
                        &nbsp;&nbsp;&nbsp;&nbsp;A.Site Code와 Site Key를 입력하고 저장합니다.</br>
                         2. 당 플러그인의 KCP 홈 폴더중 “bin” 폴더에 있는 pp_cli 화일의 실행권한을 755로 바꾸어 줍니다. 그대로 둘 경우 결제 않됨.</br>
                        &nbsp;&nbsp;&nbsp;&nbsp;예)/public_html/wp-content/plugins/wskl/includes/lib/homekcp/bin/pp_cli</br>
                        &nbsp;&nbsp;&nbsp;&nbsp;(1) ssh로 로그인 후, 해당폴더에서 "chmod 755 pp_cli" 실행 또는</br>
                        &nbsp;&nbsp;&nbsp;&nbsp;(2) FTP 로 접속하여 해당 화일에 오른쪽 마우스를 클릭 - "화일 권한" 확인 후 755 로 저장</br>
 						<span class="wskl-info">테스트시에는기본 설치된 테스트용 KCP TEST  상점이 사용되므로 참고하세요</span></br>', 'wskl'), 'type' => 'caption', 'default' => ''));
                break;
            case 'inicis':
                array_push($settings['checkout-payment-gates']['fields'], array('id' => 'inicis_admin', 'label' => __('키패스워드', 'wskl'), 'description' => __('키패스워드입력 - 상점관리자 패스워드와 무관합니다.(중요)', 'wskl'), 'type' => 'text', 'default' => '', 'placeholder' => __('예) 1111', 'wskl')), array('id' => 'inicis_mid', 'label' => __('상점 아이디', 'wskl'), 'description' => __('이니시스에서 발급된 상점아이디를 대소문자 구분하여 입력해주십시오.(중요)', 'wskl'), 'type' => 'text', 'default' => '', 'placeholder' => __('예) INIpayTest', 'wskl')), array('id' => 'inicis_url', 'label' => __('상점 URL', 'wskl'), 'description' => __('상점의 홈페이지 주소를 입력해주십시오.( http://포함 )', 'wskl'), 'type' => 'longtext', 'default' => '', 'placeholder' => __('예) http://www.your_domain.co.kr', 'wskl')), array('id' => 'dummy_11', 'label' => __('상점등록', 'wskl'), 'description' => __('<span class="wskl-notice">상점등록 과정은 매우 중요한 사항이므로  정확히 숙지하고 실행해주셔야 합니다. </span></br>
						1. 이니시스와 계약 체결 후 다음의 내용을 발급 받습니다.</br>
                        &nbsp;&nbsp;&nbsp;&nbsp;A. 키패스워드(숫자 4자리)와  상점 아이디(10자리)를 해당설정에 입력하고 저장합니다.</br>
                        &nbsp;&nbsp;&nbsp;&nbsp;B.키화일 등  4개 (keypass.enc, mcert.pem, mpriv.pem, readme.txt)</br>
                        2. 당 플러그인의 이니페이 홈 폴더중 “key” 폴더에 상점아이디와 동일한 이름의 서브 디렉터리를 만듭니다(대소문자 구별함.).</br>
                        &nbsp;&nbsp;&nbsp;&nbsp;예)/public_html/wp-content/plugins/wskl/includes/lib/homeinicis/key/[상점아이디]</br>
                        3. 발급받은 화일  4개 (keypass.enc, mcert.pem, mpriv.pem, readme.txt)를 2.에서 만든 폴더에 복사합니다.</br>
 						<span class="wskl-info">테스트시에는기본 설치된 테스트용 INIpayTest 상점아이디폴더가 사용되므로 참고하세요</span></br>', 'wskl'), 'type' => 'caption', 'default' => ''));
                break;
            case 'lgu+':
                break;
            case 'ags':
                array_push($settings['checkout-payment-gates']['fields'], array('id' => 'ags_storenm', 'label' => __('상점명', 'wskl'), 'description' => __('올더게이트 상점명을 입력해주십시오', 'wskl'), 'type' => 'text', 'default' => '', 'placeholder' => __('예) 올더게이트', 'wskl')), array('id' => 'ags_storeid', 'label' => __('상점 ID', 'wskl'), 'description' => __('올더게이트에서 발급된 상점ID를 정확히 입력해주십시오.(중요)', 'wskl'), 'type' => 'text', 'default' => '', 'placeholder' => __('예) aegis', 'wskl')), array('id' => 'ags_mallurl', 'label' => __('상점 URL', 'wskl'), 'description' => __('상점의 홈페이지 주소를 입력해주십시오.( http://포함 )', 'wskl'), 'type' => 'longtext', 'default' => '', 'placeholder' => __('예) http://www.allthegate.com', 'wskl')), array('id' => 'ags_hp_id', 'label' => __('CPID(모바일결제)', 'wskl'), 'description' => __('올더게이트에서 발급받으신 CPID로 변경', 'wskl'), 'type' => 'text', 'default' => '', 'placeholder' => ''), array('id' => 'ags_hp_pwd', 'label' => __('CP 비밀번호(모바일결제)', 'wskl'), 'description' => __('올더게이트에서 발급받으신 비밀번호로 변경', 'wskl'), 'type' => 'text', 'default' => '', 'placeholder' => ''), array('id' => 'ags_hp_subid', 'label' => __('SUB_ID(모바일결제)', 'wskl'), 'description' => __('올더게이트에서 발급받으신 상점만 입력', 'wskl'), 'type' => 'text', 'default' => '', 'placeholder' => ''), array('id' => 'ags_prodcode', 'label' => __('상품코드(모바일결제)', 'wskl'), 'description' => __('올더게이트에서 발급받으신 상품코드로 변경', 'wskl'), 'type' => 'text', 'default' => '', 'placeholder' => ''), array('id' => 'ags_unittype', 'label' => __('상품종류(모바일결제)', 'wskl'), 'description' => __('올더게이트에서 발급받으신 상품종류로 변경: 디지털컨텐츠=1, 실물(상품)=2', 'wskl'), 'type' => 'text', 'default' => '', 'placeholder' => ''));
                break;
            case 'iamport':
                array_push($settings['checkout-payment-gates']['fields'], array('id' => 'iamport_user_code', 'label' => __('가맹점 식별코드', 'wskl'), 'description' => __('아임포트의 가맹점 식별코드를 입력하여 주십시오.', 'wskl'), 'type' => 'text', 'default' => '', 'placeholder' => ''), array('id' => 'iamport_rest_key', 'label' => __('REST API 키', 'wskl'), 'description' => __('아임포트의 REST API 키를 입력하여 주십시오.', 'wskl'), 'type' => 'text', 'default' => '', 'placeholder' => ''), array('id' => 'iamport_rest_secret', 'label' => __('REST API secret', 'wskl'), 'description' => __('아임포트의 REST API secret 입력하여 주십시오.', 'wskl'), 'type' => 'longtext', 'default' => '', 'placeholder' => ''), array('id' => 'dummy_31', 'label' => __('가맹점 등록', 'wskl'), 'description' => __('
						<span class="wskl-notice">아임포트의 가맹점 등록 과정은 좀 특이하므로 세심한 주의를 요합니다.<br>고객의 결제 진행시 결제 정보를 아임포트 서버로 보내주면 아임포트 서버가 결제 처리를 대행하는<br> 구조이므로 각 결제 업체의 PG 연동 정보가 아임포트 회원 정보에 설정되어야 합니다.</span></br><span class="wskl-info">
						1. 아임포트 회원가입/로그인 후 시스템설정->내정보 에서 확인된 정보를 입력합니다.</br>
                        &nbsp;&nbsp;아임포트 회원로그인 후 확인한 REST API 정보를 입력하고 저장합니다.</br><a href="https://admin.iamport.kr/settings" target="_blank">https://admin.iamport.kr/settings  REST API 정보를 확인하러 가기</a></br>
 						2. <a href="https://admin.iamport.kr/settings" target="_blank">https://admin.iamport.kr/settings</a> 의 "PG연동 설정"에서 <br>각 결제 대행업체에서 발급 받은 PG연동 정보를 설정합니다. </br> </font></br>
  					', 'wskl'), 'type' => 'caption', 'default' => ''));
                break;
        }
        // 페이앱, 아임포트는 추가설정내용 없음.
        if (!in_array($pg_agency, array('payapp', 'iamport'))) {
            array_push($settings['checkout-payment-gates']['fields'], array('id' => 'dummy_1', 'label' => __('추가설정내용', 'wskl'), 'description' => __('<span class="wskl-notice">해당페이지 설정후 반드시 추가해야할 "우커머스 결제설정" 내용입니다.</span><a href="' . esc_url(add_query_arg(array('page' => 'wc-settings', 'tab' => 'checkout'), admin_url('admin.php'))) . '" target="_blank">결제설정 바로가기</a><br/>
						1. "해당 페이지를 설정하면 우커머스->설정->결제 설정"의 하위메뉴에 지정한 결제 방법이 추가됩니다. <br/>
						   &nbsp;&nbsp;&nbsp;각각의 하위메뉴로 들어가서 활성화에 체크하여 주십시오.  <br/>
						2. "우커머스->설정->결제옵션->지불게이트웨이"에서 고객의 결제페이지에 보일 "결제 방법의 순서"를 결정하여 주십시오.<br/>
						3. "우커머스->설정->결제설정"의 각 결제 방식을 선택하면 고객의 결제페이지에 보일 결제방식에 대한 안내문 변경이 가능합니다.<br/>', 'wskl'), 'type' => 'caption', 'default' => ''));
        }
        $settings['essential-features'] = (include WSKL_PATH . '/includes/admin/settings/structures/essential-features.php');
        $settings['convenience-features'] = (include WSKL_PATH . '/includes/admin/settings/structures/convenience-features.php');
        $settings['social-login'] = array('title' => __('소셜기능(S)', 'wskl'), 'description' => __('계정관리와  로그인 관련 설정입니다.(소셜 아이콘은 includes/lib/custom 폴더를 참조)', 'wskl'), 'fields' => array(array('id' => 'enable_social_login', 'label' => __('다보리 소셜 로그인 활성화 ', 'wskl'), 'description' => __('다보리에서 제공한 로그인을 사용하게 됩니다.', 'wskl'), 'type' => 'checkbox', 'default' => ''), array('id' => 'fb_login', 'label' => __('페이스북  계정으로 로그인 활성화 ', 'wskl'), 'description' => __('활성화이후  발급키 입력창이 나타납니다.', 'wskl'), 'type' => 'checkbox', 'default' => '')));
        if (get_option(WSKL_PREFIX . 'fb_login') == 'on') {
            array_push($settings['social-login']['fields'], array('id' => 'fb_app_id', 'label' => __('&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[페이스북] App ID', 'wskl'), 'description' => __('페이스북의 App ID 를 입력하십시오', 'wskl'), 'type' => 'longtext', 'default' => '', 'placeholder' => ''), array('id' => 'fb_app_secret', 'label' => __('&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[페이스북] App Secret', 'wskl'), 'description' => __('페이스북의 App Secret을 입력하십시오', 'wskl'), 'type' => 'longtext', 'default' => '', 'placeholder' => ''), array('id' => 'fb_login_link_text', 'label' => __('&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[페이스북]링크 텍스트', 'wskl'), 'description' => __('로그인 링크에 보여질 텍스트 또는 이미지 태그를 입력하십시오. 기본 아이콘을 사용하려면 \'[icon]\'으로 입력하세요.', 'wskl'), 'type' => 'textarea', 'default' => '[icon]', 'placeholder' => ''), array('id' => 'dummy_13', 'label' => __('&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[페이스북] 키발급', 'wskl'), 'description' => __('
						<span class="wskl-notice">반드시 https://developers.facebook.com 에서 키발급을 먼저 받으십시오.</span>   <a href="https://developers.facebook.com" target="_blank" >키발급 바로가기</a><br/>
						1. My App 메뉴에서 Add a New App 을 클릭한 후 Website 를 선택하십시오. <br/>
						2. 해당웹사이트의 이름을 입력하시고 Create New Facebook ID 하십시오. <br/>
						3. 반드시 Site URL에 http://를 포함한 고객의 웹사이트 주소를 입력하십시오. <br/>
						4. App ID 생성이 완료되면 반드시 해당 App의 Settings 로 가셔서 App Domains와 Website에서 <br/>고객의
						    웹사이트 주소가 일치하는 지 확인하세요. <span class="wskl-notice">웹사이트 주소가 바뀔때 반드시 여기와 일치시켜야 합니다.</span><br/>
						5. App ID와 App Secret 을 확인하신 후 다보리 플러그인의 해당 키값을 입력하고 저장하여 주십시오.<br/>
					', 'wskl'), 'type' => 'caption', 'default' => ''));
        }
        array_push($settings['social-login']['fields'], array('id' => 'naver_login', 'label' => __('네이버 계정으로 로그인 활성화 ', 'wskl'), 'description' => __('활성화이후  발급키 입력창이 나타납니다. ', 'wskl'), 'type' => 'checkbox', 'default' => ''));
        if (get_option($this->_prefix . 'naver_login') == 'on') {
            array_push($settings['social-login']['fields'], array('id' => 'naver_client_id', 'label' => __('&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[네이버] Client ID', 'wskl'), 'description' => __('네이버의 Client ID를 입력하십시오', 'wskl'), 'type' => 'longtext', 'default' => '', 'placeholder' => ''), array('id' => 'naver_client_secret', 'label' => __('&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[네이버] Client Secret', 'wskl'), 'description' => __('네이버의 Client Secret 을 입력하십시오', 'wskl'), 'type' => 'longtext', 'default' => '', 'placeholder' => ''), array('id' => 'naver_login_link_text', 'label' => __('&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[네이버] 링크 텍스트', 'wskl'), 'description' => __('로그인 링크에 보여질 텍스트 또는 이미지 태그를 입력하십시오. 기본 아이콘을 사용하려면 \'[icon]\'으로 입력하세요.', 'wskl'), 'type' => 'textarea', 'default' => '[icon]', 'placeholder' => ''), array('id' => 'dummy_14', 'label' => __('&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[네이버] 키발급', 'wskl'), 'description' => __('
						<span class="wskl-notice">반드시  http://developer.naver.com/wiki/pages/NaverLogin 에서 키발급을 먼저 받으십시오.</span>   <a href=" http://developer.naver.com/wiki/pages/NaverLogin" target="_blank" >키발급 바로가기</a><br/>
						1. [키발급 관리]를 선택한 후 네이버 로그인을 선택하십시오.. <br/>
						2. 새 애플리케이션을 등록하고 서비스 환경은 [www-Web]으로 선택하십시오.. <br/>
						3. PC웹과 모바일 웹에서 고객의  웹사이트 주소를 입력하시고 콜백도 동일하게 입력하십시오. <br/>
                        4. Client ID 생성이 완료되면 어플리케이션 메뉴의 [일반]메뉴로 고객의  PC웹과 모바일 웹사이트 주소가 일치하는 지 확인하세요. <br/>
						<span class="wskl-notice">웹사이트 주소가 바뀔때 반드시 여기와 일치시켜야 합니다.</span><br/>
						5. Client ID와 Client Secret 을 확인하신 후 다보리 플러그인의 해당 키값을 입력하고 저장하여 주십시오.<br/>
					', 'wskl'), 'type' => 'caption', 'default' => ''));
        }
        $settings['protection-features'] = array('title' => __('차단보안기능(R)', 'wskl'), 'description' => __('특별한 관리없이 악성댓글이나 악성트래픽이 대폭 감소합니다. 한국인 대상 사이트의 경우 한국,미국만 오픈해도 됩니다.', 'wskl'), 'fields' => array(array('id' => 'enable_countryip_block', 'label' => __('국가별 IP 차단', 'wskl'), 'description' => __('국가별 IP를 차단하여 해킹을 미연에 방지합니다.</br>
						활성화시 반드시 아래의 "화이트리스트 국가코드"를 넣어 주십시오', 'wskl'), 'type' => 'checkbox', 'default' => ''), array('id' => 'white_ipcode_list', 'label' => __('화이트 IP 코드 리스트', 'wskl'), 'description' => __('차단하지 않을 국가의 IP 코드를 추가합니다. 컴마로 분리. 자세한 국가코드는 <a href="https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2" target="_blank">ISO 3166-1 alpha-2</a>를 참고하세요. </br><span class="wskl-description">예) KR,US,JP,CN => KR-한국 US-미국, JP-일본, CN-중국</span>', 'wskl'), 'type' => 'longtext', 'default' => 'KR,US,JP,CN', 'placeholder' => 'KR,US,JP,CN'), array('id' => 'dummy_1', 'label' => __('작동 상황', 'wskl'), 'description' => site_url() == wskl_get_option('ip_block_target') ? '<span class="wskl-info">' . __('차단 기능이 동작합니다.', 'wskl') . '</span>' : '<span class="wskl-notice">' . __('도메인이 변경되어 기능이 중지되었습니다. 설정 저장 버튼을 눌러 다시 활성화시켜 주세요', 'wskl') . '</span>')));
        $settings['marketing'] = (include WSKL_PATH . '/includes/admin/settings/structures/marketing-automation.php');
        if (wskl_lab_enabled()) {
            $settings['beta-features'] = (include WSKL_PATH . '/includes/admin/settings/structures/beta-features.php');
        }
        if (wskl_debug_enabled()) {
            $settings['developer'] = (include WSKL_PATH . '/includes/admin/settings/structures/developer.php');
        }
        $settings = apply_filters('wskl_settings_fields', $settings);
        return $settings;
    }
 /**
  * 페이앱이 피드백 URL 에 대응하는 콜백.
  * 피드백 파라미터를 확인하고 올바른 경우에는 최종적으로 주문 내역을 결제된 것으로 업데이트한다.
  *
  * @action woocommerce_api_{wskl-payapp-feedback}
  */
 public static function callback_payapp_feedback()
 {
     error_log('페이앱 피드백 URL 호출됨! 일시 (UTC time): ' . date('Y-m-d H:i:s'));
     $payapp_uid = wskl_POST('userid');
     $link_key = wskl_POST('linkkey');
     $link_val = wskl_POST('linkval');
     $order_id = wskl_POST('var1', 'absint');
     $order_key = wskl_POST('var2', 'sanitize_text_field');
     $cst_url = wskl_POST('csturl', 'sanitize_text_field');
     // 전표 주소
     $pay_memo = wskl_POST('pay_memo', 'sanitize_text_field');
     // 구매자가 기록한 메모
     $mul_no = wskl_POST('mul_no', 'sanitize_text_field');
     // 결제요청번호
     $pay_state = wskl_POST('pay_state', 'absint');
     // 결제요청상태 (1: 요청, 4: 결제완료, 8, 16, 32: 요청취소, 9, 64: 승인취소)
     $pay_type = wskl_POST('pay_type', 'absint');
     // 결제수단 (1: 신용카드, 2: 휴대전화)
     $pay_date = wskl_POST('pay_date', 'sanitize_text_field');
     // check payapp_uid
     if ($payapp_uid != wskl_get_option('payapp_user_id')) {
         error_log(__('페이앱 USER ID 에러', 'wskl'));
         return;
     }
     // check link key and link val
     if ($link_key != wskl_get_option('payapp_link_key') || $link_val != wskl_get_option('payapp_link_val')) {
         error_log(__('페이앱 연동 KEY, 혹은 연동 VALUE가 올바르지 않음', 'wskl'));
         return;
     }
     $order = wc_get_order($order_id);
     if (!$order) {
         error_log(__('잘못된 주문 ID', 'wskl') . ": {$order_id}");
         return;
     }
     // check order key
     if ($order_key != $order->order_key) {
         error_log(__('잘못된 주문 KEY', 'wskl') . ": {$order_key}");
         return;
     }
     // 승인
     if ($pay_state == 4) {
         // 전표 기록
         update_post_meta($order_id, 'wskl_payapp_cst_url', $cst_url);
         switch ($pay_type) {
             case 1:
                 $card_name = wskl_POST('card_name', 'sanitize_text_field');
                 // 신용카드시 카드 이름
                 $order_note = sprintf(__('결제가 성공적으로 처리됨.<ul><li>결제방법: 신용카드</li><li>카드 이름: %s</li><li>페이앱 결제요청번호: %s</li><li>승인시각: %s</li><li>구매자의 결제창 메시지: %s</li></ul>', 'wskl'), $card_name, $mul_no, $pay_date, $pay_memo);
                 break;
             case 2:
                 $order_note = sprintf(__('결제가 성공적으로 처리됨.<ul><li>결제방법: 휴대전화</li><li>페이앱 결제요청번호: %s</li><li>승인시각: %s</li><li>구매자의 결제창 메시지: %s</li></ul>', 'wskl'), $mul_no, $pay_date, $pay_memo);
                 break;
             default:
                 $order_note = sprintf(__('결제가 성공적으로 처리됨.<ul><li>결제방법: 기타</li><li>페이앱 결제요청번호: %s</li><li>승인시각: %s</li><li>구매자의 결제창 메시지: %s</li></ul>', 'wskl'), $mul_no, $pay_date, $pay_memo);
         }
         $order->add_order_note($order_note);
         $order->payment_complete();
         $order->reduce_order_stock();
         wc_empty_cart();
     }
 }
 /**
  * @callback
  * @action    wskl_wp_members_section_footer_footer_area
  */
 public function section_footer_area()
 {
     echo '<br/>';
     echo '<h4>' . __('최근 휴면 계정 작업 기록', 'wskl') . '</h4>';
     $recent_jobs = wskl_get_option('inactive-accounts_recent_jobs');
     if (!$recent_jobs) {
         echo __('작업 기록이 없습니다.');
     } else {
         krsort($recent_jobs);
         include 'recent-jobs-code.php';
     }
     echo '<br/>';
     echo '<h4>' . __('휴면 계정을 처음 사용하는 분께 알림', 'wskl') . '</h4>';
     echo '<p>' . __('워드프레스와 우커머스는 \'마지막 로그인\' 시각을 기록하지 않습니다. 그러므로 본 모듈을 처음 작동시킨 시점에는 마지막 로그인 시각 데이터가 존재하지 않습니다.<br/>로그인 시각 데이터는 모듈 작동 중 각기 회원이 로그인한 시점에 매번 갱신됩니다.', 'wskl') . '</p>';
     echo '<p>' . __('또한 본 모듈은 정상적인 휴면 관리를 위해 검사 주기마다 회원의 누락된 마지막 로그인 시간을 채워 넣습니다.<br/>이 때 마지막 로그인 시각은 검사 당시 시간으로 간주됩니다.', 'wskl') . '</p>';
     echo '<p>' . __('모든 설정값이 제대로 채워져 있어야 정상 동작합니다. 그리고 설정 저장 버튼을 누르면 검사 시간이 재편성됩니다.<br/>최초 검사 시간은 다음날 자정인 00시 00분부터 실행되며 매 검사 주기마다 반복됩니다. 단, 워드프레스의 크론은 사용자 방문에 의해 동작하므로 약간씩 오차가 발생할 수도 있습니다.', 'wskl') . '</p>';
     echo '<h4>' . __('계정 복구에 대해', 'wskl') . '</h4>';
     echo '<p>' . __('휴면 처리된 계정 복구는 WP-Members 플러그인의 패스워드 복구 기능을 이용해 진행할 수 있습니다.', 'wskl') . '</p>';
 }
 /**
  * 로그인 필드 값이 없는 경우는 크론 작업 시간으로 채워 줌.
  *
  * @used-by WSKL_Inactive_Accounts::do_interval_jobs()
  */
 public function fill_user_login_field()
 {
     $target_role = wskl_get_option('inactive-accounts_target_role');
     if (!$target_role) {
         $message = __METHOD__ . ": Values are net properly set.\n";
         $message .= "  target_role={$target_role}";
         error_log($message);
         return;
     }
     // Get users whose last_login meta keys are missing, or their meta values are 0 or blank.
     $key = wskl_get_option_name('last_login');
     $args = array('role' => $target_role, 'meta_query' => array('relation' => 'OR', array('key' => $key, 'value' => 0, 'type' => 'NUMERIC', 'compare' => 'NOT EXISTS'), array('key' => $key, 'value' => 0, 'type' => 'NUMERIC', 'compare' => '='), array('key' => $key, 'value' => '', 'type' => 'CHAR', 'compare' => '=')));
     $query = new WP_User_Query($args);
     $results = $query->get_results();
     /** @var WP_User $user */
     foreach ($results as $user) {
         update_user_meta($user->ID, $key, $this->cron_job_id);
     }
 }
 public static function check_payment_response()
 {
     if (!empty($_REQUEST['imp_uid'])) {
         //결제승인 결과조회
         require_once WSKL_PATH . '/includes/lib/iamport/iamport.php';
         $imp_uid = $_REQUEST['imp_uid'];
         $rest_key = wskl_get_option('iamport_rest_key');
         $rest_secret = wskl_get_option('iamport_rest_secret');
         $iamport = new Iamport($rest_key, $rest_secret);
         $result = $iamport->findByImpUID($imp_uid);
         if ($result->success) {
             $payment_data = $result->data;
             if (empty($_REQUEST['order_id'])) {
                 //call by iamport notification
                 $order_id = wc_get_order_id_by_order_key($payment_data->merchant_uid);
             } else {
                 $order_id = $_REQUEST['order_id'];
             }
             $order = wc_get_order($order_id);
             update_post_meta($order_id, '_iamport_provider', $payment_data->pg_provider);
             update_post_meta($order_id, '_iamport_paymethod', $payment_data->pay_method);
             update_post_meta($order_id, '_iamport_receipt_url', $payment_data->receipt_url);
             if ($payment_data->status == 'paid') {
                 if ($order->order_total == $payment_data->amount) {
                     if (!$order->has_status(array('processing', 'completed'))) {
                         $order->payment_complete($payment_data->imp_uid);
                         //imp_uid
                         wp_redirect($order->get_checkout_order_received_url());
                         return;
                     }
                 } else {
                     $order->add_order_note('요청하신 결제금액이 다릅니다.');
                     wc_add_notice('요청하신 결제금액이 다릅니다.', 'error');
                 }
             } else {
                 if ($payment_data->status == 'ready') {
                     if ($payment_data->pay_method == 'vbank') {
                         $vbank_name = $payment_data->vbank_name;
                         $vbank_num = $payment_data->vbank_num;
                         $vbank_date = $payment_data->vbank_date;
                         //가상계좌 입금할 계좌정보 기록
                         update_post_meta($order_id, '_iamport_vbank_name', $vbank_name);
                         update_post_meta($order_id, '_iamport_vbank_num', $vbank_num);
                         update_post_meta($order_id, '_iamport_vbank_date', $vbank_date);
                         //가상계좌 입금대기 중
                         $order->update_status('awaiting-vbank', __('가상계좌 입금대기 중', 'iamport'));
                         wp_redirect($order->get_checkout_order_received_url());
                         return;
                     } else {
                         $order->add_order_note('실제 결제가 이루어지지 않았습니다.');
                         wc_add_notice('실제 결제가 이루어지지 않았습니다.', 'error');
                     }
                 } else {
                     if ($payment_data->status == 'failed') {
                         $order->add_order_note('결제요청 승인에 실패하였습니다.');
                         wc_add_notice('결제요청 승인에 실패하였습니다.', 'error');
                     }
                 }
             }
         } else {
             $payment_data =& $result->data;
             if (!empty($_REQUEST['order_id'])) {
                 $order = new WC_Order($_REQUEST['order_id']);
                 $order->update_status('failed');
                 $order->add_order_note('결제승인정보를 받아오지 못했습니다. 관리자에게 문의해주세요' . $payment_data->error['message']);
                 wc_add_notice($payment_data->error['message'], 'error');
                 $redirect_url = $order->get_checkout_payment_url(TRUE);
                 wp_redirect($redirect_url);
             }
         }
     }
 }
function wskl_email_from_name($from_name)
{
    $name = wskl_get_option('inactive-accounts_sender_name');
    if ($name) {
        return $name;
    }
    return get_bloginfo('name');
}
 /**
  * 시나리오에 따라 문자열을 보낸다.
  * 어떤 우커머스 이벤트가 있든지, 해당 이벤트에 대한 핸들링은 적절한 메시지를 보내는 것으로 귀결된다.
  * 주의. $order_id 와 $user_id 가 동시에 NULL 이 될 수 없다.
  *
  * @param int|NULL $order_id 주문에 대한 문자열이면 주문 ID. 주문과 관련되 문자가 아니면 NULL.
  * @param int|NULL $user_id  사용자와 관련된 문자열이면 사용자 ID. 사용자와 관련 없으면 NULL.
  * @param string   $scenario 시나리오. 각 섹션의 ID. e.g., new-order, customer-new-account, ...
  *
  * @uses  WSKL_SMS_Text_Substitution
  * @uses  WSKL_Dabory_SMS_Provider_Loading
  *
  * @uses  WSKL_Dabory_SMS_Trigger::get_setting_value()
  * @uses  WSKL_Dabory_SMS_Trigger::get_settings()
  * @uses  WSKL_Dabory_SMS_Trigger::is_already_sent()
  * @uses  WSKL_Dabory_SMS_Trigger::log()
  * @uses  WSKL_Dabory_SMS_Trigger::set_sending_result()
  *
  * @return bool
  */
 private function trigger_common($order_id, $user_id, $scenario)
 {
     if ($order_id) {
         $order = wc_get_order($order_id);
         if (!$order) {
             $this->log('$order is invalid. Triggering halted.', __METHOD__);
             return FALSE;
         }
     } else {
         $order = NULL;
     }
     if ($user_id) {
         $user = get_user_by('id', $user_id);
         if (!$user) {
             $this->log("User ID {$user_id} is invalid.", __METHOD__);
             return FALSE;
         }
     } else {
         $user = NULL;
     }
     if (!$order && !$user_id) {
         $this->log('Either $order_id, or $user_id must be valid.', __METHOD__);
         return FALSE;
     }
     $emulation = wskl_is_option_enabled('develop_emulate_sms');
     // check if a message is already sent (order only)
     if (!$emulation && $order && $this->is_already_sent($order, $scenario)) {
         $this->log("Order #{$order_id} has been notified. Triggering halted.", __METHOD__);
         return FALSE;
     } else {
         if (!$emulation && $user && $this->is_already_sent($user, $scenario)) {
             $this->log("User #{$user_id} ({$user->user_email}) has been notified. Triggering halted.", __METHOD__);
             return FALSE;
         }
     }
     // receiver meta key
     $gs = self::get_settings();
     // retrieve the other fields
     $ns = self::get_settings($scenario);
     $message_template = self::get_setting_value($ns, $scenario, 'message_content');
     $title_template = self::get_setting_value($ns, $scenario, 'message_title');
     $notify_to_managers = self::get_setting_value($ns, $scenario, 'send_to_managers');
     if ($order) {
         $receiver_phone_meta_key = wskl_get_from_assoc($gs, wskl_get_option_name('sms_receiver_meta_field'));
         if (empty($receiver_phone_meta_key)) {
             $this->log('$receiver_phone_meta_key is an empty string. Triggering halted.', __METHOD__);
             return FALSE;
         }
         $customer_phone = $order->{$receiver_phone_meta_key};
     } else {
         $receiver_phone_meta_key = self::get_setting_value($ns, $scenario, 'phone_meta_field');
         if (empty($receiver_phone_meta_key)) {
             $this->log('$receiver_phone_meta_key is an empty string. Triggering halted.', __METHOD__);
             return FALSE;
         }
         $customer_phone = $user->{$receiver_phone_meta_key};
     }
     if (empty($customer_phone)) {
         $this->log('customer phone is empty! Triggering halted.', __METHOD__);
         return FALSE;
     }
     // receivers
     if ($notify_to_managers == 'yes') {
         $r = explode("\n", wskl_get_option('sms_shop_manager_phones'));
         $r[] = $customer_phone;
         $r = array_map(array(__CLASS__, 'trim_phone_number'), $r);
         $r = array_filter($r, array(__CLASS__, 'not_empty'));
         $r = array_unique($r);
         $receivers = implode(',', $r);
         $num_receivers = count($receivers);
     } else {
         $receivers = $customer_phone;
         $num_receivers = 1;
     }
     if (!$num_receivers) {
         $this->log('The number of recipient is 0! Triggering halted.', __METHOD__);
         return FALSE;
     }
     // message substitution
     $sub = new WSKL_SMS_Text_Substitution();
     $sub->init_substitute($order, $user);
     $message_title = $sub->substitute($title_template);
     $message_content = $sub->substitute($message_template);
     $str_bytes = strlen($message_content);
     // message type
     if ($str_bytes > self::SMS_MAX_BYTES) {
         $message_type = 'lms';
     } else {
         $message_type = 'sms';
     }
     $args = array('remote_phone' => $receivers, 'remote_msg' => $message_content, 'remote_subject' => $message_title, 'remote_num' => $num_receivers, 'remote_etc1' => $order_id);
     if (!$emulation) {
         // ... and fire.
         /** @var WSKL_Dabory_SMS_Provider $provider_class */
         $provider_class = Provider_Loading::get_provider_class();
         $sender = $provider_class::factory();
         $response = $sender->send_message($args, $message_type);
         assert($response[3] == $order_id, __FUNCTION__ . ': Order id of etc1 and $order_id are different. This is impossible.');
     } else {
         $message = 'SMS emulation is enabled. Argument: ' . print_r($args, TRUE);
         error_log($message);
     }
     if (!$emulation && $order) {
         self::set_sending_result($order, $scenario, $message_type);
     } else {
         if (!$emulation && $user) {
             self::set_sending_result($user, $scenario, $message_type);
         }
     }
     return TRUE;
 }
 function order_received_addition($order_id)
 {
     $text = wskl_get_option('woocommerce_thankyou_text');
     if (!empty($text)) {
         echo wp_kses_post($text);
     }
 }
 /**
  * @callback
  * @filter    woocommerce_output_related_products_args
  *
  * @param $args
  *
  * @return mixed
  */
 public static function callback_related_products_args($args)
 {
     $args['posts_per_page'] = absint(wskl_get_option('related_products_count'));
     $args['columns'] = absint(wskl_get_option('related_products_columns'));
     return $args;
 }