kintone API SDK for PHPを使って、指定したアプリとそのレコードを一括でコピーするコードを書いてみました。
コード
\<?php//実行時間制限の変更set\_time\_limit(300);//「kintone API SDK for PHP」の設定require 'vendor/autoload.php';$api = new \CybozuHttp\Api\KintoneApi(new \CybozuHttp\Client(['domain' =\> 'cybozu.com','subdomain' =\> '\*\*\*\*','login' =\> '\*\*\*\*','password' =\> '\*\*\*\*','use\_basic' =\> true,'basic\_login' =\> '\*\*\*\*','basic\_password' =\> '\*\*\*\*',]));//コピー元アプリのIDdefine('ORIGIN\_APP\_ID', \*\*\*\*);//データ整形用関数function copyFile($api, $file){$path = sys\_get\_temp\_dir().'/'.$file['name'];file\_put\_contents($path, $api-\>file()-\>get($file['fileKey']));$fileKey = $api-\>file()-\>post($path);unlink($path);return $fileKey;}function formatProperties($properties){foreach(['レコード番号', '$id', '$revision', '作成者', '更新者', '作成日時', '更新日時', 'カテゴリー', '作業者', 'ステータス'] as $fieldCode){unset($properties[$fieldCode]); }return $properties;}function formatCustomize($api, $customize){return array\_map(function($file) use ($api){if($file['type'] === 'URL') return $file;return ['type' =\> 'FILE','file' =\> ['fileKey' =\> copyFile($api, $file['file']) ] ]; }, $customize);}function formatRecords($api, $records){return array\_map(function($record) use ($api){foreach(['レコード番号', '$id', '$revision', '作成者', '更新者', '作成日時', '更新日時'] as $fieldCode){unset($record[$fieldCode]); }return array\_reduce(array\_keys($record), function($carry, $fieldCode) use ($api, $record){if($record[$fieldCode]['type'] === 'FILE'){$carry[$fieldCode] = ['type' =\> 'FILE','value' =\> array\_map(function($file) use ($api){return ['fileKey' =\> copyFile($api, $file)]; }, $record[$fieldCode]['value']) ]; }else if($record[$fieldCode]['type'] === 'SUBTABLE'){$carry[$fieldCode] = ['type' =\> 'SUBTABLE','value' =\> array\_map(function($row) use ($api){return ['value' =\> array\_reduce(array\_keys($row['value']), function($carry, $fieldCode) use ($api, $row){if($row['value'][$fieldCode]['type'] === 'FILE'){$carry[$fieldCode] = ['type' =\> 'FILE','value' =\> array\_map(function($file) use ($api){return ['fileKey' =\> copyFile($api, $file)]; }, $row['value'][$fieldCode]['value']) ]; }else{$carry[$fieldCode] = $row['value'][$fieldCode]; }return $carry; }, []) ]; }, $record[$fieldCode]['value']) ]; }else{$carry[$fieldCode] = $record[$fieldCode]; }return $carry; }, []); }, $records);}//コピー元アプリのデータ取得$originApp = $api-\>app()-\>get(ORIGIN\_APP\_ID);$originAppSettings = $api-\>app()-\>getSettings(ORIGIN\_APP\_ID);$originAppFields = $api-\>app()-\>getFields(ORIGIN\_APP\_ID);$originAppLayout = $api-\>app()-\>getLayout(ORIGIN\_APP\_ID);$originAppViews = $api-\>app()-\>getViews(ORIGIN\_APP\_ID);$originAppAcl = $api-\>app()-\>getAcl(ORIGIN\_APP\_ID);$originAppRecordAcl = $api-\>app()-\>getRecordAcl(ORIGIN\_APP\_ID);$originAppFieldAcl = $api-\>app()-\>getFieldAcl(ORIGIN\_APP\_ID);$originAppCustomize = $api-\>app()-\>getCustomize(ORIGIN\_APP\_ID);$originAppStatus = $api-\>app()-\>getStatus(ORIGIN\_APP\_ID);$originAppRecords = $api-\>records()-\>all(ORIGIN\_APP\_ID, 'order by レコード番号 asc');//コピー先アプリの作成$copyAppName = $originApp['name'].'copy'.date("Ymd"); // コピー先アプリ名$copyApp = $api-\>preview()-\>post($copyAppName);//コピー先アプリの設定変更$api-\>preview()-\>putSettings($copyApp['app'], $copyAppName, $originAppSettings['description'], $originAppSettings['icon'], $originAppSettings['theme']);$api-\>preview()-\>postFields($copyApp['app'], formatProperties($originAppFields['properties']));$api-\>preview()-\>putLayout($copyApp['app'], $originAppLayout['layout']);if(!empty($originAppViews['views'])) $api-\>preview()-\>putViews($copyApp['app'], $originAppViews['views']);$api-\>preview()-\>putAcl($copyApp['app'], $originAppAcl['rights']);$api-\>preview()-\>putRecordAcl($copyApp['app'], $originAppRecordAcl['rights']);$api-\>preview()-\>putFieldAcl($copyApp['app'], $originAppFieldAcl['rights']);$api-\>preview()-\>putCustomize($copyApp['app'], formatCustomize($api, $originAppCustomize['desktop']['js']), formatCustomize($api, $originAppCustomize['desktop']['css']), formatCustomize($api, $originAppCustomize['mobile']['js']));if(!empty($originAppStatus['states'])) $api-\>preview()-\>putStatus($copyApp['app'], $originAppStatus['states'], $originAppStatus['actions'], $originAppStatus['enable']);//コピー先アプリのデプロイ$api-\>preview()-\>deploy($copyApp['app']);while(!isset($deployed)){ //デプロイ完了まで待機try{$api-\>app()-\>get($copyApp['app']);$deployed = true; }catch(Exception $e){sleep(1); }}//コピー先アプリのレコード登録foreach(array\_chunk(formatRecords($api, $originAppRecords), 100) as $recordChunk){$api-\>records()-\>post($copyApp['app'], $recordChunk);}echo '「'.$originAppSettings['name'].'('.ORIGIN\_APP\_ID.')」を「'.$copyAppName.'('.$copyApp['app'].')」へコピーしました。'."";
・$api
には、「kintoneのシステム管理権限」、「コピー元アプリのアプリ・レコード・フィールドの閲覧権限」を持ったユーザーを設定してください。
・APIが対応していない一部の設定値はコピー先に引き継がれません。場合によってはエラーになる可能性もあります。
・サンプルではコピー元アプリIDを固定値で処理していますが、引数渡しをすれば複数のアプリに対応できます。