Skip to content

Instantly share code, notes, and snippets.

@syammohanmp
Last active December 16, 2022 13:34
Show Gist options
  • Save syammohanmp/a8abf00c4bb37a58e56ac3aeb6ce84b1 to your computer and use it in GitHub Desktop.
Save syammohanmp/a8abf00c4bb37a58e56ac3aeb6ce84b1 to your computer and use it in GitHub Desktop.
Scheduled Ads Drupal settings form.
<?php
namespace Drupal\sample_module\Plugin\Block;
use Drupal\Core\Block\BlockBase;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\sample_module\Form\SampleAdsSettingsForm;
/**
* Scheduled ads block.
*
* @Block(
* id = "block_sample_module_scheduled_ads",
* admin_label = @Translation("Scheduled Ads"),
* category = @Translation("Custom")
* )
*/
class SampleScheduledAds extends BlockBase implements ContainerFactoryPluginInterface {
/**
* Config Factory.
*
* @var \Drupal\Core\Config\ConfigFactoryInterface
*/
protected $configFactory;
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
$static = new static($configuration, $plugin_id, $plugin_definition);
$static->setConfigFactory($container->get('config.factory'));
return $static;
}
/**
* Set the config factory.
*
* @param \Drupal\Core\Config\ConfigFactoryInterface $configFactory
* Config Factory.
*/
protected function setConfigFactory(ConfigFactoryInterface $configFactory) {
$this->configFactory = $configFactory;
}
/**
* {@inheritdoc}
*/
public function blockForm($form, FormStateInterface $form_state) {
$form = parent::blockForm($form, $form_state);
// Get block configuration.
$config = $this->getConfiguration();
// Get scheduled ads configuration.
$ads_config = $this->configFactory->getEditable(SampleAdsSettingsForm::SETTINGS);
$items = $ads_config->get('sample_module.ads.items');
if (!empty($items)) {
foreach ($items as $key => $item) {
$option[$key] = $item['title'];
}
}
$form['scheduled_ad'] = [
'#type' => 'select',
'#title' => $this->t('Scheduled ads'),
'#description' => $this->t('Listing scheduled ads.'),
'#default_value' => $config['scheduled_ad'],
'#options' => $option,
"#empty_option" => $this->t('- Select -'),
'#required' => TRUE,
];
return $form;
}
/**
* {@inheritdoc}
*/
public function blockSubmit($form, FormStateInterface $form_state) {
parent::blockSubmit($form, $form_state);
$values = $form_state->getValues();
$this->setConfigurationValue('scheduled_ad', $values['scheduled_ad']);
}
/**
* {@inheritdoc}
*/
public function build() {
// Get block configuration.
$config = $this->getConfiguration();
// Get scheduled ads configuration.
$ads_config = $this->configFactory->getEditable(SampleAdsSettingsForm::SETTINGS);
$output = ['#markup' => ''];
$items = $ads_config->get('sample_module.ads.items');
$item_index = $config['scheduled_ad'];
if (!empty($items) && !empty($items[$item_index])) {
if ($this->isValidAd($items[$item_index])) {
$output['#markup'] = $items[$item_index]['ads_body'];
}
}
return $output;
}
/**
* Check whether today is weekend or not.
*/
public function isTodayWeekend() {
return in_array(date("l"), ["Saturday", "Sunday"]);
}
/**
* Check if the given item is valid.
*
* @param array $item
* Ad Item.
*/
public function isValidAd(array $item) {
if (empty($item['ads_type'])) {
return FALSE;
}
// Check daily, week_days and weekend ads.
if ($item['ads_type'] === 'daily' || $item['ads_type'] === 'week_days' || $item['ads_type'] === 'weekend_days') {
if (!empty($item['schedule']['time']['start']) && !empty($item['schedule']['time']['end'])) {
$starts_on = strtotime($item['schedule']['time']['start']);
$ends_on = strtotime($item['schedule']['time']['end']);
$time_now = strtotime(date('h:i:s A'));
if ($time_now >= $starts_on && $time_now <= $ends_on) {
if ($item['ads_type'] === 'daily' ||
($item['ads_type'] === 'week_days' && !$this->isTodayWeekend()) ||
($item['ads_type'] === 'weekend_days' && $this->isTodayWeekend())
) {
return TRUE;
}
}
}
}
// Check between dates and custom days.
if ($item['ads_type'] === 'between_dates' || $item['ads_type'] === 'custom') {
if (!empty($item['between_dates']['start']) && !empty($item['between_dates']['end'])) {
$btw_starts_on = strtotime($item['between_dates']['start']);
$btw_ends_on = strtotime($item['between_dates']['end']);
$datetime_now = strtotime(date('Y-m-d h:i:s A'));
if ($datetime_now >= $btw_starts_on && $datetime_now <= $btw_ends_on) {
if ($item['ads_type'] === 'between_dates') {
return TRUE;
}
elseif ($item['ads_type'] === 'custom') {
$today = strtolower(date('l'));
if ($item['dates_fieldset'][$today]['enabled'] === 1) {
if (!empty($item['dates_fieldset'][$today]['time']['start']) && !empty($item['dates_fieldset'][$today]['time']['end'])) {
$time_starts_on = strtotime($item['dates_fieldset'][$today]['time']['start']);
$time_ends_on = strtotime($item['dates_fieldset'][$today]['time']['end']);
$time_now = strtotime(date('h:i:s A'));
if ($time_now >= $time_starts_on && $time_now <= $time_ends_on) {
return TRUE;
}
}
}
}
}
}
}
return FALSE;
}
}
<?php
namespace Drupal\sample_module\Form;
use Drupal\Core\Form\ConfigFormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Datetime\DrupalDateTime;
/**
* Configure Sample ads settings.
*/
class SampleAdsSettingsForm extends ConfigFormBase {
/**
* Config settings.
*
* @var string
*/
const SETTINGS = 'sample_module.ads.settings';
/**
* {@inheritdoc}
*/
public function getFormId() {
return 'sample_module_admin_ads_settings';
}
/**
* {@inheritdoc}
*/
protected function getEditableConfigNames() {
return [
static::SETTINGS,
];
}
/**
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state) {
$config = $this->configFactory->getEditable(static::SETTINGS);
$days = [
'monday' => 'Monday',
'tuesday' => 'Tuesday',
'wednesday' => 'Wednesday',
'thursday' => 'Thursday',
'friday' => 'Friday',
'saturday' => 'Saturday',
'sunday' => 'Sunday',
];
$item_indexes = $form_state->get('item_indexes');
if (empty($item_indexes)) {
$item_indexes = ['item_' . time()];
$items = $config->get('sample_module.ads.items');
if (!empty($items)) {
$item_indexes = array_keys($items);
}
$form_state->set('item_indexes', $item_indexes);
}
$form['#tree'] = TRUE;
$form['items'] = [
'#type' => 'container',
'#prefix' => '<div id="items-row-wrapper">',
'#suffix' => '</div>',
];
$i = 1;
foreach ($item_indexes as $index) {
$settings_key = 'sample_module.ads.items.' . $index;
if ($config->get($settings_key . '.title')) {
$title = $config->get($settings_key . '.title');
}
else {
$title = $this->t('New Item');
}
$form['items'][$index] = [
'#type' => 'details',
'#title' => $title,
];
$form['items'][$index]['title'] = [
'#type' => 'textfield',
'#title' => $this->t('Title'),
'#default_value' => $config->get($settings_key . '.title'),
];
$form['items'][$index]['ads_body'] = [
'#type' => 'textarea',
'#title' => $this->t('Ads Body'),
'#default_value' => $config->get($settings_key . '.ads_body'),
];
$form['items'][$index]['ads_type'] = [
'#type' => 'select',
'#title' => $this->t('Ads type'),
'#options' => [
'daily' => $this->t('Daily'),
'week_days' => $this->t('Week days'),
'weekend_days' => $this->t('Weekend days'),
'between_dates' => $this->t('Between dates'),
'custom' => $this->t('custom'),
],
"#empty_option" => $this->t('- Select -'),
'#default_value' => $config->get($settings_key . '.ads_type'),
];
$form['items'][$index]['schedule']['time'] = [
'#type' => 'container',
'#attributes' => [
'class' => [
'container-inline',
],
],
'#states' => [
'invisible' => [
':input[name="items[' . $index . '][ads_type]"]' => [
['value' => 'custom'],
['value' => 'between_dates'],
],
],
],
];
$form['items'][$index]['schedule']['time']['start'] = [
'#type' => 'datetime',
'#title' => $this->t('Starts on'),
'#title_display' => 'invisible',
'#date_date_element' => 'none',
];
if ($config->get($settings_key . '.schedule.time.start')) {
$form['items'][$index]['schedule']['time']['start']['#default_value'] = DrupalDateTime::createFromTimestamp(
strtotime($config->get($settings_key . '.schedule.time.start')));
}
$form['items'][$index]['schedule']['time']['end'] = [
'#type' => 'datetime',
'#title' => $this->t('Ends on'),
'#title_display' => 'invisible',
'#date_date_element' => 'none',
];
if ($config->get($settings_key . '.schedule.time.end')) {
$form['items'][$index]['schedule']['time']['end']['#default_value'] = DrupalDateTime::createFromTimestamp(
strtotime($config->get($settings_key . '.schedule.time.end')));
}
$form['items'][$index]['between_dates'] = [
'#type' => 'container',
'#attributes' => [
'class' => [
'container-inline',
],
],
'#states' => [
'visible' => [
':input[name="items[' . $index . '][ads_type]"]' => [
['value' => 'custom'],
['value' => 'between_dates'],
],
],
],
];
$form['items'][$index]['between_dates']['start'] = [
'#type' => 'datetime',
'#title' => $this->t('Starts on'),
'#title_display' => 'invisible',
];
if ($config->get($settings_key . '.between_dates.start')) {
$form['items'][$index]['between_dates']['start']['#default_value'] = DrupalDateTime::createFromTimestamp(
strtotime($config->get($settings_key . '.between_dates.start')));
}
$form['items'][$index]['between_dates']['end'] = [
'#type' => 'datetime',
'#title' => $this->t('Ends on'),
'#title_display' => 'invisible',
];
if ($config->get($settings_key . '.between_dates.end')) {
$form['items'][$index]['between_dates']['end']['#default_value'] = DrupalDateTime::createFromTimestamp(
strtotime($config->get($settings_key . '.between_dates.end')));
}
$form['items'][$index]['dates_fieldset'] = [
'#type' => 'fieldset',
'#states' => [
'visible' => [
':input[name="items[' . $index . '][ads_type]"]' => ['value' => 'custom'],
],
],
];
foreach ($days as $day_index => $day) {
$day_settings_key = $settings_key . '.dates_fieldset.' . $day_index;
$form['items'][$index]['dates_fieldset'][$day_index]['enabled'] = [
'#type' => 'checkbox',
'#title' => $day,
'#default_value' => $config->get($day_settings_key . '.enabled'),
];
$form['items'][$index]['dates_fieldset'][$day_index]['time'] = [
'#type' => 'container',
'#attributes' => [
'class' => [
'container-inline',
],
],
];
$form['items'][$index]['dates_fieldset'][$day_index]['time']['start'] = [
'#type' => 'datetime',
'#title' => $this->t('Starts on'),
'#title_display' => 'invisible',
'#date_date_element' => 'none',
];
if ($config->get($day_settings_key . '.time.start')) {
$form['items'][$index]['dates_fieldset'][$day_index]['time']['start']['#default_value'] = DrupalDateTime::createFromTimestamp(
strtotime($config->get($day_settings_key . '.time.start')));
}
$form['items'][$index]['dates_fieldset'][$day_index]['time']['end'] = [
'#type' => 'datetime',
'#title' => $this->t('Ends on'),
'#title_display' => 'invisible',
'#date_date_element' => 'none',
];
if ($config->get($day_settings_key . '.time.end')) {
$form['items'][$index]['dates_fieldset'][$day_index]['time']['end']['#default_value'] = DrupalDateTime::createFromTimestamp(
strtotime($config->get($day_settings_key . '.time.end')));
}
}
if ($i > 2) {
$form['items'][$index]['actions']['remove'] = [
'#type' => 'submit',
'#value' => $this->t('Remove'),
'#name' => 'op_remove_' . $index,
'#submit' => ['::removeCallback'],
'#limit_validation_errors' => [],
'#ajax' => [
'callback' => '::addmoreCallback',
'wrapper' => 'items-row-wrapper',
],
];
}
}
$form['actions']['add_row'] = [
'#type' => 'submit',
'#value' => $this->t('Add more'),
'#submit' => ['::addOne'],
'#limit_validation_errors' => [],
'#ajax' => [
'callback' => '::addMoreCallback',
'wrapper' => 'items-row-wrapper',
],
];
$form_state->setCached(FALSE);
return parent::buildForm($form, $form_state);
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
$config = $this->configFactory->getEditable(static::SETTINGS);
// Remove old settings.
$config->delete();
$items = $form_state->getValue('items');
foreach ($items as $key => $item) {
$settings_key = 'sample_module.ads.items.' . $key;
$config->set($settings_key . '.title', $item['title']);
$config->set($settings_key . '.ads_body', $item['ads_body']);
$config->set($settings_key . '.ads_type', $item['ads_type']);
if (!empty($item['schedule']['time']['start'])) {
$config->set($settings_key . '.schedule.time.start', $item['schedule']['time']['start']->format('h:i:s A'));
}
if (!empty($item['schedule']['time']['end'])) {
$config->set($settings_key . '.schedule.time.end', $item['schedule']['time']['end']->format('h:i:s A'));
}
if (!empty($item['between_dates']['start'])) {
$config->set($settings_key . '.between_dates.start', $item['between_dates']['start']->format('Y-m-d h:i:s A'));
}
if (!empty($item['between_dates']['end'])) {
$config->set($settings_key . '.between_dates.end', $item['between_dates']['end']->format('Y-m-d h:i:s A'));
}
if ($item['ads_type'] == 'custom') {
foreach ($item['dates_fieldset'] as $day_index => $day_item) {
$day_settings_key = $settings_key . '.dates_fieldset.' . $day_index;
$config->set($day_settings_key . '.enabled', $day_item['enabled']);
if (!empty($day_item['time']['start'])) {
$config->set($day_settings_key . '.time.start', $day_item['time']['start']->format('h:i:s A'));
}
if (!empty($day_item['time']['end'])) {
$config->set($day_settings_key . '.time.end', $day_item['time']['end']->format('h:i:s A'));
}
}
}
}
$config->save();
parent::submitForm($form, $form_state);
}
/**
* Callback for add-more button.
*/
public function addMoreCallback(array &$form, FormStateInterface $form_state) {
return $form['items'];
}
/**
* Submit handler for the "add-one-more" button.
*/
public function addOne(array &$form, FormStateInterface $form_state) {
$item_indexes = $form_state->get('item_indexes');
$item_indexes[] = 'item_' . time();
$form_state->set('item_indexes', $item_indexes);
$form_state->setRebuild();
}
/**
* Submit handler for the "remove one" button.
*/
public function removeCallback(array &$form, FormStateInterface $form_state) {
$item_indexes = $form_state->get('item_indexes');
$item_index = $form_state->getTriggeringElement()['#parents'][1];
if (($key = array_search($item_index, $item_indexes)) !== FALSE) {
unset($item_indexes[$key]);
}
$form_state->set('item_indexes', $item_indexes);
$form_state->setRebuild();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment