File Manager

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'); } } }