annotate_node-1.0.1-alpha1/annotate_node.module
annotate_node.module
<?php /** * @file * Contains annotate_node.module. */ use Drupal\user\Entity\User; use Drupal\Core\Routing\RouteMatchInterface; use Drupal\node\Entity\Node; use Drupal\Core\Form\FormStateInterface; use Drupal\editor\Entity\Editor; use Drupal\comment\Entity\Comment; use Drupal\Component\Utility\Xss; /** * Implements hook_help(). */ function annotate_node_help($route_name, RouteMatchInterface $route_match) { switch ($route_name) { // Main module help for the annotate_node module. case 'help.page.annotate_node': $output = ''; $output .= '<h3>' . t('About') . '</h3>'; $output .= '<p>' . t('Annotate content from Nodes, similar to Google Docs comments') . '</p>'; return $output; default: } } /** * Implements hook_preprocess_node() * * We will check to see if we're on a node selected in the config that should * be altered to allow annotations. * * Will also make the CommentForm we created available to the templates. * * Next we take the body of the node, alter it with divs * so that it can be broken up into paragraphs if need be. We then make * the altered html available to the template as a variable in * sentences_text. * * Finally we select comments from the database for this node and make theme * available to the templates in comment_data */ function annotate_node_preprocess_node(&$variables) { $config = \Drupal::config('annotate_node.settings'); $attachments['#attached']['library'][] = 'annotate_node/annotate_node_annotator'; $annotation_content_type = $config->get('annotation_content_types'); // Check if we're on a content type that gets annotation, if not save ourselves some trouble. $ntype = ''; $node = \Drupal::routeMatch()->getParameter('node'); if ($node) { $ntype = $node->getType(); } if ($ntype != '') { if ($ntype === $annotation_content_type) { $string_separate = $config->get('string_separate'); $custom_length = $config->get('custom_length'); $variables['annotation_content_types'] = $annotation_content_type; $variables['string_separate'] = $string_separate; $variables['custom_length'] = $custom_length; $form = \Drupal::formBuilder()->getForm('Drupal\annotate_node\Form\CommentForm'); $variables['form'] = $form; $variables['ntype'] = $ntype; // Get the text from node, then checking what config was chosen. // Run through Xss::filter since we're using raw in twig. // Split into sentences or add a div before the first paragraph // Put splitted strings together for sentences config. //$content = $variables['content']; $text = ''; $text = Xss::filter($text); $text = $node->body->value; $asian_characters = FALSE; $correction_mode = FALSE; $correction_mode = $config->get('correction_mode'); // When typing the ckeEditor puts in the html spaces, so remove so split function works below. $text = str_replace(' ', ' ', $text); $variables['paragraphs_text'] = $text; $variables['#attached']['drupalSettings']['annotate_node']['asian_characters'] = FALSE; $variables['#attached']['drupalSettings']['annotate_node']['correction_mode'] = $correction_mode; $variables['module_path'] = drupal_get_path('module', 'annotate_node'); if ($string_separate != 'Paragraphs') { // We need to handle asian characters differently, preg_split can't handle multibyte characters. if (strpos($text, '。')) { mb_regex_encoding('UTF-8'); mb_internal_encoding("UTF-8"); $splitted_text = mb_split('。', $text); $asian_characters = TRUE; $variables['#attached']['drupalSettings']['annotate_node']['asian_characters'] = TRUE; } else { $splitted_text = preg_split('/(?<!Mr.|Mrs.|Dr.)(?<=[.?!])\s+/', $text, -1, PREG_SPLIT_NO_EMPTY); } $i = 0; if ($asian_characters == TRUE) { foreach ($splitted_text as &$sentence) { if ($i == 0) { $sentence = '<div class="sentence">' . $sentence . '。</p>'; } elseif ($i == count($splitted_string) - 1) { $sentence = $sentence . '</p>'; } else { $sentence = $sentence . '。</p>'; } $i++; } } else { foreach ($splitted_text as &$sentence) { if ($i == 0) { // Not closing the div is intentional, if you close it here it will close the main content div. $sentence = '<div class="sentence">' . $sentence . '</p>'; } else { $sentence = $sentence . '</p>'; } $i++; } } $sentences_text = implode(" ", $splitted_text); $variables['sentences_text'] = $sentences_text; } else { // Not closing the div is intentional, if you close it here it will close the main content div. $text = '<div class="sentence">' . $text . '</p>'; $variables['paragraphs_text'] = $text; } if ($node) { // Get comments from database. $cids = \Drupal::entityQuery('comment') ->condition('entity_id', $node->id()) ->condition('entity_type', 'node') ->sort('cid', 'DESC') ->execute(); $arrOfComments = []; foreach ($cids as $cid) { // $comments = []; $comment = Comment::load($cid); $comment_author_uid = $comment->getOwnerId(); $account = User::load($comment_author_uid); $comment_author_name = $account->getDisplayName(); $arrOfComments[] = [ 'cid' => $cid, 'uid' => $comment_author_uid, 'name' => $comment_author_name, 'subject' => Xss::filter($comment->get('subject')->value), 'body' => Xss::filter($comment->get('comment_body')->value), 'paragraph_number' => Xss::filter($comment->get('paragraph_number')->value), 'paragraph_sentence' => $comment->get('paragraph_sentence')->value, 'comment_date' => date("F jS Y h:i:s", $comment->get('created')->value), ]; // array_push($arrOfComments,$comments);. } $arrOfComments = array_reverse($arrOfComments); $variables['comment_data'] = $arrOfComments; global $base_url; $languagecode = \Drupal::languageManager()->getCurrentLanguage()->getId(); $variables['base_url'] = $base_url; $variables['languagecode'] = $languagecode . '/'; } } } } /** * Implements hook_theme(). * * If we're on a content type selected in the config, apply the custom template. * Important, if they chose a content type other than annotate node, they had to follow * instructions in the readMe file to copy and rename node--annotate-node.html.twig. */ function annotate_node_theme($existing, $type, $theme, $path) { $ntype = ''; $config = \Drupal::configFactory()->get('annotate_node.settings'); $annotation_content_type = $config->get('annotation_content_types'); if ($annotation_content_type) { // Check and make sure template file exists. If not using the annotate node content type, they // needed to follow instructions in the ReadMe to create their own. if (file_exists($path . '/templates/node--' . $annotation_content_type . '.html.twig')) { return [ 'node__' . $annotation_content_type => [ 'template' => 'node--' . $annotation_content_type, 'base hook' => 'node' ], ]; } else { // drupal_set_message(t($path. '/templates/node--'. $annotation_content_type . '.html.twig not found. Copy node--annotate-node.html.twig and rename to node--'. $annotation_content_type . '.html.twig in the annotate_node/templates folder. More instructions in the ReadMe file for Annotate Node.'), 'error');. \Drupal::messenger()->addError($path . '/templates/node--' . $annotation_content_type . '.html.twig not found. Copy node--annotate-node.html.twig and rename to node--' . $annotation_content_type . '.html.twig in the annotate_node/templates folder. More instructions in the ReadMe file for Annotate Node.'); } } else { return [ 'node__annotate_node' => [ 'template' => 'node--annotate_node', 'base hook' => 'node' ], ]; } } /** * Implements hook_page_attachments() * * If we're on a node of the content type selected in the config, add our library. */ function annotate_node_page_attachments(array &$attachments) { $ntype = ''; $node = \Drupal::routeMatch()->getParameter('node'); if ($node) { $ntype = $node->getType(); } $config = \Drupal::configFactory()->get('annotate_node.settings'); $annotation_content_type = $config->get('annotation_content_types'); if ($ntype != '') { if ($ntype === $annotation_content_type) { $attachments['#attached']['library'][] = 'annotate_node/annotate_node_annotator'; } } }