Advertisement
Guest User

Untitled

a guest
Jan 26th, 2020
100
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 29.25 KB | None | 0 0
  1. <?php
  2.  
  3. /**
  4. * @file
  5. * Custom functionality.
  6. */
  7.  
  8. /**
  9. * Implements hook_menu().
  10. */
  11. function custom_menu() {
  12. $items = [];
  13.  
  14. $items['homepage'] = [
  15. 'title' => '',
  16. 'page callback' => 'custom_blank_page',
  17. // No need to restrict access.
  18. 'access callback' => TRUE,
  19. ];
  20. $items['about-us'] = [
  21. 'title' => '',
  22. 'page callback' => 'custom_blank_page',
  23. // No need to restrict access.
  24. 'access callback' => TRUE,
  25. ];
  26. $items['contacts'] = [
  27. 'title' => '',
  28. 'page callback' => 'custom_blank_page',
  29. // No need to restrict access.
  30. 'access callback' => TRUE,
  31. ];
  32. $items['admin/content/content-settings'] = [
  33. 'title' => 'Content settings',
  34. 'page callback' => 'drupal_get_form',
  35. 'page arguments' => ['custom_content_settings_form'],
  36. 'access arguments' => ['access administration menu'],
  37. ];
  38.  
  39. return $items;
  40. }
  41.  
  42. function custom_blank_page() {
  43. return '';
  44. }
  45.  
  46. /**
  47. * Implements hook_entity_info_alter().
  48. */
  49. function custom_entity_info_alter(&$entity_info) {
  50. $entity_info['node']['view modes']['node_in_block'] = [
  51. 'label' => t('Node in block'),
  52. 'custom settings' => TRUE,
  53. ];
  54. $entity_info['node']['view modes']['node_in_block_offset'] = [
  55. 'label' => t('Node in block (with offset)'),
  56. 'custom settings' => TRUE,
  57. ];
  58. $entity_info['node']['view modes']['chess'] = [
  59. 'label' => t('Chess'),
  60. 'custom settings' => TRUE,
  61. ];
  62. $entity_info['node']['view modes']['about_us'] = [
  63. 'label' => t('About Us'),
  64. 'custom settings' => TRUE,
  65. ];
  66. $entity_info['taxonomy_term']['view modes']['services'] = [
  67. 'label' => t('Services'),
  68. 'custom settings' => TRUE,
  69. ];
  70.  
  71. $entity_info['taxonomy_term']['view modes']['chess'] = $entity_info['node']['view modes']['chess'];
  72. }
  73.  
  74. /**
  75. * Implements hook_field_widget_info().
  76. */
  77. function custom_field_widget_info() {
  78. return [
  79. 'text_email' => [
  80. 'label' => t('Simple E-mail'),
  81. 'field types' => ['text'],
  82. ],
  83. ];
  84. }
  85.  
  86. /**
  87. * Implements hook_field_widget_form().
  88. */
  89. function custom_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
  90. $main_widget = [];
  91.  
  92. switch ($instance['widget']['type']) {
  93. case 'text_email':
  94. $new_element = [
  95. '#type' => 'textfield',
  96. '#default_value' => isset($items[$delta]['value']) ?? NULL,
  97. '#size' => 20,
  98. '#maxlength' => $field['settings']['max_length'],
  99. '#attributes' => ['class' => array('text-full')],
  100. '#element_validate' => ['custom_element_validate_email'],
  101. ];
  102. break;
  103. }
  104.  
  105. if (!empty($new_element)) {
  106. $main_widget = $element + $new_element;
  107. }
  108.  
  109. $element['value'] = $main_widget;
  110.  
  111. return $element;
  112. }
  113.  
  114. /**
  115. * Implements hook_field_formatter_info().
  116. */
  117. function custom_field_formatter_info() {
  118. return [
  119. 'text_summary_and_body' => [
  120. 'label' => t('Summary and Body'),
  121. 'field types' => ['text_with_summary'],
  122. ],
  123. ];
  124. }
  125.  
  126. /**
  127. * Implements hook_field_formatter_view().
  128. */
  129. function custom_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
  130. $element = array();
  131.  
  132. switch ($display['type']) {
  133. case 'text_summary_and_body':
  134. foreach ($items as $delta => $item) {
  135. $output = '';
  136.  
  137. foreach (['summary', 'value'] as $part) {
  138. $content = [
  139. '#theme' => 'html_tag',
  140. '#tag' => 'div',
  141. '#value' => _text_sanitize($instance, $langcode, $item, $part),
  142. '#attributes' => [
  143. 'class' => ["$part-wrapper"],
  144. ],
  145. ];
  146.  
  147. $output .= drupal_render($content);
  148. }
  149.  
  150. $element[$delta] = array('#markup' => $output);
  151. }
  152. break;
  153. }
  154.  
  155. return $element;
  156. }
  157.  
  158. /**
  159. * Implements hook_field_extra_fields().
  160. */
  161. function custom_field_extra_fields() {
  162. $extra['node']['article'] = [
  163. 'display' => [
  164. 'read_more' => [
  165. 'label' => t('Read more'),
  166. 'description' => t('Read more link'),
  167. 'weight' => 9,
  168. 'callback' => 'custom_read_more_link',
  169. ],
  170. 'publish_date' => [
  171. 'label' => t('Publish Date'),
  172. 'description' => t('Publish Date (d.m.Y)'),
  173. 'weight' => 10,
  174. ],
  175. 'view_counter' => [
  176. 'label' => t('Node view counter'),
  177. 'description' => t('Node view counter'),
  178. 'weight' => 11,
  179. ],
  180. ],
  181. ];
  182.  
  183. return $extra;
  184. }
  185.  
  186. function custom_read_more_link($entity) {
  187. $content = l(t('Read more'), 'node/' . $entity->nid);
  188. $content .= custom_get_chevron();
  189.  
  190. return '<div class="read-more-default">' . $content . '</div>';
  191. }
  192.  
  193. function custom_get_material_icon($name, $tag = 'div') {
  194. $icon = [
  195. '#theme' => 'html_tag',
  196. '#tag' => $tag,
  197. '#value' => '',
  198. '#attributes' => ['class' => ['zmdi', "zmdi-$name"]],
  199. ];
  200.  
  201. return drupal_render($icon);
  202. }
  203.  
  204. function custom_get_chevron() {
  205. return custom_get_material_icon('chevron-right');
  206. }
  207.  
  208. /**
  209. * Implements hook_form_alter().
  210. */
  211. function custom_form_alter(&$form, &$form_state, $form_id) {
  212. switch ($form_id) {
  213. case 'lang_dropdown_form':
  214. if (!empty($form['lang_dropdown_select']['#options'])) {
  215. $options =& $form['lang_dropdown_select']['#options'];
  216.  
  217. foreach ($options as &$option) {
  218. $option = drupal_substr($option, 0, 2);
  219. }
  220. }
  221. break;
  222.  
  223. case 'views_exposed_form':
  224. switch ($form['#id']) {
  225. case 'views-exposed-form-content-page-search':
  226. $form['title']['#size'] = 10;
  227. $form['submit']['#attributes'] = [
  228. 'class' => ['zmdi', 'zmdi-search', 'search-btn'],
  229. ];
  230. break;
  231. }
  232. break;
  233.  
  234. case 'feedback_node_form':
  235. if (!empty($_SESSION['messages']['status'])) {
  236. $messages =& $_SESSION['messages']['status'];
  237.  
  238. if (count($messages) > 1) {
  239. array_pop($messages);
  240. }
  241. }
  242.  
  243. foreach(['title', 'phone', 'email', 'message'] as $field_name) {
  244. if ('title' === $field_name) {
  245. $field_element =& $form[$field_name . '_field'][LANGUAGE_NONE][0]['value'];
  246. }
  247. else {
  248. $field_element =& $form["field_$field_name"][LANGUAGE_NONE][0]['value'];
  249. }
  250.  
  251. $placeholder = $field_element['#title'];
  252.  
  253. if (!empty($placeholder)) {
  254. $placeholder = drupal_strtolower($placeholder);
  255. $placeholder = explode(' ', $placeholder);
  256.  
  257. array_shift($placeholder);
  258.  
  259. $placeholder = t('Enter your @placeholder',['@placeholder' => implode(' ', $placeholder)]);
  260.  
  261. $field_element['#attributes']['placeholder'] = $placeholder;
  262. }
  263. }
  264.  
  265. $form['actions']['submit']['#value'] = t('Send');
  266. $form['actions']['submit']['#attributes']['class'][] = 'black-button';
  267.  
  268. $form['#submit'][] = 'custom_feedback_node_form_submit';
  269. break;
  270. }
  271. }
  272.  
  273. function custom_feedback_node_form_submit(&$form, $form_state) {
  274. drupal_set_message(t('!Thnx Your message has been sent.', [
  275. '!Thnx' => '<b>' . t('Thank you.') . '</b></br>',
  276. ]));
  277. }
  278.  
  279. /**
  280. * Implements hook_block_info().
  281. */
  282. function custom_block_info() {
  283. $blocks = [];
  284.  
  285. $blocks['custom_contact_info'] = [
  286. 'info' => t('Contacts'),
  287. 'cache' => DRUPAL_NO_CACHE
  288. ];
  289. $blocks['custom_contacts'] = [
  290. 'info' => t('Contacts: Address & e-mail'),
  291. 'cache' => DRUPAL_NO_CACHE
  292. ];
  293. $blocks['custom_phone'] = [
  294. 'info' => t('Contacts: Phone'),
  295. 'cache' => DRUPAL_NO_CACHE
  296. ];
  297. $blocks['custom_socials'] = [
  298. 'info' => t('Contacts: Socials'),
  299. 'cache' => DRUPAL_NO_CACHE
  300. ];
  301. $blocks['custom_scroll_status'] = [
  302. 'info' => t('Scroll Status'),
  303. 'cache' => DRUPAL_NO_CACHE
  304. ];
  305.  
  306. return $blocks;
  307. }
  308.  
  309. /**
  310. * Implements hook_block_view().
  311. */
  312. function custom_block_view($delta = '') {
  313. static $contacts;
  314. static $socials;
  315.  
  316. $block = [];
  317.  
  318. if (is_null($contacts)) {
  319. $settings = variable_get('custom_site_settings', []);
  320. $contacts = array_filter($settings, 'is_scalar');
  321. $socials = array_diff_key($settings, $contacts);
  322. $socials = array_shift($socials);
  323. }
  324.  
  325. switch ($delta) {
  326. case 'custom_scroll_status':
  327. $block = [
  328. 'content' => '<div class="scroll-status"></div>',
  329. ];
  330. break;
  331.  
  332. case 'custom_contact_info':
  333. $content = [];
  334.  
  335. foreach ($contacts as $item => $value) {
  336. $value = nl2br($value);
  337. $value = [
  338. '#theme' => 'html_tag',
  339. '#tag' => 'div',
  340. '#value' => '<div class="content">' . $value . '</div>',
  341. '#attributes' => [
  342. 'class' => ['contact-item-wrapper', "wrapper-$item"],
  343. ],
  344. ];
  345.  
  346. $content[] = drupal_render($value);
  347. }
  348.  
  349. $content = implode('', $content);
  350. // @todo: temporary hide socials, uncommment after account creation.
  351. // $content .= custom_get_social_icons($socials);
  352.  
  353. $block = [
  354. 'title' => t('Contacts'),
  355. 'content' => $content,
  356. ];
  357. break;
  358.  
  359. case 'custom_contacts':
  360. case 'custom_phone':
  361. $content = [];
  362. $fields = [
  363. 'custom_contacts' => ['address', 'e_mail'],
  364. 'custom_phone' => ['phone'],
  365. ];
  366.  
  367. foreach ($fields[$delta] as $item) {
  368. if (!empty($contacts[$item])) {
  369. $value = $contacts[$item];
  370.  
  371. if ('e_mail' === $item) {
  372. $value = '<div class="zmdi zmdi-email"></div>' . $value;
  373. }
  374.  
  375. $item = [
  376. '#theme' => 'html_tag',
  377. '#tag' => 'div',
  378. '#value' => $value,
  379. '#attributes' => [
  380. 'class' => ['contact-wrapper', "wrapper-$item"],
  381. ],
  382. ];
  383.  
  384. $content[] = drupal_render($item);
  385. }
  386. }
  387.  
  388. $block = ['content' => implode('', $content)];
  389. break;
  390.  
  391. case 'custom_socials':
  392. // @todo: temporary hide socials, uncommment after account creation.
  393. // $block = ['content' => custom_get_social_icons($socials)];
  394. $block = ['content' => ''];
  395. break;
  396. }
  397.  
  398. return $block;
  399. }
  400.  
  401. /**
  402. * Implements hook_block_view_alter().
  403. */
  404. function custom_block_view_alter(&$data, $block) {
  405. switch ($block->module) {
  406. case 'formblock':
  407. switch ($block->delta) {
  408. case 'feedback':
  409. $data['content']['secondary-title'] = [
  410. '#prefix' => '<div class="secondary-title">',
  411. '#markup' => t('Still have questions ?'),
  412. '#suffix' => '</div>',
  413. '#weight' => -1,
  414. ];
  415. break;
  416. }
  417. break;
  418.  
  419. case 'system':
  420. case 'multiblock':
  421. switch ($block->delta) {
  422. case 'powered-by':
  423. case 1:
  424. case 4:
  425. $data["content"] = t("&copy !name 2019", [
  426. '!name' => variable_get('site_name', 'Devpoint'),
  427. ]);
  428. break;
  429. }
  430. break;
  431. }
  432. }
  433.  
  434. /**
  435. * Implements hook_field_group_pre_render_alter().
  436. */
  437. function custom_field_group_pre_render_alter(&$element, $group, &$form) {
  438. switch ($group->mode) {
  439. case 'chess':
  440. static $counter = null;
  441. static $services = -1;
  442.  
  443. $groups = [
  444. 'group_left_group' => 'push',
  445. 'group_right_group' => 'pull',
  446. 'group_middle_group' => 'pull',
  447. ];
  448.  
  449. if ('taxonomy_term' !== $group->entity_type) {
  450. unset($groups['group_middle_group']);
  451. }
  452. elseif ('services' === $group->bundle) {
  453. if ($services < 0) {
  454. $results = views_get_view_result('taxonomy', 'page_1');
  455. $services = count($results) - 1;
  456. }
  457. }
  458.  
  459. $steps = count($groups);
  460.  
  461. if (is_null($counter)) {
  462. $counter = $steps;
  463. }
  464.  
  465. if (array_key_exists($group->group_name, $groups)) {
  466. $is_even = $counter < 0;
  467.  
  468. if ($is_even) {
  469. $chess_classes = [];
  470. $operation = $groups[$group->group_name];
  471.  
  472. foreach (explode(' ', $group->classes) as $class) {
  473. $parts = explode('-', $class);
  474. $media = array_intersect($parts, ['lg', 'md', 'sm']);
  475.  
  476. if (!empty($media)) {
  477. $media = reset($media);
  478. $size = 12 - end($parts);
  479. $new_class = [reset($parts), $media, $operation, $size];
  480. $chess_classes[] = implode('-', $new_class);
  481. }
  482. elseif (!$services && 'group_left_group' === $group->group_name) {
  483. $xs_class = array_intersect($parts, ['xs']);
  484.  
  485. if (!empty($xs_class)) {
  486. $element['#prefix'] = str_replace($class, 'col-xs-12', $element['#prefix']);
  487. --$services;
  488. }
  489. }
  490. }
  491.  
  492. $element['#prefix'] = custom_insert_classes($element['#prefix'], $chess_classes);
  493. }
  494.  
  495. $step = $counter / abs($counter) * (-1);
  496. $counter += $step;
  497.  
  498. if (!$counter) {
  499. $counter = $steps * $step;
  500.  
  501. --$services;
  502. }
  503. }
  504. break;
  505. }
  506. }
  507.  
  508. /**
  509. * Implements hook_node_view().
  510. */
  511. function custom_node_view($node, $view_mode, $langcode) {
  512. switch ($view_mode) {
  513. case 'chess':
  514. case 'teaser':
  515. $node->title = NULL;
  516. break;
  517. }
  518.  
  519. switch ($node->type) {
  520. case 'article':
  521. case 'page':
  522. switch ($view_mode) {
  523. case 'chess':
  524. static $counter = 1;
  525.  
  526. $styles = [
  527. 'article' => 'mediator_reverse',
  528. 'page' => 'our_work_left',
  529. ];
  530.  
  531. if ($counter++ % 2) {
  532. $node->content['field_image'][0]['#image_style'] = $styles[$node->type];
  533. }
  534. break;
  535. }
  536. break;
  537. }
  538.  
  539. $fields = ['read_more', 'publish_date', 'view_counter'];
  540. $extra_fields = field_extra_fields_get_display('node', $node->type, $view_mode);
  541.  
  542. foreach ($fields as $field) {
  543. if (!empty($extra_fields[$field]['visible'])) {
  544. switch ($field) {
  545. case 'view_counter':
  546. if (module_exists('nodeviewcount')) {
  547. // Yes, we really need to suppress errors, because of contrib module.
  548. @$amount = nodeviewcountcount_count_node_views($node);
  549.  
  550. while (!is_scalar($amount)) {
  551. $amount = (array) $amount;
  552. $amount = reset($amount);
  553. }
  554.  
  555. $node->content[$field]['#prefix'] = '<div class="pseudo-field node-view-counter">';
  556. $node->content[$field]['#markup'] = $amount;
  557. $node->content[$field]['#suffix'] = '</div>';
  558. }
  559. break;
  560.  
  561. case 'publish_date':
  562. $date = format_date($node->created, 'custom', 'd.m.Y');
  563.  
  564. $node->content[$field]['#prefix'] = '<div class="pseudo-field publish-date">';
  565. $node->content[$field]['#markup'] = $date;
  566. $node->content[$field]['#suffix'] = '</div>';
  567. break;
  568.  
  569. case 'read_more':
  570. switch ($view_mode) {
  571. case 'chess':
  572. $node->content[$field]['#markup'] = custom_read_more_link($node);
  573. break;
  574.  
  575. default:
  576. if (!empty($node->nodeblock['node_link'])) {
  577. $node->content[$field] = ['#markup' => ''];
  578.  
  579. if (in_array($view_mode, ['node_in_block', 'node_in_block_offset'])) {
  580. $node->content[$field]['#markup'] .= custom_get_chevron();
  581. $node->content[$field]['#prefix'] = '<div class="black-button">';
  582. $node->content[$field]['#suffix'] = '</div>';
  583. }
  584.  
  585. /** @noinspection SuspiciousAssignmentsInspection */
  586. $node->content[$field]['#markup'] .= l(t('read more'), 'about-us');
  587. }
  588. break;
  589. }
  590. break;
  591. }
  592. }
  593. }
  594. }
  595.  
  596. /**
  597. * Implements hook_taxonomy_term_view().
  598. */
  599. function custom_taxonomy_term_view($term, $view_mode, $langcode) {
  600. switch ($term->vocabulary_machine_name) {
  601. case 'services':
  602. switch ($view_mode) {
  603. case 'chess':
  604. $term->name = '';
  605.  
  606. if (!empty($term->content['field_icons'][0])) {
  607. unset($term->content['field_icons'][0]);
  608. }
  609. break;
  610.  
  611. case 'services':
  612. $term->name = '';
  613. break;
  614. }
  615. break;
  616. }
  617. }
  618.  
  619. /**
  620. * Implements hook_preprocess_HOOK().
  621. */
  622. function custom_preprocess_page(&$variables) {
  623. $variables['secondary_search'] = module_invoke( 'search', 'block_view', 'form');
  624.  
  625. $secondary_lang = module_invoke( 'lang_dropdown', 'block_view', 'language_content');
  626. $secondary_lang['subject'] = '';
  627. $variables['secondary_lang'] = $secondary_lang;
  628.  
  629. if (!empty($variables['node'])) {
  630. $node =& $variables['node'];
  631.  
  632. switch ($node->type) {
  633. case 'article':
  634. $variables['title'] = '';
  635. break;
  636. }
  637. }
  638. }
  639.  
  640. /**
  641. * Implements hook_preprocess_HOOK().
  642. */
  643. function custom_preprocess_node(&$variables) {
  644. $variables['classes_array'][] = 'vm-' . $variables['view_mode'];
  645. }
  646.  
  647. /**
  648. * Implements hook_preprocess_HOOK().
  649. */
  650. function custom_preprocess_taxonomy_term(&$variables) {
  651. $variables['classes_array'][] = 'vm-' . $variables['view_mode'];
  652. }
  653.  
  654. /**
  655. * Implements hook_preprocess_HOOK().
  656. */
  657. function custom_preprocess_views_view_unformatted(&$variables) {
  658. switch ($variables['view']->name) {
  659. case 'dynamic_content':
  660. switch ($variables['view']->current_display) {
  661. case 'block_related_articles':
  662. if (module_exists('slick')) {
  663. $settings = ['optionset' => 'related_articles'];
  664.  
  665. foreach ($variables['rows'] as $key => $row) {
  666. $variables['rows'][$key] = [
  667. 'slide' => $row,
  668. ];
  669. }
  670.  
  671. $variables['rows'] = slick_build($variables['rows'], [], $settings);
  672. $variables['rows'] = [render($variables['rows'])];
  673. }
  674. break;
  675. }
  676.  
  677. break;
  678. case 'taxonomy':
  679. switch ($variables['view']->current_display) {
  680. case 'block_services_images':
  681. if (!empty($variables['classes_array'][0])) {
  682. $variables['classes_array'][0] .= ' visible default';
  683. }
  684. break;
  685. }
  686. break;
  687. }
  688. }
  689.  
  690. function custom_content_settings_form() {
  691. $form = [];
  692. $settings = variable_get('custom_site_settings', []);
  693.  
  694. $form['custom_site_settings'] = array(
  695. '#type' => 'fieldset',
  696. '#title' => t('Global site settings'),
  697. '#collapsible' => FALSE,
  698. '#collapsed' => FALSE,
  699. '#tree' => TRUE,
  700. );
  701.  
  702. foreach (custom_get_site_settings_fields() as $index => $title) {
  703. switch ($index) {
  704. case 'message':
  705. case 'address':
  706. $field_type = 'textarea';
  707. break;
  708.  
  709. default:
  710. $field_type = 'textfield';
  711. break;
  712. }
  713.  
  714. $form['custom_site_settings'][$index] = [
  715. '#type' => $field_type,
  716. '#title' => $title,
  717. '#required' => TRUE,
  718. '#default_value' => $settings[$index] ?? '',
  719. ];
  720. }
  721.  
  722. $form['custom_site_settings']['social_settings'] = [
  723. '#type' => 'fieldset',
  724. '#title' => t('Social networks'),
  725. '#collapsible' => TRUE,
  726. '#collapsed' => FALSE,
  727. '#tree' => TRUE,
  728. ];
  729.  
  730. foreach (custom_get_socials_settings() as $index => $title) {
  731. $form['custom_site_settings']['social_settings'][$index] = [
  732. '#type' => 'textfield',
  733. '#title' => $title,
  734. '#required' => FALSE,
  735. '#default_value' => $settings['social_settings'][$index] ?? '',
  736. ];
  737. }
  738.  
  739. return system_settings_form($form);
  740. }
  741.  
  742. function custom_get_site_settings_fields() {
  743. $fields = [
  744. 'message' => t('Contacts message'),
  745. 'address' => t('Address'),
  746. 'e_mail' => t('E-mail'),
  747. 'phone' => t('Phone'),
  748. ];
  749.  
  750. return $fields;
  751. }
  752.  
  753. function custom_get_socials_settings() {
  754. return [
  755. 'facebook' => t('Facebook'),
  756. 'google-plus' => t('Google Plus'),
  757. 'twitter' => t('Twitter'),
  758. ];
  759. }
  760.  
  761. /**
  762. * Implements hook_preprocess_HOOK().
  763. */
  764. function custom_preprocess_views_slideshow_pager_field_item(&$variables) {
  765. if (!empty($variables['item'])) {
  766. $old_value = strip_tags($variables['item']);
  767. $new_value = sprintf(".%'.02d", $old_value);
  768. $variables['item'] = str_replace(">$old_value<", ">$new_value<", $variables['item']);
  769. }
  770. }
  771.  
  772. /**
  773. * Implements hook_preprocess_HOOK().
  774. */
  775. function custom_process_views_infinite_scroll_pager(&$variables) {
  776. // On the last page button will be empty and we don't need class there.
  777. if (!empty(drupal_render($variables['button']))) {
  778. $variables['automatic_scroll_class'] .= 'black-button';
  779. }
  780. }
  781.  
  782. /**
  783. * Implements hook_preprocess_HOOK().
  784. */
  785. function custom_preprocess_picture(&$variables) {
  786. $variables['uri'] = custom_swap_to_webp($variables['uri']);
  787. }
  788.  
  789. /**
  790. * Implements hook_preprocess_HOOK().
  791. */
  792. function custom_preprocess_image(&$variables) {
  793. $variables['path'] = custom_swap_to_webp($variables['path']);
  794. }
  795.  
  796. /**
  797. * Implements hook_preprocess_HOOK().
  798. */
  799. function custom_preprocess_lazy_image(&$variables) {
  800. $path = preg_replace('"\.(bmp|gif|png|jpg)"', '.WebP', $variables['path']);
  801. $image_style_path = image_style_path($variables['style_name'], $path);
  802.  
  803. if (file_exists(drupal_realpath($image_style_path))) {
  804. $variables['path'] = $path;
  805. }
  806. }
  807.  
  808. function custom_swap_to_webp($uri) {
  809.  
  810. $filename = preg_replace('"\.(bmp|gif|png|jpg)"', '.webp', $uri);
  811. $scheme = file_uri_scheme($filename);
  812.  
  813. switch ($scheme) {
  814. case 'http':
  815. case 'https':
  816. $headers = get_headers($filename);
  817.  
  818. if(stripos($headers[0],"200 OK")) {
  819. $uri = $filename;
  820. }
  821. break;
  822.  
  823. case 'public':
  824. $file_path = drupal_realpath($filename);
  825.  
  826. if (file_exists($file_path)) {
  827. $uri = $filename;
  828. }
  829. break;
  830. }
  831.  
  832. return $uri;
  833. }
  834.  
  835. function custom_get_social_icons($socials) {
  836. foreach ($socials as $name => $url) {
  837. if (!empty($url)) {
  838. $item = [
  839. '#theme' => 'html_tag',
  840. '#tag' => 'div',
  841. '#value' => l('', $url, [
  842. 'html' => TRUE,
  843. 'attributes' => [
  844. 'class' => ['zmdi', "zmdi-$name"],
  845. ],
  846. ]),
  847. '#attributes' => [
  848. 'class' => ['zmdi-social-wrapper'],
  849. ],
  850. ];
  851.  
  852. $content[] = drupal_render($item);
  853. }
  854. }
  855.  
  856. return '<div class="main-social-wrapper">' . implode('', $content) . '</div>';
  857. }
  858.  
  859. function custom_insert_classes($html, $classes) {
  860. $matches = [];
  861. $pattern = '/class="(.+?)"/i';
  862.  
  863. preg_match($pattern, $html, $matches);
  864.  
  865. if (!empty($matches[1])) {
  866. $old_classes = $matches[1];
  867. $new_classes = explode(' ', $old_classes);
  868. $new_classes = array_merge($new_classes, $classes);
  869. $new_classes = implode(' ', $new_classes);
  870.  
  871. $html = str_replace($old_classes, $new_classes, $html);
  872. }
  873.  
  874. return $html;
  875. }
  876.  
  877. /**
  878. * Implements hook_contextual_links_view_alter().
  879. */
  880. function custom_contextual_links_view_alter(&$element, $items) {
  881. if (!empty($element['#element']['#views_contextual_links_info']['views_ui'])) {
  882. $views_ui =& $element['#element']['#views_contextual_links_info']['views_ui'];
  883.  
  884. switch ($views_ui['view_name']) {
  885. case 'dynamic_content':
  886. switch ($views_ui['view_display_id']) {
  887. case 'block_related_articles':
  888. $element['#links']['slick-ui-edit'] = [
  889. 'title' => t('Edit slick carousel'),
  890. 'href' => 'admin/config/media/slick/list/related_articles/edit',
  891. ];
  892. break;
  893. }
  894. break;
  895. }
  896. }
  897. }
  898.  
  899. /**
  900. * Implements hook_image_effect_info().
  901. */
  902. function custom_image_effect_info() {
  903. $effects = array(
  904. 'custom_image_replace_gradient' => [
  905. 'label' => t('Replace Gradient'),
  906. 'help' => t('Partial replace of an image by effect'),
  907. 'effect callback' => 'custom_image_replace_gradient_effect',
  908. 'form callback' => 'custom_image_default_options_form',
  909. ],
  910. 'custom_image_replace_greyscale' => [
  911. 'label' => t('Replace Greyscale'),
  912. 'help' => t('Partial replace of an image by effect'),
  913. 'effect callback' => 'custom_image_replace_greyscale_effect',
  914. 'form callback' => 'custom_image_default_options_form',
  915. ],
  916. 'custom_image_phone_watermark' => [
  917. 'label' => t('Replace Phone Watermark'),
  918. 'help' => t('Partial replace of an image by effect'),
  919. 'effect callback' => 'custom_image_phone_watermark_effect',
  920. 'form callback' => 'custom_image_default_options_form',
  921. ],
  922. );
  923.  
  924. return $effects;
  925. }
  926.  
  927. function custom_image_default_options_form($data) {
  928. $fields = [
  929. 'offset_x' => t('Offset X'),
  930. 'offset_y' => t('Offset Y'),
  931. 'height' => t('Height'),
  932. 'width' => t('Width'),
  933. ];
  934.  
  935. foreach ($fields as $name => $title) {
  936. $form[$name] = [
  937. '#type' => 'textfield',
  938. '#title' => $title,
  939. '#default_value' => $data[$name] ?? '',
  940. '#field_suffix' => ' ' . t('%'),
  941. '#required' => TRUE,
  942. '#size' => 10,
  943. '#element_validate' => ['element_validate_integer'],
  944. '#allow_negative' => FALSE,
  945. ];
  946. }
  947.  
  948. return $form;
  949. }
  950.  
  951. function custom_image_get_file($name) {
  952. $path = [
  953. drupal_get_path('module', 'custom'),
  954. 'images',
  955. $name,
  956. ];
  957.  
  958. return implode('/', $path);
  959. }
  960.  
  961. function custom_image_phone_watermark_effect($source, $data) {
  962. $image = $source->resource;
  963. $im_width = imagesx($image);
  964. $im_height = imagesy($image);
  965.  
  966. $blank = imagecreatetruecolor($im_width + abs($data['width']), $im_height + abs($data['height']));
  967. $b_width = imagesx($blank) * $data['offset_x'] / 100;
  968. $b_height = imagesy($blank) * $data['offset_y'] / 100;
  969.  
  970. imagesavealpha($blank, true);
  971.  
  972. $transparent = imagecolorallocatealpha($blank, 0, 0, 0, 127);
  973.  
  974. imagefill($blank, 0, 0, $transparent);
  975.  
  976. imagelayereffect($blank, IMG_EFFECT_REPLACE);
  977.  
  978. $dst_x = $data['width'] < 0 ? abs($data['width']) : 0;
  979.  
  980. imagecopy($blank, $image, $dst_x, 0, 0, 0, $im_width, $im_height);
  981.  
  982. $path = custom_image_get_file('phone-watermark.png');
  983. $phone = imagecreatefrompng($path);
  984. $ph_width = imagesx($phone);
  985. $ph_height = imagesy($phone);
  986.  
  987. if ($data['width'] < 0) {
  988. $dst_x = 0;
  989. }
  990. else {
  991. $dst_x = $b_width - $ph_width;
  992.  
  993. if ($dst_x < 0) {
  994. $dst_x = 0;
  995. }
  996. }
  997.  
  998. imagelayereffect($blank, IMG_EFFECT_ALPHABLEND);
  999. imagecopy($blank, $phone, $dst_x, $b_height - $ph_height, 0, 0, $ph_width, $ph_height);
  1000.  
  1001. $source->resource = $blank;
  1002.  
  1003. return TRUE;
  1004. }
  1005.  
  1006. function custom_image_replace_gradient_effect($source, $data) {
  1007. $image = $source->resource;
  1008. $im_width = imagesx($image);
  1009. $im_height = imagesy($image);
  1010.  
  1011. foreach ($data as &$item) {
  1012. $item /= 100;
  1013. }
  1014.  
  1015. $data = [
  1016. 'x' => $im_width * $data['offset_x'],
  1017. 'y' => $im_height * $data['offset_y'],
  1018. 'width' => $im_width * $data['width'],
  1019. 'height' => $im_height * $data['height'],
  1020. ];
  1021.  
  1022. $part = imagecrop($image, $data);
  1023. $path = drupal_get_path('module', 'custom');
  1024. $path .= '/images/gradient.png';
  1025.  
  1026. $overlayImage = imagecreatefrompng($path);
  1027. $overlayImage = imagescale($overlayImage, $data['width'], $data['height']);
  1028.  
  1029. imagelayereffect($overlayImage, IMG_EFFECT_OVERLAY);
  1030. imagecopy($overlayImage, $part, 0, 0, 0, 0, $data['width'], $data['height']);
  1031.  
  1032. imagelayereffect($image, IMG_EFFECT_REPLACE);
  1033. imagecopy($image, $overlayImage, $data['x'], $data['y'], 0, 0, $data['width'], $data['height']);
  1034.  
  1035. imageDestroy($part);
  1036. imageDestroy($overlayImage);
  1037.  
  1038. return TRUE;
  1039. }
  1040.  
  1041. function custom_image_replace_greyscale_effect($source, $data) {
  1042. $image = $source->resource;
  1043. $im_width = imagesx($image);
  1044. $im_height = imagesy($image);
  1045.  
  1046. foreach ($data as &$item) {
  1047. $item /= 100;
  1048. }
  1049.  
  1050. $data = [
  1051. 'x' => $im_width * $data['offset_x'],
  1052. 'y' => $im_height * $data['offset_y'],
  1053. 'width' => $im_width * $data['width'],
  1054. 'height' => $im_height * $data['height'],
  1055. ];
  1056.  
  1057. $part = imagecrop($image, $data);
  1058. imagefilter($part, IMG_FILTER_GRAYSCALE);
  1059.  
  1060. imagelayereffect($image, IMG_EFFECT_REPLACE);
  1061. imagecopy($image, $part, $data['x'], $data['y'], 0, 0, $data['width'], $data['height']);
  1062.  
  1063. imageDestroy($part);
  1064.  
  1065. return TRUE;
  1066. }
  1067.  
  1068. /**
  1069. * Implements hook_field_formatter_settings_form_alter().
  1070. */
  1071. function custom_field_formatter_settings_form_alter(array &$settings_form, array $context) {
  1072. // $settings_form['single_image_delta']['#element_validate'] = ['element_validate_integer'];
  1073. }
  1074.  
  1075. function custom_element_validate_email($element, &$form_state) {
  1076. $email = trim($element['#value']);
  1077.  
  1078. if (!empty($email) && !valid_email_address($email)) {
  1079. form_error($element, t('%name is not a valid email address', [
  1080. '%name' => $element['#value'],
  1081. ]));
  1082. }
  1083. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement