safedelete-1.0.0/src/Form/SafedeleteSettingsForm.php
src/Form/SafedeleteSettingsForm.php
<?php
namespace Drupal\safedelete\Form;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Database\Connection;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\File\FileSystemInterface;
use Drupal\Core\Form\ConfigFormBase;
use Drupal\Core\Form\FormStateInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Configure safedelete settings for this site.
*/
class SafedeleteSettingsForm extends ConfigFormBase {
/**
* The entity type manager service.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* The database connection service.
*
* @var \Drupal\Core\Database\Connection
*/
protected $database;
/**
* The configuration factory service.
*
* @var \Drupal\Core\Config\ConfigFactoryInterface
*/
protected $configFactory;
/**
* The file system service.
*
* @var \Drupal\Core\File\FileSystemInterface
*/
protected $fileSystem;
/**
* Constructs a new SafedeleteSettingsForm object.
*
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* The entity type manager service.
* @param \Drupal\Core\Database\Connection $database
* The database connection service.
* @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
* The configuration factory service.
* @param \Drupal\Core\File\FileSystemInterface $file_system
* The file system service.
*/
public function __construct(EntityTypeManagerInterface $entity_type_manager,
Connection $database,
ConfigFactoryInterface $config_factory,
FileSystemInterface $file_system) {
$this->entityTypeManager = $entity_type_manager;
$this->database = $database;
$this->configFactory = $config_factory;
$this->fileSystem = $file_system;
}
/**
* Container create method.
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('entity_type.manager'),
$container->get('database'),
$container->get('config.factory'),
$container->get('file_system')
);
}
/**
* {@inheritdoc}
*/
public function getFormId() {
return 'safedelete_settings';
}
/**
* {@inheritdoc}
*/
protected function getEditableConfigNames() {
return [
'safedelete.settings',
];
}
/**
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state) {
if (!$this->entityTypeManager->hasDefinition('node_type')) {
throw new \RuntimeException($this->t('The "node" module must be enabled to use this form.'));
}
$config = $this->config('safedelete.settings');
$node_types = $this->entityTypeManager->getStorage('node_type')->loadMultiple();
if (empty($node_types)) {
return NULL;
}
$options = [];
$first_bundle = '';
foreach ($node_types as $node_type_test => $type_test) {
$first_bundle = $node_type_test;
break;
}
foreach ($node_types as $node_type => $type) {
$options[$node_type] = $type->get('name');
}
$form['bundle'] = [
'#title' => t('Bundle'),
'#type' => 'checkboxes',
'#description' => t('Check the content types that you wish to add restriction on deletion'),
'#options' => $options,
'#default_value' => (!empty($config->get('bundle'))) ? $config->get('bundle') : [$first_bundle],
];
$form['safearchive'] = [
'#title' => $this->t('Safe archive'),
'#type' => 'checkbox',
'#description' => $this->t('This option will enable safe archive validation (future option, not yet implemented)'),
'#default_value' => (!empty($config->get('safearchive'))) ? $config->get('safearchive') : TRUE,
'#disabled' => TRUE,
];
$form['safeanchors'] = [
'#title' => $this->t('Safe Anchors'),
'#type' => 'checkbox',
'#description' => $this->t('This option will enable expected url link reference checks that will perform form validation on anchors to make sure internal references are are using linkit.'),
'#default_value' => (!empty($config->get('safeanchors'))) ? $config->get('safeanchors') : FALSE,
'#disabled' => FALSE,
];
$form['safeenableotherbaseurl'] = [
'#title' => $this->t('Enable Verify Other Base Url'),
'#type' => 'checkbox',
'#description' => $this->t('Enable or disable.'),
'#default_value' => (!empty($config->get('safeenableotherbaseurl'))) ? $config->get('safeenableotherbaseurl') : FALSE,
'#disabled' => FALSE,
];
$form['safebaseurlother'] = [
'#title' => $this->t('Safe Base Url Other'),
'#type' => 'textfield',
'#description' => $this->t('This option will allow you to consider this url as an internal to this application host baseurl for linkit reference checks. Suggested value: https://hostname/prefix or https://hostname/ if you\'re not using a path prefix.'),
'#default_value' => (!empty($config->get('safebaseurlother'))) ? $config->get('safebaseurlother') : '',
'#states' => [
'visible' => [
[':input[name="safeenableotherbaseurl"]' => ['checked' => TRUE]],
]
]
];
$form['safeenableotherbaseurl2'] = [
'#title' => $this->t('Enable Verify Other Base Url 2'),
'#type' => 'checkbox',
'#description' => $this->t('Enable or disable.'),
'#default_value' => (bool) $config->get('safeenableotherbaseurl2'),
'#disabled' => FALSE,
];
$form['safebaseurlother2'] = [
'#title' => $this->t('Safe Base Url Other 2'),
'#type' => 'textfield',
'#description' => $this->t('This option will allow you to consider this url as an internal to this application host baseurl for linkit reference checks. Suggested value: https://hostname/prefix2 or https://hostname/ if you\'re not using a path prefix.'),
'#default_value' => (!empty($config->get('safebaseurlother2'))) ? $config->get('safebaseurlother2') : '',
'#states' => [
'visible' => [
[':input[name="safeenableotherbaseurl2"]' => ['checked' => TRUE]],
]
]
];
$form['safeenableprefix'] = [
'#title' => $this->t('Enable Verify Other Base Prefix'),
'#type' => 'checkbox',
'#description' => $this->t('Enable or disable.'),
'#default_value' => (!empty($config->get('safeenableprefix'))) ? $config->get('safeenableprefix') : FALSE,
'#disabled' => FALSE,
];
$form['safeprefix'] = [
'#title' => $this->t('Safe Base Relative Prefix'),
'#type' => 'textfield',
'#description' => $this->t('This option will allow you to consider this prefix as an internal to this application host for relative links.'),
'#default_value' => (!empty($config->get('safeprefix'))) ? $config->get('safeprefix') : '',
'#states' => [
'visible' => [
[':input[name="safeenableprefix"]' => ['checked' => TRUE]],
]
]
];
$form['delete_button'] = [
'#title' => $this->t('Show delete button'),
'#type' => 'checkbox',
'#description' => $this->t('This option will show delete button in the file delete form page, even when the file is associated with entities'),
'#default_value' => (!empty($config->get('delete_button'))) ? $config->get('delete_button') : FALSE,
];
$form['limit'] = [
'#title' => $this->t('Number of entities list to show in node delete form'),
'#type' => 'textfield',
'#description' => $this->t("Number of entities list to show in node delete form"),
'#size' => 2,
'#default_value' => (!empty($config->get('limit'))) ? $config->get('limit') : FALSE,
];
/* the definition of the orphaned page */
$form['orphanedpagedefinition'] = [
'#title' => $this->t('The definition of the orphaned pages'),
'#type' => 'checkboxes',
'#description' => $this->t('Check the content types that you wish to consider as the orphaned pages'),
'#options' => $options,
'#default_value' => (!empty($config->get('orphanedpagedefinition'))) ? $config->get('orphanedpagedefinition') : [$first_bundle],
];
/* the without menu link definition of the orphaned page */
$form['orphanedpagewithoutmenulink'] = [
'#title' => $this->t('Choose one type to include menu link checking in the orphaned pages logic'),
'#type' => 'radios',
'#description' => $this->t('Check the content type that you wish to consider as the orphaned pages even if it is only a menu link referencing the content'),
'#options' => $options,
'#default_value' => (!empty($config->get('orphanedpagewithoutmenulink'))) ? $config->get('orphanedpagewithoutmenulink') : $first_bundle,
];
$form['exceptionofnodes'] = [
'#title' => $this->t('Please input the node ids into the exception list of the orphaned pages'),
'#type' => 'textfield',
'#size' => 160,
'#maxlength' => 500,
'#description' => $this->t('Enter node ids and separate them by comma, e.g. "12, 34, 56".'),
'#default_value' => $config->get('exceptionofnodes') ?: '',
];
/* Enforce the bulk publish verification to check page published */
$form['enforce_bulk_publish_verify_checkpagepublished'] = [
'#title' => $this->t('Enforce the bulk publish verification to check if the linked pages are published'),
'#type' => 'checkbox',
'#description' => $this->t('Check if the linked pages are published'),
'#default_value' => (bool) $config->get('enforce_bulk_publish_verify_checkpagepublished'),
];
$form['check_published_only'] = [
'#title' => $this->t('Check only published parent pages'),
'#type' => 'checkbox',
'#default_value' => (bool) $config->get('check_published_only'),
'#description' => $this->t('Links from non-published pages are ignored'),
];
// Buttons are only required for testing and debugging reasons.
$orphdescription = '<p>' . $this->t('The section will run checking orphaned nodes proccess.');
$form['clear'] = [
'#type' => 'details',
'#title' => $this->t('Maintenance'),
'#description' => $orphdescription,
'#open' => FALSE,
];
$form['clear']['orphanedpage_check'] = [
'#type' => 'submit',
'#value' => $this->t('Check orphaned nodes'),
'#submit' => ['::submitForm', '::submitOrphanedpageCheck'],
];
return parent::buildForm($form, $form_state);
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
$this->config('safedelete.settings')
->set('bundle', $form_state->getValue('bundle'))
->set('delete_button', $form_state->getValue('delete_button'))
->set('exceptionofnodes', $form_state->getValue('exceptionofnodes'))
->set('limit', $form_state->getValue('limit'))
->set('orphanedpagedefinition', $form_state->getValue('orphanedpagedefinition'))
->set('orphanedpagewithoutmenulink', $form_state->getValue('orphanedpagewithoutmenulink'))
->set('safearchive', $form_state->getValue('safearchive'))
->set('safeanchors', $form_state->getValue('safeanchors'))
->set('safebaseurlother', $form_state->getValue('safebaseurlother'))
->set('safeenableotherbaseurl', $form_state->getValue('safeenableotherbaseurl'))
->set('safebaseurlother2', $form_state->getValue('safebaseurlother2'))
->set('safeenableotherbaseurl2', $form_state->getValue('safeenableotherbaseurl2'))
->set('safeenableprefix', $form_state->getValue('safeenableprefix'))
->set('safeprefix', $form_state->getValue('safeprefix'))
->set('enforce_bulk_publish_verify_checkpagepublished', $form_state->getValue('enforce_bulk_publish_verify_checkpagepublished'))
->set('check_published_only', $form_state->getValue('check_published_only'))
->save();
parent::submitForm($form, $form_state);
}
/**
* Check all links.
*/
public function submitOrphanedpageCheck(array &$form, FormStateInterface $form_state) {
$batch = [];
$batch = $this->generateBatch();
batch_set($batch);
}
/**
* Create a batch.
*/
public function generateBatch() {
$reporteddate = '';
$orphanedpages_results = [];
$filedirectory = 'private://orphaned_pages_files/';
$database = $this->database;
$node_types = $this->entityTypeManager->getStorage('node_type')->loadMultiple();
if (empty($node_types)) {
return NULL;
}
// A safe default value is required.
$first_bundle = '';
foreach ($node_types as $node_type_test => $type_test) {
// A safe default value.
$first_bundle = $node_type_test;
break;
}
$exceptidsconfig = $this->configFactory->get('safedelete.settings')->get('exceptionofnodes');
$exceptionarray = explode(',', $exceptidsconfig);
if (empty($exceptionarray)) {
$exceptionarray = [];
}
$super_type = $this->configFactory->get('safedelete.settings')->get('orphanedpagewithoutmenulink');
if (empty($super_type)) {
// Use the safe default value.
$super_type = $first_bundle;
}
$defconfig = $this->configFactory->get('safedelete.settings')->get('orphanedpagedefinition');
if (empty($defconfig)) {
// Use the safe default value.
$defconfig = [];
$defconfig[] = $first_bundle;
}
$query = $this->entityTypeManager->getStorage('node')->getQuery();
$query->accessCheck(FALSE)
->condition('type', $defconfig, 'IN');
$nodeids = $query->accessCheck(FALSE)
->sort('nid', 'ASC')->execute();
// Create an index array for Patch API.
$arraryofNodeIds = [];
$indx = 0;
foreach ($nodeids as $nid) {
$arraryofNodeIds[$indx] = $nid;
$indx = $indx + 1;
}
$arrayoftypes = [];
$count = 0;
foreach ($defconfig as $type) {
if (strlen($type) > 1) {
$count = $count + 1;
$arrayoftypes[$count] = $type;
}
}
$directoryexists = $this->fileSystem->prepareDirectory($filedirectory);
if (!$directoryexists) {
$this->fileSystem->mkdir($filedirectory);
}
else {
// Clean up old json files before new json files are generated.
$files = $this->fileSystem->scanDirectory($filedirectory, '/.json/');
$filearraynid = [];
foreach ($files as $file) {
$fileuri = $file->uri;
$this->fileSystem->deleteRecursive($fileuri);
}
}
$num_operations = count($arraryofNodeIds);
$operations = [];
// $i = 0;
for ($i = 0; $i < $num_operations; $i++) {
if (isset($arraryofNodeIds[$i])) {
$nid = (int) $arraryofNodeIds[$i];
$operations[] = [
'batch_ProcessNodes_Op',
[
$i + 1,
$this->t('(Operation @operation)', ['@operation' => $i]),
$nid,
$filedirectory,
$exceptionarray,
$super_type,
],
];
}
}
$batch = [
'title' => $this->t('Validating orphaned nodes process will run @num operations', ['@num' => $num_operations]),
'operations' => $operations,
'finished' => 'batch_ProcessNodes_finished',
];
return $batch;
}
}
