View source
<?php
use Drupal\Component\Utility\Html;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\ReplaceCommand;
use Drupal\Core\Cache\Cache;
use Drupal\Core\Render\Element;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Template\Attribute;
use Drupal\Core\Url;
use Drupal\field\Entity\FieldConfig;
use Drupal\field\Entity\FieldStorageConfig;
use Drupal\support_ticket\Entity\SupportTicket;
use Drupal\support_ticket\Entity\SupportTicketType;
use Drupal\support_ticket\SupportTicketInterface;
use Drupal\support_ticket\SupportTicketTypeInterface;
use Drupal\Core\Entity\Entity\EntityViewDisplay;
use Drupal\Core\Form\FormStateInterface;
use Drupal\comment\Entity\CommentType;
use Drupal\Component\Diff\Diff;
use Drupal\support_ticket\Controller\SupportTicketRevisionController;
use Symfony\Component\HttpFoundation\Request;
const SUPPORT_TICKET_NOT_PUBLISHED = 0;
const SUPPORT_TICKET_PUBLISHED = 1;
const SUPPORT_TICKET_NOT_LOCKED = 0;
const SUPPORT_TICKET_LOCKED = 1;
function support_ticket_help($route_name, RouteMatchInterface $route_match) {
switch ($route_name) {
case 'help.page.support_ticket':
$output = '';
$output .= '<h3>' . t('About') . '</h3>';
$output .= '<p>' . t('The Support Ticket module provides a support ticket types with optional time tracking.') . '</p>';
return $output;
}
}
function support_ticket_theme() {
return array(
'support_ticket' => array(
'render element' => 'elements',
),
'support_ticket_add_list' => array(
'variables' => array(
'content' => NULL,
),
),
'support_ticket_edit_form' => array(
'render element' => 'form',
),
'field__support_ticket__title' => array(
'base hook' => 'field',
),
'field__support_ticket__uid' => array(
'base hook' => 'field',
),
'field__support_ticket__created' => array(
'base hook' => 'field',
),
);
}
function support_ticket_type_get_types() {
return SupportTicketType::loadMultiple();
}
function support_ticket_type_get_names() {
return array_map(function ($bundle_info) {
return $bundle_info['label'];
}, \Drupal::entityManager()
->getBundleInfo('support_ticket'));
}
function support_ticket_get_type_label(SupportTicketInterface $support_ticket) {
$type = SupportTicketType::load($support_ticket
->bundle());
return $type ? $type
->label() : FALSE;
}
function support_ticket_type_get_description(SupportTicketTypeInterface $support_ticket_type) {
return $support_ticket_type
->getDescription();
}
function support_ticket_add_body_field(SupportTicketTypeInterface $type, $label = 'Ticket body') {
$field_storage = FieldStorageConfig::loadByName('support_ticket', 'body');
$field = FieldConfig::loadByName('support_ticket', $type
->id(), 'body');
if (empty($field)) {
$field = entity_create('field_config', array(
'field_storage' => $field_storage,
'bundle' => $type
->id(),
'label' => $label,
'settings' => array(
'display_summary' => TRUE,
),
));
$field
->save();
entity_get_form_display('support_ticket', $type
->id(), 'default')
->setComponent('body', array(
'type' => 'text_textarea_with_summary',
))
->save();
entity_get_display('support_ticket', $type
->id(), 'default')
->setComponent('body', array(
'label' => 'hidden',
'type' => 'text_default',
))
->save();
}
return $field;
}
function support_ticket_type_update_support_tickets($old_id, $new_id) {
return \Drupal::entityManager()
->getStorage('support_ticket')
->updateType($old_id, $new_id);
}
function support_ticket_load_multiple(array $stid = NULL, $reset = FALSE) {
if ($reset) {
\Drupal::entityManager()
->getStorage('support_ticket')
->resetCache($stid);
}
return SupportTicket::loadMultiple($stid);
}
function support_ticket_load($nid = NULL, $reset = FALSE) {
if ($reset) {
\Drupal::entityManager()
->getStorage('support_ticket')
->resetCache(array(
$nid,
));
}
return SupportTicket::load($nid);
}
function support_ticket_entity_update($support_ticket) {
if ($support_ticket instanceof SupportTicketInterface && !empty($support_ticket->original)) {
$type = SupportTicketType::load($support_ticket
->bundle());
if (!($field_name = _support_ticket_comment_diff_field($type
->id()))) {
return;
}
$field_storage = FieldStorageConfig::loadByName('support_ticket', $field_name);
$comment_type = $field_storage
->getSetting('comment_type');
if (!($diff_revision_changes_field = _support_ticket_comment_diff_revision_changes($type
->id(), $comment_type))) {
return;
}
$config = \Drupal::configFactory()
->get('support_ticket.settings');
$filter_format = $config
->get('support_ticket_type_settings.' . $type
->id() . '.filter_format');
$diffFormatter = \Drupal::service('diff.diff.formatter');
$dateFormatter = \Drupal::service('date.formatter');
$pluginManager = \Drupal::service('plugin.manager.diff.builder');
$diffEntityParser = \Drupal::service('diff.entity_parser');
$revisionController = new \Drupal\support_ticket\Controller\SupportTicketRevisionController($diffFormatter, $dateFormatter, $pluginManager, $diffEntityParser);
$original = $support_ticket->original;
$fields = $revisionController
->compareRevisions($original, $support_ticket);
$diff_rows = array();
foreach ($fields as $field) {
$field_label_row = '';
if (!empty($field['#name'])) {
$field_label_row = array(
'data' => t('Changes to %name', array(
'%name' => $field['#name'],
)),
'colspan' => 4,
'class' => array(
'field-name',
),
);
}
$field_diff_rows = _support_ticket_get_rows($field['#states']['raw']['#left'], $field['#states']['raw']['#right']);
if (!empty($field_diff_rows) && !empty($field_label_row)) {
$diff_rows[] = array(
$field_label_row,
);
}
$diff_rows = array_merge($diff_rows, $field_diff_rows);
}
$build['diff'] = array(
'#type' => 'table',
'#rows' => $diff_rows,
'#empty' => t('No visible changes'),
'#attributes' => array(
'class' => array(
'diff',
),
),
);
$diff_comment = array(
'cid' => NULL,
'uid' => \Drupal::currentUser()
->id(),
'entity_id' => $support_ticket
->id(),
'entity_type' => 'support_ticket',
'field_name' => $field_name,
'pid' => 0,
'comment_body' => array(
'value' => '<em>' . t('Automatically generated:') . '</em>',
'format' => $filter_format,
),
$diff_revision_changes_field => array(
'value' => \Drupal::service('renderer')
->renderPlain($build['diff']),
'format' => $filter_format,
),
'comment_type' => $comment_type,
);
if ($diff_revision_reference_field = _support_ticket_comment_diff_revision_reference($type
->id(), $comment_type)) {
$diff_comment[$diff_revision_reference_field] = $support_ticket
->getRevisionId();
}
entity_create('comment', $diff_comment)
->save();
}
}
function _support_ticket_get_rows($a, $b) {
$a = is_array($a) ? $a : explode("\n", $a);
$b = is_array($b) ? $b : explode("\n", $b);
if (count($a) == 1 && $a[0] == "") {
$a = array();
}
$line_stats = array(
'counter' => array(
'x' => 0,
'y' => 0,
),
'offset' => array(
'x' => 0,
'y' => 0,
),
);
$diff = new Diff($a, $b);
$diffFormatter = \Drupal::service('diff.formatter');
$diffFormatter->show_header = FALSE;
return $diffFormatter
->format($diff);
}
function support_ticket_revision_load($vid = NULL) {
return entity_revision_load('support_ticket', $vid);
}
function support_ticket_revision_delete($revision_id) {
entity_revision_delete('support_ticket', $revision_id);
}
function support_ticket_is_page(SupportTicketInterface $support_ticket) {
$route_match = \Drupal::routeMatch();
if ($route_match
->getRouteName() == 'entity.support_ticket.canonical') {
$page_support_ticket = $route_match
->getParameter('support_ticket');
}
return !empty($page_support_ticket) ? $page_support_ticket
->id() == $support_ticket
->id() : FALSE;
}
function template_preprocess_support_ticket_add_list(&$variables) {
$variables['types'] = array();
if (!empty($variables['content'])) {
foreach ($variables['content'] as $type) {
$variables['types'][$type
->id()] = array(
'type' => $type
->id(),
'add_link' => \Drupal::l($type
->label(), new Url('support_ticket.add', array(
'support_ticket_type' => $type
->id(),
))),
'description' => array(
'#markup' => $type
->getDescription(),
),
);
}
}
}
function support_ticket_preprocess_html(&$variables) {
if (($support_ticket = \Drupal::routeMatch()
->getParameter('support_ticket')) && $support_ticket instanceof SupportTicketInterface) {
$variables['support_ticket_type'] = $support_ticket
->getType();
}
}
function support_ticket_theme_suggestions_support_ticket(array $variables) {
$suggestions = array();
$support_ticket = $variables['elements']['#support_ticket'];
$sanitized_view_mode = strtr($variables['elements']['#view_mode'], '.', '_');
$suggestions[] = 'support_ticket__' . $sanitized_view_mode;
$suggestions[] = 'support_ticket__' . $support_ticket
->bundle();
$suggestions[] = 'support_ticket__' . $support_ticket
->bundle() . '__' . $sanitized_view_mode;
$suggestions[] = 'support_ticket__' . $support_ticket
->id();
$suggestions[] = 'support_ticket__' . $support_ticket
->id() . '__' . $sanitized_view_mode;
return $suggestions;
}
function template_preprocess_support_ticket(&$variables) {
$variables['view_mode'] = $variables['elements']['#view_mode'];
$variables['teaser'] = $variables['view_mode'] == 'teaser';
$variables['support_ticket'] = $variables['elements']['#support_ticket'];
$support_ticket = $variables['support_ticket'];
$variables['date'] = drupal_render($variables['elements']['created']);
unset($variables['elements']['created']);
$variables['author_name'] = drupal_render($variables['elements']['uid']);
unset($variables['elements']['uid']);
$variables['url'] = $support_ticket
->url('canonical', array(
'language' => $support_ticket
->language(),
));
$variables['label'] = $variables['elements']['title'];
unset($variables['elements']['title']);
$variables['page'] = $variables['view_mode'] == 'full' && support_ticket_is_page($support_ticket) || isset($support_ticket->in_preview) && in_array($support_ticket->preview_view_mode, array(
'full',
'default',
));
$variables += array(
'content' => array(),
);
foreach (Element::children($variables['elements']) as $key) {
$variables['content'][$key] = $variables['elements'][$key];
}
$support_ticket_type = $support_ticket->support_ticket_type->entity;
$variables['author_attributes'] = new Attribute();
$variables['display_submitted'] = $support_ticket_type
->displaySubmitted();
}
function support_ticket_get_recent($number = 10) {
$account = \Drupal::currentUser();
$query = \Drupal::entityQuery('support_ticket');
$access_query = \Drupal::entityQuery('support_ticket')
->condition('uid', $account
->id())
->condition('status', SUPPORT_TICKET_NOT_PUBLISHED);
if ($account
->hasPermission('view own unpublished support tickets') && ($own_unpublished = $access_query
->execute())) {
$query
->orConditionGroup()
->condition('status', SUPPORT_TICKET_PUBLISHED)
->condition('stid', $own_unpublished, 'IN');
}
else {
$query
->condition('status', SUPPORT_TICKET_PUBLISHED);
}
$stids = $query
->sort('changed', 'DESC')
->range(0, $number)
->addTag('support_ticket_access')
->execute();
$support_tickets = SupportTicket::loadMultiple($stids);
return $support_tickets ? $support_tickets : array();
}
function support_ticket_view(SupportTicketInterface $support_ticket, $view_mode = 'full', $langcode = NULL) {
return entity_view($support_ticket, $view_mode, $langcode);
}
function support_ticket_view_multiple($support_tickets, $view_mode = 'teaser', $langcode = NULL) {
return entity_view_multiple($support_tickets, $view_mode, $langcode);
}
function support_ticket_support_ticket_access(SupportTicketInterface $support_ticket, $op, $account) {
$type = $support_ticket
->bundle();
switch ($op) {
case 'create':
return AccessResult::allowedIfHasPermission($account, 'create ' . $type . ' ticket');
case 'update':
if ($account
->hasPermission('edit any ' . $type . ' ticket', $account)) {
return AccessResult::allowed()
->cachePerPermissions();
}
else {
return AccessResult::allowedIf($account
->hasPermission('edit own ' . $type . ' ticket', $account) && $account
->id() == $support_ticket
->getOwnerId())
->cachePerPermissions()
->cachePerUser()
->cacheUntilEntityChanges($support_ticket);
}
case 'delete':
if ($account
->hasPermission('delete any ' . $type . ' ticket', $account)) {
return AccessResult::allowed()
->cachePerPermissions();
}
else {
return AccessResult::allowedIf($account
->hasPermission('delete own ' . $type . ' ticket', $account) && $account
->id() == $support_ticket
->getOwnerId())
->cachePerPermissions()
->cachePerUser()
->cacheUntilEntityChanges($support_ticket);
}
default:
return AccessResult::neutral();
}
}
function support_ticket_form_support_ticket_type_edit_form_alter(&$form, FormStateInterface $form_state) {
$type = $form_state
->getFormObject()
->getEntity();
if ($type
->id()) {
$config = \Drupal::configFactory()
->get('support_ticket.settings');
$form['diff'] = array(
'#title' => t('Revision changes'),
'#type' => 'details',
'#group' => 'additional_settings',
'#tree' => FALSE,
);
$ajax_wrapper_id = Html::getUniqueId('ajax-wrapper');
$options = array();
$comment_field = $form_state
->getValue('comment_diff_field', _support_ticket_comment_diff_field($type
->id()));
$fields = \Drupal::entityManager()
->getFieldDefinitions('support_ticket', $type
->id());
foreach ($fields as $field) {
if ($field
->getType() == 'comment') {
$field_name = $field
->getName();
$field_label = $field
->getLabel();
$options[$field_name] = $field_label;
if ($field_name == $comment_field) {
$comment_field_label = $field_label;
}
}
}
$form['diff']['comment_field'] = array(
'#type' => 'container',
'#prefix' => '<div id="' . $ajax_wrapper_id . '">',
'#suffix' => '</div>',
'#attached' => [
'drupalSettings' => [
'ajax' => [
'edit-comment-diff-field' => [
'wrapper' => $ajax_wrapper_id,
],
],
],
],
);
$form['diff']['comment_field']['comment_diff_field'] = array(
'#type' => 'select',
'#title' => t('Comment field'),
'#description' => t('The comment field in the %type support ticket type where change comments will be written.', array(
'%type' => $type
->label(),
)),
'#options' => $options,
'#weight' => 12,
'#default_value' => $comment_field,
'#empty_value' => '',
'#ajax' => [
'callback' => '_support_ticket_comment_diff_ajax_callback',
'wrapper' => $ajax_wrapper_id,
'effect' => 'fade',
'selector' => '[data-drupal-selector="edit-comment-diff-field"]',
],
);
if (!empty($comment_field)) {
$revision_reference_options = $revision_changes_options = array();
$field_storage = FieldStorageConfig::loadByName('support_ticket', $comment_field);
$comment_type = $field_storage
->getSetting('comment_type');
$fields = \Drupal::entityManager()
->getFieldDefinitions('comment', $comment_type);
foreach ($fields as $field) {
if ($field
->getType() == 'integer' && ($revision_reference_field = $field
->getName()) != 'cid') {
$revision_reference_options[$revision_reference_field] = $field
->getLabel();
}
if ($field
->getType() == 'text_long' && ($revision_changes_field = $field
->getName())) {
$revision_changes_options[$revision_changes_field] = $field
->getLabel();
}
}
$form['diff']['comment_field']['comment_diff_revision_reference'] = array(
'#type' => 'select',
'#title' => t('Revision ID integer field'),
'#description' => t('Integer field in %comment_field_label comment field to store the revision ID that caused these revision changes.', array(
'%comment_field_label' => $comment_field_label,
)),
'#options' => $revision_reference_options,
'#weight' => 14,
'#default_value' => _support_ticket_comment_diff_revision_reference($type
->id(), $comment_type),
'#empty_value' => '',
);
$form['diff']['comment_field']['comment_diff_revision_changes'] = array(
'#type' => 'select',
'#title' => t('Revision changes long text field'),
'#description' => t('Long text field in %comment_field_label comment field to store the revision changes.', array(
'%comment_field_label' => $comment_field_label,
)),
'#options' => $revision_changes_options,
'#weight' => 14,
'#default_value' => _support_ticket_comment_diff_revision_changes($type
->id(), $comment_type),
'#empty_value' => '',
);
}
$options = array();
$formats = filter_formats();
foreach ($formats as $name => $format) {
$options[$format
->id()] = $name;
}
$form['diff']['filter_format'] = array(
'#type' => 'select',
'#title' => t('Filter format'),
'#description' => t('Which filter format to apply to revision changes.'),
'#options' => $options,
'#weight' => 16,
'#default_value' => $config
->get('support_ticket_type_settings.' . $type
->id() . '.filter_format'),
'#empty_value' => '',
);
$form['actions']['submit']['#submit'][] = 'support_ticket_form_support_ticket_type_form_submit';
}
}
function _support_ticket_comment_diff_ajax_callback(&$form, FormStateInterface &$form_state, Request $request) {
$renderer = \Drupal::service('renderer');
$response = new AjaxResponse();
$response
->setAttachments($form['diff']['comment_field']['#attached']);
$output = $renderer
->renderRoot($form['diff']['comment_field']);
return $response
->addCommand(new ReplaceCommand(NULL, $output));
}
function _support_ticket_comment_diff_field($entity_type) {
$config = \Drupal::configFactory()
->get('support_ticket.settings');
$default = $config
->get('support_ticket_type_settings.' . $entity_type . '.comment_diff_field');
if ($default === NULL) {
$fields = \Drupal::entityManager()
->getFieldDefinitions('support_ticket', $entity_type);
foreach ($fields as $field) {
if ($field
->getType() == 'comment') {
\Drupal::configFactory()
->getEditable('support_ticket.settings')
->set('support_ticket_type_settings.' . $entity_type . '.comment_diff_field', $default)
->save();
$default = $field
->getName();
break;
}
}
}
return $default;
}
function _support_ticket_comment_diff_revision_reference($entity_type, $comment_type) {
$config = \Drupal::configFactory()
->get('support_ticket.settings');
$default = $config
->get('support_ticket_type_settings.' . $entity_type . '.comment_diff_revision_reference');
if ($default === NULL) {
$fields = \Drupal::entityManager()
->getFieldDefinitions('comment', $comment_type);
foreach ($fields as $field) {
if ($field
->getType() == 'integer' && ($field_name = $field
->getName()) != 'cid') {
$default = $field_name;
\Drupal::configFactory()
->getEditable('support_ticket.settings')
->set('support_ticket_type_settings.' . $entity_type . '.comment_diff_revision_reference', $default)
->save();
break;
}
}
}
return $default;
}
function _support_ticket_comment_diff_revision_changes($entity_type, $comment_type) {
$config = \Drupal::configFactory()
->get('support_ticket.settings');
$default = $config
->get('support_ticket_type_settings.' . $entity_type . '.comment_diff_revision_changes');
if ($default === NULL) {
$fields = \Drupal::entityManager()
->getFieldDefinitions('comment', $comment_type);
foreach ($fields as $field) {
if ($field
->getType() == 'text_long' && ($field_name = $field
->getName()) != 'comment_body') {
$default = $field_name;
\Drupal::configFactory()
->getEditable('support_ticket.settings')
->set('support_ticket_type_settings.' . $entity_type . '.comment_diff_revision_changes', $default)
->save();
break;
}
}
}
return $default;
}
function support_ticket_form_support_ticket_type_form_submit(&$form, $form_state) {
$type = $form_state
->getFormObject()
->getEntity();
\Drupal::configFactory()
->getEditable('support_ticket.settings')
->set('support_ticket_type_settings.' . $type
->id() . '.filter_format', $form_state
->getValue('filter_format'))
->set('support_ticket_type_settings.' . $type
->id() . '.comment_diff_field', $form_state
->getValue('comment_diff_field'))
->set('support_ticket_type_settings.' . $type
->id() . '.comment_diff_revision_reference', $form_state
->getValue('comment_diff_revision_reference'))
->set('support_ticket_type_settings.' . $type
->id() . '.comment_diff_revision_changes', $form_state
->getValue('comment_diff_revision_changes'))
->save();
}