addtoany.module 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. <?php
  2. /**
  3. * @file
  4. * Handle AddToAny integration.
  5. */
  6. use Drupal\Core\Entity\EntityInterface;
  7. use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
  8. use Drupal\Core\Render\Markup;
  9. use Drupal\Core\Url;
  10. use Drupal\Component\Utility\UrlHelper;
  11. use Drupal\node\Entity\Node;
  12. use Drupal\addtoany\Form\AddToAnySettingsForm;
  13. /**
  14. * Implements hook_theme().
  15. */
  16. function addtoany_theme() {
  17. return [
  18. 'addtoany_standard' => [
  19. 'variables' => [
  20. 'addtoany_html' => FALSE,
  21. 'link_url' => FALSE,
  22. 'link_title' => FALSE,
  23. 'buttons_size' => FALSE,
  24. 'button_setting' => FALSE,
  25. 'button_image' => FALSE,
  26. 'universal_button_placement' => FALSE,
  27. 'entity_type' => '',
  28. 'bundle' => '',
  29. ],
  30. ],
  31. ];
  32. }
  33. /**
  34. * Implements hook_theme_suggestions_HOOK().
  35. */
  36. function addtoany_theme_suggestions_addtoany_standard(array $variables) {
  37. $suggestion = 'addtoany_standard__';
  38. $suggestions = [];
  39. if (!empty($variables['entity_type'])) {
  40. $suggestion .= $variables['entity_type'];
  41. $suggestions[] = $suggestion;
  42. }
  43. if (!empty($variables['entity_type']) && !empty($variables['bundle'])) {
  44. $suggestion .= '__' . $variables['bundle'];
  45. $suggestions[] = $suggestion;
  46. }
  47. return $suggestions;
  48. }
  49. /**
  50. * Implements hook_entity_extra_field_info().
  51. */
  52. function addtoany_entity_extra_field_info() {
  53. $extra = [];
  54. $entityTypes = AddToAnySettingsForm::getContentEntities();
  55. $config = Drupal::config('addtoany.settings');
  56. // Allow modules to alter the entity types.
  57. \Drupal::moduleHandler()->alter('addtoany_entity_types', $entityTypes);
  58. foreach ($entityTypes as $type) {
  59. $entityTypeId = $type->id();
  60. $isAllowed = $config->get("entities.{$entityTypeId}");
  61. if ($isAllowed) {
  62. $bundles = Drupal::service('entity_type.bundle.info')->getBundleInfo($entityTypeId);
  63. foreach ($bundles as $bundle => $bundle_data) {
  64. $extra[$entityTypeId][$bundle]['display']['addtoany'] = [
  65. 'label' => t('AddToAny'),
  66. 'description' => t('Share buttons by AddToAny'),
  67. 'weight' => 5,
  68. 'visible' => FALSE,
  69. ];
  70. }
  71. }
  72. }
  73. return $extra;
  74. }
  75. /**
  76. * Implements hook_ENTITY_TYPE_view().
  77. */
  78. function addtoany_entity_view(array &$build, EntityInterface $entity, EntityViewDisplayInterface $display, $view_mode) {
  79. if ($display->getComponent('addtoany')) {
  80. $config = Drupal::config('addtoany.settings');
  81. $isAllowed = $config->get("entities.{$entity->getEntityTypeId()}");
  82. if ($isAllowed) {
  83. $data = addtoany_create_entity_data($entity);
  84. $build['addtoany'] = [
  85. '#addtoany_html' => \Drupal::token()->replace($data['addtoany_html'], ['node' => $entity]),
  86. '#link_url' => $data['link_url'],
  87. '#link_title' => $data['link_title'],
  88. '#button_setting' => $data['button_setting'],
  89. '#button_image' => $data['button_image'],
  90. '#universal_button_placement' => $data['universal_button_placement'],
  91. '#buttons_size' => $data['buttons_size'],
  92. '#entity_type' => $entity->getEntityType()->id(),
  93. '#bundle' => $entity->bundle(),
  94. '#theme' => 'addtoany_standard',
  95. ];
  96. }
  97. }
  98. }
  99. /**
  100. * Implements hook_page_attachments().
  101. */
  102. function addtoany_page_attachments(&$page) {
  103. $config = \Drupal::config('addtoany.settings');
  104. // Initial JavaScript.
  105. $additional_js = $config->get('additional_js');
  106. if (\Drupal::moduleHandler()->moduleExists('token')) {
  107. $node = \Drupal::routeMatch()->getParameter('node');
  108. $data = [];
  109. if ($node) {
  110. if (is_numeric($node)) {
  111. $node = Node::load($node);
  112. }
  113. $data = ['node' => $node];
  114. $additional_js = \Drupal::token()->replace($additional_js, $data);
  115. }
  116. }
  117. $javascript_header = 'window.a2a_config=window.a2a_config||{};'
  118. . 'a2a_config.callbacks=[];a2a_config.overlays=[];'
  119. . 'a2a_config.templates={};'
  120. . (($config->get('no_3p')) ? 'a2a_config.no_3p=1;' : '')
  121. . $additional_js;
  122. // Add AddToAny initial JS config.
  123. $page['#attached']['html_head'][] = [
  124. // The data.
  125. [
  126. // Add a <script> tag.
  127. '#tag' => 'script',
  128. // Add JavaScript to the <script> tag.
  129. '#value' => Markup::create($javascript_header),
  130. // Give weight so it appears after meta tags, etc.
  131. '#weight' => 10,
  132. ],
  133. // Assign a key to reference this HTML <HEAD> element when altering.
  134. 'addtoany-js',
  135. ];
  136. // Custom CSS.
  137. $css = $config->get('additional_css');
  138. if (!empty($css)) {
  139. // Add AddToAny custom CSS.
  140. $page['#attached']['html_head'][] = [
  141. // The data.
  142. [
  143. // Add a <style> tag.
  144. '#tag' => 'style',
  145. // Add CSS to the <style> tag.
  146. '#value' => $css,
  147. // Give weight so it appears after meta tags, etc.
  148. '#weight' => 10,
  149. ],
  150. // Assign a key to reference this HTML <HEAD> element when altering.
  151. 'addtoany-css',
  152. ];
  153. }
  154. // Add module's main library, which includes external AddToAny core JS,
  155. // and the module's CSS.
  156. $page['#attached']['library'][] = 'addtoany/addtoany';
  157. }
  158. /**
  159. * Generate data for AddToAny buttons for a node.
  160. *
  161. * @param object $node
  162. * The node object to create the buttons for.
  163. * @param object $config
  164. * If present this will be used as custom config data. Use NULL for default
  165. * config data.
  166. *
  167. * @return array
  168. * The array with url, title, additional_html that will be send to Twig.
  169. */
  170. function addtoany_create_entity_data($node, $config = NULL) {
  171. $url = isset($node) ? $node->url('canonical', ['absolute' => TRUE]) : NULL;
  172. $title = isset($node) ? $node->label() : NULL;
  173. return addtoany_create_data($url, $title, $config);
  174. }
  175. /**
  176. * Generate data for AddToAny buttons.
  177. *
  178. * @param string $url
  179. * If present this will be used as the URL.
  180. * @param string $title
  181. * If present this will be used as the title. Use an empty string for no title
  182. * or NULL to use the current page title.
  183. * @param object $config
  184. * If present this will be used as custom config data. Use NULL for default
  185. * config data.
  186. *
  187. * @return array
  188. * The array with url, title, additional_html that will be send to Twig.
  189. */
  190. function addtoany_create_data($url = NULL, $title = NULL, $config = NULL) {
  191. if (is_null($config)) {
  192. $config = \Drupal::config('addtoany.settings');
  193. }
  194. $additional_html = rtrim($config->get('additional_html'));
  195. $universal_button_placement = $config->get('universal_button_placement');
  196. $is_front = \Drupal::service('path.matcher')->isFrontPage();
  197. // Default to <front> or the current path.
  198. if (!isset($url)) {
  199. // Use <front> for the front page to avoid '/node' as the final URL,
  200. // otherwise use current path.
  201. $url = ($is_front) ? Url::fromRoute('<front>')
  202. ->setAbsolute()
  203. ->toString() : Url::fromRoute('<current>')->setAbsolute()->toString();
  204. }
  205. else {
  206. // Sanitize and encode URL for HTML output.
  207. $url = UrlHelper::stripDangerousProtocols($url);
  208. }
  209. // Default to the current title if available, otherwise use the site name.
  210. if (!isset($title)) {
  211. $site_name = \Drupal::config('system.site')->get('name');
  212. if ($is_front) {
  213. $title = $site_name;
  214. }
  215. else {
  216. $request = \Drupal::request();
  217. $route_match = \Drupal::routeMatch();
  218. $title = \Drupal::service('title_resolver')
  219. ->getTitle($request, $route_match->getRouteObject());
  220. // Expecting array|string|null from getTitle.
  221. if (is_array($title)) {
  222. $title['#allowed_tags'] = [];
  223. $title = \Drupal::service('renderer')->renderPlain($title);
  224. }
  225. }
  226. $title = (empty($title)) ? $site_name : $title;
  227. }
  228. $buttons_size = $config->get('buttons_size');
  229. // Must be a 3 digit positive integer.
  230. $buttons_size = (
  231. $buttons_size !== '32' && strlen($buttons_size) <= 3 && $buttons_size !== ''
  232. && is_numeric($buttons_size) && intval($buttons_size) == $buttons_size && $buttons_size > 0
  233. ) ? $buttons_size : '32';
  234. $button_setting = $config->get('universal_button');
  235. if ($button_setting == 'custom') {
  236. $button_image = UrlHelper::stripDangerousProtocols($config->get('custom_universal_button'));
  237. }
  238. $info = [
  239. 'link_url' => $url,
  240. 'link_title' => $title,
  241. 'buttons_size' => $buttons_size,
  242. 'button_setting' => $button_setting,
  243. 'button_image' => isset($button_image) ? $button_image : '',
  244. 'universal_button_placement' => $universal_button_placement,
  245. 'addtoany_html' => $additional_html,
  246. ];
  247. return $info;
  248. }