View source
<?php
require 'rrssb.config.inc';
use Drupal\Component\Utility\Html;
use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\File\FileSystemInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\node\Entity\NodeType;
use Drupal\node\NodeTypeInterface;
use Drupal\Core\Render\BubbleableMetadata;
use Drupal\Core\Render\Markup;
const RRSSB_DEFAULT_IMAGE_TOKEN = '[node:field_image:url]|[rrssbsite:logo-url]';
function rrssb_tokens($type, $tokens, array $data, array $options, BubbleableMetadata $bubbleable_metadata) {
$replacements = [];
$urlencode = isset($options['urlencode']);
if ($type == 'rrssb' && !empty($data['rrssb'])) {
foreach ($tokens as $name => $original) {
if (isset($data['rrssb'][$name])) {
$replacements[$original] = $data['rrssb'][$name];
if ($urlencode) {
$replacements[$original] = Markup::create(rawurlencode($replacements[$original]));
}
}
}
}
if ($type == 'rrssbsite') {
foreach ($tokens as $name => $original) {
switch ($name) {
case 'logo-url':
if ($logo = theme_get_setting('logo')) {
global $base_url;
$replacements[$original] = $base_url . $logo['url'];
}
break;
}
}
}
return $replacements;
}
function rrssb_theme($existing, $type, $theme, $path) {
return [
'rrssb_button_list' => [
'render element' => 'element',
'variables' => [
'prefix_text' => NULL,
'button_set' => NULL,
'buttons' => [],
],
],
];
}
function _rrssb_decode(&$replacements, $data, $options) {
$replacements = array_map(function ($s) {
return htmlspecialchars_decode($s, ENT_QUOTES);
}, $replacements);
}
function rrssb_cache_flush() {
if ($old = \Drupal::state()
->get('rrssb_css_file')) {
\Drupal::service('file_system')
->delete($old);
}
\Drupal::state()
->delete('rrssb_css_file');
}
function rrssb_library_path() {
return 'libraries/rrssb-plus';
}
function rrssb_library_info_alter(&$libraries, $extension) {
if ($extension == 'rrssb') {
$libPath = rrssb_library_path();
$config = \Drupal::config('rrssb.settings');
if (is_readable("{$libPath}/VERSION.txt")) {
$libraries['main']['version'] = file_get_contents("{$libPath}/VERSION.txt");
}
elseif (is_readable("{$libPath}/package.json")) {
$packageString = file_get_contents("{$libPath}/package.json");
$packageJson = json_decode($packageString, TRUE);
$libraries['main']['version'] = $packageJson['version'];
}
if ($config
->get('test')) {
$libraries['main']['js'] = [
"/{$libPath}/js/rrssb.js" => [],
];
}
$css = \Drupal::state()
->get('rrssb_css_file');
if ($css) {
$libraries['init']['css']['component'][$css] = [];
}
}
}
function rrssb_get_buttons($buttonSet, $node, $context = NULL) {
$config = \Drupal::config("rrssb.button_set.{$buttonSet}");
if (!$config) {
return [];
}
$token_service = \Drupal::service('token');
$follow = $config
->get('follow');
$meta = BubbleableMetadata::createFromObject($config);
if (!$follow) {
if ($context) {
$meta
->setCacheContexts([
$context,
]);
}
$image_tokens = explode('|', $config
->get('image_tokens') ?: RRSSB_DEFAULT_IMAGE_TOKEN);
$mapping = [
'url' => [
'[node:url]',
'[current-page:url]',
],
'title' => [
'[node:title]',
'[current-page:title]',
],
'image' => $image_tokens,
];
foreach ($mapping as $param => $tokens) {
foreach ($tokens as $token) {
$rrssb[$param] = $token_service
->replace($token, [
'node' => $node,
], [
'clear' => TRUE,
'callback' => '_rrssb_decode',
], $meta);
if ($rrssb[$param]) {
break;
}
}
}
list($rrssb['image']) = explode(',', $rrssb['image']);
}
$key = $follow ? 'follow_url' : 'share_url';
$buttons = [];
foreach (rrssb_settings($buttonSet) as $name => $button) {
$rrssb['username'] = $button['username'];
$link = $token_service
->replace($button[$key], [
'rrssb' => $rrssb,
], [
'urlencode' => TRUE,
]);
$class = $button['popup'] ? 'class="popup"' : '';
$buttons[] = [
'svg' => $button['svg'],
'text' => $token_service
->replace($button['text'], [
'rrssb' => $rrssb,
]),
'link' => $link,
'name' => $name,
'class' => $class,
];
}
$items = [
'#theme' => 'rrssb_button_list',
'#prefix_text' => $config
->get('prefix'),
'#button_set' => $buttonSet,
'#buttons' => $buttons,
];
$meta
->applyTo($items);
if (!\Drupal::state()
->get('rrssb_css_file')) {
rrssb_gen_css();
}
$items['#attached']['library'][] = 'rrssb/init';
$items['#attached']['drupalSettings']['rrssb'][$buttonSet] = $config
->get('appearance');
return $items;
}
function rrssb_settings($buttonSet) {
$buttons = rrssb_button_config();
$config = \Drupal::config("rrssb.button_set.{$buttonSet}");
if (!$config) {
return [];
}
$chosen = $config
->get('chosen');
$defaults = [
'enabled' => FALSE,
'weight' => 0,
'username' => '',
];
$follow = $config
->get('follow');
foreach ($buttons as $name => &$button) {
if (isset($chosen[$name])) {
$button += $chosen[$name];
}
$button += $defaults;
$button['username'] = Html::escape($button['username']);
if ($follow) {
$button['text'] = $button['title_follow'];
}
}
uasort($buttons, [
'Drupal\\Component\\Utility\\SortArray',
'sortByWeightElement',
]);
$key = $follow ? 'follow_url' : 'share_url';
$buttons = array_filter($buttons, function ($button) use ($key) {
return $button['enabled'] && isset($button[$key]);
});
return $buttons;
}
function rrssb_button_config() {
$buttons =& drupal_static(__FUNCTION__);
if (isset($buttons)) {
return $buttons;
}
if ($cache = \Drupal::cache()
->get('rrssb_buttons')) {
return $cache->data;
}
$buttons = Drupal::moduleHandler()
->invokeAll('rrssb_buttons');
Drupal::moduleHandler()
->alter('rrssb_buttons', $buttons);
$iconsDir = rrssb_library_path() . '/icons';
foreach ($buttons as $name => &$button) {
if (!isset($button['svg'])) {
$svgfile = isset($button['svgfile']) ? $button['svgfile'] : "<icons>/{$name}.min.svg";
$svgfile = str_replace('<icons>', $iconsDir, $svgfile);
$button['svg'] = file_get_contents($svgfile);
}
if (!isset($button['text'])) {
$button['text'] = $name;
}
if (!isset($button['title_follow'])) {
$button['title_follow'] = $button['text'];
}
if (!isset($button['popup'])) {
$button['popup'] = TRUE;
}
}
\Drupal::cache()
->set('rrssb_buttons', $buttons);
return $buttons;
}
function rrssb_gen_css() {
$state = \Drupal::state();
$file_system = \Drupal::service('file_system');
$css = "/* Auto-generated RRSSB CSS file. */\n";
$buttons = [];
foreach (rrssb_button_sets() as $buttonSet => $config) {
$buttons += rrssb_settings($buttonSet);
}
$css .= rrssb_calc_css($buttons);
$id = substr(hash('sha256', serialize($buttons) . microtime()), 0, 8);
$dir = 'public://rrssb';
$file = "{$dir}/rrssb.{$id}.css";
$file_system
->prepareDirectory($dir, FileSystemInterface::CREATE_DIRECTORY);
$file_system
->saveData($css, $file, FileSystemInterface::EXISTS_REPLACE);
if ($old = $state
->get('rrssb_css_file')) {
$file_system
->delete($old);
}
$state
->set('rrssb_css_file', $file);
\Drupal::service('library.discovery')
->clearCachedDefinitions();
return $file;
}
function rrssb_calc_css($buttons) {
$css = '';
foreach ($buttons as $name => $button) {
$svg = str_replace('<path ', '<path fill="#FFF" ', $button['svg']);
$svg = strtr($svg, [
'<' => '%3C',
'>' => '%3E',
'#' => '%23',
'"' => '\'',
]);
$css .= <<<EOM
.rrssb-buttons li.rrssb-{<span class="php-variable">$name</span>} a { background-color: {<span class="php-variable">$button</span>[<span class="php-string">'color'</span>]}; }
.rrssb-buttons li.rrssb-{<span class="php-variable">$name</span>} a:hover { background-color: {<span class="php-variable">$button</span>[<span class="php-string">'color_hover'</span>]}; }
.rrssb-{<span class="php-variable">$name</span>} .rrssb-icon { background: url("data:image/svg+xml,{<span class="php-variable">$svg</span>}"); }
EOM;
}
return $css;
}
function rrssb_form_node_type_form_alter(&$form, FormStateInterface $form_state) {
$form['rrssb'] = [
'#type' => 'details',
'#title' => t('Ridiculously Responsive Social Share Buttons'),
'#collapsible' => TRUE,
'#group' => 'additional_settings',
'#weight' => 20,
'#access' => \Drupal::currentUser()
->hasPermission('administer nodes'),
'#attached' => [
'library' => [
'rrssb/nodetype',
],
],
];
$type = $form_state
->getFormObject()
->getEntity();
$form['rrssb']['button_set'] = [
'#type' => 'select',
'#options' => rrssb_button_set_names(),
'#title' => t('Select RRSSB button set to display.'),
'#default_value' => $type
->getThirdPartySetting('rrssb', 'button_set', ''),
];
$form['#entity_builders'][] = 'rrssb_node_type_entity_builder';
}
function rrssb_node_type_entity_builder($entity_type, NodeTypeInterface $type, &$form, FormStateInterface $form_state) {
$type
->setThirdPartySetting('rrssb', 'button_set', $form_state
->getValue('button_set'));
}
function rrssb_node_view(array &$build, EntityInterface $entity, EntityViewDisplayInterface $display, $view_mode) {
if ($display
->getComponent('rrssb')) {
$type = NodeType::load($entity
->bundle());
if ($buttonSet = $type
->getThirdPartySetting('rrssb', 'button_set', '')) {
$build['rrssb'] = rrssb_get_buttons($buttonSet, $entity);
}
}
}
function rrssb_entity_extra_field_info() {
$extra = [];
foreach (NodeType::loadMultiple() as $bundle) {
if ($bundle
->getThirdPartySetting('rrssb', 'button_set', '')) {
$extra['node'][$bundle
->id()]['display']['rrssb'] = [
'label' => t('Ridiculously Responsive Social Share Buttons'),
'description' => t('A fake field to display Social buttons'),
'weight' => 10,
];
}
}
return $extra;
}
function rrssb_button_sets() {
return \Drupal::entityTypeManager()
->getStorage('rrssb_button_set')
->loadMultiple();
}
function rrssb_button_set_names() {
$names = [
'' => t('- None -'),
];
foreach (rrssb_button_sets() as $buttonSet => $config) {
$names[$buttonSet] = $config
->label();
}
return $names;
}
function rrssb_extlink_css_exclude_alter(&$cssExclude) {
if (empty($cssExclude)) {
$cssExclude = '.rrssb-buttons';
}
else {
$cssExclude .= ', .rrssb-buttons';
}
}