jfu-1.0.x-dev/jfu.module
jfu.module
<?php
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\file\Entity\File;
use Drupal\Core\Url;
use Drupal\Component\Serialization\Json;
use Zend\Stdlib\ArrayUtils;
use Drupal\Core\Site\Settings;
use Drupal\Component\Utility\Crypt;
/**
* Implements hook_theme().
*/
function jfu_theme($existing, $type, $theme, $path) {
return [
'json_form_component_widget' => [
'template' => 'json-form-component-widget',
'variables' => [
'field_name' => NULL,
'field_label' => NULL,
'field_required_class' => NULL,
],
],
'json_widget_component' => [
'template' => 'json-widget-component',
'variables' => [
'values' => NULL,
'json_array' => NULL,
'components_config' => NULL,
'classes' => NULL,
],
],
];
}
/**
* Implements hook_form_alter().
*/
function jfu_form_alter(&$form, FormStateInterface $form_state, $form_id) {
if (isset($form['#is_jfu'])) {
$attached = '';
\Drupal::moduleHandler()->invokeAllWith('jfu_attached',
function (callable $hook, string $module) use (&$attached) {
$hook($attached);
}
);
\Drupal::moduleHandler()->alter('jfu_attached', $attached);
$form['#prefix'] = '<div id="app">';
$form['#suffix'] = '</div>';
$form['#attached']['library'][] = 'jfu/json_widget_utils';
if(!empty($attached)) {
$form['#attached']['library'][] = $attached;
}
$form['#attached']['library'][] = 'jfu/jfu_vue_js';
$form['#attached']['library'][] = 'jfu/jfu.dialog';
$form['#attached']['library'][] = 'jfu/jfu_css';
$entity_type = $form_state->getStorage()['form_display']->getTargetEntityTypeId();
$bundle = $form_state->getStorage()['form_display']->getTargetBundle();
foreach ($form as $key => $value) {
if ($key[0] != '#' && isset($value['#attributes'])
&& isset($value['#attributes']['class'])
&& in_array($form['#is_jfu'], $value['#attributes']['class'])) {
$field_name = $value['widget']['#field_name'];
$field_name_class = str_replace('_', '-', $field_name);
$config_name = \Drupal::service('jfu_config.service')->jfuConfigName($entity_type, $bundle, $field_name);
$config = \Drupal::service('config.factory')->getEditable($config_name);
$config_all[$key] = !is_null($config->get('components_config')) ? $config->get('components_config') : [];
// Send a variable to js to identify if it is a multiple field.
$form['#attached']['drupalSettings']['cardinality'][$field_name] = $value['widget']['#cardinality'];
if ($value['widget']['#cardinality_multiple']) {
$class_add_another_item = 'add-another-item-' . $field_name_class;
$form[$key]['widget']['add_more']['#attributes']['class'][] = $class_add_another_item;
$form[$key]['widget']['add_more']['#attributes']['target_field_name'] = $class_add_another_item;
$form[$key]['widget']['#attributes']['class'][] = 'visually-hidden';
}
else {
$form[$key]['widget'][0]['#prefix'] = '<div class="visually-hidden">';
$form[$key]['widget'][0]['#suffix'] = '</div>';
}
$field_required_class = [];
if ($value['widget']['#required']) {
$field_required_class = [
'js-form-required',
'form-required',
];
}
$template_component = [
'#theme' => 'json_form_component_widget',
'#field_name' => $field_name,
'#field_label' => $value['widget']['#title'],
'#field_required_class' => $field_required_class,
];
$form[$key]['#markup'] = Drupal::service('renderer')->render($template_component);
$form['#attached']['drupalSettings']['field_names'][$field_name] = $field_name;
$form['#attached']['drupalSettings']['config_components'][$field_name] = $config->get('components_config');
}
}
$defaultLabels = [
//General
'add_component' => t('Add component'),
'choose_component' => t('Choose component'),
'add_new_item' => t('Add new item'),
'delete_item' => t('Delete item'),
'edit' => t('Edit'),
'delete' => t('Delete'),
'text' => t('Text'),
'save' => t('Save'),
'link' => t('Link'),
'none' => t('- None -'),
'valid_block' => t('You have not selected a valid block'),
'responsive_image' => t('Responsive image'),
'group_items_quantity' => t('Group items quantity'),
'description_help' => t('There is no content. Add description with the following link.'),
'description_add' => t('Add description'),
'description_edit' => t('Edit description'),
'field_required' => t('It is required to fill some field of the item.'),
'image_required' => t('Image field is required.'),
'link_required' => t('It is required field link.'),
'description_link_url' => t('Start typing the title of a piece of content to select it. You can also enter an internal path such as <strong>/node/add</strong> or an external URL such as <strong>http://example.com</strong>.'),
//Quote
'quote' => t('Quote'),
'author' => t('Author'),
'position' => t('Position'),
'description' => t('Description'),
'image' => t('Image'),
'load_image' => t('Load image'),
'title' => t('Title'),
'link_url' => t('Link url'),
'help_text_load_image_1' => t('Start typing the title of a piece of content to select it. You can also enter an internal path such as'),
'help_text_load_image_2' => t('or an external URL such as'),
'link_text' => t('Link text'),
'open_in_another_tab' => t('Open in another tab'),
'full_width' => t('Full width'),
'activate_full_width' => t('Activate full width'),
//Accordion
'accordion' => t('Accordion'),
//Banner
'type' => t('Type'),
'default' => t('Default'),
'center_elements' => t('Center elements'),
'solid_background' => t('Solid background'),
'banner_title' => t('Banner title'),
'background_color' => t('Background color'),
'element_color' => t('Element color'),
//Block
'block' => t('Block'),
'row' => t('Row'),
'selected_block' => t('Selected block: '),
'search_block_for_the_blockname' => t('Search block for the blockname'),
'block_name' => t('Block Name'),
'help_text_block' => t("Write the name of the block and choose the block. If you can't find the block, use the button on the right and search again."),
'machine_name' => t('Machine name:'),
'update_lb' => t('Update list block'),
'block_style' => t('Style'),
//Tabs
'tabs' => t('Tabs'),
'tab_title' => t('Tab title'),
'select_components' => t('Select components'),
'add_tab' => t('Add tab'),
'delete_tab' => t('Delete tab'),
'component_required' => t('It is required a title and select a component.'),
//Embed
'embed' => t('Embed'),
'iframe' => t('Iframe'),
'description_embed' => t('Enter the complete code'),
'embed_type' => t('Embed type'),
'text_youtube' => t('Insert a URL of Youtube'),
'text_vimeo' => t('Insert a URL of Vimeo'),
'help_text_embed' => t('Insert a URL such as'),
'youtube_l' => t('Youtube URL'),
'vimeo_l' => t('Vimeo URL'),
//Simple card
'simple_card' => t('Simple Card'),
'subtitle' => t('Subtitle'),
'aligment' => t('Aligment'),
'left' => t('Left'),
'right' => t('Right'),
'top' => t('Top'),
'bottom' => t('Bottom'),
//Content in columns
'content_in_columns' => t('Content in columns'),
'icons' => t('Icons'),
'texts' => t('Texts'),
'column' => t('Column'),
'content' => t('Content'),
'change_image' => t('Change image'),
'delete_image' => t('Delete image'),
'alternative_text' => t('Alternative text'),
'title_text' => t('Title text'),
'item_text' => t('Item text'),
'add_link_image' => t('Add link image'),
//Data number card
'suffix' => t('Suffix'),
'value' => t('Value'),
'prefix' => t('Prefix'),
'custom_classes' => t('Custom classes'),
'class_list' => t('Class list'),
'allow_class_text_help' => t('Add classes separated by "," and without spaces. For example: class1,class-2,class_3.'),
//Table
'add_head' => t('Add head'),
'add_body' => t('Add body'),
'head' => t('Head'),
'row' => t('Row'),
'cell' => t('Cell'),
//Gallery
'gallery' => t('Gallery'),
];
foreach ($config_all as $key_config_all => $value_config_all) {
foreach ($value_config_all as $key_cf => $value_cf) {
if(isset($value_cf['max_size']) && !empty($value_cf['max_size'])) {
$defaultLabels[$key_config_all]['limit_' . $key_cf] = t('@size limit.', ['@size' => $value_cf['max_size']]);
}
if(isset($value_cf['max_dimensions']) && !empty($value_cf['max_dimensions']['width']) && !empty($value_cf['max_dimensions']['height'])){
$defaultLabels[$key_config_all]['allowed_types_' . $key_cf] = t('Allowed types: @extensions.', ['@extensions' => 'png jpg jpeg']);
$image_larger = $value_cf['max_dimensions']['width'] . 'x' . $value_cf['max_dimensions']['height'];
$defaultLabels[$key_config_all]['images_larger_' . $key_cf] = t('Images must be larger than <strong>@min</strong> pixels. Images larger than <strong>@max</strong> pixels will be resized.', ['@min' => $image_larger, '@max' => $image_larger]);
if(isset($value_cf['max_dimensions_responsive']) && !empty($value_cf['max_dimensions_responsive']['width']) && !empty($value_cf['max_dimensions_responsive']['height'])) {
$responsive_image_larger = $value_cf['max_dimensions_responsive']['width'] . 'x' . $value_cf['max_dimensions_responsive']['height'];
$defaultLabels[$key_config_all]['responsive_image_larger_' . $key_cf] = t('Images must be larger than <strong>@min</strong> pixels. Images larger than <strong>@max</strong> pixels will be resized.', ['@min' => $responsive_image_larger, '@max' => $responsive_image_larger]);
}
}
$component_name = ucfirst(str_replace('_', ' ', $key_cf));
$defaultLabels[$key_config_all]['group_items_quantity_help_' . $key_cf] = t('If you want to group the "@component" items write a number greater than zero', ['@component' => $component_name]);
}
}
$form['#attached']['drupalSettings']['defaultLabels'] = $defaultLabels;
$url_upload_image = Url::fromRoute('jfu.image_dialog', ['entity_type' => $entity_type, 'bundle' => $bundle], ['absolute' => TRUE]);
$url_text_format = Url::fromRoute('jfu.text_format_dialog', ['entity_type' => $entity_type, 'bundle' => $bundle], ['absolute' => TRUE]);
$url_base = Url::fromRoute('<front>', [], ['absolute' => TRUE]);
$module_path = \Drupal::service('extension.list.module')->getPath('jfu');
$file_url_generator = \Drupal::service('file_url_generator');
$url_public = $file_url_generator->generateAbsoluteString('public://');
//TODO: Particular entity reference autocomplete for node
$target_type = 'node';
$selection_handler = 'default';
$data = serialize([]) . $target_type . $selection_handler;
$selection_settings_key = Crypt::hmacBase64($data, Settings::getHashSalt());
$routes_parameters = [
'target_type' => $target_type,
'selection_handler' => $selection_handler,
'selection_settings_key' => $selection_settings_key
];
$key_value_storage = \Drupal::keyValue('entity_autocomplete');
if (!$key_value_storage->has($selection_settings_key)) {
$key_value_storage->set($selection_settings_key, []);
}
$url_autocomplete_link = Url::fromRoute('system.entity_autocomplete', $routes_parameters, ['absolute' => TRUE]);
$form['#attached']['drupalSettings']['url_upload_image'] = $url_upload_image->toString();
$form['#attached']['drupalSettings']['url_text_format'] = $url_text_format->toString();
$form['#attached']['drupalSettings']['url_base'] = rtrim($url_base->toString(), '/');
$form['#attached']['drupalSettings']['url_public'] = $url_public;
$form['#attached']['drupalSettings']['url_autocomplete_link'] = $url_autocomplete_link->toString();
$form['jfu_fids_permanent'] = [
'#type' => 'hidden',
'#value' => '',
];
foreach (array_keys($form['actions']) as $action) {
if ($action != 'preview' && isset($form['actions'][$action]['#type']) && $form['actions'][$action]['#type'] === 'submit') {
$form['actions'][$action]['#submit'][] = 'jfu_proccess_image';
$form['actions'][$action]['#submit'][] = 'jfu_proccess_inline_image';
}
}
}
}
/**
* Function to change status file temp to permanent.
*/
function jfu_proccess_image(&$form, FormStateInterface $form_state) {
$user_input = $form_state->getUserInput();
if (!empty($user_input['jfu_fids_permanent'])) {
$file_usage = \Drupal::service('file.usage');
$entity = $form_state->getFormObject()->getEntity();
$fids_permanent = explode(',', rtrim($user_input['jfu_fids_permanent'], ','));
foreach ($fids_permanent as $fidp) {
$file = File::load($fidp);
$file->setPermanent();
$file->save();
if (!empty($entity->id())) {
$file_usage->add($file, 'jfu', $entity->getEntityTypeId(), $entity->id());
}
}
}
}
/**
* Function to change status inline file temp to permanent.
*/
function jfu_proccess_inline_image(&$form, FormStateInterface $form_state) {
$jfu_service = \Drupal::service('jfu_config.service');
$entity = $form_state->getFormObject()->getEntity();
$jfu_fields = $jfu_service->jfuGetFieldDefinitions($entity->getEntityTypeId(), $entity->bundle());
foreach ($jfu_fields as $key => $value) {
$jfu_field = $form_state->getValue($key);
foreach ($jfu_field as $key_field => $value_field) {
if(is_array($value_field) && isset($value_field['value']) && !empty($value_field['value'])) {
$json_data = json_decode($value_field['value']);
if ($json_data->type === 'tabs') {
foreach ($json_data->items as $key_tabs => $value_tabs) {
jfu_proccess_inline_image_json_data($value_tabs->body, $jfu_service, $entity);
}
}
else {
jfu_proccess_inline_image_json_data($json_data, $jfu_service, $entity);
}
}
}
}
}
/**
* Function to change status inline file temp to permanent.
*/
function jfu_proccess_inline_image_json_data($json_data, $jfu_service, $entity) {
if (isset($json_data->body) && !empty($json_data->body) && !empty($json_data->body->value)) {
$uuids = $jfu_service->extractFilesUuid($json_data->body->value);
if (!empty($uuids)) {
$jfu_service->recordFileUsage($uuids, $entity);
}
}
if (isset($json_data->items) && !empty($json_data->items) && isset($json_data->items->items) && !empty($json_data->items->items)) {
foreach ($json_data->items->items as $key_item => $item) {
if (isset($item->body) && !empty($item->body) && !empty($item->body->value)) {
$uuids = $jfu_service->extractFilesUuid($item->body->value);
if (!empty($uuids)) {
$jfu_service->recordFileUsage($uuids, $entity);
}
}
}
}
}