class MolliePaymentInstaller in Mollie Payment 7.2
Class MolliePaymentInstaller.
@package Drupal\mollie_payment
Hierarchy
- class \Drupal\mollie_payment\MolliePaymentInstaller
Expanded class hierarchy of MolliePaymentInstaller
File
- includes/
mollie_payment.installer.inc, line 12
Namespace
Drupal\mollie_paymentView source
class MolliePaymentInstaller {
// Define constants for this class.
const LIBRARY_NAME = 'mollie-api-php';
const MOLLIE_API_CLIENT_URL = 'https://api.github.com/repos/mollie/mollie-api-php/releases/latest';
const MOLLIE_API_KEYS_URL = 'https://www.mollie.com/dashboard/developers/api-keys';
const MOLLIE_TOKENS_URL = 'https://www.mollie.com/dashboard/developers/organization-access-tokens';
const MOLLIE_CREATE_ACCOUNT_URL = 'https://www.mollie.com/dashboard/signup/958337';
const MOLLIE_ACCOUNT_URL = 'https://www.mollie.com/dashboard/login';
/**
* Checks if the Mollie API client for PHP is installed.
*
* @return array
* An associative array as expected by hook_requirements().
*/
public function checkMollieApiClient() {
// Default requirements info.
$value = 'not found';
$description = t('The Mollie API client for PHP is missing.');
$severity = REQUIREMENT_WARNING;
// Try to detect the installation state of the Mollie API client for PHP.
$library = libraries_detect(self::LIBRARY_NAME);
if ($library) {
if ($library['installed']) {
// The client is installed. Show the installed version.
$value = $library['version'];
$description = t('Version @version of the Mollie API client for PHP is installed.', array(
'@version' => $library['version'],
));
$severity = REQUIREMENT_OK;
}
else {
// The client is not installed. Show the error and error message.
$value = $library['error'];
$description = $library['error message'];
// Add a link to the client installer.
$description .= ' ' . t('Click to <a href="!url">install the Mollie API client for PHP</a>.', array(
'!url' => url('admin/config/services/mollie/client-installer', array(
'query' => array(
'destination' => current_path(),
),
)),
));
}
}
return $this
->formatRequirements('Mollie API client for PHP', $value, $description, $severity);
}
/**
* Checks if a Mollie account has been configured.
*
* @return array
* An associative array as expected by hook_requirements().
*/
public function checkMollieAccount() {
$value = 'no API key';
$description = t('There is no default live API key configured.');
$url = url('admin/config/services/mollie/account');
$severity = REQUIREMENT_WARNING;
$apiKey = variable_get('mollie_payment_default_api_key_live', '');
if (!empty($apiKey)) {
$organizationToken = variable_get('mollie_payment_default_access_token', '');
if (empty($organizationToken)) {
$value = 'no organization access token';
$description = t('There is no default organization access token configured. With an organization access token your Mollie onboarding status can be checked.');
}
else {
// Check the onboarding status. The Mollie API client for PHP does not
// support this at this moment so we need to do this manually for now.
$value = $this
->getOnboardingStatus();
switch ($value) {
case 'needs-data':
$description = t('Mollie needs more information to enable your account.');
$url = self::MOLLIE_ACCOUNT_URL;
break;
case 'in-review':
$description = t('Mollie is reviewing your account application.');
$url = self::MOLLIE_ACCOUNT_URL;
break;
case 'completed':
$description = t('Your default Mollie account has been configured.');
$severity = REQUIREMENT_OK;
break;
default:
$description = t('The onboarding status of your Mollie account could not be determined.');
break;
}
}
}
if ($severity === REQUIREMENT_WARNING) {
// Add a link to the account configuration form.
$description .= ' ' . t('Click to <a href="!url">configure your Mollie account</a>.', array(
'!url' => $url,
));
}
return $this
->formatRequirements('Mollie account', $value, $description, $severity);
}
/**
* Checks if a Mollie payment method has been defined for the Payment module.
*
* @return array
* An associative array as expected by hook_requirements().
*/
public function checkMolliePaymentMethod() {
$value = 'no payment method';
$description = t('There is no Payment method configured for Mollie.');
$severity = REQUIREMENT_WARNING;
// Load payment methods.
$methods = entity_load('payment_method', FALSE, array(
'controller_class_name' => MolliePaymentMethodController::class,
));
if (!empty($methods)) {
$value = 'ok';
$description = t('There is at least one Mollie payment method configured.');
$severity = REQUIREMENT_OK;
}
if ($severity === REQUIREMENT_WARNING) {
// Add a link to the form to add a Mollie payment method.
$description .= ' ' . t('Click to <a href="!url">add a Mollie payment method</a>.', [
'!url' => url('admin/config/services/payment/method/add/' . MolliePaymentMethodController::class, [
'query' => [
'destination' => current_path(),
],
]),
]);
}
return $this
->formatRequirements('Mollie payment method', $value, $description, $severity);
}
/**
* Installs the Mollie API client for PHP.
*/
public function installMollieApiClient() {
try {
// We cannot use system_retrieve_file() since it utilizes
// drupal_http_request() which in turn does not properly update the Host
// header when following redirects. That causes an issue when GitHub
// redirects to AWS.
$file_uri = $this
->downloadLatestsMollieApiClient();
// Extract the archive to the libraries directory.
$directory = 'sites/all/libraries/' . self::LIBRARY_NAME;
if (module_exists('update')) {
update_manager_archive_extract(drupal_realpath($file_uri), $directory);
}
else {
$this
->extractArchive(drupal_realpath($file_uri), $directory);
}
// Clear the libraries cache.
libraries_cache_clear();
drupal_set_message(t('The Mollie API client for PHP has been installed.'));
} catch (\Exception $e) {
watchdog_exception('mollie_payment', $e);
drupal_set_message(t('The Mollie API client for PHP could not be installed. See the logs for details.'));
}
}
/**
* Returns formatted requirements info to be used with hook_requirements().
*
* @param $title
* The name of the requirement.
* @param $description
* The description of the requirement/status.
* @param $severity
* The requirement's result/severity level as expected by
* hook_requirements().
*
* @return array
* An associative array as expected by hook_requirements().
*
* @see hook_requirements()
*/
protected function formatRequirements($title, $value, $description, $severity) {
// Add an additional warning to the description if the requirement is
// not met.
if (in_array($severity, array(
REQUIREMENT_WARNING,
REQUIREMENT_ERROR,
))) {
$description .= ' This needs to solved before payments can be received using Mollie.';
}
return array(
'title' => $title,
'value' => $value,
'description' => $description,
'severity' => $severity,
);
}
/**
* Downloads the latest version of the client.
*
* @return string|bool
* The path of the download or false if the client could not be downloaded.
*
* @throws \Exception
*/
protected function downloadLatestsMollieApiClient() {
$url = $this
->getLatestsMollieApiClientUrl();
// Fetch data from the URL.
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, TRUE);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
$response = curl_exec($curl);
$info = curl_getinfo($curl);
curl_close($curl);
if ($info['http_code'] == 200 && $response) {
// Write the data to a temporary file.
$temp_name = drupal_tempnam('temporary://', 'file') . '.zip';
if (file_put_contents($temp_name, $response) !== FALSE) {
return $temp_name;
}
}
else {
throw new \Exception(curl_error($curl));
}
return FALSE;
}
/**
* Returns the URL of the zip with the latest version of the client.
*
* @return string
* The URL of the zip with the latest version of the Mollie API client
* for PHP.
*
* @throws \Exception
*/
protected function getLatestsMollieApiClientUrl() {
// Fetch information about latest release.
$response = drupal_http_request(self::MOLLIE_API_CLIENT_URL);
if (isset($response->data)) {
$release = drupal_json_decode($response->data);
// Return the URL of the zip.
if (isset($release['assets']) && !empty($release['assets'])) {
foreach ($release['assets'] as $asset) {
if ($asset['content_type'] == 'application/zip') {
return $asset['browser_download_url'];
}
}
}
}
throw new \Exception('The Mollie API client for PHP could not be found on GitHub.');
}
protected function getOnboardingStatus() {
$status = 'unknown';
$organizationToken = variable_get('mollie_payment_default_access_token', '');
if (!empty($organizationToken)) {
$options = array(
'headers' => array(
'Authorization' => 'Bearer ' . $organizationToken,
),
);
$response = drupal_http_request('https://api.mollie.com/v2/onboarding/me', $options);
if ($response->code == 200) {
$data = json_decode($response->data);
return isset($data->status) ? $data->status : $status;
}
}
return $status;
}
/**
* Unpacks a downloaded archive file.
*
* We duplicate update_manager_archive_extract() since we do not want this
* module to depend on the Update manager module.
*
* @param $file
* The filename of the archive you wish to extract.
* @param $directory
* The directory you wish to extract the archive into.
*
* @return \ArchiverInterface
* The Archiver object used to extract the archive.
*
* @throws \Exception
*/
protected function extractArchive($file, $directory) {
$archiver = archiver_get_archiver($file);
if (!$archiver) {
throw new \Exception(t('Cannot extract %file, not a valid archive.', array(
'%file' => $file,
)));
}
// Remove the directory if it exists, otherwise it might contain a mixture of
// old files mixed with the new files (e.g. in cases where files were removed
// from a later release).
$files = $archiver
->listContents();
// Unfortunately, we can only use the directory name to determine the project
// name. Some archivers list the first file as the directory (i.e., MODULE/)
// and others list an actual file (i.e., MODULE/README.TXT).
$project = strtok($files[0], '/\\');
$extract_location = $directory . '/' . $project;
if (file_exists($extract_location)) {
file_unmanaged_delete_recursive($extract_location);
}
$archiver
->extract($directory);
return $archiver;
}
}