metis-3.0.x-dev/metis.module
metis.module
<?php
/**
* @file
* Primary module hooks for Metis module.
*/
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Session\AccountInterface;
/**
* Implements hook_theme().
*/
function metis_theme() {
return [
'metis_codes' => [
'variables' => [
'code_public' => NULL,
'code_private' => NULL,
'server' => NULL,
'show' => NULL,
],
],
'metis_code_public' => [
'variables' => [
'code_public' => NULL,
'code_private' => NULL,
'server' => NULL,
'show' => NULL,
],
],
'metis_code_private' => [
'variables' => [
'code_public' => NULL,
'code_private' => NULL,
'server' => NULL,
'show' => NULL,
],
],
'metis_show' => [
'variables' => [
'code_public' => NULL,
'code_private' => NULL,
'server' => NULL,
'show' => NULL,
],
],
];
}
/**
* Count unused codes.
*/
function metis_count_unused() {
$connection = \Drupal::database();
$query = $connection->select('metis', 'm');
$query
->condition('m.used', 0, '=')
->addField('m', 'code_public');
$count_query = $query->countQuery();
return $count_query->countQuery()->execute()
->fetchField();
}
/**
* Get unused code.
*
* @return array|false
* An code array or false.
*/
function metis_get_unused() {
$connection = \Drupal::database();
$query = $connection->select('metis', 'm');
$query
->fields('m', ['code_public', 'code_private', 'server'])
->condition('m.used', 0, '=');
$count_query = $query->countQuery();
$results = $count_query->countQuery()->execute()->fetchField();
// If there are no unused codes, return FALSE.
if ($results == 0) {
return FALSE;
}
// If there are unused codes, return an array
// with public and private metis code.
else {
$query = $connection->select('metis', 'm');
$query
->fields('m', ['code_public', 'code_private', 'server'])
->condition('m.used', 0, '=');
$results = $query->range(0, 1)->execute()->fetchAssoc();
return [
'code_public' => $results['code_public'],
'code_private' => $results['code_private'],
'server' => $results['server'],
];
}
}
/**
* Set code used.
*
* @param $code_public
* The public code.
* @param $nid
* The node id.
*
* @return bool
* Return true on success, false on failure.
*/
function metis_set_used($code_public, $nid) {
// Check if code has 32 characters and nid is present.
if (mb_strlen($code_public) == 32 && is_numeric($nid)) {
// Update database and set used codes as used.
try {
$connection = \Drupal::database();
$query = $connection->update('metis');
$query
->fields([
'used' => $nid,
])
->condition('code_public', $code_public)
->condition('used', 0)
->execute();
// No exception thrown; PDO thinks the record was inserted correctly.
$message = t(
'Code %public_code has been set as "used" by node %nid.',
[
'%public_code' => $code_public,
'%nid' => $nid,
]
);
\Drupal::logger('metis')->notice($message);
}
catch (PDOException $e) {
$message = t(
'Code %public_code could not be set as "used" by node %nid. Error message: :error_message',
[
'%public_code' => $code_public,
'%nid' => $nid,
':error_message' => $e->getMessage(),
]
);
\Drupal::logger('metis')->error($message);
return FALSE;
}
return TRUE;
}
else {
return FALSE;
}
}
/**
* Implements hook_entity_field_access().
*/
function metis_entity_field_access($operation, FieldDefinitionInterface $field_definition, AccountInterface $account, FieldItemListInterface $items = NULL) {
// We currently support node entities only.
if ($field_definition->getTargetEntityTypeId() !== 'node') {
return AccessResult::neutral();
}
if ($field_definition->getType() === 'metis' && $operation == 'edit') {
return AccessResult::allowedIfHasPermission($account, 'add metis codes to nodes');
}
return AccessResult::neutral();
}
/**
* Implements hook_entity_presave().
*/
function metis_entity_presave(EntityInterface $entity) {
// We currently support node entities only.
if ($entity->getEntityTypeId() !== 'node') {
return;
}
/** @var \Drupal\Core\Entity\EntityFieldManagerInterface $entity_field_manager */
$entity_field_manager = \Drupal::getContainer()->get('entity_field.manager');
$field_definitions = $entity_field_manager->getFieldDefinitions(
$entity->getEntityTypeId(), $entity->bundle()
);
foreach ($field_definitions as $field) {
if ($field->getType() === 'metis') {
$field_name = $field->getName();
$properties = $entity->getTypedData()->getProperties();
// Stop if no items where saved.
if ($show = $properties[$field_name]->__get('show')) {
// Get an unused code.
$unused = metis_get_unused();
// Check if a public metis code is set already.
// If not and the "show" option is selected, add a new one.
if ($unused && empty($properties[$field_name]->__get('code_public')) && $show == 1) {
if (is_array($unused)) {
$properties['field_metis']->__set('code_public', $unused['code_public']);
$properties['field_metis']->__set('code_private', $unused['code_private']);
$properties['field_metis']->__set('server', $unused['server']);
}
}
else {
//@todo Get new code from webservice.
}
}
}
}
}
/**
* Implements hook_entity_insert().
*/
function metis_entity_insert(EntityInterface $entity) {
// We currently support node entities only.
if ($entity->getEntityTypeId() !== 'node') {
return;
}
/** @var \Drupal\Core\Entity\EntityFieldManagerInterface $entity_field_manager */
$entity_field_manager = \Drupal::getContainer()->get('entity_field.manager');
$field_definitions = $entity_field_manager->getFieldDefinitions(
$entity->getEntityTypeId(), $entity->bundle()
);
foreach ($field_definitions as $field) {
if ($field->getType() === 'metis') {
$field_name = $field->getName();
$properties = $entity->getTypedData()->getProperties();
// Stop if no items where saved.
if (
$properties[$field_name]->__get('show') &&
$code_public = $properties[$field_name]->__get('code_public')
) {
metis_set_used($code_public, $entity->id());
}
}
}
}
/**
* Implements hook_entity_update().
*/
function metis_entity_update(EntityInterface $entity) {
// We currently support node entities only.
if ($entity->getEntityTypeId() !== 'node') {
return;
}
/** @var \Drupal\Core\Entity\EntityFieldManagerInterface $entity_field_manager */
$entity_field_manager = \Drupal::getContainer()->get('entity_field.manager');
$field_definitions = $entity_field_manager->getFieldDefinitions(
$entity->getEntityTypeId(), $entity->bundle()
);
foreach ($field_definitions as $field) {
if ($field->getType() === 'metis') {
$field_name = $field->getName();
$properties = $entity->getTypedData()->getProperties();
// Stop if no items where saved.
if (
$properties[$field_name]->__get('show') &&
$code_public = $properties[$field_name]->__get('code_public')
) {
metis_set_used($code_public, $entity->id());
}
}
}
}
