live_blog-1.0.4/live_blog.module
live_blog.module
<?php
use Drupal\Core\Form\FormStateInterface;
use Drupal\node\Entity\Node;
use Drupal\node\NodeInterface;
use Drupal\Core\Database\Query\Condition;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Url;
/**
* Implements hook_help().
*/
function live_blog_help($route_name, RouteMatchInterface $route_match) {
switch ($route_name) {
case 'help.page.live_blog':
$output = '';
$output .= '<h3>' . t('Info') . '</h3>';
$output .= '<p>' . t('Live Blog module allows to create dynamic page with new content coming in without refreshing the page.<br>This module is useful for live events and streams.<br>This module allows to add/update/delete any post by admin and the final user\'s page will get updated automatically.<br>This module works perfectly with any CDN (Akamai, Cloudflare, etc).') . '</p>';
//$output .= '<h3>' . t('Demo') . '</h3>';
//$output .= '<p>' . t('<a href="https://www.youtube.com/" target="_blank">https://www.youtube.com/</a>') . '</p>';
$output .= '<h3>' . t('Installation') . '</h3>';
$output .= '<ol>';
$output .= '<li>' . t('Enable module "Live Blog" as usual or with drush: <b>drush en live_blog</b>') . '</li>';
$output .= '<li>' . t('Use any content type or create a new one by <a href=":new_content_type">link</a>', [
':new_content_type' => Url::fromRoute('node.type_add')->toString()
]) . '</li>';
$output .= '<li>' . t('Push the button "Add field".') . '</li>';
$output .= '<li>' . t('"Add a new field" => "Live Blog type" => Label: "Live Blog status"') . '</li>';
$output .= '<li>' . t('Save => Help text: "Enable/Disable the status of Live Blog." => Save') . '</li>';
$output .= '<li>' . t('Go to the "Manage display" page and disable "Label" for this New field.') . '</li>';
$output .= '<li>' . t('Create content from step 2) by <a href=":new_content">link</a>', [
':new_content' => Url::fromRoute('node.add_page')->toString()
]) . '</li>';
$output .= '<li>' . t('Enable the "Live Blog status" checkbox and Save.') . '</li>';
$output .= '<li>' . t('Now you can add/update/delete any posts.') . '</li>';
$output .= '</ol>';
$output .= '<p>' . t('Multiple users can have that page opened and all Live Blog posts get updated automatically.') . '</p>';
$output .= '<p>' . t('Thank you for using it!') . '</p>';
return $output;
}
}
/**
* Implements hook_page_attachments().
*/
function live_blog_page_attachments(array &$page) {
// Add main JS.
$page['#attached']['library'][] = 'live_blog/main';
// Add Drupal settings.
$page['#attached']['drupalSettings']['live_blog'] = [
'api' => base_path() . 'api/live-blog/api',
'interval' => \Drupal::config('live_blog.settings')->get('interval'),
];
}
/**
* Implements hook_theme().
*/
function live_blog_theme() {
return [
'live_blog_posts' => [
'template' => 'live-blog-posts',
'variables' => [
'add_more' => '',
'node' => NULL,
'lid' => 0,
'posts' => [],
],
'file' => 'live_blog.theme.inc',
],
'live_blog_post' => [
'template' => 'live-blog-post',
'variables' => [
'post' => [],
'node' => NULL,
],
'file' => 'live_blog.theme.inc',
],
];
}
/**
* Implements hook_cron().
*/
function live_blog_cron() {
// Get Drupal state.
$state = \Drupal::state();
// Get cron limit.
$cron_limit = \Drupal::config('live_blog.settings')->get('cron');
// Get the request time.
$request_time = \Drupal::time()->getRequestTime();
if ($state->get('live_blog.last_cron', 0) < ($request_time - $cron_limit)) {
// Get DB.
$database = \Drupal::database();
// Get old logs. P.S. db_delete() does not support JOIN.
$query = $database->select('live_blog_log', 'l');
$query->addField('l', 'lid');
$query->condition('l.time', $request_time - $cron_limit, '<');
$lids = $query->execute()->fetchCol();
// Flush old logs.
if (!empty($lids)) {
$database->delete('live_blog_log')->condition('lid', $lids, 'IN')->execute();
}
// Save last flushing time.
$state->set('live_blog.last_cron', $request_time);
}
}
/**
* Implements hook_field_group_form_process_alter().
*/
function live_blog_field_group_form_process_alter(array &$element, &$group, &$complete_form) {
if ($group->entity_type == 'live_blog') {
$complete_form['status']['#group'] = 'group_admin';
$complete_form['new_revision']['#group'] = 'group_other';
$complete_form['revision_log']['#group'] = 'group_other';
$complete_form['parent_id']['#group'] = 'group_other';
}
}
/**
* Implements hook_form_FORM_ID_alter().
*/
function live_blog_form_live_blog_form_alter(&$form, FormStateInterface $form_state, $form_id) {
if (empty($form['parent_id']['widget'][0]['target_id']['#default_value'])) {
// Get current request.
$request = \Drupal::request();
// Get Parent node ID (if present).
if ($parent_id = $request->query->get('parent_id')) {
// Get Parent node.
if ($node = Node::load($parent_id)) {
// Set default Node.
$form['parent_id']['widget'][0]['target_id']['#default_value'] = $node;
}
}
}
// Validate the Parent node.
$form['parent_id'] += ['#element_validate' => []];
$form['parent_id']['#element_validate'][] = 'live_blog_validate_parent';
}
/**
* Implements hook_ENTITY_TYPE_delete().
*
* Delete multiple posts by Parent ID.
*/
function live_blog_node_delete(NodeInterface $node) {
// Get all Live Blog posts by Parent ID.
$posts = \Drupal::entityTypeManager()->getStorage('live_blog')->loadByProperties([
'parent_id' => $node->id(),
]);
// Delete multiple posts.
live_blog_delete_multiple($posts);
}
/****************************
* Main functions
****************************/
/**
* Validate the Parent node.
*/
function live_blog_validate_parent(&$element, FormStateInterface $form_state, &$complete_form) {
// Get Parent node ID.
$parent_id = $form_state->getValue('parent_id');
$parent_id = $parent_id[0]['target_id'] ?? 0;
// Get Parent node.
$node = $parent_id ? Node::load($parent_id) : NULL;
if (!$node) {
// Show an error.
$form_state->setError($element, t('The Parent node is absent.'));
}
elseif (!$node->isPublished()) {
// Show an error.
$form_state->setError($element, t('The Parent node is unpublished.'));
}
}
/**
* Delete multiple posts.
*/
function live_blog_delete_multiple($posts) {
if (!empty($posts)) {
foreach ($posts as $post) {
// Delete post.
$post->delete();
}
}
}
/**
* Load posts from the Log.
*/
function live_blog_log_load($parent_id, $lid) {
// Do request.
$query = \Drupal::database()->select('live_blog_log', 'l');
$query->fields('l', ['lid', 'id', 'action']);
$query->leftJoin('live_blog', 'e', 'e.id = l.id');
$filter = new Condition('OR');
$filter->isNull('e.parent_id');
$filter->condition('e.parent_id', $parent_id);
$query->condition($filter);
$query->condition('l.lid', $lid, '>');
$query->orderBy('l.lid', 'ACS');
// Get Post IDs.
return $query->execute()->fetchAllAssoc('id');
}
/**
* Save to log: create/update/delete.
*/
function live_blog_log_save($action, $post) {
// Get database.
$database = \Drupal::database();
// Remove old logs (if any).
$database->delete('live_blog_log')
->condition('id', $post->id())
->execute();
// Insert a log record.
$database->insert('live_blog_log')
->fields([
'id' => $post->id(),
'action' => $action,
'time' => \Drupal::time()->getRequestTime(),
])
->execute();
}
/**
* Get last Log ID.
*/
function live_blog_get_lid($id) {
$lid = \Drupal::database()->queryRange('SELECT lid
FROM {live_blog_log}
WHERE id = :id
ORDER BY lid DESC', 0, 1, [
':id' => $id,
])->fetchField();
return (int) $lid;
}
