View source
<?php
namespace Drupal\webform;
use Drupal\Core\Cache\Cache;
use Drupal\Core\Config\Entity\ConfigEntityStorage;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\StreamWrapper\StreamWrapperInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
class WebformEntityStorage extends ConfigEntityStorage implements WebformEntityStorageInterface {
protected $database;
protected $entityTypeManager;
protected $fileSystem;
protected $totals;
public static function createInstance(ContainerInterface $container, EntityTypeInterface $entity_type) {
$instance = parent::createInstance($container, $entity_type);
$instance->database = $container
->get('database');
$instance->entityTypeManager = $container
->get('entity_type.manager');
$instance->fileSystem = $container
->get('file_system');
return $instance;
}
protected function doCreate(array $values) {
$entity = parent::doCreate($values);
$id = $entity
->id();
if ($id && $id === '_webform_ui_temp_form') {
$this
->setStaticCache([
$id => $entity,
]);
}
return $entity;
}
protected function doPostSave(EntityInterface $entity, $update) {
if ($update && $entity
->getAccessRules() !== $entity->original
->getAccessRules()) {
$cache_tags = $this->entityTypeManager
->getDefinition('webform_submission')
->getListCacheTags();
Cache::invalidateTags($cache_tags);
}
parent::doPostSave($entity, $update);
}
public function save(EntityInterface $entity) {
$return = parent::save($entity);
if ($return === SAVED_NEW) {
$this->database
->insert('webform')
->fields([
'webform_id' => $entity
->id(),
'next_serial' => 1,
])
->execute();
}
return $return;
}
public function delete(array $entities) {
parent::delete($entities);
if (!$entities) {
return;
}
$webform_ids = [];
foreach ($entities as $entity) {
$webform_ids[] = $entity
->id();
}
$this->database
->delete('webform')
->condition('webform_id', $webform_ids, 'IN')
->execute();
foreach ($entities as $entity) {
$stream_wrappers = array_keys(\Drupal::service('stream_wrapper_manager')
->getNames(StreamWrapperInterface::WRITE_VISIBLE));
foreach ($stream_wrappers as $stream_wrapper) {
$file_directory = $stream_wrapper . '://webform/' . $entity
->id();
if (file_exists($file_directory)) {
$files = $this->fileSystem
->scanDirectory($file_directory, '/^signature-.*/');
foreach (array_keys($files) as $uri) {
$this->fileSystem
->delete($uri);
}
if (empty($this->fileSystem
->scanDirectory($file_directory, '/.*/'))) {
$this->fileSystem
->deleteRecursive($file_directory);
}
}
}
}
}
public function getCategories($template = NULL) {
$webforms = $this
->loadMultiple();
$categories = [];
foreach ($webforms as $webform) {
if ($template !== NULL && $webform
->get('template') !== $template) {
continue;
}
if ($category = $webform
->get('category')) {
$categories[$category] = $category;
}
}
ksort($categories);
return $categories;
}
public function getOptions($template = NULL) {
$webforms = $this
->loadMultiple();
@uasort($webforms, [
$this->entityType
->getClass(),
'sort',
]);
$uncategorized_options = [];
$categorized_options = [];
foreach ($webforms as $id => $webform) {
if ($template !== NULL && $webform
->get('template') !== $template) {
continue;
}
if ($webform
->isArchived()) {
continue;
}
if ($category = $webform
->get('category')) {
$categorized_options[$category][$id] = $webform
->label();
}
else {
$uncategorized_options[$id] = $webform
->label();
}
}
$options = $uncategorized_options;
foreach ($categorized_options as $optgroup => $optgroup_options) {
if (isset($options[$optgroup])) {
$options[$optgroup] = [
$optgroup => $options[$optgroup],
] + $optgroup_options;
asort($options[$optgroup]);
}
else {
$options[$optgroup] = $optgroup_options;
}
}
return $options;
}
public function getNextSerial(WebformInterface $webform) {
return $this->database
->select('webform', 'w')
->fields('w', [
'next_serial',
])
->condition('webform_id', $webform
->id())
->execute()
->fetchField();
}
public function setNextSerial(WebformInterface $webform, $next_serial = 1) {
$this->database
->update('webform')
->fields([
'next_serial' => $next_serial,
])
->condition('webform_id', $webform
->id())
->execute();
}
public function getSerial(WebformInterface $webform) {
$transaction = $this->database
->startTransaction();
$next_serial = $this->database
->select('webform', 'w')
->forUpdate()
->fields('w', [
'next_serial',
])
->condition('webform_id', $webform
->id())
->execute()
->fetchField();
$next_serial = max($next_serial, $this
->getMaxSerial($webform));
$this->database
->update('webform')
->fields([
'next_serial' => $next_serial + 1,
])
->condition('webform_id', $webform
->id())
->execute();
return $next_serial;
}
public function getMaxSerial(WebformInterface $webform) {
$query = $this->database
->select('webform_submission');
$query
->condition('webform_id', $webform
->id());
$query
->addExpression('MAX(serial)');
return $query
->execute()
->fetchField() + 1;
}
public function getTotalNumberOfResults($webform_id = NULL) {
if (!isset($this->totals)) {
$query = $this->database
->select('webform_submission', 'ws');
$query
->fields('ws', [
'webform_id',
]);
$query
->addExpression('COUNT(sid)', 'results');
$query
->groupBy('webform_id');
$this->totals = array_map('intval', $query
->execute()
->fetchAllKeyed());
}
if ($webform_id) {
return isset($this->totals[$webform_id]) ? $this->totals[$webform_id] : 0;
}
else {
return $this->totals;
}
}
}