Rinkerが動かないのは大変困る

WordPress用の商品リンク管理プラグインのRinkerが、自宅鯖を更新してWordPressを最新にしたら動かなくなった。いや、正確に言うとしばらく前から動かなくなっていて、「どういうコンテキストでこういうものを購入した」かという備忘録としてブログを書いてる側面があるため、とても困っていた。

で、鯖を更新したので重い腰を上げ、もう何年ぶりか分からないぐらい久しぶりにPHPを見て直した。

diff -ruwN --exclude block /tmp/yyi-rinker-orig/yyi-rinker/yyi-rinker.php new_server/wordpress/plugins/yyi-rinker/yyi-rinker.php
--- /tmp/yyi-rinker-orig/yyi-rinker/yyi-rinker.php	2026-01-25 12:02:40
+++ new_server/wordpress/plugins/yyi-rinker/yyi-rinker.php	2026-04-23 15:52:55
@@ -19,13 +19,19 @@
 	add_action( 'plugins_loaded', array( 'Yyi_Rinker_Plugin', 'get_object' ) );
 }
 
+if ( class_exists( 'Yyi_Rinker_Plugin_Gutenberg' ) ) {
+	add_action(
+		'plugins_loaded',
+		function () {
+			new Yyi_Rinker_Plugin_Gutenberg();
+		}
+	);
+}
 
+
 require 'plugin-updates/plugin-update-checker.php';
 $ExampleUpdateChecker = Puc_v4_Factory::buildUpdateChecker(
 	'https://oyakosodate.com/rinker-plugin/update.json',
 	__FILE__,
 	'yyi-rinker'
 );
-
-
-
diff -ruwN --exclude block /tmp/yyi-rinker-orig/yyi-rinker/yyi_rinker_main.php new_server/wordpress/plugins/yyi-rinker/yyi_rinker_main.php
--- /tmp/yyi-rinker-orig/yyi-rinker/yyi_rinker_main.php	2026-01-25 12:02:40
+++ new_server/wordpress/plugins/yyi-rinker/yyi_rinker_main.php	2026-04-23 17:12:23
@@ -2261,6 +2261,7 @@
         $creator_secret_key	= get_option( $this->option_column_name('amazon_creator_secret_key'));
         //v不要のため削除
         $creator_version	= str_replace('v', '', get_option( $this->option_column_name('amazon_creator_version')));
+        $creator_version_major = intval( explode( '.', $creator_version )[0] );
 
         $request->partnerType = 'Associates';
         $request->partnerTag  = $traccking_id;
@@ -2268,21 +2269,39 @@
         $request->marketplace = 'www.amazon.co.jp';
 
 
+
         //cURLがインストールされていれば利用する
         if ( function_exists( 'curl_version' ) ) {
             $access_token = get_transient($this->add_prefix( 'creator_api_access_token'));
 
+
+
             if( empty($access_token) ){
                 $curl = curl_init();
                 $auth_creds = $creator_auth_id . ':' . $creator_secret_key;
+                if ( $creator_version_major >= 3 ) {
                     $headers = [
+                        'Content-Type: application/json',
+                    ];
+                    $token_url = 'https://api.amazon.co.jp/auth/o2/token';
+                    $token_payload = wp_json_encode( [
+                        'grant_type' => 'client_credentials',
+                        'client_id' => $creator_auth_id,
+                        'client_secret' => $creator_secret_key,
+                        'scope' => 'creatorsapi::default',
+                    ] );
+                } else {
+                    $headers = [
                         'Content-Type: application/x-www-form-urlencoded',
                         'Authorization: Basic ' . base64_encode($auth_creds),
                     ];
+                    $token_url = 'https://creatorsapi.auth.us-west-2.amazoncognito.com/oauth2/token';
+                    $token_payload = 'grant_type=client_credentials&scope=creatorsapi/default';
+                }
 
-                curl_setopt($curl, CURLOPT_URL, 'https://creatorsapi.auth.us-west-2.amazoncognito.com/oauth2/token');
+                curl_setopt($curl, CURLOPT_URL, $token_url);
                 curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'POST');
-                curl_setopt($curl, CURLOPT_POSTFIELDS, 'grant_type=client_credentials&scope=creatorsapi/default');
+                curl_setopt($curl, CURLOPT_POSTFIELDS, $token_payload);
                 curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
                 curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true);
                 curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
@@ -2307,24 +2326,40 @@
                             'message_jp' => intval($error_no) . ':cURLエラー']];
                 }
                 $header_size = curl_getinfo($curl, CURLINFO_HEADER_SIZE);
+                $token_info = curl_getinfo($curl);
                 $res = substr($response, $header_size);
                 $header_json_datas = json_decode($res);
-                $access_token = $header_json_datas->access_token;
+                $access_token = ( is_object( $header_json_datas ) && isset( $header_json_datas->access_token ) ) ? $header_json_datas->access_token : '';
+                $expires_in = ( is_object( $header_json_datas ) && isset( $header_json_datas->expires_in ) ) ? $header_json_datas->expires_in : null;
 
                 curl_close($curl);
-                if ( ! empty( $access_token ) && ! empty( $header_json_datas->expires_in ) ) {
-                    set_transient($this->add_prefix('creator_api_access_token'), $access_token, $header_json_datas->expires_in);
+
+                if ( empty( $access_token ) ) {
+                    return [
+                        'error' => [
+                            'code' => 'AmazonCreatorsTokenError',
+                            'message' => intval( isset( $token_info['http_code'] ) ? $token_info['http_code'] : 0 ) . ':Amazon Creators API token error: ' . substr( (string) $res, 0, 500 ),
+                            'message_jp' => intval( isset( $token_info['http_code'] ) ? $token_info['http_code'] : 0 ) . ':Amazon Creators API token error: ' . substr( (string) $res, 0, 500 ),
+                        ]
+                    ];
                 }
+
+                if ( ! empty( $expires_in ) ) {
+                    set_transient($this->add_prefix('creator_api_access_token'), $access_token, $expires_in);
                 }
+            }
 
 
             $curl = curl_init();
             $url = 'https://creatorsapi.amazon/catalog/v1/' . $operation;
             $headers = [
-                'Authorization: Bearer ' . $access_token  . ', Version ' . $creator_version,
+                'Authorization: Bearer ' . $access_token,
                 'Content-Type: application/json',
                 'x-marketplace: www.amazon.co.jp',
             ];
+            if ( $creator_version_major < 3 ) {
+                $headers[] = 'Version: ' . $creator_version;
+            }
 
             $payload = json_encode( $request );
 
@@ -2387,17 +2422,27 @@
         if ( isset( $json_datas->errors[0] ) ) {
             $code = $json_datas->errors[0]->code;
             $en_message = $json_datas->errors[0]->message;
-            $message_ip = $this->amazon_api_json_errors($code, $en_message);
+            $error_type = isset( $json_datas->errors[0]->type ) ? $json_datas->errors[0]->type : '';
+            $message_ip = $this->amazon_api_json_errors( $error_type ? $error_type : $code, $en_message );
             return [
                 'error' => [
-                    'code' => $code,
+                    'code' => $error_type ? $error_type : $code,
                     'message' => $en_message,
                     'message_jp' => $message_ip,]];
         }
 
         if ($status_code != '200') {
+            $decoded_error = json_decode( $res );
+            if ( is_object( $decoded_error ) && isset( $decoded_error->type ) && isset( $decoded_error->message ) ) {
+                $message_ip = $this->amazon_api_json_errors( $decoded_error->type, $decoded_error->message );
                 return [
                     'error' => [
+                        'code' => $decoded_error->type,
+                        'message' => $decoded_error->message,
+                        'message_jp' => $message_ip ]];
+            }
+            return [
+                'error' => [
                     'code' => 'AmazonAPIのステータスエラー',
                     'message' =>  intval($status_code) . ':AmazonAPIのステータスエラー: ' . $res,
                     'message_jp' =>  intval($status_code) . ':AmazonAPIのステータスエラー: ' . $res]];
@@ -2773,6 +2818,13 @@
 			case 'AccessDeniedAwsUsers':
 				$message ='このアクセスキーは、Product Advertising APIにアクセスするために有効になっていません。AWS認証情報を利用している場合はProduct Advertising APIで取得し直してください。';
 				break;
+			case 'AccessDeniedException':
+				if ( $code === 'AccessDeniedException' && strpos( $en_message, 'eligibility requirements' ) !== false ) {
+					$message = 'Amazon Creators APIの利用条件を現在満たしていません。Amazonアソシエイト/Creators API側の利用資格を確認してください。';
+				} else {
+					$message = $en_message;
+				}
+				break;
 			case 'InvalidAssociate':
 				$message = 'アクセスキー[アクセスキー]は、承認されたアソシエイトストアのプライマリにマップされていません。';
 				break;
@@ -4717,4 +4769,3 @@
     }
 }';
 }
-

で、テスト用にAmazonのCreators APIのトークンを発行し直したら、Eligibilityチェックで引っかかったので、上記のようなコードになったと。