View source
<?php
namespace Drupal\contribute;
use Drupal\Component\Serialization\Json;
use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Datetime\DateFormatterInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\Core\Url;
use GuzzleHttp\ClientInterface;
class ContributeManager implements ContributeManagerInterface {
use StringTranslationTrait;
protected $status;
protected $accountType;
protected $accountId;
protected $cache;
protected $httpClient;
protected $dateFormatter;
protected $configFactory;
protected $cachedData = [];
protected $cachedPeople = [];
public function __construct(CacheBackendInterface $cache, ClientInterface $http_client, DateFormatterInterface $date_formatter, ConfigFactoryInterface $config_factory) {
$this->cache = $cache;
$this->httpClient = $http_client;
$this->dateFormatter = $date_formatter;
$this->configFactory = $config_factory;
$this->status = $this->configFactory
->get('contribute.settings')
->get('status');
$this->accountType = $this->configFactory
->get('contribute.settings')
->get('account_type');
$this->accountId = $this->configFactory
->get('contribute.settings')
->get('account_id');
}
public function getAccount() {
$account_type = $this
->getAccountType();
$account_id = $this
->getAccountId() ?: 'anonymous';
$cid = 'contribute.account.' . md5("{$account_type}.{$account_id}");
$cache = $this->cache
->get($cid);
if ($cache) {
return $cache->data;
}
$account = [];
$account['status'] = FALSE;
if ($account_id != 'anonymous') {
switch ($account_type) {
case 'organization':
$organization = $this
->getOrganization();
if ($organization) {
$account['status'] = TRUE;
$account['url'] = Url::fromUri($organization['url']);
$account['name'] = $organization['title'];
$account['created'] = $organization['created'];
$account['image'] = $this
->getOrganizationLogo();
}
break;
case 'user':
$user = $this
->getUser();
if ($user) {
$account['status'] = TRUE;
$account['url'] = Url::fromUri($user['url']);
if ($user['field_first_name'] || $user['field_last_name']) {
$account['name'] = $user['field_first_name'] . ($user['field_first_name'] && $user['field_last_name'] ? ' ' : '') . $user['field_last_name'];
}
else {
$account['name'] = $user['name'];
}
$account['created'] = $user['created'];
$account['image'] = $this
->getUserPicture();
$account['organizations'] = [];
foreach ($user['field_organizations'] as $item) {
$data = $this
->get($item['uri'] . '.json');
if (!empty($data['field_organization_name'])) {
$account['organizations'][] = $data['field_organization_name'];
}
}
}
break;
}
}
$configure_attributes = [
'data-dialog-type' => 'modal',
'data-dialog-options' => Json::encode([
'width' => 600,
]),
];
if (isset($account['name'])) {
$account['value'] = [];
$account['value']['name'] = [
'#type' => 'link',
'#title' => $account['name'],
'#url' => $account['url'],
'#prefix' => '<strong>',
'#suffix' => '</strong>',
];
if (!empty($account['organizations'])) {
$account['value']['organizations'] = [
'#prefix' => ' @ ',
'#plain_text' => implode('; ', $account['organizations']),
];
}
$t_args = [
'@date' => $this->dateFormatter
->formatTimeDiffSince($account['created']),
];
$account['value']['drupal'] = [
'#prefix' => '<br/>',
'#markup' => $this
->t('On Drupal.org for @date', $t_args),
];
$account['description']['link'] = [
'#type' => 'link',
'#title' => $this
->t('Configure'),
'#url' => Url::fromRoute('contribute.settings'),
'#attributes' => $configure_attributes + [
'class' => [
'use-ajax',
],
],
];
}
else {
$t_args = [
':href_register' => 'https://register.drupal.org/user/register',
':href_ groups' => 'https://groups.drupal.org',
':href_jobs' => 'https://jobs.drupal.org',
':href_association' => 'https://www.drupal.org/association',
];
$account['value'] = [
'#markup' => $this
->t('When you <a href=":href_register">create a Drupal.org account</a>, you gain access to a whole ecosystem of Drupal.org sites and services.', $t_args) . ' ' . $this
->t('Your account works on Drupal.org and any of its subsites including <a href=":href_ groups">Drupal Groups</a>, <a href=":href_jobs">Drupal Jobs</a>, <a href=":href_association">Drupal Association</a> and more.', $t_args),
];
$account['description'] = [
'#type' => 'link',
'#title' => $this
->t('Configure'),
'#url' => Url::fromRoute('contribute.settings'),
'#attributes' => $configure_attributes + [
'class' => [
'use-ajax',
'button',
'button--small',
'button--primary',
'contribute-status-report-community-info__button',
],
],
];
}
$this->cache
->set($cid, $account, strtotime('+1 hour'), [
'contribute',
]);
return $account;
}
public function getMembership() {
$account_type = $this
->getAccountType();
$account_id = $this
->getAccountId() ?: 'anonymous';
$cid = 'contribute.membership.' . md5("{$account_type}.{$account_id}");
$cache = $this->cache
->get($cid);
if ($cache) {
return $cache->data;
}
$membership = [];
$membership['status'] = FALSE;
if ($account_id != 'anonymous') {
switch ($account_type) {
case 'organization':
if ($badge = $this
->getOrganizationBadge()) {
$membership = [
'status' => TRUE,
'badge' => $badge,
];
}
break;
case 'user':
if ($badge = $this
->getUserBadge()) {
$membership = [
'status' => TRUE,
'badge' => $badge,
];
}
break;
}
}
if ($membership['status']) {
$membership['value'] = $this
->t('<strong>You Rock!</strong> Thank you for purchasing a Drupal Association membership.');
}
else {
$t_args = [
':href_association' => 'https://www.drupal.org/association',
':href_individual' => 'https://www.drupal.org/association/individual-membership',
':href_organization' => 'https://www.drupal.org/association/organization-membership',
':href_donate' => 'https://www.drupal.org/association/donate',
];
$membership['value'] = [
'#markup' => $this
->t('The <a href=":href_association">Drupal Association</a> is dedicated to fostering and supporting the Drupal software project.', $t_args),
];
switch ($account_type) {
case 'organization':
$membership['value']['#markup'] .= '</br></br>' . $this
->t('Organization members are active contributors in the Drupal community. By making your organization or company a member, your team funds the community grants program and you support our work on drupal.org, DrupalCons, and other projects. Together, we unite our global open source community to build and promote Drupal.');
$membership['description'] = [
'#type' => 'link',
'#title' => $this
->t('Become an organization member'),
'#url' => Url::fromUri('https://www.drupal.org/association/organization-membership'),
'#attributes' => [
'class' => [
'button',
'button--small',
'button--primary',
'contribute-status-report-community-info__button',
],
],
];
break;
case 'user':
$membership['value']['#markup'] .= '</br></br>' . $this
->t('As a member, you build our momentum while supporting the Drupal community.') . ' ' . $this
->t('Members fund the community grants program and support our team as we work on Drupal.org, DrupalCons, and other projects. Together, we unite our global open source community to build and promote Drupal.');
$membership['description'] = [
'#type' => 'link',
'#title' => $this
->t('Become an individual member'),
'#url' => Url::fromUri('https://www.drupal.org/association/individual-membership'),
'#attributes' => [
'class' => [
'button',
'button--small',
'button--primary',
'contribute-status-report-community-info__button',
],
],
];
break;
default:
$membership['value']['#markup'] .= ' ' . $this
->t('You can join as an <a href=":href_individual">individual</a> or an <a href=":href_organization">organization member</a>, or <a href=":href_donate">donate</a> directly any amount.', $t_args);
$membership['description'] = [
'#type' => 'link',
'#title' => $this
->t('Support our work'),
'#url' => Url::fromUri('https://www.drupal.org/association/support'),
'#attributes' => [
'class' => [
'button',
'button--small',
'contribute-status-report-community-info__button',
],
],
];
break;
}
}
$this->cache
->set($cid, $membership, strtotime('+1 hour'), [
'contribute',
]);
return $membership;
}
public function getContribution() {
$account_type = $this
->getAccountType();
$account_id = $this
->getAccountId() ?: 'anonymous';
$cid = 'contribute.contribution.' . md5("{$account_type}.{$account_id}");
$cache = $this->cache
->get($cid);
if ($cache) {
return $cache->data;
}
$contribution = [];
$contribution['status'] = FALSE;
if ($account_id != 'anonymous') {
switch ($account_type) {
case 'organization':
$organization = $this
->getOrganization();
$contribution['status'] = $organization && (!empty($organization['field_contributions']['value']) || !empty($organization['field_org_issue_credit_count']));
break;
case 'user':
$user = $this
->getUser();
$contribution['status'] = $user && (!empty($user['field_contributed']) || !empty($user['field_drupal_contributions']['value']));
break;
}
}
if ($contribution['status']) {
$contribution['value'] = $this
->t('<strong>You are a Rockstar!</strong> Thank you for contributing back to Drupal.');
}
else {
$t_args = [
':href_about' => 'https://www.drupal.org/about',
];
$contribution['value'] = [
'#markup' => $this
->t('<a href=":href_about">Drupal is an open source project</a>, we don’t have employees to provide Drupal improvements and support. <strong>We depend on our diverse community of passionate volunteers to move the project forward</strong> by working on not just web development and user support but also many other contributions and interests.', $t_args),
];
$contribution['description'] = [
'#type' => 'link',
'#title' => $this
->t('Ways to get involved'),
'#url' => Url::fromUri('https://www.drupal.org/contribute'),
'#attributes' => [
'class' => [
'button',
'button--small',
'contribute-status-report-community-info__button',
],
],
];
if ($account_type) {
$contribution['description']['#attributes']['class'][] = 'button--primary';
}
}
$this->cache
->set($cid, $contribution, strtotime('+1 hour'), [
'contribute',
]);
return $contribution;
}
public function getStatus() {
return $this->status;
}
public function getAccountType() {
return $this->accountType;
}
public function getAccountId() {
return $this->accountId;
}
public function setAccountType($account_type) {
$this->accountType = $account_type;
}
public function setAccountId($account_id) {
$this->accountId = $account_id;
}
public function getPerson($type) {
if (isset($this->cachedPeople[$type])) {
return $this->cachedPeople[$type];
}
$people = $this
->getPeople($type);
$person = $people[array_rand($people)];
$this->cachedPeople[$type] = $person;
return $person;
}
protected function get($uri) {
if (isset($this->cachedData[$uri])) {
return $this->cachedData[$uri];
}
try {
$response = $this->httpClient
->get($uri);
$is_json = preg_match('/\\.json($|\\?)/', $uri) ? TRUE : FALSE;
$data = $is_json ? Json::decode($response
->getBody()) : $response
->getBody();
} catch (\Exception $exception) {
$data = NULL;
}
$this->cachedData[$uri] = $data;
return $data;
}
protected function getUser() {
$account_id = $this
->getAccountId();
$data = $this
->get('https://www.drupal.org/api-d7/user.json?name=' . urlencode($account_id));
if (isset($data['list']) && count($data['list']) === 1) {
return reset($data['list']);
}
else {
return [];
}
}
protected function getUserPicture() {
$account_id = $this
->getAccountId();
$body = $this
->get('https://www.drupal.org/u/' . urlencode($account_id));
if (preg_match('#(/user-pictures/picture-[^\\.]+.[a-z]+)#', $body, $match)) {
return 'https://www.drupal.org/files' . $match[1];
}
else {
return '';
}
}
protected function getUserBadge() {
$account_id = $this
->getAccountId();
$body = $this
->get('https://www.drupal.org/u/' . urlencode($account_id));
if (strpos($body, 'association_ind_member_badge.svg') !== FALSE) {
return 'https://www.drupal.org/sites/all/modules/drupalorg/drupalorg/images/association_ind_member_badge.svg';
}
elseif (strpos($body, 'association_org_member_badge.svg') !== FALSE) {
return 'https://www.drupal.org/sites/all/modules/drupalorg/drupalorg/images/association_org_member_badge.svg';
}
else {
return NULL;
}
}
protected function getOrganization() {
$account_id = $this
->getAccountId();
$data = $this
->get('https://www.drupal.org/api-d7/node.json?type=organization&title=' . urlencode($account_id));
if (isset($data['list']) && count($data['list']) === 1) {
return reset($data['list']);
}
else {
return [];
}
}
protected function getOrganizationLogo() {
$organization = $this
->getOrganization();
if (!$organization || !isset($organization['field_logo']['file']['uri'])) {
return '';
}
$data = $this
->get($organization['field_logo']['file']['uri'] . '.json');
return $data['url'];
}
protected function getOrganizationBadge() {
$organization = $this
->getOrganization();
if (!$organization) {
return '';
}
$body = $this
->get($organization['url']);
if (preg_match('#"(https://www.drupal.org/sites/all/modules/drupalorg/drupalorg/images/association_[^"]+\\.svg)"#', $body, $match)) {
return $match[1];
}
else {
return '';
}
}
}