Current Directory: /home/astoriaah/www/old15/plugins/sh404sefcore/sh404sefsocial
Viewing File: /home/astoriaah/www/old15/plugins/sh404sefcore/sh404sefsocial/sh404sefsocial.php
<?php
/**
* sh404SEF - SEO extension for Joomla!
*
* @author Yannick Gaultier
* @copyright (c) Yannick Gaultier 2014
* @package sh404SEF
* @license http://www.gnu.org/copyleft/gpl.html GNU/GPL
* @version 4.4.4.1791
* @date 2014-07-01
*/
defined('_JEXEC') or die('Direct Access to this location is not allowed.');
jimport('joomla.plugin.plugin');
class plgSh404sefcoresh404sefSocial extends JPlugin
{
private $_params = null;
private $_enabledButtons = array('facebooklike', 'facebooksend', 'twitter', 'googleplusone', 'googlepluspage', 'pinterestpinit', 'linkedin');
private $_underscoredLanguageTag = '';
public function __construct(&$subject, $config = array())
{
parent::__construct($subject);
// get plugin params
$plugin = JPluginHelper::getPlugin('sh404sefcore', 'sh404sefsocial');
$this->_params = new JRegistry;
$this->_params->loadString($plugin->params);
// some networks use underscore in language tags
$this->_underscoredLanguageTag = str_replace('-', '_', JFactory::getLanguage()->getTag());
$this->_shortLanguageCode = explode('_', $this->_underscoredLanguageTag);
$this->_shortLanguageCode = empty($this->_shortLanguageCode) ? 'en' : $this->_shortLanguageCode[0];
$this->_linkedinScriptLoaded = false;
}
/**
* Insert appropriate script links into document
*/
public function onSh404sefInsertSocialButtons(&$page, $sefConfig)
{
$app = JFactory::getApplication();
// are we in the backend - that would be a mistake
if (!defined('SH404SEF_IS_RUNNING') || $app->isAdmin())
{
return;
}
// don't display on errors
$pageInfo = Sh404sefFactory::getPageInfo();
if (!empty($pageInfo->httpStatus) && $pageInfo->httpStatus == 404)
{
return;
}
// regexp to catch plugin requests
$regExp = '#{sh404sef_social_buttons(.*)}#Uus';
// search for our marker}
if (preg_match_all($regExp, $page, $matches, PREG_SET_ORDER) > 0)
{
// process matches
foreach ($matches as $id => $match)
{
$url = '';
$imageSrc = '';
$imageDesc = '';
// extract target URL
if (!empty($match[1]))
{
//normally, there is no quotes around attributes
// but a description will probably have spaces, so we
// now try to get attributes from both syntax
jimport('joomla.utilities.utility');
$attributes = JUtility::parseAttributes($match[1]);
$url = empty($attributes['url']) ? '' : $attributes['url'];
$imageSrc = empty($attributes['img']) ? '' : $attributes['img'];
$imageDesc = empty($attributes['desc']) ? '' : $attributes['desc'];
$type = empty($attributes['type']) ? '' : $attributes['type'];
// now process usual tags
$raw = explode(' ', $match[1]);
$attributes = array();
$enabledButtons = array();
foreach ($raw as $attribute)
{
$attribute = JString::trim($attribute);
if (strpos($attribute, '=') === false)
{
continue;
}
$bits = explode('=', $attribute);
if (empty($bits[1]))
{
continue;
}
switch ($bits[0])
{
case 'url':
if (empty($url))
{
$base = JURI::base(true);
if (substr($bits[1], 0, 10) == 'index.php?')
{
$url = JURI::getInstance()->toString(array('scheme', 'host', 'port')) . JRoute::_($bits[1]);
}
else if (substr($bits[1], 0, JString::strlen($base)) == $base)
{
$url = JURI::getInstance()->toString(array('scheme', 'host', 'port')) . $bits[1];
}
else if (substr($bits[1], 0, 1) == '/')
{
$url = JString::rtrim(JURI::base(), '/') . $bits[1];
}
else
{
$url = $bits[1];
}
}
break;
case 'type':
$newType = trim(strtolower($bits[1]));
if (!in_array($newType, $enabledButtons))
{
$enabledButtons[] = $newType;
}
break;
case 'img':
$imageSrc = empty($imageSrc) ? strtolower($bits[1]) : $imageSrc;
break;
}
}
if (!empty($enabledButtons))
{
$this->_enabledButtons = $enabledButtons;
}
}
// get buttons html
$buttons = $this->_sh404sefGetSocialButtons($sefConfig, $url, $context = '', $content = null, $imageSrc, $imageDesc, $isTag = true);
$buttons = str_replace('\'', '\\\'', $buttons);
// replace in document
$page = str_replace($match[0], $buttons, $page);
}
}
// insert head links as needed
$this->_insertSocialLinks($page, $sefConfig);
}
public function onContentBeforeDisplay($context, &$row, &$params, $page = 0)
{
$app = JFactory::getApplication();
// are we in the backend - that would be a mistake
if (!defined('SH404SEF_IS_RUNNING') || $app->isAdmin())
{
return;
}
// don't display on errors
$pageInfo = Sh404sefFactory::getPageInfo();
if (!empty($pageInfo->httpStatus) && $pageInfo->httpStatus == 404)
{
return '';
}
if ($this->_params->get('buttonsContentLocation', 'onlyTags') == 'before')
{
$buttons = $this->_sh404sefGetSocialButtons(Sh404sefFactory::getConfig(), $url = '', $context, $row);
}
else
{
$buttons = '';
}
return $buttons;
}
public function onContentAfterDisplay($context, &$row, &$params, $page = 0)
{
if ($this->_params->get('buttonsContentLocation', 'onlyTags') == 'after')
{
$buttons = $this->_sh404sefGetSocialButtons(Sh404sefFactory::getConfig(), $url = '', $context, $row);
}
else
{
$buttons = '';
}
return $buttons;
}
public function onSh404sefInsertFBJavascriptSDK(&$page, $sefConfig)
{
static $_inserted = false;
if ($sefConfig->shMetaManagementActivated && !$_inserted
&& ($this->_params->get('enableFbLike', true) || $this->_params->get('enableFbSend', true)))
{
$_inserted = true;
// append Facebook SDK
$socialSnippet = ShlMvcLayout_Helper::render('com_sh404sef.social.fb_sdk', array('languageTag' => $this->_underscoredLanguageTag));
// use page rewrite utility function to insert as needed
$page = shPregInsertCustomTagInBuffer($page, '<\s*body[^>]*>', 'after', $socialSnippet, $firstOnly = 'first');
}
}
private function _sh404sefGetSocialButtons($sefConfig, $url = '', $context = '', $content = null, $imageSrc = '', $imageDesc = '', $isTag = false)
{
$url = $this->_computeUrl($url, $sefConfig, $context, $content, $isTag);
if (empty($url))
{
return $url;
}
// JLayout renderers data array
$displayData = array();
$displayData['buttons'] = array();
// Tweet
if ($this->_params->get('enableTweet', true) && in_array('twitter', $this->_enabledButtons))
{
$displayData['buttons']['twitter'] = array('viaAccount' => $this->_params->get('viaAccount', ''),
'tweetLayout' => $this->_params->get('tweetLayout', 'none'), 'url' => $url, 'languageTag' => $this->_shortLanguageCode);
}
// plus One
if ($this->_params->get('enablePlusOne', true) && in_array('googleplusone', $this->_enabledButtons))
{
$displayData['buttons']['googleplusone'] = array('plusOneAnnotation' => $this->_params->get('plusOneAnnotation', 'none'),
'plusOneSize' => $this->_params->get('plusOneSize', ''), 'url' => $url);
}
// Google plus page badge
$page = JString::trim($this->_params->get('googlePlusPage', ''), '/');
if ($this->_params->get('enableGooglePlusPage', true) && in_array('googlepluspage', $this->_enabledButtons) && !empty($page))
{
$displayData['buttons']['googlepluspage'] = array();
$displayData['buttons']['googlepluspage']['page'] = $page;
$displayData['buttons']['googlepluspage']['url'] = $url;
$displayData['buttons']['googlepluspage']['googlePlusPageSize'] = $this->_params->get('googlePlusPageSize', 'medium');
$displayData['buttons']['googlepluspage']['googlePlusCustomText'] = $this->_params->get('googlePlusCustomText', '');
$displayData['buttons']['googlepluspage']['googlePlusCustomText2'] = $this->_params->get('googlePlusCustomText2', '');
}
// Pinterest
if ($this->_params->get('enablePinterestPinIt', 1) && in_array('pinterestpinit', $this->_enabledButtons))
{
// we use either the first image in content, or the provided one (from a user created tag)
if (empty($imageSrc))
{
// we're using the first image in the content
$regExp = '#<img([^>]*)/>#ius';
$text = empty($content->fulltext) ? (empty($content->introtext) ? '' : $content->introtext) : $content->introtext
. $content->fulltext;
$img = preg_match($regExp, $text, $match);
if (empty($img) || empty($match[1]))
{
// could not find an image in the article
// last chance is maybe webmaster is using Joomla! full text image article feature
// note: if we are not on the canonical page (ie the full article display), Joomla!
// uses the image_intro instead. However, I decided to still pin the full image
// in such case, as the image_intro will most often be a thumbnail
// Is this correct? can there be side effects?
$imageSrc = '';
if ($context == 'com_content.article' && !empty($content->images))
{
$registry = new JRegistry;
$registry->loadString($content->images);
$fulltextImage = $registry->get('image_fulltext');
if (!empty($fulltextImage))
{
$imageSrc = $fulltextImage;
$imageDesc = $registry->get('image_fulltext_alt', '');
}
}
else if ($context == 'com_k2.item')
{
// handle K2 images feature
if (!empty($content->imageMedium))
{
$imageSrc = JURI::root() . str_replace(JURI::base(true) . '/', '', $content->imageMedium);
$imageDesc = $content->image_caption;
}
}
}
else
{
// extract image details
jimport('joomla.utilities.utility');
$attributes = JUtility::parseAttributes($match[1]);
$imageSrc = empty($attributes['src']) ? '' : $attributes['src'];
$imageDesc = empty($attributes['alt']) ? '' : $attributes['alt'];
}
}
if (!empty($imageSrc))
{
if (substr($imageSrc, 0, 4) != 'http' && substr($imageSrc, 0, 1) != '/')
{
// relative url, prepend root url
$imageSrc = JURI::base() . $imageSrc;
}
$displayData['buttons']['pinterest'] = array();
$displayData['buttons']['pinterest']['url'] = $url;
$displayData['buttons']['pinterest']['imageSrc'] = $imageSrc;
$displayData['buttons']['pinterest']['imageDesc'] = $imageDesc;
$displayData['buttons']['pinterest']['pinItCountLayout'] = $this->_params->get('pinItCountLayout', 'none');
$displayData['buttons']['pinterest']['pinItButtonText'] = $this->_params->get('pinItButtonText', 'Pin it');
}
}
// FB Like
if ($this->_params->get('enableFbLike', 1) && in_array('facebooklike', $this->_enabledButtons))
{
$layout = $this->_params->get('fbLayout', '') == 'none' ? '' : $this->_params->get('fbLayout', '');
$fbData = array();
$fbData['fbLayout'] = $layout;
$fbData['url'] = $url;
$fbData['enableFbSend'] = $this->_params->get('enableFbSend', 1);
$fbData['fbAction'] = $this->_params->get('fbAction', '');
$fbData['fbWidth'] = $this->_params->get('fbWidth', '');
$fbData['fbShowFaces'] = $this->_params->get('fbShowFaces', 'true');
$fbData['fbColorscheme'] = $this->_params->get('fbColorscheme', 'light');
$fbData['enableFbShare'] = $this->_params->get('enableFbShare', 1);
if ($this->_params->get('fbUseHtml5', false))
{
$displayData['buttons']['fb-like-html5'] = $fbData;
}
else
{
$displayData['buttons']['fb-like'] = $fbData;
}
}
if ($this->_params->get('enableFbSend', 1) && in_array('facebooksend', $this->_enabledButtons))
{
$fbData = array();
$fbData['url'] = $url;
$fbData['fbColorscheme'] = $this->_params->get('fbColorscheme', 'light');
if ($this->_params->get('fbUseHtml5', false))
{
$displayData['buttons']['fb-send-html5'] = $fbData;
}
else
{
$displayData['buttons']['fb-send'] = $fbData;
}
}
if ($this->_params->get('enableLinkedIn', 1) && in_array('linkedin', $this->_enabledButtons))
{
$displayData['buttons']['linkedin'] = array('loadScript' => !$this->_linkedinScriptLoaded, 'url' => $url,
'languageTag' => $this->_underscoredLanguageTag, 'layout' => $this->_params->get('linkedinlayout', 'none'));
$this->_linkedinScriptLoaded = true;
}
// perform replace
if (!empty($displayData['buttons']))
{
$buttonsHtml = ShlMvcLayout_Helper::render('com_sh404sef.social.wrapper', $displayData);
}
else
{
$buttonsHtml = '';
}
return $buttonsHtml;
}
private function _computeUrl($url, $sefConfig, $context, $content, $isTag = false)
{
// if no URL, use current
if (empty($url))
{
// no url set on social button tag, we should
// use current URL, except if we are on a page
// where this would cause the wrong url to be shared
// try identify this condition
if ($isTag || $this->_shouldDisplaySocialButtons($url, $sefConfig, $context, $content))
{
Sh404sefHelperShurl::updateShurls();
$pageInfo = Sh404sefFactory::getPageInfo();
if (empty($url))
{
$url = !$this->_params->get('useShurl', true) || empty($pageInfo->shURL) ? $pageInfo->currentSefUrl
: JURI::base() . ltrim($sefConfig->shRewriteStrings[$sefConfig->shRewriteMode], '/') . $pageInfo->shURL;
}
}
}
return $url;
}
private function _shouldDisplaySocialButtons(&$url, $sefConfig, $context = '', $content = null)
{
// if SEO off, don't do anything
if (!$sefConfig->shMetaManagementActivated)
{
return false;
}
$shouldDisplay = true;
$updatedUrl = '';
// user can disable this attempt to identify possible failure
// to select the correct url
if (!$this->_params->get('onlyDisplayOnCanonicalUrl', true))
{
return $shouldDisplay;
}
$app = JFactory::getApplication();
$printing = $app->input->getInt('print');
if (!empty($printing))
{
return false;
}
// get request details
if (empty($context))
{
$component = '';
$view = '';
}
else
{
$bits = explode('.', $context);
if (!empty($bits))
{
$component = $bits[0];
$view = empty($bits[1]) ? $app->input->getCmd('view', '') : $bits[1];
}
}
if (empty($component) && empty($view))
{
return false;
}
switch ($component)
{
case 'com_content':
// only display if on an article page
if ($view == 'article')
{
$id = $app->input->getInt('id', 0);
if (!empty($content->id) && $id != $content->id && !empty($content->link))
{
$updatedUrl = JURI::getInstance()->toString(array('scheme', 'host')) . $content->link;
}
}
else if ($view == 'featured')
{
if (!empty($content->id))
{
$link = JRoute::_('index.php?option=com_content&view=article&id=' . $content->id);
$updatedUrl = JURI::getInstance()->toString(array('scheme', 'host')) . $link;
}
}
else
{
$shouldDisplay = false;
}
// check category
if ($shouldDisplay)
{
$cats = $this->_params->get('enabledCategories', array());
$catid = null;
if (!empty($cats) && ($cats[0] != 'show_on_all'))
{
// find about article category
if (!empty($content))
{
// we have article details
$catid = empty($content->catid) ? 0 : (int) $content->catid;
}
else
{
// no article details, use request
$catid = JRequest::getInt('catid', 0);
}
if (empty($catid))
{
if (!empty($content) && !empty($content->id))
{
$article = JTable::getInstance('content');
$article->load($content->id);
$catid = !empty($article->catid) ? (int) $article->id : 0;
}
}
if (!empty($catid))
{
$shouldDisplay = in_array($catid, $cats);
}
}
}
break;
case 'com_k2':
$shouldDisplay = $view == 'item';
break;
default:
break;
}
if (!empty($updatedUrl) && $shouldDisplay)
{
$url = $updatedUrl;
}
return $shouldDisplay;
}
/**
* Insert appropriate script links into document
*/
private function _insertSocialLinks(&$page, $sefConfig)
{
$headLinks = '';
$bottomLinks = '';
// what do we must link to
$showFb = strpos($page, '<div class="fb-"') !== false || strpos($page, '<fb:') !== false;
$showTwitter = strpos($page, '<a href="https://twitter.com/share"') !== false;
$showPlusOne = strpos($page, '<g:plusone callback="_sh404sefSocialTrackGPlusTracking"') !== false;
$gPlusPage = $this->_params->get('googlePlusPage', '');
$gPlusPage = JString::trim($gPlusPage, '/');
$showGPlusPage = strpos($page, 'onclick="_sh404sefSocialTrack.GPageTracking') !== false && !empty($gPlusPage);
$showPinterest = strpos($page, 'class="pin-it-button"') !== false;
$showLinkedin = strpos($page, '//platform.linkedin.com/in.js') !== false;
// insert social tracking javascript
if ($showFb || $showTwitter | $showPlusOne || $showGPlusPage || $showPinterest)
{
// G! use underscore in language tags
$channelUrl = JURI::base() . 'index.php?option=com_sh404sef&view=channelurl&format=raw&langtag=' . $this->_underscoredLanguageTag;
$channelUrl = str_replace(array('http://', 'https://'), '//', $channelUrl);
$headLinks .= "\n<script src='" . JURI::base(true) . '/plugins/sh404sefcore/sh404sefsocial/sh404sefsocial.js'
. "' type='text/javascript' ></script>";
$headLinks .= "\n<script type='text/javascript'>
_sh404sefSocialTrack.options = {enableGoogleTracking:" . ($this->_params->get('enableGoogleSocialEngagement') ? 'true' : 'false')
. ",
enableAnalytics:" . ($this->_params->get('enableSocialAnalyticsIntegration') && Sh404sefHelperAnalytics::isEnabled() ? 'true' : 'false')
. ", trackerName:'',
FBChannelUrl:'" . $channelUrl . "'};
window.fbAsyncInit = _sh404sefSocialTrack.setup;
</script>";
}
if ($showFb)
{
$page = str_replace('<html ', '<html xmlns:fb="http://ogp.me/ns/fb#" ', $page);
}
// twitter share
if ($showTwitter)
{
$bottomLinks .= "\n<script src='//platform.twitter.com/widgets.js' type='text/javascript'></script>";
}
// plus one
if ($showPlusOne)
{
$bottomLinks .= "
<script type='text/javascript'>
(function() {
var po = document.createElement('script');
po.type = 'text/javascript';
po.async = true;
po.src = 'https://apis.google.com/js/plusone.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
})();
</script>
";
}
// google plus page badge
if ($showGPlusPage)
{
$headLinks .= "\n<link href='https://plus.google.com/" . $gPlusPage . "/' rel='publisher' />";
}
// pinterest
if ($showPinterest)
{
$headLinks .= "
<script type='text/javascript'>
(function() {
window.PinIt = window.PinIt || { loaded:false };
if (window.PinIt.loaded) return;
window.PinIt.loaded = true;
function async_load(){
var s = document.createElement('script');
s.type = 'text/javascript';
s.async = true;
if (window.location.protocol == 'https:')
//s.src = 'https://assets.pinterest.com/js/pinit.js';
s.src = '" . JURI::base()
. "media/com_sh404sef/pinterest/pinit.js';
else
//s.src = 'http://assets.pinterest.com/js/pinit.js';
s.src = '" . JURI::base()
. "media/com_sh404sef/pinterest/pinit.js';
var x = document.getElementsByTagName('script')[0];
x.parentNode.insertBefore(s, x);
}
if (window.attachEvent)
window.attachEvent('onload', async_load);
else
window.addEventListener('load', async_load, false);
})();
</script>
";
}
if ($showFb || $showTwitter | $showPlusOne || $showGPlusPage || $showPinterest || $showLinkedin)
{
// add our wrapping css
$headLinks .= ShlMvcLayout_Helper::render('com_sh404sef.social.css');
}
// actually insert
if (!empty($headLinks))
{
$headLinks .= "<script type='text/javascript'>var _sh404SEF_live_site = '" . JURI::base() . "';</script>";
// insert everything in page
$page = shInsertCustomTagInBuffer($page, '</head>', 'before', $headLinks, $firstOnly = 'first');
}
if (!empty($bottomLinks))
{
// insert everything in page
$page = shInsertCustomTagInBuffer($page, '</body>', 'before', $bottomLinks, $firstOnly = 'first');
}
}
}