photo_albums-1.0.2/photo_albums.module
photo_albums.module
<?php
/**
* @file
* Contains photo_albums.module.
*/
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\views\ViewExecutable;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Messenger\MessengerInterface;
use Drupal\Core\Template\AttributeHelper;
/**
* Implements hook_help().
*/
function photo_albums_help($route_name, RouteMatchInterface $route_match) {
switch ($route_name) {
// Main module help for the photo_albums module.
case 'help.page.photo_albums':
$output = '';
$output .= '<h3>' . t('About') . '</h3>';
$output .= '<p>' . t('Provide photo album content.') . '</p>';
return $output;
default:
}
}
/**
* Implements hook_theme().
*/
function photo_albums_theme() {
return [
'photo_albums' => [
'render element' => 'children',
],
];
}
/**
* Implements hook_views_pre_render().
*/
function photo_albums_views_pre_render(ViewExecutable $view) {
if (isset($view) && ($view->storage->id() == 'photo_albums')) {
$view->element['#attached']['library'][] = 'photo_albums/photo_albums';
}
}
/**
* Implements hook_entity_presave().
*
* { @inheritdoc }
*/
function photo_albums_node_presave(Drupal\Core\Entity\EntityInterface $entity) {
if ($entity instanceof \Drupal\node\NodeInterface && $entity->bundle() == 'album') {
$nid = $entity->id();
$reset = $entity->field_reset_password->value;
if ($reset) {
\Drupal::database()->delete('photo_albums_protected')
->condition('nid', $nid, '=')
->execute();
$entity->field_reset_password->value = 0;
}
}
}
/**
* Implements hook_entity_insert().
*
* {@inheritdoc}
*/
function photo_albums_node_insert(EntityInterface $entity) {
_photo_albums_insert_update($entity);
}
/**
* Implements hook_entity_update().
*
* { @inheritdoc }
*/
function photo_albums_node_update(EntityInterface $entity) {
_photo_albums_insert_update($entity);
}
/**
* Implements hook_entity_delete().
*
* {@inheritdoc}
*/
function photo_albums_node_delete(EntityInterface $entity) {
if ($entity instanceof \Drupal\node\NodeInterface && $entity->bundle() == 'album') {
$results = \Drupal::database()->delete('photo_albums_protected')
->condition('nid', $entity->id(), '=')
->execute();
}
}
/**
* Implements hook_form_alter().
*/
function photo_albums_form_alter(&$form, &$form_state, $form_id) {
if ($form_id === 'node_album_edit_form') {
// get the node id for the node being edited
$nid = $form_state->getformObject()->getEntity()->id();
// if the nid is set then we can look in the protect album passwords
// table for the encrypted password for this node (album)
if ($nid) {
// get the password record for the node
$pass = \Drupal::database()->select('photo_albums_protected', 'p')
->fields('p', ['pass'])
->condition('nid', $nid, '=')
->execute()
->fetchField();
// get the Two Way hashing service
$tw_hash = \Drupal::service('photo_albums.twowayhash');
// decrypt the stored hash
$decrypted_pass = $tw_hash->decrypt($pass);
}
// if the default value for the field_protect_album is "1" then the
// album is currently protected, so show the password
if ($form['field_protect_album']['widget']['value']['#default_value'] && isset($decrypted_pass)) {
$form['field_protect_album']['widget']['value']['#title'] .= t(' - current password: <em>@pass</em>', ['@pass' => $decrypted_pass]);
}
}
}
/**
* Helper function for insert and update nodes of type album.
*/
function _photo_albums_insert_update(EntityInterface $entity) {
if ($entity instanceof \Drupal\node\NodeInterface && $entity->bundle() == 'album') {
$nid = $entity->id();
$protected = $entity->field_protect_album->value;
// check to see if a password is already set.
// only update the password if a record does not exist
// or the reset box is ticked too
$results = \Drupal::database()->select('photo_albums_protected', 'p')
->fields('p', ['nid'])
->condition('nid', $nid, '=')
->execute()
->fetchAll();
// if the protect box is not ticked, but record is found
// in the password table, delete it
if (count($results) && !$protected) {
\Drupal::database()->delete('photo_albums_protected')
->condition('nid', $nid, '=')
->execute();
}
if (!count($results) && $protected) {
$pass = user_password(8);
// use the two-way hashing service to hash the password
$tw_hash = \Drupal::service('photo_albums.twowayhash');
$pass_hashed = $tw_hash->encrypt($pass);
$insert = \Drupal::database()->insert('photo_albums_protected')
->fields([
'nid' => $nid,
'pass' => $pass_hashed,
])
->execute();
$messenger = \Drupal::messenger();
$msg = t('The album \'@title\' has been protected with the following password: @pass', ['@title' => $entity->getTitle(), '@pass' => $pass]);
$messenger->addMessage($msg, MessengerInterface::TYPE_STATUS);
}
}
}
/**
* Prepares variables for image templates.
*
* Default template: image.html.twig.
*
* @param array $variables
* An associative array containing:
* - uri: Either the path of the image file (relative to base_path()) or a
* full URL.
* - width: The width of the image (if known).
* - height: The height of the image (if known).
* - alt: The alternative text for text-based browsers. HTML 4 and XHTML 1.0
* always require an alt attribute. The HTML 5 draft allows the alt
* attribute to be omitted in some cases. Therefore, this variable defaults
* to an empty string, but can be set to NULL for the attribute to be
* omitted. Usually, neither omission nor an empty string satisfies
* accessibility requirements, so it is strongly encouraged for code
* building variables for image.html.twig templates to pass a meaningful
* value for this variable.
* - http://www.w3.org/TR/REC-html40/struct/objects.html#h-13.8
* - http://www.w3.org/TR/xhtml1/dtds.html
* - http://dev.w3.org/html5/spec/Overview.html#alt
* - title: The title text is displayed when the image is hovered in some
* popular browsers.
* - attributes: Associative array of attributes to be placed in the img tag.
* - srcset: Array of multiple URIs and sizes/multipliers.
* - sizes: The sizes attribute for viewport-based selection of images.
* - http://www.whatwg.org/specs/web-apps/current-work/multipage/embedded-content.html#introduction-3:viewport-based-selection-2
*/
function photo_albums_preprocess_image(&$variables) {
if (isset($variables['attributes']['id']) && !\Drupal::currentUser()->hasPermission('bypass album password protection')) {
$nid = $variables['attributes']['id'];
// get the stored password hash from the DB so we
// can compare any stored cookie value
$pass = \Drupal::database()->select('photo_albums_protected', 'p')
->fields('p', ['pass'])
->condition('nid', $nid, '=')
->execute()
->fetchField();
if (isset($_SESSION['_photo_albums_protected']['passwords'][$nid])) {
$cookie_pass_ok = ($pass === $_SESSION['_photo_albums_protected']['passwords'][$nid]);
}
else {
$cookie_pass_ok = FALSE;
}
if (isset($variables['attributes']['protected']) && $variables['attributes']['protected'] == '1' && !$cookie_pass_ok) {
$variables['uri'] = drupal_get_path('module', 'photo_albums') . '/images/protected.png';
}
}
if (!empty($variables['uri'])) {
$variables['attributes']['src'] = file_url_transform_relative(file_create_url($variables['uri']));
}
// Generate a srcset attribute conforming to the spec at
// http://www.w3.org/html/wg/drafts/html/master/embedded-content.html#attr-img-srcset
if (!empty($variables['srcset'])) {
$srcset = [];
foreach ($variables['srcset'] as $src) {
// URI is mandatory.
$source = file_url_transform_relative(file_create_url($src['uri']));
if (isset($src['width']) && !empty($src['width'])) {
$source .= ' ' . $src['width'];
}
elseif (isset($src['multiplier']) && !empty($src['multiplier'])) {
$source .= ' ' . $src['multiplier'];
}
$srcset[] = $source;
}
$variables['attributes']['srcset'] = implode(', ', $srcset);
}
foreach (['width', 'height', 'alt', 'title', 'sizes'] as $key) {
if (isset($variables[$key])) {
// If the property has already been defined in the attributes,
// do not override, including NULL.
if (AttributeHelper::attributeExists($key, $variables['attributes'])) {
continue;
}
$variables['attributes'][$key] = $variables[$key];
}
}
}
