View source
<?php
namespace Drupal\mollie_payment;
use MolliePaymentMethodController;
class MolliePaymentInstaller {
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';
public function checkMollieApiClient() {
$value = 'not found';
$description = t('The Mollie API client for PHP is missing.');
$severity = REQUIREMENT_WARNING;
$library = libraries_detect(self::LIBRARY_NAME);
if ($library) {
if ($library['installed']) {
$value = $library['version'];
$description = t('Version @version of the Mollie API client for PHP is installed.', array(
'@version' => $library['version'],
));
$severity = REQUIREMENT_OK;
}
else {
$value = $library['error'];
$description = $library['error message'];
$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);
}
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 {
$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) {
$description .= ' ' . t('Click to <a href="!url">configure your Mollie account</a>.', array(
'!url' => $url,
));
}
return $this
->formatRequirements('Mollie account', $value, $description, $severity);
}
public function checkMolliePaymentMethod() {
$value = 'no payment method';
$description = t('There is no Payment method configured for Mollie.');
$severity = REQUIREMENT_WARNING;
$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) {
$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);
}
public function installMollieApiClient() {
try {
$file_uri = $this
->downloadLatestsMollieApiClient();
$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);
}
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.'));
}
}
protected function formatRequirements($title, $value, $description, $severity) {
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,
);
}
protected function downloadLatestsMollieApiClient() {
$url = $this
->getLatestsMollieApiClientUrl();
$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) {
$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;
}
protected function getLatestsMollieApiClientUrl() {
$response = drupal_http_request(self::MOLLIE_API_CLIENT_URL);
if (isset($response->data)) {
$release = drupal_json_decode($response->data);
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;
}
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,
)));
}
$files = $archiver
->listContents();
$project = strtok($files[0], '/\\');
$extract_location = $directory . '/' . $project;
if (file_exists($extract_location)) {
file_unmanaged_delete_recursive($extract_location);
}
$archiver
->extract($directory);
return $archiver;
}
}