wordpress 正規API寫法教學

官方教學請參考:點我

非外掛情況:加入在function.php
外掛情況:加入在class的__construct()內

add_action('rest_api_init', function(){
   register_rest_route( 'apitest/v1', '/apitest01/', array(
                        'methods' => 'POST',
		        'callback' => array($this,'testapi'),
		         )
   );
});
//api網址=網站根目錄網址+wp-json/apitest/v1/apitest01

測試的function(實際上api做的事情)
要記得這邊有個小坑要注意,若上面的methods設定為post但實際上用get方式,反之亦然,api雖然依舊會執行function但會多回傳一個WP_ERROR的json將其視為路徑不存在

function testapi($data){
                //$data相當於PHP變數$POST
		echo json_encode(array('success'=>'測試成功'));
                //但純回傳測試成功
		exit();
	}

接下來讓我們建立一支html檔做簡單的測試,內容如下:

<form action="網站根目錄網址+wp-json/apitest/v1/apitest01" method="POST">
	<input type="submit" value="送交"/>
</form>

點擊按鈕送出後得到以下結果即代表成功!
{“success”:”\u6e2c\u8a66\u6210\u529f”}

PHPMailer發信(高安全性模式 Oauth2)

之前一直說要填的坑,研究了好幾天才終於搞懂,不得不說有關的教學真的太少了(中英文都是),導致要湊出完整的流程真的挺困難的,先把觀念記錄下來,有機會再做成外掛方便大家使用 。
本篇文章參考:https://blog.hoyo.idv.tw/?p=3692撰寫
這已經是我找到相對來講最完整的教學了,也感謝這篇文章的作者讓我可以完成這部分的改寫。

  1. 確定 PHP 已經更新到 5.4 以上 (PHPMailer get_oauth_token.php 的需求)
  2. 下載 PHPMailer 5.2.23 (最新版)
  3. 將 PHPMailer 解壓縮在你的網站/外掛內
  4. 安裝 composer
  5. 到 PHPMailer 目錄執行 composer install
    順便先補兩個 composer require , league/oauth2-client 和 league/oauth2-google
    (這邊要注意調整資料夾權限否則無法安裝)
  6. 到 Google APIs 建立一個發信件用的專案
  7. 到「憑證」內產生「OAuth 2.0 用戶端 ID」 ,並且設定好「已授權的重新導向 URI」,請設定為你的get_oauth_token.php檔案的url
  8. 到 get_oauth_token.php 內設定好 $redirectUri(這支程式的網路位置 url) $clientId $clientSecret(google api內會給) 三個變數,並執行,會詢問帳號授權,選擇欲發信帳號後會出現 Token ,請複製起來
  9. 複製 examples/gmail_xoauth.phps 到 你要用來發信的程式 做測試
    (記得檔案要改成php)
  10. 修改  你要用來發信的程式
    oauthUserEmail (你要用來發信的gmail)
    oauthClientId  (google發信專案的 oauthClientId )
    oauthClientSecret  (google發信專案的 oauthClientSecret )
    oauthRefreshToken (詢問授權後獲得的 Token )
    ,以及寄信人、收信人後即可執行發信測試

發送mail的核心程式,如果上面測試有出現錯誤請檢查一下檔案內發信的程式碼

$mail= new PHPMailer();                             //建立新物件
	$mail->setOAuth(
		new OAuth(
			[
				'provider' => $provider,
				'clientId' => $clientId,
				'clientSecret' => $clientSecret,
				'refreshToken' => $refreshToken,
				'userName' => $email,
			]
		)
	);
	$mail->SMTPDebug = 3; //如果需要顯示debug內容,測完確定沒問題請改成0
	$mail->SMTPAuth = true; //設定SMTP需要驗證
	$mail->SMTPSecure = 'tls';
	$mail->AuthType = 'XOAUTH2';
	$mail->Host = "smtp.gmail.com";  //Gamil的SMTP主機
	$mail->Port = 587;
	$mail->CharSet = "utf-8"; //郵件編碼
	$mail->From = "example@gmail.com"; //寄件者信箱
	$mail->FromName = "寄件測試"; //寄件者姓名
	$mail->Subject = $title; //郵件標題
	$mail->Body = $content; //郵件內容
	$mail->IsHTML(true);//郵件內容為html
	$mail->AddAddress($email);//收件者郵件及名稱
	$mail->Send();

如果有說明不夠清楚的地方歡迎留言反映我再做調整,感謝各位 。

wordpress外掛開發 綠界物流外掛開發踩雷分享

大概一年多前串了綠界金流的外掛,當時其實也有想試試看串物流,但因為看起來有點複雜加上各種偷懶到現在才補坑,經過一年的成長其實發現沒有當初想像的那麼難但也沒有多簡單而且還有很多坑

先附上外掛載點:

https://drive.google.com/drive/folders/1PcfhV4skRgFMiT9YhK_f-PyV7sH2gztW?usp=sharing

跟綠界的物流界接說明文件:

https://www.ecpay.com.tw/Content/files/ecpay_030.pdf

這次的範例外掛主要流程如下:

  1. 點下按鈕後 -> 開啟綠界超商api
  2. 接收到綠界超商api使用者選完回傳的商店資訊後 -> 建立物流訂單

外掛使用方式:

  1. 下載後安裝
  2. 建立一個頁面 輸入短代碼 [c2c-test type=”c2c_btn_test”]
  3. 點選按鈕”建立物流訂單”

開啟超商地圖api程式碼說明:

其實跟一般的api沒什麼兩樣,只是可能因為綠界那邊太少更新了,在串的時候就發現幾個點

  • ServerReplyURL IsCollection ->這個欄位在綠界的說明文件是要填 Y or N 實際上要填 YES or NO
  • LogisticsSubType ->這個欄位看文件說明會以為要切成C2C應該要改成UNIMARTC2C,實際上這樣寫會導致程式錯誤,應該要填寫 UNIMART_C2C即可正常運作
  • ServerReplyURL->綠界api回傳超商資料的網址
function createC2COrder(){
		// 一般物流訂單建立
		require_once(ECPAY_C2C_TEST_DIR.'/SDK/Ecpay.Logistic.Integration.php');
		try {
			$AL = new EcpayLogistics();
			$AL->Send = array(
				'MerchantID' => '2000132',
				'MerchantTradeNo' => 'no' . date('YmdHis'),
				'LogisticsSubType' => EcpayLogisticsSubType::UNIMART,
				'IsCollection' => EcpayIsCollection::NO,
				'ServerReplyURL' => get_home_url(). '/ServerReplyURL.php',
				'ExtraData' => '測試額外資訊',
				'Device' => EcpayDevice::PC
			);
			// CvsMap(Button名稱, Form target)
			$html = $AL->CvsMap('電子地圖(統一)');
			echo $html;
			exit();
		} catch(Exception $e) {
			echo $e->getMessage();
			exit();
		}
	}

建立物流訂單api程式碼說明:

  • LogisticsC2CReplyURL -> 建立訂單失敗會回傳的網址
  • ClientReplyURL -> 訂單物流狀態更改時會回傳的網址
if(strpos($_SERVER['REQUEST_URI'], '/ServerReplyURL')===0||strpos($_SERVER['REQUEST_URI'], '/ServerReplyURL')>0){
			require_once(ECPAY_C2C_TEST_DIR.'/SDK/Ecpay.Logistic.Integration.php');
			echo $_POST["MerchantID"]."\r\n";
			echo $_POST["MerchantTradeNo"]."\r\n";
			echo $_POST["LogisticsSubType"]."\r\n";
			echo $_POST["CVSStoreID"]."\r\n";
			echo $_POST["CVSStoreName"]."\r\n";
			echo $_POST["CVSAddress"]."\r\n";
			echo $_POST["CVSTelephone"]."\r\n";
			echo $_POST["CVSOutSide"]."\r\n";
			echo $_POST["ExtraData"]."\r\n";
                        //這些是超商地圖api選擇完後會回傳的參數
			try {
				$AL = new EcpayLogistics();
				$AL->HashKey = '5294y06JbISpM5x9';
				$AL->HashIV = 'v77hoKGq4kWxNNIS';
				$AL->Send = array(
					'MerchantID' => '2000132',
					'MerchantTradeNo' => 'no' . date('YmdHis'),
					'MerchantTradeDate' => date('Y/m/d H:i:s'),
					'LogisticsType' => EcpayLogisticsType::CVS,
					'LogisticsSubType' => EcpayLogisticsSubType::UNIMART,
					'GoodsAmount' => 1500,
					'CollectionAmount' => 10,
					'IsCollection' => EcpayIsCollection::NO,
					'GoodsName' => '測試商品',
					'SenderName' => '測試寄件者',
					'SenderPhone' => '0226550115',
					'SenderCellPhone' => '0911222333',
					'ReceiverName' => '測試收件者',
					'ReceiverPhone' => '0226550115',
					'ReceiverCellPhone' => '0933222111',
					'ReceiverEmail' => 'test_emjhdAJr@test.com.tw',
					'TradeDesc' => '測試交易敘述',
					'ServerReplyURL' => get_home_url() . '/ServerReplyURL.php',
					'ClientReplyURL' => get_home_url(),
					'LogisticsC2CReplyURL' => get_home_url() . '/LogisticsC2CReplyURL.php',
					'Remark' => '測試備註',
					'PlatformID' => '',
				);
				$AL->SendExtend = array(
					'ReceiverStoreID' => '991182',
					'ReturnStoreID' => '',
				);
				// CreateShippingOrder()
				$Result = $AL->CreateShippingOrder();
				echo '<pre>' . print_r($Result, true) . '</pre>';
				exit();
			} catch(Exception $e) {
				echo $e->getMessage();
				exit();
			}
		}

本次範例外掛只針對最核心的部分來做說明跟講解,各位小夥伴可依據自己開發的程式需求及功能做架構上的調整,有問題的話歡迎留言一起討論 。

wordpress 外掛適應多語言開發撰寫方式

使用時機:
網頁有多個語言版本供用戶閱覽,或是外掛開發目的是讓多國使用者使用,可提升外掛跨國通用程度。

外掛主檔設定

外掛主檔設定:

/*

 * Plugin Name: 

 * Description: * Author: nekoto

 * Plugin URI: 

 * Version: 

 * Text Domain: $文本域名

 * Domain Path: /languages

 */

1.建立.pot檔(開發主語言翻譯)

檔案名稱:$文本域名.pot

#. 翻譯文本1
msgid "翻譯索引1"
msgstr "翻譯後文字1"

#. 翻譯文本2
msgid "翻譯索引2"
msgstr "翻譯後文字2"

#. 翻譯文本3
msgid "翻譯索引3"
msgstr "翻譯後文字3"

#. 翻譯文本4
msgid "翻譯索引4"
msgstr "翻譯後文字4"

2.建立.po檔(依照語言命名)

檔案名稱:$文本域名.po

若此檔要套用至繁體中文
則檔案名稱命名為:$文本域名-zh_TW.po

(.mo檔命名同理)

3.將撰寫好的.po檔轉成.mo檔  (php只認.mo檔,所以po檔更改後要記得轉.mo檔才會套用變更)

https://po2mo.net/ 上傳撰寫好的.po檔後下載轉好的.mo檔

下載後改名
檔案名稱:$文本域名.mo

4.外掛內載入:在外掛主檔內寫入

/*
* Load plugin textdomain.
*/
function plugin_load_textdomain() {
load_plugin_textdomain( '$文本域名', false, basename( dirname( __FILE__ ) ) .'/languages/' );
//這邊等於我把翻譯檔路徑設在我外掛下的languages資料夾,wordpress框架會自動去抓翻譯檔
}
add_action( 'init', 'plugin_load_textdomain' );

5.在呼叫文字時使用

例如我語言設定檔內有個

#. 翻譯範例

msgid “apple”

msgstr “蘋果”

在頁面要呼叫的時候:

原本不用語言管理時:echo “蘋果”; 

使用語言管理寫法後: _e( ‘apple’ , ‘$文本域名’ );

兩個寫法在頁面上都會顯示 蘋果

若要翻譯的文檔中含有變數 則使用printf搭配使用:

printf(

__( ‘你的蘋果是 %s.’, ‘$文本域名’ ),$apple

);

wordpress外掛開發 簡易綠界API串接結合自己開發的外掛(進階版+不須另外建立頁面)

閱讀本篇前建議先閱讀

重點概念

1.新建一個class(要被外掛主檔引入)

2.在該支程式__construct()內做網址判斷

這邊假設我希望綠界回傳給我的網址是{Mywebsite_base_Url}/ecpayverify
我的判斷就會如下:

if(strpos($_SERVER['REQUEST_URI'], '/ecpayverify/')===0||strpos($_SERVER['REQUEST_URI'], '/ecpayverify/')>0){

}

3.將要處理的邏輯寫在裡面,處理完後記得要"exit();"避免回傳給綠界資訊時產生多於的程式碼,以下附上範例

<?php
if(!class_exists('onlineScheduleTrans')):

class onlineScheduleTrans{
	public static $_instance=NULL;
	function __construct(){
		global $wpdb;

		add_action('wp_ajax_nopriv_buyService', array($this, 'buyService'));
		add_action('wp_ajax_buyService', array($this, 'buyService'));

		if(strpos($_SERVER['REQUEST_URI'], '/ecpayverify/')===0||strpos($_SERVER['REQUEST_URI'], '/ecpayverify/')>0){
			global $wpdb;
			require_once onlineSchedule_DIR.'/SDK/ECPay.Payment.Integration.php';
			define( 'ECPay_MerchantID', '3145753' );
			define( 'ECPay_HashKey', 'kUMKO4xa8YHtgc1B' );
			define( 'ECPay_HashIV', 'CSZqL9EXECkOMlUt' );
			 
			// 重新整理回傳參數。
			$arParameters = $_POST;
			foreach ($arParameters as $keys => $value) {
			    if ($keys != 'CheckMacValue') {
			        if ($keys == 'PaymentType') {
			            $value = str_replace('_CVS', '', $value);
			            $value = str_replace('_BARCODE', '', $value);
			            $value = str_replace('_CreditCard', '', $value);
			        }
			        if ($keys == 'PeriodType') {
			            $value = str_replace('Y', 'Year', $value);
			            $value = str_replace('M', 'Month', $value);
			            $value = str_replace('D', 'Day', $value);
			        }
			        $arFeedback[$keys] = $value;
			    }
			}
			 
			// 計算出 CheckMacValue
			$CheckMacValue = ECPay_CheckMacValue::generate( $arParameters, ECPay_HashKey, ECPay_HashIV );
			// 必須要支付成功並且驗證碼正確
			if ( $_POST['RtnCode'] =='1' && $CheckMacValue == $_POST['CheckMacValue'] ){
			    // 要處理的程式放在這裡,例如將線上服務啟用、更新訂單資料庫付款資訊等
			    $MerchantTradeNo=$_POST["MerchantTradeNo"];
			    $RtnCode=$_POST["RtnCode"];
			    $TradeAmt=$_POST["TradeAmt"];
			    $CheckMacValue=$_POST["CheckMacValue"];
			    //if success do something
			}
			else{
				//if fail do something
			}
			// 接收到資訊回應綠界
			echo '1|OK';
			exit();
		}
	}

	public static function instance(){
		if(is_null(self::$_instance))self::$_instance=new self();
		return self::$_instance;
	}

}

endif;

這個寫法是正規外掛的寫法,比起基礎版可以省去建立頁面的麻煩,如果本篇教學有幫到你記得幫我點個讚~

(分享) windows 批次(batch)檔 – 將指定格式的檔案編碼轉成 utf-8

各位在做案子的時候不知道有沒有遇過一種狀況,按照廠商方的需求開發完程式了,卻因為要處理的檔案編碼的問題導致又得增加額外的工作量,想要簡單的上網查個現成的轉編碼方式直接套用又總是遇到各種問題,因為每個語言讀入和寫出檔案都有各自的處理方式,所以常常導致最後執行完的結果往往跟想像中的不一樣?

這個是我自己後來最常用的解決方法,只要在自己原本要執行的程式執行前先呼叫此執行檔進行要處理的文件編碼,即可正常執行,這邊提供兩個版本一個是轉成UTF-8 with BOM,一個是轉成utf-8,裡面都有文字檔可以設定要轉檔的路徑(循環往下讀入)及要轉檔的檔案格式

如果這邊文章讓你少繞了很多路或是您覺得好用的話動動小手點讚一下給個支持吧!

轉成 UTF8( no BOM ) :
https://drive.google.com/file/d/1ycanhBFOS5XcB1L0_m7aKtUMk-rLn2mN/view?usp=sharing

轉成 UTF8( with BOM ) :
https://drive.google.com/file/d/1ycanhBFOS5XcB1L0_m7aKtUMk-rLn2mN/view?usp=sharing