Introduction

In the article How to Integrate Amadeus APIs in PHP, we demonstrated how to build a basic flight search feature using the Amadeus Flight Offers Search API. In this two-part series, we’ll demonstrate how to integrate this same API into a WordPress plugin.

This series is for PHP and WordPress developers with some prior knowledge and experience developing WordPress plugins. If you have any doubts about WordPress plugin development, visit the WordPress Codex for a refresher or clarification. If you’d like to add search and booking capabilities to your WordPress site, the techniques shown in this series will give you a great start toward harnessing the power of Amadeus Self-Service travel APIs.

Part 1 of this series will demonstrate, step-by-step, how to create a simple WordPress plugin, equip it with an admin page where users can configure the API credential settings and give the plugin the ability to communicate with the Flight Offers Search API.

Part 2 will follow up by equipping the plugin with a user interface where users can enter their travel details, giving it the ability to receive input from users and display flight deals received from the Flight Offers Search API in a table.

You can find the source code used in the article on our GitHub repository.

Creating the plugin

In a nutshell, a WordPress plugin is a PHP file with a WordPress plugin header comment. To create the plugin, first give the plugin a unique name that describes its purpose. In this case, you’ll name it Amadeus Flight Offers Search. Then navigate to the plugins directory inside the WordPress wp-content directory and create a new directory. Name it after the plugin — for example, amadeus-flight-offers-search.

Create a new PHP file inside the new directory and name it after its directory, something like amadeus-flight-offers-search.php. This will be the main PHP file for the plugin. WordPress plugins can contain multiple PHP files, but one (and only one) must be the main PHP file, which is the equivalent of index.php or index.html in a web application.

What sets the main PHP file apart from the rest of the PHP files is that the main PHP file starts with a specially formatted PHP block comment-styled plugin header that contains metadata about the plugin, such as its name, author, version, license, and so forth. The plugin header must comply with the header requirements and, at the very least, contain the name of the plugin. For clarity, it’s good practice to name the main PHP file after its directory.

Now add a plugin header to amadeus-flight-offers-search.php as shown here:

<?php
/**
 * Plugin Name:     Amadeus Flight Offers Search
 * Plugin URI:      https://developers.amadeus.com
 * Description:     Connecting to Flight Offers Search API.
 * Version:         1.0.0
 * Requires PHP:    5.2
 * Author:          Amadeus for Developers
 * Author URI:      https://developers.amadeus.com
 * License:         GPL v2 or later
 * License URI:     https://www.gnu.org/licenses/gpl-2.0.html
 */
?>

Save the file. You’ve just added a plugin called Amadeus Flight Offers Search to your WordPress site. If you head over to the Plugins menu on the main navigation bar of the WordPress administration screen, you should see the newly created Amadeus Flight Offers Search plugin, along with some of its metadata from the plugin header in amadeus-flight-offers-search.php:

Now you’ve created a bare-minimum plugin, but it still doesn’t do anything. In the next section, you’ll add an admin page where users can set the credentials required to connect to Amadeus Self-Service APIs.

Adding the admin page

To access Amadeus Self-Service APIs, you must request an access token from the Amadeus authorization server using an API key and an API secret. You can provide these values as settings through a page consisting of a form with two text fields for entering the settings and a button for saving them as an option (namely a record) in the {$wpdb->prefix}_options table of the WordPress database. Your plugin can then retrieve the saved settings for later use. You can include this settings page as a submenu of the Settings menu of the WordPress administration screen and it becomes the admin page for your Amadeus Flight Offers Search plugin.

You’ll create this admin page using a combination of the WordPress Settings API and the Options API. The Settings API provides functions to define the composition of settings pages and add them as submenus of the Settings menu, and handles the practical details of security and page rendering. The Options API offers functions for creating, reading, updating and deleting WordPress options.

To create the admin page for your Amadeus Flight Offers Search plugin, start by adding a new PHP file to your plugin directory called, for example, amadeus-api-settings.php. In the amadeus-api-settings.php file, add a function called amadeus_api_settings_init:

function amadeus_api_settings_init() {
	// to add code here
}

In the amadeus_api_settings_init function, add the following code to register a new settings page with a slug name—a unique identifier—called amadeus_api, insert a new row into the {$wpdb->prefix}_options table in the WordPress database, and add amadeus_api_options as a value to the option_name field of this new row. Here’s the code to add:

register_setting( 'amadeus_api', 'amadeus_api_options' );

Note that amadeus_api_options is the unique name given to the option that stores the settings of your Amadeus Flight Offers Search plugin in the {$wpdb->prefix}_options table, and it’s needed to read, update or delete the settings.

Next, in the amadeus_api_settings_init function, add the Settings API’s add_settings_section function to define a section with a slug name called amadeus_api_section, a section title called Client Credentials, a callback function called amadeus_api_section_callback, and the slug name of the admin page called amadeus_api on which to show this section:

add_settings_section(
	'amadeus_api_section',
	'Client Credentials',
	'amadeus_api_section_callback',
	'amadeus_api'
  );

In the amadeus_api_settings_init function, add the Settings API’s add_settings_field function to define a text field for the API key option, with a slug name called api_key_text_field_0, a field label called API Key, a callback function called api_key_text_field_0_render, the slug name of the admin page called amadeus_api on which to show the section, and the slug name of the section called amadeus_api_section on which to show this text field:

add_settings_field(
	'api_key_text_field_0',
	'API Key', 
	'api_key_text_field_0_render',
	'amadeus_api',
	'amadeus_api_section'
);

Similarly, complete the amadeus_api_settings_init function with the following code to define another text field for the API secret option:

add_settings_field(
	'api_secret_text_field_1',
	'API Secret',
	'api_secret_text_field_1_render',
	'amadeus_api',
	'amadeus_api_section'
);

Then create the callback function amadeus_api_section_callback required for rendering the amadeus_api_section, which was defined earlier:

function amadeus_api_section_callback() {
	echo 'Enter the API key and API secret of your app obtained from Amadeus for Developers portal.', 'amadeus_api';
}

This amadeus_api_section_callback function will simply display an instruction on the admin page.

Now create the callback function api_key_text_field_0_render, which is required for rendering the api_key_text_field_0 text field that was defined four paragraphs earlier.

function api_key_text_field_0_render() {
	$options = get_option( 'amadeus_api_options' );
	echo '<input type="text" name="amadeus_api_options[api_key_text_field_0]" value="' . $options[ 'api_key_text_field_0' ] . '">';
}

When called on, this api_key_text_field_0_render function will call the Options API’s get_option function to retrieve from the {$wpdb->prefix}_options table a row whose option_name field contains the value amadeus_api_options. It will get the value stored in the option_value field of that row and display it in the api_key_text_field_0 text field.

Similarly, create another callback function api_secret_text_field_1_render required for rendering the api_secret_text_field_1 text field defined 4 paragraphs ago:

function api_secret_text_field_1_render() {
	$options = get_option( 'amadeus_api_options' );
	echo '<;input type="text" name="amadeus_api_options[api_secret_text_field_1]" value="' . $options[ 'api_secret_text_field_1' ] . '">;';
}

Add the following code to bind the amadeus_api_settings_init function to the admin_init action hook, as follows:

add_action( 'admin_init', 'amadeus_api_settings_init' );

So far, you’ve registered a settings page and defined the section and fields that go into it. Next, you’ll include this settings page as a submenu in the Settings menu of the WordPress administration screen. In the amadeus-api-settings.php, create a function called add_amadeus_api_options_page, like so:

function add_amadeus_api_options_page() {
	add_options_page( 'Amadeus API Settings Page', 'Amadeus API Settings Menu', 'manage_options', 'amadeus_api_menu', 'amadeus_api_options_page' );
}

This function will call the WordPress add_options_page function to add a submenu called amadeus_api_menu to the Settings menu of the WordPress administration screen. The first two arguments give this submenu a page title called Amadeus API Settings Page and a menu title called Amadeus API Settings Menu. The third argument, manage_options, specifies the permission required to access this admin page, the fourth argument gives the menu a slug name called amadeus_api_menu, and the last argument specifies a callback function called amadeus_api_options_page. This function will be called to render the admin page when this submenu is selected.

Now create the amadeus_api_options_page function that will handle the practical details of security and page rendering for the admin page, with the following code:

function amadeus_api_options_page() {
	if ( ! current_user_can( 'manage_options' ) ) {
		wp_die( 'You do not have sufficient permissions to access this page.' );
	}
 ?>
	<h1><?php echo esc_html( get_admin_page_title() ); ?></h1>
	<form action="options.php" method="post">
	<?php
	// display hidden fields and handle security
	settings_fields( 'amadeus_api' );
	// output all the sections and fields
	do_settings_sections( 'amadeus_api' );
	// output a save button
	submit_button( 'Save Settings' );
	?>
	</form>
<?php
}

Next, add the following code to bind the add_amadeus_api_options_page function to the admin_menu action hook:

add_action( 'admin_menu', 'add_amadeus_api_options_page' );

You’ve written the program to compose the admin page for your Amadeus Flight Offers Search plugin as a submenu in the Settings menu of the WordPress administration screen in the amadeus-api-settings.php file. Now, all you have to do is put it to work. Let’s get started!

First, include the code from the amadeus-api-settings.php file in the main PHP file, amadeus-flight-offers-search.php, of your Amadeus Flight Offers Search plugin:

require_once( 'amadeus-api-settings.php' );

Then, navigate to the Plugins page of the WordPress administration screen and activate the Amadeus Flight Offers Search plugin. After a successful activation, a submenu titled Amadeus API Settings Menu will appear under the Settings menu as shown:

Go ahead and select the Amadeus API Settings Menu submenu to launch the admin page for your Amadeus Flight Offers Search plugin. You’ll see the Amadeus API Settings Page dialog box shown here.

Voilà! You now have an admin page to provide the API key and API secret that your Amadeus Flight Offers Search plugin needs to connect to Amadeus Self-Service APIs.

The complete code in amadeus-api-settings.php file should look like this:

<?php
function amadeus_api_settings_init() {
  register_setting( 'amadeus_api', 'amadeus_api_options' );
  add_settings_section(
	  'amadeus_api_section',
	  'Client Credentials',
	  'amadeus_api_section_callback',
	  'amadeus_api'
  );
  add_settings_field(
	  'api_key_text_field_0',
	  'API Key',
	  'api_key_text_field_0_render',
	  'amadeus_api',
	  'amadeus_api_section'
  );
  add_settings_field(
	  'api_secret_text_field_1',
	  'API Secret',
	  'api_secret_text_field_1_render',
	  'amadeus_api',
	  'amadeus_api_section'
  );
}
function amadeus_api_section_callback() {
  echo 'Enter the API key and API secret of your app obtained from Amadeus for Developers portal.', 'amadeus_api';
}
function api_key_text_field_0_render() {
  $options = get_option( 'amadeus_api_options' );
  echo '<input type="text" name="amadeus_api_options[api_key_text_field_0]" value="' . $options[ 'api_key_text_field_0' ] . '">';
}
function api_secret_text_field_1_render() {
  $options = get_option( 'amadeus_api_options' );
  echo '<input type="text" name="amadeus_api_options[api_secret_text_field_1]" value="' . $options[ 'api_secret_text_field_1' ] . '">';
}
add_action( 'admin_init', 'amadeus_api_settings_init' );
function add_amadeus_api_options_page() {
  add_options_page( 'Amadeus API Settings Page', 'Amadeus API Settings Menu', 'manage_options', 'amadeus_api', 'amadeus_api_options_page' );
}
function amadeus_api_options_page() {
  if ( ! current_user_can( 'manage_options' ) ) {
	  wp_die( 'You do not have sufficient permissions to access this page.' );
  }
?>
<h1><?php echo esc_html( get_admin_page_title( ) ); ?></h1>
<form action="options.php" method="post">
<?php
settings_fields( 'amadeus_api' );
do_settings_sections( 'amadeus_api' );
submit_button( 'Save Settings' );
?>
</form>
<?php
}
add_action( 'admin_menu', 'add_amadeus_api_options_page' );
?>

Interacting with the API

Now, let’s write the code to enable your plugin to interact with the Amadeus Flight Offers Search API and display the response on a WordPress post. In our previous article on integrating Amadeus APIs in PHP, we wrote a PHP script to access and consume the Amadeus Flight Offers Search API. In the name of DRY —Don’t Repeat Yourself— you’ll reuse this script for your plugin. However, you have to make some changes to the original script so it can fit the WordPress environment and meet the requirements of your plugin. Let’s go through the original script and make the following changes:

Start by removing the following statement to include the PHP Requests library as modern WordPress sites are already Requests-ready:

require_once 'path/requests/library/Requests.php';

Instead of hardcoding the API key and API secret, retrieve them dynamically from the {$wpdb->prefix}_options table by calling the Options API’s get_option function and passing it an option name called amadeus_api_option like this:

/*
$auth_data = array(
	'client_id' 	=>  'API Key',
	'client_secret' =>  'API Secret',
	'grant_type' 	=> 'client_credentials'
);
*/
$options = get_option( 'amadeus_api_options' ); 
$auth_data = array();
$auth_data[ 'client_id' ] = $options[ 'api_key_text_field_0' ];
$auth_data[ 'client_secret' ] = $options[ 'api_secret_text_field_1' ];
$auth_data[ 'grant_type' ] = 'client_credentials';

Then include an element called returnDate in the $travel_data array to store the return date, as shown here:

$travel_data = array(
'originLocationCode' 	  => 'SIN',
	'destinationLocationCode' => 'BKK',
	'departureDate' 	        => '2020-08-14',
	'returnDate' 	        => '2020-08-17',
	'adults'                  => 2
);

Add a timeout option to the GET request to manage the timeout issue:

$options = array(
	'timeout' => 10,
);
$requests_response = Requests::get( $url, $headers, $options );

Then finally, for a trial run, truncate the raw travel data returned by the Amadeus Flight Offers Search API up to the first 5,000 letters:

echo '<pre>', substr( json_encode($response_body, JSON_PRETTY_PRINT ), 0, 5000 ), </pre>';

That’s all you need to do to amend the original script to fit your plugin. Let’s move the amended script into a function called get_flight_offers and save it as get-flight-offers.php inside your plugin’s directory. Once this is done, the get-flight-offers.php file should contain the following code:

function get_flight_offers() {
  Requests::register_autoloader();
  $url = 'https://test.api.amadeus.com/v1/security/oauth2/token';
  $options = get_option( 'amadeus_api_options' ); 
  $auth_data = array();
  $auth_data[ 'client_id' ] = $options[ 'api_key_text_field_0' ];
  $auth_data[ 'client_secret' ] = $options[ 'api_secret_text_field_1' ];
  $auth_data[ 'grant_type' ] = 'client_credentials';
  $headers = array( 'Content-Type' => 'application/x-www-form-urlencoded' );
  try {
	$requests_response = Requests::post( $url, $headers, $auth_data );
	echo 'Response from the authorization server:';
	$response_body = json_decode( $requests_response->body );
	echo '<pre>', json_encode($response_body, JSON_PRETTY_PRINT), '</pre>';
	if( property_exists( $response_body, 'error' ) ) die;
	$access_token = $response_body->access_token;
  } catch (Exception $e) {
	print_r( $e->getMessage() );
  }
  if(isset($access_token)){
	$endpoint = 'https://test.api.amadeus.com/v2/shopping/flight-offers';
	$travel_data = array(
	  'originLocationCode' 	  => 'SIN',
	  'destinationLocationCode' => 'BKK',
	  'departureDate' 	      => '2020-08-14',
	  'returnDate' 	          => '2020-08-17',
	  'adults'                  => 2
	);
	$params = http_build_query( $travel_data );
	$url = $endpoint.'?'.$params;
	$headers = array( 'Authorization' => 'Bearer '.$access_token );
	$options = array(
	  'timeout' => 10,
	);
	try {
	  $requests_response = Requests::get( $url, $headers, $options );
	  echo 'Response from the Flight Offers Search API:';
	  $response_body = json_decode( $requests_response->body );
	  echo '&<pre>', substr( json_encode($response_body, JSON_PRETTY_PRINT), 0, 5000 ), '</pre>';
	  if(property_exists( $response_body, 'error' ) ) die;
	} catch ( Exception $e ) {
	   print_r( $e->getMessage() );
	}
  }
}

You created a function called get_flight_offers with the capability to interact with the Amadeus Flight Search API in the get-flight-offers.php file. Next, you have to integrate this function into your Amadeus Flight Offers Search plugin so your plugin can interact with the Amadeus Flight Offers Search API. As a trial run, you’ll get the plugin to output part of the response from the Amadeus Flight Offers Search API to a WordPress post.

To accomplish this, you need to perform several steps in the main PHP file, amadeus-flight-offers-search.php. Start by including the file:

require_once( 'get-flight-offers.php' );

Then add the Shortcode API’s add_shortcode function to create a shortcode with a shortcode tag called amadeus-flight-offers-search and a callback function called amadeus_flight_offers_search_shortcode. This will add the get_flight_offers function to any posts or pages on which this shortcode is found:

function amadeus_flight_offers_search_shortcode() {  
    get_flight_offers();
}
add_shortcode( 'amadeus-flight-offers-search', 'amadeus_flight_offers_search_shortcode' );

To add the get_flight_offers function to a WordPress post or page, simply add the shortcode tag of the shortcode—amadeus-flight-offers-search—in a pair of square brackets to the post or page, for example:

Launch a WordPress post that has this tag [amadeus-flight-offers-search] added and you’ll see that the post displays a response from the API that looks something like this:

At this point, the amadeus-flight-offers-search.php file should contain the following code:

<?php
/**
 * Plugin Name:     Amadeus Flight Offers Search
 * Plugin URI:      https://developers.amadeus.com
 * Description:     Connecting to Flight Offers Search API.
 * Version:         1.0.0
 * Requires PHP:    5.2
 * Author:          Amadeus for Developers
 * Author URI:      https://developers.amadeus.com
 * License:         GPL v2 or later
 * License URI:     https://www.gnu.org/licenses/gpl-2.0.html
 */
require_once( 'amadeus-api-settings.php' );
require_once( 'get-flight-offers.php' );
function amadeus_flight_offers_search_shortcode() {
    get_flight_offers();
}
add_shortcode( 'amadeus-flight-offers-search', 'amadeus_flight_offers_search_shortcode' );
?>

Intermission

We’ve arrived at the end of Part 1. So far, you’ve created a simple WordPress plugin called Amadeus Flight Offers Search, equipped it with an admin page where users can configure their credential settings as required to connect to Amadeus Self-Service APIs, and given the plugin the ability to communicate with the Flight Offers Search API, which proved successful in a trial run.

In Part 2 of this series, you’ll further enhance the plugin by adding a user interface that lets users enter their travel details, giving it the ability to receive input from users and output flight deals received from the Flight Offers Search API in a table.

This article was first published on Amadeus’s blog.

How to work with us

  • Contact us to set up a call.
  • We will analyze your needs and recommend a content contract solution.
  • Sign on with ContentLab.
  • We deliver topic-curated, deeply technical content to you.

To get started, complete the form to the right to schedule a call with us.

Send this to a friend